|
|
| version 1.1, 2019/10/21 14:25:31 | version 1.1.1.3, 2023/09/27 11:18:58 |
|---|---|
| Line 11 | Line 11 |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU General Public License for more details. | GNU General Public License for more details. |
| You should have received a copy of the GNU General Public License | You should have received a copy of the GNU General Public License along |
| along with this program; if not, write to the Free Software | with this program; if not, write to the Free Software Foundation, Inc., |
| Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
| */ | */ |
| #include "cmdpipe.h" | #include "cmdpipe.h" |
| Line 73 int send_synchronous_command( | Line 73 int send_synchronous_command( |
| struct mtr_ctl *ctl, | struct mtr_ctl *ctl, |
| struct packet_command_pipe_t *cmdpipe, | struct packet_command_pipe_t *cmdpipe, |
| const char *cmd, | const char *cmd, |
| struct command_t *result) | struct command_t *result, |
| char *reply) | |
| { | { |
| char reply[PACKET_REPLY_BUFFER_SIZE]; | |
| int command_length; | int command_length; |
| int write_length; | int write_length; |
| int read_length; | int read_length; |
| Line 120 int check_feature( | Line 120 int check_feature( |
| { | { |
| char check_command[COMMAND_BUFFER_SIZE]; | char check_command[COMMAND_BUFFER_SIZE]; |
| struct command_t reply; | struct command_t reply; |
| char reply_buf[PACKET_REPLY_BUFFER_SIZE]; | |
| snprintf(check_command, COMMAND_BUFFER_SIZE, | snprintf(check_command, COMMAND_BUFFER_SIZE, |
| "1 check-support feature %s\n", feature); | "1 check-support feature %s\n", feature); |
| if (send_synchronous_command(ctl, cmdpipe, check_command, &reply) == | if (send_synchronous_command(ctl, cmdpipe, check_command, &reply, reply_buf) == |
| -1) { | -1) { |
| return -1; | return -1; |
| } | } |
| Line 204 int check_packet_features( | Line 205 int check_packet_features( |
| } | } |
| extern char *myname; | |
| /* | /* |
| Execute mtr-packet, allowing the MTR_PACKET evironment to override | Execute mtr-packet, allowing the MTR_PACKET environment to override |
| the PATH when locating the executable. | the PATH when locating the executable. |
| */ | */ |
| static | static |
| void execute_packet_child( | void execute_packet_child( |
| void) | void) |
| { | { |
| char buf[256]; | |
| /* | /* |
| Allow the MTR_PACKET environment variable to override | Allow the MTR_PACKET environment variable to override |
| the path to the mtr-packet executable. This is necessary | the path to the mtr-packet executable. This is necessary |
| Line 229 void execute_packet_child( | Line 232 void execute_packet_child( |
| execlp(mtr_packet_path, "mtr-packet", (char *) NULL); | execlp(mtr_packet_path, "mtr-packet", (char *) NULL); |
| /* | /* |
| Then try to find it where WE were executed from. | |
| */ | |
| strncpy (buf, myname, 240); | |
| strcat (buf, "-packet"); | |
| mtr_packet_path = buf; | |
| execl(mtr_packet_path, "mtr-packet", (char *) NULL); | |
| /* | |
| If mtr-packet is not found, try to use mtr-packet from current directory | If mtr-packet is not found, try to use mtr-packet from current directory |
| */ | */ |
| execl("./mtr-packet", "./mtr-packet", (char *) NULL); | execl("./mtr-packet", "./mtr-packet", (char *) NULL); |
| Line 344 void construct_base_command( | Line 355 void construct_base_command( |
| const char *local_ip_type; | const char *local_ip_type; |
| const char *protocol = NULL; | const char *protocol = NULL; |
| /* Conver the remote IP address to a string */ | /* Convert the remote IP address to a string */ |
| if (inet_ntop(ctl->af, address, ip_string, INET6_ADDRSTRLEN) == NULL) { | if (inet_ntop(ctl->af, address, ip_string, INET6_ADDRSTRLEN) == NULL) { |
| display_close(ctl); | display_close(ctl); |
| Line 507 void parse_mpls_values( | Line 518 void parse_mpls_values( |
| if (label_field == 0) { | if (label_field == 0) { |
| mpls->label[label_count] = value; | mpls->label[label_count] = value; |
| } else if (label_field == 1) { | } else if (label_field == 1) { |
| mpls->exp[label_count] = value; | mpls->tc[label_count] = value; |
| } else if (label_field == 2) { | } else if (label_field == 2) { |
| mpls->s[label_count] = value; | mpls->s[label_count] = value; |
| } else if (label_field == 3) { | } else if (label_field == 3) { |
| Line 611 void handle_reply_errors( | Line 622 void handle_reply_errors( |
| reply_name = reply->command_name; | reply_name = reply->command_name; |
| if (!strcmp(reply_name, "no-route")) { | |
| display_close(ctl); | |
| error(EXIT_FAILURE, 0, "No route to host"); | |
| } | |
| if (!strcmp(reply_name, "network-down")) { | |
| display_close(ctl); | |
| error(EXIT_FAILURE, 0, "Network down"); | |
| } | |
| if (!strcmp(reply_name, "probes-exhausted")) { | if (!strcmp(reply_name, "probes-exhausted")) { |
| display_close(ctl); | display_close(ctl); |
| error(EXIT_FAILURE, 0, "Probes exhausted"); | error(EXIT_FAILURE, 0, "Probes exhausted"); |
| Line 667 void handle_command_reply( | Line 668 void handle_command_reply( |
| struct command_t reply; | struct command_t reply; |
| ip_t fromaddress; | ip_t fromaddress; |
| int seq_num; | int seq_num; |
| int err; | |
| int round_trip_time; | int round_trip_time; |
| char *reply_name; | char *reply_name; |
| struct mplslen mpls; | struct mplslen mpls; |
| Line 688 void handle_command_reply( | Line 690 void handle_command_reply( |
| seq_num = reply.token; | seq_num = reply.token; |
| reply_name = reply.command_name; | reply_name = reply.command_name; |
| /* If the reply type is unknown, ignore it for future compatibility */ | /* Check for known reply types. */ |
| if (strcmp(reply_name, "reply") && strcmp(reply_name, "ttl-expired")) { | if (!strcmp(reply_name, "reply") |
| || !strcmp(reply_name, "ttl-expired")) { | |
| err = 0; | |
| } else if (!strcmp(reply_name, "no-route")) { | |
| err = ENETUNREACH; | |
| } else if (!strcmp(reply_name, "network-down")) { | |
| err = ENETDOWN; | |
| } else { | |
| /* If the reply type is unknown, ignore it */ | |
| return; | return; |
| } | } |
| Line 700 void handle_command_reply( | Line 710 void handle_command_reply( |
| if (parse_reply_arguments | if (parse_reply_arguments |
| (ctl, &reply, &fromaddress, &round_trip_time, &mpls)) { | (ctl, &reply, &fromaddress, &round_trip_time, &mpls)) { |
| reply_func(ctl, seq_num, &mpls, (void *) &fromaddress, | reply_func(ctl, seq_num, err, &mpls, (void *) &fromaddress, |
| round_trip_time); | round_trip_time); |
| } | } |
| } | } |
| Line 732 void consume_reply_buffer( | Line 742 void consume_reply_buffer( |
| /* | /* |
| We may have multiple completed replies. Loop until we don't | We may have multiple completed replies. Loop until we don't |
| have any more newlines termininating replies. | have any more newlines terminating replies. |
| */ | */ |
| while (true) { | while (true) { |
| /* If no newline is found, our reply isn't yet complete */ | /* If no newline is found, our reply isn't yet complete */ |
| Line 745 void consume_reply_buffer( | Line 755 void consume_reply_buffer( |
| /* | /* |
| Terminate the reply string at the newline, which | Terminate the reply string at the newline, which |
| is necessary in the case where we are able to read | is necessary in the case where we are able to read |
| mulitple replies arriving simultaneously. | multiple replies arriving simultaneously. |
| */ | */ |
| *end_of_reply = 0; | *end_of_reply = 0; |
| Line 793 void handle_command_replies( | Line 803 void handle_command_replies( |
| reply_buffer = cmdpipe->reply_buffer; | reply_buffer = cmdpipe->reply_buffer; |
| /* | /* |
| Read the available reply text, up to the the remaining | Read the available reply text, up to the remaining |
| buffer space. (Minus one for the terminating NUL.) | buffer space. (Minus one for the terminating NUL.) |
| */ | */ |
| read_buffer = &reply_buffer[cmdpipe->reply_buffer_used]; | read_buffer = &reply_buffer[cmdpipe->reply_buffer_used]; |