aboutsummaryrefslogtreecommitdiff
path: root/networking/ping.c
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-03-03 00:36:35 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-03-03 00:36:35 +0000
commit19c238bc909d1e06a6bc70fe5f74124b64a4fa9d (patch)
treea696356bc1b8c002af41aa928bc6bf64d3832f17 /networking/ping.c
parent2110aa9ece6f30563068b2ea29bd75e6ea1787eb (diff)
downloadbusybox-w32-19c238bc909d1e06a6bc70fe5f74124b64a4fa9d.tar.gz
busybox-w32-19c238bc909d1e06a6bc70fe5f74124b64a4fa9d.tar.bz2
busybox-w32-19c238bc909d1e06a6bc70fe5f74124b64a4fa9d.zip
ping: don't measure times if ping payload is less than 8 bytes;
commonalize some ping code.
Diffstat (limited to 'networking/ping.c')
-rw-r--r--networking/ping.c180
1 files changed, 75 insertions, 105 deletions
diff --git a/networking/ping.c b/networking/ping.c
index 4c1ec836e..bbe2c9f76 100644
--- a/networking/ping.c
+++ b/networking/ping.c
@@ -262,7 +262,8 @@ static int if_index;
262 262
263static unsigned long ntransmitted, nreceived, nrepeats, pingcount; 263static unsigned long ntransmitted, nreceived, nrepeats, pingcount;
264static int myid; 264static int myid;
265static unsigned long tmin = ULONG_MAX, tmax, tsum; 265static unsigned tmin = UINT_MAX, tmax;
266static unsigned long tsum;
266static char rcvd_tbl[MAX_DUP_CHK / 8]; 267static char rcvd_tbl[MAX_DUP_CHK / 8];
267 268
268static const char *hostname; 269static const char *hostname;
@@ -278,8 +279,6 @@ static const char *dotted;
278 279
279static void pingstats(int junk ATTRIBUTE_UNUSED) 280static void pingstats(int junk ATTRIBUTE_UNUSED)
280{ 281{
281 int status;
282
283 signal(SIGINT, SIG_IGN); 282 signal(SIGINT, SIG_IGN);
284 283
285 printf("\n--- %s ping statistics ---\n", hostname); 284 printf("\n--- %s ping statistics ---\n", hostname);
@@ -290,16 +289,12 @@ static void pingstats(int junk ATTRIBUTE_UNUSED)
290 if (ntransmitted) 289 if (ntransmitted)
291 ntransmitted = (ntransmitted - nreceived) * 100 / ntransmitted; 290 ntransmitted = (ntransmitted - nreceived) * 100 / ntransmitted;
292 printf("%lu%% packet loss\n", ntransmitted); 291 printf("%lu%% packet loss\n", ntransmitted);
293 if (nreceived) 292 if (tmin != UINT_MAX)
294 printf("round-trip min/avg/max = %lu.%lu/%lu.%lu/%lu.%lu ms\n", 293 printf("round-trip min/avg/max = %u.%u/%lu.%lu/%u.%u ms\n",
295 tmin / 10, tmin % 10, 294 tmin / 10, tmin % 10,
296 (tsum / (nreceived + nrepeats)) / 10, 295 (tsum / (nreceived + nrepeats)) / 10,
297 (tsum / (nreceived + nrepeats)) % 10, tmax / 10, tmax % 10); 296 (tsum / (nreceived + nrepeats)) % 10, tmax / 10, tmax % 10);
298 if (nreceived != 0) 297 exit(nreceived == 0); /* (nreceived == 0) is true (1) -- 'failure' */
299 status = EXIT_SUCCESS;
300 else
301 status = EXIT_FAILURE;
302 exit(status);
303} 298}
304 299
305static void sendping_tail(void (*sp)(int), const void *pkt, int size_pkt) 300static void sendping_tail(void (*sp)(int), const void *pkt, int size_pkt)
@@ -406,15 +401,57 @@ static const char *icmp6_type_name(int id)
406} 401}
407#endif 402#endif
408 403
404static void unpack_tail(int sz, struct timeval *tp,
405 const char *from_str,
406 uint16_t recv_seq, int ttl)
407{
408 const char *dupmsg = " (DUP!)";
409 unsigned triptime = triptime; /* for gcc */
410
411 ++nreceived;
412
413 if (tp) {
414 struct timeval tv;
415
416 gettimeofday(&tv, NULL);
417 tv.tv_usec -= tp->tv_usec;
418 if (tv.tv_usec < 0) {
419 --tv.tv_sec;
420 tv.tv_usec += 1000000;
421 }
422 tv.tv_sec -= tp->tv_sec;
423
424 triptime = tv.tv_sec * 10000 + (tv.tv_usec / 100);
425 tsum += triptime;
426 if (triptime < tmin)
427 tmin = triptime;
428 if (triptime > tmax)
429 tmax = triptime;
430 }
431
432 if (TST(recv_seq % MAX_DUP_CHK)) {
433 ++nrepeats;
434 --nreceived;
435 } else {
436 SET(recv_seq % MAX_DUP_CHK);
437 dupmsg += 7;
438 }
439
440 if (option_mask32 & OPT_QUIET)
441 return;
442
443 printf("%d bytes from %s: seq=%u ttl=%d", sz,
444 from_str, recv_seq, ttl);
445 if (tp)
446 printf(" time=%u.%u ms", triptime / 10, triptime % 10);
447 puts(dupmsg);
448 fflush(stdout);
449}
409static void unpack4(char *buf, int sz, struct sockaddr_in *from) 450static void unpack4(char *buf, int sz, struct sockaddr_in *from)
410{ 451{
411 struct icmp *icmppkt; 452 struct icmp *icmppkt;
412 struct iphdr *iphdr; 453 struct iphdr *iphdr;
413 struct timeval tv, *tp; 454 int hlen;
414 int hlen, dupflag;
415 unsigned long triptime;
416
417 gettimeofday(&tv, NULL);
418 455
419 /* discard if too short */ 456 /* discard if too short */
420 if (sz < (datalen + ICMP_MINLEN)) 457 if (sz < (datalen + ICMP_MINLEN))
@@ -430,61 +467,25 @@ static void unpack4(char *buf, int sz, struct sockaddr_in *from)
430 467
431 if (icmppkt->icmp_type == ICMP_ECHOREPLY) { 468 if (icmppkt->icmp_type == ICMP_ECHOREPLY) {
432 uint16_t recv_seq = ntohs(icmppkt->icmp_seq); 469 uint16_t recv_seq = ntohs(icmppkt->icmp_seq);
433 ++nreceived; 470 struct timeval *tp = NULL;
434 tp = (struct timeval *) icmppkt->icmp_data; 471
435 472 if (sz >= ICMP_MINLEN + sizeof(struct timeval))
436 if ((tv.tv_usec -= tp->tv_usec) < 0) { 473 tp = (struct timeval *) icmppkt->icmp_data;
437 --tv.tv_sec; 474 unpack_tail(sz, tp,
438 tv.tv_usec += 1000000; 475 inet_ntoa(*(struct in_addr *) &from->sin_addr.s_addr),
439 } 476 recv_seq, iphdr->ttl);
440 tv.tv_sec -= tp->tv_sec; 477 } else if (icmppkt->icmp_type != ICMP_ECHO) {
441 478 bb_error_msg("warning: got ICMP %d (%s)",
442 triptime = tv.tv_sec * 10000 + (tv.tv_usec / 100); 479 icmppkt->icmp_type,
443 tsum += triptime; 480 icmp_type_name(icmppkt->icmp_type));
444 if (triptime < tmin)
445 tmin = triptime;
446 if (triptime > tmax)
447 tmax = triptime;
448
449 if (TST(recv_seq % MAX_DUP_CHK)) {
450 ++nrepeats;
451 --nreceived;
452 dupflag = 1;
453 } else {
454 SET(recv_seq % MAX_DUP_CHK);
455 dupflag = 0;
456 }
457
458 if (option_mask32 & OPT_QUIET)
459 return;
460
461 printf("%d bytes from %s: icmp_seq=%u", sz,
462 inet_ntoa(*(struct in_addr *) &from->sin_addr.s_addr),
463 recv_seq);
464 printf(" ttl=%d", iphdr->ttl);
465 printf(" time=%lu.%lu ms", triptime / 10, triptime % 10);
466 if (dupflag)
467 printf(" (DUP!)");
468 puts("");
469 } else {
470 if (icmppkt->icmp_type != ICMP_ECHO)
471 bb_error_msg("warning: got ICMP %d (%s)",
472 icmppkt->icmp_type,
473 icmp_type_name(icmppkt->icmp_type));
474 } 481 }
475 fflush(stdout);
476} 482}
477#if ENABLE_PING6 483#if ENABLE_PING6
478static void unpack6(char *packet, int sz, struct sockaddr_in6 *from, int hoplimit) 484static void unpack6(char *packet, int sz, struct sockaddr_in6 *from, int hoplimit)
479{ 485{
480 struct icmp6_hdr *icmppkt; 486 struct icmp6_hdr *icmppkt;
481 struct timeval tv, *tp;
482 int dupflag;
483 unsigned long triptime;
484 char buf[INET6_ADDRSTRLEN]; 487 char buf[INET6_ADDRSTRLEN];
485 488
486 gettimeofday(&tv, NULL);
487
488 /* discard if too short */ 489 /* discard if too short */
489 if (sz < (datalen + sizeof(struct icmp6_hdr))) 490 if (sz < (datalen + sizeof(struct icmp6_hdr)))
490 return; 491 return;
@@ -495,50 +496,19 @@ static void unpack6(char *packet, int sz, struct sockaddr_in6 *from, int hoplimi
495 496
496 if (icmppkt->icmp6_type == ICMP6_ECHO_REPLY) { 497 if (icmppkt->icmp6_type == ICMP6_ECHO_REPLY) {
497 uint16_t recv_seq = ntohs(icmppkt->icmp6_seq); 498 uint16_t recv_seq = ntohs(icmppkt->icmp6_seq);
498 ++nreceived; 499 struct timeval *tp = NULL;
499 tp = (struct timeval *) &icmppkt->icmp6_data8[4]; 500
500 501 if (sz >= sizeof(struct icmp6_hdr) + sizeof(struct timeval))
501 if ((tv.tv_usec -= tp->tv_usec) < 0) { 502 tp = (struct timeval *) &icmppkt->icmp6_data8[4];
502 --tv.tv_sec; 503 unpack_tail(sz, tp,
503 tv.tv_usec += 1000000; 504 inet_ntop(AF_INET6, &pingaddr.sin6.sin6_addr,
504 } 505 buf, sizeof(buf)),
505 tv.tv_sec -= tp->tv_sec; 506 recv_seq, hoplimit);
506 507 } else if (icmppkt->icmp6_type != ICMP6_ECHO_REQUEST) {
507 triptime = tv.tv_sec * 10000 + (tv.tv_usec / 100); 508 bb_error_msg("warning: got ICMP %d (%s)",
508 tsum += triptime; 509 icmppkt->icmp6_type,
509 if (triptime < tmin) 510 icmp6_type_name(icmppkt->icmp6_type));
510 tmin = triptime;
511 if (triptime > tmax)
512 tmax = triptime;
513
514 if (TST(recv_seq % MAX_DUP_CHK)) {
515 ++nrepeats;
516 --nreceived;
517 dupflag = 1;
518 } else {
519 SET(recv_seq % MAX_DUP_CHK);
520 dupflag = 0;
521 }
522
523 if (option_mask32 & OPT_QUIET)
524 return;
525
526 printf("%d bytes from %s: icmp6_seq=%u", sz,
527 inet_ntop(AF_INET6, &pingaddr.sin6.sin6_addr,
528 buf, sizeof(buf)),
529 recv_seq);
530 printf(" ttl=%d time=%lu.%lu ms", hoplimit,
531 triptime / 10, triptime % 10);
532 if (dupflag)
533 printf(" (DUP!)");
534 puts("");
535 } else {
536 if (icmppkt->icmp6_type != ICMP6_ECHO_REQUEST)
537 bb_error_msg("warning: got ICMP %d (%s)",
538 icmppkt->icmp6_type,
539 icmp6_type_name(icmppkt->icmp6_type));
540 } 511 }
541 fflush(stdout);
542} 512}
543#endif 513#endif
544 514