diff options
Diffstat (limited to 'contrib/libpcap/pcap-nit.c')
-rw-r--r-- | contrib/libpcap/pcap-nit.c | 58 |
1 files changed, 39 insertions, 19 deletions
diff --git a/contrib/libpcap/pcap-nit.c b/contrib/libpcap/pcap-nit.c index 85b32f2..ea81eb5 100644 --- a/contrib/libpcap/pcap-nit.c +++ b/contrib/libpcap/pcap-nit.c @@ -18,10 +18,6 @@ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#ifndef lint -static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/libpcap/pcap-nit.c,v 1.62 2008-04-14 20:40:58 guy Exp $ (LBL)"; -#endif #ifdef HAVE_CONFIG_H #include "config.h" @@ -71,9 +67,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->priv; /* * "ps_recv" counts packets handed to the filter, not packets @@ -91,13 +95,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->priv; register int cc, n; register u_char *bp, *cp, *ep; register struct nit_hdr *nh; @@ -156,7 +161,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 +172,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)); @@ -180,7 +185,7 @@ pcap_read_nit(pcap_t *p, int cnt, pcap_handler callback, u_char *user) h.len = nh->nh_wirelen; 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); @@ -209,28 +214,42 @@ pcap_inject_nit(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) { struct nit_ioc nioc; memset(&nioc, 0, sizeof(nioc)); - nioc.nioc_bufspace = BUFSPACE; - nioc.nioc_chunksize = CHUNKSIZE; nioc.nioc_typetomatch = NT_ALLTYPES; nioc.nioc_snaplen = p->snapshot; nioc.nioc_bufalign = sizeof(int); nioc.nioc_bufoffset = 0; - if (to_ms != 0) { + if (p->opt.buffer_size != 0) + nioc.nioc_bufspace = p->opt.buffer_size; + else { + /* Default buffer size */ + nioc.nioc_bufspace = BUFSPACE; + } + + if (p->opt.immediate) { + /* + * XXX - will this cause packets to be delivered immediately? + * XXX - given that this is for SunOS prior to 4.0, do + * we care? + */ + nioc.nioc_chunksize = 0; + } else + nioc.nioc_chunksize = CHUNKSIZE; + if (p->opt.timeout != 0) { nioc.nioc_flags |= NF_TIMEOUT; - nioc.nioc_timeout.tv_sec = to_ms / 1000; - nioc.nioc_timeout.tv_usec = (to_ms * 1000) % 1000000; + nioc.nioc_timeout.tv_sec = p->opt.timeout / 1000; + nioc.nioc_timeout.tv_usec = (p->opt.timeout * 1000) % 1000000; } - if (promisc) + if (p->opt.promisc) nioc.nioc_flags |= NF_PROMISC; - if (ioctl(fd, SIOCSNIT, &nioc) < 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "SIOCSNIT: %s", + if (ioctl(p->fd, SIOCSNIT, &nioc) < 0) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "SIOCSNIT: %s", pcap_strerror(errno)); return (-1); } @@ -273,7 +292,8 @@ 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); + if (nit_setflags(p) < 0) + goto bad; /* * NIT supports only ethernets. @@ -332,7 +352,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); |