diff options
-rw-r--r-- | networking/ping.c | 61 |
1 files changed, 34 insertions, 27 deletions
diff --git a/networking/ping.c b/networking/ping.c index 3df67f5c3..e919b3a09 100644 --- a/networking/ping.c +++ b/networking/ping.c | |||
@@ -89,7 +89,9 @@ | |||
89 | //usage: "[OPTIONS] HOST" | 89 | //usage: "[OPTIONS] HOST" |
90 | //usage:# define ping_full_usage "\n\n" | 90 | //usage:# define ping_full_usage "\n\n" |
91 | //usage: "Send ICMP ECHO_REQUEST packets to network hosts\n" | 91 | //usage: "Send ICMP ECHO_REQUEST packets to network hosts\n" |
92 | //usage: IF_PING6( | ||
92 | //usage: "\n -4,-6 Force IP or IPv6 name resolution" | 93 | //usage: "\n -4,-6 Force IP or IPv6 name resolution" |
94 | //usage: ) | ||
93 | //usage: "\n -c CNT Send only CNT pings" | 95 | //usage: "\n -c CNT Send only CNT pings" |
94 | //usage: "\n -s SIZE Send SIZE data bytes in packets (default:56)" | 96 | //usage: "\n -s SIZE Send SIZE data bytes in packets (default:56)" |
95 | //usage: "\n -t TTL Set TTL" | 97 | //usage: "\n -t TTL Set TTL" |
@@ -299,7 +301,7 @@ static int common_ping_main(sa_family_t af, char **argv) | |||
299 | 301 | ||
300 | /* Full(er) version */ | 302 | /* Full(er) version */ |
301 | 303 | ||
302 | #define OPT_STRING ("qvc:s:t:w:W:I:4" IF_PING6("6")) | 304 | #define OPT_STRING ("qvc:s:t:w:W:I:n4" IF_PING6("6")) |
303 | enum { | 305 | enum { |
304 | OPT_QUIET = 1 << 0, | 306 | OPT_QUIET = 1 << 0, |
305 | OPT_VERBOSE = 1 << 1, | 307 | OPT_VERBOSE = 1 << 1, |
@@ -309,8 +311,9 @@ enum { | |||
309 | OPT_w = 1 << 5, | 311 | OPT_w = 1 << 5, |
310 | OPT_W = 1 << 6, | 312 | OPT_W = 1 << 6, |
311 | OPT_I = 1 << 7, | 313 | OPT_I = 1 << 7, |
312 | OPT_IPV4 = 1 << 8, | 314 | /*OPT_n = 1 << 8, - ignored */ |
313 | OPT_IPV6 = (1 << 9) * ENABLE_PING6, | 315 | OPT_IPV4 = 1 << 9, |
316 | OPT_IPV6 = (1 << 10) * ENABLE_PING6, | ||
314 | }; | 317 | }; |
315 | 318 | ||
316 | 319 | ||
@@ -349,9 +352,6 @@ struct globals { | |||
349 | #define source_lsa (G.source_lsa ) | 352 | #define source_lsa (G.source_lsa ) |
350 | #define str_I (G.str_I ) | 353 | #define str_I (G.str_I ) |
351 | #define datalen (G.datalen ) | 354 | #define datalen (G.datalen ) |
352 | #define ntransmitted (G.ntransmitted) | ||
353 | #define nreceived (G.nreceived ) | ||
354 | #define nrepeats (G.nrepeats ) | ||
355 | #define pingcount (G.pingcount ) | 355 | #define pingcount (G.pingcount ) |
356 | #define opt_ttl (G.opt_ttl ) | 356 | #define opt_ttl (G.opt_ttl ) |
357 | #define myid (G.myid ) | 357 | #define myid (G.myid ) |
@@ -387,33 +387,40 @@ void BUG_ping_globals_too_big(void); | |||
387 | static void print_stats_and_exit(int junk) NORETURN; | 387 | static void print_stats_and_exit(int junk) NORETURN; |
388 | static void print_stats_and_exit(int junk UNUSED_PARAM) | 388 | static void print_stats_and_exit(int junk UNUSED_PARAM) |
389 | { | 389 | { |
390 | unsigned long ul; | ||
391 | unsigned long nrecv; | ||
392 | |||
390 | signal(SIGINT, SIG_IGN); | 393 | signal(SIGINT, SIG_IGN); |
391 | 394 | ||
392 | printf("\n--- %s ping statistics ---\n", hostname); | 395 | nrecv = G.nreceived; |
393 | printf("%lu packets transmitted, ", ntransmitted); | 396 | printf("\n--- %s ping statistics ---\n" |
394 | printf("%lu packets received, ", nreceived); | 397 | "%lu packets transmitted, " |
395 | if (nrepeats) | 398 | "%lu packets received, ", |
396 | printf("%lu duplicates, ", nrepeats); | 399 | hostname, G.ntransmitted, nrecv |
397 | if (ntransmitted) | 400 | ); |
398 | ntransmitted = (ntransmitted - nreceived) * 100 / ntransmitted; | 401 | if (G.nrepeats) |
399 | printf("%lu%% packet loss\n", ntransmitted); | 402 | printf("%lu duplicates, ", G.nrepeats); |
403 | ul = G.ntransmitted; | ||
404 | if (ul != 0) | ||
405 | ul = (ul - nrecv) * 100 / ul; | ||
406 | printf("%lu%% packet loss\n", ul); | ||
400 | if (tmin != UINT_MAX) { | 407 | if (tmin != UINT_MAX) { |
401 | unsigned tavg = tsum / (nreceived + nrepeats); | 408 | unsigned tavg = tsum / (nrecv + G.nrepeats); |
402 | printf("round-trip min/avg/max = %u.%03u/%u.%03u/%u.%03u ms\n", | 409 | printf("round-trip min/avg/max = %u.%03u/%u.%03u/%u.%03u ms\n", |
403 | tmin / 1000, tmin % 1000, | 410 | tmin / 1000, tmin % 1000, |
404 | tavg / 1000, tavg % 1000, | 411 | tavg / 1000, tavg % 1000, |
405 | tmax / 1000, tmax % 1000); | 412 | tmax / 1000, tmax % 1000); |
406 | } | 413 | } |
407 | /* if condition is true, exit with 1 -- 'failure' */ | 414 | /* if condition is true, exit with 1 -- 'failure' */ |
408 | exit(nreceived == 0 || (deadline && nreceived < pingcount)); | 415 | exit(nrecv == 0 || (deadline && nrecv < pingcount)); |
409 | } | 416 | } |
410 | 417 | ||
411 | static void sendping_tail(void (*sp)(int), int size_pkt) | 418 | static void sendping_tail(void (*sp)(int), int size_pkt) |
412 | { | 419 | { |
413 | int sz; | 420 | int sz; |
414 | 421 | ||
415 | CLR((uint16_t)ntransmitted % MAX_DUP_CHK); | 422 | CLR((uint16_t)G.ntransmitted % MAX_DUP_CHK); |
416 | ntransmitted++; | 423 | G.ntransmitted++; |
417 | 424 | ||
418 | size_pkt += datalen; | 425 | size_pkt += datalen; |
419 | 426 | ||
@@ -423,7 +430,7 @@ static void sendping_tail(void (*sp)(int), int size_pkt) | |||
423 | if (sz != size_pkt) | 430 | if (sz != size_pkt) |
424 | bb_error_msg_and_die(bb_msg_write_error); | 431 | bb_error_msg_and_die(bb_msg_write_error); |
425 | 432 | ||
426 | if (pingcount == 0 || deadline || ntransmitted < pingcount) { | 433 | if (pingcount == 0 || deadline || G.ntransmitted < pingcount) { |
427 | /* Didn't send all pings yet - schedule next in 1s */ | 434 | /* Didn't send all pings yet - schedule next in 1s */ |
428 | signal(SIGALRM, sp); | 435 | signal(SIGALRM, sp); |
429 | if (deadline) { | 436 | if (deadline) { |
@@ -439,7 +446,7 @@ static void sendping_tail(void (*sp)(int), int size_pkt) | |||
439 | * otherwise ping waits for two RTTs. */ | 446 | * otherwise ping waits for two RTTs. */ |
440 | unsigned expire = timeout; | 447 | unsigned expire = timeout; |
441 | 448 | ||
442 | if (nreceived) { | 449 | if (G.nreceived) { |
443 | /* approx. 2*tmax, in seconds (2 RTT) */ | 450 | /* approx. 2*tmax, in seconds (2 RTT) */ |
444 | expire = tmax / (512*1024); | 451 | expire = tmax / (512*1024); |
445 | if (expire == 0) | 452 | if (expire == 0) |
@@ -458,7 +465,7 @@ static void sendping4(int junk UNUSED_PARAM) | |||
458 | pkt->icmp_type = ICMP_ECHO; | 465 | pkt->icmp_type = ICMP_ECHO; |
459 | /*pkt->icmp_code = 0;*/ | 466 | /*pkt->icmp_code = 0;*/ |
460 | pkt->icmp_cksum = 0; /* cksum is calculated with this field set to 0 */ | 467 | pkt->icmp_cksum = 0; /* cksum is calculated with this field set to 0 */ |
461 | pkt->icmp_seq = htons(ntransmitted); /* don't ++ here, it can be a macro */ | 468 | pkt->icmp_seq = htons(G.ntransmitted); /* don't ++ here, it can be a macro */ |
462 | pkt->icmp_id = myid; | 469 | pkt->icmp_id = myid; |
463 | 470 | ||
464 | /* If datalen < 4, we store timestamp _past_ the packet, | 471 | /* If datalen < 4, we store timestamp _past_ the packet, |
@@ -481,7 +488,7 @@ static void sendping6(int junk UNUSED_PARAM) | |||
481 | pkt->icmp6_type = ICMP6_ECHO_REQUEST; | 488 | pkt->icmp6_type = ICMP6_ECHO_REQUEST; |
482 | /*pkt->icmp6_code = 0;*/ | 489 | /*pkt->icmp6_code = 0;*/ |
483 | /*pkt->icmp6_cksum = 0;*/ | 490 | /*pkt->icmp6_cksum = 0;*/ |
484 | pkt->icmp6_seq = htons(ntransmitted); /* don't ++ here, it can be a macro */ | 491 | pkt->icmp6_seq = htons(G.ntransmitted); /* don't ++ here, it can be a macro */ |
485 | pkt->icmp6_id = myid; | 492 | pkt->icmp6_id = myid; |
486 | 493 | ||
487 | /*if (datalen >= 4)*/ | 494 | /*if (datalen >= 4)*/ |
@@ -548,7 +555,7 @@ static void unpack_tail(int sz, uint32_t *tp, | |||
548 | const char *dupmsg = " (DUP!)"; | 555 | const char *dupmsg = " (DUP!)"; |
549 | unsigned triptime = triptime; /* for gcc */ | 556 | unsigned triptime = triptime; /* for gcc */ |
550 | 557 | ||
551 | ++nreceived; | 558 | ++G.nreceived; |
552 | 559 | ||
553 | if (tp) { | 560 | if (tp) { |
554 | /* (int32_t) cast is for hypothetical 64-bit unsigned */ | 561 | /* (int32_t) cast is for hypothetical 64-bit unsigned */ |
@@ -562,8 +569,8 @@ static void unpack_tail(int sz, uint32_t *tp, | |||
562 | } | 569 | } |
563 | 570 | ||
564 | if (TST(recv_seq % MAX_DUP_CHK)) { | 571 | if (TST(recv_seq % MAX_DUP_CHK)) { |
565 | ++nrepeats; | 572 | ++G.nrepeats; |
566 | --nreceived; | 573 | --G.nreceived; |
567 | } else { | 574 | } else { |
568 | SET(recv_seq % MAX_DUP_CHK); | 575 | SET(recv_seq % MAX_DUP_CHK); |
569 | dupmsg += 7; | 576 | dupmsg += 7; |
@@ -692,7 +699,7 @@ static void ping4(len_and_sockaddr *lsa) | |||
692 | continue; | 699 | continue; |
693 | } | 700 | } |
694 | unpack4(G.rcv_packet, c, &from); | 701 | unpack4(G.rcv_packet, c, &from); |
695 | if (pingcount && nreceived >= pingcount) | 702 | if (pingcount && G.nreceived >= pingcount) |
696 | break; | 703 | break; |
697 | } | 704 | } |
698 | } | 705 | } |
@@ -784,7 +791,7 @@ static void ping6(len_and_sockaddr *lsa) | |||
784 | } | 791 | } |
785 | } | 792 | } |
786 | unpack6(G.rcv_packet, c, &from, hoplimit); | 793 | unpack6(G.rcv_packet, c, &from, hoplimit); |
787 | if (pingcount && nreceived >= pingcount) | 794 | if (pingcount && G.nreceived >= pingcount) |
788 | break; | 795 | break; |
789 | } | 796 | } |
790 | } | 797 | } |