summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Habets <thomas@habets.se>2014-05-18 12:52:16 +0100
committerThomas Habets <thomas@habets.se>2014-05-18 12:52:16 +0100
commitb03ea4693b5a3e1eed3c37e3482480536107eb04 (patch)
tree4eb285f3ccff5c2ad4fa8fa8d33b540b513f316c
parent40eaa255c28ed133a257fb15690a660570ac43ed (diff)
downloadarping-b03ea4693b5a3e1eed3c37e3482480536107eb04.tar.gz
Work around libnet interface autodetection bug.
Under some circumstances libnet_init() will try to open an IPv6-in-IPv4 tunnel with LIBNET_LINK when asked to autodetect. If this happens then retry with interface "lo" which should succeed. This libnet_t* is only used for resolving, so doesn't affect functionality.
-rwxr-xr-xextra/testing.ex10
-rw-r--r--src/arping.c31
-rw-r--r--src/arping.h2
-rw-r--r--src/findif_bsdroute.c2
-rw-r--r--src/findif_linux.c2
5 files changed, 30 insertions, 17 deletions
diff --git a/extra/testing.ex b/extra/testing.ex
index 6b6a9f2..5c26fcf 100755
--- a/extra/testing.ex
+++ b/extra/testing.ex
@@ -170,7 +170,7 @@ Timeout\r
expect eof
send_user -- "--------------- Ping MAC with IP destination ------------------\n"
-spawn $bin -c 1 $mac -T $ip
+spawn $bin -A -c 1 $mac -T $ip
expect -re "ARPING $mac\r
60 bytes from $ip \\($mac\\): icmp_seq=0 time=(.*)sec\r
\r
@@ -181,22 +181,22 @@ rtt min/avg/max/std-dev = \[0-9.\]+/\[0-9.\]+/\[0-9.\]+/0.000 ms\r
expect eof
send_user -- "--------------- Ping MAC cisco style (-D) ------------------\n"
-spawn $bin -c 3 -D $mac -T $ip
+spawn $bin -A -c 3 -D $mac -T $ip
expect "!!!\t 0% packet loss\r\n"
expect eof
send_user -- "--------------- Ping MAC cisco style with audio (-D -a) -----------\n"
-spawn $bin -c 3 -D -a $mac -T $ip
+spawn $bin -A -c 3 -D -a $mac -T $ip
expect "!\a!\a!\a\t 0% packet loss\r\n"
expect eof
send_user -- "--------- Ping MAC x 2 with inverted audio (-e -D) ------------\n"
-spawn $bin -c 2 -D $mac -T $ip
+spawn $bin -A -c 2 -D $mac -T $ip
expect -re "!!\t 0% packet loss\r\n"
expect eof
send_user -- "--------- Ping MAC x 2 with inverted audio, bad dest (-e -D) ------------\n"
# TODO: surely this should be \a.\a. ?
-spawn $bin -c 2 -e -i eth0 -D 00:11:22:33:44:55 -T $ip
+spawn $bin -A -c 2 -e -i eth0 -D 00:11:22:33:44:55 -T $ip
expect "\a\a..\t100% packet loss\r\n"
expect eof
diff --git a/src/arping.c b/src/arping.c
index 4514167..1b5ed55 100644
--- a/src/arping.c
+++ b/src/arping.c
@@ -229,9 +229,12 @@ count_missing_dots()
/**
* Init libnet with specified ifname. Destroy if already inited.
+ * If this function retries with different parameter it will preserve
+ * the original error message and print that.
+ * Call with recursive=0.
*/
void
-do_libnet_init(const char *ifname)
+do_libnet_init(const char *ifname, int recursive)
{
char ebuf[LIBNET_ERRBUF_SIZE];
if (verbose > 1) {
@@ -248,7 +251,17 @@ do_libnet_init(const char *ifname)
if (!(libnet = libnet_init(LIBNET_LINK,
(char*)ifname,
ebuf))) {
- fprintf(stderr, "arping: %s\n", ebuf);
+ if (!ifname) {
+ /* Sometimes libnet guesses an interface that it then
+ * can't use. Work around that by attempting to
+ * use "lo". */
+ return do_libnet_init("lo", 1);
+ } else if (recursive) {
+ /* Continue original execution. */
+ return;
+ }
+ fprintf(stderr, "arping: libnet_init(LIBNET_LINK, %s): %s\n",
+ ifname ? ifname : "<null>", ebuf);
if (getuid() && geteuid()) {
fprintf(stderr,
"arping: you may need to run as root\n");
@@ -1113,7 +1126,7 @@ int main(int argc, char **argv)
break;
}
case 'S': /* set source IP, may be null for don't-know */
- do_libnet_init(ifname);
+ do_libnet_init(ifname, 0);
if (-1 == (srcip = libnet_name2addr4(libnet,
optarg,
LIBNET_RESOLVE))){
@@ -1150,7 +1163,7 @@ int main(int argc, char **argv)
"in MAC ping mode\n");
exit(1);
}
- do_libnet_init(ifname);
+ do_libnet_init(ifname, 0);
if (-1 == (dstip = libnet_name2addr4(libnet,
optarg,
LIBNET_RESOLVE))){
@@ -1207,7 +1220,7 @@ int main(int argc, char **argv)
/* default to own IP address when doing -d */
if (finddup && !parm) {
dstip_given = 1;
- do_libnet_init(ifname);
+ do_libnet_init(ifname, 0);
dstip = libnet_get_ipaddr4(libnet);
if (verbose) {
printf("defaulting to checking dup for %s\n",
@@ -1223,7 +1236,7 @@ int main(int argc, char **argv)
mode = is_mac_addr(parm)?PINGMAC:PINGIP;
} else if (dstip_given) {
mode = PINGIP;
- do_libnet_init(ifname);
+ do_libnet_init(ifname, 0);
parm = strdup(libnet_addr2name4(dstip,0));
if (!parm) {
fprintf(stderr, "arping: out of mem\n");
@@ -1246,8 +1259,8 @@ int main(int argc, char **argv)
/*
* libnet init (may be done already for resolving)
*/
- do_libnet_init(ifname);
-
+ do_libnet_init(ifname, 0);
+
/*
* Make sure dstip and parm like eachother
*/
@@ -1336,7 +1349,7 @@ int main(int argc, char **argv)
* Init libnet again, because we now know the interface name.
* We should know it by know at least
*/
- do_libnet_init(ifname);
+ do_libnet_init(ifname, 0);
/*
* pcap init
diff --git a/src/arping.h b/src/arping.h
index 7d30d2e..a196d16 100644
--- a/src/arping.h
+++ b/src/arping.h
@@ -27,7 +27,7 @@
extern int verbose;
void do_signal_init();
-void do_libnet_init(const char *ifname);
+void do_libnet_init(const char *ifname, int recursive);
void sigint(int);
const char *arping_lookupdev_default(uint32_t srcip, uint32_t dstip,
char *ebuf);
diff --git a/src/findif_bsdroute.c b/src/findif_bsdroute.c
index 3456299..db321ff 100644
--- a/src/findif_bsdroute.c
+++ b/src/findif_bsdroute.c
@@ -43,7 +43,7 @@ arping_lookupdev(uint32_t srcip,
char *p,*p2;
int n;
- do_libnet_init(NULL);
+ do_libnet_init(NULL, 0);
libnet_addr2name4_r(dstip,0,buf1, 1024);
/*
diff --git a/src/findif_linux.c b/src/findif_linux.c
index 1e44e77..de5515d 100644
--- a/src/findif_linux.c
+++ b/src/findif_linux.c
@@ -44,7 +44,7 @@ arping_lookupdev(uint32_t srcip,
char *p,*p2;
int n;
- do_libnet_init(NULL);
+ do_libnet_init(NULL, 0);
libnet_addr2name4_r(dstip,0,buf2,1024);
libnet_addr2name4_r(srcip,0,buf1,1024);