diff options
author | Thomas Habets <thomas@habets.se> | 2014-05-18 12:52:16 +0100 |
---|---|---|
committer | Thomas Habets <thomas@habets.se> | 2014-05-18 12:52:16 +0100 |
commit | b03ea4693b5a3e1eed3c37e3482480536107eb04 (patch) | |
tree | 4eb285f3ccff5c2ad4fa8fa8d33b540b513f316c | |
parent | 40eaa255c28ed133a257fb15690a660570ac43ed (diff) | |
download | arping-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-x | extra/testing.ex | 10 | ||||
-rw-r--r-- | src/arping.c | 31 | ||||
-rw-r--r-- | src/arping.h | 2 | ||||
-rw-r--r-- | src/findif_bsdroute.c | 2 | ||||
-rw-r--r-- | src/findif_linux.c | 2 |
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); |