summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/arping.88
-rw-r--r--doc/arping.yodl6
-rw-r--r--src/arping.c55
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) {