aboutsummaryrefslogtreecommitdiff
path: root/networking/ping.c
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-04-07 00:46:29 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-04-07 00:46:29 +0000
commit90c31b3d4b58512ec2e1ed00670668dd52236415 (patch)
tree99f428830311a06751f258784573bb0262d43f11 /networking/ping.c
parent278a1c22645263f1a82bb3437345e3d96c3f13eb (diff)
downloadbusybox-w32-90c31b3d4b58512ec2e1ed00670668dd52236415.tar.gz
busybox-w32-90c31b3d4b58512ec2e1ed00670668dd52236415.tar.bz2
busybox-w32-90c31b3d4b58512ec2e1ed00670668dd52236415.zip
ping: add -w, -W support (James Simmons <jsimmons AT infradead.org>)
function old new delta print_stats_and_exit - 282 +282 sendping_tail 151 231 +80 packed_usage 23976 24054 +78 ping_main 401 412 +11 arm_ioctl 13 20 +7 pingstats 259 - -259 ------------------------------------------------------------------------------ (add/remove: 1/1 grow/shrink: 4/0 up/down: 458/-259) Total: 199 bytes
Diffstat (limited to 'networking/ping.c')
-rw-r--r--networking/ping.c73
1 files changed, 50 insertions, 23 deletions
diff --git a/networking/ping.c b/networking/ping.c
index 93b2e02f1..299148641 100644
--- a/networking/ping.c
+++ b/networking/ping.c
@@ -224,15 +224,17 @@ int ping_main(int argc ATTRIBUTE_UNUSED, char **argv)
224 224
225/* full(er) version */ 225/* full(er) version */
226 226
227#define OPT_STRING ("qvc:s:I:4" USE_PING6("6")) 227#define OPT_STRING ("qvc:s:w:W:I:4" USE_PING6("6"))
228enum { 228enum {
229 OPT_QUIET = 1 << 0, 229 OPT_QUIET = 1 << 0,
230 OPT_VERBOSE = 1 << 1, 230 OPT_VERBOSE = 1 << 1,
231 OPT_c = 1 << 2, 231 OPT_c = 1 << 2,
232 OPT_s = 1 << 3, 232 OPT_s = 1 << 3,
233 OPT_I = 1 << 4, 233 OPT_w = 1 << 4,
234 OPT_IPV4 = 1 << 5, 234 OPT_W = 1 << 5,
235 OPT_IPV6 = (1 << 6) * ENABLE_PING6, 235 OPT_I = 1 << 6,
236 OPT_IPV4 = 1 << 7,
237 OPT_IPV6 = (1 << 8) * ENABLE_PING6,
236}; 238};
237 239
238 240
@@ -246,6 +248,9 @@ struct globals {
246 uint16_t myid; 248 uint16_t myid;
247 unsigned tmin, tmax; /* in us */ 249 unsigned tmin, tmax; /* in us */
248 unsigned long long tsum; /* in us, sum of all times */ 250 unsigned long long tsum; /* in us, sum of all times */
251 unsigned deadline;
252 unsigned timeout;
253 unsigned total_secs;
249 const char *hostname; 254 const char *hostname;
250 const char *dotted; 255 const char *dotted;
251 union { 256 union {
@@ -271,6 +276,9 @@ struct globals {
271#define tmin (G.tmin ) 276#define tmin (G.tmin )
272#define tmax (G.tmax ) 277#define tmax (G.tmax )
273#define tsum (G.tsum ) 278#define tsum (G.tsum )
279#define deadline (G.deadline )
280#define timeout (G.timeout )
281#define total_secs (G.total_secs )
274#define hostname (G.hostname ) 282#define hostname (G.hostname )
275#define dotted (G.dotted ) 283#define dotted (G.dotted )
276#define pingaddr (G.pingaddr ) 284#define pingaddr (G.pingaddr )
@@ -280,6 +288,8 @@ void BUG_ping_globals_too_big(void);
280 if (sizeof(G) > COMMON_BUFSIZE) \ 288 if (sizeof(G) > COMMON_BUFSIZE) \
281 BUG_ping_globals_too_big(); \ 289 BUG_ping_globals_too_big(); \
282 pingsock = -1; \ 290 pingsock = -1; \
291 datalen = DEFDATALEN; \
292 timeout = MAXWAIT; \
283 tmin = UINT_MAX; \ 293 tmin = UINT_MAX; \
284} while (0) 294} while (0)
285 295
@@ -292,7 +302,8 @@ void BUG_ping_globals_too_big(void);
292 302
293/**************************************************************************/ 303/**************************************************************************/
294 304
295static void pingstats(int junk ATTRIBUTE_UNUSED) 305static void print_stats_and_exit(int junk) ATTRIBUTE_NORETURN;
306static void print_stats_and_exit(int junk ATTRIBUTE_UNUSED)
296{ 307{
297 signal(SIGINT, SIG_IGN); 308 signal(SIGINT, SIG_IGN);
298 309
@@ -311,7 +322,8 @@ static void pingstats(int junk ATTRIBUTE_UNUSED)
311 tavg / 1000, tavg % 1000, 322 tavg / 1000, tavg % 1000,
312 tmax / 1000, tmax % 1000); 323 tmax / 1000, tmax % 1000);
313 } 324 }
314 exit(nreceived == 0); /* (nreceived == 0) is true (1) -- 'failure' */ 325 /* if condition is true, exit with 1 -- 'failure' */
326 exit(nreceived == 0 || (deadline && nreceived < pingcount));
315} 327}
316 328
317static void sendping_tail(void (*sp)(int), const void *pkt, int size_pkt) 329static void sendping_tail(void (*sp)(int), const void *pkt, int size_pkt)
@@ -327,13 +339,30 @@ static void sendping_tail(void (*sp)(int), const void *pkt, int size_pkt)
327 if (sz != size_pkt) 339 if (sz != size_pkt)
328 bb_error_msg_and_die(bb_msg_write_error); 340 bb_error_msg_and_die(bb_msg_write_error);
329 341
330 signal(SIGALRM, sp); 342 if (pingcount == 0 || deadline || ntransmitted < pingcount) {
331 if (pingcount == 0 || ntransmitted < pingcount) { /* schedule next in 1s */ 343 /* Didn't send all pings yet - schedule next in 1s */
344 signal(SIGALRM, sp);
345 if (deadline) {
346 total_secs += PINGINTERVAL;
347 if (total_secs >= deadline)
348 signal(SIGALRM, print_stats_and_exit);
349 }
332 alarm(PINGINTERVAL); 350 alarm(PINGINTERVAL);
333 } else { /* done, wait for the last ping to come back */ 351 } else { /* -c NN, and all NN are sent (and no deadline) */
334 /* todo, don't necessarily need to wait so long... */ 352 /* Wait for the last ping to come back.
335 signal(SIGALRM, pingstats); 353 * -W timeout: wait for a response in seconds.
336 alarm(MAXWAIT); 354 * Affects only timeout in absense of any responses,
355 * otherwise ping waits for two RTTs. */
356 unsigned expire = timeout;
357
358 if (nreceived) {
359 /* approx. 2*tmax, in seconds (2 RTT) */
360 expire = tmax / (512*1024);
361 if (expire == 0)
362 expire = 1;
363 }
364 signal(SIGALRM, print_stats_and_exit);
365 alarm(expire);
337 } 366 }
338} 367}
339 368
@@ -549,7 +578,7 @@ static void ping4(len_and_sockaddr *lsa)
549 sockopt = 48 * 1024; /* explain why 48k? */ 578 sockopt = 48 * 1024; /* explain why 48k? */
550 setsockopt(pingsock, SOL_SOCKET, SO_RCVBUF, &sockopt, sizeof(sockopt)); 579 setsockopt(pingsock, SOL_SOCKET, SO_RCVBUF, &sockopt, sizeof(sockopt));
551 580
552 signal(SIGINT, pingstats); 581 signal(SIGINT, print_stats_and_exit);
553 582
554 /* start the ping's going ... */ 583 /* start the ping's going ... */
555 sendping4(0); 584 sendping4(0);
@@ -568,7 +597,7 @@ static void ping4(len_and_sockaddr *lsa)
568 continue; 597 continue;
569 } 598 }
570 unpack4(packet, c, &from); 599 unpack4(packet, c, &from);
571 if (pingcount > 0 && nreceived >= pingcount) 600 if (pingcount && nreceived >= pingcount)
572 break; 601 break;
573 } 602 }
574} 603}
@@ -624,7 +653,7 @@ static void ping6(len_and_sockaddr *lsa)
624 if (if_index) 653 if (if_index)
625 pingaddr.sin6.sin6_scope_id = if_index; 654 pingaddr.sin6.sin6_scope_id = if_index;
626 655
627 signal(SIGINT, pingstats); 656 signal(SIGINT, print_stats_and_exit);
628 657
629 /* start the ping's going ... */ 658 /* start the ping's going ... */
630 sendping6(0); 659 sendping6(0);
@@ -659,7 +688,7 @@ static void ping6(len_and_sockaddr *lsa)
659 } 688 }
660 } 689 }
661 unpack6(packet, c, /*&from,*/ hoplimit); 690 unpack6(packet, c, /*&from,*/ hoplimit);
662 if (pingcount > 0 && nreceived >= pingcount) 691 if (pingcount && nreceived >= pingcount)
663 break; 692 break;
664 } 693 }
665} 694}
@@ -691,11 +720,9 @@ int ping_main(int argc ATTRIBUTE_UNUSED, char **argv)
691 720
692 INIT_G(); 721 INIT_G();
693 722
694 datalen = DEFDATALEN; 723 /* exactly one argument needed; -v and -q don't mix; -w NUM, -W NUM */
695 724 opt_complementary = "=1:q--v:v--q:w+:W+";
696 /* exactly one argument needed, -v and -q don't mix */ 725 getopt32(argv, OPT_STRING, &opt_c, &opt_s, &deadline, &timeout, &opt_I);
697 opt_complementary = "=1:q--v:v--q";
698 getopt32(argv, OPT_STRING, &opt_c, &opt_s, &opt_I);
699 if (option_mask32 & OPT_c) 726 if (option_mask32 & OPT_c)
700 pingcount = xatoul(opt_c); // -c 727 pingcount = xatoul(opt_c); // -c
701 if (option_mask32 & OPT_s) 728 if (option_mask32 & OPT_s)
@@ -726,8 +753,8 @@ int ping_main(int argc ATTRIBUTE_UNUSED, char **argv)
726 753
727 dotted = xmalloc_sockaddr2dotted_noport(&lsa->u.sa); 754 dotted = xmalloc_sockaddr2dotted_noport(&lsa->u.sa);
728 ping(lsa); 755 ping(lsa);
729 pingstats(0); 756 print_stats_and_exit(0);
730 return EXIT_SUCCESS; 757 /*return EXIT_SUCCESS;*/
731} 758}
732#endif /* FEATURE_FANCY_PING */ 759#endif /* FEATURE_FANCY_PING */
733 760