]> The Tcpdump Group git mirrors - libpcap/blobdiff - pcap-netmap.c
Fix building without protochain support. (GH #852)
[libpcap] / pcap-netmap.c
index 61c820ccaf9973092b8be594cba73a7eb6c1c1ec..27d36e5bb6d31b678e875887a5e9941f5540090c 100644 (file)
@@ -29,7 +29,6 @@
 #endif
 
 #include <poll.h>
-#include <ctype.h>
 #include <errno.h>
 #include <netdb.h>
 #include <stdio.h>
 #include "pcap-int.h"
 #include "pcap-netmap.h"
 
-#if defined (linux)
-/* On FreeBSD we use IFF_PPROMISC which is in ifr_flagshigh.
- * remap to IFF_PROMISC on linux
- */
-#define IFF_PPROMISC   IFF_PROMISC
-#endif /* linux */
+#ifndef __FreeBSD__
+  /*
+   * On FreeBSD we use IFF_PPROMISC which is in ifr_flagshigh.
+   * Remap to IFF_PROMISC on other platforms.
+   *
+   * XXX - DragonFly BSD?
+   */
+  #define IFF_PPROMISC IFF_PROMISC
+#endif /* __FreeBSD__ */
 
 struct pcap_netmap {
        struct nm_desc *d;      /* pointer returned by nm_open() */
@@ -64,7 +66,7 @@ pcap_netmap_stats(pcap_t *p, struct pcap_stat *ps)
 {
        struct pcap_netmap *pn = p->priv;
 
-       ps->ps_recv = pn->rx_pkts;
+       ps->ps_recv = (u_int)pn->rx_pkts;
        ps->ps_drop = 0;
        ps->ps_ifdrop = 0;
        return 0;
@@ -79,7 +81,7 @@ pcap_netmap_filter(u_char *arg, struct pcap_pkthdr *h, const u_char *buf)
        const struct bpf_insn *pc = p->fcode.bf_insns;
 
        ++pn->rx_pkts;
-       if (pc == NULL || bpf_filter(pc, buf, h->len, h->caplen))
+       if (pc == NULL || pcap_filter(pc, buf, h->len, h->caplen))
                pn->cb(pn->cb_arg, h, buf);
 }
 
@@ -114,7 +116,7 @@ pcap_netmap_dispatch(pcap_t *p, int cnt, pcap_handler cb, u_char *user)
 
 /* XXX need to check the NIOCTXSYNC/poll */
 static int
-pcap_netmap_inject(pcap_t *p, const void *buf, size_t size)
+pcap_netmap_inject(pcap_t *p, const void *buf, int size)
 {
        struct pcap_netmap *pn = p->priv;
        struct nm_desc *d = pn->d;
@@ -142,8 +144,25 @@ pcap_netmap_ioctl(pcap_t *p, u_long what, uint32_t *if_flags)
        strncpy(ifr.ifr_name, d->req.nr_name, sizeof(ifr.ifr_name));
        switch (what) {
        case SIOCSIFFLAGS:
+               /*
+                * The flags we pass in are 32-bit and unsigned.
+                *
+                * On most if not all UN*Xes, ifr_flags is 16-bit and
+                * signed, and the result of assigning a longer
+                * unsigned value to a shorter signed value is
+                * implementation-defined (even if, in practice, it'll
+                * do what's intended on all platforms we support
+                * result of assigning a 32-bit unsigned value).
+                * So we mask out the upper 16 bits.
+                */
                ifr.ifr_flags = *if_flags & 0xffff;
 #ifdef __FreeBSD__
+               /*
+                * In FreeBSD, we need to set the high-order flags,
+                * as we're using IFF_PPROMISC, which is in those bits.
+                *
+                * XXX - DragonFly BSD?
+                */
                ifr.ifr_flagshigh = *if_flags >> 16;
 #endif /* __FreeBSD__ */
                break;
@@ -152,8 +171,25 @@ pcap_netmap_ioctl(pcap_t *p, u_long what, uint32_t *if_flags)
        if (!error) {
                switch (what) {
                case SIOCGIFFLAGS:
+                       /*
+                        * The flags we return are 32-bit.
+                        *
+                        * On most if not all UN*Xes, ifr_flags is
+                        * 16-bit and signed, and will get sign-
+                        * extended, so that the upper 16 bits of
+                        * those flags will be forced on.  So we
+                        * mask out the upper 16 bits of the
+                        * sign-extended value.
+                        */
                        *if_flags = ifr.ifr_flags & 0xffff;
 #ifdef __FreeBSD__
+                       /*
+                        * In FreeBSD, we need to return the
+                        * high-order flags, as we're using
+                        * IFF_PPROMISC, which is in those bits.
+                        *
+                        * XXX - DragonFly BSD?
+                        */
                        *if_flags |= (ifr.ifr_flagshigh << 16);
 #endif /* __FreeBSD__ */
                }
@@ -199,10 +235,11 @@ pcap_netmap_activate(pcap_t *p)
                pcap_cleanup_live_common(p);
                return (PCAP_ERROR);
        }
-       if (0)
-           fprintf(stderr, "%s device %s priv %p fd %d ports %d..%d\n",
-               __FUNCTION__, p->opt.device, d, d->fd,
-               d->first_rx_ring, d->last_rx_ring);
+#if 0
+       fprintf(stderr, "%s device %s priv %p fd %d ports %d..%d\n",
+           __FUNCTION__, p->opt.device, d, d->fd,
+           d->first_rx_ring, d->last_rx_ring);
+#endif
        pn->d = d;
        p->fd = d->fd;
 
@@ -228,7 +265,7 @@ pcap_netmap_activate(pcap_t *p)
        p->linktype = DLT_EN10MB;
        p->selectable_fd = p->fd;
        p->read_op = pcap_netmap_dispatch;
-       p->inject_op = pcap_netmap_inject,
+       p->inject_op = pcap_netmap_inject;
        p->setfilter_op = install_bpf_program;
        p->setdirection_op = NULL;
        p->set_datalink_op = NULL;
@@ -249,7 +286,7 @@ pcap_netmap_create(const char *device, char *ebuf, int *is_ours)
        *is_ours = (!strncmp(device, "netmap:", 7) || !strncmp(device, "vale", 4));
        if (! *is_ours)
                return NULL;
-       p = pcap_create_common(ebuf, sizeof (struct pcap_netmap));
+       p = PCAP_CREATE_COMMON(ebuf, struct pcap_netmap);
        if (p == NULL)
                return (NULL);
        p->activate_op = pcap_netmap_activate;