--- ping.c.orig Thu Jun 29 01:26:46 2000 +++ ping.c Thu Jun 29 01:09:28 2000 @@ -151,6 +151,7 @@ #define F_SO_DEBUG 0x040 #define F_SO_DONTROUTE 0x080 #define F_VERBOSE 0x100 +#define F_MINTERVAL 0x200 /* multicast options */ int moptions; @@ -254,7 +255,7 @@ preload = 0; datap = &outpack[8 + sizeof(struct timeval)]; - while ((ch = getopt(argc, argv, "I:LRc:dfh:i:l:np:qrs:t:v")) != EOF) + while ((ch = getopt(argc, argv, "I:LRc:dfh:i:l:np:qrs:t:u:v")) != EOF) switch(ch) { case 'c': npackets = atoi(optarg); @@ -332,6 +333,20 @@ exit(2); } break; + case 'u': /* Specify microsecond intervals. */ + if (!am_i_root) { + (void)fprintf(stderr, + "ping: %s\n", strerror(EPERM)); + exit(2); + } + interval = atoi(optarg); + if (interval <= 0) { + (void)fprintf(stderr, + "ping: bad timing interval.\n"); + exit(2); + } + options |= F_MINTERVAL; + break; case 'v': options |= F_VERBOSE; break; @@ -396,12 +411,24 @@ hostname = hnamebuf; } - if (options & F_FLOOD && options & F_INTERVAL) { + if ((options & F_FLOOD) && (options & F_INTERVAL)) { (void)fprintf(stderr, "ping: -f and -i incompatible options.\n"); exit(2); } + if ((options & F_FLOOD) && (options & F_MINTERVAL)) { + (void)fprintf(stderr, + "ping: -f and -u incompatible options.\n"); + exit(2); + } + + if ((options & F_INTERVAL) && (options & F_MINTERVAL)) { + (void)fprintf(stderr, + "ping: -i and -u incompatible options.\n"); + exit(2); + } + if (datalen >= (int)sizeof(struct timeval)) /* can we time transfer */ timing = 1; packlen = datalen + MAXIPLEN + MAXICMPLEN; @@ -546,24 +573,30 @@ static void catcher(int signum) { - struct tms buf; - clock_t current; - static clock_t last = 0; int waittime; + struct itimerval itime; - if (signum) { - current = times(&buf); - if (current - last >= CLK_TCK - 1 || current < last) { - last = current; - pinger(); - } - } else - pinger(); + pinger(); + /* Prevent warning about unused parameter */ + signum = signum; + (void)signal(SIGALRM, catcher); - if (!npackets || ntransmitted < npackets) - alarm((u_int)interval); - else { + if (!npackets || ntransmitted < npackets) { + if (options & F_MINTERVAL) { + itime.it_interval.tv_sec = 0; + itime.it_interval.tv_usec = 0; + + /* I don't know if setitimer handles tv_usec + greater than a second, so make sure it's less. + */ + itime.it_value.tv_sec = interval / 1000000; + itime.it_value.tv_usec = interval % 1000000; + setitimer (ITIMER_REAL, &itime, 0); + } else { + alarm((u_int)interval); + } + } else { if (nreceived) { waittime = 2 * tmax / 1000; if (!waittime) @@ -943,13 +976,14 @@ (void)printf("%ld packets received, ", nreceived); if (nrepeats) (void)printf("+%ld duplicates, ", nrepeats); - if (ntransmitted) + if (ntransmitted) { if (nreceived > ntransmitted) (void)printf("-- somebody's printing up packets!"); else (void)printf("%d%% packet loss", (int) (((ntransmitted - nreceived) * 100) / ntransmitted)); + } (void)putchar('\n'); if (nreceived && timing) (void)printf("round-trip min/avg/max = %lu.%lu/%lu.%lu/%lu.%lu ms\n", @@ -1255,6 +1289,6 @@ usage(void) { (void)fprintf(stderr, - "usage: ping [-LRdfnqrv] [-c count] [-i wait] [-l preload]\n\t[-p pattern] [-s packetsize] [-t ttl] [-I interface address] host\n"); + "usage: ping [-LRdfnqrv] [-c count] [-i wait] [-l preload]\n\t[-p pattern] [-s packetsize] [-t ttl] [-I interface address] host\n\t[-u microsecond interval]\n"); exit(2); }