diff options
-rw-r--r-- | doc/arping.8 | 8 | ||||
-rw-r--r-- | doc/arping.yodl | 6 | ||||
-rw-r--r-- | src/arping.c | 55 |
3 files changed, 53 insertions, 16 deletions
diff --git a/doc/arping.8 b/doc/arping.8 index d2f96fd..7860dcf 100644 --- a/doc/arping.8 +++ b/doc/arping.8 @@ -5,7 +5,7 @@ arping \- sends arp and/or ip pings to a given host .PP .SH "SYNOPSIS" -\fBarping\fP [\-0aAbBdDeFhpqrRuUv] [\-S \fIhost/ip\fP] [\-T \fIhost/ip\fP] [\-s \fIMAC\fP] [\-t \fIMAC\fP] [\-c \fIcount\fP] [\-i \fIinterface\fP] [ \-w \fIus\fP ] [ \-V \fIvlan\fP ] [ \-Q \fIpriority\fP ] <\fIhost\fP | \-B> +\fBarping\fP [\-0aAbBdDeFhpqrRuUv] [\-S \fIhost/ip\fP] [\-T \fIhost/ip\fP] [\-s \fIMAC\fP] [\-t \fIMAC\fP] [\-c \fIcount\fP] [\-i \fIinterface\fP] [ \-w \fIseconds\fP ] [ \-W \fIseconds\fP ] [ \-V \fIvlan\fP ] [ \-Q \fIpriority\fP ] <\fIhost\fP | \-B> .PP \fBarping\fP \-\-help .PP @@ -130,10 +130,10 @@ $ arping \-i <interface> \-U <interface IP> Verbose output\&. Use twice for more messages\&. .IP "\-V \fIvlan\fP" VLAN tag to set\&. Defaults to no VLAN tag\&. -.IP "\-w \fIusec\fP" -Time to wait between pings, in microseconds\&. +.IP "\-w \fIsec\fP" +Specify a timeout before ping exits regardless of how many packets have been sent or received\&. .IP "\-W \fIsec\fP" -Same as \-w, but in floating point seconds\&. +Time to wait between pings\&. .PP .SH "EXAMPLES" diff --git a/doc/arping.yodl b/doc/arping.yodl index 67b81dd..7be341c 100644 --- a/doc/arping.yodl +++ b/doc/arping.yodl @@ -4,7 +4,7 @@ manpagename(arping)(sends arp and/or ip pings to a given host) manpagesynopsis() bf(arping) [-0aAbBdDeFhpqrRuUv] [-S em(host/ip)] [-T em(host/ip)] [-s em(MAC)] \ -[-t em(MAC)] [-c em(count)] [-i em(interface)] [ -w em(us) ] [ -V em(vlan) ] [ -Q em(priority) ] <em(host) | -B> +[-t em(MAC)] [-c em(count)] [-i em(interface)] [ -w em(seconds) ] [ -W em(seconds) ] [ -V em(vlan) ] [ -Q em(priority) ] <em(host) | -B> bf(arping) --help @@ -100,8 +100,8 @@ mancommand(.sp) $ arping -i <interface> -U <interface IP> dit(-v) Verbose output. Use twice for more messages. dit(-V em(vlan)) VLAN tag to set. Defaults to no VLAN tag. - dit(-w em(usec)) Time to wait between pings, in microseconds. - dit(-W em(sec)) Same as -w, but in floating point seconds. + dit(-w em(sec)) Specify a timeout before ping exits regardless of how many packets have been sent or received. + dit(-W em(sec)) Time to wait between pings. enddit() diff --git a/src/arping.c b/src/arping.c index 4a56014..60dc7c5 100644 --- a/src/arping.c +++ b/src/arping.c @@ -638,8 +638,9 @@ extended_usage() " -U Send unsolicited ARP.\n" " -v Verbose output. Use twice for more messages.\n" " -V num 802.1Q tag to add. Defaults to no VLAN tag.\n" - " -w Time to wait between pings, in microseconds.\n" - " -W Same as -w, but in floating point seconds.\n"); + " -w sec Specify a timeout before ping exits regardless of how" + " many\npackets have been sent or received.\n" + " -W sec Time to wait between pings.\n"); printf("Report bugs to: thomas@habets.se\n" "Arping home page: <http://www.habets.pp.se/synscan/>\n" "Development repo: http://github.com/ThomasHabets/arping\n"); @@ -653,7 +654,7 @@ standard_usage() { printf("ARPing %s, by Thomas Habets <thomas@habets.se>\n", version); - printf("usage: arping [ -0aAbdDeFpPqrRuUv ] [ -w <us> ] " + printf("usage: arping [ -0aAbdDeFpPqrRuUv ] [ -w <sec> ] " "[ -W <sec> ] " "[ -S <host/ip> ]\n" " " @@ -783,6 +784,30 @@ timespec2dbl(const struct timespec *tv) } /** + * return number of microseconds to wait for packets. + */ +static uint32_t +wait_time(double deadline, uint32_t packetwait) +{ + struct timespec ts; + + // If deadline not specified, then don't use it. + if (deadline < 0) { + return packetwait; + } + + getclock(&ts); + const double max_wait = deadline - timespec2dbl(&ts); + if (max_wait < 0) { + return 0; + } + if (max_wait > packetwait / 1000000) { + return packetwait; + } + return max_wait * 1000000; +} + +/** * max size of buffer is intsize + 1 + intsize + 4 = 70 bytes or so * * Still, I'm using at least 128bytes below @@ -1440,7 +1465,8 @@ arping_main(int argc, char **argv) struct bpf_program bp; pcap_t *pcap; enum { NONE, PINGMAC, PINGIP } mode = NONE; - unsigned int packetwait = 1000000; + unsigned int packetwait = 1000000; // Default one second. + double deadline = -1; char bpf_filter[64]; ebuf[0] = 0; @@ -1574,7 +1600,7 @@ arping_main(int argc, char **argv) } break; case 'w': - packetwait = (unsigned)atoi(optarg); + deadline = atof(optarg); break; case 'W': packetwait = (unsigned)(1000000.0 * atof(optarg)); @@ -1908,14 +1934,22 @@ arping_main(int argc, char **argv) /* * let's roll */ + if (deadline > 0) { + struct timespec ts; + getclock(&ts); + deadline += timespec2dbl(&ts); + } if (mode == PINGIP) { unsigned int c; unsigned int r; for (c = 0; c < maxcount && !time_to_die; c++) { pingip_send(); r = numrecvd; - ping_recv(pcap,packetwait, - (pcap_handler)pingip_recv); + const uint32_t w = wait_time(deadline, packetwait); + if (w == 0) { + break; + } + ping_recv(pcap, w, (pcap_handler)pingip_recv); } } else { /* PINGMAC */ unsigned int c; @@ -1923,8 +1957,11 @@ arping_main(int argc, char **argv) for (c = 0; c < maxcount && !time_to_die; c++) { pingmac_send(rand(), c); r = numrecvd; - ping_recv(pcap,packetwait, - (pcap_handler)pingmac_recv); + const uint32_t w = wait_time(deadline, packetwait); + if (w == 0) { + break; + } + ping_recv(pcap, w, (pcap_handler)pingmac_recv); } } if (display == DOT) { |