summaryrefslogtreecommitdiffstats
path: root/contrib/libpcap/pcap-snit.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/libpcap/pcap-snit.c')
-rw-r--r--contrib/libpcap/pcap-snit.c59
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);
OpenPOWER on IntegriCloud