diff options
author | Guy Harris <guy@alum.mit.edu> | 2016-06-28 02:29:46 -0700 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2016-06-28 02:30:09 -0700 |
commit | 01dabcda25ed695976e5c844cdd7fc6875a17bf6 (patch) | |
tree | 1942c269617b36aa4dcb03ce42f4cf26da8e599c /fad-getad.c | |
parent | 71d90a93c5cb7f15e10254d6ee711f1f690b0a9c (diff) |
Let the platform decide how to check capturable interfaces.
(Git's annoying policy of expecting a short one-line description of every
change means that the first line isn't very explanatory.)
Make pcap_findalldevs_interfaces() take as an argument a function that's
used to check whether an interface can be captured on or not, rather
than doing the check by trying to open the device for capturing.
This lets pcap_findalldevs() find interfaces even if you don't have
permission to capture on them; that way, instead of users saying "why
isn't {tcpdump -D, tshark -D, dumpcap -D, Wireshark, etc.} showing me
any interfaces?", they'll say "why am I getting a 'you don't have
permissions' error when I try to capture on this interface?", which is a
better description of the underlying problem.
On some platforms, it also avoids a bunch of extra work when getting a
list of interfaces.
Diffstat (limited to 'fad-getad.c')
-rw-r--r-- | fad-getad.c | 71 |
1 files changed, 41 insertions, 30 deletions
diff --git a/fad-getad.c b/fad-getad.c index ec77f334..b67b5cdc 100644 --- a/fad-getad.c +++ b/fad-getad.c @@ -144,7 +144,8 @@ get_sa_len(struct sockaddr *addr) * could be opened. */ int -pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf) +pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf, + int (*check_usable)(const char *)) { pcap_if_t *devlist = NULL; struct ifaddrs *ifap, *ifa; @@ -174,6 +175,45 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf) } for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) { /* + * If this entry has a colon followed by a number at + * the end, we assume it's a logical interface. Those + * are just the way you assign multiple IP addresses to + * a real interface on Linux, so an entry for a logical + * interface should be treated like the entry for the + * real interface; we do that by stripping off the ":" + * and the number. + * + * XXX - should we do this only on Linux? + */ + p = strchr(ifa->ifa_name, ':'); + if (p != NULL) { + /* + * We have a ":"; is it followed by a number? + */ + q = p + 1; + while (isdigit((unsigned char)*q)) + q++; + if (*q == '\0') { + /* + * All digits after the ":" until the end. + * Strip off the ":" and everything after + * it. + */ + *p = '\0'; + } + } + + /* + * Can we capture on this device? + */ + if (!(*check_usable)(ifa->ifa_name)) { + /* + * No. + */ + continue; + } + + /* * "ifa_addr" was apparently null on at least one * interface on some system. Therefore, we supply * the address and netmask only if "ifa_addr" is @@ -223,35 +263,6 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf) } /* - * If this entry has a colon followed by a number at - * the end, we assume it's a logical interface. Those - * are just the way you assign multiple IP addresses to - * a real interface on Linux, so an entry for a logical - * interface should be treated like the entry for the - * real interface; we do that by stripping off the ":" - * and the number. - * - * XXX - should we do this only on Linux? - */ - p = strchr(ifa->ifa_name, ':'); - if (p != NULL) { - /* - * We have a ":"; is it followed by a number? - */ - q = p + 1; - while (isdigit((unsigned char)*q)) - q++; - if (*q == '\0') { - /* - * All digits after the ":" until the end. - * Strip off the ":" and everything after - * it. - */ - *p = '\0'; - } - } - - /* * Add information for this address to the list. */ if (add_addr_to_iflist(&devlist, ifa->ifa_name, |