diff options
author | Thomas Habets <habets@google.com> | 2019-11-07 15:06:24 +0000 |
---|---|---|
committer | Thomas Habets <habets@google.com> | 2019-11-07 15:11:30 +0000 |
commit | 28cddfdb6d87163dcae28f992b956c13d3daf0a9 (patch) | |
tree | 3d3d752f64a82d9b76d5483215a5ca252f565d8b | |
parent | b1df66491af36baf2b05e3386c8e1a996f6cccb2 (diff) | |
download | arping-28cddfdb6d87163dcae28f992b956c13d3daf0a9.tar.gz |
Use pcap_findalldevs() when available instead of pcap_lookupdev()
This change is only used when using -F.
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | src/unix.c | 47 |
2 files changed, 48 insertions, 1 deletions
diff --git a/configure.ac b/configure.ac index 429d64b..2e3a83f 100644 --- a/configure.ac +++ b/configure.ac @@ -75,7 +75,7 @@ AC_FUNC_SETVBUF_REVERSED AC_TYPE_SIGNAL AC_CHECK_FUNCS([gettimeofday memset select strchr strdup strerror strstr \ getifaddrs cap_init pcap_create pcap_list_tstamp_types pcap_set_immediate_mode \ -pledge unveil]) +pledge unveil pcap_findalldevs]) if test x$ac_cv_func_getifaddrs = xyes; then AC_LIBOBJ([findif_getifaddrs]) @@ -21,6 +21,7 @@ #endif #include <signal.h> +#include <string.h> #include <pcap.h> @@ -34,9 +35,55 @@ const char * arping_lookupdev_default(uint32_t srcip, uint32_t dstip, char *ebuf) { +#ifdef HAVE_PCAP_FINDALLDEVS + UNUSED(srcip); + pcap_if_t *ifs = NULL; + int rc = pcap_findalldevs(&ifs, ebuf); + if (rc) { + return NULL; + } + + pcap_if_t *t; + char* ifname = NULL; + for (t = ifs; !ifname && t; t = t->next) { + if (t->flags & PCAP_IF_LOOPBACK) { + continue; + } + if (!(t->flags & PCAP_IF_UP)) { + continue; + } + + // This code is only called when using -F, which is "don't try + // to be smart". If we wanted to be smart we would have used + // findif_*.c. + if (1) { + ifname = strdup(t->name); // Memory leak. + break; + } + + // UNREACHABLE + pcap_addr_t *a; + for (a = t->addresses; !ifname && a; a = a->next) { + if (a->addr->sa_family != AF_INET) { + continue; + } + const struct sockaddr_in* sa = (struct sockaddr_in*)a->addr; + const struct sockaddr_in* smask = (struct sockaddr_in*)a->netmask; + const uint32_t addr = sa->sin_addr.s_addr; + const uint32_t mask = smask->sin_addr.s_addr; + if ((addr & mask) != (dstip & mask)) { + // Not optimal: memory leak. + ifname = strdup(t->name); + } + } + } + pcap_freealldevs(ifs); + return ifname; +#else UNUSED(srcip); UNUSED(dstip); return pcap_lookupdev(ebuf); +#endif } /** |