diff options
Diffstat (limited to 'contrib/libpcap/pcap-snit.c')
-rw-r--r-- | contrib/libpcap/pcap-snit.c | 59 |
1 files changed, 39 insertions, 20 deletions
diff --git a/contrib/libpcap/pcap-snit.c b/contrib/libpcap/pcap-snit.c index b22b737..e6232c2 100644 --- a/contrib/libpcap/pcap-snit.c +++ b/contrib/libpcap/pcap-snit.c @@ -23,11 +23,6 @@ * This module now handles the STREAMS based NIT. */ -#ifndef lint -static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/libpcap/pcap-snit.c,v 1.77 2008-04-14 20:40:58 guy Exp $ (LBL)"; -#endif - #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -84,9 +79,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->priv; /* * "ps_recv" counts packets handed to the filter, not packets @@ -105,13 +108,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->priv; register int cc, n; register u_char *bp, *cp, *ep; register struct nit_bufhdr *hdrp; @@ -160,7 +164,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 +176,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 */ @@ -192,7 +196,7 @@ pcap_read_snit(pcap_t *p, int cnt, pcap_handler callback, u_char *user) h.len = nlp->nh_pktlen; h.caplen = caplen; (*callback)(user, &h, cp); - if (++n >= cnt && cnt > 0) { + if (++n >= cnt && !PACKET_COUNT_IS_UNLIMITED(cnt)) { p->cc = ep - bp; p->bp = bp; return (n); @@ -227,33 +231,48 @@ pcap_inject_snit(pcap_t *p, const void *buf, size_t size) } static int -nit_setflags(int fd, int promisc, int to_ms, char *ebuf) +nit_setflags(pcap_t *p) { bpf_u_int32 flags; struct strioctl si; + u_int zero = 0; struct timeval timeout; + if (p->opt.immediate) { + /* + * Set the chunk size to zero, so that chunks get sent + * up immediately. + */ + si.ic_cmd = NIOCSCHUNK; + si.ic_len = sizeof(zero); + si.ic_dp = (char *)&zero; + if (ioctl(p->fd, I_STR, (char *)&si) < 0) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "NIOCSCHUNK: %s", + pcap_strerror(errno)); + return (-1); + } + } si.ic_timout = INFTIM; - if (to_ms != 0) { - timeout.tv_sec = to_ms / 1000; - timeout.tv_usec = (to_ms * 1000) % 1000000; + if (p->opt.timeout != 0) { + timeout.tv_sec = p->opt.timeout / 1000; + timeout.tv_usec = (p->opt.timeout * 1000) % 1000000; si.ic_cmd = NIOCSTIME; si.ic_len = sizeof(timeout); si.ic_dp = (char *)&timeout; - if (ioctl(fd, I_STR, (char *)&si) < 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "NIOCSTIME: %s", + if (ioctl(p->fd, I_STR, (char *)&si) < 0) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "NIOCSTIME: %s", pcap_strerror(errno)); return (-1); } } flags = NI_TIMESTAMP | NI_LEN | NI_DROPS; - if (promisc) + if (p->opt.promisc) flags |= NI_PROMISC; si.ic_cmd = NIOCSFLAGS; si.ic_len = sizeof(flags); si.ic_dp = (char *)&flags; - if (ioctl(fd, I_STR, (char *)&si) < 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "NIOCSFLAGS: %s", + if (ioctl(p->fd, I_STR, (char *)&si) < 0) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "NIOCSFLAGS: %s", pcap_strerror(errno)); return (-1); } @@ -349,7 +368,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) < 0) goto bad; (void)ioctl(fd, I_FLUSH, (char *)FLUSHR); @@ -411,7 +430,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); |