]> The Tcpdump Group git mirrors - libpcap/commitdiff
Have non-interface modules take responsibility for identifying their devices.
authorGuy Harris <[email protected]>
Mon, 11 Jun 2012 20:22:34 +0000 (13:22 -0700)
committerGuy Harris <[email protected]>
Mon, 11 Jun 2012 20:22:34 +0000 (13:22 -0700)
Have a table of routines to do pcap_create() for devices that aren't
regular network interfaces.  Try each of those in succession until one
says "it's mine" (whether it succeeds or fails); if none do, do a
pcap_create() for a regular interface.

Have those routines do more stringent tests of the name - don't just
accept any name that has a particular substring anywhere in it.  That
reduces the likelihood of a false match (as happened with the CANbus
module when somebody renamed their Ethernet interface "canopy").

Have the table also include routines for pcap_findalldevs().

33 files changed:
fad-getad.c
fad-gifc.c
fad-glifc.c
fad-sita.c
pcap-bpf.c
pcap-bt-linux.c
pcap-bt-linux.h
pcap-can-linux.c
pcap-can-linux.h
pcap-canusb-linux.c
pcap-canusb-linux.h
pcap-dag.c
pcap-dag.h
pcap-dlpi.c
pcap-int.h
pcap-libdlpi.c
pcap-linux.c
pcap-netfilter-linux.c
pcap-netfilter-linux.h
pcap-nit.c
pcap-null.c
pcap-pf.c
pcap-septel.c
pcap-septel.h
pcap-sita.c
pcap-snf.c
pcap-snf.h
pcap-snit.c
pcap-snoop.c
pcap-usb-linux.c
pcap-usb-linux.h
pcap-win32.c
pcap.c

index 742ae1facb17f0434911644b49a3584bae39068c..f4d5869c2db1611cd01fca41190902a545b2b696 100644 (file)
@@ -141,11 +141,9 @@ get_sa_len(struct sockaddr *addr)
  * Returns -1 on error, 0 otherwise.
  * The list, as returned through "alldevsp", may be null if no interfaces
  * were up and could be opened.
- *
- * This is the implementation used on platforms that have "getifaddrs()".
  */
 int
-pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
+pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
 {
        pcap_if_t *devlist = NULL;
        struct ifaddrs *ifap, *ifa;
@@ -273,15 +271,6 @@ pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
 
        freeifaddrs(ifap);
 
-       if (ret != -1) {
-               /*
-                * We haven't had any errors yet; do any platform-specific
-                * operations to add devices.
-                */
-               if (pcap_platform_finddevs(&devlist, errbuf) < 0)
-                       ret = -1;
-       }
-
        if (ret == -1) {
                /*
                 * We had an error; free the list we've been constructing.
index d0a2e99e0f84f88167b5e51e7915f0b3d17736a2..d453518fd1a2e1cb2d3257832e42a3da7be880b4 100644 (file)
@@ -133,10 +133,11 @@ struct rtentry;           /* declarations in <net/if.h> */
  *
  * XXX - or platforms that have other, better mechanisms but for which
  * we don't yet have code to use that mechanism; I think there's a better
- * way on Linux, for example.
+ * way on Linux, for example, but if that better way is "getifaddrs()",
+ * we already have that.
  */
 int
-pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
+pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
 {
        pcap_if_t *devlist = NULL;
        register int fd;
@@ -409,15 +410,6 @@ pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
        free(buf);
        (void)close(fd);
 
-       if (ret != -1) {
-               /*
-                * We haven't had any errors yet; do any platform-specific
-                * operations to add devices.
-                */
-               if (pcap_platform_finddevs(&devlist, errbuf) < 0)
-                       ret = -1;
-       }
-
        if (ret == -1) {
                /*
                 * We had an error; free the list we've been constructing.
index 664bb78aee646a70eed7b6286a383a0dab5a3ec3..b24b56441d0c90765774e6b8b8913aa8e9ef8ff5 100644 (file)
@@ -80,7 +80,7 @@ struct rtentry;               /* declarations in <net/if.h> */
  * SIOCGLIFCONF rather than SIOCGIFCONF in order to get IPv6 addresses.)
  */
 int
-pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
+pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
 {
        pcap_if_t *devlist = NULL;
        register int fd4, fd6, fd;
@@ -362,15 +362,6 @@ pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
        (void)close(fd6);
        (void)close(fd4);
 
-       if (ret != -1) {
-               /*
-                * We haven't had any errors yet; do any platform-specific
-                * operations to add devices.
-                */
-               if (pcap_platform_finddevs(&devlist, errbuf) < 0)
-                       ret = -1;
-       }
-
        if (ret == -1) {
                /*
                 * We had an error; free the list we've been constructing.
index 2619045679981c84bb21b37b3fea82a89ec75664..76dcb2e77fe5d87e35ca9c79681d832a1170d718 100644 (file)
@@ -37,7 +37,7 @@
 
 extern pcap_if_t       *acn_if_list;                                                           /* pcap's list of available interfaces */
 
-int pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) {
+int pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf) {
 
        //printf("pcap_findalldevs()\n");                               // fulko
 
index 944445f54c57a136344d67b3f4ece6165fadb7b3..3dd4234042fa4a4ec4b6ca16e4e39a715a90bd2e 100644 (file)
@@ -122,14 +122,6 @@ static int bpf_load(char *errbuf);
 
 #include "pcap-int.h"
 
-#ifdef HAVE_DAG_API
-#include "pcap-dag.h"
-#endif /* HAVE_DAG_API */
-
-#ifdef HAVE_SNF_API
-#include "pcap-snf.h"
-#endif /* HAVE_SNF_API */
-
 #ifdef HAVE_OS_PROTO_H
 #include "os-proto.h"
 #endif
@@ -407,19 +399,10 @@ pcap_ack_zbuf(pcap_t *p)
 #endif /* HAVE_ZEROCOPY_BPF */
 
 pcap_t *
-pcap_create(const char *device, char *ebuf)
+pcap_create_interface(const char *device, char *ebuf)
 {
        pcap_t *p;
 
-#ifdef HAVE_DAG_API
-       if (strstr(device, "dag"))
-               return (dag_create(device, ebuf));
-#endif /* HAVE_DAG_API */
-#ifdef HAVE_SNF_API
-       if (strstr(device, "snf"))
-               return (snf_create(device, ebuf));
-#endif /* HAVE_SNF_API */
-
        p = pcap_create_common(device, ebuf);
        if (p == NULL)
                return (NULL);
@@ -2283,15 +2266,6 @@ pcap_activate_bpf(pcap_t *p)
 int
 pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
 {
-#ifdef HAVE_DAG_API
-       if (dag_platform_finddevs(alldevsp, errbuf) < 0)
-               return (-1);
-#endif /* HAVE_DAG_API */
-#ifdef HAVE_SNF_API
-       if (snf_platform_finddevs(alldevsp, errbuf) < 0)
-               return (-1);
-#endif /* HAVE_SNF_API */
-
        return (0);
 }
 
index 0c6c08d199eb53cb06ca9984872adc401a3e6ad9..508710116e1e9ff7338576f57ba263fd8fa7bfb7 100644 (file)
@@ -71,7 +71,7 @@ static int bt_setdirection_linux(pcap_t *, pcap_direction_t);
 static int bt_stats_linux(pcap_t *, struct pcap_stat *);
 
 int 
-bt_platform_finddevs(pcap_if_t **alldevsp, char *err_str)
+bt_findalldevs(pcap_if_t **alldevsp, char *err_str)
 {
        pcap_if_t *found_dev = *alldevsp;
        struct hci_dev_list_req *dev_list;
@@ -135,10 +135,39 @@ done:
 }
 
 pcap_t *
-bt_create(const char *device, char *ebuf)
+bt_create(const char *device, char *ebuf, int *is_ours)
 {
+       char *cp, *cpend;
+       long devnum;
        pcap_t *p;
 
+       /* Does this look like a Bluetooth device? */
+       cp = strrchr(device, '/');
+       if (cp == NULL)
+               cp = device;
+       /* Does it begin with BT_IFACE? */
+       if (strncmp(cp, BT_IFACE, sizeof BT_IFACE - 1) != 0) {
+               /* Nope, doesn't begin with BT_IFACE */
+               *is_ours = 0;
+               return NULL;
+       }
+       /* Yes - is BT_IFACE followed by a number? */
+       cp += sizeof BT_IFACE - 1;
+       devnum = strtol(cp, &cpend, 10);
+       if (cpend == cp || *cpend != '\0') {
+               /* Not followed by a number. */
+               *is_ours = 0;
+               return NULL;
+       }
+       if (devnum < 0) {
+               /* Followed by a non-valid number. */
+               *is_ours = 0;
+               return NULL;
+       }
+
+       /* OK, it's probably ours. */
+       *is_ours = 1;
+
        p = pcap_create_common(device, ebuf);
        if (p == NULL)
                return (NULL);
index ed01190f87768817010b61400067f93a4933d6b7..fbe8f48706775df8e0b0b855fc164b11fb359208 100644 (file)
@@ -36,5 +36,5 @@
 /*
  * Prototypes for Bluetooth-related functions
  */
-int bt_platform_finddevs(pcap_if_t **alldevsp, char *err_str);
-pcap_t *bt_create(const char *device, char *ebuf);
+int bt_findalldevs(pcap_if_t **alldevsp, char *err_str);
+pcap_t *bt_create(const char *device, char *ebuf, int *is_ours);
index fb8e232c8973677d8a057713e596e7b3a3a5a885..1c5d95808d6729ab9abfd8fa410b306feb72b83b 100644 (file)
@@ -72,11 +72,57 @@ static int can_setfilter_linux(pcap_t *, struct bpf_program *);
 static int can_setdirection_linux(pcap_t *, pcap_direction_t);
 static int can_stats_linux(pcap_t *, struct pcap_stat *);
 
+int
+can_findalldevs(pcap_if_t **devlistp, char *errbuf)
+{
+       /*
+        * There are no platform-specific devices since each device
+        * exists as a regular network interface.
+        *
+        * XXX - true?
+        */
+       return 0;
+}
+
 pcap_t *
-can_create(const char *device, char *ebuf)
+can_create(const char *device, char *ebuf, int *is_ours)
 {
+       char *cp, *cpend;
+       long devnum;
        pcap_t* p;
 
+       /* Does this look like a CANbus device? */
+       cp = strrchr(device, '/');
+       if (cp == NULL)
+               cp = device;
+       /* Does it begin with "can" or "vcan"? */
+       if (strncmp(cp, "can", 3) == 0) {
+               /* Begins with "can" */
+               cp += 3;        /* skip past "can" */
+       } else if (strncmp(cp, "vcan", 4) == 0) {
+               /* Begins with "vcan" */
+               cp += 4;
+       } else {
+               /* Nope, doesn't begin with "can" or "vcan" */
+               *is_ours = 0;
+               return NULL;
+       }
+       /* Yes - is "can" or "vcan" followed by a number from 0? */
+       devnum = strtol(cp, &cpend, 10);
+       if (cpend == cp || *cpend != '\0') {
+               /* Not followed by a number. */
+               *is_ours = 0;
+               return NULL;
+       }
+       if (devnum < 0) {
+               /* Followed by a non-valid number. */
+               *is_ours = 0;
+               return NULL;
+       }
+
+       /* OK, it's probably ours. */
+       *is_ours = 1;
+
        p = pcap_create_common(device, ebuf);
        if (p == NULL)
                return (NULL);
index 0c8f3b5510908c58b01994d3b5d3f4492a1bd146..fe806ff93578302471124138389b7b2425182e25 100644 (file)
@@ -32,4 +32,5 @@
 /*
  * Prototypes for SocketCAN related functions
  */
-pcap_t* can_create(const char *device, char *ebuf);
+pcap_t* can_create(const char *device, char *ebuf, int *is_ours);
+int can_findalldevs(pcap_if_t **devlistp, char *errbuf);
index 5abfe18ec71f6ec673cd7802467a3259196fe5f2..f341cc3eb2a4e383dc050b2c4d040e4496de5a7f 100644 (file)
@@ -75,20 +75,17 @@ struct CAN_Msg
 
 struct canusb_t
 {
-  libusb_context *ctx;
-  libusb_device_handle *dev;
-  char* src;
-  pthread_t worker;
-  int rdpipe, wrpipe;
-  volatile int* loop;
+    libusb_context *ctx;
+    libusb_device_handle *dev;
+    pthread_t worker;
+    int rdpipe, wrpipe;
+    volatile int* loop;
 };
 
 static struct canusb_t canusb;
 static volatile int loop;
 
-
-
-int canusb_platform_finddevs(pcap_if_t **alldevsp, char *err_str)
+int canusb_findalldevs(pcap_if_t **alldevsp, char *err_str)
 {
     libusb_context *fdctx;
     libusb_device** devs;
@@ -108,27 +105,27 @@ int canusb_platform_finddevs(pcap_if_t **alldevsp, char *err_str)
         libusb_get_device_descriptor(devs[i],&desc);
 
         if ((desc.idVendor != CANUSB_VID) || (desc.idProduct != CANUSB_PID)) 
-          continue; //It is not, check next device
+            continue; //It is not, check next device
           
         //It is!
         libusb_device_handle *dh = NULL;
 
         if (ret = libusb_open(devs[i],&dh) == 0)
         {
-               char dev_name[30];
-                 char dev_descr[50]; 
+            char dev_name[30];
+            char dev_descr[50]; 
             int n = libusb_get_string_descriptor_ascii(dh,desc.iSerialNumber,sernum,64);
             sernum[n] = 0;
 
-               snprintf(dev_name, 30, CANUSB_IFACE"%s", sernum);
-               snprintf(dev_descr, 50, "CanUSB [%s]", sernum);
+            snprintf(dev_name, 30, CANUSB_IFACE"%s", sernum);
+            snprintf(dev_descr, 50, "CanUSB [%s]", sernum);
             
             libusb_close(dh);
             
             if (pcap_add_if(alldevsp, dev_name, 0, dev_descr, err_str) < 0)
             {
-              libusb_free_device_list(devs,1);
-              return -1;
+                libusb_free_device_list(devs,1);
+                return -1;
             }
         }
     }
@@ -199,23 +196,50 @@ static libusb_device_handle* canusb_opendevice(struct libusb_context *ctx, char*
 
 
 pcap_t *
-canusb_create(const char *device, char *ebuf)
+canusb_create(const char *device, char *ebuf, int *is_ours)
 { 
-  pcap_t* p;
+    char *cp, *cpend;
+    long devnum;
+    pcap_t* p;
                
-  libusb_init(&canusb.ctx);
-  
-       p = pcap_create_common(device, ebuf);
-       if (p == NULL)
-               return (NULL);
-               
-  memset(&canusb, 0x00, sizeof(canusb));
+    libusb_init(&canusb.ctx);
+
+    /* Does this look like a DAG device? */
+    cp = strrchr(device, '/');
+    if (cp == NULL)
+        cp = device;
+    /* Does it begin with "canusb"? */
+    if (strncmp(cp, "canusb", 6) != 0) {
+        /* Nope, doesn't begin with "canusb" */
+        *is_ours = 0;
+        return NULL;
+    }
+    /* Yes - is "canusb" followed by a number? */
+    cp += 6;
+    devnum = strtol(cp, &cpend, 10);
+    if (cpend == cp || *cpend != '\0') {
+        /* Not followed by a number. */
+        *is_ours = 0;
+        return NULL;
+    }
+    if (devnum < 0) {
+        /* Followed by a non-valid number. */
+        *is_ours = 0;
+        return NULL;
+    }
+
+    /* OK, it's probably ours. */
+    *is_ours = 1;
+
+    p = pcap_create_common(device, ebuf);
+    if (p == NULL)
+        return (NULL);
+
+    memset(&canusb, 0x00, sizeof(canusb));
                
+    p->activate_op = canusb_activate;
        
-       p->activate_op = canusb_activate;
-       
-       canusb.src = strdup(p->opt.source);
-       return (p);
+    return (p);
 }
 
 
index f03053acbed32533f00f24d573e7996ae803bf28..a87b293c43fe8825c8aaa24511131eb85c2b5e6a 100644 (file)
@@ -32,6 +32,6 @@
 /*
  * Prototypes for SocketCAN related functions
  */
-pcap_t* canusb_create(const char *device, char *ebuf);
-int canusb_listdevices(pcap_if_t **pdevlist, char* errbuf);
+pcap_t* canusb_create(const char *device, char *ebuf, int *is_ours);
+int canusb_findalldevspcap_if_t **pdevlist, char* errbuf);
 
index b5de0691b95a448993f36b12913abbf987ef8adf..e38bdd784ef7c515cdee19e40d72f9a17c1e1012 100644 (file)
@@ -48,6 +48,12 @@ struct rtentry;              /* declarations in <net/if.h> */
 
 #include "pcap-dag.h"
 
+/*
+ * DAG devices have names beginning with "dag", followed by a number
+ * from 0 to MAXDAG.
+ */
+#define MAXDAG 31
+
 #define ATM_CELL_SIZE          52
 #define ATM_HDR_SIZE           4
 
@@ -82,15 +88,6 @@ static const unsigned short endian_test_word = 0x0100;
 
 #define IS_BIGENDIAN() (*((unsigned char *)&endian_test_word))
 
-
-#ifdef DAG_ONLY
-/* This code is required when compiling for a DAG device only. */
-
-/* Replace dag function names with pcap equivalent. */
-#define dag_create pcap_create
-#define dag_platform_finddevs pcap_platform_finddevs
-#endif /* DAG_ONLY */
-
 #define MAX_DAG_PACKET 65536
 
 static unsigned char TempPkt[MAX_DAG_PACKET];
@@ -835,10 +832,39 @@ fail:
        return PCAP_ERROR;
 }
 
-pcap_t *dag_create(const char *device, char *ebuf)
+pcap_t *dag_create(const char *device, char *ebuf, int *is_ours)
 {
+       char *cp, *cpend;
+       long devnum;
        pcap_t *p;
 
+       /* Does this look like a DAG device? */
+       cp = strrchr(device, '/');
+       if (cp == NULL)
+               cp = device;
+       /* Does it begin with "dag"? */
+       if (strncmp(cp, "dag", 3) != 0) {
+               /* Nope, doesn't begin with "dag" */
+               *is_ours = 0;
+               return NULL;
+       }
+       /* Yes - is "dag" followed by a number from 0 to MAXDAG? */
+       cp += 3;
+       devnum = strtol(cp, &cpend, 10);
+       if (cpend == cp || *cpend != '\0') {
+               /* Not followed by a number. */
+               *is_ours = 0;
+               return NULL;
+       }
+       if (devnum < 0 || devnum > MAXDAG) {
+               /* Followed by a non-valid number. */
+               *is_ours = 0;
+               return NULL;
+       }
+
+       /* OK, it's probably ours. */
+       *is_ours = 1;
+
        p = pcap_create_common(device, ebuf);
        if (p == NULL)
                return NULL;
@@ -870,7 +896,7 @@ dag_stats(pcap_t *p, struct pcap_stat *ps) {
  * open attempts will still be much less than the naive approach.
  */
 int
-dag_platform_finddevs(pcap_if_t **devlistp, char *errbuf)
+dag_findalldevs(pcap_if_t **devlistp, char *errbuf)
 {
        char name[12];  /* XXX - pick a size */
        int ret = 0;
@@ -879,8 +905,8 @@ dag_platform_finddevs(pcap_if_t **devlistp, char *errbuf)
        int dagstream;
        int dagfd;
 
-       /* Try all the DAGs 0-31 */
-       for (c = 0; c < 32; c++) {
+       /* Try all the DAGs 0-MAXDAG */
+       for (c = 0; c <= MAXDAG; c++) {
                snprintf(name, 12, "dag%d", c);
                if (-1 == dag_parse_name(name, dagname, DAGNAME_BUFSIZE, &dagstream))
                {
index fcdef7bda856cbb35242d884332dda00889155c9..47511866e41264a2995f48e2b67717319ddafbe9 100644 (file)
@@ -10,8 +10,8 @@
  * @(#) $Header: /tcpdump/master/libpcap/pcap-dag.h,v 1.7 2008-04-04 19:37:45 guy Exp $ (LBL)
  */
 
-pcap_t *dag_create(const char *, char *);
-int dag_platform_finddevs(pcap_if_t **devlistp, char *errbuf);
+pcap_t *dag_create(const char *, char *, int *);
+int dag_findalldevs(pcap_if_t **devlistp, char *errbuf);
 
 #ifndef TYPE_AAL5
 #define TYPE_AAL5               4
index 78bb45118330d8486d4907477c53c0608fb1ceac..4b285f39d156c5304bbd562450554c7ce97373b0 100644 (file)
@@ -1693,7 +1693,7 @@ dlpi_kread(register int fd, register off_t addr,
 #endif
 
 pcap_t *
-pcap_create(const char *device, char *ebuf)
+pcap_create_interface(const char *device, char *ebuf)
 {
        pcap_t *p;
 
index 8444e62cee846ea087fd789d7b7e4cf1a95d52eb..4a73ac77fb82eefc4f160bac5427d7f14e27a371 100644 (file)
@@ -454,6 +454,18 @@ int        pcap_getnonblock_fd(pcap_t *, char *);
 int    pcap_setnonblock_fd(pcap_t *p, int, char *);
 #endif
 
+/*
+ * Internal interfaces for "pcap_create()".
+ *
+ * "pcap_create_interface()" is the routine to do a pcap_create on
+ * a regular network interface.  There are multiple implementations
+ * of this, one for each platform type (Linux, BPF, DLPI, etc.),
+ * with the one used chosen by the configure script.
+ *
+ * "pcap_create_common()" allocates and fills in a pcap_t, for use
+ * by pcap_create routines.
+ */
+pcap_t *pcap_create_interface(const char *, char *);
 pcap_t *pcap_create_common(const char *, char *);
 int    pcap_do_addexit(pcap_t *);
 void   pcap_add_to_pcaps_to_close(pcap_t *);
@@ -465,12 +477,16 @@ int       pcap_check_activated(pcap_t *);
 /*
  * Internal interfaces for "pcap_findalldevs()".
  *
+ * "pcap_findalldevs_interfaces()" finds interfaces using the
+ * "standard" mechanisms (SIOCGIFCONF, "getifaddrs()", etc.).
+ *
  * "pcap_platform_finddevs()" is a platform-dependent routine to
- * add devices not found by the "standard" mechanisms (SIOCGIFCONF,
- * "getifaddrs()", etc..
+ * add devices not found by the "standard" mechanisms.
  *
- * "pcap_add_if()" adds an interface to the list of interfaces.
+ * "pcap_add_if()" adds an interface to the list of interfaces, for
+ * use by various "find interfaces" routines.
  */
+int    pcap_findalldevs_interfaces(pcap_if_t **, char *);
 int    pcap_platform_finddevs(pcap_if_t **, char *);
 int    add_addr_to_iflist(pcap_if_t **, const char *, u_int, struct sockaddr *,
            size_t, struct sockaddr *, size_t, struct sockaddr *, size_t,
index 8d6a0386e012f3b1f871663e0d8f75f8afadd796..e3aa7796dd0a67aebffbd6c478b83a70cc106cb4 100644 (file)
@@ -391,7 +391,7 @@ pcap_libdlpi_err(const char *linkname, const char *func, int err, char *errbuf)
 }
 
 pcap_t *
-pcap_create(const char *device, char *ebuf)
+pcap_create_interface(const char *device, char *ebuf)
 {
        pcap_t *p;
 
index 8168e474778d9e9a7dc8d62216e69cf418c657ec..fb24dadf98d02967b9df1fc87b2c7dd629f95047 100644 (file)
@@ -142,38 +142,6 @@ static const char rcsid[] _U_ =
 #include "pcap/sll.h"
 #include "pcap/vlan.h"
 
-#ifdef HAVE_DAG_API
-#include "pcap-dag.h"
-#endif /* HAVE_DAG_API */
-
-#ifdef HAVE_SEPTEL_API
-#include "pcap-septel.h"
-#endif /* HAVE_SEPTEL_API */
-
-#ifdef HAVE_SNF_API
-#include "pcap-snf.h"
-#endif /* HAVE_SNF_API */
-
-#ifdef PCAP_SUPPORT_USB
-#include "pcap-usb-linux.h"
-#endif
-
-#ifdef PCAP_SUPPORT_BT
-#include "pcap-bt-linux.h"
-#endif
-
-#ifdef PCAP_SUPPORT_CAN
-#include "pcap-can-linux.h"
-#endif
-
-#if PCAP_SUPPORT_CANUSB
-#include "pcap-canusb-linux.h"
-#endif
-
-#ifdef PCAP_SUPPORT_NETFILTER
-#include "pcap-netfilter-linux.h"
-#endif
-
 /*
  * If PF_PACKET is defined, we can use {SOCK_RAW,SOCK_DGRAM}/PF_PACKET
  * sockets rather than SOCK_PACKET sockets.
@@ -387,66 +355,10 @@ static struct sock_fprog  total_fcode
 #endif /* SO_ATTACH_FILTER */
 
 pcap_t *
-pcap_create(const char *device, char *ebuf)
+pcap_create_interface(const char *device, char *ebuf)
 {
        pcap_t *handle;
 
-       /*
-        * A null device name is equivalent to the "any" device.
-        */
-       if (device == NULL)
-               device = "any";
-
-#ifdef HAVE_DAG_API
-       if (strstr(device, "dag")) {
-               return dag_create(device, ebuf);
-       }
-#endif /* HAVE_DAG_API */
-
-#ifdef HAVE_SEPTEL_API
-       if (strstr(device, "septel")) {
-               return septel_create(device, ebuf);
-       }
-#endif /* HAVE_SEPTEL_API */
-
-#ifdef HAVE_SNF_API
-        handle = snf_create(device, ebuf);
-        if (strstr(device, "snf") || handle != NULL)
-               return handle;
-
-#endif /* HAVE_SNF_API */
-
-#ifdef PCAP_SUPPORT_BT
-       if (strstr(device, "bluetooth")) {
-               return bt_create(device, ebuf);
-       }
-#endif
-
-#if PCAP_SUPPORT_CANUSB
-  if (strstr(device, "canusb")) {
-    return canusb_create(device, ebuf);
-  }
-#endif
-
-#ifdef PCAP_SUPPORT_CAN
-       if ((strncmp(device, "can", 3) == 0 && isdigit(device[3])) ||
-           (strncmp(device, "vcan", 4) == 0 && isdigit(device[4]))) {
-               return can_create(device, ebuf);
-       }
-#endif
-
-#ifdef PCAP_SUPPORT_USB
-       if (strstr(device, "usbmon")) {
-               return usb_create(device, ebuf);
-       }
-#endif
-
-#ifdef PCAP_SUPPORT_NETFILTER
-       if (strncmp(device, "nflog", strlen("nflog")) == 0) {
-               return nflog_create(device, ebuf);
-       }
-#endif
-
        handle = pcap_create_common(device, ebuf);
        if (handle == NULL)
                return NULL;
@@ -2265,56 +2177,6 @@ pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
        if (pcap_add_if(alldevsp, "any", 0, any_descr, errbuf) < 0)
                return (-1);
 
-#ifdef HAVE_DAG_API
-       /*
-        * Add DAG devices.
-        */
-       if (dag_platform_finddevs(alldevsp, errbuf) < 0)
-               return (-1);
-#endif /* HAVE_DAG_API */
-
-#ifdef HAVE_SEPTEL_API
-       /*
-        * Add Septel devices.
-        */
-       if (septel_platform_finddevs(alldevsp, errbuf) < 0)
-               return (-1);
-#endif /* HAVE_SEPTEL_API */
-
-#ifdef HAVE_SNF_API
-       if (snf_platform_finddevs(alldevsp, errbuf) < 0)
-               return (-1);
-#endif /* HAVE_SNF_API */
-
-#ifdef PCAP_SUPPORT_BT
-       /*
-        * Add Bluetooth devices.
-        */
-       if (bt_platform_finddevs(alldevsp, errbuf) < 0)
-               return (-1);
-#endif
-
-#ifdef PCAP_SUPPORT_USB
-       /*
-        * Add USB devices.
-        */
-       if (usb_platform_finddevs(alldevsp, errbuf) < 0)
-               return (-1);
-#endif
-
-#ifdef PCAP_SUPPORT_NETFILTER
-       /*
-        * Add netfilter devices.
-        */
-       if (netfilter_platform_finddevs(alldevsp, errbuf) < 0)
-               return (-1);
-#endif
-
-#if PCAP_SUPPORT_CANUSB
-  if (canusb_platform_finddevs(alldevsp, errbuf) < 0)
-    return (-1);
-#endif
-
        return (0);
 }
 
index f9c6beff6e820bf59d609fc36eae63a8bf270084..56e5435b927f35eeeadef58ab2ce3e6365ee396b 100644 (file)
@@ -434,8 +434,33 @@ close_fail:
 pcap_t *
 nflog_create(const char *device, char *ebuf)
 {
+       char *cp;
        pcap_t *p;
 
+       /* Does this look like an nflog device? */
+       cp = strrchr(device, '/');
+       if (cp == NULL)
+               cp = device;
+       /* Does it begin with NFLOG_IFACE? */
+       if (strncmp(cp, NFLOG_IFACE, sizeof NFLOG_IFACE - 1) != 0) {
+               /* Nope, doesn't begin with NFLOG_IFACE */
+               *is_ours = 0;
+               return NULL;
+       }
+       /*
+        * Yes - is that either the end of the name, or is it followed
+        * by a colon?
+        */
+       cp += sizeof NFLOG_IFACE - 1;
+       if (*cp != ':' && *cp != '\0') {
+               /* Nope */
+               *is_ours = 0;
+               return NULL;
+       }
+
+       /* OK, it's probably ours. */
+       *is_ours = 1;
+
        p = pcap_create_common(device, ebuf);
        if (p == NULL)
                return (NULL);
@@ -445,7 +470,7 @@ nflog_create(const char *device, char *ebuf)
 }
 
 int 
-netfilter_platform_finddevs(pcap_if_t **alldevsp, char *err_str)
+nflog_findalldevs(pcap_if_t **alldevsp, char *err_str)
 {
        pcap_if_t *found_dev = *alldevsp;
        int sock;
@@ -465,4 +490,3 @@ netfilter_platform_finddevs(pcap_if_t **alldevsp, char *err_str)
                return -1;
        return 0;
 }
-
index dd76b8a4350cfefa3fccdd80ce6fd31eac126ae4..e16e0ec67f48edfeceb1db3bc2422b46e2e409f7 100644 (file)
@@ -31,5 +31,5 @@
 /*
  * Prototypes for netlink-related functions
  */
-int netfilter_platform_finddevs(pcap_if_t **alldevsp, char *err_str);
-pcap_t *nflog_create(const char *device, char *ebuf);
+int nflog_findalldevs(pcap_if_t **alldevsp, char *err_str);
+pcap_t *nflog_create(const char *device, char *ebuf, int *is_ours);
index b799549e4eda39eb8e4e349c561d43015873e04c..85b32f2a9d752652972d1ffb97526e4b4c5d025b 100644 (file)
@@ -328,7 +328,7 @@ pcap_activate_nit(pcap_t *p)
 }
 
 pcap_t *
-pcap_create(const char *device, char *ebuf)
+pcap_create_interface(const char *device, char *ebuf)
 {
        pcap_t *p;
 
index 2d271eb423bcc47dc2d8269888abab0cbc521564..6737386851d6f15b38793b1905459d7c138664b2 100644 (file)
@@ -40,7 +40,7 @@ static const char rcsid[] _U_ =
 static char nosup[] = "live packet capture not supported on this system";
 
 pcap_t *
-pcap_create(const char *device, char *ebuf)
+pcap_create_interface(const char *device, char *ebuf)
 {
        (void)strlcpy(ebuf, nosup, PCAP_ERRBUF_SIZE);
        return (NULL);
index d8326df9ae984821c480870fedcfaa96f1ceaff4..84c6d54784954cdcdfcce0eda9a0a9f3b184c8a5 100644 (file)
--- a/pcap-pf.c
+++ b/pcap-pf.c
@@ -499,7 +499,7 @@ your system may not be properly configured; see the packetfilter(4) man page\n",
 }
 
 pcap_t *
-pcap_create(const char *device, char *ebuf)
+pcap_create_interface(const char *device, char *ebuf)
 {
        pcap_t *p;
 
index 8cc2403ac7fffadaec3735f27ee86698a9295d58..a02efca3a262c6415cdef0d7c710005b704d7178 100644 (file)
@@ -38,23 +38,14 @@ static const char rcsid[] _U_ =
 #include <sys/types.h>
 #include <unistd.h>
 
-#ifdef HAVE_SEPTEL_API
 #include <msg.h>
 #include <ss7_inc.h>
 #include <sysgct.h>
 #include <pack.h>
 #include <system.h>
-#endif /* HAVE_SEPTEL_API */
 
-#ifdef SEPTEL_ONLY
-/* This code is required when compiling for a Septel device only. */
 #include "pcap-septel.h"
 
-/* Replace septel function names with pcap equivalent. */
-#define septel_create pcap_create
-#define septel_platform_finddevs pcap_platform_finddevs
-#endif /* SEPTEL_ONLY */
-
 static int septel_setfilter(pcap_t *p, struct bpf_program *fp);
 static int septel_stats(pcap_t *p, struct pcap_stat *ps);
 static int septel_setnonblock(pcap_t *p, int nonblock, char *errbuf);
@@ -221,9 +212,23 @@ static pcap_t *septel_activate(pcap_t* handle) {
   return 0;
 }
 
-pcap_t *septel_create(const char *device, char *ebuf) {
+pcap_t *septel_create(const char *device, char *ebuf, int *is_ours) {
+       char *cp;
        pcap_t *p;
 
+       /* Does this look like the Septel device? */
+       cp = strrchr(device, '/');
+       if (cp == NULL)
+               cp = device;
+       if (strcmp(cp, "septel") != 0) {
+               /* Nope, it's not "septel" */
+               *is_ours = 0;
+               return NULL;
+       }
+
+       /* OK, it's probably ours. */
+       *is_ours = 1;
+
        p = pcap_create_common(device, ebuf);
        if (p == NULL)
                return NULL;
@@ -243,7 +248,7 @@ static int septel_stats(pcap_t *p, struct pcap_stat *ps) {
 
 
 int
-septel_platform_finddevs(pcap_if_t **devlistp, char *errbuf)
+septel_findalldevs(pcap_if_t **devlistp, char *errbuf)
 {
 unsigned char *p;
   const char description[512]= "Intel/Septel device";
index 227d05685fc107d9331980e70da16940cb79cd94..b72f35bc4c743cbbd673d79a58c5916ae9a06fb9 100644 (file)
@@ -11,5 +11,5 @@
  * @(#) $Header: /tcpdump/master/libpcap/pcap-septel.h,v 1.2 2008-04-04 19:37:45 guy Exp $
  */
 
-pcap_t *septel_create(const char *device, char *ebuf);
-
+pcap_t *septel_create(const char *device, char *ebuf, int *is_ours);
+int septel_findalldevs(pcap_if_t **devlistp, char *errbuf);
index 971f8b03af76ea0eebc6cbf19293d9924c00f2d3..4379f2cf77420c037276257a7dbc4ce5fdfb3177 100644 (file)
@@ -776,7 +776,7 @@ static int acn_open_live(const char *name, char *errbuf, int *linktype) {           /* re
        iface_t         *p;
        pcap_if_t       *alldevsp;
 
-       pcap_findalldevs(&alldevsp, errbuf);
+       pcap_findalldevs_interfaces(&alldevsp, errbuf);
        for (chassis = 0; chassis <= MAX_CHASSIS; chassis++) {                                                                          /* scan the table... */
                for (geoslot = 0; geoslot <= MAX_GEOSLOT; geoslot++) {
                        u = &units[chassis][geoslot];
@@ -968,7 +968,7 @@ static int pcap_activate_sita(pcap_t *handle) {
        return 0;
 }
 
-pcap_t *pcap_create(const char *device, char *ebuf) {
+pcap_t *pcap_create_interface(const char *device, char *ebuf) {
        pcap_t *p;
 
        p = pcap_create_common(device, ebuf);
index 96781bd713ba6165afd560878ece23dd97376722..396f3e5b058710b83e434bcfd3ba2f31fc2ae8be 100644 (file)
 #include "snf.h"
 #include "pcap-int.h"
 
-#ifdef SNF_ONLY
-#define snf_create pcap_create
-#define snf_platform_finddevs pcap_platform_finddevs
-#endif
-
 static int
 snf_set_datalink(pcap_t *p, int dlt)
 {
@@ -249,7 +244,7 @@ snf_activate(pcap_t* p)
 }
 
 int
-snf_platform_finddevs(pcap_if_t **devlistp, char *errbuf)
+snf_findalldevs(pcap_if_t **devlistp, char *errbuf)
 {
        /*
         * There are no platform-specific devices since each device
@@ -259,22 +254,28 @@ snf_platform_finddevs(pcap_if_t **devlistp, char *errbuf)
 }
 
 pcap_t *
-snf_create(const char *device, char *ebuf)
+snf_create(const char *device, char *ebuf, int *is_ours)
 {
        pcap_t *p;
        int boardnum = -1;
        struct snf_ifaddrs *ifaddrs, *ifa;
        size_t devlen;
 
-       if (snf_init(SNF_VERSION_API))
+       if (snf_init(SNF_VERSION_API)) {
+               /* Can't initialize the API, so no SNF devices */
+               *is_ours = 0;
                return NULL;
+       }
 
        /*
         * Match a given interface name to our list of interface names, from
         * which we can obtain the intended board number
         */
-       if (snf_getifaddrs(&ifaddrs) || ifaddrs == NULL)
+       if (snf_getifaddrs(&ifaddrs) || ifaddrs == NULL) {
+               /* Can't get SNF addresses */
+               *is_ours = 0;
                return NULL;
+       }
        devlen = strlen(device) + 1;
        ifa = ifaddrs;
        while (ifa) {
@@ -292,10 +293,16 @@ snf_create(const char *device, char *ebuf)
                 * and "snf10gX" where X is the board number.
                 */
                if (sscanf(device, "snf10g%d", &boardnum) != 1 &&
-                   sscanf(device, "snf%d", &boardnum) != 1)
+                   sscanf(device, "snf%d", &boardnum) != 1) {
+                       /* Nope, not a supported name */
+                       *is_ours = 0;
                        return NULL;
+                   }
        }
 
+       /* OK, it's probably ours. */
+       *is_ours = 1;
+
        p = pcap_create_common(device, ebuf);
        if (p == NULL)
                return NULL;
index 8c197551a2812653e2ce2f238158935642ea945f..c9d7722bf4fc87ba38a766603a1a8a585586c2c4 100644 (file)
@@ -1,2 +1,2 @@
-pcap_t *snf_create(const char *, char *);
-int snf_platform_finddevs(pcap_if_t **devlistp, char *errbuf);
+pcap_t *snf_create(const char *, char *, int *);
+int snf_findalldevs(pcap_if_t **devlistp, char *errbuf);
index fa0c4ef259331444390b25a89e7cc3fc28f37be4..b22b737f8dbfef419415c96869c04cec10f816d7 100644 (file)
@@ -407,7 +407,7 @@ pcap_activate_snit(pcap_t *p)
 }
 
 pcap_t *
-pcap_create(const char *device, char *ebuf)
+pcap_create_interface(const char *device, char *ebuf)
 {
        pcap_t *p;
 
index 330e01d3a92e45f9f4168714b0662ce7519451b0..9314b8ce74bce5c80b3c5415bcbd4dc23320a903 100644 (file)
@@ -394,7 +394,7 @@ pcap_activate_snoop(pcap_t *p)
 }
 
 pcap_t *
-pcap_create(const char *device, char *ebuf)
+pcap_create_interface(const char *device, char *ebuf)
 {
        pcap_t *p;
 
index f1b430c7bda936f1eb327f62b0319899a7ea155a..263c25db400b8d0ed3d92d2853a5d84e68838f8b 100644 (file)
@@ -148,7 +148,7 @@ usb_dev_add(pcap_if_t** alldevsp, int n, char *err_str)
 }
 
 int 
-usb_platform_finddevs(pcap_if_t **alldevsp, char *err_str)
+usb_findalldevs(pcap_if_t **alldevsp, char *err_str)
 {
        struct dirent* data;
        int ret = 0;
@@ -284,10 +284,39 @@ probe_devices(int bus)
 }
 
 pcap_t *
-usb_create(const char *device, char *ebuf)
+usb_create(const char *device, char *ebuf, int *is_ours)
 {
+       char *cp, *cpend;
+       long devnum;
        pcap_t *p;
 
+       /* Does this look like a USB monitoring device? */
+       cp = strrchr(device, '/');
+       if (cp == NULL)
+               cp = device;
+       /* Does it begin with USB_IFACE? */
+       if (strncmp(cp, USB_IFACE, sizeof USB_IFACE - 1) != 0) {
+               /* Nope, doesn't begin with USB_IFACE */
+               *is_ours = 0;
+               return NULL;
+       }
+       /* Yes - is USB_IFACE followed by a number? */
+       cp += sizeof USB_IFACE - 1;
+       devnum = strtol(cp, &cpend, 10);
+       if (cpend == cp || *cpend != '\0') {
+               /* Not followed by a number. */
+               *is_ours = 0;
+               return NULL;
+       }
+       if (devnum < 0) {
+               /* Followed by a non-valid number. */
+               *is_ours = 0;
+               return NULL;
+       }
+
+       /* OK, it's probably ours. */
+       *is_ours = 1;
+
        p = pcap_create_common(device, ebuf);
        if (p == NULL)
                return (NULL);
index 2d9638c544c4967f49d905ad5bfde22224d355af..d64386dbb53c77040e5abad12306e7c7a9208cb3 100644 (file)
@@ -36,5 +36,5 @@
 /*
  * Prototypes for USB-related functions
  */
-int usb_platform_finddevs(pcap_if_t **alldevsp, char *err_str);
-pcap_t *usb_create(const char *device, char *ebuf);
+int usb_findalldevs(pcap_if_t **alldevsp, char *err_str);
+pcap_t *usb_create(const char *device, char *ebuf, int *is_ours);
index d8ed453510d99c46af5343a61057bc838cda0082..19b3e876e78b69f578178b1a0f989311bdff5383 100644 (file)
@@ -715,7 +715,7 @@ bad:
 }
 
 pcap_t *
-pcap_create(const char *device, char *ebuf)
+pcap_create_interface(const char *device, char *ebuf)
 {
        pcap_t *p;
 
diff --git a/pcap.c b/pcap.c
index cfdd83fec6d82fb7ac20f218c7b35defcb6de95a..8560c5fd5a70f274e51c04ce29aa851cddfa942a 100644 (file)
--- a/pcap.c
+++ b/pcap.c
@@ -74,8 +74,35 @@ static const char rcsid[] _U_ =
 #include "pcap-int.h"
 
 #ifdef HAVE_DAG_API
-#include <dagnew.h>
-#include <dagapi.h>
+#include "pcap-dag.h"
+#endif /* HAVE_DAG_API */
+
+#ifdef HAVE_SEPTEL_API
+#include "pcap-septel.h"
+#endif /* HAVE_SEPTEL_API */
+
+#ifdef HAVE_SNF_API
+#include "pcap-snf.h"
+#endif /* HAVE_SNF_API */
+
+#ifdef PCAP_SUPPORT_USB
+#include "pcap-usb-linux.h"
+#endif
+
+#ifdef PCAP_SUPPORT_BT
+#include "pcap-bt-linux.h"
+#endif
+
+#ifdef PCAP_SUPPORT_CAN
+#include "pcap-can-linux.h"
+#endif
+
+#ifdef PCAP_SUPPORT_CANUSB
+#include "pcap-canusb-linux.h"
+#endif
+
+#ifdef PCAP_SUPPORT_NETFILTER
+#include "pcap-netfilter-linux.h"
 #endif
 
 int 
@@ -232,6 +259,174 @@ pcap_next_ex(pcap_t *p, struct pcap_pkthdr **pkt_header,
        return (p->read_op(p, 1, p->oneshot_callback, (u_char *)&s));
 }
 
+#if defined(DAG_ONLY)
+int
+pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
+{
+       return (dag_findalldevs(alldevsp, errbuf));
+}
+
+pcap_t *
+pcap_create(const char *source, char *errbuf)
+{
+       return (dag_create(source, errbuf));
+}
+#elif defined(SEPTEL_ONLY)
+int
+pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
+{
+       return (septel_findalldevs(alldevsp, errbuf));
+}
+
+pcap_t *
+pcap_create(const char *source, char *errbuf)
+{
+       return (septel_create(source, errbuf));
+}
+#elif defined(SNF_ONLY)
+int
+pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
+{
+       return (snf_findalldevs(alldevsp, errbuf));
+}
+
+pcap_t *
+pcap_create(const char *source, char *errbuf)
+{
+       return (snf_create(source, errbuf));
+}
+#else /* regular pcap */
+struct capture_source_type {
+       int (*findalldevs_op)(pcap_if_t **, char *);
+       pcap_t *(*create_op)(const char *, char *, int *);
+} capture_source_types[] = {
+#ifdef HAVE_DAG_API
+       { dag_findalldevs, dag_create },
+#endif
+#ifdef HAVE_SEPTEL_API
+       { septel_findalldevs, septel_create },
+#endif
+#ifdef HAVE_SNF_API
+       { snf_findalldevs, snf_create },
+#endif
+#ifdef PCAP_SUPPORT_BT
+       { bt_findalldevs, bt_create },
+#endif
+#if PCAP_SUPPORT_CANUSB
+       { canusb_findalldevs, canusb_create },
+#endif
+#ifdef PCAP_SUPPORT_CAN
+       { can_findalldevs, can_create },
+#endif
+#ifdef PCAP_SUPPORT_USB
+       { usb_findalldevs, usb_create },
+#endif
+#ifdef PCAP_SUPPORT_NETFILTER
+       { nflog_findalldevs, nflog_create },
+#endif
+};
+
+#define N_CAPTURE_SOURCE_TYPES (sizeof capture_source_types / sizeof capture_source_types[0])
+
+/*
+ * Get a list of all capture sources that are up and that we can open.
+ * Returns -1 on error, 0 otherwise.
+ * The list, as returned through "alldevsp", may be null if no interfaces
+ * were up and could be opened.
+ */
+int
+pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
+{
+       size_t i;
+
+       /*
+        * Get the list of regular interfaces first.
+        */ 
+       if (pcap_findalldevs_interfaces(alldevsp, errbuf) == -1)
+               return (-1);    /* failure */
+
+       /*
+        * Add any interfaces that need a platform-specific mechanism
+        * to find.
+        */
+       if (pcap_platform_finddevs(alldevsp, errbuf) == -1) {
+               /*
+                * We had an error; free the list we've been
+                * constructing.
+                */
+               if (*alldevsp != NULL) {
+                       pcap_freealldevs(*alldevsp);
+                       *alldevsp = NULL;
+               }
+               return (-1);
+       }
+
+       /*
+        * Ask each of the non-local-network-interface capture
+        * source types what interfaces they have.
+        */
+       for (i = 0; i < N_CAPTURE_SOURCE_TYPES; i++) {
+               if (capture_source_types[i].findalldevs_op(alldevsp, errbuf) == -1) {
+                       /*
+                        * We had an error; free the list we've been
+                        * constructing.
+                        */
+                       if (*alldevsp != NULL) {
+                               pcap_freealldevs(*alldevsp);
+                               *alldevsp = NULL;
+                       }
+                       return (-1);
+               }
+       }
+       return (0);
+}
+
+pcap_t *
+pcap_create(const char *source, char *errbuf)
+{
+       size_t i;
+       int is_theirs;
+       pcap_t *p;
+
+       /*
+        * A null source name is equivalent to the "any" device -
+        * which might not be supported on this platform, but
+        * this means that you'll get a "not supported" error
+        * rather than, say, a crash when we try to dereference
+        * the null pointer.
+        */
+       if (source == NULL)
+               source = "any";
+
+       /*
+        * Try each of the non-local-network-interface capture
+        * source types until we find one that works for this
+        * device or run out of types.
+        */
+       for (i = 0; i < N_CAPTURE_SOURCE_TYPES; i++) {
+               is_theirs = 0;
+               p = capture_source_types[i].create_op(source, errbuf, &is_theirs);
+               if (is_theirs) {
+                       /*
+                        * The device name refers to a device of the
+                        * type in question; either it succeeded,
+                        * in which case p refers to a pcap_t to
+                        * later activate for the device, or it
+                        * failed, in which case p is null and we
+                        * should return that to report the failure
+                        * to create.
+                        */
+                       return (p);
+               }
+       }
+
+       /*
+        * OK, try it as a regular network interface.
+        */
+       return (pcap_create_interface(source, errbuf));
+}
+#endif
+
 static void
 initialize_ops(pcap_t *p)
 {