diff options
Diffstat (limited to 'contrib/libpcap/pcap-pf.c')
-rw-r--r-- | contrib/libpcap/pcap-pf.c | 81 |
1 files changed, 43 insertions, 38 deletions
diff --git a/contrib/libpcap/pcap-pf.c b/contrib/libpcap/pcap-pf.c index 84c6d54..96a4a50 100644 --- a/contrib/libpcap/pcap-pf.c +++ b/contrib/libpcap/pcap-pf.c @@ -22,11 +22,6 @@ * Extraction/creation by Jeffrey Mogul, DECWRL */ -#ifndef lint -static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/libpcap/pcap-pf.c,v 1.97 2008-04-14 20:40:58 guy Exp $ (LBL)"; -#endif - #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -74,6 +69,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 +100,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->priv; 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 +138,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,42 +187,34 @@ 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) { + if (++n >= cnt && !PACKET_COUNT_IS_UNLIMITED(cnt)) { pc->cc = cc; pc->bp = bp; return (n); @@ -240,6 +242,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->priv; /* * If packet filtering is being done in the kernel: @@ -277,9 +280,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 +297,7 @@ pcap_stats_pf(pcap_t *p, struct pcap_stat *ps) static int pcap_activate_pf(pcap_t *p) { + struct pcap_pf *pf = p->priv; short enmode; int backlog = -1; /* request the most */ struct enfilter Filter; @@ -327,8 +331,10 @@ 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; - enmode = ENTSTAMP|ENBATCH|ENNONEXCL; + pf->OrigMissed = -1; + enmode = ENTSTAMP|ENNONEXCL; + if (!p->opt.immediate) + enmode |= ENBATCH; if (p->opt.promisc) enmode |= ENPROMISC; if (ioctl(p->fd, EIOCMBIS, (caddr_t)&enmode) < 0) { @@ -436,7 +442,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 +449,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 +464,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 +507,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 +524,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->priv; struct bpf_version bv; /* @@ -561,7 +566,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 +604,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); } |