summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Habets <habets@google.com>2019-11-07 15:06:24 +0000
committerThomas Habets <habets@google.com>2019-11-07 15:11:30 +0000
commit28cddfdb6d87163dcae28f992b956c13d3daf0a9 (patch)
tree3d3d752f64a82d9b76d5483215a5ca252f565d8b
parentb1df66491af36baf2b05e3386c8e1a996f6cccb2 (diff)
downloadarping-28cddfdb6d87163dcae28f992b956c13d3daf0a9.tar.gz
Use pcap_findalldevs() when available instead of pcap_lookupdev()
This change is only used when using -F.
-rw-r--r--configure.ac2
-rw-r--r--src/unix.c47
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])
diff --git a/src/unix.c b/src/unix.c
index 9ce41a0..21137f6 100644
--- a/src/unix.c
+++ b/src/unix.c
@@ -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
}
/**