diff options
Diffstat (limited to 'pcap-snf.c')
-rw-r--r-- | pcap-snf.c | 67 |
1 files changed, 42 insertions, 25 deletions
diff --git a/pcap-snf.c b/pcap-snf.c index 396f3e5b0587..ee6ffa4dcc6e 100644 --- a/pcap-snf.c +++ b/pcap-snf.c @@ -15,8 +15,20 @@ #include <sys/types.h> #include <unistd.h> -#include "snf.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->priv; + 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->priv; + + return (ps->snf_timeout == 0); } static int snf_setnonblock(pcap_t *p, int nonblock, char *errbuf) { + struct pcap_snf *ps = p->priv; + 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->priv; struct pcap_pkthdr hdr; int i, flags, err, caplen, n; struct snf_recv_req req; @@ -99,7 +118,7 @@ snf_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) return -1; n = 0; - while (n < cnt || cnt < 0) { + while (n < cnt || PACKET_COUNT_IS_UNLIMITED(cnt)) { /* * Has "pcap_breakloop()" been called? */ @@ -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->priv; 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->priv; p->activate_op = snf_activate; - p->md.snf_boardnum = boardnum; + ps->snf_boardnum = boardnum; return p; } |