summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dlpisubs.c10
-rw-r--r--dlpisubs.h16
-rw-r--r--gencode.c21
-rw-r--r--pcap-bpf.c212
-rw-r--r--pcap-bt-linux.c19
-rw-r--r--pcap-can-linux.c18
-rw-r--r--pcap-canusb-linux.c114
-rw-r--r--pcap-dag.c140
-rw-r--r--pcap-dbus.c60
-rw-r--r--pcap-dlpi.c48
-rw-r--r--pcap-dos.c43
-rw-r--r--pcap-int.h242
-rw-r--r--pcap-libdlpi.c34
-rw-r--r--pcap-linux.c354
-rw-r--r--pcap-netfilter-linux.c17
-rw-r--r--pcap-nit.c19
-rw-r--r--pcap-pf.c70
-rw-r--r--pcap-septel.c24
-rw-r--r--pcap-sita.c86
-rw-r--r--pcap-snf.c63
-rw-r--r--pcap-snit.c19
-rw-r--r--pcap-snoop.c17
-rw-r--r--pcap-usb-linux.c63
-rw-r--r--pcap-win32.c38
-rw-r--r--pcap.c90
-rw-r--r--savefile.c41
-rw-r--r--sf-pcap-ng.c130
-rw-r--r--sf-pcap-ng.h3
-rw-r--r--sf-pcap.c93
-rw-r--r--sf-pcap.h3
30 files changed, 1232 insertions, 875 deletions
diff --git a/dlpisubs.c b/dlpisubs.c
index 23c78ced..4f2150df 100644
--- a/dlpisubs.c
+++ b/dlpisubs.c
@@ -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;
diff --git a/dlpisubs.h b/dlpisubs.h
index 1b57d4d2..8795af64 100644
--- a/dlpisubs.h
+++ b/dlpisubs.h
@@ -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);
diff --git a/gencode.c b/gencode.c
index 1cbaeebd..cb84dc48 100644
--- 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);
diff --git a/pcap-bpf.c b/pcap-bpf.c
index 9e739dc6..10b90264 100644
--- a/pcap-bpf.c
+++ b/pcap-bpf.c
@@ -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);
}
diff --git a/pcap-bt-linux.c b/pcap-bt-linux.c
index 037f64b9..e2268b8e 100644
--- a/pcap-bt-linux.c
+++ b/pcap-bt-linux.c
@@ -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 {
diff --git a/pcap-can-linux.c b/pcap-can-linux.c
index f6a3925e..bee669b0 100644
--- a/pcap-can-linux.c
+++ b/pcap-can-linux.c
@@ -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;
diff --git a/pcap-canusb-linux.c b/pcap-canusb-linux.c
index f3bebbc7..b04e8b6d 100644
--- a/pcap-canusb-linux.c
+++ b/pcap-canusb-linux.c
@@ -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;
diff --git a/pcap-dag.c b/pcap-dag.c
index 847a556f..d006aa61 100644
--- a/pcap-dag.c
+++ b/pcap-dag.c
@@ -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);
}
diff --git a/pcap-dbus.c b/pcap-dbus.c
index 40ace7f9..3a54d444 100644
--- a/pcap-dbus.c
+++ b/pcap-dbus.c
@@ -42,10 +42,18 @@
#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;
}
diff --git a/pcap-dlpi.c b/pcap-dlpi.c
index 4b285f39..323fbad9 100644
--- a/pcap-dlpi.c
+++ b/pcap-dlpi.c
@@ -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);
diff --git a/pcap-dos.c b/pcap-dos.c
index 72e8fdec..3c24758e 100644
--- a/pcap-dos.c
+++ b/pcap-dos.c
@@ -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;
}
}
diff --git a/pcap-int.h b/pcap-int.h
index 28b80fb4..3527ca34 100644
--- a/pcap-int.h
+++ b/pcap-int.h
@@ -42,10 +42,6 @@
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,29 +168,9 @@ 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().
*/
u_char *pkt;
@@ -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
diff --git a/pcap-libdlpi.c b/pcap-libdlpi.c
index acaa400d..351e9846 100644
--- a/pcap-libdlpi.c
+++ b/pcap-libdlpi.c
@@ -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);
diff --git a/pcap-linux.c b/pcap-linux.c
index 201f2aad..e49af804 100644
--- a/pcap-linux.c
+++ b/pcap-linux.c
@@ -284,6 +284,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.
*/
static void map_arphrd_to_dlt(pcap_t *, int, int);
@@ -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.
diff --git a/pcap-netfilter-linux.c b/pcap-netfilter-linux.c
index 48f29b02..35c677bc 100644
--- a/pcap-netfilter-linux.c
+++ b/pcap-netfilter-linux.c
@@ -74,11 +74,19 @@
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);
diff --git a/pcap-nit.c b/pcap-nit.c
index 85b32f2a..8e357211 100644
--- a/pcap-nit.c
+++ b/pcap-nit.c
@@ -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);
diff --git a/pcap-pf.c b/pcap-pf.c
index 84c6d547..eb06e7b5 100644
--- 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);
}
diff --git a/pcap-septel.c b/pcap-septel.c
index e0be766f..1210b7ce 100644
--- a/pcap-septel.c
+++ b/pcap-septel.c
@@ -51,12 +51,20 @@ 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
* error occured, or -2 if we were told to break out of the loop.
*/
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);
}
diff --git a/pcap-sita.c b/pcap-sita.c
index 19219993..7ab801ec 100644
--- a/pcap-sita.c
+++ b/pcap-sita.c
@@ -55,40 +55,37 @@
#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);
diff --git a/pcap-snf.c b/pcap-snf.c
index f09952f9..6d215ea1 100644
--- a/pcap-snf.c
+++ b/pcap-snf.c
@@ -15,9 +15,21 @@
#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;
}
diff --git a/pcap-snit.c b/pcap-snit.c
index b22b737f..c910c8b3 100644
--- a/pcap-snit.c
+++ b/pcap-snit.c
@@ -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);
diff --git a/pcap-snoop.c b/pcap-snoop.c
index 9314b8ce..7d0db139 100644
--- a/pcap-snoop.c
+++ b/pcap-snoop.c
@@ -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);
diff --git a/pcap-usb-linux.c b/pcap-usb-linux.c
index 26f61897..ff04baae 100644
--- a/pcap-usb-linux.c
+++ b/pcap-usb-linux.c
@@ -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);
}
diff --git a/pcap-win32.c b/pcap-win32.c
index 130a4429..a490d0b2 100644
--- a/pcap-win32.c
+++ b/pcap-win32.c
@@ -72,6 +72,17 @@ static int pcap_setnonblock_win32(pcap_t *, int, char *);
#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 0bf845db..b69e9ed9 100644
--- 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
}
diff --git a/savefile.c b/savefile.c
index 8115749b..ad3f6bda 100644
--- a/savefile.c
+++ b/savefile.c
@@ -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);
diff --git a/sf-pcap-ng.c b/sf-pcap-ng.c
index 7eb6db76..a34cf317 100644
--- a/sf-pcap-ng.c
+++ b/sf-pcap-ng.c
@@ -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,19 +505,27 @@ 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,10 +605,24 @@ 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
diff --git a/sf-pcap-ng.h b/sf-pcap-ng.h
index cc551824..abeb0181 100644
--- a/sf-pcap-ng.h
+++ b/sf-pcap-ng.h
@@ -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
diff --git a/sf-pcap.c b/sf-pcap.c
index 2b31a2b7..3344a2f3 100644
--- a/sf-pcap.c
+++ b/sf-pcap.c
@@ -123,14 +123,36 @@ 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
diff --git a/sf-pcap.h b/sf-pcap.h
index 3b3fbe89..fce6ee58 100644
--- 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