]> The Tcpdump Group git mirrors - libpcap/commitdiff
Move platform-dependent pcap_t data out of the pcap_t structure.
authorGuy Harris <[email protected]>
Mon, 6 May 2013 21:16:14 +0000 (14:16 -0700)
committerGuy Harris <[email protected]>
Mon, 6 May 2013 21:16:14 +0000 (14:16 -0700)
Put the private data right after the pcap_t structure, with a pointer to
it in the pcap_t.

The initial goal is to allow new pcap modules to be added without having
to hack pcap-int.h.

In the longer term, we may want to freeze the pcap_t structure, except
possibly for adding new method pointers at the end, and provide an ABI
for adding modules.

We also put the stuff used by the read path at the beginning of the
pcap_t structure, to try to keep it on the same set of cache lines.

30 files changed:
dlpisubs.c
dlpisubs.h
gencode.c
pcap-bpf.c
pcap-bt-linux.c
pcap-can-linux.c
pcap-canusb-linux.c
pcap-dag.c
pcap-dbus.c
pcap-dlpi.c
pcap-dos.c
pcap-int.h
pcap-libdlpi.c
pcap-linux.c
pcap-netfilter-linux.c
pcap-nit.c
pcap-pf.c
pcap-septel.c
pcap-sita.c
pcap-snf.c
pcap-snit.c
pcap-snoop.c
pcap-usb-linux.c
pcap-win32.c
pcap.c
savefile.c
sf-pcap-ng.c
sf-pcap-ng.h
sf-pcap.c
sf-pcap.h

index 23c78ced218320487a8a8c341e1c909ae38bbc4d..4f2150dfc4ef05f328ed6ec61163b366a1a3ffc8 100644 (file)
@@ -66,6 +66,8 @@ static const char rcsid[] _U_ =
 #include <stropts.h>
 #include <unistd.h>
 
+#include <libdlpi.h>
+
 #include "pcap-int.h"
 #include "dlpisubs.h"
 
