From 62f1f99d0fd639602667981b1d451f6ee9806415 Mon Sep 17 00:00:00 2001 From: Thomas Habets Date: Mon, 3 May 2010 22:41:25 +0200 Subject: Don't fail if not uid 0. We may have capabilities anyway, so try to go on --- README | 13 +++++++++---- src/arping.c | 12 +++++++----- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/README b/README index 7b90a34..86d5ee9 100644 --- a/README +++ b/README @@ -191,13 +191,18 @@ A: Be my guest, but if care about security *at all* you will have to restrict a network debugging tool, which generates low-level network packets that ordinary users have absolutely no business generating. - For example, I don't protect against an ALRM signal flood, which will result - in a packet flood. (arping 2.x doesn't have this issue) - If you are honestly debugging the network then I don't see why you aren't root already. - If you think I'm wrong, tell me why. + That being said, on Linux you can add the CAP_NET_RAW capability to arping + limiting the damage if arping were to be compromised: + sudo setcap cap_net_raw+ep /usr/local/sbin/arping + This requires a libnet which does not explicitly check for uid 0. The + current version of libnet does check this, so unless you patch it it will + not help. + + Patch: + http://github.com/ThomasHabets/libnet/commit/aaa383b5c816107082508b7646929a9479b81645 --- Q: What's this -A switch all about, I don't understand it. diff --git a/src/arping.c b/src/arping.c index 7b5e43e..4080637 100644 --- a/src/arping.c +++ b/src/arping.c @@ -163,15 +163,17 @@ do_libnet_init(const char *ifname) libnet_destroy(libnet); libnet = 0; } - if (getuid() && geteuid()) { - fprintf(stderr, "arping: must run as root\n"); - exit(1); - } + /* try libnet_init() even though we aren't root. We may have + * a capability or something */ if (!(libnet = libnet_init(LIBNET_LINK, (char*)ifname, ebuf))) { - fprintf(stderr, "arping: libnet_init(): %s\n", ebuf); + fprintf(stderr, "arping: %s\n", ebuf); + if (getuid() && geteuid()) { + fprintf(stderr, + "arping: you may need to run as root\n"); + } exit(1); } } -- cgit v1.2.1 From fe8a1f97539c51e314bbd1ee5ae3333a208088d2 Mon Sep 17 00:00:00 2001 From: Thomas Habets Date: Sun, 2 May 2010 22:41:11 +0200 Subject: Applied kfreebsd.patch from debian. Thanks to Petr Salinger. --- src/arping.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/arping.c b/src/arping.c index 4080637..2444c94 100644 --- a/src/arping.c +++ b/src/arping.c @@ -78,11 +78,11 @@ #if HAVE_WIN32_LIBNET_H #include #endif -#include #if HAVE_NET_BPF_H #include #endif +#include #ifndef ETH_ALEN #define ETH_ALEN 6 -- cgit v1.2.1 From 3b06e89e89f2d48b415d99887f81a3d5b5bd22ef Mon Sep 17 00:00:00 2001 From: Thomas Habets Date: Sun, 4 Apr 2010 00:49:04 +0200 Subject: Corrected IRIX configure example --- INSTALL | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/INSTALL b/INSTALL index 6a56d94..d469771 100644 --- a/INSTALL +++ b/INSTALL @@ -42,9 +42,9 @@ Examples that I use on some systems: Linux, OpenBSD, FreeBSD: ./configure -Solaris +Solaris: ./configure LDFLAGS="-R/usr/local/lib -L/opt/csw/lib -R/opt/csw/lib" \ CPPFLAGS="-I/usr/local/include" -IRIX (FIXME: double-check this): - ./configure LDFLAGS="-L/usr/local/lib -R/usr/local/lib" +IRIX: + ./configure LDFLAGS="-L/usr/local/lib -Wl,-rpath -Wl,/usr/local/lib" -- cgit v1.2.1 From 1e974035b374677c81fda11089b6aaac1dc7e82d Mon Sep 17 00:00:00 2001 From: Thomas Habets Date: Fri, 9 Apr 2010 23:57:33 +0200 Subject: documented how to configure on openbsd --- INSTALL | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/INSTALL b/INSTALL index d469771..8e776f6 100644 --- a/INSTALL +++ b/INSTALL @@ -39,9 +39,13 @@ that. Examples that I use on some systems: -Linux, OpenBSD, FreeBSD: +Linux: ./configure +OpenBSD: + ./configure LDFLAGS=-L/usr/local/lib CPPFLAGS=-I/usr/local/include/libnet-1.1 + + Solaris: ./configure LDFLAGS="-R/usr/local/lib -L/opt/csw/lib -R/opt/csw/lib" \ CPPFLAGS="-I/usr/local/include" -- cgit v1.2.1 From 440bbfc80421579a49a0ba22a4b7dea377337b1f Mon Sep 17 00:00:00 2001 From: Thomas Habets Date: Mon, 3 May 2010 23:06:57 +0200 Subject: silence cast warning on some archs --- src/arping.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/arping.c b/src/arping.c index 2444c94..d5e2987 100644 --- a/src/arping.c +++ b/src/arping.c @@ -500,8 +500,8 @@ pingmac_send(uint8_t *srcmac, uint8_t *dstmac, sigint(0); } printf("arping: sending packet at time %d %d\n", - lastpacketsent.tv_sec, - lastpacketsent.tv_usec); + (int)lastpacketsent.tv_sec, + (int)lastpacketsent.tv_usec); } if (-1 == (c = libnet_write(libnet))) { fprintf(stderr, "arping: libnet_write(): %s\n", @@ -564,8 +564,8 @@ pingip_send(uint8_t *srcmac, uint8_t *dstmac, sigint(0); } printf("arping: sending packet at time %d %d\n", - lastpacketsent.tv_sec, - lastpacketsent.tv_usec); + (int)lastpacketsent.tv_sec, + (int)lastpacketsent.tv_usec); } if (-1 == libnet_write(libnet)) { fprintf(stderr, "arping: libnet_write(): %s\n", -- cgit v1.2.1 From 49f8e05670eef09421b086acb56e24a699d4fc29 Mon Sep 17 00:00:00 2001 From: Thomas Habets Date: Tue, 4 May 2010 17:46:17 +0200 Subject: fix manpage warning (line too long) --- doc/arping.8 | 5 ++++- doc/arping.yodl | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/doc/arping.8 b/doc/arping.8 index f73e6d0..6de448a 100644 --- a/doc/arping.8 +++ b/doc/arping.8 @@ -98,7 +98,10 @@ Set target MAC address to use when pinging IP address\&. Use -T as target address when pinging MACs that won\&'t respond to a broadcast ping but perhaps to a directed broadcast\&. .IP -\fIExample\fP: To check the address of MAC-A, use knowledge of MAC-B and IP-B\&. +\fIExample\fP: +.nf +.sp +To check the address of MAC-A, use knowledge of MAC-B and IP-B\&. .IP $ arping -S -s -p .IP "-u" diff --git a/doc/arping.yodl b/doc/arping.yodl index 1f655bc..18b38f1 100644 --- a/doc/arping.yodl +++ b/doc/arping.yodl @@ -76,7 +76,9 @@ out what IP-address a host has without taking an IP-address yourself. dit(-T em(IP)) Use -T as target address when pinging MACs that won't respond to a broadcast ping but perhaps to a directed broadcast. -em(Example): \ +em(Example): +mancommand(.nf) +mancommand(.sp) To check the address of MAC-A, use knowledge of MAC-B and IP-B. $ arping -S -s -p -- cgit v1.2.1 From 43cc503603db24c3cece160d07f417158f260234 Mon Sep 17 00:00:00 2001 From: Thomas Habets Date: Wed, 5 May 2010 14:42:25 +0200 Subject: manpage tweak to fit in 80 columns --- doc/arping.yodl | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/doc/arping.yodl b/doc/arping.yodl index 18b38f1..76df777 100644 --- a/doc/arping.yodl +++ b/doc/arping.yodl @@ -92,20 +92,20 @@ enddit() manpagesection(EXAMPLES) mancommand(.nf) mancommand(.sp) - # bf(arping -c 3 88.123.180.225) - ARPING 88.123.180.225 - 60 bytes from 00:11:85:4c:01:01 (88.123.180.225): index=0 time=13.910 msec - 60 bytes from 00:11:85:4c:01:01 (88.123.180.225): index=1 time=13.935 msec - 60 bytes from 00:11:85:4c:01:01 (88.123.180.225): index=2 time=13.944 msec + # bf(arping -c 3 88.1.180.225) + ARPING 88.1.180.225 + 60 bytes from 00:11:85:4c:01:01 (88.1.180.225): index=0 time=13.910 msec + 60 bytes from 00:11:85:4c:01:01 (88.1.180.225): index=1 time=13.935 msec + 60 bytes from 00:11:85:4c:01:01 (88.1.180.225): index=2 time=13.944 msec - --- 88.123.180.225 statistics --- + --- 88.1.180.225 statistics --- 3 packets transmitted, 3 packets received, 0% unanswered # bf(arping -c 3 00:11:85:4c:01:01) ARPING 00:11:85:4c:01:01 - 60 bytes from 88.123.180.225 (00:11:85:4c:01:01): icmp_seq=0 time=13.367 msec - 60 bytes from 88.123.180.225 (00:11:85:4c:01:01): icmp_seq=1 time=13.929 msec - 60 bytes from 88.123.180.225 (00:11:85:4c:01:01): icmp_seq=2 time=13.929 msec + 60 bytes from 88.1.180.225 (00:11:85:4c:01:01): icmp_seq=0 time=13.367 msec + 60 bytes from 88.1.180.225 (00:11:85:4c:01:01): icmp_seq=1 time=13.929 msec + 60 bytes from 88.1.180.225 (00:11:85:4c:01:01): icmp_seq=2 time=13.929 msec --- 00:11:85:4c:01:01 statistics --- 3 packets transmitted, 3 packets received, 0% unanswered -- cgit v1.2.1 From d1c5c11439e8c8597e8f739bbb9cb4fbf0b16c61 Mon Sep 17 00:00:00 2001 From: Thomas Habets Date: Wed, 5 May 2010 14:53:25 +0200 Subject: regenerated manpage --- doc/arping.8 | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/doc/arping.8 b/doc/arping.8 index 6de448a..f49909b 100644 --- a/doc/arping.8 +++ b/doc/arping.8 @@ -116,20 +116,20 @@ Time to wait between pings, in microseconds\&. .SH "EXAMPLES" .nf .sp -# \fBarping -c 3 88\&.123\&.180\&.225\fP -ARPING 88\&.123\&.180\&.225 -60 bytes from 00:11:85:4c:01:01 (88\&.123\&.180\&.225): index=0 time=13\&.910 msec -60 bytes from 00:11:85:4c:01:01 (88\&.123\&.180\&.225): index=1 time=13\&.935 msec -60 bytes from 00:11:85:4c:01:01 (88\&.123\&.180\&.225): index=2 time=13\&.944 msec +# \fBarping -c 3 88\&.1\&.180\&.225\fP +ARPING 88\&.1\&.180\&.225 +60 bytes from 00:11:85:4c:01:01 (88\&.1\&.180\&.225): index=0 time=13\&.910 msec +60 bytes from 00:11:85:4c:01:01 (88\&.1\&.180\&.225): index=1 time=13\&.935 msec +60 bytes from 00:11:85:4c:01:01 (88\&.1\&.180\&.225): index=2 time=13\&.944 msec .PP ---- 88\&.123\&.180\&.225 statistics --- +--- 88\&.1\&.180\&.225 statistics --- 3 packets transmitted, 3 packets received, 0% unanswered .PP # \fBarping -c 3 00:11:85:4c:01:01\fP ARPING 00:11:85:4c:01:01 -60 bytes from 88\&.123\&.180\&.225 (00:11:85:4c:01:01): icmp_seq=0 time=13\&.367 msec -60 bytes from 88\&.123\&.180\&.225 (00:11:85:4c:01:01): icmp_seq=1 time=13\&.929 msec -60 bytes from 88\&.123\&.180\&.225 (00:11:85:4c:01:01): icmp_seq=2 time=13\&.929 msec +60 bytes from 88\&.1\&.180\&.225 (00:11:85:4c:01:01): icmp_seq=0 time=13\&.367 msec +60 bytes from 88\&.1\&.180\&.225 (00:11:85:4c:01:01): icmp_seq=1 time=13\&.929 msec +60 bytes from 88\&.1\&.180\&.225 (00:11:85:4c:01:01): icmp_seq=2 time=13\&.929 msec .PP --- 00:11:85:4c:01:01 statistics --- 3 packets transmitted, 3 packets received, 0% unanswered -- cgit v1.2.1 From 853481d4a329db5975baf1dae8ac25bb9e83649a Mon Sep 17 00:00:00 2001 From: Thomas Habets Date: Wed, 5 May 2010 14:56:31 +0200 Subject: Options should be minuses in manpage, not hyphens. See http://lintian.debian.org/tags/hyphen-used-as-minus-sign.html --- doc/Makefile.am | 6 +++- doc/Makefile.in | 7 ++++- doc/arping.8 | 92 ++++++++++++++++++++++++++++----------------------------- 3 files changed, 57 insertions(+), 48 deletions(-) diff --git a/doc/Makefile.am b/doc/Makefile.am index 725ba02..4b12519 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -2,6 +2,10 @@ # include $(top_srcdir)/Makefile.am.common +# Manpage is only run by maintainer, not by end user. That's why there +# is no dependency on arping.yodl. man_MANS = arping.8 arping.8: - yodl2man -o arping.8 arping.yodl + yodl2man -o arping.8.tmp arping.yodl + perl -ne 's/(^|(?<=[^\\\w]))-/\\-/g;print' < arping.8.tmp > arping.8 + rm -f arping.8.tmp diff --git a/doc/Makefile.in b/doc/Makefile.in index a1b6515..af444ce 100644 --- a/doc/Makefile.in +++ b/doc/Makefile.in @@ -153,6 +153,9 @@ DISTCLEANFILES = *~ # arping/doc/Makefile.am # + +# Manpage is only run by maintainer, not by end user. That's why there +# is no dependency on arping.yodl. man_MANS = arping.8 all: all-am @@ -366,7 +369,9 @@ uninstall-man: uninstall-man8 uninstall-am uninstall-man uninstall-man8 arping.8: - yodl2man -o arping.8 arping.yodl + yodl2man -o arping.8.tmp arping.yodl + perl -ne 's/(^|(?<=[^\\\w]))-/\\-/g;print' < arping.8.tmp > arping.8 + rm -f arping.8.tmp # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: diff --git a/doc/arping.8 b/doc/arping.8 index f49909b..c42ce38 100644 --- a/doc/arping.8 +++ b/doc/arping.8 @@ -5,9 +5,9 @@ arping \- sends arp and/or ip pings to a given host .PP .SH "SYNOPSIS" -\fBarping\fP [-abdDeFhpqrRd0uv] [-S \fIhost/ip\fP] [-T \fIhost/ip\fP] [-s \fIMAC\fP] [-t \fIMAC\fP] [-c \fIcount\fP] [-i \fIinterface\fP] [ -w \fIus\fP ] <\fIhost\fP | -B> +\fBarping\fP [\-abdDeFhpqrRd0uv] [\-S \fIhost/ip\fP] [\-T \fIhost/ip\fP] [\-s \fIMAC\fP] [\-t \fIMAC\fP] [\-c \fIcount\fP] [\-i \fIinterface\fP] [ \-w \fIus\fP ] <\fIhost\fP | \-B> .PP -\fBarping\fP --help +\fBarping\fP \-\-help .PP .SH "DESCRIPTION" The \fIarping\fP utility sends \fBARP\fP and/or \fBICMP\fP requests to the specified \fIhost\fP and displays the replies\&. The \fIhost\fP may be specified by its \fBhostname\fP, its \fBIP\fP address, or its \fBMAC\fP address\&. @@ -25,9 +25,9 @@ scheduler can\&'t keep up to get exact enough timing\&. On an idle system the roundtrip times will be pretty much accurate, but with more load the timing gets less exact\&. .PP -To get more exact timing on a non-idle system, re-nice arping to -15 or so\&. +To get more exact timing on a non-idle system, re-nice arping to \-15 or so\&. .PP -# nice -n -15 arping foobar +# nice \-n \-15 arping foobar .PP This is not just an issue with arping, it is with normal ping also (at least it is on my system)\&. But it doesn\&'t show up as much with ping @@ -37,65 +37,65 @@ received and are therefore replied to faster\&. .SH "OPTIONS" .PP -.IP "--help" +.IP "\-\-help" Show extended help\&. Not quite as extensive as this manpage, -but more than -h\&. -.IP "-0" +but more than \-h\&. +.IP "\-0" Use this option to ping with source IP address 0\&.0\&.0\&.0\&. Use this when you haven\&'t configured your interface yet\&. Note that this may get the MAC-ping unanswered\&. -This is an alias for -S 0\&.0\&.0\&.0\&. -.IP "-a" +This is an alias for \-S 0\&.0\&.0\&.0\&. +.IP "\-a" Audible ping\&. -.IP "-A" +.IP "\-A" Only count addresses matching requested address (This *WILL* break most things you do\&. Only useful if you are arpinging many hosts at once\&. See arping-scan-net\&.sh for an example)\&. -.IP "-b" -Like -0 but source broadcast source address (255\&.255\&.255\&.255)\&. +.IP "\-b" +Like \-0 but source broadcast source address (255\&.255\&.255\&.255)\&. Note that this may get the arping unanswered since it\&'s not normal behavior for a host\&. -.IP "-B" +.IP "\-B" Use instead of host if you want to address 255\&.255\&.255\&.255\&. -.IP "-c \fIcount\fP" +.IP "\-c \fIcount\fP" Only send \fIcount\fP requests\&. -.IP "-d" +.IP "\-d" Find duplicate replies\&. Exit with 1 if there are answers from two different MAC addresses\&. -.IP "-D" +.IP "\-D" Display answers as dots and missing packets as exclamation points\&. Like flood ping on a Cisco\&. -.IP "-e" -Like -a but beep when there is no reply\&. -.IP "-F" +.IP "\-e" +Like \-a but beep when there is no reply\&. +.IP "\-F" Don\&'t try to be smart about the interface name\&. Even if this -switch is not given, -i disables this smartness\&. -.IP "-h" +switch is not given, \-i disables this smartness\&. +.IP "\-h" Displays a help message and exits\&. -.IP "-i \fIinterface\fP" +.IP "\-i \fIinterface\fP" Don\&'t guess, use the specified interface\&. -.IP "-p" +.IP "\-p" Turn on promiscious mode on interface, use this if you don\&'t "own" the MAC address you are using\&. -.IP "-q" +.IP "\-q" Does not display messages, except error messages\&. -.IP "-r" +.IP "\-r" Raw output: only the MAC/IP address is displayed for each reply\&. -.IP "-R" -Raw output: Like -r but shows "the other one", can be combined with --r\&. -.IP "-s \fIMAC\fP" -Set source MAC address\&. You may need to use -p with this\&. -.IP "-S \fIIP\fP" -Like -b and -0 but with set source address\&. +.IP "\-R" +Raw output: Like \-r but shows "the other one", can be combined with +\-r\&. +.IP "\-s \fIMAC\fP" +Set source MAC address\&. You may need to use \-p with this\&. +.IP "\-S \fIIP\fP" +Like \-b and \-0 but with set source address\&. Note that this may get the arping unanswered if the target does not have routing to the IP\&. If you don\&'t own the IP you are using, you may need to turn -on promiscious mode on the interface (with -p)\&. With this switch you can find +on promiscious mode on the interface (with \-p)\&. With this switch you can find out what IP-address a host has without taking an IP-address yourself\&. -.IP "-t \fIMAC\fP" +.IP "\-t \fIMAC\fP" Set target MAC address to use when pinging IP address\&. -.IP "-T \fIIP\fP" -Use -T as target address when pinging MACs that won\&'t +.IP "\-T \fIIP\fP" +Use \-T as target address when pinging MACs that won\&'t respond to a broadcast ping but perhaps to a directed broadcast\&. .IP \fIExample\fP: @@ -103,35 +103,35 @@ respond to a broadcast ping but perhaps to a directed broadcast\&. .sp To check the address of MAC-A, use knowledge of MAC-B and IP-B\&. .IP -$ arping -S -s -p -.IP "-u" +$ arping \-S \-s \-p +.IP "\-u" Show index=received/sent instead of just index=received when pinging MACs\&. -.IP "-v" +.IP "\-v" Verbose output\&. Use twice for more messages\&. -.IP "-w" +.IP "\-w" Time to wait between pings, in microseconds\&. .PP .SH "EXAMPLES" .nf .sp -# \fBarping -c 3 88\&.1\&.180\&.225\fP +# \fBarping \-c 3 88\&.1\&.180\&.225\fP ARPING 88\&.1\&.180\&.225 60 bytes from 00:11:85:4c:01:01 (88\&.1\&.180\&.225): index=0 time=13\&.910 msec 60 bytes from 00:11:85:4c:01:01 (88\&.1\&.180\&.225): index=1 time=13\&.935 msec 60 bytes from 00:11:85:4c:01:01 (88\&.1\&.180\&.225): index=2 time=13\&.944 msec .PP ---- 88\&.1\&.180\&.225 statistics --- +\-\-\- 88\&.1\&.180\&.225 statistics \-\-\- 3 packets transmitted, 3 packets received, 0% unanswered .PP -# \fBarping -c 3 00:11:85:4c:01:01\fP +# \fBarping \-c 3 00:11:85:4c:01:01\fP ARPING 00:11:85:4c:01:01 60 bytes from 88\&.1\&.180\&.225 (00:11:85:4c:01:01): icmp_seq=0 time=13\&.367 msec 60 bytes from 88\&.1\&.180\&.225 (00:11:85:4c:01:01): icmp_seq=1 time=13\&.929 msec 60 bytes from 88\&.1\&.180\&.225 (00:11:85:4c:01:01): icmp_seq=2 time=13\&.929 msec .PP ---- 00:11:85:4c:01:01 statistics --- +\-\-\- 00:11:85:4c:01:01 statistics \-\-\- 3 packets transmitted, 3 packets received, 0% unanswered .PP .fi @@ -140,8 +140,8 @@ ARPING 00:11:85:4c:01:01 .SH "BUGS" .PP -You have to use -B instead of arpinging 255\&.255\&.255\&.255, and -b -instead of -S 255\&.255\&.255\&.255\&. This is libnets fault\&. +You have to use \-B instead of arpinging 255\&.255\&.255\&.255, and \-b +instead of \-S 255\&.255\&.255\&.255\&. This is libnets fault\&. .PP .SH "SEE ALSO" -- cgit v1.2.1 From 86112ba1232dda9ec8cc2bb57269ac2f4584e8cb Mon Sep 17 00:00:00 2001 From: Thomas Habets Date: Mon, 9 Aug 2010 22:26:07 +0200 Subject: use sig_atomic_t for sigint recording --- src/arping.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/arping.c b/src/arping.c index d5e2987..0057b41 100644 --- a/src/arping.c +++ b/src/arping.c @@ -134,7 +134,7 @@ static char dstmac[ETH_ALEN]; static char lastreplymac[ETH_ALEN]; /* doesn't need to be volatile */ -volatile int time_to_die = 0; +volatile sig_atomic_t time_to_die = 0; /** * -- cgit v1.2.1 From 3bff1171e661bfbb3a53bda202a7a43f6fff4e20 Mon Sep 17 00:00:00 2001 From: Thomas Habets Date: Sun, 5 Sep 2010 00:30:46 +0200 Subject: Use monotonic clock to time out waiting for a reply If clock_gettime(CLOCK_MONOTONIC,) is supported then use that and all should be well. If it's not then at least work around hanging until next ping. --- config.h.in | 6 ++ configure | 189 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- configure.ac | 25 ++++++++ src/arping.c | 56 ++++++++++++++++-- 4 files changed, 265 insertions(+), 11 deletions(-) diff --git a/config.h.in b/config.h.in index c15430b..b3015a0 100644 --- a/config.h.in +++ b/config.h.in @@ -3,6 +3,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_ARPA_INET_H +/* Monotonic clock */ +#undef HAVE_CLOCK_MONOTONIC + /* Define to 1 if you have the `gettimeofday' function. */ #undef HAVE_GETTIMEOFDAY @@ -78,6 +81,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H +/* Define to 1 if you have the header file. */ +#undef HAVE_TIME_H + /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H diff --git a/configure b/configure index b9bdb6e..9dc2afd 100755 --- a/configure +++ b/configure @@ -709,6 +709,8 @@ CPP GREP EGREP LIBOBJS +HAVE_CLOCK_MONOTONIC_TRUE +HAVE_CLOCK_MONOTONIC_FALSE LTLIBOBJS' ac_subst_files='' ac_precious_vars='build_alias @@ -3944,6 +3946,89 @@ echo "$as_me: error: libpcap not found" >&2;} { (exit 1); exit 1; }; } fi +{ echo "$as_me:$LINENO: checking for library containing clock_gettime" >&5 +echo $ECHO_N "checking for library containing clock_gettime... $ECHO_C" >&6; } +if test "${ac_cv_search_clock_gettime+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_func_search_save_LIBS=$LIBS +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char clock_gettime (); +int +main () +{ +return clock_gettime (); + ; + return 0; +} +_ACEOF +for ac_lib in '' rt; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_search_clock_gettime=$ac_res +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext + if test "${ac_cv_search_clock_gettime+set}" = set; then + break +fi +done +if test "${ac_cv_search_clock_gettime+set}" = set; then + : +else + ac_cv_search_clock_gettime=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_search_clock_gettime" >&5 +echo "${ECHO_T}$ac_cv_search_clock_gettime" >&6; } +ac_res=$ac_cv_search_clock_gettime +if test "$ac_res" != no; then + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + # Checks for header files. ac_ext=c @@ -4593,11 +4678,13 @@ done + for ac_header in \ arpa/inet.h \ netinet/in.h \ stdlib.h \ sys/socket.h \ +time.h \ sys/time.h \ sys/types.h \ stdint.h \ @@ -5941,6 +6028,91 @@ esac ;; esac + + + +# check for CLOCK_MONOTONIC +{ echo "$as_me:$LINENO: checking for CLOCK_MONOTONIC" >&5 +echo $ECHO_N "checking for CLOCK_MONOTONIC... $ECHO_C" >&6; } +if test "${ac_cv_have_clock_monotonic+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + if test "$cross_compiling" = yes; then + { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run test program while cross compiling +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include +int main() { +struct timespec ts; +exit(!!clock_gettime(CLOCK_MONOTONIC, &ts)); +} + +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_have_clock_monotonic="yes" +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) + ac_cv_have_clock_monotonic="no" + +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_have_clock_monotonic" >&5 +echo "${ECHO_T}$ac_cv_have_clock_monotonic" >&6; } + if test x$ac_cv_have_clock_monotonic = xyes; then + HAVE_CLOCK_MONOTONIC_TRUE= + HAVE_CLOCK_MONOTONIC_FALSE='#' +else + HAVE_CLOCK_MONOTONIC_TRUE='#' + HAVE_CLOCK_MONOTONIC_FALSE= +fi + +if test x$ac_cv_have_clock_monotonic = xyes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_CLOCK_MONOTONIC 1 +_ACEOF + +fi + ac_config_files="$ac_config_files Makefile" ac_config_files="$ac_config_files src/Makefile" @@ -6064,6 +6236,13 @@ echo "$as_me: error: conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi +if test -z "${HAVE_CLOCK_MONOTONIC_TRUE}" && test -z "${HAVE_CLOCK_MONOTONIC_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"HAVE_CLOCK_MONOTONIC\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"HAVE_CLOCK_MONOTONIC\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi : ${CONFIG_STATUS=./config.status} ac_clean_files_save=$ac_clean_files @@ -6692,10 +6871,12 @@ CPP!$CPP$ac_delim GREP!$GREP$ac_delim EGREP!$EGREP$ac_delim LIBOBJS!$LIBOBJS$ac_delim +HAVE_CLOCK_MONOTONIC_TRUE!$HAVE_CLOCK_MONOTONIC_TRUE$ac_delim +HAVE_CLOCK_MONOTONIC_FALSE!$HAVE_CLOCK_MONOTONIC_FALSE$ac_delim LTLIBOBJS!$LTLIBOBJS$ac_delim _ACEOF - if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 95; then + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then break elif $ac_last_try; then { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 @@ -6714,7 +6895,7 @@ fi cat >>$CONFIG_STATUS <<_ACEOF cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof -/@[a-zA-Z_][a-zA-Z_0-9]*@/!b end +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b _ACEOF sed ' s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g @@ -6727,8 +6908,6 @@ N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n ' >>$CONFIG_STATUS >$CONFIG_STATUS <<_ACEOF -:end -s/|#_!!_#|//g CEOF$ac_eof _ACEOF @@ -6982,7 +7161,7 @@ s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t s&@MKDIR_P@&$ac_MKDIR_P&;t t $ac_datarootdir_hack -" $ac_file_inputs | sed -f "$tmp/subs-1.sed" >$tmp/out +" $ac_file_inputs | sed -f "$tmp/subs-1.sed" | sed 's/|#_!!_#|//g' >$tmp/out test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && diff --git a/configure.ac b/configure.ac index 2b42253..e653723 100644 --- a/configure.ac +++ b/configure.ac @@ -22,6 +22,7 @@ AC_CHECK_LIB([net], [libnet_name_resolve], [AC_MSG_ERROR([libnet 1.0.x found. Arping 2.x requires libnet 1.1.x])]) AC_CHECK_LIB([net], [libnet_init], ,[AC_MSG_ERROR([libnet 1.1.x not found])]) AC_CHECK_LIB([pcap], [pcap_open_live], ,[AC_MSG_ERROR([libpcap not found])]) +AC_SEARCH_LIBS([clock_gettime], [rt]) # Checks for header files. AC_HEADER_STDC @@ -30,6 +31,7 @@ arpa/inet.h \ netinet/in.h \ stdlib.h \ sys/socket.h \ +time.h \ sys/time.h \ sys/types.h \ stdint.h \ @@ -70,6 +72,29 @@ case "$target_os" in AC_LIBOBJ([findif_other]) ;; esac + + + +# check for CLOCK_MONOTONIC +AC_CACHE_CHECK([for CLOCK_MONOTONIC], + ac_cv_have_clock_monotonic, [ + AC_TRY_RUN( + [ +#include +int main() { +struct timespec ts; +exit(!!clock_gettime(CLOCK_MONOTONIC, &ts)); +} + ], + [ ac_cv_have_clock_monotonic="yes" ], + [ ac_cv_have_clock_monotonic="no" ] + ) +]) +AM_CONDITIONAL(HAVE_CLOCK_MONOTONIC, test x$ac_cv_have_clock_monotonic = xyes) +if test x$ac_cv_have_clock_monotonic = xyes; then + AC_DEFINE([HAVE_CLOCK_MONOTONIC], [1], [Monotonic clock]) +fi + AC_CONFIG_FILES([Makefile]) AC_CONFIG_FILES([src/Makefile]) AC_CONFIG_FILES([doc/Makefile]) diff --git a/src/arping.c b/src/arping.c index 0057b41..5d17426 100644 --- a/src/arping.c +++ b/src/arping.c @@ -51,6 +51,10 @@ #include #endif +#if HAVE_TIME_H +#include +#endif + #if HAVE_SYS_TIME_H #include #endif @@ -493,13 +497,13 @@ pingmac_send(uint8_t *srcmac, uint8_t *dstmac, libnet_geterror(libnet)); sigint(0); } - if(verbose>1) { + if (verbose > 1) { if (-1 == gettimeofday(&lastpacketsent, NULL)) { fprintf(stderr, "arping: gettimeofday(): %s\n", strerror(errno)); sigint(0); } - printf("arping: sending packet at time %d %d\n", + printf("arping: sending packet at time %d.%.6d\n", (int)lastpacketsent.tv_sec, (int)lastpacketsent.tv_usec); } @@ -845,6 +849,22 @@ gettv(struct timeval *tv) } } +/** + * get monotonic clock if available, gettimeofday() if not + */ +void +getclock(struct timeval *tv) +{ +#if HAVE_CLOCK_MONOTONIC + struct timespec ts; + if (!clock_gettime(CLOCK_MONOTONIC, &ts)) { + tv->tv_sec = ts.tv_sec; + tv->tv_usec = ts.tv_nsec / 1000; + return; + } +#endif + gettv(tv); +} /** * @@ -855,28 +875,46 @@ ping_recv_unix(pcap_t *pcap,uint32_t packetwait, pcap_handler func) struct timeval tv; struct timeval endtime; char done = 0; + int fd; - gettv(&tv); + getclock(&tv); endtime.tv_sec = tv.tv_sec + (packetwait / 1000000); endtime.tv_usec = tv.tv_usec + (packetwait % 1000000); fixup_timeval(&endtime); - int fd; - fd = pcap_get_selectable_fd(pcap); for (;!done;) { int trydispatch = 0; - gettv(&tv); + getclock(&tv); tv.tv_sec = endtime.tv_sec - tv.tv_sec; tv.tv_usec = endtime.tv_usec - tv.tv_usec; fixup_timeval(&tv); + + /* if time has passed, do one last check and then we're done. + * this also triggers if not using monotonic clock and time + * is set forwards */ if (tv.tv_sec < 0) { tv.tv_sec = 0; tv.tv_usec = 1; done = 1; } + + /* if wait-for-packet time is longer than full period, + * we're obviously not using a monotonic clock and the system + * time has been changed. + * we don't know how far we're into the waiting, so just end + * it here */ + if ((tv.tv_sec > packetwait / 1000000) + || ((tv.tv_sec == packetwait / 1000000) + && (tv.tv_usec > packetwait % 1000000))) { + tv.tv_sec = 0; + tv.tv_usec = 1; + done = 1; + } + + /* check for sigint */ if (time_to_die) { return; } @@ -1396,3 +1434,9 @@ int main(int argc, char **argv) return !numrecvd; } } +/* ---- Emacs Variables ---- + * Local Variables: + * c-basic-offset: 8 + * indent-tabs-mode: nil + * End: + */ -- cgit v1.2.1 From b0a754550bb873b4fdb7049bfc394d38bfe3c72b Mon Sep 17 00:00:00 2001 From: Thomas Habets Date: Mon, 6 Sep 2010 21:14:45 +0200 Subject: changed from poll() to select() to work around bug in MacOSX. Sometimes there's a packet waiting even though poll() says there isn't when checking pcap_get_selectable() fd. Thanks to dlorch at github --- src/arping.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/arping.c b/src/arping.c index 5d17426..2292204 100644 --- a/src/arping.c +++ b/src/arping.c @@ -921,12 +921,13 @@ ping_recv_unix(pcap_t *pcap,uint32_t packetwait, pcap_handler func) /* try to wait for data */ { - struct pollfd p; + fd_set fds; int r; - p.fd = fd; - p.events = POLLIN | POLLPRI; - r = poll(&p, 1, tv.tv_sec * 1000 + tv.tv_usec / 1000); + FD_ZERO(&fds); + FD_SET(fd, &fds); + + r = select(fd + 1, &fds, NULL, NULL, &tv); switch (r) { case 0: /* timeout */ done = 1; -- cgit v1.2.1 From 91e1da907d9024dd2be06151fc23f3542d896f05 Mon Sep 17 00:00:00 2001 From: Thomas Habets Date: Mon, 6 Sep 2010 22:00:54 +0200 Subject: used bsd interface-finding code on MacOSX too --- configure | 2 +- configure.ac | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/configure b/configure index 9dc2afd..cfb6d6d 100755 --- a/configure +++ b/configure @@ -6011,7 +6011,7 @@ case "$target_os" in esac ;; - *freebsd*|*openbsd*|*solaris*) + *freebsd*|*openbsd*|*solaris*|*darwin*) case " $LIBOBJS " in *" findif_bsd.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS findif_bsd.$ac_objext" diff --git a/configure.ac b/configure.ac index e653723..a961140 100644 --- a/configure.ac +++ b/configure.ac @@ -65,7 +65,7 @@ case "$target_os" in *linux*) AC_LIBOBJ([findif_linux]) ;; - *freebsd*|*openbsd*|*solaris*) + *freebsd*|*openbsd*|*solaris*|*darwin*) AC_LIBOBJ([findif_bsd]) ;; *) -- cgit v1.2.1