aboutsummaryrefslogtreecommitdiff
path: root/fad-getad.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2016-06-28 02:29:46 -0700
committerGuy Harris <guy@alum.mit.edu>2016-06-28 02:30:09 -0700
commit01dabcda25ed695976e5c844cdd7fc6875a17bf6 (patch)
tree1942c269617b36aa4dcb03ce42f4cf26da8e599c /fad-getad.c
parent71d90a93c5cb7f15e10254d6ee711f1f690b0a9c (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.c71
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,