@@ -79,6 +81,7 @@ static void pcap_stream_err(const char *, int, char *);
 int
 pcap_stats_dlpi(pcap_t *p, struct pcap_stat *ps)
 {
+       struct pcap_dlpi *pd = p->private;
 
        /*
         * "ps_recv" counts packets handed to the filter, not packets
@@ -103,7 +106,7 @@ pcap_stats_dlpi(pcap_t *p, struct pcap_stat *ps)
         * the kernel by libpcap, but they may include packets not
         * yet read from libpcap by the application.
         */
-       *ps = p->md.stat;
+       *ps = pd->stat;
 
        /*
         * Add in the drop count, as per the above comment.
@@ -120,6 +123,7 @@ int
 pcap_process_pkts(pcap_t *p, pcap_handler callback, u_char *user,
        int count, u_char *bufp, int len)
 {
+       struct pcap_dlpi *pd = p->private;
        int n, caplen, origlen;
        u_char *ep, *pk;
        struct pcap_pkthdr pkthdr;
@@ -162,7 +166,7 @@ pcap_process_pkts(pcap_t *p, pcap_handler callback, u_char *user,
                } else
 #endif
                        sbp = (struct sb_hdr *)bufp;
-               p->md.stat.ps_drop = sbp->sbh_drops;
+               pd->stat.ps_drop = sbp->sbh_drops;
                pk = bufp + sizeof(*sbp);
                bufp += sbp->sbh_totlen;
                origlen = sbp->sbh_origlen;
@@ -173,7 +177,7 @@ pcap_process_pkts(pcap_t *p, pcap_handler callback, u_char *user,
                pk = bufp;
                bufp += caplen;
 #endif
-               ++p->md.stat.ps_recv;
+               ++pd->stat.ps_recv;
                if (bpf_filter(p->fcode.bf_insns, pk, origlen, caplen)) {
 #ifdef HAVE_SYS_BUFMOD_H
                        pkthdr.ts.tv_sec = sbp->sbh_timestamp.tv_sec;
index 1b57d4d2e7e89846988c4d4afc90c75c6a2d4b6e..8795af645e8cc22e49a2ead04112b82069ef7738 100644 (file)
@@ -10,7 +10,21 @@ extern "C" {
 #endif
 
 /*
- * Functions used by dlpisubs.c.
+ * Private data for capturing on DLPI devices.
+ */
+struct pcap_dlpi {
+#ifdef HAVE_LIBDLPI
+       dlpi_handle_t dlpi_hd;
+#endif /* HAVE_LIBDLPI */
+#ifdef DL_HP_RAWDLS
+       int send_fd;
+#endif /* DL_HP_RAWDLS */
+
+       struct pcap_stat stat;
+};
+
+/*
+ * Functions defined by dlpisubs.c.
  */
 int pcap_stats_dlpi(pcap_t *, struct pcap_stat *);
 int pcap_process_pkts(pcap_t *, pcap_handler, u_char *, int, u_char *, int);
index 1cbaeebdd36c76c166e729c6847e85d4ab2762c7..cb84dc48208688903a2a20760d367ccb9227cbea 100644 (file)
--- a/gencode.c
+++ b/gencode.c
@@ -141,9 +141,7 @@ static u_int        orig_linktype = -1U, orig_nl = -1U, label_stack_depth = -1U;
 #endif
 
 /* XXX */
-#ifdef PCAP_FDDIPAD
 static int     pcap_fddipad;
-#endif
 
 /* VARARGS */
 void
@@ -926,9 +924,7 @@ init_linktype(p)
        pcap_t *p;
 {
        linktype = pcap_datalink(p);
-#ifdef PCAP_FDDIPAD
        pcap_fddipad = p->fddipad;
-#endif
 
        /*
         * Assume it's not raw ATM with a pseudo-header, for now.
@@ -1066,13 +1062,9 @@ init_linktype(p)
                 * XXX - should we generate code to check for SNAP?
                 */
                off_linktype = 13;
-#ifdef PCAP_FDDIPAD
                off_linktype += pcap_fddipad;
-#endif
                off_macpl = 13;         /* FDDI MAC header length */
-#ifdef PCAP_FDDIPAD
                off_macpl += pcap_fddipad;
-#endif
                off_nl = 8;             /* 802.2+SNAP */
                off_nl_nosnap = 3;      /* 802.2 */
                return;
@@ -3205,8 +3197,7 @@ gen_linktype(proto)
                         * Then we run it through "htonl()", and
                         * generate code to compare against the result.
                         */
-                       if (bpf_pcap->sf.rfile != NULL &&
-                           bpf_pcap->sf.swapped)
+                       if (bpf_pcap->rfile != NULL && bpf_pcap->swapped)
                                proto = SWAPLONG(proto);
                        proto = htonl(proto);
                }
@@ -3718,18 +3709,10 @@ gen_fhostop(eaddr, dir)
 
        switch (dir) {
        case Q_SRC:
-#ifdef PCAP_FDDIPAD
                return gen_bcmp(OR_LINK, 6 + 1 + pcap_fddipad, 6, eaddr);
-#else
-               return gen_bcmp(OR_LINK, 6 + 1, 6, eaddr);
-#endif
 
        case Q_DST:
-#ifdef PCAP_FDDIPAD
                return gen_bcmp(OR_LINK, 0 + 1 + pcap_fddipad, 6, eaddr);
-#else
-               return gen_bcmp(OR_LINK, 0 + 1, 6, eaddr);
-#endif
 
        case Q_AND:
                b0 = gen_fhostop(eaddr, Q_SRC);
@@ -7555,7 +7538,7 @@ gen_inbound(dir)
                 * special meta-data in the filter expression;
                 * if it's a savefile, we can't.
                 */
-               if (bpf_pcap->sf.rfile != NULL) {
+               if (bpf_pcap->rfile != NULL) {
                        /* We have a FILE *, so this is a savefile */
                        bpf_error("inbound/outbound not supported on linktype %d when reading savefiles",
                            linktype);
index 9e739dc6a46ce1b67b51e7e67ce1ed01b060e213..10b902647f459a6100d8e7d31253f18636355993 100644 (file)
@@ -126,6 +126,56 @@ static int bpf_load(char *errbuf);
 #include "os-proto.h"
 #endif
 
+/*
+ * Later versions of NetBSD stick padding in front of FDDI frames
+ * to align the IP header on a 4-byte boundary.
+ */
+#if defined(__NetBSD__) && __NetBSD_Version__ > 106000000
+#define       PCAP_FDDIPAD 3
+#endif
+
+/*
+ * Private data for capturing on BPF devices.
+ */
+struct pcap_bpf {
+#ifdef PCAP_FDDIPAD
+       int fddipad;
+#endif
+
+#ifdef HAVE_ZEROCOPY_BPF
+       /*
+        * Zero-copy read buffer -- for zero-copy BPF.  'buffer' above will
+        * alternative between these two actual mmap'd buffers as required.
+        * As there is a header on the front size of the mmap'd buffer, only
+        * some of the buffer is exposed to libpcap as a whole via bufsize;
+        * zbufsize is the true size.  zbuffer tracks the current zbuf
+        * assocated with buffer so that it can be used to decide which the
+        * next buffer to read will be.
+        */
+       u_char *zbuf1, *zbuf2, *zbuffer;
+       u_int zbufsize;
+       u_int zerocopy;
+       u_int interrupted;
+       struct timespec firstsel;
+       /*
+        * If there's currently a buffer being actively processed, then it is
+        * referenced here; 'buffer' is also pointed at it, but offset by the
+        * size of the header.
+        */
+       struct bpf_zbuf_header *bzh;
+#endif /* HAVE_ZEROCOPY_BPF */
+
+       char *device;           /* device name */
+       int filtering_in_kernel; /* using kernel filter */
+       int timeout;            /* timeout for buffering */
+       int must_do_on_close;   /* stuff we must do when we close */
+};
+
+/*
+ * Stuff to do when we close.
+ */
+#define MUST_CLEAR_RFMON       0x00000001      /* clear rfmon (monitor) mode */
+
 #ifdef BIOCGDLTLIST
 # if (defined(HAVE_NET_IF_MEDIA_H) && defined(IFM_IEEE80211)) && !defined(__APPLE__)
 #define HAVE_BSD_IEEE80211
@@ -184,7 +234,7 @@ static int pcap_set_datalink_bpf(pcap_t *p, int dlt);
 
 /*
  * For zerocopy bpf, the setnonblock/getnonblock routines need to modify
- * p->md.timeout so we don't call select(2) if the pcap handle is in non-
+ * pb->timeout so we don't call select(2) if the pcap handle is in non-
  * blocking mode.  We preserve the timeout supplied by pcap_open functions
  * to make sure it does not get clobbered if the pcap handle moves between
  * blocking and non-blocking mode.
@@ -193,12 +243,14 @@ static int
 pcap_getnonblock_bpf(pcap_t *p, char *errbuf)
 { 
 #ifdef HAVE_ZEROCOPY_BPF
-       if (p->md.zerocopy) {
+       struct pcap_bpf *pb = p->private;
+
+       if (pb->zerocopy) {
                /*
                 * Use a negative value for the timeout to represent that the
                 * pcap handle is in non-blocking mode.
                 */
-               return (p->md.timeout < 0);
+               return (pb->timeout < 0);
        }
 #endif
        return (pcap_getnonblock_fd(p, errbuf));
@@ -208,23 +260,31 @@ static int
 pcap_setnonblock_bpf(pcap_t *p, int nonblock, char *errbuf)
 {   
 #ifdef HAVE_ZEROCOPY_BPF
-       if (p->md.zerocopy) {
+       struct pcap_bpf *pb = p->private;
+
+       if (pb->zerocopy) {
                /*
                 * Map each value to their corresponding negation to
                 * preserve the timeout value provided with pcap_set_timeout.
                 * (from pcap-linux.c).
                 */
                if (nonblock) {
-                       if (p->md.timeout >= 0) {
+                       if (pb->timeout >= 0) {
                                /*
                                 * Indicate that we're switching to
                                 * non-blocking mode.
                                 */
-                               p->md.timeout = ~p->md.timeout;
+                               pb->timeout = ~pb->timeout;
                        }
                } else {
-                       if (p->md.timeout < 0) {
-                               p->md.timeout = ~p->md.timeout;
+                       if (pb->timeout < 0) {
+                               /*
+                                * Timeout is negative, so we're currently
+                                * in blocking mode; reverse the previous
+                                * operation, to make the timeout non-negative
+                                * again.
+                                */
+                               pb->timeout = ~pb->timeout;
                        }
                }
                return (0);
@@ -246,25 +306,26 @@ pcap_setnonblock_bpf(pcap_t *p, int nonblock, char *errbuf)
 static int
 pcap_next_zbuf_shm(pcap_t *p, int *cc)
 {
+       struct pcap_bpf *pb = p->private;
        struct bpf_zbuf_header *bzh;
 
-       if (p->md.zbuffer == p->md.zbuf2 || p->md.zbuffer == NULL) {
-               bzh = (struct bpf_zbuf_header *)p->md.zbuf1;
+       if (pb->zbuffer == pb->zbuf2 || pb->zbuffer == NULL) {
+               bzh = (struct bpf_zbuf_header *)pb->zbuf1;
                if (bzh->bzh_user_gen !=
                    atomic_load_acq_int(&bzh->bzh_kernel_gen)) {
-                       p->md.bzh = bzh;
-                       p->md.zbuffer = (u_char *)p->md.zbuf1;
-                       p->buffer = p->md.zbuffer + sizeof(*bzh);
+                       pb->bzh = bzh;
+                       pb->zbuffer = (u_char *)pb->zbuf1;
+                       p->buffer = pb->zbuffer + sizeof(*bzh);
                        *cc = bzh->bzh_kernel_len;
                        return (1);
                }
-       } else if (p->md.zbuffer == p->md.zbuf1) {
-               bzh = (struct bpf_zbuf_header *)p->md.zbuf2;
+       } else if (pb->zbuffer == pb->zbuf1) {
+               bzh = (struct bpf_zbuf_header *)pb->zbuf2;
                if (bzh->bzh_user_gen !=
                    atomic_load_acq_int(&bzh->bzh_kernel_gen)) {
-                       p->md.bzh = bzh;
-                       p->md.zbuffer = (u_char *)p->md.zbuf2;
-                       p->buffer = p->md.zbuffer + sizeof(*bzh);
+                       pb->bzh = bzh;
+                       pb->zbuffer = (u_char *)pb->zbuf2;
+                       p->buffer = pb->zbuffer + sizeof(*bzh);
                        *cc = bzh->bzh_kernel_len;
                        return (1);
                }
@@ -283,6 +344,7 @@ pcap_next_zbuf_shm(pcap_t *p, int *cc)
 static int
 pcap_next_zbuf(pcap_t *p, int *cc)
 {
+       struct pcap_bpf *pb = p->private;
        struct bpf_zbuf bz;
        struct timeval tv;
        struct timespec cur;
@@ -306,15 +368,15 @@ pcap_next_zbuf(pcap_t *p, int *cc)
         * our timeout is less then or equal to zero, handle it like a
         * regular timeout.
         */
-       tmout = p->md.timeout;
+       tmout = pb->timeout;
        if (tmout)
                (void) clock_gettime(CLOCK_MONOTONIC, &cur);
-       if (p->md.interrupted && p->md.timeout) {
-               expire = TSTOMILLI(&p->md.firstsel) + p->md.timeout;
+       if (pb->interrupted && pb->timeout) {
+               expire = TSTOMILLI(&pb->firstsel) + pb->timeout;
                tmout = expire - TSTOMILLI(&cur);
 #undef TSTOMILLI
                if (tmout <= 0) {
-                       p->md.interrupted = 0;
+                       pb->interrupted = 0;
                        data = pcap_next_zbuf_shm(p, cc);
                        if (data)
                                return (data);
@@ -331,7 +393,7 @@ pcap_next_zbuf(pcap_t *p, int *cc)
         * the next timeout.  Note that we only call select if the handle
         * is in blocking mode.
         */
-       if (p->md.timeout >= 0) {
+       if (pb->timeout >= 0) {
                FD_ZERO(&r_set);
                FD_SET(p->fd, &r_set);
                if (tmout != 0) {
@@ -339,11 +401,11 @@ pcap_next_zbuf(pcap_t *p, int *cc)
                        tv.tv_usec = (tmout * 1000) % 1000000;
                }
                r = select(p->fd + 1, &r_set, NULL, NULL,
-                   p->md.timeout != 0 ? &tv : NULL);
+                   pb->timeout != 0 ? &tv : NULL);
                if (r < 0 && errno == EINTR) {
-                       if (!p->md.interrupted && p->md.timeout) {
-                               p->md.interrupted = 1;
-                               p->md.firstsel = cur;
+                       if (!pb->interrupted && pb->timeout) {
+                               pb->interrupted = 1;
+                               pb->firstsel = cur;
                        }
                        return (0);
                } else if (r < 0) {
@@ -352,7 +414,7 @@ pcap_next_zbuf(pcap_t *p, int *cc)
                        return (PCAP_ERROR);
                }
        }
-       p->md.interrupted = 0;
+       pb->interrupted = 0;
        /*
         * Check again for data, which may exist now that we've either been
         * woken up as a result of data or timed out.  Try the "there's data"
@@ -380,10 +442,11 @@ pcap_next_zbuf(pcap_t *p, int *cc)
 static int
 pcap_ack_zbuf(pcap_t *p)
 {
+       struct pcap_bpf *pb = p->private;
 
-       atomic_store_rel_int(&p->md.bzh->bzh_user_gen,
-           p->md.bzh->bzh_kernel_gen);
-       p->md.bzh = NULL;
+       atomic_store_rel_int(&pb->bzh->bzh_user_gen,
+           pb->bzh->bzh_kernel_gen);
+       pb->bzh = NULL;
        p->buffer = NULL;
        return (0);
 }
@@ -394,7 +457,7 @@ pcap_create_interface(const char *device, char *ebuf)
 {
        pcap_t *p;
 
-       p = pcap_create_common(device, ebuf);
+       p = pcap_create_common(device, ebuf, sizeof (struct pcap_bpf));
        if (p == NULL)
                return (NULL);
 
@@ -790,6 +853,7 @@ pcap_stats_bpf(pcap_t *p, struct pcap_stat *ps)
 static int
 pcap_read_bpf(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
 {
+       struct pcap_bpf *pb = p->private;
        int cc;
        int n = 0;
        register u_char *bp, *ep;
@@ -825,7 +889,7 @@ pcap_read_bpf(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
                 * buffer.
                 */
 #ifdef HAVE_ZEROCOPY_BPF
-               if (p->md.zerocopy) {
+               if (pb->zerocopy) {
                        if (p->buffer != NULL)
                                pcap_ack_zbuf(p);
                        i = pcap_next_zbuf(p, &cc);
@@ -973,7 +1037,7 @@ pcap_read_bpf(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
                 * skipping that padding.
 #endif
                 */
-               if (p->md.use_bpf ||
+               if (pb->filtering_in_kernel ||
                    bpf_filter(p->fcode.bf_insns, datap, bhp->bh_datalen, caplen)) {
                        struct pcap_pkthdr pkthdr;
 
@@ -1240,19 +1304,20 @@ bpf_load(char *errbuf)
 static void
 pcap_cleanup_bpf(pcap_t *p)
 {
+       struct pcap_bpf *pb = p->private;
 #ifdef HAVE_BSD_IEEE80211
        int sock;
        struct ifmediareq req;
        struct ifreq ifr;
 #endif
 
-       if (p->md.must_do_on_close != 0) {
+       if (pb->must_do_on_close != 0) {
                /*
                 * There's something we have to do when closing this
                 * pcap_t.
                 */
 #ifdef HAVE_BSD_IEEE80211
-               if (p->md.must_do_on_close & MUST_CLEAR_RFMON) {
+               if (pb->must_do_on_close & MUST_CLEAR_RFMON) {
                        /*
                         * We put the interface into rfmon mode;
                         * take it out of rfmon mode.
@@ -1269,7 +1334,7 @@ pcap_cleanup_bpf(pcap_t *p)
                                    strerror(errno));
                        } else {
                                memset(&req, 0, sizeof(req));
-                               strncpy(req.ifm_name, p->md.device,
+                               strncpy(req.ifm_name, pb->device,
                                    sizeof(req.ifm_name));
                                if (ioctl(sock, SIOCGIFMEDIA, &req) < 0) {
                                        fprintf(stderr,
@@ -1284,7 +1349,7 @@ pcap_cleanup_bpf(pcap_t *p)
                                                 */
                                                memset(&ifr, 0, sizeof(ifr));
                                                (void)strncpy(ifr.ifr_name,
-                                                   p->md.device,
+                                                   pb->device,
                                                    sizeof(ifr.ifr_name));
                                                ifr.ifr_media =
                                                    req.ifm_current & ~IFM_IEEE80211_MONITOR;
@@ -1307,11 +1372,11 @@ pcap_cleanup_bpf(pcap_t *p)
                 * have to take the interface out of some mode.
                 */
                pcap_remove_from_pcaps_to_close(p);
-               p->md.must_do_on_close = 0;
+               pb->must_do_on_close = 0;
        }
 
 #ifdef HAVE_ZEROCOPY_BPF
-       if (p->md.zerocopy) {
+       if (pb->zerocopy) {
                /*
                 * Delete the mappings.  Note that p->buffer gets
                 * initialized to one of the mmapped regions in
@@ -1319,16 +1384,16 @@ pcap_cleanup_bpf(pcap_t *p)
                 * null it out so that pcap_cleanup_live_common()
                 * doesn't try to free it.
                 */
-               if (p->md.zbuf1 != MAP_FAILED && p->md.zbuf1 != NULL)
-                       (void) munmap(p->md.zbuf1, p->md.zbufsize);
-               if (p->md.zbuf2 != MAP_FAILED && p->md.zbuf2 != NULL)
-                       (void) munmap(p->md.zbuf2, p->md.zbufsize);
+               if (pb->zbuf1 != MAP_FAILED && pb->zbuf1 != NULL)
+                       (void) munmap(pb->zbuf1, pb->zbufsize);
+               if (pb->zbuf2 != MAP_FAILED && pb->zbuf2 != NULL)
+                       (void) munmap(pb->zbuf2, pb->zbufsize);
                p->buffer = NULL;
        }
 #endif
-       if (p->md.device != NULL) {
-               free(p->md.device);
-               p->md.device = NULL;
+       if (pb->device != NULL) {
+               free(pb->device);
+               pb->device = NULL;
        }
        pcap_cleanup_live_common(p);
 }
@@ -1443,6 +1508,7 @@ check_setif_failure(pcap_t *p, int error)
 static int
 pcap_activate_bpf(pcap_t *p)
 {
+       struct pcap_bpf *pb = p->private;
        int status = 0;
        int fd;
 #ifdef LIFNAMSIZ
@@ -1524,8 +1590,8 @@ pcap_activate_bpf(pcap_t *p)
        }
 #endif
 
-       p->md.device = strdup(p->opt.source);
-       if (p->md.device == NULL) {
+       pb->device = strdup(p->opt.source);
+       if (pb->device == NULL) {
                snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "strdup: %s",
                     pcap_strerror(errno));
                status = PCAP_ERROR;
@@ -1633,7 +1699,7 @@ pcap_activate_bpf(pcap_t *p)
                /*
                 * We have zerocopy BPF; use it.
                 */
-               p->md.zerocopy = 1;
+               pb->zerocopy = 1;
 
                /*
                 * How to pick a buffer size: first, query the maximum buffer
@@ -1663,22 +1729,22 @@ pcap_activate_bpf(pcap_t *p)
 #ifndef roundup
 #define roundup(x, y)   ((((x)+((y)-1))/(y))*(y))  /* to any y */
 #endif
-               p->md.zbufsize = roundup(v, getpagesize());
-               if (p->md.zbufsize > zbufmax)
-                       p->md.zbufsize = zbufmax;
-               p->md.zbuf1 = mmap(NULL, p->md.zbufsize, PROT_READ | PROT_WRITE,
+               pb->zbufsize = roundup(v, getpagesize());
+               if (pb->zbufsize > zbufmax)
+                       pb->zbufsize = zbufmax;
+               pb->zbuf1 = mmap(NULL, pb->zbufsize, PROT_READ | PROT_WRITE,
                    MAP_ANON, -1, 0);
-               p->md.zbuf2 = mmap(NULL, p->md.zbufsize, PROT_READ | PROT_WRITE,
+               pb->zbuf2 = mmap(NULL, pb->zbufsize, PROT_READ | PROT_WRITE,
                    MAP_ANON, -1, 0);
-               if (p->md.zbuf1 == MAP_FAILED || p->md.zbuf2 == MAP_FAILED) {
+               if (pb->zbuf1 == MAP_FAILED || pb->zbuf2 == MAP_FAILED) {
                        snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "mmap: %s",
                            pcap_strerror(errno));
                        goto bad;
                }
                memset(&bz, 0, sizeof(bz)); /* bzero() deprecated, replaced with memset() */
-               bz.bz_bufa = p->md.zbuf1;
-               bz.bz_bufb = p->md.zbuf2;
-               bz.bz_buflen = p->md.zbufsize;
+               bz.bz_bufa = pb->zbuf1;
+               bz.bz_bufb = pb->zbuf2;
+               bz.bz_buflen = pb->zbufsize;
                if (ioctl(fd, BIOCSETZBUF, (caddr_t)&bz) < 0) {
                        snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCSETZBUF: %s",
                            pcap_strerror(errno));
@@ -1690,7 +1756,7 @@ pcap_activate_bpf(pcap_t *p)
                            p->opt.source, pcap_strerror(errno));
                        goto bad;
                }
-               v = p->md.zbufsize - sizeof(struct bpf_zbuf_header);
+               v = pb->zbufsize - sizeof(struct bpf_zbuf_header);
        } else
 #endif
        {
@@ -2002,8 +2068,8 @@ pcap_activate_bpf(pcap_t *p)
        if (v == DLT_FDDI)
                p->fddipad = PCAP_FDDIPAD;
        else
-               p->fddipad = 0;
 #endif
+               p->fddipad = 0;
        p->linktype = v;
 
 #if defined(BIOCGHDRCMPLT) && defined(BIOCSHDRCMPLT)
@@ -2024,10 +2090,11 @@ pcap_activate_bpf(pcap_t *p)
        }
 #endif
        /* set timeout */
+       pb->timeout = p->opt.timeout;
 #ifdef HAVE_ZEROCOPY_BPF
-       if (p->md.timeout != 0 && !p->md.zerocopy) {
+       if (pb->timeout != 0 && !pb->zerocopy) {
 #else
-       if (p->md.timeout) {
+       if (pb->timeout) {
 #endif
                /*
                 * XXX - is this seconds/nanoseconds in AIX?
@@ -2051,8 +2118,8 @@ pcap_activate_bpf(pcap_t *p)
                struct BPF_TIMEVAL bpf_to;
 
                if (IOCPARM_LEN(BIOCSRTIMEOUT) != sizeof(struct timeval)) {
-                       bpf_to.tv_sec = p->md.timeout / 1000;
-                       bpf_to.tv_usec = (p->md.timeout * 1000) % 1000000;
+                       bpf_to.tv_sec = pb->timeout / 1000;
+                       bpf_to.tv_usec = (pb->timeout * 1000) % 1000000;
                        if (ioctl(p->fd, BIOCSRTIMEOUT, (caddr_t)&bpf_to) < 0) {
                                snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
                                    "BIOCSRTIMEOUT: %s", pcap_strerror(errno));
@@ -2061,8 +2128,8 @@ pcap_activate_bpf(pcap_t *p)
                        }
                } else {
 #endif
-                       to.tv_sec = p->md.timeout / 1000;
-                       to.tv_usec = (p->md.timeout * 1000) % 1000000;
+                       to.tv_sec = pb->timeout / 1000;
+                       to.tv_usec = (pb->timeout * 1000) % 1000000;
                        if (ioctl(p->fd, BIOCSRTIMEOUT, (caddr_t)&to) < 0) {
                                snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
                                    "BIOCSRTIMEOUT: %s", pcap_strerror(errno));
@@ -2149,7 +2216,7 @@ pcap_activate_bpf(pcap_t *p)
        }
        p->bufsize = v;
 #ifdef HAVE_ZEROCOPY_BPF
-       if (!p->md.zerocopy) {
+       if (!pb->zerocopy) {
 #endif
        p->buffer = (u_char *)malloc(p->bufsize);
        if (p->buffer == NULL) {
@@ -2264,6 +2331,7 @@ pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
 static int
 monitor_mode(pcap_t *p, int set)
 {
+       struct pcap_bpf *pb = p->private;
        int sock;
        struct ifmediareq req;
        int *media_list;
@@ -2401,7 +2469,7 @@ monitor_mode(pcap_t *p, int set)
                                return (PCAP_ERROR);
                        }
 
-                       p->md.must_do_on_close |= MUST_CLEAR_RFMON;
+                       pb->must_do_on_close |= MUST_CLEAR_RFMON;
 
                        /*
                         * Add this to the list of pcaps to close when we exit.
@@ -2578,6 +2646,8 @@ remove_802_11(pcap_t *p)
 static int
 pcap_setfilter_bpf(pcap_t *p, struct bpf_program *fp)
 {
+       struct pcap_bpf *pb = p->private;
+
        /*
         * Free any user-mode filter we might happen to have installed.
         */
@@ -2590,7 +2660,7 @@ pcap_setfilter_bpf(pcap_t *p, struct bpf_program *fp)
                /*
                 * It worked.
                 */
-               p->md.use_bpf = 1;      /* filtering in the kernel */
+               pb->filtering_in_kernel = 1;    /* filtering in the kernel */
 
                /*
                 * Discard any previously-received packets, as they might
@@ -2630,7 +2700,7 @@ pcap_setfilter_bpf(pcap_t *p, struct bpf_program *fp)
         */
        if (install_bpf_program(p, fp) < 0)
                return (-1);
-       p->md.use_bpf = 0;      /* filtering in userland */
+       pb->filtering_in_kernel = 0;    /* filtering in userland */
        return (0);
 }
 
index 037f64b9f72341c67e163c6a75000a6f35baf182..e2268b8e9bae8e68f9b268db4019279e725c492d 100644 (file)
@@ -70,6 +70,13 @@ static int bt_inject_linux(pcap_t *, const void *, size_t);
 static int bt_setdirection_linux(pcap_t *, pcap_direction_t);
 static int bt_stats_linux(pcap_t *, struct pcap_stat *);
 
+/*
+ * Private data for capturing on Linux Bluetooth devices.
+ */
+struct pcap_bt {
+       int dev_id;             /* device ID of device we're bound to */
+};
+
 int 
 bt_findalldevs(pcap_if_t **alldevsp, char *err_str)
 {
@@ -169,7 +176,7 @@ bt_create(const char *device, char *ebuf, int *is_ours)
        /* OK, it's probably ours. */
        *is_ours = 1;
 
-       p = pcap_create_common(device, ebuf);
+       p = pcap_create_common(device, ebuf, sizeof (struct pcap_bt));
        if (p == NULL)
                return (NULL);
 
@@ -180,6 +187,7 @@ bt_create(const char *device, char *ebuf, int *is_ours)
 static int
 bt_activate(pcap_t* handle)
 {
+       struct pcap_bt *handlep = handle->private;
        struct sockaddr_hci addr;
        int opt;
        int             dev_id;
@@ -208,7 +216,7 @@ bt_activate(pcap_t* handle)
        handle->getnonblock_op = pcap_getnonblock_fd;
        handle->setnonblock_op = pcap_setnonblock_fd;
        handle->stats_op = bt_stats_linux;
-       handle->md.ifindex = dev_id;
+       handlep->dev_id = dev_id;
        
        /* Create HCI socket */
        handle->fd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
@@ -253,13 +261,13 @@ bt_activate(pcap_t* handle)
 
        /* Bind socket to the HCI device */
        addr.hci_family = AF_BLUETOOTH;
-       addr.hci_dev = handle->md.ifindex;
+       addr.hci_dev = handlep->dev_id;
 #ifdef SOCKADDR_HCI_HAS_HCI_CHANNEL
        addr.hci_channel = HCI_CHANNEL_RAW;
 #endif
        if (bind(handle->fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
                snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
-                   "Can't attach to device %d: %s", handle->md.ifindex,
+                   "Can't attach to device %d: %s", handlep->dev_id,
                    strerror(errno));
                goto close_fail;
        }
@@ -374,10 +382,11 @@ bt_inject_linux(pcap_t *handle, const void *buf, size_t size)
 static int 
 bt_stats_linux(pcap_t *handle, struct pcap_stat *stats)
 {
+       struct pcap_bt *handlep = handle->private;
        int ret;
        struct hci_dev_info dev_info;
        struct hci_dev_stats * s = &dev_info.stat;
-       dev_info.dev_id = handle->md.ifindex;
+       dev_info.dev_id = handlep->dev_id;
        
        /* ignore eintr */
        do {
index f6a3925ec065cfc4084c741f1c3e9a3a93aaedf5..bee669b03eb26833618bc4d2e5a2df4e4aee26af 100644 (file)
@@ -72,6 +72,13 @@ 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 *);
 
+/*
+ * Private data for capturing on Linux CANbus devices.
+ */
+struct pcap_can {
+       int ifindex;            /* interface index of device we're bound to */
+};
+
 int
 can_findalldevs(pcap_if_t **devlistp, char *errbuf)
 {
@@ -124,7 +131,7 @@ can_create(const char *device, char *ebuf, int *is_ours)
        /* OK, it's probably ours. */
        *is_ours = 1;
 
-       p = pcap_create_common(device, ebuf);
+       p = pcap_create_common(device, ebuf, sizeof (struct pcap_can));
        if (p == NULL)
                return (NULL);
 
@@ -136,6 +143,7 @@ can_create(const char *device, char *ebuf, int *is_ours)
 static int
 can_activate(pcap_t* handle)
 {
+       struct pcap_can *handlep = handle->private;
        struct sockaddr_can addr;
        struct ifreq ifr;
 
@@ -172,7 +180,7 @@ can_activate(pcap_t* handle)
                pcap_cleanup_live_common(handle);
                return PCAP_ERROR;
        }
-       handle->md.ifindex = ifr.ifr_ifindex;
+       handlep->ifindex = ifr.ifr_ifindex;
 
        /* allocate butter */
        handle->buffer = malloc(handle->bufsize);
@@ -186,11 +194,11 @@ can_activate(pcap_t* handle)
 
        /* Bind to the socket */
        addr.can_family = AF_CAN;
-       addr.can_ifindex = handle->md.ifindex;
+       addr.can_ifindex = handlep->ifindex;
        if( bind( handle->fd, (struct sockaddr*)&addr, sizeof(addr) ) < 0  )
        {
                snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't attach to device %d %d:%s",
-                       handle->md.ifindex, errno, strerror(errno));
+                       handlep->ifindex, errno, strerror(errno));
                pcap_cleanup_live_common(handle);
                return PCAP_ERROR;
        }
@@ -199,7 +207,7 @@ can_activate(pcap_t* handle)
        {
                /* Monitor mode doesn't apply to CAN devices. */
                pcap_cleanup_live_common(handle);
-               return PCAP_ERROR;
+               return PCAP_ERROR_RFMON_NOTSUP;
        }
 
        handle->selectable_fd = handle->fd;
index f3bebbc7aa386a8b66db7aa2cc6e244a0267eaa5..b04e8b6d0cfc74bbb1fa6ac481ce7e8f0322d5e5 100644 (file)
@@ -42,6 +42,7 @@
 #include <unistd.h>
 #include <fcntl.h>
 #include <string.h>
+#include <pthread.h>
 
 #include "pcap-int.h"
 #include "pcap-canusb-linux.h"
@@ -74,25 +75,22 @@ struct CAN_Msg
     uint8_t data[8];
 };
 
-struct canusb_t
-{
+/*
+ * Private data for capturing on Linux CANbus USB devices.
+ */
+struct pcap_canusb {
     libusb_context *ctx;
     libusb_device_handle *dev;
-    char *serial;
     pthread_t worker;
     int rdpipe, wrpipe;
-    volatile int* loop;
+    volatile int loop;
 };
 
-static struct canusb_t canusb;
-static volatile int loop;
-
 int canusb_findalldevs(pcap_if_t **alldevsp, char *err_str)
 {
     libusb_context *fdctx;
     libusb_device** devs;
     unsigned char sernum[65];
-    unsigned char buf[96];
     int cnt, i;
     
     if (libusb_init(&fdctx) != 0) {
@@ -119,7 +117,7 @@ int canusb_findalldevs(pcap_if_t **alldevsp, char *err_str)
         //It is!
         libusb_device_handle *dh = NULL;
 
-        if (ret = libusb_open(devs[i],&dh) == 0)
+        if ((ret = libusb_open(devs[i],&dh)) == 0)
         {
             char dev_name[30];
             char dev_descr[50]; 
@@ -134,6 +132,7 @@ int canusb_findalldevs(pcap_if_t **alldevsp, char *err_str)
             if (pcap_add_if(alldevsp, dev_name, 0, dev_descr, err_str) < 0)
             {
                 libusb_free_device_list(devs,1);
+                libusb_exit(fdctx);
                 return -1;
             }
         }
@@ -146,7 +145,6 @@ int canusb_findalldevs(pcap_if_t **alldevsp, char *err_str)
 
 static libusb_device_handle* canusb_opendevice(struct libusb_context *ctx, char* devserial)
 {
-    libusb_device_handle* dh;
     libusb_device** devs;
     unsigned char serial[65];
     int cnt,i,n;
@@ -170,7 +168,7 @@ static libusb_device_handle* canusb_opendevice(struct libusb_context *ctx, char*
         n = libusb_get_string_descriptor_ascii(dh,desc.iSerialNumber,serial,64);
         serial[n] = 0;
 
-        if ((devserial) && (strcmp(serial,devserial) != 0))
+        if ((devserial) && (strcmp((char *)serial,devserial) != 0))
         {
             libusb_close(dh);
             continue;
@@ -211,8 +209,7 @@ canusb_create(const char *device, char *ebuf, int *is_ours)
     char *cpend;
     long devnum;
     pcap_t* p;
-
-    libusb_init(&canusb.ctx);
+    struct pcap_canusb *canusb;
 
     /* Does this look like a DAG device? */
     cp = strrchr(device, '/');
@@ -241,11 +238,15 @@ canusb_create(const char *device, char *ebuf, int *is_ours)
     /* OK, it's probably ours. */
     *is_ours = 1;
 
-    p = pcap_create_common(device, ebuf);
+    p = pcap_create_common(device, ebuf, sizeof (struct pcap_canusb));
     if (p == NULL)
         return (NULL);
 
-    memset(&canusb, 0x00, sizeof(canusb));
+    canusb = p->private;
+    canusb->ctx = NULL;
+    canusb->dev = NULL;
+    canusb->rdpipe = -1;
+    canusb->wrpipe = -1;
 
     p->activate_op = canusb_activate;
 
@@ -253,65 +254,54 @@ canusb_create(const char *device, char *ebuf, int *is_ours)
 }
 
 
-static void* canusb_capture_thread(struct canusb_t *canusb)
+static void* canusb_capture_thread(void *arg)
 {
-    struct libusb_context *ctx;
-    libusb_device_handle *dev;
-    int i, n;  
+    struct pcap_canusb *canusb = arg;
+    int i;
     struct 
     {
       uint8_t rxsz, txsz;
     } status;
-    char *serial;
-  
-    libusb_init(&ctx);
-  
-    serial = canusb->serial;
-    dev = canusb_opendevice(ctx, serial);
   
     fcntl(canusb->wrpipe, F_SETFL, O_NONBLOCK);  
 
-    while(*canusb->loop)
+    while(canusb->loop)
     {
-        int sz, ret;
+        int sz;
         struct CAN_Msg msg;
     
-        libusb_interrupt_transfer(dev, 0x81, (unsigned char*)&status, sizeof(status), &sz, 100);
+        libusb_interrupt_transfer(canusb->dev, 0x81, (unsigned char*)&status, sizeof(status), &sz, 100);
         //HACK!!!!! -> drop buffered data, read new one by reading twice.        
-        ret = libusb_interrupt_transfer(dev, 0x81, (unsigned char*)&status, sizeof(status), &sz, 100);                                   
+        libusb_interrupt_transfer(canusb->dev, 0x81, (unsigned char*)&status, sizeof(status), &sz, 100);                                   
 
         for(i = 0; i<status.rxsz; i++)
         {
-            libusb_bulk_transfer(dev, 0x85, (unsigned char*)&msg, sizeof(msg), &sz, 100);      
-            n = write(canusb->wrpipe, &msg, sizeof(msg));
+            libusb_bulk_transfer(canusb->dev, 0x85, (unsigned char*)&msg, sizeof(msg), &sz, 100);      
+            write(canusb->wrpipe, &msg, sizeof(msg));
         }
 
     }
   
-    libusb_close(dev);
-    libusb_exit(ctx);
-  
     return NULL;
 }
 
-static int canusb_startcapture(struct canusb_t* this)
+static int canusb_startcapture(struct pcap_canusb* this)
 {
     int pipefd[2];
 
     if (pipe(pipefd) == -1)
         return -1;
 
-    canusb.rdpipe = pipefd[0];
-    canusb.wrpipe = pipefd[1];
-    canusb.loop = &loop;
+    this->rdpipe = pipefd[0];
+    this->wrpipe = pipefd[1];
 
-    loop = 1;  
-    pthread_create(&this->worker, NULL, canusb_capture_thread, &canusb);
+    this->loop = 1;  
+    pthread_create(&this->worker, NULL, canusb_capture_thread, this);
 
-    return canusb.rdpipe;
+    return this->rdpipe;
 }
 
-static void canusb_clearbufs(struct canusb_t* this)
+static void canusb_clearbufs(struct pcap_canusb* this)
 {
     unsigned char cmd[16];
     int al;
@@ -327,22 +317,38 @@ static void canusb_clearbufs(struct canusb_t* this)
 
 static void canusb_close(pcap_t* handle)
 {
-    loop = 0;
-    pthread_join(canusb.worker, NULL);
+    struct pcap_canusb *canusb = handle->private;
+
+    canusb->loop = 0;
+    pthread_join(canusb->worker, NULL);
 
-    if (canusb.dev)
+    if (canusb->dev)
     {
-        libusb_close(canusb.dev);
-        canusb.dev = NULL;    
+        libusb_close(canusb->dev);
+        canusb->dev = NULL;
     }    
+    if (canusb->ctx)
+    {
+        libusb_exit(canusb->ctx);
+        canusb->ctx = NULL;
+    }
 }
 
 
 
 static int canusb_activate(pcap_t* handle)
 {
+    struct pcap_canusb *canusb = handle->private;
     char *serial;
 
+    if (libusb_init(&canusb->ctx) != 0) {
+        /*
+         * XXX - what causes this to fail?
+         */
+        snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "libusb_init() failed");  
+        return PCAP_ERROR;
+    } 
+
     handle->read_op = canusb_read_linux;
 
     handle->inject_op = canusb_inject_linux;
@@ -360,18 +366,18 @@ static int canusb_activate(pcap_t* handle)
     handle->set_datalink_op = NULL;
 
     serial = handle->opt.source + strlen(CANUSB_IFACE);
-    canusb.serial = strdup(serial);
 
-    canusb.dev = canusb_opendevice(canusb.ctx,serial);
-    if (!canusb.dev)
+    canusb->dev = canusb_opendevice(canusb->ctx, serial);
+    if (!canusb->dev)
     {
-        snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't open USB Device:");  
+        libusb_exit(canusb->ctx);
+        snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't open USB Device");  
         return PCAP_ERROR;
     }
 
-    canusb_clearbufs(&canusb);
+    canusb_clearbufs(canusb);
 
-    handle->fd = canusb_startcapture(&canusb);
+    handle->fd = canusb_startcapture(canusb);
     handle->selectable_fd = handle->fd;
 
     return 0;
@@ -384,8 +390,6 @@ static int
 canusb_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user)
 {
     static struct timeval firstpacket = { -1, -1};
-  
-    int msgsent = 0;
     int i = 0;
     struct CAN_Msg msg;
     struct pcap_pkthdr pkth;
index 847a556f41b6ab5068782f43586edc22917142d5..d006aa61ca15205e364791fa6de9829866954415 100644 (file)
@@ -76,6 +76,27 @@ struct sunatm_hdr {
        unsigned short  vci;            /* VCI */
 };
 
+/*
+ * Private data for capturing on DAG devices.
+ */
+struct pcap_dag {
+       struct pcap_stat stat;
+#ifdef HAVE_DAG_STREAMS_API
+       u_char  *dag_mem_bottom;        /* DAG card current memory bottom pointer */
+       u_char  *dag_mem_top;   /* DAG card current memory top pointer */
+#else /* HAVE_DAG_STREAMS_API */
+       void    *dag_mem_base;  /* DAG card memory base address */
+       u_int   dag_mem_bottom; /* DAG card current memory bottom offset */
+       u_int   dag_mem_top;    /* DAG card current memory top offset */
+#endif /* HAVE_DAG_STREAMS_API */
+       int     dag_fcs_bits;   /* Number of checksum bits from link layer */
+       int     dag_offset_flags; /* Flags to pass to dag_offset(). */
+       int     dag_stream;     /* DAG stream number */
+       int     dag_timeout;    /* timeout specified to pcap_open_live.
+                                * Same as in linux above, introduce
+                                * generally? */
+};
+
 typedef struct pcap_dag_node {
        struct pcap_dag_node *next;
        pcap_t *p;
@@ -124,13 +145,15 @@ delete_pcap_dag(pcap_t *p)
 static void
 dag_platform_cleanup(pcap_t *p)
 {
-       
+       struct pcap_dag *pd;
+
        if (p != NULL) {
+               pd = p->private;
 #ifdef HAVE_DAG_STREAMS_API
-               if(dag_stop_stream(p->fd, p->md.dag_stream) < 0)
+               if(dag_stop_stream(p->fd, pd->dag_stream) < 0)
                        fprintf(stderr,"dag_stop_stream: %s\n", strerror(errno));
                
-               if(dag_detach_stream(p->fd, p->md.dag_stream) < 0)
+               if(dag_detach_stream(p->fd, pd->dag_stream) < 0)
                        fprintf(stderr,"dag_detach_stream: %s\n", strerror(errno));
 #else
                if(dag_stop(p->fd) < 0)
@@ -222,13 +245,14 @@ dag_erf_ext_header_count(uint8_t * erf, size_t len)
 static int
 dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
 {
+       struct pcap_dag *pd = p->private;
        unsigned int processed = 0;
-       int flags = p->md.dag_offset_flags;
+       int flags = pd->dag_offset_flags;
        unsigned int nonblocking = flags & DAGF_NONBLOCK;
        unsigned int num_ext_hdr = 0;
 
        /* Get the next bufferful of packets (if necessary). */
-       while (p->md.dag_mem_top - p->md.dag_mem_bottom < dag_record_size) {
+       while (pd->dag_mem_top - pd->dag_mem_bottom < dag_record_size) {
  
                /*
                 * Has "pcap_breakloop()" been called?
@@ -255,23 +279,23 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
                 * If non-block is specified it will return immediately. The user
                 * is then responsible for efficiency.
                 */
-               if ( NULL == (p->md.dag_mem_top = dag_advance_stream(p->fd, p->md.dag_stream, &(p->md.dag_mem_bottom))) ) {
+               if ( NULL == (pd->dag_mem_top = dag_advance_stream(p->fd, pd->dag_stream, &(pd->dag_mem_bottom))) ) {
                     return -1;
                }
 #else
                /* dag_offset does not support timeouts */
-               p->md.dag_mem_top = dag_offset(p->fd, &(p->md.dag_mem_bottom), flags);
+               pd->dag_mem_top = dag_offset(p->fd, &(pd->dag_mem_bottom), flags);
 #endif /* HAVE_DAG_STREAMS_API */
 
-               if (nonblocking && (p->md.dag_mem_top - p->md.dag_mem_bottom < dag_record_size))
+               if (nonblocking && (pd->dag_mem_top - pd->dag_mem_bottom < dag_record_size))
                {
                        /* Pcap is configured to process only available packets, and there aren't any, return immediately. */
                        return 0;
                }
                
                if(!nonblocking &&
-                  p->md.dag_timeout &&
-                  (p->md.dag_mem_top - p->md.dag_mem_bottom < dag_record_size))
+                  pd->dag_timeout &&
+                  (pd->dag_mem_top - pd->dag_mem_bottom < dag_record_size))
                {
                        /* Blocking mode, but timeout set and no data has arrived, return anyway.*/
                        return 0;
@@ -280,16 +304,16 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
        }
        
        /* Process the packets. */
-       while (p->md.dag_mem_top - p->md.dag_mem_bottom >= dag_record_size) {
+       while (pd->dag_mem_top - pd->dag_mem_bottom >= dag_record_size) {
                
                unsigned short packet_len = 0;
                int caplen = 0;
                struct pcap_pkthdr      pcap_header;
                
 #ifdef HAVE_DAG_STREAMS_API
-               dag_record_t *header = (dag_record_t *)(p->md.dag_mem_bottom);
+               dag_record_t *header = (dag_record_t *)(pd->dag_mem_bottom);
 #else
-               dag_record_t *header = (dag_record_t *)(p->md.dag_mem_base + p->md.dag_mem_bottom);
+               dag_record_t *header = (dag_record_t *)(pd->dag_mem_base + pd->dag_mem_bottom);
 #endif /* HAVE_DAG_STREAMS_API */
 
                u_char *dp = ((u_char *)header); /* + dag_record_size; */
@@ -314,7 +338,7 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
                        strncpy(p->errbuf, "dag_read: record too small", PCAP_ERRBUF_SIZE);
                        return -1;
                }
-               p->md.dag_mem_bottom += rlen;
+               pd->dag_mem_bottom += rlen;
 
                /* Count lost packets. */
                switch((header->type & 0x7f)) {
@@ -330,10 +354,10 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
 
                default:
                        if (header->lctr) {
-                               if (p->md.stat.ps_drop > (UINT_MAX - ntohs(header->lctr))) {
-                                       p->md.stat.ps_drop = UINT_MAX;
+                               if (pd->stat.ps_drop > (UINT_MAX - ntohs(header->lctr))) {
+                                       pd->stat.ps_drop = UINT_MAX;
                                } else {
-                                       p->md.stat.ps_drop += ntohs(header->lctr);
+                                       pd->stat.ps_drop += ntohs(header->lctr);
                                }
                        }
                }
@@ -441,7 +465,7 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
                        case TYPE_COLOR_ETH:
                        case TYPE_ETH:
                                packet_len = ntohs(header->wlen);
-                               packet_len -= (p->md.dag_fcs_bits >> 3);
+                               packet_len -= (pd->dag_fcs_bits >> 3);
                                caplen = rlen - dag_record_size - 2;
                                if (caplen > packet_len) {
                                        caplen = packet_len;
@@ -454,7 +478,7 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
                        case TYPE_COLOR_HDLC_POS:
                        case TYPE_HDLC_POS:
                                packet_len = ntohs(header->wlen);
-                               packet_len -= (p->md.dag_fcs_bits >> 3);
+                               packet_len -= (pd->dag_fcs_bits >> 3);
                                caplen = rlen - dag_record_size;
                                if (caplen > packet_len) {
                                        caplen = packet_len;
@@ -464,7 +488,7 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
                        case TYPE_COLOR_MC_HDLC_POS:
                        case TYPE_MC_HDLC:
                                packet_len = ntohs(header->wlen);
-                               packet_len -= (p->md.dag_fcs_bits >> 3);
+                               packet_len -= (pd->dag_fcs_bits >> 3);
                                caplen = rlen - dag_record_size - 4;
                                if (caplen > packet_len) {
                                        caplen = packet_len;
@@ -545,7 +569,7 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
                        pcap_header.len = packet_len;
        
                        /* Count the packet. */
-                       p->md.stat.ps_recv++;
+                       pd->stat.ps_recv++;
        
                        /* Call the user supplied callback function */
                        callback(user, &pcap_header, dp);
@@ -584,6 +608,7 @@ dag_inject(pcap_t *p, const void *buf _U_, size_t size _U_)
  */
 static int dag_activate(pcap_t* handle)
 {
+       struct pcap_dag *handlep = handle->private;
 #if 0
        char conf[30]; /* dag configure string */
 #endif
@@ -613,13 +638,13 @@ static int dag_activate(pcap_t* handle)
        }
        
        /* Parse input name to get dag device and stream number if provided */
-       if (dag_parse_name(device, newDev, strlen(device) + 16, &handle->md.dag_stream) < 0) {
+       if (dag_parse_name(device, newDev, strlen(device) + 16, &handlep->dag_stream) < 0) {
                snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_parse_name: %s\n", pcap_strerror(errno));
                goto fail;
        }
        device = newDev;
 
-       if (handle->md.dag_stream%2) {
+       if (handlep->dag_stream%2) {
                snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_parse_name: tx (even numbered) streams not supported for capture\n");
                goto fail;
        }
@@ -644,7 +669,7 @@ static int dag_activate(pcap_t* handle)
 
 #ifdef HAVE_DAG_STREAMS_API
        /* Open requested stream. Can fail if already locked or on error */
-       if (dag_attach_stream(handle->fd, handle->md.dag_stream, 0, 0) < 0) {
+       if (dag_attach_stream(handle->fd, handlep->dag_stream, 0, 0) < 0) {
                snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_attach_stream: %s\n", pcap_strerror(errno));
                goto failclose;
        }
@@ -652,7 +677,7 @@ static int dag_activate(pcap_t* handle)
        /* Set up default poll parameters for stream
         * Can be overridden by pcap_set_nonblock()
         */
-       if (dag_get_stream_poll(handle->fd, handle->md.dag_stream,
+       if (dag_get_stream_poll(handle->fd, handlep->dag_stream,
                                &mindata, &maxwait, &poll) < 0) {
                snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_get_stream_poll: %s\n", pcap_strerror(errno));
                goto faildetach;
@@ -664,20 +689,20 @@ static int dag_activate(pcap_t* handle)
         */
        mindata = 65536;
 
-       /* Obey md.timeout (was to_ms) if supplied. This is a good idea!
+       /* Obey opt.timeout (was to_ms) if supplied. This is a good idea!
         * Recommend 10-100ms. Calls will time out even if no data arrived.
         */
-       maxwait.tv_sec = handle->md.timeout/1000;
-       maxwait.tv_usec = (handle->md.timeout%1000) * 1000;
+       maxwait.tv_sec = handle->opt.timeout/1000;
+       maxwait.tv_usec = (handle->opt.timeout%1000) * 1000;
 
-       if (dag_set_stream_poll(handle->fd, handle->md.dag_stream,
+       if (dag_set_stream_poll(handle->fd, handlep->dag_stream,
                                mindata, &maxwait, &poll) < 0) {
                snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_set_stream_poll: %s\n", pcap_strerror(errno));
                goto faildetach;
        }
                
 #else
-       if((handle->md.dag_mem_base = dag_mmap(handle->fd)) == MAP_FAILED) {
+       if((handlep->dag_mem_base = dag_mmap(handle->fd)) == MAP_FAILED) {
                snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,"dag_mmap %s: %s\n", device, pcap_strerror(errno));
                goto failclose;
        }
@@ -707,7 +732,7 @@ static int dag_activate(pcap_t* handle)
 #endif 
        
 #ifdef HAVE_DAG_STREAMS_API
-       if(dag_start_stream(handle->fd, handle->md.dag_stream) < 0) {
+       if(dag_start_stream(handle->fd, handlep->dag_stream) < 0) {
                snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_start_stream %s: %s\n", device, pcap_strerror(errno));
                goto faildetach;
        }
@@ -723,8 +748,8 @@ static int dag_activate(pcap_t* handle)
         * initialized to zero on startup, it won't give you
         * a compiler warning if you make this mistake!
         */
-       handle->md.dag_mem_bottom = 0;
-       handle->md.dag_mem_top = 0;
+       handlep->dag_mem_bottom = 0;
+       handlep->dag_mem_top = 0;
 
        /*
         * Find out how many FCS bits we should strip.
@@ -733,7 +758,7 @@ static int dag_activate(pcap_t* handle)
        daginf = dag_info(handle->fd);
        if ((0x4200 == daginf->device_code) || (0x4230 == daginf->device_code)) {
                /* DAG 4.2S and 4.23S already strip the FCS.  Stripping the final word again truncates the packet. */
-               handle->md.dag_fcs_bits = 0;
+               handlep->dag_fcs_bits = 0;
 
                /* Note that no FCS will be supplied. */
                handle->linktype_ext = LT_FCS_DATALINK_EXT(0);
@@ -741,12 +766,12 @@ static int dag_activate(pcap_t* handle)
                /*
                 * Start out assuming it's 32 bits.
                 */
-               handle->md.dag_fcs_bits = 32;
+               handlep->dag_fcs_bits = 32;
 
                /* Allow an environment variable to override. */
                if ((s = getenv("ERF_FCS_BITS")) != NULL) {
                        if ((n = atoi(s)) == 0 || n == 16 || n == 32) {
-                               handle->md.dag_fcs_bits = n;
+                               handlep->dag_fcs_bits = n;
                        } else {
                                snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
                                        "pcap_activate %s: bad ERF_FCS_BITS value (%d) in environment\n", device, n);
@@ -760,14 +785,14 @@ static int dag_activate(pcap_t* handle)
                if ((s = getenv("ERF_DONT_STRIP_FCS")) != NULL) {
                        /* Yes.  Note the number of bytes that will be
                           supplied. */
-                       handle->linktype_ext = LT_FCS_DATALINK_EXT(handle->md.dag_fcs_bits/16);
+                       handle->linktype_ext = LT_FCS_DATALINK_EXT(handlep->dag_fcs_bits/16);
 
                        /* And don't strip them. */
-                       handle->md.dag_fcs_bits = 0;
+                       handlep->dag_fcs_bits = 0;
                }
        }
 
-       handle->md.dag_timeout  = handle->md.timeout;
+       handlep->dag_timeout    = handle->opt.timeout;
 
        handle->linktype = -1;
        if (dag_get_datalink(handle) < 0)
@@ -798,19 +823,19 @@ static int dag_activate(pcap_t* handle)
        handle->setnonblock_op = dag_setnonblock;
        handle->stats_op = dag_stats;
        handle->cleanup_op = dag_platform_cleanup;
-       handle->md.stat.ps_drop = 0;
-       handle->md.stat.ps_recv = 0;
-       handle->md.stat.ps_ifdrop = 0;
+       handlep->stat.ps_drop = 0;
+       handlep->stat.ps_recv = 0;
+       handlep->stat.ps_ifdrop = 0;
        return 0;
 
 #ifdef HAVE_DAG_STREAMS_API 
 failstop:
-       if (dag_stop_stream(handle->fd, handle->md.dag_stream) < 0) {
+       if (dag_stop_stream(handle->fd, handlep->dag_stream) < 0) {
                fprintf(stderr,"dag_stop_stream: %s\n", strerror(errno));
        }
        
 faildetach:
-       if (dag_detach_stream(handle->fd, handle->md.dag_stream) < 0)
+       if (dag_detach_stream(handle->fd, handlep->dag_stream) < 0)
                fprintf(stderr,"dag_detach_stream: %s\n", strerror(errno));
 #else
 failstop:
@@ -866,7 +891,7 @@ pcap_t *dag_create(const char *device, char *ebuf, int *is_ours)
        /* OK, it's probably ours. */
        *is_ours = 1;
 
-       p = pcap_create_common(device, ebuf);
+       p = pcap_create_common(device, ebuf, sizeof (struct pcap_dag));
        if (p == NULL)
                return NULL;
 
@@ -876,13 +901,15 @@ pcap_t *dag_create(const char *device, char *ebuf, int *is_ours)
 
 static int
 dag_stats(pcap_t *p, struct pcap_stat *ps) {
+       struct pcap_dag *pd = p->private;
+
        /* This needs to be filled out correctly.  Hopefully a dagapi call will
                 provide all necessary information.
        */
-       /*p->md.stat.ps_recv = 0;*/
-       /*p->md.stat.ps_drop = 0;*/
+       /*pd->stat.ps_recv = 0;*/
+       /*pd->stat.ps_drop = 0;*/
        
-       *ps = p->md.stat;
+       *ps = pd->stat;
  
        return 0;
 }
@@ -972,8 +999,6 @@ dag_setfilter(pcap_t *p, struct bpf_program *fp)
        if (install_bpf_program(p, fp) < 0)
                return -1;
 
-       p->md.use_bpf = 0;
-
        return (0);
 }
 
@@ -988,11 +1013,13 @@ dag_set_datalink(pcap_t *p, int dlt)
 static int
 dag_setnonblock(pcap_t *p, int nonblock, char *errbuf)
 {
+       struct pcap_dag *pd = p->private;
+
        /*
         * Set non-blocking mode on the FD.
         * XXX - is that necessary?  If not, don't bother calling it,
         * and have a "dag_getnonblock()" function that looks at
-        * "p->md.dag_offset_flags".
+        * "pd->dag_offset_flags".
         */
        if (pcap_setnonblock_fd(p, nonblock, errbuf) < 0)
                return (-1);
@@ -1002,7 +1029,7 @@ dag_setnonblock(pcap_t *p, int nonblock, char *errbuf)
                struct timeval maxwait;
                struct timeval poll;
                
-               if (dag_get_stream_poll(p->fd, p->md.dag_stream,
+               if (dag_get_stream_poll(p->fd, pd->dag_stream,
                                        &mindata, &maxwait, &poll) < 0) {
                        snprintf(errbuf, PCAP_ERRBUF_SIZE, "dag_get_stream_poll: %s\n", pcap_strerror(errno));
                        return -1;
@@ -1017,7 +1044,7 @@ dag_setnonblock(pcap_t *p, int nonblock, char *errbuf)
                else
                        mindata = 65536;
                
-               if (dag_set_stream_poll(p->fd, p->md.dag_stream,
+               if (dag_set_stream_poll(p->fd, pd->dag_stream,
                                        mindata, &maxwait, &poll) < 0) {
                        snprintf(errbuf, PCAP_ERRBUF_SIZE, "dag_set_stream_poll: %s\n", pcap_strerror(errno));
                        return -1;
@@ -1025,9 +1052,9 @@ dag_setnonblock(pcap_t *p, int nonblock, char *errbuf)
        }
 #endif /* HAVE_DAG_STREAMS_API */
        if (nonblock) {
-               p->md.dag_offset_flags |= DAGF_NONBLOCK;
+               pd->dag_offset_flags |= DAGF_NONBLOCK;
        } else {
-               p->md.dag_offset_flags &= ~DAGF_NONBLOCK;
+               pd->dag_offset_flags &= ~DAGF_NONBLOCK;
        }
        return (0);
 }
@@ -1035,6 +1062,7 @@ dag_setnonblock(pcap_t *p, int nonblock, char *errbuf)
 static int
 dag_get_datalink(pcap_t *p)
 {
+       struct pcap_dag *pd = p->private;
        int index=0, dlt_index=0;
        uint8_t types[255];
 
@@ -1049,7 +1077,7 @@ dag_get_datalink(pcap_t *p)
 
 #ifdef HAVE_DAG_GET_STREAM_ERF_TYPES
        /* Get list of possible ERF types for this card */
-       if (dag_get_stream_erf_types(p->fd, p->md.dag_stream, types, 255) < 0) {
+       if (dag_get_stream_erf_types(p->fd, pd->dag_stream, types, 255) < 0) {
                snprintf(p->errbuf, sizeof(p->errbuf), "dag_get_stream_erf_types: %s", pcap_strerror(errno));
                return (-1);            
        }
index 40ace7f9f31f7d2de989849c390dae9cc76e6a19..3a54d444b35ac4e036dd3ad095931fed64c36256 100644 (file)
 #include "pcap-int.h"
 #include "pcap-dbus.h"
 
+/*
+ * Private data for capturing on D-Bus.
+ */
+struct pcap_dbus {
+       DBusConnection *conn;
+       u_int   packets_read;   /* count of packets read */
+};
+
 static int
 dbus_read(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user)
 {
-       DBusConnection *conn = handle->md.priv;
+       struct pcap_dbus *handlep = handle->private;
 
        struct pcap_pkthdr pkth;
        DBusMessage *message;
@@ -55,11 +63,11 @@ dbus_read(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user)
 
        int count = 0;
 
-       message = dbus_connection_pop_message(conn);
+       message = dbus_connection_pop_message(handlep->conn);
 
        while (!message) {
-               // XXX p->md.timeout = timeout_ms;
-               if (!dbus_connection_read_write(conn, 100)) {
+               // XXX handle->opt.timeout = timeout_ms;
+               if (!dbus_connection_read_write(handlep->conn, 100)) {
                        snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Connection closed");
                        return -1;
                }
@@ -69,7 +77,7 @@ dbus_read(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user)
                        return -2;
                }
 
-               message = dbus_connection_pop_message(conn);
+               message = dbus_connection_pop_message(handlep->conn);
        }
 
        if (dbus_message_is_signal(message, DBUS_INTERFACE_LOCAL, "Disconnected")) {
@@ -84,7 +92,7 @@ dbus_read(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user)
                gettimeofday(&pkth.ts, NULL);
                if (handle->fcode.bf_insns == NULL ||
                    bpf_filter(handle->fcode.bf_insns, (u_char *)raw_msg, pkth.len, pkth.caplen)) {
-                       handle->md.packets_read++;
+                       handlep->packets_read++;
                        callback(user, &pkth, (u_char *)raw_msg);
                        count++;
                }
@@ -98,7 +106,7 @@ static int
 dbus_write(pcap_t *handle, const void *buf, size_t size)
 {
        /* XXX, not tested */
-       DBusConnection *conn = handle->md.priv;
+       struct pcap_dbus *handlep = handle->private;
 
        DBusError error = DBUS_ERROR_INIT;
        DBusMessage *msg;
@@ -109,8 +117,8 @@ dbus_write(pcap_t *handle, const void *buf, size_t size)
                return -1;
        }
 
-       dbus_connection_send(conn, msg, NULL);
-       dbus_connection_flush(conn);
+       dbus_connection_send(handlep->conn, msg, NULL);
+       dbus_connection_flush(handlep->conn);
 
        dbus_message_unref(msg);
        return 0;
@@ -119,7 +127,9 @@ dbus_write(pcap_t *handle, const void *buf, size_t size)
 static int
 dbus_stats(pcap_t *handle, struct pcap_stat *stats)
 {
-       stats->ps_recv = handle->md.packets_read;
+       struct pcap_dbus *handlep = handle->private;
+
+       stats->ps_recv = handlep->packets_read;
        stats->ps_drop = 0;
        stats->ps_ifdrop = 0;
        return 0;
@@ -128,10 +138,9 @@ dbus_stats(pcap_t *handle, struct pcap_stat *stats)
 static void
 dbus_cleanup(pcap_t *handle)
 {
-       DBusConnection *conn = handle->md.priv;
+       struct pcap_dbus *handlep = handle->private;
 
-       handle->md.priv = NULL;
-       dbus_connection_unref(conn);
+       dbus_connection_unref(handlep->conn);
 
        pcap_cleanup_live_common(handle);
 }
@@ -150,21 +159,21 @@ dbus_activate(pcap_t *handle)
 
        #define N_RULES sizeof(rules)/sizeof(rules[0])
 
+       struct pcap_dbus *handlep = handle->private;
        const char *dev = handle->opt.source;
 
        DBusError error = DBUS_ERROR_INIT;
-       DBusConnection *conn;
        int i;
 
        if (strcmp(dev, "dbus-system") == 0) {
-               if (!(conn = dbus_bus_get(DBUS_BUS_SYSTEM, &error))) {
+               if (!(handlep->conn = dbus_bus_get(DBUS_BUS_SYSTEM, &error))) {
                        snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Failed to get system bus: %s", error.message);
                        dbus_error_free(&error);
                        return PCAP_ERROR;
                }
 
        } else if (strcmp(dev, "dbus-session") == 0) {
-               if (!(conn = dbus_bus_get(DBUS_BUS_SESSION, &error))) {
+               if (!(handlep->conn = dbus_bus_get(DBUS_BUS_SESSION, &error))) {
                        snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Failed to get session bus: %s", error.message);
                        dbus_error_free(&error);
                        return PCAP_ERROR;
@@ -173,13 +182,13 @@ dbus_activate(pcap_t *handle)
        } else if (strncmp(dev, "dbus://", 7) == 0) {
                const char *addr = dev + 7;
 
-               if (!(conn = dbus_connection_open(addr, &error))) {
+               if (!(handlep->conn = dbus_connection_open(addr, &error))) {
                        snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Failed to open connection to: %s: %s", addr, error.message);
                        dbus_error_free(&error);
                        return PCAP_ERROR;
                }
 
-               if (!dbus_bus_register(conn, &error)) {
+               if (!dbus_bus_register(handlep->conn, &error)) {
                        snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Failed to register bus %s: %s\n", addr, error.message);
                        dbus_error_free(&error);
                        return PCAP_ERROR;
@@ -204,7 +213,6 @@ dbus_activate(pcap_t *handle)
        handle->stats_op = dbus_stats;
 
        handle->selectable_fd = handle->fd = -1;
-       handle->md.priv = conn;
 
        if (handle->opt.rfmon) {
                /*
@@ -214,17 +222,17 @@ dbus_activate(pcap_t *handle)
                return PCAP_ERROR_RFMON_NOTSUP;
        }
 
-       /* dbus_connection_set_max_message_size(conn, handle->snapshot); */
+       /* dbus_connection_set_max_message_size(handlep->conn, handle->snapshot); */
        if (handle->opt.buffer_size != 0)
-               dbus_connection_set_max_received_size(conn, handle->opt.buffer_size);
+               dbus_connection_set_max_received_size(handlep->conn, handle->opt.buffer_size);
 
        for (i = 0; i < N_RULES; i++) {
-               dbus_bus_add_match(conn, rules[i], &error);
+               dbus_bus_add_match(handlep->conn, rules[i], &error);
                if (dbus_error_is_set(&error)) {
                        dbus_error_free(&error);
 
                        /* try without eavesdrop */
-                       dbus_bus_add_match(conn, rules[i] + strlen(EAVESDROPPING_RULE), &error);
+                       dbus_bus_add_match(handlep->conn, rules[i] + strlen(EAVESDROPPING_RULE), &error);
                        if (dbus_error_is_set(&error)) {
                                snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Failed to add bus match: %s\n", error.message);
                                dbus_error_free(&error);
@@ -251,7 +259,7 @@ dbus_create(const char *device, char *ebuf, int *is_ours)
        }
 
        *is_ours = 1;
-       p = pcap_create_common(device, ebuf);
+       p = pcap_create_common(device, ebuf, sizeof (struct pcap_dbus));
        if (p == NULL)
                return (NULL);
 
@@ -264,9 +272,9 @@ dbus_findalldevs(pcap_if_t **alldevsp, char *err_str)
 {
        pcap_if_t *found_dev = *alldevsp;
 
-       if (pcap_add_if(&found_dev, "dbus-system", 0, "D-BUS system bus", err_str) < 0)
+       if (pcap_add_if(&found_dev, "dbus-system", 0, "D-Bus system bus", err_str) < 0)
                return -1;
-       if (pcap_add_if(&found_dev, "dbus-session", 0, "D-BUS session bus", err_str) < 0)
+       if (pcap_add_if(&found_dev, "dbus-session", 0, "D-Bus session bus", err_str) < 0)
                return -1;
        return 0;
 }
index 4b285f39d156c5304bbd562450554c7ce97373b0..323fbad94c534a0feff518a0bb8cbdd2738167cd 100644 (file)
@@ -245,6 +245,9 @@ pcap_read_dlpi(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
 static int
 pcap_inject_dlpi(pcap_t *p, const void *buf, size_t size)
 {
+#ifdef DL_HP_RAWDLS
+       struct pcap_dlpi *pd = p->private;
+#endif
        int ret;
 
 #if defined(DLIOCRAW)
@@ -255,12 +258,12 @@ pcap_inject_dlpi(pcap_t *p, const void *buf, size_t size)
                return (-1);
        }
 #elif defined(DL_HP_RAWDLS)
-       if (p->send_fd < 0) {
+       if (pd->send_fd < 0) {
                snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
                    "send: Output FD couldn't be opened");
                return (-1);
        }
-       ret = dlrawdatareq(p->send_fd, buf, size);
+       ret = dlrawdatareq(pd->send_fd, buf, size);
        if (ret == -1) {
                snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
                    pcap_strerror(errno));
@@ -321,16 +324,23 @@ pcap_inject_dlpi(pcap_t *p, const void *buf, size_t size)
 static void
 pcap_cleanup_dlpi(pcap_t *p)
 {
-       if (p->send_fd >= 0) {
-               close(p->send_fd);
-               p->send_fd = -1;
+#ifdef DL_HP_RAWDLS
+       struct pcap_dlpi *pd = p->private;
+
+       if (pd->send_fd >= 0) {
+               close(pd->send_fd);
+               pd->send_fd = -1;
        }
+#endif
        pcap_cleanup_live_common(p);
 }
 
 static int
 pcap_activate_dlpi(pcap_t *p)
 {
+#ifdef DL_HP_RAWDLS
+       struct pcap_dlpi *pd = p->private;
+#endif
        register char *cp;
        int ppa;
 #ifdef HAVE_SOLARIS
@@ -398,13 +408,13 @@ pcap_activate_dlpi(pcap_t *p)
         * receiving packets on the same descriptor - you need separate
         * descriptors for sending and receiving, bound to different SAPs.
         *
-        * If the open fails, we just leave -1 in "p->send_fd" and reject
+        * If the open fails, we just leave -1 in "pd->send_fd" and reject
         * attempts to send packets, just as if, in pcap-bpf.c, we fail
         * to open the BPF device for reading and writing, we just try
         * to open it for reading only and, if that succeeds, just let
         * the send attempts fail.
         */
-       p->send_fd = open(cp, O_RDWR);
+       pd->send_fd = open(cp, O_RDWR);
 #endif
 
        /*
@@ -513,8 +523,8 @@ pcap_activate_dlpi(pcap_t *p)
                if (status < 0)
                        goto bad;
 #ifdef DL_HP_RAWDLS
-               if (p->send_fd >= 0) {
-                       if (dl_doattach(p->send_fd, ppa, p->errbuf) < 0)
+               if (pd->send_fd >= 0) {
+                       if (dl_doattach(pd->send_fd, ppa, p->errbuf) < 0)
                                goto bad;
                }
 #endif
@@ -570,13 +580,13 @@ pcap_activate_dlpi(pcap_t *p)
        */
        if (dl_dohpuxbind(p->fd, p->errbuf) < 0)
                goto bad;
-       if (p->send_fd >= 0) {
+       if (pd->send_fd >= 0) {
                /*
                ** XXX - if this fails, just close send_fd and
                ** set it to -1, so that you can't send but can
                ** still receive?
                */
-               if (dl_dohpuxbind(p->send_fd, p->errbuf) < 0)
+               if (dl_dohpuxbind(pd->send_fd, p->errbuf) < 0)
                        goto bad;
        }
 #else /* neither AIX nor HP-UX */
@@ -669,13 +679,13 @@ pcap_activate_dlpi(pcap_t *p)
        ** binding it anyway, just to keep the HP-UX 9/10.20 or later
        ** code together.
        */
-       if (p->send_fd >= 0) {
+       if (pd->send_fd >= 0) {
                /*
                ** XXX - if this fails, just close send_fd and
                ** set it to -1, so that you can't send but can
                ** still receive?
                */
-               if (dl_dohpuxbind(p->send_fd, p->errbuf) < 0)
+               if (dl_dohpuxbind(pd->send_fd, p->errbuf) < 0)
                        goto bad;
        }
 #endif
@@ -729,7 +739,7 @@ pcap_activate_dlpi(pcap_t *p)
 #endif
 
        /* Push and configure bufmod. */
-       if (pcap_conf_bufmod(p, ss, p->md.timeout) != 0)
+       if (pcap_conf_bufmod(p, ss, p->opt.timeout) != 0)
                goto bad;
 #endif
 
@@ -1696,12 +1706,18 @@ pcap_t *
 pcap_create_interface(const char *device, char *ebuf)
 {
        pcap_t *p;
+#ifdef DL_HP_RAWDLS
+       struct pcap_dlpi *pd;
+#endif
 
-       p = pcap_create_common(device, ebuf);
+       p = pcap_create_common(device, ebuf, sizeof (struct pcap_dlpi));
        if (p == NULL)
                return (NULL);
 
-       p->send_fd = -1;        /* it hasn't been opened yet */
+#ifdef DL_HP_RAWDLS
+       pd = p->private;
+       pd->send_fd = -1;       /* it hasn't been opened yet */
+#endif
 
        p->activate_op = pcap_activate_dlpi;
        return (p);
index 72e8fdec27cb583fb06249028605c220ae51c740..3c24758e15a4da747226d789856d2f97523c55d6 100644 (file)
@@ -143,11 +143,19 @@ static struct device *get_device (int fd)
   return handle_to_device [fd-1];
 }
 
+/*
+ * Private data for capturing on MS-DOS.
+ */
+struct pcap_dos {
+       void (*wait_proc)(void); /*          call proc while waiting */
+       struct pcap_stat stat;
+};
+
 pcap_t *pcap_create_interface (const char *device, char *ebuf)
 {
        pcap_t *p;
 
-       p = pcap_create_common(device, ebuf);
+       p = pcap_create_common(device, ebuf, sizeof (struct pcap_dos));
        if (p == NULL)
                return (NULL);
 
@@ -161,6 +169,8 @@ pcap_t *pcap_create_interface (const char *device, char *ebuf)
  */
 static int pcap_activate_dos (pcap_t *pcap)
 { 
+  struct pcap_dos *pcapd = pcap->private;
+
   if (pcap->opt.rfmon) {
     /*
      * No monitor mode on DOS.
@@ -210,15 +220,16 @@ static int pcap_activate_dos (pcap_t *pcap)
 static int
 pcap_read_one (pcap_t *p, pcap_handler callback, u_char *data)
 {
+  struct pcap_dos *pd = p->private;
   struct pcap_pkthdr pcap;
   struct timeval     now, expiry = { 0,0 };
   BYTE  *rx_buf;
   int    rx_len = 0;
 
-  if (p->md.timeout > 0)
+  if (p->opt.timeout > 0)
   {
     gettimeofday2 (&now, NULL);
-    expiry.tv_usec = now.tv_usec + 1000UL * p->md.timeout;
+    expiry.tv_usec = now.tv_usec + 1000UL * p->opt.timeout;
     expiry.tv_sec  = now.tv_sec;
     while (expiry.tv_usec >= 1000000L)
     {
@@ -290,7 +301,7 @@ pcap_read_one (pcap_t *p, pcap_handler callback, u_char *data)
     /* If not to wait for a packet or pcap_cleanup_dos() called from
      * e.g. SIGINT handler, exit loop now.
      */
-    if (p->md.timeout <= 0 || (volatile int)p->fd <= 0)
+    if (p->opt.timeout <= 0 || (volatile int)p->fd <= 0)
        break;
 
     gettimeofday2 (&now, NULL);
@@ -308,7 +319,7 @@ pcap_read_one (pcap_t *p, pcap_handler callback, u_char *data)
 
   if (rx_len < 0)            /* receive error */
   {
-    p->md.stat.ps_drop++;
+    pd->stat.ps_drop++;
 #ifdef USE_32BIT_DRIVERS
     if (pcap_pkt_debug > 1)
        printk ("pkt-err %s\n", pktInfo.error);
@@ -321,6 +332,7 @@ pcap_read_one (pcap_t *p, pcap_handler callback, u_char *data)
 static int
 pcap_read_dos (pcap_t *p, int cnt, pcap_handler callback, u_char *data)
 {
+  struct pcap_dos *pd = p->private;
   int rc, num = 0;
 
   while (num <= cnt || (cnt < 0))
@@ -343,6 +355,7 @@ pcap_read_dos (pcap_t *p, int cnt, pcap_handler callback, u_char *data)
 static int pcap_stats_dos (pcap_t *p, struct pcap_stat *ps)
 {
   struct net_device_stats *stats;
+  struct pcap_dos         *pd;
   struct device           *dev = p ? get_device(p->fd) : NULL;
 
   if (!dev)
@@ -359,12 +372,13 @@ static int pcap_stats_dos (pcap_t *p, struct pcap_stat *ps)
 
   FLUSHK();
 
-  p->md.stat.ps_recv   = stats->rx_packets;
-  p->md.stat.ps_drop  += stats->rx_missed_errors;
-  p->md.stat.ps_ifdrop = stats->rx_dropped +  /* queue full */
+  pd = p->private;
+  pd->stat.ps_recv   = stats->rx_packets;
+  pd->stat.ps_drop  += stats->rx_missed_errors;
+  pd->stat.ps_ifdrop = stats->rx_dropped +  /* queue full */
                          stats->rx_errors;    /* HW errors */
   if (ps)
-     *ps = p->md.stat;
+     *ps = pd->stat;
 
   return (0);
 }
@@ -428,10 +442,13 @@ u_long pcap_filter_packets (void)
  */
 static void pcap_cleanup_dos (pcap_t *p)
 {
+  struct pcap_dos *pd;
+
   if (p && !exc_occured)
   {
+    pd = p->private;
     if (pcap_stats(p,NULL) < 0)
-       p->md.stat.ps_drop = 0;
+       pd->stat.ps_drop = 0;
     if (!get_device(p->fd))
        return;
 
@@ -590,10 +607,12 @@ void pcap_assert (const char *what, const char *file, unsigned line)
  */
 void pcap_set_wait (pcap_t *p, void (*yield)(void), int wait)
 {
+  struct pcap_dos *pd;
   if (p)
   {
-    p->wait_proc         = yield;
-    p->md.timeout        = wait;
+    pd                   = p->private;
+    pd->wait_proc        = yield;
+    p->opt.timeout        = wait;
   }
 }
 
index 28b80fb4fd13d72c4df1aef1e1f3400f213723b1..3527ca349aafa77ee749ae58a6a5317d74696b17 100644 (file)
 extern "C" {
 #endif
 
-#ifdef HAVE_LIBDLPI
-#include <libdlpi.h>
-#endif
-
 #ifdef WIN32
 #include <Packet32.h>
 extern CRITICAL_SECTION g_PcapCompileCriticalSection;
@@ -56,10 +52,6 @@ extern CRITICAL_SECTION g_PcapCompileCriticalSection;
 #include <io.h>
 #endif
 
-#ifdef HAVE_SNF_API
-#include <snf.h>
-#endif
-
 #if (defined(_MSC_VER) && (_MSC_VER <= 1200)) /* we are compiling with Visual Studio 6, that doesn't support the LL suffix*/
 
 /*
@@ -92,124 +84,8 @@ extern CRITICAL_SECTION g_PcapCompileCriticalSection;
 
 #endif /* _MSC_VER */
 
-/*
- * Savefile
- */
-typedef enum {
-       NOT_SWAPPED,
-       SWAPPED,
-       MAYBE_SWAPPED
-} swapped_type_t;
-
-/*
- * Used when reading a savefile.
- */
-struct pcap_sf {
-       FILE *rfile;
-       int (*next_packet_op)(pcap_t *, struct pcap_pkthdr *, u_char **);
-       int swapped;
-       size_t hdrsize;
-       swapped_type_t lengths_swapped;
-       int version_major;
-       int version_minor;
-       bpf_u_int32 ifcount;    /* number of interfaces seen in this capture */
-       u_int tsresol;          /* time stamp resolution */
-       u_int tsscale;          /* scaling factor for resolution -> microseconds */
-       u_int64_t tsoffset;     /* time stamp offset */
-};
-
-/*
- * Used when doing a live capture.
- */
-struct pcap_md {
-       struct pcap_stat stat;
-       /*XXX*/
-       int use_bpf;            /* using kernel filter */
-       u_long  TotPkts;        /* can't oflow for 79 hrs on ether */
-       u_long  TotAccepted;    /* count accepted by filter */
-       u_long  TotDrops;       /* count of dropped packets */
-       long    TotMissed;      /* missed by i/f during this run */
-       long    OrigMissed;     /* missed by i/f before this run */
-       char    *device;        /* device name */
-       int     timeout;        /* timeout for buffering */
-       int     must_do_on_close; /* stuff we must do when we close */
-       struct pcap *next;      /* list of open pcaps that need stuff cleared on close */
-#if defined(linux) || defined(PCAP_SUPPORT_DBUS)
-       u_int   packets_read;   /* count of packets read with recvfrom() */
-#endif
-#ifdef linux
-       int     sock_packet;    /* using Linux 2.0 compatible interface */
-       int     cooked;         /* using SOCK_DGRAM rather than SOCK_RAW */
-       int     ifindex;        /* interface index of device we're bound to */
-       int     lo_ifindex;     /* interface index of the loopback device */
-       bpf_u_int32 oldmode;    /* mode to restore when turning monitor mode off */
-       char    *mondevice;     /* mac80211 monitor device we created */
-       u_char  *mmapbuf;       /* memory-mapped region pointer */
-       size_t  mmapbuflen;     /* size of region */
-       int     vlan_offset;    /* offset at which to insert vlan tags; if -1, don't insert */
-       u_int   tp_version;     /* version of tpacket_hdr for mmaped ring */
-       u_int   tp_hdrlen;      /* hdrlen of tpacket_hdr for mmaped ring */
-       u_char  *oneshot_buffer; /* buffer for copy of packet */
-       long    proc_dropped; /* packets reported dropped by /proc/net/dev */
-#endif /* linux */
-
-#ifdef HAVE_DAG_API
-#ifdef HAVE_DAG_STREAMS_API
-       u_char  *dag_mem_bottom;        /* DAG card current memory bottom pointer */
-       u_char  *dag_mem_top;   /* DAG card current memory top pointer */
-#else /* HAVE_DAG_STREAMS_API */
-       void    *dag_mem_base;  /* DAG card memory base address */
-       u_int   dag_mem_bottom; /* DAG card current memory bottom offset */
-       u_int   dag_mem_top;    /* DAG card current memory top offset */
-#endif /* HAVE_DAG_STREAMS_API */
-       int     dag_fcs_bits;   /* Number of checksum bits from link layer */
-       int     dag_offset_flags; /* Flags to pass to dag_offset(). */
-       int     dag_stream;     /* DAG stream number */
-       int     dag_timeout;    /* timeout specified to pcap_open_live.
-                                * Same as in linux above, introduce
-                                * generally? */
-#endif /* HAVE_DAG_API */
-#ifdef HAVE_SNF_API
-       snf_handle_t snf_handle; /* opaque device handle */
-       snf_ring_t   snf_ring;   /* opaque device ring handle */
-        int          snf_timeout;
-        int          snf_boardnum;
-#endif /*HAVE_SNF_API*/
-
-#ifdef HAVE_ZEROCOPY_BPF
-       /*
-        * Zero-copy read buffer -- for zero-copy BPF.  'buffer' above will
-        * alternative between these two actual mmap'd buffers as required.
-        * As there is a header on the front size of the mmap'd buffer, only
-        * some of the buffer is exposed to libpcap as a whole via bufsize;
-        * zbufsize is the true size.  zbuffer tracks the current zbuf
-        * assocated with buffer so that it can be used to decide which the
-        * next buffer to read will be.
-        */
-       u_char *zbuf1, *zbuf2, *zbuffer;
-       u_int zbufsize;
-       u_int zerocopy;
-       u_int interrupted;
-       struct timespec firstsel;
-       /*
-        * If there's currently a buffer being actively processed, then it is
-        * referenced here; 'buffer' is also pointed at it, but offset by the
-        * size of the header.
-        */
-       struct bpf_zbuf_header *bzh;
-#endif /* HAVE_ZEROCOPY_BPF */
-
-       void *priv;
-};
-
-/*
- * Stuff to do when we close.
- */
-#define MUST_CLEAR_PROMISC     0x00000001      /* clear promiscuous mode */
-#define MUST_CLEAR_RFMON       0x00000002      /* clear rfmon (monitor) mode */
-#define MUST_DELETE_MONIF      0x00000004      /* delete monitor-mode interface */
-
 struct pcap_opt {
+       int     timeout;        /* timeout for buffering */
        int     buffer_size;
        char    *source;
        int     promisc;
@@ -217,19 +93,6 @@ struct pcap_opt {
        int     tstamp_type;
 };
 
-/*
- * Ultrix, DEC OSF/1^H^H^H^H^H^H^H^H^HDigital UNIX^H^H^H^H^H^H^H^H^H^H^H^H
- * Tru64 UNIX, and some versions of NetBSD pad FDDI packets to make everything
- * line up on a nice boundary.
- */
-#ifdef __NetBSD__
-#include <sys/param.h> /* needed to declare __NetBSD_Version__ */
-#endif
-
-#if defined(ultrix) || defined(__osf__) || (defined(__NetBSD__) && __NetBSD_Version__ > 106000000)
-#define       PCAP_FDDIPAD 3
-#endif
-
 typedef int    (*activate_op_t)(pcap_t *);
 typedef int    (*can_set_rfmon_op_t)(pcap_t *);
 typedef int    (*read_op_t)(pcap_t *, int cnt, pcap_handler, u_char *);
@@ -247,7 +110,21 @@ typedef int        (*setmintocopy_op_t)(pcap_t *, int);
 #endif
 typedef void   (*cleanup_op_t)(pcap_t *);
 
+/*
+ * We put all the stuff used in the read code path at the beginning,
+ * to try to keep it together in the same cache line or lines.
+ */
 struct pcap {
+       /*
+        * Method to call to read packets on a live capture.
+        */
+       read_op_t read_op;
+
+       /*
+        * Method to call to read to read packets from a savefile.
+        */
+       int (*next_packet_op)(pcap_t *, struct pcap_pkthdr *, u_char **);
+
 #ifdef WIN32
        ADAPTER *adapter;
        LPPACKET Packet;
@@ -255,12 +132,34 @@ struct pcap {
 #else
        int fd;
        int selectable_fd;
-       int send_fd;
 #endif /* WIN32 */
 
-#ifdef HAVE_LIBDLPI
-       dlpi_handle_t dlpi_hd;
-#endif
+       /*
+        * Read buffer.
+        */
+       int bufsize;
+       u_char *buffer;
+       u_char *bp;
+       int cc;
+
+       int break_loop;         /* flag set to force break from packet-reading loop */
+
+       void *private;          /* private data for methods */
+
+       int swapped;
+       FILE *rfile;            /* null if live capture, non-null if savefile */
+       int fddipad;
+       struct pcap *next;      /* list of open pcaps that need stuff cleared on close */
+
+       /*
+        * File version number; meaningful only for a savefile, but we
+        * keep it here so that apps that (mistakenly) ask for the
+        * version numbers will get the same zero values that they
+        * always did.
+        */
+       int version_major;
+       int version_minor;
+
        int snapshot;
        int linktype;           /* Network linktype */
        int linktype_ext;       /* Extended information stored in the linktype field of a file */
@@ -269,28 +168,8 @@ struct pcap {
        int activated;          /* true if the capture is really started */
        int oldstyle;           /* if we're opening with pcap_open_live() */
 
-       int break_loop;         /* flag set to force break from packet-reading loop */
-
-#ifdef PCAP_FDDIPAD
-       int fddipad;
-#endif
-
-#ifdef MSDOS
-        void (*wait_proc)(void); /*          call proc while waiting */
-#endif
-
-       struct pcap_sf sf;
-       struct pcap_md md;
        struct pcap_opt opt;
 
-       /*
-        * Read buffer.
-        */
-       int bufsize;
-       u_char *buffer;
-       u_char *bp;
-       int cc;
-
        /*
         * Place holder for pcap_next().
         */
@@ -300,11 +179,23 @@ struct pcap {
        pcap_direction_t direction;
 
        /*
-        * Methods.
+        * Placeholder for filter code if bpf not in kernel.
+        */
+       struct bpf_program fcode;
+
+       char errbuf[PCAP_ERRBUF_SIZE + 1];
+       int dlt_count;
+       u_int *dlt_list;
+       int tstamp_type_count;
+       u_int *tstamp_type_list;
+
+       struct pcap_pkthdr pcap_header; /* This is needed for the pcap_next_ex() to work */
+
+       /*
+        * More methods.
         */
        activate_op_t activate_op;
        can_set_rfmon_op_t can_set_rfmon_op;
-       read_op_t read_op;
        inject_op_t inject_op;
        setfilter_op_t setfilter_op;
        setdirection_op_t setdirection_op;
@@ -328,19 +219,6 @@ struct pcap {
        setmintocopy_op_t setmintocopy_op;
 #endif
        cleanup_op_t cleanup_op;
-
-       /*
-        * Placeholder for filter code if bpf not in kernel.
-        */
-       struct bpf_program fcode;
-
-       char errbuf[PCAP_ERRBUF_SIZE + 1];
-       int dlt_count;
-       u_int *dlt_list;
-       int tstamp_type_count;
-       u_int *tstamp_type_list;
-
-       struct pcap_pkthdr pcap_header; /* This is needed for the pcap_next_ex() to work */
 };
 
 /*
@@ -472,7 +350,7 @@ int pcap_setnonblock_fd(pcap_t *p, int, char *);
  * by pcap_create routines.
  */
 pcap_t *pcap_create_interface(const char *, char *);
-pcap_t *pcap_create_common(const char *, char *);
+pcap_t *pcap_create_common(const char *, char *, size_t);
 int    pcap_do_addexit(pcap_t *);
 void   pcap_add_to_pcaps_to_close(pcap_t *);
 void   pcap_remove_from_pcaps_to_close(pcap_t *);
@@ -502,6 +380,14 @@ struct sockaddr *dup_sockaddr(struct sockaddr *, size_t);
 int    add_or_find_if(pcap_if_t **, pcap_if_t **, const char *, u_int,
            const char *, char *);
 
+/*
+ * Internal interfaces for "pcap_open_offline()".
+ *
+ * "pcap_open_offline_common()" allocates and fills in a pcap_t, for use
+ * by pcap_open_offline routines.
+ */
+pcap_t *pcap_open_offline_common(char *ebuf, size_t size);
+
 #ifdef WIN32
 char   *pcap_win32strerror(void);
 #endif
index acaa400de419128416ec9edf8e905c29e60235bd..351e9846a5083caf1a16e136c5054ffeba7be0ee 100644 (file)
@@ -100,6 +100,7 @@ list_interfaces(const char *linkname, void *arg)
 static int
 pcap_activate_libdlpi(pcap_t *p)
 {
+       struct pcap_dlpi *pd = p->private;
        int retv;
        dlpi_handle_t dh;
        dlpi_info_t dlinfo;
@@ -121,7 +122,7 @@ pcap_activate_libdlpi(pcap_t *p)
                    p->errbuf);
                return (err);
        }
-       p->dlpi_hd = dh;
+       pd->dlpi_hd = dh;
 
        if (p->opt.rfmon) {
                /*
@@ -133,7 +134,7 @@ pcap_activate_libdlpi(pcap_t *p)
        }
 
        /* Bind with DLPI_ANY_SAP. */
-       if ((retv = dlpi_bind(p->dlpi_hd, DLPI_ANY_SAP, 0)) != DLPI_SUCCESS) {
+       if ((retv = dlpi_bind(pd->dlpi_hd, DLPI_ANY_SAP, 0)) != DLPI_SUCCESS) {
                pcap_libdlpi_err(p->opt.source, "dlpi_bind", retv, p->errbuf);
                goto bad;
        }
@@ -180,7 +181,7 @@ pcap_activate_libdlpi(pcap_t *p)
        }
 
        /* Determine link type.  */
-       if ((retv = dlpi_info(p->dlpi_hd, &dlinfo, 0)) != DLPI_SUCCESS) {
+       if ((retv = dlpi_info(pd->dlpi_hd, &dlinfo, 0)) != DLPI_SUCCESS) {
                pcap_libdlpi_err(p->opt.source, "dlpi_info", retv, p->errbuf);
                goto bad;
        }
@@ -188,10 +189,10 @@ pcap_activate_libdlpi(pcap_t *p)
        if (pcap_process_mactype(p, dlinfo.di_mactype) != 0)
                goto bad;
 
-       p->fd = dlpi_fd(p->dlpi_hd);
+       p->fd = dlpi_fd(pd->dlpi_hd);
 
        /* Push and configure bufmod. */
-       if (pcap_conf_bufmod(p, p->snapshot, p->md.timeout) != 0)
+       if (pcap_conf_bufmod(p, p->snapshot, p->opt.timeout) != 0)
                goto bad;
 
        /*
@@ -234,10 +235,11 @@ bad:
 static int
 dlpromiscon(pcap_t *p, bpf_u_int32 level)
 {
+       struct pcap_dlpi *pd = p->private;
        int retv;
        int err;
 
-       retv = dlpi_promiscon(p->dlpi_hd, level);
+       retv = dlpi_promiscon(pd->dlpi_hd, level);
        if (retv != DLPI_SUCCESS) {
                if (retv == DL_SYSERR &&
                    (errno == EPERM || errno == EACCES))
@@ -299,6 +301,7 @@ done:
 static int
 pcap_read_libdlpi(pcap_t *p, int count, pcap_handler callback, u_char *user)
 {
+       struct pcap_dlpi *pd = p->private;
        int len;
        u_char *bufp;
        size_t msglen;
@@ -324,7 +327,7 @@ pcap_read_libdlpi(pcap_t *p, int count, pcap_handler callback, u_char *user)
                msglen = p->bufsize;
                bufp = p->buffer + p->offset;
 
-               retv = dlpi_recv(p->dlpi_hd, NULL, NULL, bufp,
+               retv = dlpi_recv(pd->dlpi_hd, NULL, NULL, bufp,
                    &msglen, -1, NULL);
                if (retv != DLPI_SUCCESS) {
                        /*
@@ -336,7 +339,7 @@ pcap_read_libdlpi(pcap_t *p, int count, pcap_handler callback, u_char *user)
                                len = 0;
                                continue;
                        }
-                       pcap_libdlpi_err(dlpi_linkname(p->dlpi_hd),
+                       pcap_libdlpi_err(dlpi_linkname(pd->dlpi_hd),
                            "dlpi_recv", retv, p->errbuf);
                        return (-1);
                }
@@ -350,11 +353,12 @@ process_pkts:
 static int
 pcap_inject_libdlpi(pcap_t *p, const void *buf, size_t size)
 {
+       struct pcap_dlpi *pd = p->private;
        int retv;
 
-       retv = dlpi_send(p->dlpi_hd, NULL, 0, buf, size, NULL);
+       retv = dlpi_send(pd->dlpi_hd, NULL, 0, buf, size, NULL);
        if (retv != DLPI_SUCCESS) {
-               pcap_libdlpi_err(dlpi_linkname(p->dlpi_hd), "dlpi_send", retv,
+               pcap_libdlpi_err(dlpi_linkname(pd->dlpi_hd), "dlpi_send", retv,
                    p->errbuf);
                return (-1);
        }
@@ -372,9 +376,11 @@ pcap_inject_libdlpi(pcap_t *p, const void *buf, size_t size)
 static void
 pcap_cleanup_libdlpi(pcap_t *p)
 {
-       if (p->dlpi_hd != NULL) {
-               dlpi_close(p->dlpi_hd);
-               p->dlpi_hd = NULL;
+       struct pcap_dlpi *pd = p->private;
+
+       if (pd->dlpi_hd != NULL) {
+               dlpi_close(pd->dlpi_hd);
+               pd->dlpi_hd = NULL;
                p->fd = -1;
        }
        pcap_cleanup_live_common(p);
@@ -395,7 +401,7 @@ pcap_create_interface(const char *device, char *ebuf)
 {
        pcap_t *p;
 
-       p = pcap_create_common(device, ebuf);
+       p = pcap_create_common(device, ebuf, sizeof (struct pcap_dlpi));
        if (p == NULL)
                return (NULL);
 
index 201f2aade2baa6d1cb3a1875d5899e6039972563..e49af804be85e1aadfae662a12c2a237631471dd 100644 (file)
@@ -283,6 +283,39 @@ typedef int                socklen_t;
  */
 #define BIGGER_THAN_ALL_MTUS   (64*1024)
 
+/*
+ * Private data for capturing on Linux SOCK_PACKET or PF_PACKET sockets.
+ */
+struct pcap_linux {
+       u_int   packets_read;   /* count of packets read with recvfrom() */
+       long    proc_dropped;   /* packets reported dropped by /proc/net/dev */
+       struct pcap_stat stat;
+
+       char    *device;        /* device name */
+       int     filtering_in_kernel; /* using kernel filter */
+       int     must_do_on_close; /* stuff we must do when we close */
+       int     timeout;        /* timeout for buffering */
+       int     sock_packet;    /* using Linux 2.0 compatible interface */
+       int     cooked;         /* using SOCK_DGRAM rather than SOCK_RAW */
+       int     ifindex;        /* interface index of device we're bound to */
+       int     lo_ifindex;     /* interface index of the loopback device */
+       bpf_u_int32 oldmode;    /* mode to restore when turning monitor mode off */
+       char    *mondevice;     /* mac80211 monitor device we created */
+       u_char  *mmapbuf;       /* memory-mapped region pointer */
+       size_t  mmapbuflen;     /* size of region */
+       int     vlan_offset;    /* offset at which to insert vlan tags; if -1, don't insert */
+       u_int   tp_version;     /* version of tpacket_hdr for mmaped ring */
+       u_int   tp_hdrlen;      /* hdrlen of tpacket_hdr for mmaped ring */
+       u_char  *oneshot_buffer; /* buffer for copy of packet */
+};
+
+/*
+ * Stuff to do when we close.
+ */
+#define MUST_CLEAR_PROMISC     0x00000001      /* clear promiscuous mode */
+#define MUST_CLEAR_RFMON       0x00000002      /* clear rfmon (monitor) mode */
+#define MUST_DELETE_MONIF      0x00000004      /* delete monitor-mode interface */
+
 /*
  * Prototypes for internal functions and methods.
  */
@@ -362,7 +395,7 @@ pcap_create_interface(const char *device, char *ebuf)
 {
        pcap_t *handle;
 
-       handle = pcap_create_common(device, ebuf);
+       handle = pcap_create_common(device, ebuf, sizeof (struct pcap_linux));
        if (handle == NULL)
                return NULL;
 
@@ -721,6 +754,7 @@ nla_put_failure:
 static int
 enter_rfmon_mode_mac80211(pcap_t *handle, int sock_fd, const char *device)
 {
+       struct pcap_linux *handlep = handle->private;
        int ret;
        char phydev_path[PATH_MAX+1];
        struct nl80211_state nlstate;
@@ -758,7 +792,7 @@ enter_rfmon_mode_mac80211(pcap_t *handle, int sock_fd, const char *device)
                snprintf(mondevice, sizeof mondevice, "mon%u", n);
                ret = add_mon_if(handle, sock_fd, &nlstate, device, mondevice);
                if (ret == 1) {
-                       handle->md.mondevice = strdup(mondevice);
+                       handlep->mondevice = strdup(mondevice);
                        goto added;
                }
                if (ret < 0) {
@@ -803,13 +837,13 @@ added:
         * Now configure the monitor interface up.
         */
        memset(&ifr, 0, sizeof(ifr));
-       strncpy(ifr.ifr_name, handle->md.mondevice, sizeof(ifr.ifr_name));
+       strncpy(ifr.ifr_name, handlep->mondevice, sizeof(ifr.ifr_name));
        if (ioctl(sock_fd, SIOCGIFFLAGS, &ifr) == -1) {
                snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
                    "%s: Can't get flags for %s: %s", device,
-                   handle->md.mondevice, strerror(errno));
+                   handlep->mondevice, strerror(errno));
                del_mon_if(handle, sock_fd, &nlstate, device,
-                   handle->md.mondevice);
+                   handlep->mondevice);
                nl80211_cleanup(&nlstate);
                return PCAP_ERROR;
        }
@@ -817,9 +851,9 @@ added:
        if (ioctl(sock_fd, SIOCSIFFLAGS, &ifr) == -1) {
                snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
                    "%s: Can't set flags for %s: %s", device,
-                   handle->md.mondevice, strerror(errno));
+                   handlep->mondevice, strerror(errno));
                del_mon_if(handle, sock_fd, &nlstate, device,
-                   handle->md.mondevice);
+                   handlep->mondevice);
                nl80211_cleanup(&nlstate);
                return PCAP_ERROR;
        }
@@ -833,7 +867,7 @@ added:
         * Note that we have to delete the monitor device when we close
         * the handle.
         */
-       handle->md.must_do_on_close |= MUST_DELETE_MONIF;
+       handlep->must_do_on_close |= MUST_DELETE_MONIF;
 
        /*
         * Add this to the list of pcaps to close when we exit.
@@ -1002,6 +1036,7 @@ linux_if_drops(const char * if_name)
 
 static void    pcap_cleanup_linux( pcap_t *handle )
 {
+       struct pcap_linux *handlep = handle->private;
        struct ifreq    ifr;
 #ifdef HAVE_LIBNL
        struct nl80211_state nlstate;
@@ -1012,12 +1047,12 @@ static void     pcap_cleanup_linux( pcap_t *handle )
        struct iwreq ireq;
 #endif /* IW_MODE_MONITOR */
 
-       if (handle->md.must_do_on_close != 0) {
+       if (handlep->must_do_on_close != 0) {
                /*
                 * There's something we have to do when closing this
                 * pcap_t.
                 */
-               if (handle->md.must_do_on_close & MUST_CLEAR_PROMISC) {
+               if (handlep->must_do_on_close & MUST_CLEAR_PROMISC) {
                        /*
                         * We put the interface into promiscuous mode;
                         * take it out of promiscuous mode.
@@ -1028,14 +1063,14 @@ static void     pcap_cleanup_linux( pcap_t *handle )
                         * in 2.0[.x] kernels.
                         */
                        memset(&ifr, 0, sizeof(ifr));
-                       strncpy(ifr.ifr_name, handle->md.device,
+                       strncpy(ifr.ifr_name, handlep->device,
                            sizeof(ifr.ifr_name));
                        if (ioctl(handle->fd, SIOCGIFFLAGS, &ifr) == -1) {
                                fprintf(stderr,
                                    "Can't restore interface %s flags (SIOCGIFFLAGS failed: %s).\n"
                                    "Please adjust manually.\n"
                                    "Hint: This can't happen with Linux >= 2.2.0.\n",
-                                   handle->md.device, strerror(errno));
+                                   handlep->device, strerror(errno));
                        } else {
                                if (ifr.ifr_flags & IFF_PROMISC) {
                                        /*
@@ -1049,7 +1084,7 @@ static void       pcap_cleanup_linux( pcap_t *handle )
                                                    "Can't restore interface %s flags (SIOCSIFFLAGS failed: %s).\n"
                                                    "Please adjust manually.\n"
                                                    "Hint: This can't happen with Linux >= 2.2.0.\n",
-                                                   handle->md.device,
+                                                   handlep->device,
                                                    strerror(errno));
                                        }
                                }
@@ -1057,24 +1092,24 @@ static void     pcap_cleanup_linux( pcap_t *handle )
                }
 
 #ifdef HAVE_LIBNL
-               if (handle->md.must_do_on_close & MUST_DELETE_MONIF) {
-                       ret = nl80211_init(handle, &nlstate, handle->md.device);
+               if (handlep->must_do_on_close & MUST_DELETE_MONIF) {
+                       ret = nl80211_init(handle, &nlstate, handlep->device);
                        if (ret >= 0) {
                                ret = del_mon_if(handle, handle->fd, &nlstate,
-                                   handle->md.device, handle->md.mondevice);
+                                   handlep->device, handlep->mondevice);
                                nl80211_cleanup(&nlstate);
                        }
                        if (ret < 0) {
                                fprintf(stderr,
                                    "Can't delete monitor interface %s (%s).\n"
                                    "Please delete manually.\n",
-                                   handle->md.mondevice, handle->errbuf);
+                                   handlep->mondevice, handle->errbuf);
                        }
                }
 #endif /* HAVE_LIBNL */
 
 #ifdef IW_MODE_MONITOR
-               if (handle->md.must_do_on_close & MUST_CLEAR_RFMON) {
+               if (handlep->must_do_on_close & MUST_CLEAR_RFMON) {
                        /*
                         * We put the interface into rfmon mode;
                         * take it out of rfmon mode.
@@ -1092,7 +1127,7 @@ static void       pcap_cleanup_linux( pcap_t *handle )
                         */
                        oldflags = 0;
                        memset(&ifr, 0, sizeof(ifr));
-                       strncpy(ifr.ifr_name, handle->md.device,
+                       strncpy(ifr.ifr_name, handlep->device,
                            sizeof(ifr.ifr_name));
                        if (ioctl(handle->fd, SIOCGIFFLAGS, &ifr) != -1) {
                                if (ifr.ifr_flags & IFF_UP) {
@@ -1106,11 +1141,11 @@ static void     pcap_cleanup_linux( pcap_t *handle )
                        /*
                         * Now restore the mode.
                         */
-                       strncpy(ireq.ifr_ifrn.ifrn_name, handle->md.device,
+                       strncpy(ireq.ifr_ifrn.ifrn_name, handlep->device,
                            sizeof ireq.ifr_ifrn.ifrn_name);
                        ireq.ifr_ifrn.ifrn_name[sizeof ireq.ifr_ifrn.ifrn_name - 1]
                            = 0;
-                       ireq.u.mode = handle->md.oldmode;
+                       ireq.u.mode = handlep->oldmode;
                        if (ioctl(handle->fd, SIOCSIWMODE, &ireq) == -1) {
                                /*
                                 * Scientist, you've failed.
@@ -1118,7 +1153,7 @@ static void       pcap_cleanup_linux( pcap_t *handle )
                                fprintf(stderr,
                                    "Can't restore interface %s wireless mode (SIOCSIWMODE failed: %s).\n"
                                    "Please adjust manually.\n",
-                                   handle->md.device, strerror(errno));
+                                   handlep->device, strerror(errno));
                        }
 
                        /*
@@ -1131,7 +1166,7 @@ static void       pcap_cleanup_linux( pcap_t *handle )
                                        fprintf(stderr,
                                            "Can't bring interface %s back up (SIOCSIFFLAGS failed: %s).\n"
                                            "Please adjust manually.\n",
-                                           handle->md.device, strerror(errno));
+                                           handlep->device, strerror(errno));
                                }
                        }
                }
@@ -1144,13 +1179,13 @@ static void     pcap_cleanup_linux( pcap_t *handle )
                pcap_remove_from_pcaps_to_close(handle);
        }
 
-       if (handle->md.mondevice != NULL) {
-               free(handle->md.mondevice);
-               handle->md.mondevice = NULL;
+       if (handlep->mondevice != NULL) {
+               free(handlep->mondevice);
+               handlep->mondevice = NULL;
        }
-       if (handle->md.device != NULL) {
-               free(handle->md.device);
-               handle->md.device = NULL;
+       if (handlep->device != NULL) {
+               free(handlep->device);
+               handlep->device = NULL;
        }
        pcap_cleanup_live_common(handle);
 }
@@ -1166,6 +1201,7 @@ static void       pcap_cleanup_linux( pcap_t *handle )
 static int
 pcap_activate_linux(pcap_t *handle)
 {
+       struct pcap_linux *handlep = handle->private;
        const char      *device;
        int             status = 0;
 
@@ -1196,20 +1232,23 @@ pcap_activate_linux(pcap_t *handle)
                }
        }
 
-       handle->md.device       = strdup(device);
-       if (handle->md.device == NULL) {
+       handlep->device = strdup(device);
+       if (handlep->device == NULL) {
                snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "strdup: %s",
                         pcap_strerror(errno) );
                return PCAP_ERROR;
        }
        
+       /* copy timeout value */
+       handlep->timeout = handle->opt.timeout;
+
        /*
         * If we're in promiscuous mode, then we probably want 
         * to see when the interface drops packets too, so get an
         * initial count from /proc/net/dev
         */
        if (handle->opt.promisc)
-               handle->md.proc_dropped = linux_if_drops(handle->md.device);
+               handlep->proc_dropped = linux_if_drops(handlep->device);
 
        /*
         * Current Linux kernels use the protocol family PF_PACKET to
@@ -1346,6 +1385,7 @@ pcap_set_datalink_linux(pcap_t *handle, int dlt)
 static int
 pcap_read_packet(pcap_t *handle, pcap_handler callback, u_char *userdata)
 {
+       struct pcap_linux       *handlep = handle->private;
        u_char                  *bp;
        int                     offset;
 #ifdef HAVE_PF_PACKET_SOCKETS
@@ -1373,7 +1413,7 @@ pcap_read_packet(pcap_t *handle, pcap_handler callback, u_char *userdata)
         * If this is a cooked device, leave extra room for a
         * fake packet header.
         */
-       if (handle->md.cooked)
+       if (handlep->cooked)
                offset = SLL_HDR_LEN;
        else
                offset = 0;
@@ -1468,7 +1508,7 @@ pcap_read_packet(pcap_t *handle, pcap_handler callback, u_char *userdata)
        }
 
 #ifdef HAVE_PF_PACKET_SOCKETS
-       if (!handle->md.sock_packet) {
+       if (!handlep->sock_packet) {
                /*
                 * Unfortunately, there is a window between socket() and
                 * bind() where the kernel may queue packets from any
@@ -1481,8 +1521,8 @@ pcap_read_packet(pcap_t *handle, pcap_handler callback, u_char *userdata)
                 * filter support, and it's a bit more complicated.
                 * It would save some instructions per packet, however.)
                 */
-               if (handle->md.ifindex != -1 &&
-                   from.sll_ifindex != handle->md.ifindex)
+               if (handlep->ifindex != -1 &&
+                   from.sll_ifindex != handlep->ifindex)
                        return 0;
 
                /*
@@ -1498,7 +1538,7 @@ pcap_read_packet(pcap_t *handle, pcap_handler callback, u_char *userdata)
                         * we'll see the packet as an incoming packet as well,
                         * and we don't want to see it twice.
                         */
-                       if (from.sll_ifindex == handle->md.lo_ifindex)
+                       if (from.sll_ifindex == handlep->lo_ifindex)
                                return 0;
 
                        /*
@@ -1521,7 +1561,7 @@ pcap_read_packet(pcap_t *handle, pcap_handler callback, u_char *userdata)
        /*
         * If this is a cooked device, fill in the fake packet header.
         */
-       if (handle->md.cooked) {
+       if (handlep->cooked) {
                /*
                 * Add the length of the fake header to the length
                 * of packet data we read.
@@ -1540,7 +1580,7 @@ pcap_read_packet(pcap_t *handle, pcap_handler callback, u_char *userdata)
        }
 
 #if defined(HAVE_PACKET_AUXDATA) && defined(HAVE_LINUX_TPACKET_AUXDATA_TP_VLAN_TCI)
-       if (handle->md.vlan_offset != -1) {
+       if (handlep->vlan_offset != -1) {
                for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
                        struct tpacket_auxdata *aux;
                        unsigned int len;
@@ -1562,13 +1602,13 @@ pcap_read_packet(pcap_t *handle, pcap_handler callback, u_char *userdata)
                                continue;
 
                        len = packet_len > iov.iov_len ? iov.iov_len : packet_len;
-                       if (len < (unsigned int) handle->md.vlan_offset)
+                       if (len < (unsigned int) handlep->vlan_offset)
                                break;
 
                        bp -= VLAN_TAG_LEN;
-                       memmove(bp, bp + VLAN_TAG_LEN, handle->md.vlan_offset);
+                       memmove(bp, bp + VLAN_TAG_LEN, handlep->vlan_offset);
 
-                       tag = (struct vlan_tag *)(bp + handle->md.vlan_offset);
+                       tag = (struct vlan_tag *)(bp + handlep->vlan_offset);
                        tag->vlan_tpid = htons(ETH_P_8021Q);
                        tag->vlan_tci = htons(aux->tp_vlan_tci);
 
@@ -1615,7 +1655,7 @@ pcap_read_packet(pcap_t *handle, pcap_handler callback, u_char *userdata)
                caplen = handle->snapshot;
 
        /* Run the packet filter if not using kernel filter */
-       if (!handle->md.use_bpf && handle->fcode.bf_insns) {
+       if (!handlep->filtering_in_kernel && handle->fcode.bf_insns) {
                if (bpf_filter(handle->fcode.bf_insns, bp,
                                packet_len, caplen) == 0)
                {
@@ -1667,17 +1707,18 @@ pcap_read_packet(pcap_t *handle, pcap_handler callback, u_char *userdata)
         * the count is more expensive than always testing a flag
         * in memory.
         *
-        * We keep the count in "md.packets_read", and use that for
-        * "ps_recv" if we can't get the statistics from the kernel.
+        * We keep the count in "handlep->packets_read", and use that
+        * for "ps_recv" if we can't get the statistics from the kernel.
         * We do that because, if we *can* get the statistics from
-        * the kernel, we use "md.stat.ps_recv" and "md.stat.ps_drop"
-        * as running counts, as reading the statistics from the
-        * kernel resets the kernel statistics, and if we directly
-        * increment "md.stat.ps_recv" here, that means it will
-        * count packets *twice* on systems where we can get kernel
-        * statistics - once here, and once in pcap_stats_linux().
+        * the kernel, we use "handlep->stat.ps_recv" and
+        * "handlep->stat.ps_drop" as running counts, as reading the
+        * statistics from the kernel resets the kernel statistics,
+        * and if we directly increment "handlep->stat.ps_recv" here,
+        * that means it will count packets *twice* on systems where
+        * we can get kernel statistics - once here, and once in
+        * pcap_stats_linux().
         */
-       handle->md.packets_read++;
+       handlep->packets_read++;
 
        /* Call the user supplied callback function */
        callback(userdata, &pcap_header, bp);
@@ -1688,12 +1729,13 @@ pcap_read_packet(pcap_t *handle, pcap_handler callback, u_char *userdata)
 static int
 pcap_inject_linux(pcap_t *handle, const void *buf, size_t size)
 {
+       struct pcap_linux *handlep = handle->private;
        int ret;
 
 #ifdef HAVE_PF_PACKET_SOCKETS
-       if (!handle->md.sock_packet) {
+       if (!handlep->sock_packet) {
                /* PF_PACKET socket */
-               if (handle->md.ifindex == -1) {
+               if (handlep->ifindex == -1) {
                        /*
                         * We don't support sending on the "any" device.
                         */
@@ -1703,7 +1745,7 @@ pcap_inject_linux(pcap_t *handle, const void *buf, size_t size)
                        return (-1);
                }
 
-               if (handle->md.cooked) {
+               if (handlep->cooked) {
                        /*
                         * We don't support sending on the "any" device.
                         *
@@ -1739,6 +1781,7 @@ pcap_inject_linux(pcap_t *handle, const void *buf, size_t size)
 static int
 pcap_stats_linux(pcap_t *handle, struct pcap_stat *stats)
 {
+       struct pcap_linux *handlep = handle->private;
 #ifdef HAVE_TPACKET_STATS
        struct tpacket_stats kstats;
        socklen_t len = sizeof (struct tpacket_stats);
@@ -1751,9 +1794,9 @@ pcap_stats_linux(pcap_t *handle, struct pcap_stat *stats)
         */
        if (handle->opt.promisc)
        {
-               if_dropped = handle->md.proc_dropped;
-               handle->md.proc_dropped = linux_if_drops(handle->md.device);
-               handle->md.stat.ps_ifdrop += (handle->md.proc_dropped - if_dropped);
+               if_dropped = handlep->proc_dropped;
+               handlep->proc_dropped = linux_if_drops(handlep->device);
+               handlep->stat.ps_ifdrop += (handlep->proc_dropped - if_dropped);
        }
 
 #ifdef HAVE_TPACKET_STATS
@@ -1809,9 +1852,9 @@ pcap_stats_linux(pcap_t *handle, struct pcap_stat *stats)
                 *    getsockopt(handle->fd, SOL_PACKET, PACKET_STATISTICS, ....
                 * resets the counters to zero.
                 */
-               handle->md.stat.ps_recv += kstats.tp_packets;
-               handle->md.stat.ps_drop += kstats.tp_drops;
-               *stats = handle->md.stat;
+               handlep->stat.ps_recv += kstats.tp_packets;
+               handlep->stat.ps_drop += kstats.tp_drops;
+               *stats = handlep->stat;
                return 0;
        }
        else
@@ -1849,15 +1892,15 @@ pcap_stats_linux(pcap_t *handle, struct pcap_stat *stats)
         *      the kernel by libpcap.
         *
         * We maintain the count of packets processed by libpcap in
-        * "md.packets_read", for reasons described in the comment
+        * "handlep->packets_read", for reasons described in the comment
         * at the end of pcap_read_packet().  We have no idea how many
         * packets were dropped by the kernel buffers -- but we know 
         * how many the interface dropped, so we can return that.
         */
         
-       stats->ps_recv = handle->md.packets_read;
+       stats->ps_recv = handlep->packets_read;
        stats->ps_drop = 0;
-       stats->ps_ifdrop = handle->md.stat.ps_ifdrop;
+       stats->ps_ifdrop = handlep->stat.ps_ifdrop;
        return 0;
 }
 
@@ -2238,6 +2281,7 @@ static int
 pcap_setfilter_linux_common(pcap_t *handle, struct bpf_program *filter,
     int is_mmapped)
 {
+       struct pcap_linux *handlep;
 #ifdef SO_ATTACH_FILTER
        struct sock_fprog       fcode;
        int                     can_filter_in_kernel;
@@ -2252,6 +2296,8 @@ pcap_setfilter_linux_common(pcap_t *handle, struct bpf_program *filter,
                return -1;
        }
 
+       handlep = handle->private;
+
        /* Make our private copy of the filter */
 
        if (install_bpf_program(handle, filter) < 0)
@@ -2262,7 +2308,7 @@ pcap_setfilter_linux_common(pcap_t *handle, struct bpf_program *filter,
         * Run user level packet filter by default. Will be overriden if
         * installing a kernel filter succeeds.
         */
-       handle->md.use_bpf = 0;
+       handlep->filtering_in_kernel = 0;
 
        /* Install kernel level filter if possible */
 
@@ -2351,7 +2397,7 @@ pcap_setfilter_linux_common(pcap_t *handle, struct bpf_program *filter,
                if ((err = set_kernel_filter(handle, &fcode)) == 0)
                {
                        /* Installation succeded - using kernel filter. */
-                       handle->md.use_bpf = 1;
+                       handlep->filtering_in_kernel = 1;
                }
                else if (err == -1)     /* Non-fatal error */
                {
@@ -2376,7 +2422,7 @@ pcap_setfilter_linux_common(pcap_t *handle, struct bpf_program *filter,
         * calling "pcap_setfilter()".  Otherwise, the kernel filter may
         * filter out packets that would pass the new userland filter.
         */
-       if (!handle->md.use_bpf)
+       if (!handlep->filtering_in_kernel)
                reset_kernel_filter(handle);
 
        /*
@@ -2408,7 +2454,9 @@ static int
 pcap_setdirection_linux(pcap_t *handle, pcap_direction_t d)
 {
 #ifdef HAVE_PF_PACKET_SOCKETS
-       if (!handle->md.sock_packet) {
+       struct pcap_linux *handlep = handle->private;
+
+       if (!handlep->sock_packet) {
                handle->direction = d;
                return 0;
        }
@@ -2814,7 +2862,7 @@ static void map_arphrd_to_dlt(pcap_t *handle, int arptype, int cooked_ok)
                handle->linktype = DLT_LINUX_IRDA;
                /* We need to save packet direction for IrDA decoding,
                 * so let's use "Linux-cooked" mode. Jean II */
-               //handle->md.cooked = 1;
+               //handlep->cooked = 1;
                break;
 
        /* ARPHRD_LAPD is unofficial and randomly allocated, if reallocation
@@ -2864,6 +2912,7 @@ static int
 activate_new(pcap_t *handle)
 {
 #ifdef HAVE_PF_PACKET_SOCKETS
+       struct pcap_linux *handlep = handle->private;
        const char              *device = handle->opt.source;
        int                     is_any_device = (strcmp(device, "any") == 0);
        int                     sock_fd = -1, arptype;
@@ -2909,12 +2958,12 @@ activate_new(pcap_t *handle)
        }
 
        /* It seems the kernel supports the new interface. */
-       handle->md.sock_packet = 0;
+       handlep->sock_packet = 0;
 
        /*
         * Get the interface index of the loopback device.
         * If the attempt fails, don't fail, just set the
-        * "md.lo_ifindex" to -1.
+        * "handlep->lo_ifindex" to -1.
         *
         * XXX - can there be more than one device that loops
         * packets back, i.e. devices other than "lo"?  If so,
@@ -2922,7 +2971,7 @@ activate_new(pcap_t *handle)
         * indices for them, and check all of them in
         * "pcap_read_packet()".
         */
-       handle->md.lo_ifindex = iface_get_id(sock_fd, "lo", handle->errbuf);
+       handlep->lo_ifindex = iface_get_id(sock_fd, "lo", handle->errbuf);
 
        /*
         * Default value for offset to align link-layer payload
@@ -2937,7 +2986,7 @@ activate_new(pcap_t *handle)
         */
        if (!is_any_device) {
                /* Assume for now we don't need cooked mode. */
-               handle->md.cooked = 0;
+               handlep->cooked = 0;
 
                if (handle->opt.rfmon) {
                        /*
@@ -2967,8 +3016,8 @@ activate_new(pcap_t *handle)
                         * device to open for monitor mode.  If we've
                         * been given a different device, use it.
                         */
-                       if (handle->md.mondevice != NULL)
-                               device = handle->md.mondevice;
+                       if (handlep->mondevice != NULL)
+                               device = handlep->mondevice;
                }
                arptype = iface_get_arptype(sock_fd, device, handle->errbuf);
                if (arptype < 0) {
@@ -3015,7 +3064,7 @@ activate_new(pcap_t *handle)
                                        return PCAP_ERROR;
                                }
                        }
-                       handle->md.cooked = 1;
+                       handlep->cooked = 1;
 
                        /*
                         * Get rid of any link-layer type list
@@ -3053,14 +3102,14 @@ activate_new(pcap_t *handle)
                                handle->linktype = DLT_LINUX_SLL;
                }
 
-               handle->md.ifindex = iface_get_id(sock_fd, device,
+               handlep->ifindex = iface_get_id(sock_fd, device,
                    handle->errbuf);
-               if (handle->md.ifindex == -1) {
+               if (handlep->ifindex == -1) {
                        close(sock_fd);
                        return PCAP_ERROR;
                }
 
-               if ((err = iface_bind(sock_fd, handle->md.ifindex,
+               if ((err = iface_bind(sock_fd, handlep->ifindex,
                    handle->errbuf)) != 1) {
                        close(sock_fd);
                        if (err < 0)
@@ -3082,7 +3131,7 @@ activate_new(pcap_t *handle)
                /*
                 * It uses cooked mode.
                 */
-               handle->md.cooked = 1;
+               handlep->cooked = 1;
                handle->linktype = DLT_LINUX_SLL;
 
                /*
@@ -3092,7 +3141,7 @@ activate_new(pcap_t *handle)
                 * if we figure out how to transmit in cooked
                 * mode.
                 */
-               handle->md.ifindex = -1;
+               handlep->ifindex = -1;
        }
 
        /*
@@ -3119,7 +3168,7 @@ activate_new(pcap_t *handle)
 
        if (!is_any_device && handle->opt.promisc) {
                memset(&mr, 0, sizeof(mr));
-               mr.mr_ifindex = handle->md.ifindex;
+               mr.mr_ifindex = handlep->ifindex;
                mr.mr_type    = PACKET_MR_PROMISC;
                if (setsockopt(sock_fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP,
                    &mr, sizeof(mr)) == -1) {
@@ -3158,7 +3207,7 @@ activate_new(pcap_t *handle)
         * 1 byte of packet data (so we don't pass a byte
         * count of 0 to "recvfrom()").
         */
-       if (handle->md.cooked) {
+       if (handlep->cooked) {
                if (handle->snapshot < SLL_HDR_LEN + 1)
                        handle->snapshot = SLL_HDR_LEN + 1;
        }
@@ -3170,15 +3219,15 @@ activate_new(pcap_t *handle)
        switch (handle->linktype) {
 
        case DLT_EN10MB:
-               handle->md.vlan_offset = 2 * ETH_ALEN;
+               handlep->vlan_offset = 2 * ETH_ALEN;
                break;
 
        case DLT_LINUX_SLL:
-               handle->md.vlan_offset = 14;
+               handlep->vlan_offset = 14;
                break;
 
        default:
-               handle->md.vlan_offset = -1; /* unknown */
+               handlep->vlan_offset = -1; /* unknown */
                break;
        }
 
@@ -3210,14 +3259,15 @@ activate_new(pcap_t *handle)
 static int 
 activate_mmap(pcap_t *handle, int *status)
 {
+       struct pcap_linux *handlep = handle->private;
        int ret;
 
        /*
         * Attempt to allocate a buffer to hold the contents of one
         * packet, for use by the oneshot callback.
         */
-       handle->md.oneshot_buffer = malloc(handle->snapshot);
-       if (handle->md.oneshot_buffer == NULL) {
+       handlep->oneshot_buffer = malloc(handle->snapshot);
+       if (handlep->oneshot_buffer == NULL) {
                snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
                         "can't allocate oneshot buffer: %s",
                         pcap_strerror(errno));
@@ -3231,7 +3281,7 @@ activate_mmap(pcap_t *handle, int *status)
        }
        ret = prepare_tpacket_socket(handle);
        if (ret == -1) {
-               free(handle->md.oneshot_buffer);
+               free(handlep->oneshot_buffer);
                *status = PCAP_ERROR;
                return ret;
        }
@@ -3241,7 +3291,7 @@ activate_mmap(pcap_t *handle, int *status)
                 * We don't support memory-mapped capture; our caller
                 * will fall back on reading from the socket.
                 */
-               free(handle->md.oneshot_buffer);
+               free(handlep->oneshot_buffer);
                return 0;
        }
        if (ret == -1) {
@@ -3249,7 +3299,7 @@ activate_mmap(pcap_t *handle, int *status)
                 * Error attempting to enable memory-mapped capture;
                 * fail.  create_ring() has set *status.
                 */
-               free(handle->md.oneshot_buffer);
+               free(handlep->oneshot_buffer);
                return -1;
        }
 
@@ -3288,13 +3338,14 @@ activate_mmap(pcap_t *handle _U_, int *status _U_)
 static int
 prepare_tpacket_socket(pcap_t *handle)
 {
+       struct pcap_linux *handlep = handle->private;
 #ifdef HAVE_TPACKET2
        socklen_t len;
        int val;
 #endif
 
-       handle->md.tp_version = TPACKET_V1;
-       handle->md.tp_hdrlen = sizeof(struct tpacket_hdr);
+       handlep->tp_version = TPACKET_V1;
+       handlep->tp_hdrlen = sizeof(struct tpacket_hdr);
 
 #ifdef HAVE_TPACKET2
        /* Probe whether kernel supports TPACKET_V2 */
@@ -3310,7 +3361,7 @@ prepare_tpacket_socket(pcap_t *handle)
                    pcap_strerror(errno));
                return -1;
        }
-       handle->md.tp_hdrlen = val;
+       handlep->tp_hdrlen = val;
 
        val = TPACKET_V2;
        if (setsockopt(handle->fd, SOL_PACKET, PACKET_VERSION, &val,
@@ -3320,7 +3371,7 @@ prepare_tpacket_socket(pcap_t *handle)
                    pcap_strerror(errno));
                return -1;
        }
-       handle->md.tp_version = TPACKET_V2;
+       handlep->tp_version = TPACKET_V2;
 
        /* Reserve space for VLAN tag reconstruction */
        val = VLAN_TAG_LEN;
@@ -3351,6 +3402,7 @@ prepare_tpacket_socket(pcap_t *handle)
 static int
 create_ring(pcap_t *handle, int *status)
 {
+       struct pcap_linux *handlep = handle->private;
        unsigned i, j, frames_per_block;
        struct tpacket_req req;
        socklen_t len;
@@ -3455,7 +3507,7 @@ create_ring(pcap_t *handle, int *status)
                 * let's use it.. maybe is it even large enough to directly
                 * replace macoff..
                 */
-       tp_hdrlen = TPACKET_ALIGN(handle->md.tp_hdrlen) + sizeof(struct sockaddr_ll) ;
+       tp_hdrlen = TPACKET_ALIGN(handlep->tp_hdrlen) + sizeof(struct sockaddr_ll) ;
        netoff = TPACKET_ALIGN(tp_hdrlen + (maclen < 16 ? 16 : maclen)) + tp_reserve;
                /* NOTE: AFAICS tp_reserve may break the TPACKET_ALIGN of
                 * netoff, which contradicts
@@ -3624,10 +3676,10 @@ retry:
        }
 
        /* memory map the rx ring */
-       handle->md.mmapbuflen = req.tp_block_nr * req.tp_block_size;
-       handle->md.mmapbuf = mmap(0, handle->md.mmapbuflen,
+       handlep->mmapbuflen = req.tp_block_nr * req.tp_block_size;
+       handlep->mmapbuf = mmap(0, handlep->mmapbuflen,
            PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
-       if (handle->md.mmapbuf == MAP_FAILED) {
+       if (handlep->mmapbuf == MAP_FAILED) {
                snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
                    "can't mmap rx ring: %s", pcap_strerror(errno));
 
@@ -3653,7 +3705,7 @@ retry:
        /* fill the header ring with proper frame ptr*/
        handle->offset = 0;
        for (i=0; i<req.tp_block_nr; ++i) {
-               void *base = &handle->md.mmapbuf[i*req.tp_block_size];
+               void *base = &handlep->mmapbuf[i*req.tp_block_size];
                for (j=0; j<frames_per_block; ++j, ++handle->offset) {
                        RING_GET_FRAME(handle) = base;
                        base += req.tp_frame_size;
@@ -3669,6 +3721,8 @@ retry:
 static void
 destroy_ring(pcap_t *handle)
 {
+       struct pcap_linux *handlep = handle->private;
+
        /* tell the kernel to destroy the ring*/
        struct tpacket_req req;
        memset(&req, 0, sizeof(req));
@@ -3676,10 +3730,10 @@ destroy_ring(pcap_t *handle)
                                (void *) &req, sizeof(req));
 
        /* if ring is mapped, unmap it*/
-       if (handle->md.mmapbuf) {
+       if (handlep->mmapbuf) {
                /* do not test for mmap failure, as we can't recover from any error */
-               munmap(handle->md.mmapbuf, handle->md.mmapbuflen);
-               handle->md.mmapbuf = NULL;
+               munmap(handlep->mmapbuf, handlep->mmapbuflen);
+               handlep->mmapbuf = NULL;
        }
 }
 
@@ -3705,19 +3759,23 @@ pcap_oneshot_mmap(u_char *user, const struct pcap_pkthdr *h,
     const u_char *bytes)
 {
        struct oneshot_userdata *sp = (struct oneshot_userdata *)user;
+       pcap_t *handle = sp->pd;
+       struct pcap_linux *handlep = handle->private;
 
        *sp->hdr = *h;
-       memcpy(sp->pd->md.oneshot_buffer, bytes, h->caplen);
-       *sp->pkt = sp->pd->md.oneshot_buffer;
+       memcpy(handlep->oneshot_buffer, bytes, h->caplen);
+       *sp->pkt = handlep->oneshot_buffer;
 }
     
 static void
 pcap_cleanup_linux_mmap( pcap_t *handle )
 {
+       struct pcap_linux *handlep = handle->private;
+
        destroy_ring(handle);
-       if (handle->md.oneshot_buffer != NULL) {
-               free(handle->md.oneshot_buffer);
-               handle->md.oneshot_buffer = NULL;
+       if (handlep->oneshot_buffer != NULL) {
+               free(handlep->oneshot_buffer);
+               handlep->oneshot_buffer = NULL;
        }
        pcap_cleanup_linux(handle);
 }
@@ -3726,28 +3784,32 @@ pcap_cleanup_linux_mmap( pcap_t *handle )
 static int
 pcap_getnonblock_mmap(pcap_t *p, char *errbuf)
 {
+       struct pcap_linux *handlep = p->private;
+
        /* use negative value of timeout to indicate non blocking ops */
-       return (p->md.timeout<0);
+       return (handlep->timeout<0);
 }
 
 static int
 pcap_setnonblock_mmap(pcap_t *p, int nonblock, char *errbuf)
 {
+       struct pcap_linux *handlep = p->private;
+
        /*
         * Map each value to their corresponding negation to
         * preserve the timeout value provided with pcap_set_timeout.
         */
        if (nonblock) {
-               if (p->md.timeout >= 0) {
+               if (handlep->timeout >= 0) {
                        /*
                         * Indicate that we're switching to
                         * non-blocking mode.
                         */
-                       p->md.timeout = ~p->md.timeout;
+                       handlep->timeout = ~handlep->timeout;
                }
        } else {
-               if (p->md.timeout < 0) {
-                       p->md.timeout = ~p->md.timeout;
+               if (handlep->timeout < 0) {
+                       handlep->timeout = ~handlep->timeout;
                }
        }
        return 0;
@@ -3756,10 +3818,11 @@ pcap_setnonblock_mmap(pcap_t *p, int nonblock, char *errbuf)
 static inline union thdr *
 pcap_get_ring_frame(pcap_t *handle, int status)
 {
+       struct pcap_linux *handlep = handle->private;
        union thdr h;
 
        h.raw = RING_GET_FRAME(handle);
-       switch (handle->md.tp_version) {
+       switch (handlep->tp_version) {
        case TPACKET_V1:
                if (status != (h.h1->tp_status ? TP_STATUS_USER :
                                                TP_STATUS_KERNEL))
@@ -3784,6 +3847,7 @@ static int
 pcap_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback, 
                u_char *user)
 {
+       struct pcap_linux *handlep = handle->private;
        int timeout;
        int pkts = 0;
        char c;
@@ -3796,10 +3860,10 @@ pcap_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback,
                pollinfo.fd = handle->fd;
                pollinfo.events = POLLIN;
 
-               if (handle->md.timeout == 0)
+               if (handlep->timeout == 0)
                        timeout = -1;   /* block forever */
-               else if (handle->md.timeout > 0)
-                       timeout = handle->md.timeout;   /* block for that amount of time */
+               else if (handlep->timeout > 0)
+                       timeout = handlep->timeout;     /* block for that amount of time */
                else
                        timeout = 0;    /* non-blocking mode - poll to pick up errors */
                do {
@@ -3887,7 +3951,7 @@ pcap_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback,
                if (!h.raw)
                        break;
 
-               switch (handle->md.tp_version) {
+               switch (handlep->tp_version) {
                case TPACKET_V1:
                        tp_len     = h.h1->tp_len;
                        tp_mac     = h.h1->tp_mac;
@@ -3907,7 +3971,7 @@ pcap_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback,
                default:
                        snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 
                                "unsupported tpacket version %d",
-                               handle->md.tp_version);
+                               handlep->tp_version);
                        return -1;
                }
                /* perform sanity check on internal offset. */
@@ -3923,14 +3987,14 @@ pcap_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback,
                 * If the kernel filtering is enabled we need to run the
                 * filter until all the frames present into the ring 
                 * at filter creation time are processed. 
-                * In such case md.use_bpf is used as a counter for the 
+                * In such case filtering_in_kernel is used as a counter for the 
                 * packet we need to filter.
                 * Note: alternatively it could be possible to stop applying 
                 * the filter when the ring became empty, but it can possibly
                 * happen a lot later... */
                bp = (unsigned char*)h.raw + tp_mac;
-               run_bpf = (!handle->md.use_bpf) || 
-                       ((handle->md.use_bpf>1) && handle->md.use_bpf--);
+               run_bpf = (!handlep->filtering_in_kernel) || 
+                       ((handlep->filtering_in_kernel>1) && handlep->filtering_in_kernel--);
                if (run_bpf && handle->fcode.bf_insns && 
                                (bpf_filter(handle->fcode.bf_insns, bp,
                                        tp_len, tp_snaplen) == 0))
@@ -3939,7 +4003,7 @@ pcap_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback,
                /*
                 * Do checks based on packet direction.
                 */
-               sll = (void *)h.raw + TPACKET_ALIGN(handle->md.tp_hdrlen);
+               sll = (void *)h.raw + TPACKET_ALIGN(handlep->tp_hdrlen);
                if (sll->sll_pkttype == PACKET_OUTGOING) {
                        /*
                         * Outgoing packet.
@@ -3947,7 +4011,7 @@ pcap_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback,
                         * we'll see the packet as an incoming packet as well,
                         * and we don't want to see it twice.
                         */
-                       if (sll->sll_ifindex == handle->md.lo_ifindex)
+                       if (sll->sll_ifindex == handlep->lo_ifindex)
                                goto skip;
 
                        /*
@@ -3971,7 +4035,7 @@ pcap_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback,
                pcaphdr.len = tp_len;
 
                /* if required build in place the sll header*/
-               if (handle->md.cooked) {
+               if (handlep->cooked) {
                        struct sll_header *hdrp;
 
                        /*
@@ -3991,7 +4055,7 @@ pcap_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback,
                         * the sll header.
                         */
                        if (bp < (u_char *)h.raw +
-                                          TPACKET_ALIGN(handle->md.tp_hdrlen) +
+                                          TPACKET_ALIGN(handlep->tp_hdrlen) +
                                           sizeof(struct sockaddr_ll)) {
                                snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 
                                        "cooked-mode frame doesn't have room for sll header");
@@ -4015,20 +4079,20 @@ pcap_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback,
                }
 
 #ifdef HAVE_TPACKET2
-               if ((handle->md.tp_version == TPACKET_V2) &&
+               if ((handlep->tp_version == TPACKET_V2) &&
 #if defined(TP_STATUS_VLAN_VALID)
                (h.h2->tp_vlan_tci || (h.h2->tp_status & TP_STATUS_VLAN_VALID)) &&
 #else
                h.h2->tp_vlan_tci &&
 #endif
-                   handle->md.vlan_offset != -1 &&
-                   tp_snaplen >= (unsigned int) handle->md.vlan_offset) {
+                   handlep->vlan_offset != -1 &&
+                   tp_snaplen >= (unsigned int) handlep->vlan_offset) {
                        struct vlan_tag *tag;
 
                        bp -= VLAN_TAG_LEN;
-                       memmove(bp, bp + VLAN_TAG_LEN, handle->md.vlan_offset);
+                       memmove(bp, bp + VLAN_TAG_LEN, handlep->vlan_offset);
 
-                       tag = (struct vlan_tag *)(bp + handle->md.vlan_offset);
+                       tag = (struct vlan_tag *)(bp + handlep->vlan_offset);
                        tag->vlan_tpid = htons(ETH_P_8021Q);
                        tag->vlan_tci = htons(h.h2->tp_vlan_tci);
 
@@ -4052,11 +4116,11 @@ pcap_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback,
                /* pass the packet to the user */
                pkts++;
                callback(user, &pcaphdr, bp);
-               handle->md.packets_read++;
+               handlep->packets_read++;
 
 skip:
                /* next packet */
-               switch (handle->md.tp_version) {
+               switch (handlep->tp_version) {
                case TPACKET_V1:
                        h.h1->tp_status = TP_STATUS_KERNEL;
                        break;
@@ -4081,6 +4145,7 @@ skip:
 static int 
 pcap_setfilter_linux_mmap(pcap_t *handle, struct bpf_program *filter)
 {
+       struct pcap_linux *handlep = handle->private;
        int n, offset;
        int ret;
 
@@ -4097,7 +4162,7 @@ pcap_setfilter_linux_mmap(pcap_t *handle, struct bpf_program *filter)
        /* if the kernel filter is enabled, we need to apply the filter on
         * all packets present into the ring. Get an upper bound of their number
         */
-       if (!handle->md.use_bpf)
+       if (!handlep->filtering_in_kernel)
                return ret;
 
        /* walk the ring backward and count the free slot */
@@ -4115,7 +4180,7 @@ pcap_setfilter_linux_mmap(pcap_t *handle, struct bpf_program *filter)
        handle->offset = offset;
 
        /* store the number of packets currently present in the ring */
-       handle->md.use_bpf = 1 + (handle->cc - n);
+       handlep->filtering_in_kernel = 1 + (handle->cc - n);
        return ret;
 }
 
@@ -4317,6 +4382,7 @@ enter_rfmon_mode_wext(pcap_t *handle, int sock_fd, const char *device)
         * value of -ENFILE.  (Return values are negative errnos.)  We
         * could probably use that to find an unused device.
         */
+       struct pcap_linux *handlep = handle->private;
        int err;
        struct iwreq ireq;
        struct iw_priv_args *priv;
@@ -4597,7 +4663,7 @@ enter_rfmon_mode_wext(pcap_t *handle, int sock_fd, const char *device)
        /*
         * Save the old mode.
         */
-       handle->md.oldmode = ireq.u.mode;
+       handlep->oldmode = ireq.u.mode;
 
        /*
         * Put the adapter in rfmon mode.  How we do this depends
@@ -4624,7 +4690,7 @@ enter_rfmon_mode_wext(pcap_t *handle, int sock_fd, const char *device)
                         * Note that we have to put the old mode back
                         * when we close the device.
                         */
-                       handle->md.must_do_on_close |= MUST_CLEAR_RFMON;
+                       handlep->must_do_on_close |= MUST_CLEAR_RFMON;
 
                        /*
                         * Add this to the list of pcaps to close
@@ -4871,7 +4937,7 @@ enter_rfmon_mode_wext(pcap_t *handle, int sock_fd, const char *device)
         * Note that we have to put the old mode back when we
         * close the device.
         */
-       handle->md.must_do_on_close |= MUST_CLEAR_RFMON;
+       handlep->must_do_on_close |= MUST_CLEAR_RFMON;
 
        /*
         * Add this to the list of pcaps to close when we exit.
@@ -5034,6 +5100,7 @@ iface_get_offload(pcap_t *handle _U_)
 static int
 activate_old(pcap_t *handle)
 {
+       struct pcap_linux *handlep = handle->private;
        int             arptype;
        struct ifreq    ifr;
        const char      *device = handle->opt.source;
@@ -5061,10 +5128,10 @@ activate_old(pcap_t *handle)
        }
 
        /* It worked - we are using the old interface */
-       handle->md.sock_packet = 1;
+       handlep->sock_packet = 1;
 
        /* ...which means we get the link-layer header. */
-       handle->md.cooked = 0;
+       handlep->cooked = 0;
 
        /* Bind to the given device */
 
@@ -5133,7 +5200,7 @@ activate_old(pcap_t *handle)
                                         pcap_strerror(errno));
                                return PCAP_ERROR;
                        }
-                       handle->md.must_do_on_close |= MUST_CLEAR_PROMISC;
+                       handlep->must_do_on_close |= MUST_CLEAR_PROMISC;
 
                        /*
                         * Add this to the list of pcaps
@@ -5219,7 +5286,7 @@ activate_old(pcap_t *handle)
         * SOCK_PACKET sockets don't supply information from
         * stripped VLAN tags.
         */
-       handle->md.vlan_offset = -1; /* unknown */
+       handlep->vlan_offset = -1; /* unknown */
 
        return 1;
 }
@@ -5316,6 +5383,7 @@ iface_get_arptype(int fd, const char *device, char *ebuf)
 static int
 fix_program(pcap_t *handle, struct sock_fprog *fcode, int is_mmapped)
 {
+       struct pcap_linux *handlep = handle->private;
        size_t prog_size;
        register int i;
        register struct bpf_insn *p;
@@ -5391,7 +5459,7 @@ fix_program(pcap_t *handle, struct sock_fprog *fcode, int is_mmapped)
                                /*
                                 * Yes; are we in cooked mode?
                                 */
-                               if (handle->md.cooked) {
+                               if (handlep->cooked) {
                                        /*
                                         * Yes, so we need to fix this
                                         * instruction.
index 48f29b02529407e0ad734c2f79306dc4be313858..35c677bc679eec086e86df9c4c2a9fefcd8ee1f4 100644 (file)
 
 typedef enum { OTHER = -1, NFLOG, NFQUEUE } nftype_t;
 
+/*
+ * Private data for capturing on Linux netfilter sockets.
+ */
+struct pcap_netfilter {
+       u_int   packets_read;   /* count of packets read with recvfrom() */
+};
+
 static int nfqueue_send_verdict(const pcap_t *handle, u_int16_t group_id, u_int32_t id, u_int32_t verdict);
 
 static int
 netfilter_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user)
 {
+       struct pcap_netfilter *handlep = handle->private;
        const unsigned char *buf;
        int count = 0;
        int len;
@@ -179,7 +187,7 @@ netfilter_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_c
                                if (handle->fcode.bf_insns == NULL ||
                                                bpf_filter(handle->fcode.bf_insns, payload, pkth.len, pkth.caplen)) 
                                {
-                                       handle->md.packets_read++;
+                                       handlep->packets_read++;
                                        callback(user, &pkth, payload);
                                        count++;
                                }
@@ -211,7 +219,9 @@ netfilter_set_datalink(pcap_t *handle, int dlt)
 static int
 netfilter_stats_linux(pcap_t *handle, struct pcap_stat *stats)
 {
-       stats->ps_recv = handle->md.packets_read;
+       struct pcap_netfilter *handlep = handle->private;
+
+       stats->ps_recv = handlep->packets_read;
        stats->ps_drop = 0;
        stats->ps_ifdrop = 0;
        return 0;
@@ -471,7 +481,6 @@ netfilter_activate(pcap_t* handle)
        handle->inject_op = netfilter_inject_linux;
        handle->setfilter_op = install_bpf_program; /* no kernel filtering */
        handle->setdirection_op = NULL;
-       handle->set_datalink_op = NULL;
        handle->set_datalink_op = netfilter_set_datalink;
        handle->getnonblock_op = pcap_getnonblock_fd;
        handle->setnonblock_op = pcap_setnonblock_fd;
@@ -612,7 +621,7 @@ netfilter_create(const char *device, char *ebuf, int *is_ours)
        /* OK, it's probably ours. */
        *is_ours = 1;
 
-       p = pcap_create_common(device, ebuf);
+       p = pcap_create_common(device, ebuf, sizeof (struct pcap_netfilter));
        if (p == NULL)
                return (NULL);
 
index 85b32f2a9d752652972d1ffb97526e4b4c5d025b..8e3572116e33dda0af5fca6af98bac38e49dc2b7 100644 (file)
@@ -71,9 +71,17 @@ static const char rcsid[] _U_ =
 /* Forwards */
 static int nit_setflags(int, int, int, char *);
 
+/*
+ * Private data for capturing on NIT devices.
+ */
+struct pcap_nit {
+       struct pcap_stat stat;
+};
+
 static int
 pcap_stats_nit(pcap_t *p, struct pcap_stat *ps)
 {
+       struct pcap_nit *pn = p->private;
 
        /*
         * "ps_recv" counts packets handed to the filter, not packets
@@ -91,13 +99,14 @@ pcap_stats_nit(pcap_t *p, struct pcap_stat *ps)
         * kernel by libpcap or packets not yet read from libpcap by the
         * application.
         */
-       *ps = p->md.stat;
+       *ps = pn->stat;
        return (0);
 }
 
 static int
 pcap_read_nit(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
 {
+       struct pcap_nit *pn = p->private;
        register int cc, n;
        register u_char *bp, *cp, *ep;
        register struct nit_hdr *nh;
@@ -156,7 +165,7 @@ pcap_read_nit(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
                case NIT_NOMBUF:
                case NIT_NOCLUSTER:
                case NIT_NOSPACE:
-                       p->md.stat.ps_drop = nh->nh_dropped;
+                       pn->stat.ps_drop = nh->nh_dropped;
                        continue;
 
                case NIT_SEQNO:
@@ -167,7 +176,7 @@ pcap_read_nit(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
                            "bad nit state %d", nh->nh_state);
                        return (-1);
                }
-               ++p->md.stat.ps_recv;
+               ++pn->stat.ps_recv;
                bp += ((sizeof(struct nit_hdr) + nh->nh_datalen +
                    sizeof(int) - 1) & ~(sizeof(int) - 1));
 
@@ -273,7 +282,7 @@ pcap_activate_nit(pcap_t *p)
                    "bind: %s: %s", snit.snit_ifname, pcap_strerror(errno));
                goto bad;
        }
-       nit_setflags(p->fd, p->opt.promisc, p->md.timeout, p->errbuf);
+       nit_setflags(p->fd, p->opt.promisc, p->opt.timeout, p->errbuf);
 
        /*
         * NIT supports only ethernets.
@@ -332,7 +341,7 @@ pcap_create_interface(const char *device, char *ebuf)
 {
        pcap_t *p;
 
-       p = pcap_create_common(device, ebuf);
+       p = pcap_create_common(device, ebuf, sizeof (struct pcap_nit));
        if (p == NULL)
                return (NULL);
 
index 84c6d54784954cdcdfcce0eda9a0a9f3b184c8a5..eb06e7b5ba8b21ed2dbd215758e71ce4155a25d9 100644 (file)
--- a/pcap-pf.c
+++ b/pcap-pf.c
@@ -74,6 +74,24 @@ struct rtentry;
 #include "os-proto.h"
 #endif
 
+/*
+ * FDDI packets are padded to make everything line up on a nice boundary.
+ */
+#define       PCAP_FDDIPAD 3
+
+/*
+ * Private data for capturing on Ultrix and DEC OSF/1^WDigital UNIX^W^W
+ * Tru64 UNIX packetfilter devices.
+ */
+struct pcap_pf {
+       int     filtering_in_kernel; /* using kernel filter */
+       u_long  TotPkts;        /* can't oflow for 79 hrs on ether */
+       u_long  TotAccepted;    /* count accepted by filter */
+       u_long  TotDrops;       /* count of dropped packets */
+       long    TotMissed;      /* missed by i/f during this run */
+       long    OrigMissed;     /* missed by i/f before this run */
+};
+
 static int pcap_setfilter_pf(pcap_t *, struct bpf_program *);
 
 /*
@@ -87,15 +105,14 @@ static int pcap_setfilter_pf(pcap_t *, struct bpf_program *);
 static int
 pcap_read_pf(pcap_t *pc, int cnt, pcap_handler callback, u_char *user)
 {
+       struct pcap_pf *pf = pc->private;
        register u_char *p, *bp;
        register int cc, n, buflen, inc;
        register struct enstamp *sp;
 #ifdef LBL_ALIGN
        struct enstamp stamp;
 #endif
-#ifdef PCAP_FDDIPAD
        register int pad;
-#endif
 
  again:
        cc = pc->cc;
@@ -126,9 +143,7 @@ pcap_read_pf(pcap_t *pc, int cnt, pcap_handler callback, u_char *user)
         * Loop through each packet.
         */
        n = 0;
-#ifdef PCAP_FDDIPAD
        pad = pc->fddipad;
-#endif
        while (cc > 0) {
                /*
                 * Has "pcap_breakloop()" been called?
@@ -177,39 +192,31 @@ pcap_read_pf(pcap_t *pc, int cnt, pcap_handler callback, u_char *user)
                inc = ENALIGN(buflen + sp->ens_stamplen);
                cc -= inc;
                bp += inc;
-               pc->md.TotPkts++;
-               pc->md.TotDrops += sp->ens_dropped;
-               pc->md.TotMissed = sp->ens_ifoverflows;
-               if (pc->md.OrigMissed < 0)
-                       pc->md.OrigMissed = pc->md.TotMissed;
+               pf->TotPkts++;
+               pf->TotDrops += sp->ens_dropped;
+               pf->TotMissed = sp->ens_ifoverflows;
+               if (pf->OrigMissed < 0)
+                       pf->OrigMissed = pf->TotMissed;
 
                /*
                 * Short-circuit evaluation: if using BPF filter
                 * in kernel, no need to do it now - we already know
                 * the packet passed the filter.
                 *
-#ifdef PCAP_FDDIPAD
                 * Note: the filter code was generated assuming
                 * that pc->fddipad was the amount of padding
                 * before the header, as that's what's required
                 * in the kernel, so we run the filter before
                 * skipping that padding.
-#endif
                 */
-               if (pc->md.use_bpf ||
+               if (pf->filtering_in_kernel ||
                    bpf_filter(pc->fcode.bf_insns, p, sp->ens_count, buflen)) {
                        struct pcap_pkthdr h;
-                       pc->md.TotAccepted++;
+                       pf->TotAccepted++;
                        h.ts = sp->ens_tstamp;
-#ifdef PCAP_FDDIPAD
                        h.len = sp->ens_count - pad;
-#else
-                       h.len = sp->ens_count;
-#endif
-#ifdef PCAP_FDDIPAD
                        p += pad;
                        buflen -= pad;
-#endif
                        h.caplen = buflen;
                        (*callback)(user, &h, p);
                        if (++n >= cnt && cnt > 0) {
@@ -240,6 +247,7 @@ pcap_inject_pf(pcap_t *p, const void *buf, size_t size)
 static int
 pcap_stats_pf(pcap_t *p, struct pcap_stat *ps)
 {
+       struct pcap_pf *pf = p->private;
 
        /*
         * If packet filtering is being done in the kernel:
@@ -277,9 +285,9 @@ pcap_stats_pf(pcap_t *p, struct pcap_stat *ps)
         * the kernel by libpcap, but they may include packets not
         * yet read from libpcap by the application.
         */
-       ps->ps_recv = p->md.TotAccepted;
-       ps->ps_drop = p->md.TotDrops;
-       ps->ps_ifdrop = p->md.TotMissed - p->md.OrigMissed;
+       ps->ps_recv = pf->TotAccepted;
+       ps->ps_drop = pf->TotDrops;
+       ps->ps_ifdrop = pf->TotMissed - pf->OrigMissed;
        return (0);
 }
 
@@ -294,6 +302,7 @@ pcap_stats_pf(pcap_t *p, struct pcap_stat *ps)
 static int
 pcap_activate_pf(pcap_t *p)
 {
+       struct pcap_pf *pf = p->private;
        short enmode;
        int backlog = -1;       /* request the most */
        struct enfilter Filter;
@@ -327,7 +336,7 @@ your system may not be properly configured; see the packetfilter(4) man page\n",
                        p->opt.source, pcap_strerror(errno));
                goto bad;
        }
-       p->md.OrigMissed = -1;
+       pf->OrigMissed = -1;
        enmode = ENTSTAMP|ENBATCH|ENNONEXCL;
        if (p->opt.promisc)
                enmode |= ENPROMISC;
@@ -436,7 +445,6 @@ your system may not be properly configured; see the packetfilter(4) man page\n",
                goto bad;
        }
        /* set truncation */
-#ifdef PCAP_FDDIPAD
        if (p->linktype == DLT_FDDI) {
                p->fddipad = PCAP_FDDIPAD;
 
@@ -444,7 +452,6 @@ your system may not be properly configured; see the packetfilter(4) man page\n",
                p->snapshot += PCAP_FDDIPAD;
        } else
                p->fddipad = 0;
-#endif
        if (ioctl(p->fd, EIOCTRUNCATE, (caddr_t)&p->snapshot) < 0) {
                snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCTRUNCATE: %s",
                    pcap_strerror(errno));
@@ -460,10 +467,10 @@ your system may not be properly configured; see the packetfilter(4) man page\n",
                goto bad;
        }
 
-       if (p->md.timeout != 0) {
+       if (p->opt.timeout != 0) {
                struct timeval timeout;
-               timeout.tv_sec = p->md.timeout / 1000;
-               timeout.tv_usec = (p->md.timeout * 1000) % 1000000;
+               timeout.tv_sec = p->opt.timeout / 1000;
+               timeout.tv_usec = (p->opt.timeout * 1000) % 1000000;
                if (ioctl(p->fd, EIOCSRTIMEOUT, (caddr_t)&timeout) < 0) {
                        snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCSRTIMEOUT: %s",
                                pcap_strerror(errno));
@@ -503,7 +510,7 @@ pcap_create_interface(const char *device, char *ebuf)
 {
        pcap_t *p;
 
-       p = pcap_create_common(device, ebuf);
+       p = pcap_create_common(device, ebuf, sizeof (struct pcap_pf));
        if (p == NULL)
                return (NULL);
 
@@ -520,6 +527,7 @@ pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
 static int
 pcap_setfilter_pf(pcap_t *p, struct bpf_program *fp)
 {
+       struct pcap_pf *pf = p->private;
        struct bpf_version bv;
 
        /*
@@ -561,7 +569,7 @@ pcap_setfilter_pf(pcap_t *p, struct bpf_program *fp)
                         * a window to annoy the user.
                         */
                        fprintf(stderr, "tcpdump: Using kernel BPF filter\n");
-                       p->md.use_bpf = 1;
+                       pf->filtering_in_kernel = 1;
 
                        /*
                         * Discard any previously-received packets,
@@ -599,6 +607,6 @@ pcap_setfilter_pf(pcap_t *p, struct bpf_program *fp)
         * a warning of some sort.
         */
        fprintf(stderr, "tcpdump: Filtering in user process\n");
-       p->md.use_bpf = 0;
+       pf->filtering_in_kernel = 0;
        return (0);
 }
index e0be766f7cc4c8f23697b3da9ce2e7999acd934f..1210b7ce24128909dd1a301c5817b91349a537fb 100644 (file)
@@ -50,6 +50,13 @@ 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);
 
+/*
+ * Private data for capturing on Septel devices.
+ */
+struct pcap_septel {
+       struct pcap_stat stat;
+}
+
 /*
  *  Read at most max_packets from the capture queue and call the callback
  *  for each of them. Returns the number of packets handled, -1 if an
@@ -57,6 +64,7 @@ static int septel_setnonblock(pcap_t *p, int nonblock, char *errbuf);
  */
 static int septel_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) {
 
+  struct pcap_septel *ps = p->private;
   HDR *h;
   MSG *m;
   int processed = 0 ;
@@ -154,7 +162,7 @@ loop:
         pcap_header.len = packet_len;
 
         /* Count the packet. */
-        p->md.stat.ps_recv++;
+        ps->stat.ps_recv++;
 
         /* Call the user supplied callback function */
         callback(user, &pcap_header, dp);
@@ -229,7 +237,7 @@ pcap_t *septel_create(const char *device, char *ebuf, int *is_ours) {
        /* OK, it's probably ours. */
        *is_ours = 1;
 
-       p = pcap_create_common(device, ebuf);
+       p = pcap_create_common(device, ebuf, sizeof (struct pcap_septel));
        if (p == NULL)
                return NULL;
 
@@ -238,10 +246,11 @@ pcap_t *septel_create(const char *device, char *ebuf, int *is_ours) {
 }
 
 static int septel_stats(pcap_t *p, struct pcap_stat *ps) {
-  /*p->md.stat.ps_recv = 0;*/
-  /*p->md.stat.ps_drop = 0;*/
+  struct pcap_septel *handlep = p->private;
+  /*handlep->stat.ps_recv = 0;*/
+  /*handlep->stat.ps_drop = 0;*/
   
-  *ps = p->md.stat;
+  *ps = handlep->stat;
  
   return 0;
 }
@@ -282,8 +291,6 @@ static int septel_setfilter(pcap_t *p, struct bpf_program *fp) {
     return -1;
   }
 
-  p->md.use_bpf = 0;
-
   return (0);
 }
 
@@ -291,5 +298,6 @@ static int septel_setfilter(pcap_t *p, struct bpf_program *fp) {
 static int
 septel_setnonblock(pcap_t *p, int nonblock, char *errbuf)
 {
-  return (0);
+  fprintf(errbuf, PCAP_ERRBUF_SIZE, "Non-blocking mode not supported on Septel devices");
+  return (-1);
 }
index 19219993e533e35a46246583c3ee5a7770bc7771..7ab801ecee6146b2f0a54191465846aa0024bdfe 100644 (file)
 #define LIVE                   1
 
 typedef struct iface {
-       struct iface    *next;                                  /* a pointer to the next interface */
-       char                    *name;                                  /* this interface's name on Wireshark */
-       char                    *IOPname;                               /* this interface's name on an IOP */
-       uint32_t                iftype;                                 /* the type of interface (DLT values) */
+       struct iface    *next;          /* a pointer to the next interface */
+       char            *name;          /* this interface's name */
+       char            *IOPname;       /* this interface's name on an IOP */
+       uint32_t        iftype;         /* the type of interface (DLT values) */
 } iface_t;
 
 typedef struct unit {
-       char                            *ip;                            /* this unit's IP address (as extracted from /etc/hosts) */
-       int                                     fd;                                     /* the connection to this unit (if it exists) */
-       int                                     find_fd;                        /* a big kludge to avoid my programming limitations since I could have this unit open for findalldevs purposes */
-       int                                     first_time;                     /* 0 = just opened via acn_open_live(),  ie. the first time, NZ = nth time */
-       struct sockaddr_in      *serv_addr;                     /* the address control block for comms to this unit */
-       int                                     chassis;
-       int                                     geoslot;
-       iface_t                         *iface;                         /* a pointer to a linked list of interface structures */
-       char                            *imsg;                          /* a pointer to an inbound message */
-       int                                     len;                            /* the current size of the inbound message */
+       char                    *ip;            /* this unit's IP address (as extracted from /etc/hosts) */
+       int                     fd;             /* the connection to this unit (if it exists) */
+       int                     find_fd;        /* a big kludge to avoid my programming limitations since I could have this unit open for findalldevs purposes */
+       int                     first_time;     /* 0 = just opened via acn_open_live(),  ie. the first time, NZ = nth time */
+       struct sockaddr_in      *serv_addr;     /* the address control block for comms to this unit */
+       int                     chassis;
+       int                     geoslot;
+       iface_t                 *iface;         /* a pointer to a linked list of interface structures */
+       char                    *imsg;          /* a pointer to an inbound message */
+       int                     len;            /* the current size of the inbound message */
 } unit_t;
 
-static char                    *errorString;
 static unit_t          units[MAX_CHASSIS+1][MAX_GEOSLOT+1];    /* we use indexes of 1 through 8, but we reserve/waste index 0 */
-static fd_set          readfds;                                                                /* a place to store the file descriptors for the connections to the IOPs */
-static fd_set          working_set;
-static int                     max_fs;
-static char                    static_buf[32];
+static fd_set          readfds;                                /* a place to store the file descriptors for the connections to the IOPs */
+static int             max_fs;
 
-pcap_if_t                      *acn_if_list;                                                   /* pcap's list of available interfaces */
+pcap_if_t              *acn_if_list;           /* pcap's list of available interfaces */
 
 static void dump_interface_list(void) {
        pcap_if_t               *iff;
        pcap_addr_t             *addr;
-       int                             longest_name_len = 0;
+       int                     longest_name_len = 0;
        char                    *n, *d, *f;
-       int                             if_number = 0;
+       int                     if_number = 0;
 
        iff = acn_if_list;
        while (iff) {
@@ -405,18 +402,16 @@ static void acn_freealldevs(void) {
        }
 }
 
-static char *nonUnified_port_num(unit_t *u, int IOPportnum) {
+static void nonUnified_IOP_port_name(char *buf, size_t bufsize, const char *proto, unit_t *u) {
 
-       sprintf(static_buf, "%d_%d", u->chassis, u->geoslot);
-       return static_buf;
+       snprintf(buf, bufsize, "%s_%d_%d", proto, u->chassis, u->geoslot);
 }
 
-static char *unified_port_num(unit_t *u, int IOPportnum) {
+static void unified_IOP_port_name(char *buf, size_t bufsize, const char *proto, unit_t *u, int IOPportnum) {
        int                     portnum;
 
        portnum = ((u->chassis - 1) * 64) + ((u->geoslot - 1) * 8) + IOPportnum + 1;
-       sprintf(static_buf, "%d", portnum);
-       return static_buf;
+       snprintf(buf, bufsize, "%s_%d", proto, portnum);
 }
 
 static char *translate_IOP_to_pcap_name(unit_t *u, char *IOPname, bpf_u_int32 iftype) {
@@ -448,24 +443,38 @@ static char *translate_IOP_to_pcap_name(unit_t *u, char *IOPname, bpf_u_int32 if
        if (strncmp(IOPname, "lo", 2) == 0) {
                IOPportnum = atoi(&IOPname[2]);
                switch (iftype) {
-                       case DLT_EN10MB:        proto = "lo";           port = nonUnified_port_num(u, IOPportnum);      break;
-                       default:                        proto = "???";          port = unified_port_num(u, IOPportnum);         break;
+                       case DLT_EN10MB:
+                               nonUnified_IOP_port_name(buf, sizeof buf, "lo", u);
+                               break;
+                       default:
+                               unified_IOP_port_name(buf, sizeof buf, "???", u, IOPportnum);
+                               break;
                }
        } else if (strncmp(IOPname, "eth", 3) == 0) {
                IOPportnum = atoi(&IOPname[3]);
                switch (iftype) {
-                       case DLT_EN10MB:        proto = "eth";          port = nonUnified_port_num(u, IOPportnum);      break;
-                       default:                        proto = "???";          port = unified_port_num(u, IOPportnum);         break;
+                       case DLT_EN10MB:
+                               nonUnified_IOP_port_name(buf, sizeof buf, "eth", u);
+                               break;
+                       default:
+                               unified_IOP_port_name(buf, sizeof buf, "???", u, IOPportnum);
+                               break;
                }
        } else if (strncmp(IOPname, "wan", 3) == 0) {
                IOPportnum = atoi(&IOPname[3]);
                switch (iftype) {
-                       case DLT_SITA:          proto = "wan";          port = unified_port_num(u, IOPportnum);         break;
-                       default:                        proto = "???";          port = unified_port_num(u, IOPportnum);         break;
+                       case DLT_SITA:
+                               unified_IOP_port_name(buf, sizeof buf, "wan", u, IOPportnum);
+                               break;
+                       default:
+                               unified_IOP_port_name(buf, sizeof buf, "???", u, IOPportnum);
+                               break;
                }
+       } else {
+               fprintf(stderr, "Error... invalid IOP name %s\n", IOPname);
+               return NULL;
        }
 
-       sprintf(buf, "%s_%s", proto, port);             /* compose the user's name for that IOP port name */
        name = malloc(strlen(buf) + 1);                 /* get memory for that name */
         if (name == NULL) {    /* oops, we didn't get the memory requested     */
                 fprintf(stderr, "Error...couldn't allocate memory for IOP port name...value of errno is: %d\n", errno);
@@ -714,6 +723,8 @@ static void wait_for_all_answers(void) {
 
        while (1) {
                int flag = 0;
+               fd_set working_set;
+
                for (fd = 0; fd <= max_fs; fd++) {                                                              /* scan the list of descriptors we may be listening to */
                        if (FD_ISSET(fd, &readfds)) flag = 1;                                           /* and see if there are any still set */
                }
@@ -931,7 +942,7 @@ static int pcap_read_acn(pcap_t *handle, int max_packets, pcap_handler callback,
        struct pcap_pkthdr      pcap_header;
 
        //printf("pcap_read_acn()\n");                  // fulko
-       acn_start_monitor(handle->fd, handle->snapshot, handle->md.timeout, handle->md.clear_promisc, handle->direction);       /* maybe tell him to start monitoring */
+       acn_start_monitor(handle->fd, handle->snapshot, handle->opt.timeout, handle->opt.promisc, handle->direction);   /* maybe tell him to start monitoring */
        //printf("pcap_read_acn() after start monitor\n");                      // fulko
 
        handle->bp = packet_header;
@@ -976,7 +987,6 @@ static int pcap_activate_sita(pcap_t *handle) {
            &handle->linktype);
        if (fd == -1)
                return PCAP_ERROR;
-       handle->md.clear_promisc = handle->md.promisc;
        handle->fd = fd;
        handle->bufsize = handle->snapshot;
 
@@ -1002,7 +1012,7 @@ static int pcap_activate_sita(pcap_t *handle) {
 pcap_t *pcap_create_interface(const char *device, char *ebuf) {
        pcap_t *p;
 
-       p = pcap_create_common(device, ebuf);
+       p = pcap_create_common(device, ebuf, 0);
        if (p == NULL)
                return (NULL);
 
index f09952f9ce05b92b39198a8562596c758dc1fd0a..6d215ea146078d749df451e7df1756ae46abef23 100644 (file)
 #include <sys/types.h>
 #include <unistd.h>
 
+#include <snf.h>
+
 #include "pcap-int.h"
 #include "pcap-snf.h"
 
+/*
+ * Private data for capturing on SNF devices.
+ */
+struct pcap_snf {
+       snf_handle_t snf_handle; /* opaque device handle */
+       snf_ring_t   snf_ring;   /* opaque device ring handle */
+        int          snf_timeout;
+        int          snf_boardnum;
+};
+
 static int
 snf_set_datalink(pcap_t *p, int dlt)
 {
@@ -31,7 +43,7 @@ snf_pcap_stats(pcap_t *p, struct pcap_stat *ps)
        struct snf_ring_stats stats;
        int rc;
 
-       if ((rc = snf_ring_getstats(p->md.snf_ring, &stats))) {
+       if ((rc = snf_ring_getstats(ps->snf_ring, &stats))) {
                snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "snf_get_stats: %s",
                         pcap_strerror(rc));
                return -1;
@@ -45,30 +57,36 @@ snf_pcap_stats(pcap_t *p, struct pcap_stat *ps)
 static void
 snf_platform_cleanup(pcap_t *p)
 {
+       struct pcap_snf *ps = p->private;
+
        if (p == NULL)
                return;
 
-       snf_ring_close(p->md.snf_ring);
-       snf_close(p->md.snf_handle);
+       snf_ring_close(ps->snf_ring);
+       snf_close(ps->snf_handle);
        pcap_cleanup_live_common(p);
 }
 
 static int
 snf_getnonblock(pcap_t *p, char *errbuf)
 {
-       return (p->md.snf_timeout == 0);
+       struct pcap_snf *ps = p->private;
+
+       return (ps->snf_timeout == 0);
 }
 
 static int
 snf_setnonblock(pcap_t *p, int nonblock, char *errbuf)
 {
+       struct pcap_snf *ps = p->private;
+
        if (nonblock)
-               p->md.snf_timeout = 0;
+               ps->snf_timeout = 0;
        else {
-               if (p->md.timeout <= 0)
-                       p->md.snf_timeout = -1; /* forever */
+               if (p->opt.timeout <= 0)
+                       ps->snf_timeout = -1; /* forever */
                else
-                       p->md.snf_timeout = p->md.timeout;
+                       ps->snf_timeout = p->opt.timeout;
        }
        return (0);
 }
@@ -91,6 +109,7 @@ snf_timestamp_to_timeval(const int64_t ts_nanosec)
 static int
 snf_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
 {
+       struct pcap_snf *ps = p->private;
        struct pcap_pkthdr hdr;
        int i, flags, err, caplen, n;
        struct snf_recv_req req;
@@ -112,7 +131,7 @@ snf_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
                        }
                }
 
-               err = snf_ring_recv(p->md.snf_ring, p->md.snf_timeout, &req);
+               err = snf_ring_recv(ps->snf_ring, ps->snf_timeout, &req);
 
                if (err) {
                        if (err == EBUSY || err == EAGAIN)
@@ -158,8 +177,6 @@ snf_setfilter(pcap_t *p, struct bpf_program *fp)
        if (install_bpf_program(p, fp) < 0)
                return -1;
 
-       p->md.use_bpf = 0;
-
        return (0);
 }
 
@@ -174,6 +191,7 @@ snf_inject(pcap_t *p, const void *buf _U_, size_t size _U_)
 static int
 snf_activate(pcap_t* p)
 {
+       struct pcap_snf *ps = p->private;
        char *device = p->opt.source;
        const char *nr = NULL;
        int err;
@@ -192,31 +210,31 @@ snf_activate(pcap_t* p)
        else
                nr = NULL;
 
-       err = snf_open(p->md.snf_boardnum,
+       err = snf_open(ps->snf_boardnum,
                        0, /* let SNF API parse SNF_NUM_RINGS, if set */
                        NULL, /* default RSS, or use SNF_RSS_FLAGS env */
                        0, /* default to SNF_DATARING_SIZE from env */
                        flags, /* may want pshared */
-                       &p->md.snf_handle);
+                       &ps->snf_handle);
        if (err != 0) {
                snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
                         "snf_open failed: %s", pcap_strerror(err));
                return -1;
        }
 
-       err = snf_ring_open(p->md.snf_handle, &p->md.snf_ring);
+       err = snf_ring_open(ps->snf_handle, &ps->snf_ring);
        if (err != 0) {
                snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
                         "snf_ring_open failed: %s", pcap_strerror(err));
                return -1;
        }
 
-       if (p->md.timeout <= 0)
-               p->md.snf_timeout = -1;
+       if (p->opt.timeout <= 0)
+               ps->snf_timeout = -1;
        else
-               p->md.snf_timeout = p->md.timeout;
+               ps->snf_timeout = p->opt.timeout;
 
-       err = snf_start(p->md.snf_handle);
+       err = snf_start(ps->snf_handle);
        if (err != 0) {
                snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
                         "snf_start failed: %s", pcap_strerror(err));
@@ -237,9 +255,6 @@ snf_activate(pcap_t* p)
        p->setnonblock_op = snf_setnonblock;
        p->stats_op = snf_pcap_stats;
        p->cleanup_op = snf_platform_cleanup;
-       p->md.stat.ps_recv = 0;
-       p->md.stat.ps_drop = 0;
-       p->md.stat.ps_ifdrop = 0;
        return 0;
 }
 
@@ -260,6 +275,7 @@ snf_create(const char *device, char *ebuf, int *is_ours)
        int boardnum = -1;
        struct snf_ifaddrs *ifaddrs, *ifa;
        size_t devlen;
+       struct pcap_snf *ps;
 
        if (snf_init(SNF_VERSION_API)) {
                /* Can't initialize the API, so no SNF devices */
@@ -303,11 +319,12 @@ snf_create(const char *device, char *ebuf, int *is_ours)
        /* OK, it's probably ours. */
        *is_ours = 1;
 
-       p = pcap_create_common(device, ebuf);
+       p = pcap_create_common(device, ebuf, sizeof (struct pcap_snf));
        if (p == NULL)
                return NULL;
+       ps = p->private;
 
        p->activate_op = snf_activate;
-       p->md.snf_boardnum = boardnum;
+       ps->snf_boardnum = boardnum;
        return p;
 }
index b22b737f8dbfef419415c96869c04cec10f816d7..c910c8b35a315cc028080c5c0b3c81c620bf4846 100644 (file)
@@ -84,9 +84,17 @@ static const char rcsid[] _U_ =
 /* Forwards */
 static int nit_setflags(int, int, int, char *);
 
+/*
+ * Private data for capturing on STREAMS NIT devices.
+ */
+struct pcap_snit {
+       struct pcap_stat stat;
+};
+
 static int
 pcap_stats_snit(pcap_t *p, struct pcap_stat *ps)
 {
+       struct pcap_snit *psn = p->private;
 
        /*
         * "ps_recv" counts packets handed to the filter, not packets
@@ -105,13 +113,14 @@ pcap_stats_snit(pcap_t *p, struct pcap_stat *ps)
         * kernel by libpcap or packets not yet read from libpcap by the
         * application.
         */
-       *ps = p->md.stat;
+       *ps = psn->stat;
        return (0);
 }
 
 static int
 pcap_read_snit(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
 {
+       struct pcap_snit *psn = p->private;
        register int cc, n;
        register u_char *bp, *cp, *ep;
        register struct nit_bufhdr *hdrp;
@@ -160,7 +169,7 @@ pcap_read_snit(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
                        }
                }
 
-               ++p->md.stat.ps_recv;
+               ++psn->stat.ps_recv;
                cp = bp;
 
                /* get past NIT buffer  */
@@ -172,7 +181,7 @@ pcap_read_snit(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
                cp += sizeof(*ntp);
 
                ndp = (struct nit_ifdrops *)cp;
-               p->md.stat.ps_drop = ndp->nh_drops;
+               psn->stat.ps_drop = ndp->nh_drops;
                cp += sizeof *ndp;
 
                /* get past packet len  */
@@ -349,7 +358,7 @@ pcap_activate_snit(pcap_t *p)
                    pcap_strerror(errno));
                goto bad;
        }
-       if (nit_setflags(p->fd, p->opt.promisc, p->md.timeout, p->errbuf) < 0)
+       if (nit_setflags(p->fd, p->opt.promisc, p->opt.timeout, p->errbuf) < 0)
                goto bad;
 
        (void)ioctl(fd, I_FLUSH, (char *)FLUSHR);
@@ -411,7 +420,7 @@ pcap_create_interface(const char *device, char *ebuf)
 {
        pcap_t *p;
 
-       p = pcap_create_common(device, ebuf);
+       p = pcap_create_common(device, ebuf, sizeof (struct pcap_snit));
        if (p == NULL)
                return (NULL);
 
index 9314b8ce74bce5c80b3c5415bcbd4dc23320a903..7d0db139ade6e305dcbf3567718dd6455e0a1ef7 100644 (file)
@@ -58,9 +58,17 @@ static const char rcsid[] _U_ =
 #include "os-proto.h"
 #endif
 
+/*
+ * Private data for capturing on snoop devices.
+ */
+struct pcap_snoop {
+       struct pcap_stat stat;
+};
+
 static int
 pcap_read_snoop(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
 {
+       struct pcap_snoop *psn = p->private;
        int cc;
        register struct snoopheader *sh;
        register u_int datalen;
@@ -124,7 +132,7 @@ again:
        if (p->fcode.bf_insns == NULL ||
            bpf_filter(p->fcode.bf_insns, cp, datalen, caplen)) {
                struct pcap_pkthdr h;
-               ++p->md.stat.ps_recv;
+               ++psn->stat.ps_recv;
                h.ts.tv_sec = sh->snoop_timestamp.tv_sec;
                h.ts.tv_usec = sh->snoop_timestamp.tv_usec;
                h.len = datalen;
@@ -156,6 +164,7 @@ pcap_inject_snoop(pcap_t *p, const void *buf, size_t size)
 static int
 pcap_stats_snoop(pcap_t *p, struct pcap_stat *ps)
 {
+       struct pcap_snoop *psn = p->private;
        register struct rawstats *rs;
        struct rawstats rawstats;
 
@@ -180,7 +189,7 @@ pcap_stats_snoop(pcap_t *p, struct pcap_stat *ps)
         * rather than just this socket?  If not, why does it have
         * both Snoop and Drain statistics?
         */
-       p->md.stat.ps_drop =
+       psn->stat.ps_drop =
            rs->rs_snoop.ss_ifdrops + rs->rs_snoop.ss_sbdrops +
            rs->rs_drain.ds_ifdrops + rs->rs_drain.ds_sbdrops;
 
@@ -189,7 +198,7 @@ pcap_stats_snoop(pcap_t *p, struct pcap_stat *ps)
         * As filtering is done in userland, this does not include
         * packets dropped because we ran out of buffer space.
         */
-       *ps = p->md.stat;
+       *ps = psn->stat;
        return (0);
 }
 
@@ -398,7 +407,7 @@ pcap_create_interface(const char *device, char *ebuf)
 {
        pcap_t *p;
 
-       p = pcap_create_common(device, ebuf);
+       p = pcap_create_common(device, ebuf, sizeof (struct pcap_snoop));
        if (p == NULL)
                return (NULL);
 
index 26f61897060415949fd08e5ac4e65728fe940c29..ff04baae1748082e131308b1312e71cb1850a52a 100644 (file)
@@ -121,6 +121,16 @@ struct mon_bin_mfetch {
 #define MON_BIN_DATA_ZERO      0x4 /* data buffer is not available */
 #define MON_BIN_ERROR  0x8
 
+/*
+ * Private data for capturing on Linux USB.
+ */
+struct pcap_usb_linux {
+       u_char *mmapbuf;        /* memory-mapped region pointer */
+       size_t mmapbuflen;      /* size of region */
+       int bus_index;
+       u_int packets_read;
+};
+
 /* forward declaration */
 static int usb_activate(pcap_t *);
 static int usb_stats_linux(pcap_t *, struct pcap_stat *);
@@ -204,14 +214,15 @@ usb_findalldevs(pcap_if_t **alldevsp, char *err_str)
 static 
 int usb_mmap(pcap_t* handle)
 {
+       struct pcap_usb_linux *handlep = handle->private;
        int len = ioctl(handle->fd, MON_IOCQ_RING_SIZE);
        if (len < 0) 
                return 0;
 
-       handle->md.mmapbuflen = len;
-       handle->md.mmapbuf = mmap(0, handle->md.mmapbuflen, PROT_READ,
+       handlep->mmapbuflen = len;
+       handlep->mmapbuf = mmap(0, handlep->mmapbuflen, PROT_READ,
            MAP_SHARED, handle->fd, 0);
-       return handle->md.mmapbuf != MAP_FAILED;
+       return handlep->mmapbuf != MAP_FAILED;
 }
 
 #define CTRL_TIMEOUT    (5*1000)        /* milliseconds */
@@ -318,7 +329,7 @@ usb_create(const char *device, char *ebuf, int *is_ours)
        /* OK, it's probably ours. */
        *is_ours = 1;
 
-       p = pcap_create_common(device, ebuf);
+       p = pcap_create_common(device, ebuf, sizeof (struct pcap_usb_linux));
        if (p == NULL)
                return (NULL);
 
@@ -329,6 +340,7 @@ usb_create(const char *device, char *ebuf, int *is_ours)
 static int
 usb_activate(pcap_t* handle)
 {
+       struct pcap_usb_linux *handlep = handle->private;
        char            full_path[USB_LINE_LEN];
 
        /* Initialize some components of the pcap structure. */
@@ -344,7 +356,7 @@ usb_activate(pcap_t* handle)
        handle->setnonblock_op = pcap_setnonblock_fd;
 
        /*get usb bus index from device name */
-       if (sscanf(handle->opt.source, USB_IFACE"%d", &handle->md.ifindex) != 1)
+       if (sscanf(handle->opt.source, USB_IFACE"%d", &handlep->bus_index) != 1)
        {
                snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
                        "Can't get USB bus index from %s", handle->opt.source);
@@ -352,7 +364,7 @@ usb_activate(pcap_t* handle)
        }
 
        /*now select the read method: try to open binary interface */
-       snprintf(full_path, USB_LINE_LEN, LINUX_USB_MON_DEV"%d", handle->md.ifindex);  
+       snprintf(full_path, USB_LINE_LEN, LINUX_USB_MON_DEV"%d", handlep->bus_index);  
        handle->fd = open(full_path, O_RDONLY, 0);
        if (handle->fd >= 0)
        {
@@ -370,7 +382,7 @@ usb_activate(pcap_t* handle)
                        handle->stats_op = usb_stats_linux_bin;
                        handle->read_op = usb_read_linux_mmap;
                        handle->cleanup_op = usb_cleanup_linux_mmap;
-                       probe_devices(handle->md.ifindex);
+                       probe_devices(handlep->bus_index);
 
                        /*
                         * "handle->fd" is a real file, so "select()" and
@@ -383,11 +395,11 @@ usb_activate(pcap_t* handle)
                /* can't mmap, use plain binary interface access */
                handle->stats_op = usb_stats_linux_bin;
                handle->read_op = usb_read_linux_bin;
-               probe_devices(handle->md.ifindex);
+               probe_devices(handlep->bus_index);
        }
        else {
                /*Binary interface not available, try open text interface */
-               snprintf(full_path, USB_LINE_LEN, USB_TEXT_DIR"/%dt", handle->md.ifindex);  
+               snprintf(full_path, USB_LINE_LEN, USB_TEXT_DIR"/%dt", handlep->bus_index);  
                handle->fd = open(full_path, O_RDONLY, 0);
                if (handle->fd < 0)
                {
@@ -397,7 +409,7 @@ usb_activate(pcap_t* handle)
                                 * Not found at the new location; try
                                 * the old location.
                                 */
-                               snprintf(full_path, USB_LINE_LEN, USB_TEXT_DIR_OLD"/%dt", handle->md.ifindex);  
+                               snprintf(full_path, USB_LINE_LEN, USB_TEXT_DIR_OLD"/%dt", handlep->bus_index);  
                                handle->fd = open(full_path, O_RDONLY, 0);
                        }
                        if (handle->fd < 0) {
@@ -456,6 +468,7 @@ usb_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *u
        * /usr/src/linux/Documentation/usb/usbmon.txt 
        * for message format
        */
+       struct pcap_usb_linux *handlep = handle->private;
        unsigned timestamp;
        int tag, cnt, ep_num, dev_addr, dummy, ret, urb_len, data_len;
        char etype, pipeid1, pipeid2, status[16], urb_tag, line[USB_LINE_LEN];
@@ -500,7 +513,7 @@ usb_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *u
        }
        uhdr->id = tag;
        uhdr->device_address = dev_addr;
-       uhdr->bus_id = handle->md.ifindex;
+       uhdr->bus_id = handlep->bus_index;
        uhdr->status = 0;
        string += cnt;
 
@@ -639,7 +652,7 @@ got:
        if (handle->fcode.bf_insns == NULL ||
            bpf_filter(handle->fcode.bf_insns, handle->buffer,
              pkth.len, pkth.caplen)) {
-               handle->md.packets_read++;
+               handlep->packets_read++;
                callback(user, &pkth, handle->buffer);
                return 1;
        }
@@ -657,13 +670,14 @@ usb_inject_linux(pcap_t *handle, const void *buf, size_t size)
 static int 
 usb_stats_linux(pcap_t *handle, struct pcap_stat *stats)
 {
+       struct pcap_usb_linux *handlep = handle->private;
        int dummy, ret, consumed, cnt;
        char string[USB_LINE_LEN];
        char token[USB_LINE_LEN];
        char * ptr = string;
        int fd;
 
-       snprintf(string, USB_LINE_LEN, USB_TEXT_DIR"/%ds", handle->md.ifindex);
+       snprintf(string, USB_LINE_LEN, USB_TEXT_DIR"/%ds", handlep->bus_index);
        fd = open(string, O_RDONLY, 0);
        if (fd < 0)
        {
@@ -673,7 +687,7 @@ usb_stats_linux(pcap_t *handle, struct pcap_stat *stats)
                         * Not found at the new location; try the old
                         * location.
                         */
-                       snprintf(string, USB_LINE_LEN, USB_TEXT_DIR_OLD"/%ds", handle->md.ifindex);
+                       snprintf(string, USB_LINE_LEN, USB_TEXT_DIR_OLD"/%ds", handlep->bus_index);
                        fd = open(string, O_RDONLY, 0);
                }
                if (fd < 0) {
@@ -724,7 +738,7 @@ usb_stats_linux(pcap_t *handle, struct pcap_stat *stats)
                ptr += cnt;
        }
 
-       stats->ps_recv = handle->md.packets_read;
+       stats->ps_recv = handlep->packets_read;
        stats->ps_ifdrop = 0;
        return 0;
 }
@@ -740,6 +754,7 @@ usb_setdirection_linux(pcap_t *p, pcap_direction_t d)
 static int 
 usb_stats_linux_bin(pcap_t *handle, struct pcap_stat *stats)
 {
+       struct pcap_usb_linux *handlep = handle->private;
        int ret;
        struct mon_bin_stats st;
        ret = ioctl(handle->fd, MON_IOCG_STATS, &st);
@@ -750,7 +765,7 @@ usb_stats_linux_bin(pcap_t *handle, struct pcap_stat *stats)
                return -1;
        }
 
-       stats->ps_recv = handle->md.packets_read + st.queued;
+       stats->ps_recv = handlep->packets_read + st.queued;
        stats->ps_drop = st.dropped;
        stats->ps_ifdrop = 0;
        return 0;
@@ -763,6 +778,7 @@ usb_stats_linux_bin(pcap_t *handle, struct pcap_stat *stats)
 static int
 usb_read_linux_bin(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user)
 {
+       struct pcap_usb_linux *handlep = handle->private;
        struct mon_bin_get info;
        int ret;
        struct pcap_pkthdr pkth;
@@ -805,7 +821,7 @@ usb_read_linux_bin(pcap_t *handle, int max_packets, pcap_handler callback, u_cha
        if (handle->fcode.bf_insns == NULL ||
            bpf_filter(handle->fcode.bf_insns, handle->buffer,
              pkth.len, pkth.caplen)) {
-               handle->md.packets_read++;
+               handlep->packets_read++;
                callback(user, &pkth, handle->buffer);
                return 1;
        }
@@ -821,6 +837,7 @@ usb_read_linux_bin(pcap_t *handle, int max_packets, pcap_handler callback, u_cha
 static int
 usb_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user)
 {
+       struct pcap_usb_linux *handlep = handle->private;
        struct mon_bin_mfetch fetch;
        int32_t vec[VEC_SIZE];
        struct pcap_pkthdr pkth;
@@ -866,7 +883,7 @@ usb_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback, u_ch
                nflush = fetch.nfetch;
                for (i=0; i<fetch.nfetch; ++i) {
                        /* discard filler */
-                       hdr = (pcap_usb_header*) &handle->md.mmapbuf[vec[i]];
+                       hdr = (pcap_usb_header*) &handlep->mmapbuf[vec[i]];
                        if (hdr->event_type == '@') 
                                continue;
 
@@ -885,7 +902,7 @@ usb_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback, u_ch
                        if (handle->fcode.bf_insns == NULL ||
                            bpf_filter(handle->fcode.bf_insns, (u_char*) hdr,
                              pkth.len, pkth.caplen)) {
-                               handle->md.packets_read++;
+                               handlep->packets_read++;
                                callback(user, &pkth, (u_char*) hdr);
                                packets++;
                        }
@@ -904,10 +921,12 @@ usb_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback, u_ch
 static void
 usb_cleanup_linux_mmap(pcap_t* handle)
 {
+       struct pcap_usb_linux *handlep = handle->private;
+
        /* if we have a memory-mapped buffer, unmap it */
-       if (handle->md.mmapbuf != NULL) {
-               munmap(handle->md.mmapbuf, handle->md.mmapbuflen);
-               handle->md.mmapbuf = NULL;
+       if (handlep->mmapbuf != NULL) {
+               munmap(handlep->mmapbuf, handlep->mmapbuflen);
+               handlep->mmapbuf = NULL;
        }
        pcap_cleanup_live_common(handle);
 }
index 130a44296ed5526eb9e393ef7312899d2bb7fb03..a490d0b24c5bf9cad755c616c95342d4080e20f3 100644 (file)
@@ -71,6 +71,17 @@ static int pcap_setnonblock_win32(pcap_t *, int, char *);
 /* Equivalent to ntohs(), but a lot faster under Windows */
 #define SWAPS(_X) ((_X & 0xff) << 8) | (_X >> 8)
 
+/*
+ * Private data for capturing on WinPcap devices.
+ */
+struct pcap_win {
+       int nonblock;
+
+#ifdef HAVE_DAG_API
+       int     dag_fcs_bits;   /* Number of checksum bits from link layer */
+#endif
+};
+
 /*
  * Header that the WinPcap driver associates to the packets.
  * Once was in bpf.h
@@ -253,6 +264,7 @@ pcap_read_win32_npf(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
 static int
 pcap_read_win32_dag(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
 {
+       struct pcap_win *pw = p->private;
        u_char *dp = NULL;
        int     packet_len = 0, caplen = 0;
        struct pcap_pkthdr      pcap_header;
@@ -295,7 +307,7 @@ pcap_read_win32_dag(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
                        break;
 
                /* Increase the number of captured packets */
-               p->md.stat.ps_recv++;
+               pw->stat.ps_recv++;
                
                /* Find the beginning of the packet */
                dp = ((u_char *)header) + dag_record_size;
@@ -312,7 +324,7 @@ pcap_read_win32_dag(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
 
                case TYPE_ETH:
                        swt = SWAPS(header->wlen);
-                       packet_len = swt - (p->md.dag_fcs_bits);
+                       packet_len = swt - (pw->dag_fcs_bits);
                        caplen = erf_record_len - dag_record_size - 2;
                        if (caplen > packet_len)
                        {
@@ -324,7 +336,7 @@ pcap_read_win32_dag(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
                
                case TYPE_HDLC_POS:
                        swt = SWAPS(header->wlen);
-                       packet_len = swt - (p->md.dag_fcs_bits);
+                       packet_len = swt - (pw->dag_fcs_bits);
                        caplen = erf_record_len - dag_record_size;
                        if (caplen > packet_len)
                        {
@@ -457,6 +469,7 @@ pcap_cleanup_win32(pcap_t *p)
 static int
 pcap_activate_win32(pcap_t *p)
 {
+       struct pcap_win *pw = p->private;
        NetType type;
 
        if (p->opt.rfmon) {
@@ -672,13 +685,13 @@ pcap_activate_win32(pcap_t *p)
                
                /* Set the length of the FCS associated to any packet. This value 
                 * will be subtracted to the packet length */
-               p->md.dag_fcs_bits = p->adapter->DagFcsLen;
+               pw->dag_fcs_bits = p->adapter->DagFcsLen;
        }
 #else
        goto bad;
 #endif /* HAVE_DAG_API */
        
-       PacketSetReadTimeout(p->adapter, p->md.timeout);
+       PacketSetReadTimeout(p->adapter, p->opt.timeout);
        
 #ifdef HAVE_DAG_API
        if(p->adapter->Flags & INFO_FLAG_DAG_CARD)
@@ -743,12 +756,12 @@ pcap_create_interface(const char *device, char *ebuf)
                }
 
                snprintf(deviceAscii, length + 1, "%ws", (wchar_t*)device);
-               p = pcap_create_common(deviceAscii, ebuf);
+               p = pcap_create_common(deviceAscii, ebuf, sizeof (struct pcap_win));
                free(deviceAscii);
        }
        else
        {
-               p = pcap_create_common(device, ebuf);
+               p = pcap_create_common(device, ebuf, sizeof (struct pcap_win));
        }
 
        if (p == NULL)
@@ -801,25 +814,26 @@ pcap_setfilter_win32_dag(pcap_t *p, struct bpf_program *fp) {
                return -1;
        }
        
-       p->md.use_bpf = 0;
-       
        return (0);
 }
 
 static int
 pcap_getnonblock_win32(pcap_t *p, char *errbuf)
 {
+       struct pcap_win *pw = p->private;
+
        /*
         * XXX - if there were a PacketGetReadTimeout() call, we
         * would use it, and return 1 if the timeout is -1
         * and 0 otherwise.
         */
-       return (p->nonblock);
+       return (pw->nonblock);
 }
 
 static int
 pcap_setnonblock_win32(pcap_t *p, int nonblock, char *errbuf)
 {
+       struct pcap_win *pw = p->private;
        int newtimeout;
 
        if (nonblock) {
@@ -833,14 +847,14 @@ pcap_setnonblock_win32(pcap_t *p, int nonblock, char *errbuf)
                 * (Note that this may be -1, in which case we're not
                 * really leaving non-blocking mode.)
                 */
-               newtimeout = p->md.timeout;
+               newtimeout = p->opt.timeout;
        }
        if (!PacketSetReadTimeout(p->adapter, newtimeout)) {
                snprintf(errbuf, PCAP_ERRBUF_SIZE,
                    "PacketSetReadTimeout: %s", pcap_win32strerror());
                return (-1);
        }
-       p->nonblock = (newtimeout == -1);
+       pw->nonblock = (newtimeout == -1);
        return (0);
 }
 
diff --git a/pcap.c b/pcap.c
index 0bf845db89b9925fcfc8704358b8aa339bd80541..b69e9ed9736cc713815dc0a7c059a564afcaa6a1 100644 (file)
--- a/pcap.c
+++ b/pcap.c
@@ -226,7 +226,7 @@ pcap_next_ex(pcap_t *p, struct pcap_pkthdr **pkt_header,
        /* Saves a pointer to the packet headers */
        *pkt_header= &p->pcap_header;
 
-       if (p->sf.rfile != NULL) {
+       if (p->rfile != NULL) {
                int status;
 
                /* We are on an offline capture */
@@ -469,24 +469,59 @@ initialize_ops(pcap_t *p)
        p->oneshot_callback = pcap_oneshot;
 }
 
-pcap_t *
-pcap_create_common(const char *source, char *ebuf)
+static pcap_t *
+pcap_alloc_pcap_t(char *ebuf, size_t size)
 {
+       char *chunk;
        pcap_t *p;
 
-       p = malloc(sizeof(*p));
-       if (p == NULL) {
+       /*
+        * Allocate a chunk of memory big enough for a pcap_t
+        * plus a structure following it of size "size".  The
+        * structure following it is a private data structure
+        * for the routines that handle this pcap_t.
+        */
+       chunk = malloc(sizeof (pcap_t) + size);
+       if (chunk == NULL) {
                snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
                    pcap_strerror(errno));
                return (NULL);
        }
-       memset(p, 0, sizeof(*p));
+       memset(chunk, 0, sizeof (pcap_t) + size);
+
+       /*
+        * Get a pointer to the pcap_t at the beginning.
+        */
+       p = (pcap_t *)chunk;
+
 #ifndef WIN32
        p->fd = -1;     /* not opened yet */
        p->selectable_fd = -1;
-       p->send_fd = -1;
 #endif 
 
+       if (size == 0) {
+               /* No private data was requested. */
+               p->private = NULL;
+       } else {
+               /*
+                * Set the pointer to the private data; that's the structure
+                * of size "size" following the pcap_t.
+                */
+               p->private = (void *)(chunk + sizeof (pcap_t));
+       }
+
+       return (p);
+}
+
+pcap_t *
+pcap_create_common(const char *source, char *ebuf, size_t size)
+{
+       pcap_t *p;
+
+       p = pcap_alloc_pcap_t(ebuf, size);
+       if (p == NULL)
+               return (NULL);
+
        p->opt.source = strdup(source);
        if (p->opt.source == NULL) {
                snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
@@ -557,7 +592,7 @@ pcap_set_timeout(pcap_t *p, int timeout_ms)
 {
        if (pcap_check_activated(p))
                return (PCAP_ERROR_ACTIVATED);
-       p->md.timeout = timeout_ms;
+       p->opt.timeout = timeout_ms;
        return (0);
 }
 
@@ -692,6 +727,26 @@ fail:
        return (NULL);
 }
 
+pcap_t *
+pcap_open_offline_common(char *ebuf, size_t size)
+{
+       pcap_t *p;
+
+       p = pcap_alloc_pcap_t(ebuf, size);
+       if (p == NULL)
+               return (NULL);
+
+       p->opt.source = strdup("(savefile)");
+       if (p->opt.source == NULL) {
+               snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
+                   pcap_strerror(errno));
+               free(p);
+               return (NULL);
+       }
+
+       return (p);
+}
+
 int
 pcap_dispatch(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
 {
@@ -714,7 +769,7 @@ pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
        register int n;
 
        for (;;) {
-               if (p->sf.rfile != NULL) {
+               if (p->rfile != NULL) {
                        /*
                         * 0 means EOF, so don't loop if we get 0.
                         */
@@ -1168,25 +1223,25 @@ pcap_snapshot(pcap_t *p)
 int
 pcap_is_swapped(pcap_t *p)
 {
-       return (p->sf.swapped);
+       return (p->swapped);
 }
 
 int
 pcap_major_version(pcap_t *p)
 {
-       return (p->sf.version_major);
+       return (p->version_major);
 }
 
 int
 pcap_minor_version(pcap_t *p)
 {
-       return (p->sf.version_minor);
+       return (p->version_minor);
 }
 
 FILE *
 pcap_file(pcap_t *p)
 {
-       return (p->sf.rfile);
+       return (p->rfile);
 }
 
 int
@@ -1561,7 +1616,7 @@ pcap_do_addexit(pcap_t *p)
 void
 pcap_add_to_pcaps_to_close(pcap_t *p)
 {
-       p->md.next = pcaps_to_close;
+       p->next = pcaps_to_close;
        pcaps_to_close = p;
 }
 
@@ -1571,7 +1626,7 @@ pcap_remove_from_pcaps_to_close(pcap_t *p)
        pcap_t *pc, *prevpc;
 
        for (pc = pcaps_to_close, prevpc = NULL; pc != NULL;
-           prevpc = pc, pc = pc->md.next) {
+           prevpc = pc, pc = pc->next) {
                if (pc == p) {
                        /*
                         * Found it.  Remove it from the list.
@@ -1580,12 +1635,12 @@ pcap_remove_from_pcaps_to_close(pcap_t *p)
                                /*
                                 * It was at the head of the list.
                                 */
-                               pcaps_to_close = pc->md.next;
+                               pcaps_to_close = pc->next;
                        } else {
                                /*
                                 * It was in the middle of the list.
                                 */
-                               prevpc->md.next = pc->md.next;
+                               prevpc->next = pc->next;
                        }
                        break;
                }
@@ -1616,7 +1671,6 @@ pcap_cleanup_live_common(pcap_t *p)
                p->fd = -1;
        }
        p->selectable_fd = -1;
-       p->send_fd = -1;
 #endif
 }
 
index 8115749b1343a9be633fa5f07b7380ef5cc189c4..ad3f6bdab38937fc941c6eecd9994128742cdd98 100644 (file)
@@ -163,8 +163,8 @@ sf_setdirection(pcap_t *p, pcap_direction_t d)
 static void
 sf_cleanup(pcap_t *p)
 {
-       if (p->sf.rfile != stdin)
-               (void)fclose(p->sf.rfile);
+       if (p->rfile != stdin)
+               (void)fclose(p->rfile);
        if (p->buffer != NULL)
                free(p->buffer);
        pcap_freecode(&p->fcode);
@@ -231,7 +231,7 @@ pcap_t* pcap_hopen_offline(intptr_t osfd, char *errbuf)
 }
 #endif
 
-static int (*check_headers[])(pcap_t *, bpf_u_int32, FILE *, char *) = {
+static pcap_t *(*check_headers[])(bpf_u_int32, FILE *, char *, int *) = {
        pcap_check_header,
        pcap_ng_check_header
 };
@@ -248,10 +248,7 @@ pcap_fopen_offline(FILE *fp, char *errbuf)
        bpf_u_int32 magic;
        size_t amt_read;
        u_int i;
-
-       p = pcap_create_common("(savefile)", errbuf);
-       if (p == NULL)
-               return (NULL);
+       int err;
 
        /*
         * Read the first 4 bytes of the file; the network analyzer dump
@@ -272,26 +269,23 @@ pcap_fopen_offline(FILE *fp, char *errbuf)
                            (unsigned long)sizeof(magic),
                            (unsigned long)amt_read);
                }
-               goto bad;
+               return (NULL);
        }
 
        /*
         * Try all file types.
         */
        for (i = 0; i < N_FILE_TYPES; i++) {
-               switch ((*check_headers[i])(p, magic, fp, errbuf)) {
-
-               case -1:
+               p = (*check_headers[i])(magic, fp, errbuf, &err);
+               if (p != NULL) {
+                       /* Yup, that's it. */
+                       goto found;
+               }
+               if (err) {
                        /*
                         * Error trying to read the header.
                         */
-                       goto bad;
-
-               case 1:
-                       /*
-                        * Yup, that's it.
-                        */
-                       goto found;
+                       return (NULL);
                }
        }
 
@@ -299,15 +293,13 @@ pcap_fopen_offline(FILE *fp, char *errbuf)
         * Well, who knows what this mess is....
         */
        snprintf(errbuf, PCAP_ERRBUF_SIZE, "unknown file format");
-       goto bad;
+       return (NULL);
 
 found:
-       p->sf.rfile = fp;
+       p->rfile = fp;
 
-#ifdef PCAP_FDDIPAD
        /* Padding only needed for live capture fcode */
        p->fddipad = 0;
-#endif
 
 #if !defined(WIN32) && !defined(MSDOS)
        /*
@@ -337,9 +329,6 @@ found:
        p->activated = 1;
 
        return (p);
- bad:
-       free(p);
-       return (NULL);
 }
 
 /*
@@ -375,7 +364,7 @@ pcap_offline_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
                                return (n);
                }
 
-               status = p->sf.next_packet_op(p, &h, &data);
+               status = p->next_packet_op(p, &h, &data);
                if (status) {
                        if (status == 1)
                                return (0);
index 7eb6db76493b1b4b49c2bc7f86fe5685a15042d6..a34cf317e0d03114ca231f22ca91a6f8c75499ec 100644 (file)
@@ -201,6 +201,13 @@ struct block_cursor {
        bpf_u_int32     block_type;
 };
 
+struct pcap_ng_sf {
+       bpf_u_int32 ifcount;    /* number of interfaces seen in this capture */
+       u_int tsresol;          /* time stamp resolution */
+       u_int tsscale;          /* scaling factor for resolution -> microseconds */
+       u_int64_t tsoffset;     /* time stamp offset */
+};
+
 static int pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr,
     u_char **data);
 
@@ -239,7 +246,7 @@ read_block(FILE *fp, pcap_t *p, struct block_cursor *cursor, char *errbuf)
        if (status <= 0)
                return (status);        /* error or EOF */
 
-       if (p->sf.swapped) {
+       if (p->swapped) {
                bhdr.block_type = SWAPLONG(bhdr.block_type);
                bhdr.total_length = SWAPLONG(bhdr.total_length);
        }
@@ -346,7 +353,7 @@ get_opthdr_from_block_data(pcap_t *p, struct block_cursor *cursor, char *errbuf)
        /*
         * Byte-swap it if necessary.
         */
-       if (p->sf.swapped) {
+       if (p->swapped) {
                opthdr->option_code = SWAPSHORT(opthdr->option_code);
                opthdr->option_length = SWAPSHORT(opthdr->option_length);
        }
@@ -481,7 +488,7 @@ process_idb_options(pcap_t *p, struct block_cursor *cursor, u_int *tsresol,
                        }
                        saw_tsoffset = 1;
                        memcpy(tsoffset, optvalue, sizeof(*tsoffset));
-                       if (p->sf.swapped)
+                       if (p->swapped)
                                *tsoffset = SWAPLL(*tsoffset);
                        break;
 
@@ -498,18 +505,26 @@ done:
  * Check whether this is a pcap-ng savefile and, if it is, extract the
  * relevant information from the header.
  */
-int
-pcap_ng_check_header(pcap_t *p, bpf_u_int32 magic, FILE *fp, char *errbuf)
+pcap_t *
+pcap_ng_check_header(bpf_u_int32 magic, FILE *fp, char *errbuf, int *err)
 {
        size_t amt_read;
        bpf_u_int32 total_length;
        bpf_u_int32 byte_order_magic;
        struct block_header *bhdrp;
        struct section_header_block *shbp;
+       pcap_t *p;
+       int swapped = 0;
+       struct pcap_ng_sf *ps;
        int status;
        struct block_cursor cursor;
        struct interface_description_block *idbp;
 
+       /*
+        * Assume no read errors.
+        */
+       *err = 0;
+
        /*
         * Check whether the first 4 bytes of the file are the block
         * type for a pcap-ng savefile. 
@@ -524,7 +539,7 @@ pcap_ng_check_header(pcap_t *p, bpf_u_int32 magic, FILE *fp, char *errbuf)
                 * this as possibly being a pcap-ng file transferred
                 * between UN*X and Windows in text file format?
                 */
-               return (0);     /* nope */
+               return (NULL);  /* nope */
        }
 
        /*
@@ -544,14 +559,15 @@ pcap_ng_check_header(pcap_t *p, bpf_u_int32 magic, FILE *fp, char *errbuf)
                        snprintf(errbuf, PCAP_ERRBUF_SIZE,
                            "error reading dump file: %s",
                            pcap_strerror(errno));
-                       return (-1);    /* fail */
+                       *err = 1;
+                       return (NULL);  /* fail */
                }
 
                /*
                 * Possibly a weird short text file, so just say
                 * "not pcap-ng".
                 */
-               return (0);
+               return (NULL);
        }
        amt_read = fread(&byte_order_magic, 1, sizeof(byte_order_magic), fp);
        if (amt_read < sizeof(byte_order_magic)) {
@@ -559,14 +575,15 @@ pcap_ng_check_header(pcap_t *p, bpf_u_int32 magic, FILE *fp, char *errbuf)
                        snprintf(errbuf, PCAP_ERRBUF_SIZE,
                            "error reading dump file: %s",
                            pcap_strerror(errno));
-                       return (-1);    /* fail */
+                       *err = 1;
+                       return (NULL);  /* fail */
                }
 
                /*
                 * Possibly a weird short text file, so just say
                 * "not pcap-ng".
                 */
-               return (0);
+               return (NULL);
        }
        if (byte_order_magic != BYTE_ORDER_MAGIC) {
                byte_order_magic = SWAPLONG(byte_order_magic);
@@ -574,9 +591,9 @@ pcap_ng_check_header(pcap_t *p, bpf_u_int32 magic, FILE *fp, char *errbuf)
                        /*
                         * Not a pcap-ng file.
                         */
-                       return (0);
+                       return (NULL);
                }
-               p->sf.swapped = 1;
+               swapped = 1;
                total_length = SWAPLONG(total_length);
        }
 
@@ -588,9 +605,23 @@ pcap_ng_check_header(pcap_t *p, bpf_u_int32 magic, FILE *fp, char *errbuf)
                    "Section Header Block in pcap-ng dump file has a length of %u < %lu",
                    total_length,
                    (unsigned long)(sizeof(*bhdrp) + sizeof(*shbp) + sizeof(struct block_trailer)));
-               return (-1);
+               *err = 1;
+               return (NULL);
        }
 
+       /*
+        * OK, this is a good pcap-ng file.
+        * Allocate a pcap_t for it.
+        */
+       p = pcap_open_offline_common(errbuf, sizeof (struct pcap_ng_sf));
+       if (p == NULL) {
+               /* Allocation failed. */
+               *err = 1;
+               return (NULL);
+       }
+       p->swapped = swapped;
+       ps = p->private;
+
        /*
         * Allocate a buffer into which to read blocks.  We default to
         * the maximum of:
@@ -609,7 +640,9 @@ pcap_ng_check_header(pcap_t *p, bpf_u_int32 magic, FILE *fp, char *errbuf)
        p->buffer = malloc(p->bufsize);
        if (p->buffer == NULL) {
                snprintf(errbuf, PCAP_ERRBUF_SIZE, "out of memory");
-               return (-1);
+               free(p);
+               *err = 1;
+               return (NULL);
        }
 
        /*
@@ -627,7 +660,7 @@ pcap_ng_check_header(pcap_t *p, bpf_u_int32 magic, FILE *fp, char *errbuf)
            1, errbuf) == -1)
                goto fail;
 
-       if (p->sf.swapped) {
+       if (p->swapped) {
                /*
                 * Byte-swap the fields we've read.
                 */
@@ -644,15 +677,15 @@ pcap_ng_check_header(pcap_t *p, bpf_u_int32 magic, FILE *fp, char *errbuf)
                    shbp->major_version);
                goto fail;
        }
-       p->sf.version_major = shbp->major_version;
-       p->sf.version_minor = shbp->minor_version;
+       p->version_major = shbp->major_version;
+       p->version_minor = shbp->minor_version;
 
        /*
         * Set the default time stamp resolution and offset.
         */
-       p->sf.tsresol = 1000000;        /* microsecond resolution */
-       p->sf.tsscale = 1;              /* multiply by 1 to scale to microseconds */
-       p->sf.tsoffset = 0;             /* absolute timestamps */
+       ps->tsresol = 1000000;  /* microsecond resolution */
+       ps->tsscale = 1;        /* multiply by 1 to scale to microseconds */
+       ps->tsoffset = 0;       /* absolute timestamps */
 
        /*
         * Now start looking for an Interface Description Block.
@@ -685,7 +718,7 @@ pcap_ng_check_header(pcap_t *p, bpf_u_int32 magic, FILE *fp, char *errbuf)
                        /*
                         * Byte-swap it if necessary.
                         */
-                       if (p->sf.swapped) {
+                       if (p->swapped) {
                                idbp->linktype = SWAPSHORT(idbp->linktype);
                                idbp->snaplen = SWAPLONG(idbp->snaplen);
                        }
@@ -693,14 +726,14 @@ pcap_ng_check_header(pcap_t *p, bpf_u_int32 magic, FILE *fp, char *errbuf)
                        /*
                         * Count this interface.
                         */
-                       p->sf.ifcount++;
+                       ps->ifcount++;
 
                        /*
                         * Now look for various time stamp options, so
                         * we know how to interpret the time stamps.
                         */
-                       if (process_idb_options(p, &cursor, &p->sf.tsresol,
-                           &p->sf.tsoffset, errbuf) == -1)
+                       if (process_idb_options(p, &cursor, &ps->tsresol,
+                           &ps->tsoffset, errbuf) == -1)
                                goto fail;
 
                        /*
@@ -708,18 +741,18 @@ pcap_ng_check_header(pcap_t *p, bpf_u_int32 magic, FILE *fp, char *errbuf)
                         * sub-second part of the time stamp to
                         * microseconds.
                         */
-                       if (p->sf.tsresol > 1000000) {
+                       if (ps->tsresol > 1000000) {
                                /*
                                 * Higher than microsecond resolution;
                                 * scale down to microseconds.
                                 */
-                               p->sf.tsscale = (p->sf.tsresol / 1000000);
+                               ps->tsscale = (ps->tsresol / 1000000);
                        } else {
                                /*
                                 * Lower than microsecond resolution;
                                 * scale up to microseconds.
                                 */
-                               p->sf.tsscale = (1000000 / p->sf.tsresol);
+                               ps->tsscale = (1000000 / ps->tsresol);
                        }
                        goto done;
 
@@ -749,13 +782,15 @@ done:
        p->linktype = linktype_to_dlt(idbp->linktype);
        p->linktype_ext = 0;
 
-       p->sf.next_packet_op = pcap_ng_next_packet;
+       p->next_packet_op = pcap_ng_next_packet;
 
-       return (1);
+       return (p);
 
 fail:
        free(p->buffer);
-       return (-1);
+       free(p);
+       *err = 1;
+       return (NULL);
 }
 
 /*
@@ -766,6 +801,7 @@ fail:
 static int
 pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
 {
+       struct pcap_ng_sf *ps = p->private;
        struct block_cursor cursor;
        int status;
        struct enhanced_packet_block *epbp;
@@ -774,7 +810,7 @@ pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
        bpf_u_int32 interface_id = 0xFFFFFFFF;
        struct interface_description_block *idbp;
        struct section_header_block *shbp;
-       FILE *fp = p->sf.rfile;
+       FILE *fp = p->rfile;
        u_int tsresol;
        u_int64_t tsoffset;
        u_int64_t t, sec, frac;
@@ -808,7 +844,7 @@ pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
                        /*
                         * Byte-swap it if necessary.
                         */
-                       if (p->sf.swapped) {
+                       if (p->swapped) {
                                /* these were written in opposite byte order */
                                interface_id = SWAPLONG(epbp->interface_id);
                                hdr->caplen = SWAPLONG(epbp->caplen);
@@ -843,7 +879,7 @@ pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
                        /*
                         * Byte-swap it if necessary.
                         */
-                       if (p->sf.swapped) {
+                       if (p->swapped) {
                                /* these were written in opposite byte order */
                                hdr->len = SWAPLONG(spbp->len);
                        } else
@@ -873,7 +909,7 @@ pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
                        /*
                         * Byte-swap it if necessary.
                         */
-                       if (p->sf.swapped) {
+                       if (p->swapped) {
                                /* these were written in opposite byte order */
                                interface_id = SWAPSHORT(pbp->interface_id);
                                hdr->caplen = SWAPLONG(pbp->caplen);
@@ -902,7 +938,7 @@ pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
                        /*
                         * Byte-swap it if necessary.
                         */
-                       if (p->sf.swapped) {
+                       if (p->swapped) {
                                idbp->linktype = SWAPSHORT(idbp->linktype);
                                idbp->snaplen = SWAPLONG(idbp->snaplen);
                        }
@@ -931,7 +967,7 @@ pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
                        /*
                         * Count this interface.
                         */
-                       p->sf.ifcount++;
+                       ps->ifcount++;
 
                        /*
                         * Set the default time stamp resolution and offset.
@@ -950,12 +986,12 @@ pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
                        if (process_idb_options(p, &cursor, &tsresol, &tsoffset,
                            p->errbuf) == -1)
                                return (-1);
-                       if (tsresol != p->sf.tsresol) {
+                       if (tsresol != ps->tsresol) {
                                snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
                                    "an interface has a time stamp resolution different from the time stamp resolution of the first interface");
                                return (-1);
                        }
-                       if (tsoffset != p->sf.tsoffset) {
+                       if (tsoffset != ps->tsoffset) {
                                snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
                                    "an interface has a time stamp offset different from the time stamp offset of the first interface");
                                return (-1);
@@ -977,7 +1013,7 @@ pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
                         * the same as that of the previous section.
                         * We'll check for that later.
                         */
-                       if (p->sf.swapped) {
+                       if (p->swapped) {
                                shbp->byte_order_magic =
                                    SWAPLONG(shbp->byte_order_magic);
                                shbp->major_version =
@@ -1034,7 +1070,7 @@ pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
                         * any IDBs, we'll fail when we see a packet
                         * block.)
                         */
-                       p->sf.ifcount = 0;
+                       ps->ifcount = 0;
                        break;
 
                default:
@@ -1049,7 +1085,7 @@ found:
        /*
         * Is the interface ID an interface we know?
         */
-       if (interface_id >= p->sf.ifcount) {
+       if (interface_id >= ps->ifcount) {
                /*
                 * Yes.  Fail.
                 */
@@ -1062,20 +1098,20 @@ found:
        /*
         * Convert the time stamp to a struct timeval.
         */
-       sec = t / p->sf.tsresol + p->sf.tsoffset;
-       frac = t % p->sf.tsresol;
-       if (p->sf.tsresol > 1000000) {
+       sec = t / ps->tsresol + ps->tsoffset;
+       frac = t % ps->tsresol;
+       if (ps->tsresol > 1000000) {
                /*
                 * Higher than microsecond resolution; scale down to
                 * microseconds.
                 */
-               frac /= p->sf.tsscale;
+               frac /= ps->tsscale;
        } else {
                /*
                 * Lower than microsecond resolution; scale up to
                 * microseconds.
                 */
-               frac *= p->sf.tsscale;
+               frac *= ps->tsscale;
        }
        hdr->ts.tv_sec = sec;
        hdr->ts.tv_usec = frac;
@@ -1087,7 +1123,7 @@ found:
        if (*data == NULL)
                return (-1);
 
-       if (p->sf.swapped) {
+       if (p->swapped) {
                /*
                 * Convert pseudo-headers from the byte order of
                 * the host on which the file was saved to our
index cc5518241b4537bc91c39bc584ca9cb0854fd071..abeb018140016c9dbc976df9d399e58104c96edd 100644 (file)
@@ -26,6 +26,7 @@
 #ifndef sf_pcap_ng_h
 #define        sf_pcap_ng_h
 
-extern int pcap_ng_check_header(pcap_t *, bpf_u_int32, FILE *, char *);
+extern pcap_t *pcap_ng_check_header(bpf_u_int32 magic, FILE *fp, char *errbuf,
+    int *err);
 
 #endif
index 2b31a2b7a0f1f2d94ebff1ab1b5e4fc5fa19b3e3..3344a2f3f39e16250991afd84a30cbf01455e52e 100644 (file)
--- a/sf-pcap.c
+++ b/sf-pcap.c
@@ -122,15 +122,37 @@ static const char rcsid[] _U_ =
 
 static int pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **datap);
 
+/*
+ * Private data for reading pcap savefiles.
+ */
+typedef enum {
+       NOT_SWAPPED,
+       SWAPPED,
+       MAYBE_SWAPPED
+} swapped_type_t;
+
+struct pcap_sf {
+       size_t hdrsize;
+       swapped_type_t lengths_swapped;
+};
+
 /*
  * Check whether this is a pcap savefile and, if it is, extract the
  * relevant information from the header.
  */
-int
-pcap_check_header(pcap_t *p, bpf_u_int32 magic, FILE *fp, char *errbuf)
+pcap_t *
+pcap_check_header(bpf_u_int32 magic, FILE *fp, char *errbuf, int *err)
 {
        struct pcap_file_header hdr;
        size_t amt_read;
+       pcap_t *p;
+       int swapped = 0;
+       struct pcap_sf *ps;
+
+       /*
+        * Assume no read errors.
+        */
+       *err = 0;
 
        /*
         * Check whether the first 4 bytes of the file are the magic
@@ -140,8 +162,8 @@ pcap_check_header(pcap_t *p, bpf_u_int32 magic, FILE *fp, char *errbuf)
        if (magic != TCPDUMP_MAGIC && magic != KUZNETZOV_TCPDUMP_MAGIC) {
                magic = SWAPLONG(magic);
                if (magic != TCPDUMP_MAGIC && magic != KUZNETZOV_TCPDUMP_MAGIC)
-                       return (0);     /* nope */
-               p->sf.swapped = 1;
+                       return (NULL);  /* nope */
+               swapped = 1;
        }
 
        /*
@@ -162,13 +184,14 @@ pcap_check_header(pcap_t *p, bpf_u_int32 magic, FILE *fp, char *errbuf)
                            (unsigned long)sizeof(hdr),
                            (unsigned long)amt_read);
                }
-               return (-1);
+               *err = 1;
+               return (NULL);
        }
 
        /*
         * If it's a byte-swapped capture file, byte-swap the header.
         */
-       if (p->sf.swapped) {
+       if (swapped) {
                hdr.version_major = SWAPSHORT(hdr.version_major);
                hdr.version_minor = SWAPSHORT(hdr.version_minor);
                hdr.thiszone = SWAPLONG(hdr.thiszone);
@@ -180,16 +203,31 @@ pcap_check_header(pcap_t *p, bpf_u_int32 magic, FILE *fp, char *errbuf)
        if (hdr.version_major < PCAP_VERSION_MAJOR) {
                snprintf(errbuf, PCAP_ERRBUF_SIZE,
                    "archaic pcap savefile format");
-               return (-1);
+               *err = 1;
+               return (NULL);
+       }
+
+       /*
+        * OK, this is a good pcap file.
+        * Allocate a pcap_t for it.
+        */
+       p = pcap_open_offline_common(errbuf, sizeof (struct pcap_sf));
+       if (p == NULL) {
+               /* Allocation failed. */
+               *err = 1;
+               return (NULL);
        }
-       p->sf.version_major = hdr.version_major;
-       p->sf.version_minor = hdr.version_minor;
+       p->swapped = swapped;
+       p->version_major = hdr.version_major;
+       p->version_minor = hdr.version_minor;
        p->tzoff = hdr.thiszone;
        p->snapshot = hdr.snaplen;
        p->linktype = linktype_to_dlt(LT_LINKTYPE(hdr.linktype));
        p->linktype_ext = LT_LINKTYPE_EXT(hdr.linktype);
 
-       p->sf.next_packet_op = pcap_next_packet;
+       p->next_packet_op = pcap_next_packet;
+
+       ps = p->private;
 
        /*
         * We interchanged the caplen and len fields at version 2.3,
@@ -205,19 +243,19 @@ pcap_check_header(pcap_t *p, bpf_u_int32 magic, FILE *fp, char *errbuf)
 
        case 2:
                if (hdr.version_minor < 3)
-                       p->sf.lengths_swapped = SWAPPED;
+                       ps->lengths_swapped = SWAPPED;
                else if (hdr.version_minor == 3)
-                       p->sf.lengths_swapped = MAYBE_SWAPPED;
+                       ps->lengths_swapped = MAYBE_SWAPPED;
                else
-                       p->sf.lengths_swapped = NOT_SWAPPED;
+                       ps->lengths_swapped = NOT_SWAPPED;
                break;
 
        case 543:
-               p->sf.lengths_swapped = SWAPPED;
+               ps->lengths_swapped = SWAPPED;
                break;
 
        default:
-               p->sf.lengths_swapped = NOT_SWAPPED;
+               ps->lengths_swapped = NOT_SWAPPED;
                break;
        }
 
@@ -239,7 +277,7 @@ pcap_check_header(pcap_t *p, bpf_u_int32 magic, FILE *fp, char *errbuf)
                 * data ourselves and read from that buffer in order to
                 * make that work.
                 */
-               p->sf.hdrsize = sizeof(struct pcap_sf_patched_pkthdr);
+               ps->hdrsize = sizeof(struct pcap_sf_patched_pkthdr);
 
                if (p->linktype == DLT_EN10MB) {
                        /*
@@ -265,7 +303,7 @@ pcap_check_header(pcap_t *p, bpf_u_int32 magic, FILE *fp, char *errbuf)
                        p->snapshot += 14;
                }
        } else
-               p->sf.hdrsize = sizeof(struct pcap_sf_pkthdr);
+               ps->hdrsize = sizeof(struct pcap_sf_pkthdr);
 
        /*
         * Allocate a buffer for the packet data.
@@ -280,10 +318,12 @@ pcap_check_header(pcap_t *p, bpf_u_int32 magic, FILE *fp, char *errbuf)
        p->buffer = malloc(p->bufsize);
        if (p->buffer == NULL) {
                snprintf(errbuf, PCAP_ERRBUF_SIZE, "out of memory");
-               return (-1);
+               free(p);
+               *err = 1;
+               return (NULL);
        }
 
-       return (1);
+       return (p);
 }
 
 /*
@@ -294,8 +334,9 @@ pcap_check_header(pcap_t *p, bpf_u_int32 magic, FILE *fp, char *errbuf)
 static int
 pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
 {
+       struct pcap_sf *ps = p->private;
        struct pcap_sf_patched_pkthdr sf_hdr;
-       FILE *fp = p->sf.rfile;
+       FILE *fp = p->rfile;
        size_t amt_read;
        bpf_u_int32 t;
 
@@ -306,8 +347,8 @@ pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
         * unpatched libpcap we only read as many bytes as the regular
         * header has.
         */
-       amt_read = fread(&sf_hdr, 1, p->sf.hdrsize, fp);
-       if (amt_read != p->sf.hdrsize) {
+       amt_read = fread(&sf_hdr, 1, ps->hdrsize, fp);
+       if (amt_read != ps->hdrsize) {
                if (ferror(fp)) {
                        snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
                            "error reading dump file: %s",
@@ -317,7 +358,7 @@ pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
                        if (amt_read != 0) {
                                snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
                                    "truncated dump file; tried to read %lu header bytes, only got %lu",
-                                   (unsigned long)p->sf.hdrsize,
+                                   (unsigned long)ps->hdrsize,
                                    (unsigned long)amt_read);
                                return (-1);
                        }
@@ -326,7 +367,7 @@ pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
                }
        }
 
-       if (p->sf.swapped) {
+       if (p->swapped) {
                /* these were written in opposite byte order */
                hdr->caplen = SWAPLONG(sf_hdr.caplen);
                hdr->len = SWAPLONG(sf_hdr.len);
@@ -339,7 +380,7 @@ pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
                hdr->ts.tv_usec = sf_hdr.ts.tv_usec;
        }
        /* Swap the caplen and len fields, if necessary. */
-       switch (p->sf.lengths_swapped) {
+       switch (ps->lengths_swapped) {
 
        case NOT_SWAPPED:
                break;
@@ -430,7 +471,7 @@ pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
        }
        *data = p->buffer;
 
-       if (p->sf.swapped) {
+       if (p->swapped) {
                /*
                 * Convert pseudo-headers from the byte order of
                 * the host on which the file was saved to our
index 3b3fbe893b4640b7e90a5e0cefdac455693264d8..fce6ee58a0352cecfc8bd72b787805e3785b7e9d 100644 (file)
--- a/sf-pcap.h
+++ b/sf-pcap.h
@@ -31,6 +31,7 @@
 #ifndef sf_pcap_h
 #define        sf_pcap_h
 
-extern int pcap_check_header(pcap_t *, bpf_u_int32, FILE *, char *);
+extern pcap_t *pcap_check_header(bpf_u_int32 magic, FILE *fp, char *errbuf,
+    int *err);
 
 #endif