summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/libpcap/Makefile36
-rw-r--r--lib/libpcap/bpf_filter.c550
-rw-r--r--lib/libpcap/bpf_image.c284
-rw-r--r--lib/libpcap/etherent.c148
-rw-r--r--lib/libpcap/ethertype.h74
-rw-r--r--lib/libpcap/gencode.c1764
-rw-r--r--lib/libpcap/gencode.h173
-rw-r--r--lib/libpcap/grammar.y266
-rw-r--r--lib/libpcap/inet.c196
-rw-r--r--lib/libpcap/nametoaddr.c358
-rw-r--r--lib/libpcap/optimize.c1924
-rw-r--r--lib/libpcap/pcap-bpf.c235
-rw-r--r--lib/libpcap/pcap-dlpi.c506
-rw-r--r--lib/libpcap/pcap-enet.c227
-rw-r--r--lib/libpcap/pcap-int.h98
-rw-r--r--lib/libpcap/pcap-namedb.h76
-rw-r--r--lib/libpcap/pcap-nit.c240
-rw-r--r--lib/libpcap/pcap-nit.h19
-rw-r--r--lib/libpcap/pcap-pf.c310
-rw-r--r--lib/libpcap/pcap-pf.h19
-rw-r--r--lib/libpcap/pcap-snit.c293
-rw-r--r--lib/libpcap/pcap-snoop.c195
-rw-r--r--lib/libpcap/pcap.3325
-rw-r--r--lib/libpcap/pcap.c173
-rw-r--r--lib/libpcap/pcap.h137
-rw-r--r--lib/libpcap/savefile.c285
-rw-r--r--lib/libpcap/scanner.l193
27 files changed, 23 insertions, 9081 deletions
diff --git a/lib/libpcap/Makefile b/lib/libpcap/Makefile
index a3009c7..85509b1 100644
--- a/lib/libpcap/Makefile
+++ b/lib/libpcap/Makefile
@@ -2,30 +2,40 @@
# $Id: Makefile,v 1.7 1996/06/02 17:09:03 phk Exp $
LIB= pcap
-
-SRCS= \
- pcap-bpf.c \
- pcap.c inet.c gencode.c optimize.c nametoaddr.c etherent.c savefile.c \
- bpf_filter.c bpf_image.c \
+SRCS= pcap-bpf.c \
+ pcap.c inet.c gencode.c optimize.c nametoaddr.c \
+ etherent.c savefile.c bpf_filter.c bpf_image.c \
grammar.y scanner.l
+MAN3= pcap.3
CLEANFILES+= lex.yy.c tokdefs.h grammar.c scanner.c
-# CFLAGS+=-Wall -I. -I${.CURDIR} -DFDDI -Dyylval=pcap_lval
-CFLAGS+=-DFDDI -I. -I${.CURDIR} -DETHER_SERVICE
-MAN3= pcap.3
+
+DEFS= -DHAVE_SYS_IOCCOM_H=1 -DHAVE_SYS_SOCKIO_H=1 \
+ -DHAVE_ETHER_HOSTTON=1 -DHAVE_STRERROR=1 \
+ -DHAVE_SOCKADDR_SA_LEN=1 -DLBL_ALIGN=1
+
+CFLAGS+=-Wall -I. -I${.CURDIR} -Dyylval=pcap_lval -Dlint ${DEFS}
+
+#
+# Magic to grab sources out of src/contrib
+#
+DISTDIR?=${.CURDIR}/../../contrib/libpcap
+.PATH: ${DISTDIR}
+.PATH: ${DISTDIR}/bpf/net
+CFLAGS+=-I${DISTDIR} -I${DISTDIR}/lbl
beforeinstall:
- -cmp -s ${.CURDIR}/pcap.h ${DESTDIR}/usr/include/pcap.h || \
+ -cmp -s ${DISTDIR}/pcap.h ${DESTDIR}/usr/include/pcap.h || \
( $(INSTALL) -c -o ${BINOWN} -g ${BINGRP} -m 444 \
- ${.CURDIR}/pcap.h ${DESTDIR}/usr/include; )
- -cmp -s ${.CURDIR}/pcap-namedb.h ${DESTDIR}/usr/include/pcap-namedb.h || \
+ ${DISTDIR}/pcap.h ${DESTDIR}/usr/include; )
+ -cmp -s ${DISTDIR}/pcap-namedb.h ${DESTDIR}/usr/include/pcap-namedb.h || \
( $(INSTALL) -c -o ${BINOWN} -g ${BINGRP} -m 444 \
- ${.CURDIR}/pcap-namedb.h ${DESTDIR}/usr/include; )
+ ${DISTDIR}/pcap-namedb.h ${DESTDIR}/usr/include; )
+
scanner.o: tokdefs.h
tokdefs.h: grammar.c
mv -f y.tab.h tokdefs.h
-
.include <bsd.lib.mk>
diff --git a/lib/libpcap/bpf_filter.c b/lib/libpcap/bpf_filter.c
deleted file mode 100644
index e755b59..0000000
--- a/lib/libpcap/bpf_filter.c
+++ /dev/null
@@ -1,550 +0,0 @@
-/*-
- * Copyright (c) 1990, 1991, 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from the Stanford/CMU enet packet filter,
- * (net/enet.c) distributed as part of 4.3BSD, and code contributed
- * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
- * Berkeley Laboratory.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)bpf.c 7.5 (Berkeley) 7/15/91
- *
- * static char rcsid[] =
- * "$Header: /home/ncvs/src/lib/libpcap/bpf_filter.c,v 1.1.1.1 1995/01/20 04:13:02 jkh Exp $";
- */
-#if !(defined(lint) || defined(KERNEL))
-static char rcsid[] =
- "@(#) $Header: /home/ncvs/src/lib/libpcap/bpf_filter.c,v 1.1.1.1 1995/01/20 04:13:02 jkh Exp $ (LBL)";
-#endif
-
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <net/bpf.h>
-
-#if defined(__alpha)
-typedef int int32;
-typedef u_int u_int32;
-#else
-typedef long int32;
-typedef u_long u_int32;
-#endif
-
-#ifdef sun
-#include <netinet/in.h>
-#endif
-
-#if defined(sparc) || defined(mips) || defined(ibm032) || defined(__alpha)
-#define BPF_ALIGN
-#endif
-
-#ifndef BPF_ALIGN
-#define EXTRACT_SHORT(p) ((u_short)ntohs(*(u_short *)p))
-#define EXTRACT_LONG(p) (ntohl(*(u_int32 *)p))
-#else
-#define EXTRACT_SHORT(p)\
- ((u_short)\
- ((u_short)*((u_char *)p+0)<<8|\
- (u_short)*((u_char *)p+1)<<0))
-#define EXTRACT_LONG(p)\
- ((u_int32)*((u_char *)p+0)<<24|\
- (u_int32)*((u_char *)p+1)<<16|\
- (u_int32)*((u_char *)p+2)<<8|\
- (u_int32)*((u_char *)p+3)<<0)
-#endif
-
-#ifdef KERNEL
-#include <sys/mbuf.h>
-#define MINDEX(m, k) \
-{ \
- register int len = m->m_len; \
- \
- while (k >= len) { \
- k -= len; \
- m = m->m_next; \
- if (m == 0) \
- return 0; \
- len = m->m_len; \
- } \
-}
-
-static int
-m_xword(m, k, err)
- register struct mbuf *m;
- register int k, *err;
-{
- register int len;
- register u_char *cp, *np;
- register struct mbuf *m0;
-
- len = m->m_len;
- while (k >= len) {
- k -= len;
- m = m->m_next;
- if (m == 0)
- goto bad;
- len = m->m_len;
- }
- cp = mtod(m, u_char *) + k;
- if (len - k >= 4) {
- *err = 0;
- return EXTRACT_LONG(cp);
- }
- m0 = m->m_next;
- if (m0 == 0 || m0->m_len + len - k < 4)
- goto bad;
- *err = 0;
- np = mtod(m0, u_char *);
- switch (len - k) {
-
- case 1:
- return (cp[k] << 24) | (np[0] << 16) | (np[1] << 8) | np[2];
-
- case 2:
- return (cp[k] << 24) | (cp[k + 1] << 16) | (np[0] << 8) |
- np[1];
-
- default:
- return (cp[k] << 24) | (cp[k + 1] << 16) | (cp[k + 2] << 8) |
- np[0];
- }
- bad:
- *err = 1;
- return 0;
-}
-
-static int
-m_xhalf(m, k, err)
- register struct mbuf *m;
- register int k, *err;
-{
- register int len;
- register u_char *cp;
- register struct mbuf *m0;
-
- len = m->m_len;
- while (k >= len) {
- k -= len;
- m = m->m_next;
- if (m == 0)
- goto bad;
- len = m->m_len;
- }
- cp = mtod(m, u_char *) + k;
- if (len - k >= 2) {
- *err = 0;
- return EXTRACT_SHORT(cp);
- }
- m0 = m->m_next;
- if (m0 == 0)
- goto bad;
- *err = 0;
- return (cp[k] << 8) | mtod(m0, u_char *)[0];
- bad:
- *err = 1;
- return 0;
-}
-#endif
-
-/*
- * Execute the filter program starting at pc on the packet p
- * wirelen is the length of the original packet
- * buflen is the amount of data present
- */
-u_int
-bpf_filter(pc, p, wirelen, buflen)
- register struct bpf_insn *pc;
- register u_char *p;
- u_int wirelen;
- register u_int buflen;
-{
- register u_int32 A, X;
- register int k;
- int32 mem[BPF_MEMWORDS];
-
- if (pc == 0)
- /*
- * No filter means accept all.
- */
- return (u_int)-1;
-#ifdef lint
- A = 0;
- X = 0;
-#endif
- --pc;
- while (1) {
- ++pc;
- switch (pc->code) {
-
- default:
-#ifdef KERNEL
- return 0;
-#else
- abort();
-#endif
- case BPF_RET|BPF_K:
- return (u_int)pc->k;
-
- case BPF_RET|BPF_A:
- return (u_int)A;
-
- case BPF_LD|BPF_W|BPF_ABS:
- k = pc->k;
- if (k + sizeof(int32) > buflen) {
-#ifdef KERNEL
- int merr;
-
- if (buflen != 0)
- return 0;
- A = m_xword((struct mbuf *)p, k, &merr);
- if (merr != 0)
- return 0;
- continue;
-#else
- return 0;
-#endif
- }
- A = EXTRACT_LONG(&p[k]);
- continue;
-
- case BPF_LD|BPF_H|BPF_ABS:
- k = pc->k;
- if (k + sizeof(short) > buflen) {
-#ifdef KERNEL
- int merr;
-
- if (buflen != 0)
- return 0;
- A = m_xhalf((struct mbuf *)p, k, &merr);
- continue;
-#else
- return 0;
-#endif
- }
- A = EXTRACT_SHORT(&p[k]);
- continue;
-
- case BPF_LD|BPF_B|BPF_ABS:
- k = pc->k;
- if (k >= buflen) {
-#ifdef KERNEL
- register struct mbuf *m;
-
- if (buflen != 0)
- return 0;
- m = (struct mbuf *)p;
- MINDEX(m, k);
- A = mtod(m, u_char *)[k];
- continue;
-#else
- return 0;
-#endif
- }
- A = p[k];
- continue;
-
- case BPF_LD|BPF_W|BPF_LEN:
- A = wirelen;
- continue;
-
- case BPF_LDX|BPF_W|BPF_LEN:
- X = wirelen;
- continue;
-
- case BPF_LD|BPF_W|BPF_IND:
- k = X + pc->k;
- if (k + sizeof(int32) > buflen) {
-#ifdef KERNEL
- int merr;
-
- if (buflen != 0)
- return 0;
- A = m_xword((struct mbuf *)p, k, &merr);
- if (merr != 0)
- return 0;
- continue;
-#else
- return 0;
-#endif
- }
- A = EXTRACT_LONG(&p[k]);
- continue;
-
- case BPF_LD|BPF_H|BPF_IND:
- k = X + pc->k;
- if (k + sizeof(short) > buflen) {
-#ifdef KERNEL
- int merr;
-
- if (buflen != 0)
- return 0;
- A = m_xhalf((struct mbuf *)p, k, &merr);
- if (merr != 0)
- return 0;
- continue;
-#else
- return 0;
-#endif
- }
- A = EXTRACT_SHORT(&p[k]);
- continue;
-
- case BPF_LD|BPF_B|BPF_IND:
- k = X + pc->k;
- if (k >= buflen) {
-#ifdef KERNEL
- register struct mbuf *m;
-
- if (buflen != 0)
- return 0;
- m = (struct mbuf *)p;
- MINDEX(m, k);
- A = mtod(m, char *)[k];
- continue;
-#else
- return 0;
-#endif
- }
- A = p[k];
- continue;
-
- case BPF_LDX|BPF_MSH|BPF_B:
- k = pc->k;
- if (k >= buflen) {
-#ifdef KERNEL
- register struct mbuf *m;
-
- if (buflen != 0)
- return 0;
- m = (struct mbuf *)p;
- MINDEX(m, k);
- X = (mtod(m, char *)[k] & 0xf) << 2;
- continue;
-#else
- return 0;
-#endif
- }
- X = (p[pc->k] & 0xf) << 2;
- continue;
-
- case BPF_LD|BPF_IMM:
- A = pc->k;
- continue;
-
- case BPF_LDX|BPF_IMM:
- X = pc->k;
- continue;
-
- case BPF_LD|BPF_MEM:
- A = mem[pc->k];
- continue;
-
- case BPF_LDX|BPF_MEM:
- X = mem[pc->k];
- continue;
-
- case BPF_ST:
- mem[pc->k] = A;
- continue;
-
- case BPF_STX:
- mem[pc->k] = X;
- continue;
-
- case BPF_JMP|BPF_JA:
- pc += pc->k;
- continue;
-
- case BPF_JMP|BPF_JGT|BPF_K:
- pc += (A > pc->k) ? pc->jt : pc->jf;
- continue;
-
- case BPF_JMP|BPF_JGE|BPF_K:
- pc += (A >= pc->k) ? pc->jt : pc->jf;
- continue;
-
- case BPF_JMP|BPF_JEQ|BPF_K:
- pc += (A == pc->k) ? pc->jt : pc->jf;
- continue;
-
- case BPF_JMP|BPF_JSET|BPF_K:
- pc += (A & pc->k) ? pc->jt : pc->jf;
- continue;
-
- case BPF_JMP|BPF_JGT|BPF_X:
- pc += (A > X) ? pc->jt : pc->jf;
- continue;
-
- case BPF_JMP|BPF_JGE|BPF_X:
- pc += (A >= X) ? pc->jt : pc->jf;
- continue;
-
- case BPF_JMP|BPF_JEQ|BPF_X:
- pc += (A == X) ? pc->jt : pc->jf;
- continue;
-
- case BPF_JMP|BPF_JSET|BPF_X:
- pc += (A & X) ? pc->jt : pc->jf;
- continue;
-
- case BPF_ALU|BPF_ADD|BPF_X:
- A += X;
- continue;
-
- case BPF_ALU|BPF_SUB|BPF_X:
- A -= X;
- continue;
-
- case BPF_ALU|BPF_MUL|BPF_X:
- A *= X;
- continue;
-
- case BPF_ALU|BPF_DIV|BPF_X:
- if (X == 0)
- return 0;
- A /= X;
- continue;
-
- case BPF_ALU|BPF_AND|BPF_X:
- A &= X;
- continue;
-
- case BPF_ALU|BPF_OR|BPF_X:
- A |= X;
- continue;
-
- case BPF_ALU|BPF_LSH|BPF_X:
- A <<= X;
- continue;
-
- case BPF_ALU|BPF_RSH|BPF_X:
- A >>= X;
- continue;
-
- case BPF_ALU|BPF_ADD|BPF_K:
- A += pc->k;
- continue;
-
- case BPF_ALU|BPF_SUB|BPF_K:
- A -= pc->k;
- continue;
-
- case BPF_ALU|BPF_MUL|BPF_K:
- A *= pc->k;
- continue;
-
- case BPF_ALU|BPF_DIV|BPF_K:
- A /= pc->k;
- continue;
-
- case BPF_ALU|BPF_AND|BPF_K:
- A &= pc->k;
- continue;
-
- case BPF_ALU|BPF_OR|BPF_K:
- A |= pc->k;
- continue;
-
- case BPF_ALU|BPF_LSH|BPF_K:
- A <<= pc->k;
- continue;
-
- case BPF_ALU|BPF_RSH|BPF_K:
- A >>= pc->k;
- continue;
-
- case BPF_ALU|BPF_NEG:
- A = -A;
- continue;
-
- case BPF_MISC|BPF_TAX:
- X = A;
- continue;
-
- case BPF_MISC|BPF_TXA:
- A = X;
- continue;
- }
- }
-}
-
-#ifdef KERNEL
-/*
- * Return true if the 'fcode' is a valid filter program.
- * The constraints are that each jump be forward and to a valid
- * code. The code must terminate with either an accept or reject.
- * 'valid' is an array for use by the routine (it must be at least
- * 'len' bytes long).
- *
- * The kernel needs to be able to verify an application's filter code.
- * Otherwise, a bogus program could easily crash the system.
- */
-int
-bpf_validate(f, len)
- struct bpf_insn *f;
- int len;
-{
- register int i;
- register struct bpf_insn *p;
-
- for (i = 0; i < len; ++i) {
- /*
- * Check that that jumps are forward, and within
- * the code block.
- */
- p = &f[i];
- if (BPF_CLASS(p->code) == BPF_JMP) {
- register int from = i + 1;
-
- if (BPF_OP(p->code) == BPF_JA) {
- if (from + p->k >= len)
- return 0;
- }
- else if (from + p->jt >= len || from + p->jf >= len)
- return 0;
- }
- /*
- * Check that memory operations use valid addresses.
- */
- if ((BPF_CLASS(p->code) == BPF_ST ||
- (BPF_CLASS(p->code) == BPF_LD &&
- (p->code & 0xe0) == BPF_MEM)) &&
- (p->k >= BPF_MEMWORDS || p->k < 0))
- return 0;
- /*
- * Check for constant division by 0.
- */
- if (p->code == (BPF_ALU|BPF_DIV|BPF_K) && p->k == 0)
- return 0;
- }
- return BPF_CLASS(f[len - 1].code) == BPF_RET;
-}
-#endif
diff --git a/lib/libpcap/bpf_image.c b/lib/libpcap/bpf_image.c
deleted file mode 100644
index e86fa85..0000000
--- a/lib/libpcap/bpf_image.c
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- * Copyright (c) 1990, 1991, 1992, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that: (1) source code distributions
- * retain the above copyright notice and this paragraph in its entirety, (2)
- * distributions including binary code include the above copyright notice and
- * this paragraph in its entirety in the documentation or other materials
- * provided with the distribution, and (3) all advertising materials mentioning
- * features or use of this software display the following acknowledgement:
- * ``This product includes software developed by the University of California,
- * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
- * the University nor the names of its contributors may be used to endorse
- * or promote products derived from this software without specific prior
- * written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef lint
-static char rcsid[] =
- "@(#) $Header: bpf_image.c,v 1.12 94/01/31 03:22:34 leres Exp $ (LBL)";
-#endif
-
-#include <sys/types.h>
-#include <sys/time.h>
-
-#include <net/bpf.h>
-
-#include <pcap.h>
-#include <stdio.h>
-#include <string.h>
-
-char *
-bpf_image(p, n)
- struct bpf_insn *p;
- int n;
-{
- int v;
- char *fmt, *op;
- static char image[256];
- char operand[64];
-
- v = p->k;
- switch (p->code) {
-
- default:
- op = "unimp";
- fmt = "0x%x";
- v = p->code;
- break;
-
- case BPF_RET|BPF_K:
- op = "ret";
- fmt = "#%d";
- break;
-
- case BPF_RET|BPF_A:
- op = "ret";
- fmt = "";
- break;
-
- case BPF_LD|BPF_W|BPF_ABS:
- op = "ld";
- fmt = "[%d]";
- break;
-
- case BPF_LD|BPF_H|BPF_ABS:
- op = "ldh";
- fmt = "[%d]";
- break;
-
- case BPF_LD|BPF_B|BPF_ABS:
- op = "ldb";
- fmt = "[%d]";
- break;
-
- case BPF_LD|BPF_W|BPF_LEN:
- op = "ld";
- fmt = "#pktlen";
- break;
-
- case BPF_LD|BPF_W|BPF_IND:
- op = "ld";
- fmt = "[x + %d]";
- break;
-
- case BPF_LD|BPF_H|BPF_IND:
- op = "ldh";
- fmt = "[x + %d]";
- break;
-
- case BPF_LD|BPF_B|BPF_IND:
- op = "ldb";
- fmt = "[x + %d]";
- break;
-
- case BPF_LD|BPF_IMM:
- op = "ld";
- fmt = "#0x%x";
- break;
-
- case BPF_LDX|BPF_IMM:
- op = "ldx";
- fmt = "#0x%x";
- break;
-
- case BPF_LDX|BPF_MSH|BPF_B:
- op = "ldxb";
- fmt = "4*([%d]&0xf)";
- break;
-
- case BPF_LD|BPF_MEM:
- op = "ld";
- fmt = "M[%d]";
- break;
-
- case BPF_LDX|BPF_MEM:
- op = "ldx";
- fmt = "M[%d]";
- break;
-
- case BPF_ST:
- op = "st";
- fmt = "M[%d]";
- break;
-
- case BPF_STX:
- op = "stx";
- fmt = "M[%d]";
- break;
-
- case BPF_JMP|BPF_JA:
- op = "ja";
- fmt = "%d";
- v = n + p->k;
- break;
-
- case BPF_JMP|BPF_JGT|BPF_K:
- op = "jgt";
- fmt = "#0x%x";
- break;
-
- case BPF_JMP|BPF_JGE|BPF_K:
- op = "jge";
- fmt = "#0x%x";
- break;
-
- case BPF_JMP|BPF_JEQ|BPF_K:
- op = "jeq";
- fmt = "#0x%x";
- break;
-
- case BPF_JMP|BPF_JSET|BPF_K:
- op = "jset";
- fmt = "#0x%x";
- break;
-
- case BPF_JMP|BPF_JGT|BPF_X:
- op = "jgt";
- fmt = "x";
- break;
-
- case BPF_JMP|BPF_JGE|BPF_X:
- op = "jge";
- fmt = "x";
- break;
-
- case BPF_JMP|BPF_JEQ|BPF_X:
- op = "jeq";
- fmt = "x";
- break;
-
- case BPF_JMP|BPF_JSET|BPF_X:
- op = "jset";
- fmt = "x";
- break;
-
- case BPF_ALU|BPF_ADD|BPF_X:
- op = "add";
- fmt = "x";
- break;
-
- case BPF_ALU|BPF_SUB|BPF_X:
- op = "sub";
- fmt = "x";
- break;
-
- case BPF_ALU|BPF_MUL|BPF_X:
- op = "mul";
- fmt = "x";
- break;
-
- case BPF_ALU|BPF_DIV|BPF_X:
- op = "div";
- fmt = "x";
- break;
-
- case BPF_ALU|BPF_AND|BPF_X:
- op = "and";
- fmt = "x";
- break;
-
- case BPF_ALU|BPF_OR|BPF_X:
- op = "or";
- fmt = "x";
- break;
-
- case BPF_ALU|BPF_LSH|BPF_X:
- op = "lsh";
- fmt = "x";
- break;
-
- case BPF_ALU|BPF_RSH|BPF_X:
- op = "rsh";
- fmt = "x";
- break;
-
- case BPF_ALU|BPF_ADD|BPF_K:
- op = "add";
- fmt = "#%d";
- break;
-
- case BPF_ALU|BPF_SUB|BPF_K:
- op = "sub";
- fmt = "#%d";
- break;
-
- case BPF_ALU|BPF_MUL|BPF_K:
- op = "mul";
- fmt = "#%d";
- break;
-
- case BPF_ALU|BPF_DIV|BPF_K:
- op = "div";
- fmt = "#%d";
- break;
-
- case BPF_ALU|BPF_AND|BPF_K:
- op = "and";
- fmt = "#%d";
- break;
-
- case BPF_ALU|BPF_OR|BPF_K:
- op = "or";
- fmt = "#%d";
- break;
-
- case BPF_ALU|BPF_LSH|BPF_K:
- op = "lsh";
- fmt = "#%d";
- break;
-
- case BPF_ALU|BPF_RSH|BPF_K:
- op = "rsh";
- fmt = "#%d";
- break;
-
- case BPF_ALU|BPF_NEG:
- op = "neg";
- fmt = "";
- break;
-
- case BPF_MISC|BPF_TAX:
- op = "tax";
- fmt = "";
- break;
-
- case BPF_MISC|BPF_TXA:
- op = "txa";
- fmt = "";
- break;
- }
- (void)sprintf(operand, fmt, v);
- (void)sprintf(image,
- (BPF_CLASS(p->code) == BPF_JMP &&
- BPF_OP(p->code) != BPF_JA) ?
- "(%03d) %-8s %-16s jt %d\tjf %d"
- : "(%03d) %-8s %s",
- n, op, operand, n + 1 + p->jt, n + 1 + p->jf);
- return image;
-}
diff --git a/lib/libpcap/etherent.c b/lib/libpcap/etherent.c
deleted file mode 100644
index 7045f3d..0000000
--- a/lib/libpcap/etherent.c
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright (c) 1990, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that: (1) source code distributions
- * retain the above copyright notice and this paragraph in its entirety, (2)
- * distributions including binary code include the above copyright notice and
- * this paragraph in its entirety in the documentation or other materials
- * provided with the distribution, and (3) all advertising materials mentioning
- * features or use of this software display the following acknowledgement:
- * ``This product includes software developed by the University of California,
- * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
- * the University nor the names of its contributors may be used to endorse
- * or promote products derived from this software without specific prior
- * written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-#ifndef lint
-static char rcsid[] =
- "@(#) $Header: etherent.c,v 1.8 94/06/20 19:07:50 leres Exp $ (LBL)";
-#endif
-
-#include <sys/types.h>
-
-#include <ctype.h>
-#include <pcap.h>
-#include <pcap-namedb.h>
-#include <stdio.h>
-
-#ifndef __GNUC__
-#define inline
-#endif
-
-static inline int xdtoi(int);
-static inline int skip_space(FILE *);
-static inline int skip_line(FILE *);
-
-/* Hex digit to integer. */
-static inline int
-xdtoi(c)
- register int c;
-{
- if (isdigit(c))
- return c - '0';
- else if (islower(c))
- return c - 'a' + 10;
- else
- return c - 'A' + 10;
-}
-
-static inline int
-skip_space(f)
- FILE *f;
-{
- int c;
-
- do {
- c = getc(f);
- } while (isspace(c) && c != '\n');
-
- return c;
-}
-
-static inline int
-skip_line(f)
- FILE *f;
-{
- int c;
-
- do
- c = getc(f);
- while (c != '\n' && c != EOF);
-
- return c;
-}
-
-struct pcap_etherent *
-pcap_next_etherent(FILE *fp)
-{
- register int c, d, i;
- char *bp;
- static struct pcap_etherent e;
- static int nline = 1;
- top:
- while (nline) {
- /* Find addr */
- c = skip_space(fp);
- if (c == '\n')
- continue;
- /* If this is a comment, or first thing on line
- cannot be ethernet address, skip the line. */
- else if (!isxdigit(c))
- c = skip_line(fp);
- else {
- /* must be the start of an address */
- for (i = 0; i < 6; i += 1) {
- d = xdtoi(c);
- c = getc(fp);
- if (c != ':') {
- d <<= 4;
- d |= xdtoi(c);
- c = getc(fp);
- }
- e.addr[i] = d;
- if (c != ':')
- break;
- c = getc(fp);
- }
- nline = 0;
- }
- if (c == EOF)
- return 0;
- }
-
- /* If we started a new line, 'c' holds the char past the ether addr,
- which we assume is white space. If we are continuing a line,
- 'c' is garbage. In either case, we can throw it away. */
-
- c = skip_space(fp);
- if (c == '\n') {
- nline = 1;
- goto top;
- }
- else if (c == '#') {
- (void)skip_line(fp);
- nline = 1;
- goto top;
- }
- else if (c == EOF)
- return 0;
-
- /* Must be a name. */
- bp = e.name;
- /* Use 'd' to prevent buffer overflow. */
- d = sizeof(e.name) - 1;
- do {
- *bp++ = c;
- c = getc(fp);
- } while (!isspace(c) && c != EOF && --d > 0);
- *bp = '\0';
- if (c == '\n')
- nline = 1;
-
- return &e;
-}
diff --git a/lib/libpcap/ethertype.h b/lib/libpcap/ethertype.h
deleted file mode 100644
index 37f6920..0000000
--- a/lib/libpcap/ethertype.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (c) 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that: (1) source code distributions
- * retain the above copyright notice and this paragraph in its entirety, (2)
- * distributions including binary code include the above copyright notice and
- * this paragraph in its entirety in the documentation or other materials
- * provided with the distribution, and (3) all advertising materials mentioning
- * features or use of this software display the following acknowledgement:
- * ``This product includes software developed by the University of California,
- * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
- * the University nor the names of its contributors may be used to endorse
- * or promote products derived from this software without specific prior
- * written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * @(#) $Header: ethertype.h,v 1.2 94/06/14 20:03:27 leres Exp $ (LBL)
- */
-
-/* Map between Ethernet protocol types and names */
-
-/* Add other Ethernet packet types here */
-#ifndef ETHERTYPE_SPRITE
-#define ETHERTYPE_SPRITE 0x0500
-#endif
-#ifndef ETHERTYPE_MOPDL
-#define ETHERTYPE_MOPDL 0x6001
-#endif
-#ifndef ETHERTYPE_MOPRC
-#define ETHERTYPE_MOPRC 0x6002
-#endif
-#ifndef ETHERTYPE_DN
-#define ETHERTYPE_DN 0x6003
-#endif
-#ifndef ETHERTYPE_LAT
-#define ETHERTYPE_LAT 0x6004
-#endif
-#ifndef ETHERTYPE_LANBRIDGE
-#define ETHERTYPE_LANBRIDGE 0x8038
-#endif
-#ifndef ETHERTYPE_DECDNS
-#define ETHERTYPE_DECDNS 0x803c
-#endif
-#ifndef ETHERTYPE_DECDTS
-#define ETHERTYPE_DECDTS 0x803e
-#endif
-#ifndef ETHERTYPE_VEXP
-#define ETHERTYPE_VEXP 0x805b
-#endif
-#ifndef ETHERTYPE_VPROD
-#define ETHERTYPE_VPROD 0x805c
-#endif
-#ifndef ETHERTYPE_LOOPBACK
-#define ETHERTYPE_LOOPBACK 0x9000
-#endif
-
-#ifndef ETHERTYPE_ATALK
-#define ETHERTYPE_ATALK 0x809b /* XXX */
-#endif
-#ifndef ETHERTYPE_AARP
-#define ETHERTYPE_AARP 0x80f3
-#endif
-#ifndef ETHERTYPE_NS
-#define ETHERTYPE_NS 0x0600
-#endif
-
-#ifndef ETHERTYPE_REVARP
-#define ETHERTYPE_REVARP 0x8035
-#endif
-
diff --git a/lib/libpcap/gencode.c b/lib/libpcap/gencode.c
deleted file mode 100644
index 3f237c1..0000000
--- a/lib/libpcap/gencode.c
+++ /dev/null
@@ -1,1764 +0,0 @@
-/*
- * Copyright (c) 1990, 1991, 1992, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that: (1) source code distributions
- * retain the above copyright notice and this paragraph in its entirety, (2)
- * distributions including binary code include the above copyright notice and
- * this paragraph in its entirety in the documentation or other materials
- * provided with the distribution, and (3) all advertising materials mentioning
- * features or use of this software display the following acknowledgement:
- * ``This product includes software developed by the University of California,
- * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
- * the University nor the names of its contributors may be used to endorse
- * or promote products derived from this software without specific prior
- * written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-#ifndef lint
-static char rcsid[] =
- "@(#) $Header: /home/ncvs/src/lib/libpcap/gencode.c,v 1.1.1.1 1995/01/20 04:13:04 jkh Exp $ (LBL)";
-#endif
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-
-#include <net/if.h>
-#include <net/bpf.h>
-
-#include <netinet/in.h>
-#include <netinet/if_ether.h>
-
-#include <memory.h>
-#include <pcap.h>
-#include <pcap-namedb.h>
-#include <setjmp.h>
-#if __STDC__
-#include <stdarg.h>
-#include <stdlib.h>
-#else
-#include <varargs.h>
-#endif
-
-#include "gencode.h"
-
-#ifndef __GNUC__
-#define inline
-#endif
-
-#ifndef ETHERTYPE_REVARP
-#define ETHERTYPE_REVARP 0x8035
-#endif
-#ifndef ETHERTYPE_MOPDL
-#define ETHERTYPE_MOPDL 0x6001
-#endif
-#ifndef ETHERTYPE_MOPRC
-#define ETHERTYPE_MOPRC 0x6002
-#endif
-#ifndef ETHERTYPE_DN
-#define ETHERTYPE_DN 0x6003
-#endif
-#ifndef ETHERTYPE_LAT
-#define ETHERTYPE_LAT 0x6004
-#endif
-
-#define JMP(c) ((c)|BPF_JMP|BPF_K)
-
-static jmp_buf top_ctx;
-static pcap_t *bpf_pcap;
-
-/* VARARGS */
-volatile void
-#if __STDC__ || defined(SOLARIS)
-bpf_error(char *fmt, ...)
-#else
-bpf_error(fmt, va_alist)
- char *fmt;
- va_dcl
-#endif
-{
- va_list ap;
-
-#if __STDC__
- va_start(ap, fmt);
-#else
- va_start(ap);
-#endif
- if (bpf_pcap != NULL)
- (void)vsprintf(pcap_geterr(bpf_pcap), fmt, ap);
- va_end(ap);
- longjmp(top_ctx, 1);
- /* NOTREACHED */
-}
-
-static void init_linktype(int);
-
-static int alloc_reg(void);
-static void free_reg(int);
-
-static struct block *root;
-
-/*
- * We divy out chunks of memory rather than call malloc each time so
- * we don't have to worry about leaking memory. It's probably
- * not a big deal if all this memory was wasted but it this ever
- * goes into a library that would probably not be a good idea.
- */
-#define NCHUNKS 16
-#define CHUNK0SIZE 1024
-struct chunk {
- u_int n_left;
- void *m;
-};
-
-static struct chunk chunks[NCHUNKS];
-static int cur_chunk;
-
-static void *newchunk(u_int);
-static void freechunks(void);
-static inline struct block *new_block(int);
-static inline struct slist *new_stmt(int);
-static struct block *gen_retblk(int);
-static inline void syntax(void);
-
-static void backpatch(struct block *, struct block *);
-static void merge(struct block *, struct block *);
-static struct block *gen_cmp(u_int, u_int, long);
-static struct block *gen_mcmp(u_int, u_int, long, u_long);
-static struct block *gen_bcmp(u_int, u_int, u_char *);
-static struct block *gen_uncond(int);
-static inline struct block *gen_true(void);
-static inline struct block *gen_false(void);
-static struct block *gen_linktype(int);
-static struct block *gen_hostop(u_long, u_long, int, int, u_int, u_int);
-static struct block *gen_ehostop(u_char *, int);
-#ifdef FDDI
-static struct block *gen_fhostop(u_char *, int);
-#endif
-static struct block *gen_dnhostop(u_long, int, u_int);
-static struct block *gen_host(u_long, u_long, int, int);
-static struct block *gen_gateway(u_char *, u_long **, int, int);
-static struct block *gen_ipfrag(void);
-static struct block *gen_portatom(int, long);
-struct block *gen_portop(int, int, int);
-static struct block *gen_port(int, int, int);
-static int lookup_proto(char *, int);
-static struct block *gen_proto(int, int, int);
-static u_long net_mask(u_long *);
-static u_long net_mask(u_long *);
-static struct slist *xfer_to_x(struct arth *);
-static struct slist *xfer_to_a(struct arth *);
-static struct block *gen_len(int, int);
-
-static void *
-newchunk(n)
- u_int n;
-{
- struct chunk *cp;
- int k, size;
-
- /* XXX Round up to nearest long. */
- n = (n + sizeof(long) - 1) & ~(sizeof(long) - 1);
-
- cp = &chunks[cur_chunk];
- if (n > cp->n_left) {
- ++cp, k = ++cur_chunk;
- if (k >= NCHUNKS)
- bpf_error("out of memory");
- size = CHUNK0SIZE << k;
- cp->m = (void *)malloc(size);
- memset((char *)cp->m, 0, size);
- cp->n_left = size;
- if (n > size)
- bpf_error("out of memory");
- }
- cp->n_left -= n;
- return (void *)((char *)cp->m + cp->n_left);
-}
-
-static void
-freechunks()
-{
- int i;
-
- for (i = 0; i < NCHUNKS; ++i)
- if (chunks[i].m)
- free(chunks[i].m);
-}
-
-/*
- * A strdup whose allocations are freed after code generation is over.
- */
-char *
-sdup(s)
- char *s;
-{
- int n = strlen(s) + 1;
- char *cp = newchunk(n);
- strcpy(cp, s);
- return (cp);
-}
-
-static inline struct block *
-new_block(code)
- int code;
-{
- struct block *p;
-
- p = (struct block *)newchunk(sizeof(*p));
- p->s.code = code;
- p->head = p;
-
- return p;
-}
-
-static inline struct slist *
-new_stmt(code)
- int code;
-{
- struct slist *p;
-
- p = (struct slist *)newchunk(sizeof(*p));
- p->s.code = code;
-
- return p;
-}
-
-static struct block *
-gen_retblk(v)
- int v;
-{
- struct block *b = new_block(BPF_RET|BPF_K);
-
- b->s.k = v;
- return b;
-}
-
-static inline void
-syntax()
-{
- bpf_error("syntax error in filter expression");
-}
-
-static u_long netmask;
-static int snaplen;
-
-int
-pcap_compile(pcap_t *p, struct bpf_program *program,
- char *buf, int optimize, u_long mask)
-{
- extern int n_errors;
- int len;
-
- bpf_pcap = p;
- if (setjmp(top_ctx))
- return (-1);
-
- netmask = mask;
- snaplen = pcap_snapshot(p);
-
- lex_init(buf ? buf : "");
- init_linktype(pcap_datalink(p));
- pcap_parse();
-
- if (n_errors)
- syntax();
-
- if (root == NULL)
- root = gen_retblk(snaplen);
-
- if (optimize) {
- bpf_optimize(&root);
- if (root == NULL ||
- (root->s.code == (BPF_RET|BPF_K) && root->s.k == 0))
- bpf_error("expression rejects all packets");
- }
- program->bf_insns = icode_to_fcode(root, &len);
- program->bf_len = len;
-
- freechunks();
- return (0);
-}
-
-/*
- * Backpatch the blocks in 'list' to 'target'. The 'sense' field indicates
- * which of the jt and jf fields has been resolved and which is a pointer
- * back to another unresolved block (or nil). At least one of the fields
- * in each block is already resolved.
- */
-static void
-backpatch(list, target)
- struct block *list, *target;
-{
- struct block *next;
-
- while (list) {
- if (!list->sense) {
- next = JT(list);
- JT(list) = target;
- } else {
- next = JF(list);
- JF(list) = target;
- }
- list = next;
- }
-}
-
-/*
- * Merge the lists in b0 and b1, using the 'sense' field to indicate
- * which of jt and jf is the link.
- */
-static void
-merge(b0, b1)
- struct block *b0, *b1;
-{
- register struct block **p = &b0;
-
- /* Find end of list. */
- while (*p)
- p = !((*p)->sense) ? &JT(*p) : &JF(*p);
-
- /* Concatenate the lists. */
- *p = b1;
-}
-
-void
-finish_parse(p)
- struct block *p;
-{
- backpatch(p, gen_retblk(snaplen));
- p->sense = !p->sense;
- backpatch(p, gen_retblk(0));
- root = p->head;
-}
-
-void
-gen_and(b0, b1)
- struct block *b0, *b1;
-{
- backpatch(b0, b1->head);
- b0->sense = !b0->sense;
- b1->sense = !b1->sense;
- merge(b1, b0);
- b1->sense = !b1->sense;
- b1->head = b0->head;
-}
-
-void
-gen_or(b0, b1)
- struct block *b0, *b1;
-{
- b0->sense = !b0->sense;
- backpatch(b0, b1->head);
- b0->sense = !b0->sense;
- merge(b1, b0);
- b1->head = b0->head;
-}
-
-void
-gen_not(b)
- struct block *b;
-{
- b->sense = !b->sense;
-}
-
-static struct block *
-gen_cmp(offset, size, v)
- u_int offset, size;
- long v;
-{
- struct slist *s;
- struct block *b;
-
- s = new_stmt(BPF_LD|BPF_ABS|size);
- s->s.k = offset;
-
- b = new_block(JMP(BPF_JEQ));
- b->stmts = s;
- b->s.k = v;
-
- return b;
-}
-
-static struct block *
-gen_mcmp(offset, size, v, mask)
- u_int offset, size;
- long v;
- u_long mask;
-{
- struct block *b = gen_cmp(offset, size, v);
- struct slist *s;
-
- if (mask != 0xffffffff) {
- s = new_stmt(BPF_ALU|BPF_AND|BPF_K);
- s->s.k = mask;
- b->stmts->next = s;
- }
- return b;
-}
-
-static struct block *
-gen_bcmp(offset, size, v)
- u_int offset, size;
- u_char *v;
-{
- struct block *b, *tmp;
-
- b = NULL;
- while (size >= 4) {
- u_char *p = &v[size - 4];
- long w = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
- tmp = gen_cmp(offset + size - 4, BPF_W, w);
- if (b != NULL)
- gen_and(b, tmp);
- b = tmp;
- size -= 4;
- }
- while (size >= 2) {
- u_char *p = &v[size - 2];
- long w = (p[0] << 8) | p[1];
- tmp = gen_cmp(offset + size - 2, BPF_H, w);
- if (b != NULL)
- gen_and(b, tmp);
- b = tmp;
- size -= 2;
- }
- if (size > 0) {
- tmp = gen_cmp(offset, BPF_B, (long)v[0]);
- if (b != NULL)
- gen_and(b, tmp);
- b = tmp;
- }
- return b;
-}
-
-/*
- * Various code constructs need to know the layout of the data link
- * layer. These variables give the necessary offsets. off_linktype
- * is set to -1 for no encapsulation, in which case, IP is assumed.
- */
-static u_int off_linktype;
-static u_int off_nl;
-static int linktype;
-#ifdef FDDI
-extern int fddipad;
-#endif
-
-static void
-init_linktype(type)
- int type;
-{
- linktype = type;
-
- switch (type) {
-
- case DLT_EN10MB:
- off_linktype = 12;
- off_nl = 14;
- return;
-
- case DLT_SLIP:
- /*
- * SLIP doesn't have a link level type. The 16 byte
- * header is hacked into our SLIP driver.
- */
- off_linktype = -1;
- off_nl = 16;
- return;
-
- case DLT_NULL:
- off_linktype = 0;
- off_nl = 4;
- return;
-
- case DLT_PPP:
- off_linktype = 2;
- off_nl = 4;
- return;
-
-#ifdef FDDI
- case DLT_FDDI:
- /*
- * FDDI doesn't really have a link-level type field.
- * We assume that SSAP = SNAP is being used and pick
- * out the encapsulated Ethernet type.
- */
- off_linktype = 19 + fddipad;
- off_nl = 21 + fddipad;
- return;
-#endif
-
- case DLT_IEEE802:
- off_linktype = 20;
- off_nl = 22;
- return;
- }
- bpf_error("unknown data link type 0x%x", linktype);
- /* NOTREACHED */
-}
-
-static struct block *
-gen_uncond(rsense)
- int rsense;
-{
- struct block *b;
- struct slist *s;
-
- s = new_stmt(BPF_LD|BPF_IMM);
- s->s.k = !rsense;
- b = new_block(JMP(BPF_JEQ));
- b->stmts = s;
-
- return b;
-}
-
-static inline struct block *
-gen_true()
-{
- return gen_uncond(1);
-}
-
-static inline struct block *
-gen_false()
-{
- return gen_uncond(0);
-}
-
-static struct block *
-gen_linktype(proto)
- int proto;
-{
- switch (linktype) {
- case DLT_SLIP:
- if (proto == ETHERTYPE_IP)
- return gen_true();
- else
- return gen_false();
-
- case DLT_PPP:
- if (proto == ETHERTYPE_IP)
- proto = 0x0021; /* XXX - need ppp.h defs */
- break;
-
- case DLT_NULL:
- if (proto == ETHERTYPE_IP) {
- proto = htonl(AF_INET); /* loopback & tun put */
- /* sa_family into */
- /* prepended word */
- return gen_cmp(off_linktype, BPF_W, (long)proto);
- }
- break;
- }
- return gen_cmp(off_linktype, BPF_H, (long)proto);
-}
-
-static struct block *
-gen_hostop(addr, mask, dir, proto, src_off, dst_off)
- u_long addr;
- u_long mask;
- int dir, proto;
- u_int src_off, dst_off;
-{
- struct block *b0, *b1;
- u_int offset;
-
- switch (dir) {
-
- case Q_SRC:
- offset = src_off;
- break;
-
- case Q_DST:
- offset = dst_off;
- break;
-
- case Q_AND:
- b0 = gen_hostop(addr, mask, Q_SRC, proto, src_off, dst_off);
- b1 = gen_hostop(addr, mask, Q_DST, proto, src_off, dst_off);
- gen_and(b0, b1);
- return b1;
-
- case Q_OR:
- case Q_DEFAULT:
- b0 = gen_hostop(addr, mask, Q_SRC, proto, src_off, dst_off);
- b1 = gen_hostop(addr, mask, Q_DST, proto, src_off, dst_off);
- gen_or(b0, b1);
- return b1;
-
- default:
- abort();
- }
- b0 = gen_linktype(proto);
- b1 = gen_mcmp(offset, BPF_W, (long)addr, mask);
- gen_and(b0, b1);
- return b1;
-}
-
-static struct block *
-gen_ehostop(eaddr, dir)
- u_char *eaddr;
- int dir;
-{
- struct block *b0, *b1;
-
- switch (dir) {
- case Q_SRC:
- return gen_bcmp(6, 6, eaddr);
-
- case Q_DST:
- return gen_bcmp(0, 6, eaddr);
-
- case Q_AND:
- b0 = gen_ehostop(eaddr, Q_SRC);
- b1 = gen_ehostop(eaddr, Q_DST);
- gen_and(b0, b1);
- return b1;
-
- case Q_DEFAULT:
- case Q_OR:
- b0 = gen_ehostop(eaddr, Q_SRC);
- b1 = gen_ehostop(eaddr, Q_DST);
- gen_or(b0, b1);
- return b1;
- }
- abort();
- /* NOTREACHED */
-}
-
-#ifdef FDDI
-/*
- * Like gen_ehostop, but for DLT_FDDI
- */
-static struct block *
-gen_fhostop(eaddr, dir)
- u_char *eaddr;
- int dir;
-{
- struct block *b0, *b1;
-
- switch (dir) {
- case Q_SRC:
- return gen_bcmp(6 + 1 + fddipad, 6, eaddr);
-
- case Q_DST:
- return gen_bcmp(0 + 1 + fddipad, 6, eaddr);
-
- case Q_AND:
- b0 = gen_fhostop(eaddr, Q_SRC);
- b1 = gen_fhostop(eaddr, Q_DST);
- gen_and(b0, b1);
- return b1;
-
- case Q_DEFAULT:
- case Q_OR:
- b0 = gen_fhostop(eaddr, Q_SRC);
- b1 = gen_fhostop(eaddr, Q_DST);
- gen_or(b0, b1);
- return b1;
- }
- abort();
- /* NOTREACHED */
-}
-#endif
-
-/*
- * This is quite tricky because there may be pad bytes in front of the
- * DECNET header, and then there are two possible data packet formats that
- * carry both src and dst addresses, plus 5 packet types in a format that
- * carries only the src node, plus 2 types that use a different format and
- * also carry just the src node.
- *
- * Yuck.
- *
- * Instead of doing those all right, we just look for data packets with
- * 0 or 1 bytes of padding. If you want to look at other packets, that
- * will require a lot more hacking.
- *
- * To add support for filtering on DECNET "areas" (network numbers)
- * one would want to add a "mask" argument to this routine. That would
- * make the filter even more inefficient, although one could be clever
- * and not generate masking instructions if the mask is 0xFFFF.
- */
-static struct block *
-gen_dnhostop(addr, dir, base_off)
- u_long addr;
- int dir;
- u_int base_off;
-{
- struct block *b0, *b1, *b2, *tmp;
- u_int offset_lh; /* offset if long header is received */
- u_int offset_sh; /* offset if short header is received */
-
- switch (dir) {
-
- case Q_DST:
- offset_sh = 1; /* follows flags */
- offset_lh = 7; /* flgs,darea,dsubarea,HIORD */
- break;
-
- case Q_SRC:
- offset_sh = 3; /* follows flags, dstnode */
- offset_lh = 15; /* flgs,darea,dsubarea,did,sarea,ssub,HIORD */
- break;
-
- case Q_AND:
- /* Inefficient because we do our Calvinball dance twice */
- b0 = gen_dnhostop(addr, Q_SRC, base_off);
- b1 = gen_dnhostop(addr, Q_DST, base_off);
- gen_and(b0, b1);
- return b1;
-
- case Q_OR:
- case Q_DEFAULT:
- /* Inefficient because we do our Calvinball dance twice */
- b0 = gen_dnhostop(addr, Q_SRC, base_off);
- b1 = gen_dnhostop(addr, Q_DST, base_off);
- gen_or(b0, b1);
- return b1;
-
- default:
- abort();
- }
- b0 = gen_linktype(ETHERTYPE_DN);
- /* Check for pad = 1, long header case */
- tmp = gen_mcmp(base_off + 2, BPF_H,
- (long)ntohs(0x0681), (long)ntohs(0x07FF));
- b1 = gen_cmp(base_off + 2 + 1 + offset_lh, BPF_H, (long)ntohs(addr));
- gen_and(tmp, b1);
- /* Check for pad = 0, long header case */
- tmp = gen_mcmp(base_off + 2, BPF_B, (long)0x06, (long)0x7);
- b2 = gen_cmp(base_off + 2 + offset_lh, BPF_H, (long)ntohs(addr));
- gen_and(tmp, b2);
- gen_or(b2, b1);
- /* Check for pad = 1, short header case */
- tmp = gen_mcmp(base_off + 2, BPF_H,
- (long)ntohs(0x0281), (long)ntohs(0x07FF));
- b2 = gen_cmp(base_off + 2 + 1 + offset_sh, BPF_H, (long)ntohs(addr));
- gen_and(tmp, b2);
- gen_or(b2, b1);
- /* Check for pad = 0, short header case */
- tmp = gen_mcmp(base_off + 2, BPF_B, (long)0x02, (long)0x7);
- b2 = gen_cmp(base_off + 2 + offset_sh, BPF_H, (long)ntohs(addr));
- gen_and(tmp, b2);
- gen_or(b2, b1);
-
- /* Combine with test for linktype */
- gen_and(b0, b1);
- return b1;
-}
-
-static struct block *
-gen_host(addr, mask, proto, dir)
- u_long addr;
- u_long mask;
- int proto;
- int dir;
-{
- struct block *b0, *b1;
-
- switch (proto) {
-
- case Q_DEFAULT:
- b0 = gen_host(addr, mask, Q_IP, dir);
- b1 = gen_host(addr, mask, Q_ARP, dir);
- gen_or(b0, b1);
- b0 = gen_host(addr, mask, Q_RARP, dir);
- gen_or(b1, b0);
- return b0;
-
- case Q_IP:
- return gen_hostop(addr, mask, dir, ETHERTYPE_IP,
- off_nl + 12, off_nl + 16);
-
- case Q_RARP:
- return gen_hostop(addr, mask, dir, ETHERTYPE_REVARP,
- off_nl + 14, off_nl + 24);
-
- case Q_ARP:
- return gen_hostop(addr, mask, dir, ETHERTYPE_ARP,
- off_nl + 14, off_nl + 24);
-
- case Q_TCP:
- bpf_error("'tcp' modifier applied to host");
-
- case Q_UDP:
- bpf_error("'udp' modifier applied to host");
-
- case Q_ICMP:
- bpf_error("'icmp' modifier applied to host");
-
- case Q_DECNET:
- return gen_dnhostop(addr, dir, off_nl);
-
- case Q_LAT:
- bpf_error("LAT host filtering not implemented");
-
- case Q_MOPDL:
- bpf_error("MOPDL host filtering not implemented");
-
- case Q_MOPRC:
- bpf_error("MOPRC host filtering not implemented");
-
- default:
- abort();
- }
- /* NOTREACHED */
-}
-
-static struct block *
-gen_gateway(eaddr, alist, proto, dir)
- u_char *eaddr;
- u_long **alist;
- int proto;
- int dir;
-{
- struct block *b0, *b1, *tmp;
-
- if (dir != 0)
- bpf_error("direction applied to 'gateway'");
-
- switch (proto) {
- case Q_DEFAULT:
- case Q_IP:
- case Q_ARP:
- case Q_RARP:
- if (linktype == DLT_EN10MB)
- b0 = gen_ehostop(eaddr, Q_OR);
-#ifdef FDDI
- else if (linktype == DLT_FDDI)
- b0 = gen_fhostop(eaddr, Q_OR);
-#endif
- else
- bpf_error("'gateway' supported only on ethernet or FDDI");
-
- b1 = gen_host(**alist++, 0xffffffffL, proto, Q_OR);
- while (*alist) {
- tmp = gen_host(**alist++, 0xffffffffL, proto, Q_OR);
- gen_or(b1, tmp);
- b1 = tmp;
- }
- gen_not(b1);
- gen_and(b0, b1);
- return b1;
- }
- bpf_error("illegal modifier of 'gateway'");
- /* NOTREACHED */
-}
-
-struct block *
-gen_proto_abbrev(proto)
- int proto;
-{
- struct block *b0, *b1;
-
- switch (proto) {
-
- case Q_TCP:
- b0 = gen_linktype(ETHERTYPE_IP);
- b1 = gen_cmp(off_nl + 9, BPF_B, (long)IPPROTO_TCP);
- gen_and(b0, b1);
- break;
-
- case Q_UDP:
- b0 = gen_linktype(ETHERTYPE_IP);
- b1 = gen_cmp(off_nl + 9, BPF_B, (long)IPPROTO_UDP);
- gen_and(b0, b1);
- break;
-
- case Q_ICMP:
- b0 = gen_linktype(ETHERTYPE_IP);
- b1 = gen_cmp(off_nl + 9, BPF_B, (long)IPPROTO_ICMP);
- gen_and(b0, b1);
- break;
-
- case Q_IP:
- b1 = gen_linktype(ETHERTYPE_IP);
- break;
-
- case Q_ARP:
- b1 = gen_linktype(ETHERTYPE_ARP);
- break;
-
- case Q_RARP:
- b1 = gen_linktype(ETHERTYPE_REVARP);
- break;
-
- case Q_LINK:
- bpf_error("link layer applied in wrong context");
-
- case Q_DECNET:
- b1 = gen_linktype(ETHERTYPE_DN);
- break;
-
- case Q_LAT:
- b1 = gen_linktype(ETHERTYPE_LAT);
- break;
-
- case Q_MOPDL:
- b1 = gen_linktype(ETHERTYPE_MOPDL);
- break;
-
- case Q_MOPRC:
- b1 = gen_linktype(ETHERTYPE_MOPRC);
- break;
-
- default:
- abort();
- }
- return b1;
-}
-
-static struct block *
-gen_ipfrag()
-{
- struct slist *s;
- struct block *b;
-
- /* not ip frag */
- s = new_stmt(BPF_LD|BPF_H|BPF_ABS);
- s->s.k = off_nl + 6;
- b = new_block(JMP(BPF_JSET));
- b->s.k = 0x1fff;
- b->stmts = s;
- gen_not(b);
-
- return b;
-}
-
-static struct block *
-gen_portatom(off, v)
- int off;
- long v;
-{
- struct slist *s;
- struct block *b;
-
- s = new_stmt(BPF_LDX|BPF_MSH|BPF_B);
- s->s.k = off_nl;
-
- s->next = new_stmt(BPF_LD|BPF_IND|BPF_H);
- s->next->s.k = off_nl + off;
-
- b = new_block(JMP(BPF_JEQ));
- b->stmts = s;
- b->s.k = v;
-
- return b;
-}
-
-struct block *
-gen_portop(port, proto, dir)
- int port, proto, dir;
-{
- struct block *b0, *b1, *tmp;
-
- /* ip proto 'proto' */
- tmp = gen_cmp(off_nl + 9, BPF_B, (long)proto);
- b0 = gen_ipfrag();
- gen_and(tmp, b0);
-
- switch (dir) {
- case Q_SRC:
- b1 = gen_portatom(0, (long)port);
- break;
-
- case Q_DST:
- b1 = gen_portatom(2, (long)port);
- break;
-
- case Q_OR:
- case Q_DEFAULT:
- tmp = gen_portatom(0, (long)port);
- b1 = gen_portatom(2, (long)port);
- gen_or(tmp, b1);
- break;
-
- case Q_AND:
- tmp = gen_portatom(0, (long)port);
- b1 = gen_portatom(2, (long)port);
- gen_and(tmp, b1);
- break;
-
- default:
- abort();
- }
- gen_and(b0, b1);
-
- return b1;
-}
-
-static struct block *
-gen_port(port, ip_proto, dir)
- int port;
- int ip_proto;
- int dir;
-{
- struct block *b0, *b1, *tmp;
-
- /* ether proto ip */
- b0 = gen_linktype(ETHERTYPE_IP);
-
- switch (ip_proto) {
- case IPPROTO_UDP:
- case IPPROTO_TCP:
- b1 = gen_portop(port, ip_proto, dir);
- break;
-
- case PROTO_UNDEF:
- tmp = gen_portop(port, IPPROTO_TCP, dir);
- b1 = gen_portop(port, IPPROTO_UDP, dir);
- gen_or(tmp, b1);
- break;
-
- default:
- abort();
- }
- gen_and(b0, b1);
- return b1;
-}
-
-static int
-lookup_proto(name, proto)
- char *name;
- int proto;
-{
- int v;
-
- switch (proto) {
- case Q_DEFAULT:
- case Q_IP:
- v = pcap_nametoproto(name);
- if (v == PROTO_UNDEF)
- bpf_error("unknown ip proto '%s'", name);
- break;
-
- case Q_LINK:
- /* XXX should look up h/w protocol type based on linktype */
- v = pcap_nametoeproto(name);
- if (v == PROTO_UNDEF)
- bpf_error("unknown ether proto '%s'", name);
- break;
-
- default:
- v = PROTO_UNDEF;
- break;
- }
- return v;
-}
-
-static struct block *
-gen_proto(v, proto, dir)
- int v;
- int proto;
- int dir;
-{
- struct block *b0, *b1;
-
- if (dir != Q_DEFAULT)
- bpf_error("direction applied to 'proto'");
-
- switch (proto) {
- case Q_DEFAULT:
- case Q_IP:
- b0 = gen_linktype(ETHERTYPE_IP);
- b1 = gen_cmp(off_nl + 9, BPF_B, (long)v);
- gen_and(b0, b1);
- return b1;
-
- case Q_ARP:
- bpf_error("arp does not encapsulate another protocol");
- /* NOTREACHED */
-
- case Q_RARP:
- bpf_error("rarp does not encapsulate another protocol");
- /* NOTREACHED */
-
- case Q_DECNET:
- bpf_error("decnet encapsulation is not specifiable");
- /* NOTREACHED */
-
- case Q_LAT:
- bpf_error("lat does not encapsulate another protocol");
- /* NOTREACHED */
-
- case Q_MOPRC:
- bpf_error("moprc does not encapsulate another protocol");
- /* NOTREACHED */
-
- case Q_MOPDL:
- bpf_error("mopdl does not encapsulate another protocol");
- /* NOTREACHED */
-
- case Q_LINK:
- return gen_linktype(v);
-
- case Q_UDP:
- bpf_error("'udp proto' is bogus");
- /* NOTREACHED */
-
- case Q_TCP:
- bpf_error("'tcp proto' is bogus");
- /* NOTREACHED */
-
- case Q_ICMP:
- bpf_error("'icmp proto' is bogus");
- /* NOTREACHED */
-
- default:
- abort();
- /* NOTREACHED */
- }
- /* NOTREACHED */
-}
-
-/*
- * Left justify 'addr' and return its resulting network mask.
- */
-static u_long
-net_mask(addr)
- u_long *addr;
-{
- register u_long m = 0xffffffff;
-
- if (*addr)
- while ((*addr & 0xff000000) == 0)
- *addr <<= 8, m <<= 8;
-
- return m;
-}
-
-struct block *
-gen_scode(name, q)
- char *name;
- struct qual q;
-{
- int proto = q.proto;
- int dir = q.dir;
- u_char *eaddr;
- u_long mask, addr, **alist;
- struct block *b, *tmp;
- int port, real_proto;
-
- switch (q.addr) {
-
- case Q_NET:
- addr = pcap_nametonetaddr(name);
- if (addr == 0)
- bpf_error("unknown network '%s'", name);
- mask = net_mask(&addr);
- return gen_host(addr, mask, proto, dir);
-
- case Q_DEFAULT:
- case Q_HOST:
- if (proto == Q_LINK) {
- switch (linktype) {
- case DLT_EN10MB:
- eaddr = pcap_ether_hostton(name);
- if (eaddr == NULL)
- bpf_error("unknown ether host '%s'", name);
- return gen_ehostop(eaddr, dir);
-
-#ifdef FDDI
- case DLT_FDDI:
- eaddr = pcap_ether_hostton(name);
- if (eaddr == NULL)
- bpf_error("unknown FDDI host '%s'", name);
- return gen_fhostop(eaddr, dir);
-#endif
- default:
- bpf_error("only ethernet/FDDI supports link-level host name");
- break;
- }
- } else if (proto == Q_DECNET) {
- unsigned short dn_addr = __pcap_nametodnaddr(name);
- /*
- * I don't think DECNET hosts can be multihomed, so
- * there is no need to build up a list of addresses
- */
- return (gen_host(dn_addr, 0, proto, dir));
- } else {
- alist = pcap_nametoaddr(name);
- if (alist == NULL || *alist == NULL)
- bpf_error("unknown host '%s'", name);
- b = gen_host(**alist++, 0xffffffffL, proto, dir);
- while (*alist) {
- tmp = gen_host(**alist++, 0xffffffffL,
- proto, dir);
- gen_or(b, tmp);
- b = tmp;
- }
- return b;
- }
-
- case Q_PORT:
- if (proto != Q_DEFAULT && proto != Q_UDP && proto != Q_TCP)
- bpf_error("illegal qualifier of 'port'");
- if (pcap_nametoport(name, &port, &real_proto) == 0)
- bpf_error("unknown port '%s'", name);
- if (proto == Q_UDP) {
- if (real_proto == IPPROTO_TCP)
- bpf_error("port '%s' is tcp", name);
- else
- /* override PROTO_UNDEF */
- real_proto = IPPROTO_UDP;
- }
- if (proto == Q_TCP) {
- if (real_proto == IPPROTO_UDP)
- bpf_error("port '%s' is udp", name);
- else
- /* override PROTO_UNDEF */
- real_proto = IPPROTO_TCP;
- }
- return gen_port(port, real_proto, dir);
-
- case Q_GATEWAY:
- eaddr = pcap_ether_hostton(name);
- if (eaddr == NULL)
- bpf_error("unknown ether host: %s", name);
-
- alist = pcap_nametoaddr(name);
- if (alist == NULL || *alist == NULL)
- bpf_error("unknown host '%s'", name);
- return gen_gateway(eaddr, alist, proto, dir);
-
- case Q_PROTO:
- real_proto = lookup_proto(name, proto);
- if (real_proto >= 0)
- return gen_proto(real_proto, proto, dir);
- else
- bpf_error("unknown protocol: %s", name);
-
- case Q_UNDEF:
- syntax();
- /* NOTREACHED */
- }
- abort();
- /* NOTREACHED */
-}
-
-struct block *
-gen_ncode(v, q)
- u_long v;
- struct qual q;
-{
- u_long mask;
- int proto = q.proto;
- int dir = q.dir;
-
- switch (q.addr) {
-
- case Q_DEFAULT:
- case Q_HOST:
- case Q_NET:
- if (proto == Q_DECNET)
- return gen_host(v, 0, proto, dir);
- else if (proto == Q_LINK) {
- bpf_error("illegal link layer address");
- } else {
- mask = net_mask(&v);
- return gen_host(v, mask, proto, dir);
- }
-
- case Q_PORT:
- if (proto == Q_UDP)
- proto = IPPROTO_UDP;
- else if (proto == Q_TCP)
- proto = IPPROTO_TCP;
- else if (proto == Q_DEFAULT)
- proto = PROTO_UNDEF;
- else
- bpf_error("illegal qualifier of 'port'");
-
- return gen_port((int)v, proto, dir);
-
- case Q_GATEWAY:
- bpf_error("'gateway' requires a name");
- /* NOTREACHED */
-
- case Q_PROTO:
- return gen_proto((int)v, proto, dir);
-
- case Q_UNDEF:
- syntax();
- /* NOTREACHED */
-
- default:
- abort();
- /* NOTREACHED */
- }
- /* NOTREACHED */
-}
-
-struct block *
-gen_ecode(eaddr, q)
- u_char *eaddr;
- struct qual q;
-{
- if ((q.addr == Q_HOST || q.addr == Q_DEFAULT) && q.proto == Q_LINK) {
- if (linktype == DLT_EN10MB)
- return gen_ehostop(eaddr, (int)q.dir);
-#ifdef FDDI
- if (linktype == DLT_FDDI)
- return gen_fhostop(eaddr, (int)q.dir);
-#endif
- }
- bpf_error("ethernet address used in non-ether expression");
- /* NOTREACHED */
-}
-
-void
-sappend(s0, s1)
- struct slist *s0, *s1;
-{
- /*
- * This is definitely not the best way to do this, but the
- * lists will rarely get long.
- */
- while (s0->next)
- s0 = s0->next;
- s0->next = s1;
-}
-
-static struct slist *
-xfer_to_x(a)
- struct arth *a;
-{
- struct slist *s;
-
- s = new_stmt(BPF_LDX|BPF_MEM);
- s->s.k = a->regno;
- return s;
-}
-
-static struct slist *
-xfer_to_a(a)
- struct arth *a;
-{
- struct slist *s;
-
- s = new_stmt(BPF_LD|BPF_MEM);
- s->s.k = a->regno;
- return s;
-}
-
-struct arth *
-gen_load(proto, index, size)
- int proto;
- struct arth *index;
- int size;
-{
- struct slist *s, *tmp;
- struct block *b;
- int regno = alloc_reg();
-
- free_reg(index->regno);
- switch (size) {
-
- default:
- bpf_error("data size must be 1, 2, or 4");
-
- case 1:
- size = BPF_B;
- break;
-
- case 2:
- size = BPF_H;
- break;
-
- case 4:
- size = BPF_W;
- break;
- }
- switch (proto) {
- default:
- bpf_error("unsupported index operation");
-
- case Q_LINK:
- s = xfer_to_x(index);
- tmp = new_stmt(BPF_LD|BPF_IND|size);
- sappend(s, tmp);
- sappend(index->s, s);
- break;
-
- case Q_IP:
- case Q_ARP:
- case Q_RARP:
- case Q_DECNET:
- case Q_LAT:
- case Q_MOPRC:
- case Q_MOPDL:
- /* XXX Note that we assume a fixed link link header here. */
- s = xfer_to_x(index);
- tmp = new_stmt(BPF_LD|BPF_IND|size);
- tmp->s.k = off_nl;
- sappend(s, tmp);
- sappend(index->s, s);
-
- b = gen_proto_abbrev(proto);
- if (index->b)
- gen_and(index->b, b);
- index->b = b;
- break;
-
- case Q_TCP:
- case Q_UDP:
- case Q_ICMP:
- s = new_stmt(BPF_LDX|BPF_MSH|BPF_B);
- s->s.k = off_nl;
- sappend(s, xfer_to_a(index));
- sappend(s, new_stmt(BPF_ALU|BPF_ADD|BPF_X));
- sappend(s, new_stmt(BPF_MISC|BPF_TAX));
- sappend(s, tmp = new_stmt(BPF_LD|BPF_IND|size));
- tmp->s.k = off_nl;
- sappend(index->s, s);
-
- gen_and(gen_proto_abbrev(proto), b = gen_ipfrag());
- if (index->b)
- gen_and(index->b, b);
- index->b = b;
- break;
- }
- index->regno = regno;
- s = new_stmt(BPF_ST);
- s->s.k = regno;
- sappend(index->s, s);
-
- return index;
-}
-
-struct block *
-gen_relation(code, a0, a1, reversed)
- int code;
- struct arth *a0, *a1;
- int reversed;
-{
- struct slist *s0, *s1, *s2;
- struct block *b, *tmp;
-
- s0 = xfer_to_x(a1);
- s1 = xfer_to_a(a0);
- s2 = new_stmt(BPF_ALU|BPF_SUB|BPF_X);
- b = new_block(JMP(code));
- if (reversed)
- gen_not(b);
-
- sappend(s1, s2);
- sappend(s0, s1);
- sappend(a1->s, s0);
- sappend(a0->s, a1->s);
-
- b->stmts = a0->s;
-
- free_reg(a0->regno);
- free_reg(a1->regno);
-
- /* 'and' together protocol checks */
- if (a0->b) {
- if (a1->b) {
- gen_and(a0->b, tmp = a1->b);
- }
- else
- tmp = a0->b;
- } else
- tmp = a1->b;
-
- if (tmp)
- gen_and(tmp, b);
-
- return b;
-}
-
-struct arth *
-gen_loadlen()
-{
- int regno = alloc_reg();
- struct arth *a = (struct arth *)newchunk(sizeof(*a));
- struct slist *s;
-
- s = new_stmt(BPF_LD|BPF_LEN);
- s->next = new_stmt(BPF_ST);
- s->next->s.k = regno;
- a->s = s;
- a->regno = regno;
-
- return a;
-}
-
-struct arth *
-gen_loadi(val)
- int val;
-{
- struct arth *a;
- struct slist *s;
- int reg;
-
- a = (struct arth *)newchunk(sizeof(*a));
-
- reg = alloc_reg();
-
- s = new_stmt(BPF_LD|BPF_IMM);
- s->s.k = val;
- s->next = new_stmt(BPF_ST);
- s->next->s.k = reg;
- a->s = s;
- a->regno = reg;
-
- return a;
-}
-
-struct arth *
-gen_neg(a)
- struct arth *a;
-{
- struct slist *s;
-
- s = xfer_to_a(a);
- sappend(a->s, s);
- s = new_stmt(BPF_ALU|BPF_NEG);
- s->s.k = 0;
- sappend(a->s, s);
- s = new_stmt(BPF_ST);
- s->s.k = a->regno;
- sappend(a->s, s);
-
- return a;
-}
-
-struct arth *
-gen_arth(code, a0, a1)
- int code;
- struct arth *a0, *a1;
-{
- struct slist *s0, *s1, *s2;
-
- s0 = xfer_to_x(a1);
- s1 = xfer_to_a(a0);
- s2 = new_stmt(BPF_ALU|BPF_X|code);
-
- sappend(s1, s2);
- sappend(s0, s1);
- sappend(a1->s, s0);
- sappend(a0->s, a1->s);
-
- free_reg(a1->regno);
-
- s0 = new_stmt(BPF_ST);
- a0->regno = s0->s.k = alloc_reg();
- sappend(a0->s, s0);
-
- return a0;
-}
-
-/*
- * Here we handle simple allocation of the scratch registers.
- * If too many registers are alloc'd, the allocator punts.
- */
-static int regused[BPF_MEMWORDS];
-static int curreg;
-
-/*
- * Return the next free register.
- */
-static int
-alloc_reg()
-{
- int n = BPF_MEMWORDS;
-
- while (--n >= 0) {
- if (regused[curreg])
- curreg = (curreg + 1) % BPF_MEMWORDS;
- else {
- regused[curreg] = 1;
- return curreg;
- }
- }
- bpf_error("too many registers needed to evaluate expression");
- /* NOTREACHED */
-}
-
-/*
- * Return a register to the table so it can
- * be used later.
- */
-static void
-free_reg(n)
- int n;
-{
- regused[n] = 0;
-}
-
-static struct block *
-gen_len(jmp, n)
- int jmp, n;
-{
- struct slist *s;
- struct block *b;
-
- s = new_stmt(BPF_LD|BPF_LEN);
- s->next = new_stmt(BPF_ALU|BPF_SUB|BPF_K);
- s->next->s.k = n;
- b = new_block(JMP(jmp));
- b->stmts = s;
-
- return b;
-}
-
-struct block *
-gen_greater(n)
- int n;
-{
- return gen_len(BPF_JGE, n);
-}
-
-struct block *
-gen_less(n)
- int n;
-{
- struct block *b;
-
- b = gen_len(BPF_JGT, n);
- gen_not(b);
-
- return b;
-}
-
-struct block *
-gen_byteop(op, idx, val)
- int op, idx, val;
-{
- struct block *b;
- struct slist *s;
-
- switch (op) {
- default:
- abort();
-
- case '=':
- return gen_cmp((u_int)idx, BPF_B, (long)val);
-
- case '<':
- b = gen_cmp((u_int)idx, BPF_B, (long)val);
- b->s.code = JMP(BPF_JGE);
- gen_not(b);
- return b;
-
- case '>':
- b = gen_cmp((u_int)idx, BPF_B, (long)val);
- b->s.code = JMP(BPF_JGT);
- return b;
-
- case '|':
- s = new_stmt(BPF_ALU|BPF_OR|BPF_K);
- break;
-
- case '&':
- s = new_stmt(BPF_ALU|BPF_AND|BPF_K);
- break;
- }
- s->s.k = val;
- b = new_block(JMP(BPF_JEQ));
- b->stmts = s;
- gen_not(b);
-
- return b;
-}
-
-struct block *
-gen_broadcast(proto)
- int proto;
-{
- u_long hostmask;
- struct block *b0, *b1, *b2;
- static u_char ebroadcast[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
-
- switch (proto) {
-
- case Q_DEFAULT:
- case Q_LINK:
- if (linktype == DLT_EN10MB)
- return gen_ehostop(ebroadcast, Q_DST);
-#ifdef FDDI
- if (linktype == DLT_FDDI)
- return gen_fhostop(ebroadcast, Q_DST);
-#endif
- bpf_error("not a broadcast link");
- break;
-
- case Q_IP:
- b0 = gen_linktype(ETHERTYPE_IP);
- hostmask = ~netmask;
- b1 = gen_mcmp(off_nl + 16, BPF_W, (long)0, hostmask);
- b2 = gen_mcmp(off_nl + 16, BPF_W,
- (long)(~0 & hostmask), hostmask);
- gen_or(b1, b2);
- gen_and(b0, b2);
- return b2;
- }
- bpf_error("only ether/ip broadcast filters supported");
-}
-
-struct block *
-gen_multicast(proto)
- int proto;
-{
- register struct block *b0, *b1;
- register struct slist *s;
-
- switch (proto) {
-
- case Q_DEFAULT:
- case Q_LINK:
- if (linktype == DLT_EN10MB) {
- /* ether[0] & 1 != 0 */
- s = new_stmt(BPF_LD|BPF_B|BPF_ABS);
- s->s.k = 0;
- b0 = new_block(JMP(BPF_JSET));
- b0->s.k = 1;
- b0->stmts = s;
- return b0;
- }
-
- if (linktype == DLT_FDDI) {
- /* XXX TEST THIS: MIGHT NOT PORT PROPERLY XXX */
- /* fddi[1] & 1 != 0 */
- s = new_stmt(BPF_LD|BPF_B|BPF_ABS);
- s->s.k = 1;
- b0 = new_block(JMP(BPF_JSET));
- b0->s.k = 1;
- b0->stmts = s;
- return b0;
- }
- /* Link not known to support multicasts */
- break;
-
- case Q_IP:
- b0 = gen_linktype(ETHERTYPE_IP);
- b1 = gen_cmp(off_nl + 16, BPF_B, (long)224);
- b1->s.code = JMP(BPF_JGE);
- gen_and(b0, b1);
- return b1;
- }
- bpf_error("only IP multicast filters supported on ethernet/FDDI");
-}
-
-/*
- * generate command for inbound/outbound. It's here so we can
- * make it link-type specific. 'dir' = 0 implies "inbound",
- * = 1 implies "outbound".
- */
-struct block *
-gen_inbound(dir)
- int dir;
-{
- register struct block *b0;
-
- b0 = gen_relation(BPF_JEQ,
- gen_load(Q_LINK, gen_loadi(0), 1),
- gen_loadi(0),
- dir);
- return (b0);
-}
diff --git a/lib/libpcap/gencode.h b/lib/libpcap/gencode.h
deleted file mode 100644
index 34d4c19..0000000
--- a/lib/libpcap/gencode.h
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Copyright (c) 1990, 1991, 1992, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that: (1) source code distributions
- * retain the above copyright notice and this paragraph in its entirety, (2)
- * distributions including binary code include the above copyright notice and
- * this paragraph in its entirety in the documentation or other materials
- * provided with the distribution, and (3) all advertising materials mentioning
- * features or use of this software display the following acknowledgement:
- * ``This product includes software developed by the University of California,
- * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
- * the University nor the names of its contributors may be used to endorse
- * or promote products derived from this software without specific prior
- * written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * @(#) $Header: /home/ncvs/src/lib/libpcap/gencode.h,v 1.1.1.1 1995/01/20 04:13:06 jkh Exp $ (LBL)
- */
-
-/*
- * filter.h must be included before this file.
- */
-
-/* Address qualifers. */
-
-#define Q_HOST 1
-#define Q_NET 2
-#define Q_PORT 3
-#define Q_GATEWAY 4
-#define Q_PROTO 5
-
-/* Protocol qualifiers. */
-
-#define Q_LINK 1
-#define Q_IP 2
-#define Q_ARP 3
-#define Q_RARP 4
-#define Q_TCP 5
-#define Q_UDP 6
-#define Q_ICMP 7
-
-#define Q_DECNET 8
-#define Q_LAT 9
-#define Q_MOPRC 10
-#define Q_MOPDL 11
-
-/* Directional qualifers. */
-
-#define Q_SRC 1
-#define Q_DST 2
-#define Q_OR 3
-#define Q_AND 4
-
-#define Q_DEFAULT 0
-#define Q_UNDEF 255
-
-struct stmt {
- int code;
- long k;
-};
-
-struct slist {
- struct stmt s;
- struct slist *next;
-};
-
-/*
- * A bit vector to represent definition sets. We assume TOT_REGISTERS
- * is smaller than 8*sizeof(atomset).
- */
-typedef u_long atomset;
-#define ATOMMASK(n) (1 << (n))
-#define ATOMELEM(d, n) (d & ATOMMASK(n))
-
-/*
- * An unbounded set.
- */
-typedef u_long *uset;
-
-/*
- * Total number of atomic entities, including accumulator (A) and index (X).
- * We treat all these guys similarly during flow analysis.
- */
-#define N_ATOMS (BPF_MEMWORDS+2)
-
-struct edge {
- int id;
- int code;
- uset edom;
- struct block *succ;
- struct block *pred;
- struct edge *next; /* link list of incoming edges for a node */
-};
-
-struct block {
- int id;
- struct slist *stmts; /* side effect stmts */
- struct stmt s; /* branch stmt */
- int mark;
- int level;
- int offset;
- int sense;
- struct edge et;
- struct edge ef;
- struct block *head;
- struct block *link; /* link field used by optimizer */
- uset dom;
- uset closure;
- struct edge *in_edges;
- atomset def, kill;
- atomset in_use;
- atomset out_use;
- long oval;
- long val[N_ATOMS];
-};
-
-struct arth {
- struct block *b; /* protocol checks */
- struct slist *s; /* stmt list */
- int regno; /* virtual register number of result */
-};
-
-struct qual {
- unsigned char addr;
- unsigned char proto;
- unsigned char dir;
- unsigned char pad;
-};
-
-#ifndef __GNUC__
-#define volatile
-#endif
-
-struct arth *gen_loadi(int);
-struct arth *gen_load(int, struct arth *, int);
-struct arth *gen_loadlen(void);
-struct arth *gen_neg(struct arth *);
-struct arth *gen_arth(int, struct arth *, struct arth *);
-
-void gen_and(struct block *, struct block *);
-void gen_or(struct block *, struct block *);
-void gen_not(struct block *);
-
-struct block *gen_scode(char *, struct qual);
-struct block *gen_ecode(u_char *, struct qual);
-struct block *gen_ncode(u_long, struct qual);
-struct block *gen_proto_abbrev(int);
-struct block *gen_relation(int, struct arth *, struct arth *, int);
-struct block *gen_less(int);
-struct block *gen_greater(int);
-struct block *gen_byteop(int, int, int);
-struct block *gen_broadcast(int);
-struct block *gen_multicast(int);
-struct block *gen_inbound(int);
-
-void bpf_optimize(struct block **);
-volatile void bpf_error(char *, ...);
-
-void finish_parse(struct block *);
-char *sdup(char *);
-
-struct bpf_insn *icode_to_fcode(struct block *, int *);
-int pcap_parse(void);
-void lex_init(char *);
-void sappend(struct slist *, struct slist *);
-
-/* XXX */
-#define JT(b) ((b)->et.succ)
-#define JF(b) ((b)->ef.succ)
diff --git a/lib/libpcap/grammar.y b/lib/libpcap/grammar.y
deleted file mode 100644
index 4c17bdc..0000000
--- a/lib/libpcap/grammar.y
+++ /dev/null
@@ -1,266 +0,0 @@
-%{
-/*
- * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that: (1) source code distributions
- * retain the above copyright notice and this paragraph in its entirety, (2)
- * distributions including binary code include the above copyright notice and
- * this paragraph in its entirety in the documentation or other materials
- * provided with the distribution, and (3) all advertising materials mentioning
- * features or use of this software display the following acknowledgement:
- * ``This product includes software developed by the University of California,
- * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
- * the University nor the names of its contributors may be used to endorse
- * or promote products derived from this software without specific prior
- * written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- */
-#ifndef lint
-static char rcsid[] =
- "@(#) $Header: /home/ncvs/src/lib/libpcap/grammar.y,v 1.1.1.1 1995/01/20 04:13:06 jkh Exp $ (LBL)";
-#endif
-
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/socket.h>
-
-#include <net/if.h>
-#include <net/bpf.h>
-
-#include <netinet/in.h>
-#include <netinet/if_ether.h>
-
-#include <stdio.h>
-#include <pcap.h>
-#include <pcap-namedb.h>
-
-#include "gencode.h"
-
-#define yylval pcap_lval
-
-#define QSET(q, p, d, a) (q).proto = (p),\
- (q).dir = (d),\
- (q).addr = (a)
-
-int n_errors = 0;
-
-static struct qual qerr = { Q_UNDEF, Q_UNDEF, Q_UNDEF, Q_UNDEF };
-
-static void
-yyerror(char *msg)
-{
- ++n_errors;
- bpf_error(msg);
- /* NOTREACHED */
-}
-
-#ifndef YYBISON
-pcap_parse()
-{
- return (yyparse());
-}
-#endif
-
-%}
-
-%union {
- int i;
- u_long h;
- u_char *e;
- char *s;
- struct stmt *stmt;
- struct arth *a;
- struct {
- struct qual q;
- struct block *b;
- } blk;
- struct block *rblk;
-}
-
-%type <blk> expr id nid pid term rterm qid
-%type <blk> head
-%type <i> pqual dqual aqual ndaqual
-%type <a> arth narth
-%type <i> byteop pname pnum relop irelop
-%type <blk> and or paren not null prog
-%type <rblk> other
-
-%token DST SRC HOST GATEWAY
-%token NET PORT LESS GREATER PROTO BYTE
-%token ARP RARP IP TCP UDP ICMP
-%token DECNET LAT MOPRC MOPDL
-%token TK_BROADCAST TK_MULTICAST
-%token NUM INBOUND OUTBOUND
-%token LINK
-%token GEQ LEQ NEQ
-%token ID EID HID
-%token LSH RSH
-%token LEN
-
-%type <s> ID
-%type <e> EID
-%type <h> HID
-%type <i> NUM
-
-%left OR AND
-%nonassoc '!'
-%left '|'
-%left '&'
-%left LSH RSH
-%left '+' '-'
-%left '*' '/'
-%nonassoc UMINUS
-%%
-prog: null expr
-{
- finish_parse($2.b);
-}
- | null
- ;
-null: /* null */ { $$.q = qerr; }
- ;
-expr: term
- | expr and term { gen_and($1.b, $3.b); $$ = $3; }
- | expr and id { gen_and($1.b, $3.b); $$ = $3; }
- | expr or term { gen_or($1.b, $3.b); $$ = $3; }
- | expr or id { gen_or($1.b, $3.b); $$ = $3; }
- ;
-and: AND { $$ = $<blk>0; }
- ;
-or: OR { $$ = $<blk>0; }
- ;
-id: nid
- | pnum { $$.b = gen_ncode((u_long)$1,
- $$.q = $<blk>0.q); }
- | paren pid ')' { $$ = $2; }
- ;
-nid: ID { $$.b = gen_scode($1, $$.q = $<blk>0.q); }
- | HID {
- /* Decide how to parse HID based on proto */
- $$.q = $<blk>0.q;
- switch ($$.q.proto) {
- case Q_DECNET:
- $$.b =
- gen_ncode(__pcap_atodn((char *)$1),
- $$.q);
- break;
- default:
- $$.b =
- gen_ncode(__pcap_atoin((char *)$1),
- $$.q);
- break;
- }
- }
- | EID { $$.b = gen_ecode($1, $$.q = $<blk>0.q); }
- | not id { gen_not($2.b); $$ = $2; }
- ;
-not: '!' { $$ = $<blk>0; }
- ;
-paren: '(' { $$ = $<blk>0; }
- ;
-pid: nid
- | qid and id { gen_and($1.b, $3.b); $$ = $3; }
- | qid or id { gen_or($1.b, $3.b); $$ = $3; }
- ;
-qid: pnum { $$.b = gen_ncode((u_long)$1,
- $$.q = $<blk>0.q); }
- | pid
- ;
-term: rterm
- | not term { gen_not($2.b); $$ = $2; }
- ;
-head: pqual dqual aqual { QSET($$.q, $1, $2, $3); }
- | pqual dqual { QSET($$.q, $1, $2, Q_DEFAULT); }
- | pqual aqual { QSET($$.q, $1, Q_DEFAULT, $2); }
- | pqual PROTO { QSET($$.q, $1, Q_DEFAULT, Q_PROTO); }
- | pqual ndaqual { QSET($$.q, $1, Q_DEFAULT, $2); }
- ;
-rterm: head id { $$ = $2; }
- | paren expr ')' { $$.b = $2.b; $$.q = $1.q; }
- | pname { $$.b = gen_proto_abbrev($1); $$.q = qerr; }
- | arth relop arth { $$.b = gen_relation($2, $1, $3, 0);
- $$.q = qerr; }
- | arth irelop arth { $$.b = gen_relation($2, $1, $3, 1);
- $$.q = qerr; }
- | other { $$.b = $1; $$.q = qerr; }
- ;
-/* protocol level qualifiers */
-pqual: pname
- | { $$ = Q_DEFAULT; }
- ;
-/* 'direction' qualifiers */
-dqual: SRC { $$ = Q_SRC; }
- | DST { $$ = Q_DST; }
- | SRC OR DST { $$ = Q_OR; }
- | DST OR SRC { $$ = Q_OR; }
- | SRC AND DST { $$ = Q_AND; }
- | DST AND SRC { $$ = Q_AND; }
- ;
-/* address type qualifiers */
-aqual: HOST { $$ = Q_HOST; }
- | NET { $$ = Q_NET; }
- | PORT { $$ = Q_PORT; }
- ;
-/* non-directional address type qualifiers */
-ndaqual: GATEWAY { $$ = Q_GATEWAY; }
- ;
-pname: LINK { $$ = Q_LINK; }
- | IP { $$ = Q_IP; }
- | ARP { $$ = Q_ARP; }
- | RARP { $$ = Q_RARP; }
- | TCP { $$ = Q_TCP; }
- | UDP { $$ = Q_UDP; }
- | ICMP { $$ = Q_ICMP; }
- | DECNET { $$ = Q_DECNET; }
- | LAT { $$ = Q_LAT; }
- | MOPDL { $$ = Q_MOPDL; }
- | MOPRC { $$ = Q_MOPRC; }
- ;
-other: pqual TK_BROADCAST { $$ = gen_broadcast($1); }
- | pqual TK_MULTICAST { $$ = gen_multicast($1); }
- | LESS NUM { $$ = gen_less($2); }
- | GREATER NUM { $$ = gen_greater($2); }
- | BYTE NUM byteop NUM { $$ = gen_byteop($3, $2, $4); }
- | INBOUND { $$ = gen_inbound(0); }
- | OUTBOUND { $$ = gen_inbound(1); }
- ;
-relop: '>' { $$ = BPF_JGT; }
- | GEQ { $$ = BPF_JGE; }
- | '=' { $$ = BPF_JEQ; }
- ;
-irelop: LEQ { $$ = BPF_JGT; }
- | '<' { $$ = BPF_JGE; }
- | NEQ { $$ = BPF_JEQ; }
- ;
-arth: pnum { $$ = gen_loadi($1); }
- | narth
- ;
-narth: pname '[' arth ']' { $$ = gen_load($1, $3, 1); }
- | pname '[' arth ':' NUM ']' { $$ = gen_load($1, $3, $5); }
- | arth '+' arth { $$ = gen_arth(BPF_ADD, $1, $3); }
- | arth '-' arth { $$ = gen_arth(BPF_SUB, $1, $3); }
- | arth '*' arth { $$ = gen_arth(BPF_MUL, $1, $3); }
- | arth '/' arth { $$ = gen_arth(BPF_DIV, $1, $3); }
- | arth '&' arth { $$ = gen_arth(BPF_AND, $1, $3); }
- | arth '|' arth { $$ = gen_arth(BPF_OR, $1, $3); }
- | arth LSH arth { $$ = gen_arth(BPF_LSH, $1, $3); }
- | arth RSH arth { $$ = gen_arth(BPF_RSH, $1, $3); }
- | '-' arth %prec UMINUS { $$ = gen_neg($2); }
- | paren narth ')' { $$ = $2; }
- | LEN { $$ = gen_loadlen(); }
- ;
-byteop: '&' { $$ = '&'; }
- | '|' { $$ = '|'; }
- | '<' { $$ = '<'; }
- | '>' { $$ = '>'; }
- | '=' { $$ = '='; }
- ;
-pnum: NUM
- | paren pnum ')' { $$ = $2; }
- ;
-%%
diff --git a/lib/libpcap/inet.c b/lib/libpcap/inet.c
deleted file mode 100644
index 3092011..0000000
--- a/lib/libpcap/inet.c
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * Copyright (c) 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the Computer Systems
- * Engineering Group at Lawrence Berkeley Laboratory.
- * 4. Neither the name of the University nor of the Laboratory may be used
- * to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-static char rcsid[] =
- "@(#) $Header: /home/ncvs/src/lib/libpcap/inet.c,v 1.1.1.1 1995/01/20 04:13:03 jkh Exp $ (LBL)";
-#endif
-
-#include <sys/param.h>
-#include <sys/file.h>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-#ifdef SOLARIS
-#include <sys/sockio.h>
-#endif
-
-#include <net/if.h>
-#include <netinet/in.h>
-
-#include <ctype.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <pcap.h>
-
-/* Not all systems have IFF_LOOPBACK */
-#ifdef IFF_LOOPBACK
-#define ISLOOPBACK(p) ((p)->ifr_flags & IFF_LOOPBACK)
-#else
-#define ISLOOPBACK(p) (strcmp((p)->ifr_name, "lo0") == 0)
-#endif
-
-/*
- * Return the name of a network interface attached to the system, or NULL
- * if none can be found. The interface must be configured up; the
- * lowest unit number is preferred; loopback is ignored.
- */
-char *
-pcap_lookupdev(errbuf)
- register char *errbuf;
-{
- register int fd, minunit, n;
- register char *cp;
- register struct ifreq *ifrp, *ifend, *ifnext, *mp;
- struct ifconf ifc;
- struct ifreq ibuf[16], ifr;
- static char device[sizeof(ifrp->ifr_name) + 1];
-
- fd = socket(AF_INET, SOCK_DGRAM, 0);
- if (fd < 0) {
- (void)sprintf(errbuf, "socket: %s", pcap_strerror(errno));
- return (NULL);
- }
- ifc.ifc_len = sizeof ibuf;
- ifc.ifc_buf = (caddr_t)ibuf;
-
- if (ioctl(fd, SIOCGIFCONF, (char *)&ifc) < 0 ||
- ifc.ifc_len < sizeof(struct ifreq)) {
- (void)sprintf(errbuf, "SIOCGIFCONF: %s", pcap_strerror(errno));
- (void)close(fd);
- return (NULL);
- }
- ifrp = ibuf;
- ifend = (struct ifreq *)((char *)ibuf + ifc.ifc_len);
-
- mp = NULL;
- minunit = 666;
- for (; ifrp < ifend; ifrp = ifnext) {
-#if BSD - 0 >= 199006
- n = ifrp->ifr_addr.sa_len + sizeof(ifrp->ifr_name);
- if (n < sizeof(*ifrp))
- ifnext = ifrp + 1;
- else
- ifnext = (struct ifreq *)((char *)ifrp + n);
- if (ifrp->ifr_addr.sa_family != AF_INET)
- continue;
-#else
- ifnext = ifrp + 1;
-#endif
- /*
- * Need a template to preserve address info that is
- * used below to locate the next entry. (Otherwise,
- * SIOCGIFFLAGS stomps over it because the requests
- * are returned in a union.)
- */
- strncpy(ifr.ifr_name, ifrp->ifr_name, sizeof(ifr.ifr_name));
- if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifr) < 0) {
- (void)sprintf(errbuf, "SIOCGIFFLAGS: %s",
- pcap_strerror(errno));
- (void)close(fd);
- return (NULL);
- }
-
- /* Must be up and not the loopback */
- if ((ifr.ifr_flags & IFF_UP) == 0 || ISLOOPBACK(&ifr))
- continue;
-
- for (cp = ifrp->ifr_name; !isdigit(*cp); ++cp)
- continue;
- n = atoi(cp);
- if (n < minunit) {
- minunit = n;
- mp = ifrp;
- }
- }
- (void)close(fd);
- if (mp == NULL) {
- (void)strcpy(errbuf, "no suitable device found");
- return (NULL);
- }
-
- (void)strncpy(device, mp->ifr_name, sizeof(device) - 1);
- device[sizeof(device) - 1] = '\0';
- return (device);
-}
-
-int
-pcap_lookupnet(device, netp, maskp, errbuf)
- register char *device;
- register u_long *netp, *maskp;
- register char *errbuf;
-{
- register int fd;
- register struct sockaddr_in *sin;
- struct ifreq ifr;
-
- fd = socket(AF_INET, SOCK_DGRAM, 0);
- if (fd < 0) {
- (void)sprintf(errbuf, "socket: %s", pcap_strerror(errno));
- return (-1);
- }
- (void)strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
- if (ioctl(fd, SIOCGIFADDR, (char *)&ifr) < 0) {
- (void)sprintf(errbuf, "SIOCGIFADDR: %s: %s",
- device, pcap_strerror(errno));
- (void)close(fd);
- return (-1);
- }
- sin = (struct sockaddr_in *)&ifr.ifr_addr;
- *netp = sin->sin_addr.s_addr;
- if (ioctl(fd, SIOCGIFNETMASK, (char *)&ifr) < 0) {
- (void)sprintf(errbuf, "SIOCGIFNETMASK: %s: %s",
- device, pcap_strerror(errno));
- (void)close(fd);
- return (-1);
- }
- (void)close(fd);
- *maskp = sin->sin_addr.s_addr;
- if (*maskp == 0) {
- if (IN_CLASSA(*netp))
- *maskp = IN_CLASSA_NET;
- else if (IN_CLASSB(*netp))
- *maskp = IN_CLASSB_NET;
- else if (IN_CLASSC(*netp))
- *maskp = IN_CLASSC_NET;
- else {
- (void)sprintf(errbuf, "inet class for 0x%lx unknown",
- *netp);
- return (-1);
- }
- }
- *netp &= *maskp;
- return (0);
-}
diff --git a/lib/libpcap/nametoaddr.c b/lib/libpcap/nametoaddr.c
deleted file mode 100644
index 59e7439..0000000
--- a/lib/libpcap/nametoaddr.c
+++ /dev/null
@@ -1,358 +0,0 @@
-/*
- * Copyright (c) 1990, 1991, 1992, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that: (1) source code distributions
- * retain the above copyright notice and this paragraph in its entirety, (2)
- * distributions including binary code include the above copyright notice and
- * this paragraph in its entirety in the documentation or other materials
- * provided with the distribution, and (3) all advertising materials mentioning
- * features or use of this software display the following acknowledgement:
- * ``This product includes software developed by the University of California,
- * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
- * the University nor the names of its contributors may be used to endorse
- * or promote products derived from this software without specific prior
- * written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Name to id translation routines used by the scanner.
- * These functions are not time critical.
- */
-
-#ifndef lint
-static char rcsid[] =
- "@(#) $Header: /home/ncvs/src/lib/libpcap/nametoaddr.c,v 1.2 1995/05/30 05:47:21 rgrimes Exp $ (LBL)";
-#endif
-
-#include <sys/param.h>
-#include <sys/socket.h>
-#include <net/if.h>
-#include <netinet/in.h>
-#include <netinet/if_ether.h>
-#include <arpa/inet.h>
-
-#include <ctype.h>
-#include <errno.h>
-#include <netdb.h>
-#include <pcap.h>
-#include <pcap-namedb.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "gencode.h"
-
-#ifndef __GNUC__
-#define inline
-#endif
-
-#ifndef NTOHL
-#define NTOHL(x) (x) = ntohl(x)
-#define NTOHS(x) (x) = ntohs(x)
-#endif
-
-static inline int xdtoi(int);
-
-/*
- * Convert host name to internet address.
- * Return 0 upon failure.
- */
-u_long **
-pcap_nametoaddr(const char *name)
-{
-#ifndef h_addr
- static u_long *hlist[2];
-#endif
- u_long **p;
- struct hostent *hp;
-
- if ((hp = gethostbyname(name)) != NULL) {
-#ifndef h_addr
- hlist[0] = (u_long *)hp->h_addr;
- NTOHL(hp->h_addr);
- return hlist;
-#else
- for (p = (u_long **)hp->h_addr_list; *p; ++p)
- NTOHL(**p);
- return (u_long **)hp->h_addr_list;
-#endif
- }
- else
- return 0;
-}
-
-/*
- * Convert net name to internet address.
- * Return 0 upon failure.
- */
-u_long
-pcap_nametonetaddr(const char *name)
-{
- struct netent *np;
-
- if ((np = getnetbyname(name)) != NULL)
- return np->n_net;
- else
- return 0;
-}
-
-/*
- * Convert a port name to its port and protocol numbers.
- * We assume only TCP or UDP.
- * Return 0 upon failure.
- */
-int
-pcap_nametoport(const char *name, int *port, int *proto)
-{
- struct servent *sp;
- char *other;
-
- sp = getservbyname(name, (char *)0);
- if (sp != NULL) {
- NTOHS(sp->s_port);
- *port = sp->s_port;
- *proto = pcap_nametoproto(sp->s_proto);
- /*
- * We need to check /etc/services for ambiguous entries.
- * If we find the ambiguous entry, and it has the
- * same port number, change the proto to PROTO_UNDEF
- * so both TCP and UDP will be checked.
- */
- if (*proto == IPPROTO_TCP)
- other = "udp";
- else
- other = "tcp";
-
- sp = getservbyname(name, other);
- if (sp != 0) {
- NTOHS(sp->s_port);
- if (*port != sp->s_port)
- /* Can't handle ambiguous names that refer
- to different port numbers. */
-#ifdef notdef
- warning("ambiguous port %s in /etc/services",
- name);
-#else
- ;
-#endif
- *proto = PROTO_UNDEF;
- }
- return 1;
- }
-#if defined(ultrix) || defined(__osf__)
- /* Special hack in case NFS isn't in /etc/services */
- if (strcmp(name, "nfs") == 0) {
- *port = 2049;
- *proto = PROTO_UNDEF;
- return 1;
- }
-#endif
- return 0;
-}
-
-int
-pcap_nametoproto(const char *str)
-{
- struct protoent *p;
-
- p = getprotobyname(str);
- if (p != 0)
- return p->p_proto;
- else
- return PROTO_UNDEF;
-}
-
-#include "ethertype.h"
-
-struct eproto {
- char *s;
- u_short p;
-};
-
-/* Static data base of ether protocol types. */
-struct eproto eproto_db[] = {
- { "pup", ETHERTYPE_PUP },
- { "xns", ETHERTYPE_NS },
- { "ip", ETHERTYPE_IP },
- { "arp", ETHERTYPE_ARP },
- { "rarp", ETHERTYPE_REVARP },
- { "sprite", ETHERTYPE_SPRITE },
- { "mopdl", ETHERTYPE_MOPDL },
- { "moprc", ETHERTYPE_MOPRC },
- { "decnet", ETHERTYPE_DN },
- { "lat", ETHERTYPE_LAT },
- { "lanbridge", ETHERTYPE_LANBRIDGE },
- { "vexp", ETHERTYPE_VEXP },
- { "vprod", ETHERTYPE_VPROD },
- { "atalk", ETHERTYPE_ATALK },
- { "atalkarp", ETHERTYPE_AARP },
- { "loopback", ETHERTYPE_LOOPBACK },
- { "decdts", ETHERTYPE_DECDTS },
- { "decdns", ETHERTYPE_DECDNS },
- { (char *)0, 0 }
-};
-
-int
-pcap_nametoeproto(const char *s)
-{
- struct eproto *p = eproto_db;
-
- while (p->s != 0) {
- if (strcmp(p->s, s) == 0)
- return p->p;
- p += 1;
- }
- return PROTO_UNDEF;
-}
-
-/* Hex digit to integer. */
-static inline int
-xdtoi(c)
- register int c;
-{
- if (isdigit(c))
- return c - '0';
- else if (islower(c))
- return c - 'a' + 10;
- else
- return c - 'A' + 10;
-}
-
-u_long
-__pcap_atoin(const char *s)
-{
- u_long addr = 0;
- u_int n;
-
- while (1) {
- n = 0;
- while (*s && *s != '.')
- n = n * 10 + *s++ - '0';
- addr <<= 8;
- addr |= n & 0xff;
- if (*s == '\0')
- return addr;
- ++s;
- }
- /* NOTREACHED */
-}
-
-u_long
-__pcap_atodn(const char *s)
-{
-#define AREASHIFT 10
-#define AREAMASK 0176000
-#define NODEMASK 01777
-
- u_long addr = 0;
- u_int node, area;
-
- if (sscanf((char *)s, "%d.%d", &area, &node) != 2)
- bpf_error("malformed decnet address '%s'", s);
-
- addr = (area << AREASHIFT) & AREAMASK;
- addr |= (node & NODEMASK);
-
- return(addr);
-}
-
-/*
- * Convert 's' which has the form "xx:xx:xx:xx:xx:xx" into a new
- * ethernet address. Assumes 's' is well formed.
- */
-u_char *
-pcap_ether_aton(const char *s)
-{
- register u_char *ep, *e;
- register u_int d;
-
- e = ep = (u_char *)malloc(6);
-
- while (*s) {
- if (*s == ':')
- s += 1;
- d = xdtoi(*s++);
- if (isxdigit(*s)) {
- d <<= 4;
- d |= xdtoi(*s++);
- }
- *ep++ = d;
- }
-
- return (e);
-}
-
-#ifndef ETHER_SERVICE
-/* Roll our own */
-u_char *
-pcap_ether_hostton(const char *name)
-{
- register struct pcap_etherent *ep;
- register u_char *ap;
- static FILE *fp = NULL;
- static init = 0;
-
- if (!init) {
- fp = fopen(PCAP_ETHERS_FILE, "r");
- ++init;
- if (fp == NULL)
- return (NULL);
- } else if (fp == NULL)
- return (NULL);
- else
- rewind(fp);
-
- while ((ep = pcap_next_etherent(fp)) != NULL) {
- if (strcmp(ep->name, name) == 0) {
- ap = (u_char *)malloc(6);
- if (ap != NULL) {
- memcpy(ap, ep->addr, 6);
- return (ap);
- }
- break;
- }
- }
- return (NULL);
-}
-#else
-/* Use the os supplied routines */
-u_char *
-pcap_ether_hostton(const char *name)
-{
- register u_char *ap;
- u_char a[6];
-#ifndef sgi
- extern int ether_hostton(char *, struct ether_addr *);
-#endif
-
- ap = NULL;
- if (ether_hostton((char*)name, (struct ether_addr *)a) == 0) {
- ap = (u_char *)malloc(6);
- if (ap != NULL)
- memcpy(ap, a, 6);
- }
- return (ap);
-}
-#endif
-
-u_short
-__pcap_nametodnaddr(const char *name)
-{
-#ifdef DECNETLIB
- struct nodeent *getnodebyname();
- struct nodeent *nep;
- unsigned short res;
-
- nep = getnodebyname(name);
- if (nep == ((struct nodeent *)0))
- bpf_error("unknown decnet host name '%s'\n", name);
-
- memcpy((char *)&res, (char *)nep->n_addr, sizeof(unsigned short));
- return(res);
-#else
- bpf_error("decnet name support not included, '%s' cannot be translated\n",
- name);
-#endif
-}
diff --git a/lib/libpcap/optimize.c b/lib/libpcap/optimize.c
deleted file mode 100644
index c198e36..0000000
--- a/lib/libpcap/optimize.c
+++ /dev/null
@@ -1,1924 +0,0 @@
-/*
- * Copyright (c) 1988, 1989, 1990, 1991, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that: (1) source code distributions
- * retain the above copyright notice and this paragraph in its entirety, (2)
- * distributions including binary code include the above copyright notice and
- * this paragraph in its entirety in the documentation or other materials
- * provided with the distribution, and (3) all advertising materials mentioning
- * features or use of this software display the following acknowledgement:
- * ``This product includes software developed by the University of California,
- * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
- * the University nor the names of its contributors may be used to endorse
- * or promote products derived from this software without specific prior
- * written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Optimization module for tcpdump intermediate representation.
- */
-#ifndef lint
-static char rcsid[] =
- "@(#) $Header: /home/ncvs/src/lib/libpcap/optimize.c,v 1.1.1.1 1995/01/20 04:13:03 jkh Exp $ (LBL)";
-#endif
-
-#include <sys/types.h>
-#include <sys/time.h>
-
-#include <net/bpf.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#ifdef __osf__
-#include <stdlib.h>
-#include <malloc.h>
-#endif
-#include <memory.h>
-
-#include "gencode.h"
-
-#ifndef __GNUC__
-#define inline
-#endif
-
-#define A_ATOM BPF_MEMWORDS
-#define X_ATOM (BPF_MEMWORDS+1)
-
-#define NOP -1
-
-/*
- * This define is used to represent *both* the accumulator and
- * x register in use-def computations.
- * Currently, the use-def code assumes only one definition per instruction.
- */
-#define AX_ATOM N_ATOMS
-
-/*
- * A flag to indicate that further optimization is needed.
- * Iterative passes are continued until a given pass yields no
- * branch movement.
- */
-static int done;
-
-/*
- * A block is marked if only if its mark equals the current mark.
- * Rather than traverse the code array, marking each item, 'cur_mark' is
- * incremented. This automatically makes each element unmarked.
- */
-static int cur_mark;
-#define isMarked(p) ((p)->mark == cur_mark)
-#define unMarkAll() cur_mark += 1
-#define Mark(p) ((p)->mark = cur_mark)
-
-static void opt_init(struct block *);
-static void opt_cleanup(void);
-
-static void make_marks(struct block *);
-static void mark_code(struct block *);
-
-static void intern_blocks(struct block *);
-
-static int eq_slist(struct slist *, struct slist *);
-
-static void find_levels_r(struct block *);
-
-static void find_levels(struct block *);
-static void find_dom(struct block *);
-static void propedom(struct edge *);
-static void find_edom(struct block *);
-static void find_closure(struct block *);
-static int atomuse(struct stmt *);
-static int atomdef(struct stmt *);
-static void compute_local_ud(struct block *);
-static void find_ud(struct block *);
-static void init_val(void);
-static long F(int, long, long);
-static inline void vstore(struct stmt *, long *, long, int);
-static void opt_blk(struct block *, int);
-static int use_conflict(struct block *, struct block *);
-static void opt_j(struct edge *);
-static void or_pullup(struct block *);
-static void and_pullup(struct block *);
-static void opt_blks(struct block *, int);
-static inline void link_inedge(struct edge *, struct block *);
-static void find_inedges(struct block *);
-static void opt_root(struct block **);
-static void opt_loop(struct block *, int);
-static void fold_op(struct stmt *, long, long);
-static inline struct slist *this_op(struct slist *);
-static void opt_not(struct block *);
-static void opt_peep(struct block *);
-static void opt_stmt(struct stmt *, long[], int);
-static void deadstmt(struct stmt *, struct stmt *[]);
-static void opt_deadstores(struct block *);
-static void opt_blk(struct block *, int);
-static int use_conflict(struct block *, struct block *);
-static void opt_j(struct edge *);
-static struct block *fold_edge(struct block *, struct edge *);
-static inline int eq_blk(struct block *, struct block *);
-static int slength(struct slist *);
-static int count_blocks(struct block *);
-static void number_blks_r(struct block *);
-static int count_stmts(struct block *);
-static void convert_code_r(struct block *);
-
-static int n_blocks;
-struct block **blocks;
-static int n_edges;
-struct edge **edges;
-
-/*
- * A bit vector set representation of the dominators.
- * We round up the set size to the next power of two.
- */
-static int nodewords;
-static int edgewords;
-struct block **levels;
-u_long *space;
-#define BITS_PER_WORD (8*sizeof(u_long))
-/*
- * True if a is in uset {p}
- */
-#define SET_MEMBER(p, a) \
-((p)[(unsigned)(a) / BITS_PER_WORD] & (1 << ((unsigned)(a) % BITS_PER_WORD)))
-
-/*
- * Add 'a' to uset p.
- */
-#define SET_INSERT(p, a) \
-(p)[(unsigned)(a) / BITS_PER_WORD] |= (1 << ((unsigned)(a) % BITS_PER_WORD))
-
-/*
- * Delete 'a' from uset p.
- */
-#define SET_DELETE(p, a) \
-(p)[(unsigned)(a) / BITS_PER_WORD] &= ~(1 << ((unsigned)(a) % BITS_PER_WORD))
-
-/*
- * a := a intersect b
- */
-#define SET_INTERSECT(a, b, n)\
-{\
- register u_long *_x = a, *_y = b;\
- register int _n = n;\
- while (--_n >= 0) *_x++ &= *_y++;\
-}
-
-/*
- * a := a - b
- */
-#define SET_SUBTRACT(a, b, n)\
-{\
- register u_long *_x = a, *_y = b;\
- register int _n = n;\
- while (--_n >= 0) *_x++ &=~ *_y++;\
-}
-
-/*
- * a := a union b
- */
-#define SET_UNION(a, b, n)\
-{\
- register u_long *_x = a, *_y = b;\
- register int _n = n;\
- while (--_n >= 0) *_x++ |= *_y++;\
-}
-
-static uset all_dom_sets;
-static uset all_closure_sets;
-static uset all_edge_sets;
-
-#ifndef MAX
-#define MAX(a,b) ((a)>(b)?(a):(b))
-#endif
-
-static void
-find_levels_r(b)
- struct block *b;
-{
- int level;
-
- if (isMarked(b))
- return;
-
- Mark(b);
- b->link = 0;
-
- if (JT(b)) {
- find_levels_r(JT(b));
- find_levels_r(JF(b));
- level = MAX(JT(b)->level, JF(b)->level) + 1;
- } else
- level = 0;
- b->level = level;
- b->link = levels[level];
- levels[level] = b;
-}
-
-/*
- * Level graph. The levels go from 0 at the leaves to
- * N_LEVELS at the root. The levels[] array points to the
- * first node of the level list, whose elements are linked
- * with the 'link' field of the struct block.
- */
-static void
-find_levels(root)
- struct block *root;
-{
- memset((char *)levels, 0, n_blocks * sizeof(*levels));
- unMarkAll();
- find_levels_r(root);
-}
-
-/*
- * Find dominator relationships.
- * Assumes graph has been leveled.
- */
-static void
-find_dom(root)
- struct block *root;
-{
- int i;
- struct block *b;
- u_long *x;
-
- /*
- * Initialize sets to contain all nodes.
- */
- x = all_dom_sets;
- i = n_blocks * nodewords;
- while (--i >= 0)
- *x++ = ~0;
- /* Root starts off empty. */
- for (i = nodewords; --i >= 0;)
- root->dom[i] = 0;
-
- /* root->level is the highest level no found. */
- for (i = root->level; i >= 0; --i) {
- for (b = levels[i]; b; b = b->link) {
- SET_INSERT(b->dom, b->id);
- if (JT(b) == 0)
- continue;
- SET_INTERSECT(JT(b)->dom, b->dom, nodewords);
- SET_INTERSECT(JF(b)->dom, b->dom, nodewords);
- }
- }
-}
-
-static void
-propedom(ep)
- struct edge *ep;
-{
- SET_INSERT(ep->edom, ep->id);
- if (ep->succ) {
- SET_INTERSECT(ep->succ->et.edom, ep->edom, edgewords);
- SET_INTERSECT(ep->succ->ef.edom, ep->edom, edgewords);
- }
-}
-
-/*
- * Compute edge dominators.
- * Assumes graph has been leveled and predecessors established.
- */
-static void
-find_edom(root)
- struct block *root;
-{
- int i;
- uset x;
- struct block *b;
-
- x = all_edge_sets;
- for (i = n_edges * edgewords; --i >= 0; )
- x[i] = ~0;
-
- /* root->level is the highest level no found. */
- memset(root->et.edom, 0, edgewords * sizeof(*(uset)0));
- memset(root->ef.edom, 0, edgewords * sizeof(*(uset)0));
- for (i = root->level; i >= 0; --i) {
- for (b = levels[i]; b != 0; b = b->link) {
- propedom(&b->et);
- propedom(&b->ef);
- }
- }
-}
-
-/*
- * Find the backwards transitive closure of the flow graph. These sets
- * are backwards in the sense that we find the set of nodes that reach
- * a given node, not the set of nodes that can be reached by a node.
- *
- * Assumes graph has been leveled.
- */
-static void
-find_closure(root)
- struct block *root;
-{
- int i;
- struct block *b;
-
- /*
- * Initialize sets to contain no nodes.
- */
- memset((char *)all_closure_sets, 0,
- n_blocks * nodewords * sizeof(*all_closure_sets));
-
- /* root->level is the highest level no found. */
- for (i = root->level; i >= 0; --i) {
- for (b = levels[i]; b; b = b->link) {
- SET_INSERT(b->closure, b->id);
- if (JT(b) == 0)
- continue;
- SET_UNION(JT(b)->closure, b->closure, nodewords);
- SET_UNION(JF(b)->closure, b->closure, nodewords);
- }
- }
-}
-
-/*
- * Return the register number that is used by s. If A and X are both
- * used, return AX_ATOM. If no register is used, return -1.
- *
- * The implementation should probably change to an array access.
- */
-static int
-atomuse(s)
- struct stmt *s;
-{
- register int c = s->code;
-
- if (c == NOP)
- return -1;
-
- switch (BPF_CLASS(c)) {
-
- case BPF_RET:
- return (BPF_RVAL(c) == BPF_A) ? A_ATOM :
- (BPF_RVAL(c) == BPF_X) ? X_ATOM : -1;
-
- case BPF_LD:
- case BPF_LDX:
- return (BPF_MODE(c) == BPF_IND) ? X_ATOM :
- (BPF_MODE(c) == BPF_MEM) ? s->k : -1;
-
- case BPF_ST:
- return A_ATOM;
-
- case BPF_STX:
- return X_ATOM;
-
- case BPF_JMP:
- case BPF_ALU:
- if (BPF_SRC(c) == BPF_X)
- return AX_ATOM;
- return A_ATOM;
-
- case BPF_MISC:
- return BPF_MISCOP(c) == BPF_TXA ? X_ATOM : A_ATOM;
- }
- abort();
- /* NOTREACHED */
-}
-
-/*
- * Return the register number that is defined by 's'. We assume that
- * a single stmt cannot define more than one register. If no register
- * is defined, return -1.
- *
- * The implementation should probably change to an array access.
- */
-static int
-atomdef(s)
- struct stmt *s;
-{
- if (s->code == NOP)
- return -1;
-
- switch (BPF_CLASS(s->code)) {
-
- case BPF_LD:
- case BPF_ALU:
- return A_ATOM;
-
- case BPF_LDX:
- return X_ATOM;
-
- case BPF_ST:
- case BPF_STX:
- return s->k;
-
- case BPF_MISC:
- return BPF_MISCOP(s->code) == BPF_TAX ? X_ATOM : A_ATOM;
- }
- return -1;
-}
-
-static void
-compute_local_ud(b)
- struct block *b;
-{
- struct slist *s;
- atomset def = 0, use = 0, kill = 0;
- int atom;
-
- for (s = b->stmts; s; s = s->next) {
- if (s->s.code == NOP)
- continue;
- atom = atomuse(&s->s);
- if (atom >= 0) {
- if (atom == AX_ATOM) {
- if (!ATOMELEM(def, X_ATOM))
- use |= ATOMMASK(X_ATOM);
- if (!ATOMELEM(def, A_ATOM))
- use |= ATOMMASK(A_ATOM);
- }
- else if (atom < N_ATOMS) {
- if (!ATOMELEM(def, atom))
- use |= ATOMMASK(atom);
- }
- else
- abort();
- }
- atom = atomdef(&s->s);
- if (atom >= 0) {
- if (!ATOMELEM(use, atom))
- kill |= ATOMMASK(atom);
- def |= ATOMMASK(atom);
- }
- }
- if (!ATOMELEM(def, A_ATOM) && BPF_CLASS(b->s.code) == BPF_JMP)
- use |= ATOMMASK(A_ATOM);
-
- b->def = def;
- b->kill = kill;
- b->in_use = use;
-}
-
-/*
- * Assume graph is already leveled.
- */
-static void
-find_ud(root)
- struct block *root;
-{
- int i, maxlevel;
- struct block *p;
-
- /*
- * root->level is the highest level no found;
- * count down from there.
- */
- maxlevel = root->level;
- for (i = maxlevel; i >= 0; --i)
- for (p = levels[i]; p; p = p->link) {
- compute_local_ud(p);
- p->out_use = 0;
- }
-
- for (i = 1; i <= maxlevel; ++i) {
- for (p = levels[i]; p; p = p->link) {
- p->out_use |= JT(p)->in_use | JF(p)->in_use;
- p->in_use |= p->out_use &~ p->kill;
- }
- }
-}
-
-/*
- * These data structures are used in a Cocke and Shwarz style
- * value numbering scheme. Since the flowgraph is acyclic,
- * exit values can be propagated from a node's predecessors
- * provided it is uniquely defined.
- */
-struct valnode {
- int code;
- long v0, v1;
- long val;
- struct valnode *next;
-};
-
-#define MODULUS 213
-static struct valnode *hashtbl[MODULUS];
-static int curval;
-static int maxval;
-
-/* Integer constants mapped with the load immediate opcode. */
-#define K(i) F(BPF_LD|BPF_IMM|BPF_W, i, 0L)
-
-struct vmapinfo {
- int is_const;
- long const_val;
-};
-
-struct vmapinfo *vmap;
-struct valnode *vnode_base;
-struct valnode *next_vnode;
-
-static void
-init_val()
-{
- curval = 0;
- next_vnode = vnode_base;
- memset((char *)vmap, 0, maxval * sizeof(*vmap));
- memset((char *)hashtbl, 0, sizeof hashtbl);
-}
-
-/* Because we really don't have an IR, this stuff is a little messy. */
-static long
-F(code, v0, v1)
- int code;
- long v0, v1;
-{
- u_int hash;
- int val;
- struct valnode *p;
-
- hash = (u_int)code ^ (v0 << 4) ^ (v1 << 8);
- hash %= MODULUS;
-
- for (p = hashtbl[hash]; p; p = p->next)
- if (p->code == code && p->v0 == v0 && p->v1 == v1)
- return p->val;
-
- val = ++curval;
- if (BPF_MODE(code) == BPF_IMM &&
- (BPF_CLASS(code) == BPF_LD || BPF_CLASS(code) == BPF_LDX)) {
- vmap[val].const_val = v0;
- vmap[val].is_const = 1;
- }
- p = next_vnode++;
- p->val = val;
- p->code = code;
- p->v0 = v0;
- p->v1 = v1;
- p->next = hashtbl[hash];
- hashtbl[hash] = p;
-
- return val;
-}
-
-static inline void
-vstore(s, valp, newval, alter)
- struct stmt *s;
- long *valp;
- long newval;
- int alter;
-{
- if (alter && *valp == newval)
- s->code = NOP;
- else
- *valp = newval;
-}
-
-static void
-fold_op(s, v0, v1)
- struct stmt *s;
- long v0, v1;
-{
- long a, b;
-
- a = vmap[v0].const_val;
- b = vmap[v1].const_val;
-
- switch (BPF_OP(s->code)) {
- case BPF_ADD:
- a += b;
- break;
-
- case BPF_SUB:
- a -= b;
- break;
-
- case BPF_MUL:
- a *= b;
- break;
-
- case BPF_DIV:
- if (b == 0)
- bpf_error("division by zero");
- a /= b;
- break;
-
- case BPF_AND:
- a &= b;
- break;
-
- case BPF_OR:
- a |= b;
- break;
-
- case BPF_LSH:
- a <<= b;
- break;
-
- case BPF_RSH:
- a >>= b;
- break;
-
- case BPF_NEG:
- a = -a;
- break;
-
- default:
- abort();
- }
- s->k = a;
- s->code = BPF_LD|BPF_IMM;
- done = 0;
-}
-
-static inline struct slist *
-this_op(s)
- struct slist *s;
-{
- while (s != 0 && s->s.code == NOP)
- s = s->next;
- return s;
-}
-
-static void
-opt_not(b)
- struct block *b;
-{
- struct block *tmp = JT(b);
-
- JT(b) = JF(b);
- JF(b) = tmp;
-}
-
-static void
-opt_peep(b)
- struct block *b;
-{
- struct slist *s;
- struct slist *next, *last;
- int val;
- long v;
-
- s = b->stmts;
- if (s == 0)
- return;
-
- last = s;
- while (1) {
- s = this_op(s);
- if (s == 0)
- break;
- next = this_op(s->next);
- if (next == 0)
- break;
- last = next;
-
- /*
- * st M[k] --> st M[k]
- * ldx M[k] tax
- */
- if (s->s.code == BPF_ST &&
- next->s.code == (BPF_LDX|BPF_MEM) &&
- s->s.k == next->s.k) {
- done = 0;
- next->s.code = BPF_MISC|BPF_TAX;
- }
- /*
- * ld #k --> ldx #k
- * tax txa
- */
- if (s->s.code == (BPF_LD|BPF_IMM) &&
- next->s.code == (BPF_MISC|BPF_TAX)) {
- s->s.code = BPF_LDX|BPF_IMM;
- next->s.code = BPF_MISC|BPF_TXA;
- done = 0;
- }
- /*
- * This is an ugly special case, but it happens
- * when you say tcp[k] or udp[k] where k is a constant.
- */
- if (s->s.code == (BPF_LD|BPF_IMM)) {
- struct slist *add, *tax, *ild;
-
- /*
- * Check that X isn't used on exit from this
- * block (which the optimizer might cause).
- * We know the code generator won't generate
- * any local dependencies.
- */
- if (ATOMELEM(b->out_use, X_ATOM))
- break;
-
- if (next->s.code != (BPF_LDX|BPF_MSH|BPF_B))
- add = next;
- else
- add = this_op(next->next);
- if (add == 0 || add->s.code != (BPF_ALU|BPF_ADD|BPF_X))
- break;
-
- tax = this_op(add->next);
- if (tax == 0 || tax->s.code != (BPF_MISC|BPF_TAX))
- break;
-
- ild = this_op(tax->next);
- if (ild == 0 || BPF_CLASS(ild->s.code) != BPF_LD ||
- BPF_MODE(ild->s.code) != BPF_IND)
- break;
- /*
- * XXX We need to check that X is not
- * subsequently used. We know we can eliminate the
- * accumulator modifications since it is defined
- * by the last stmt of this sequence.
- *
- * We want to turn this sequence:
- *
- * (004) ldi #0x2 {s}
- * (005) ldxms [14] {next} -- optional
- * (006) addx {add}
- * (007) tax {tax}
- * (008) ild [x+0] {ild}
- *
- * into this sequence:
- *
- * (004) nop
- * (005) ldxms [14]
- * (006) nop
- * (007) nop
- * (008) ild [x+2]
- *
- */
- ild->s.k += s->s.k;
- s->s.code = NOP;
- add->s.code = NOP;
- tax->s.code = NOP;
- done = 0;
- }
- s = next;
- }
- /*
- * If we have a subtract to do a comparison, and the X register
- * is a known constant, we can merge this value into the
- * comparison.
- */
- if (last->s.code == (BPF_ALU|BPF_SUB|BPF_X) &&
- !ATOMELEM(b->out_use, A_ATOM)) {
- val = b->val[X_ATOM];
- if (vmap[val].is_const) {
- b->s.k += vmap[val].const_val;
- last->s.code = NOP;
- done = 0;
- } else if (b->s.k == 0) {
- /*
- * sub x -> nop
- * j #0 j x
- */
- last->s.code = NOP;
- b->s.code = BPF_CLASS(b->s.code) | BPF_OP(b->s.code) |
- BPF_X;
- done = 0;
- }
- }
- /*
- * Likewise, a constant subtract can be simplified.
- */
- else if (last->s.code == (BPF_ALU|BPF_SUB|BPF_K) &&
- !ATOMELEM(b->out_use, A_ATOM)) {
- b->s.k += last->s.k;
- last->s.code = NOP;
- done = 0;
- }
- /*
- * and #k nop
- * jeq #0 -> jset #k
- */
- if (last->s.code == (BPF_ALU|BPF_AND|BPF_K) &&
- !ATOMELEM(b->out_use, A_ATOM) && b->s.k == 0) {
- b->s.k = last->s.k;
- b->s.code = BPF_JMP|BPF_K|BPF_JSET;
- last->s.code = NOP;
- done = 0;
- opt_not(b);
- }
- /*
- * If the accumulator is a known constant, we can compute the
- * comparison result.
- */
- val = b->val[A_ATOM];
- if (vmap[val].is_const && BPF_SRC(b->s.code) == BPF_K) {
- v = vmap[val].const_val;
- switch (BPF_OP(b->s.code)) {
-
- case BPF_JEQ:
- v = v == b->s.k;
- break;
-
- case BPF_JGT:
- v = v > b->s.k;
- break;
-
- case BPF_JGE:
- v = v >= b->s.k;
- break;
-
- case BPF_JSET:
- v &= b->s.k;
- break;
-
- default:
- abort();
- }
- if (JF(b) != JT(b))
- done = 0;
- if (v)
- JF(b) = JT(b);
- else
- JT(b) = JF(b);
- }
-}
-
-/*
- * Compute the symbolic value of expression of 's', and update
- * anything it defines in the value table 'val'. If 'alter' is true,
- * do various optimizations. This code would be cleaner if symbolic
- * evaluation and code transformations weren't folded together.
- */
-static void
-opt_stmt(s, val, alter)
- struct stmt *s;
- long val[];
- int alter;
-{
- int op;
- long v;
-
- switch (s->code) {
-
- case BPF_LD|BPF_ABS|BPF_W:
- case BPF_LD|BPF_ABS|BPF_H:
- case BPF_LD|BPF_ABS|BPF_B:
- v = F(s->code, s->k, 0L);
- vstore(s, &val[A_ATOM], v, alter);
- break;
-
- case BPF_LD|BPF_IND|BPF_W:
- case BPF_LD|BPF_IND|BPF_H:
- case BPF_LD|BPF_IND|BPF_B:
- v = val[X_ATOM];
- if (alter && vmap[v].is_const) {
- s->code = BPF_LD|BPF_ABS|BPF_SIZE(s->code);
- s->k += vmap[v].const_val;
- v = F(s->code, s->k, 0L);
- done = 0;
- }
- else
- v = F(s->code, s->k, v);
- vstore(s, &val[A_ATOM], v, alter);
- break;
-
- case BPF_LD|BPF_LEN:
- v = F(s->code, 0L, 0L);
- vstore(s, &val[A_ATOM], v, alter);
- break;
-
- case BPF_LD|BPF_IMM:
- v = K(s->k);
- vstore(s, &val[A_ATOM], v, alter);
- break;
-
- case BPF_LDX|BPF_IMM:
- v = K(s->k);
- vstore(s, &val[X_ATOM], v, alter);
- break;
-
- case BPF_LDX|BPF_MSH|BPF_B:
- v = F(s->code, s->k, 0L);
- vstore(s, &val[X_ATOM], v, alter);
- break;
-
- case BPF_ALU|BPF_NEG:
- if (alter && vmap[val[A_ATOM]].is_const) {
- s->code = BPF_LD|BPF_IMM;
- s->k = -vmap[val[A_ATOM]].const_val;
- val[A_ATOM] = K(s->k);
- }
- else
- val[A_ATOM] = F(s->code, val[A_ATOM], 0L);
- break;
-
- case BPF_ALU|BPF_ADD|BPF_K:
- case BPF_ALU|BPF_SUB|BPF_K:
- case BPF_ALU|BPF_MUL|BPF_K:
- case BPF_ALU|BPF_DIV|BPF_K:
- case BPF_ALU|BPF_AND|BPF_K:
- case BPF_ALU|BPF_OR|BPF_K:
- case BPF_ALU|BPF_LSH|BPF_K:
- case BPF_ALU|BPF_RSH|BPF_K:
- op = BPF_OP(s->code);
- if (alter) {
- if (s->k == 0) {
- if (op == BPF_ADD || op == BPF_SUB ||
- op == BPF_LSH || op == BPF_RSH ||
- op == BPF_OR) {
- s->code = NOP;
- break;
- }
- if (op == BPF_MUL || op == BPF_AND) {
- s->code = BPF_LD|BPF_IMM;
- val[A_ATOM] = K(s->k);
- break;
- }
- }
- if (vmap[val[A_ATOM]].is_const) {
- fold_op(s, val[A_ATOM], K(s->k));
- val[A_ATOM] = K(s->k);
- break;
- }
- }
- val[A_ATOM] = F(s->code, val[A_ATOM], K(s->k));
- break;
-
- case BPF_ALU|BPF_ADD|BPF_X:
- case BPF_ALU|BPF_SUB|BPF_X:
- case BPF_ALU|BPF_MUL|BPF_X:
- case BPF_ALU|BPF_DIV|BPF_X:
- case BPF_ALU|BPF_AND|BPF_X:
- case BPF_ALU|BPF_OR|BPF_X:
- case BPF_ALU|BPF_LSH|BPF_X:
- case BPF_ALU|BPF_RSH|BPF_X:
- op = BPF_OP(s->code);
- if (alter && vmap[val[X_ATOM]].is_const) {
- if (vmap[val[A_ATOM]].is_const) {
- fold_op(s, val[A_ATOM], val[X_ATOM]);
- val[A_ATOM] = K(s->k);
- }
- else {
- s->code = BPF_ALU|BPF_K|op;
- s->k = vmap[val[X_ATOM]].const_val;
- done = 0;
- val[A_ATOM] =
- F(s->code, val[A_ATOM], K(s->k));
- }
- break;
- }
- /*
- * Check if we're doing something to an accumulator
- * that is 0, and simplify. This may not seem like
- * much of a simplification but it could open up further
- * optimizations.
- * XXX We could also check for mul by 1, and -1, etc.
- */
- if (alter && vmap[val[A_ATOM]].is_const
- && vmap[val[A_ATOM]].const_val == 0) {
- if (op == BPF_ADD || op == BPF_OR ||
- op == BPF_LSH || op == BPF_RSH || op == BPF_SUB) {
- s->code = BPF_MISC|BPF_TXA;
- vstore(s, &val[A_ATOM], val[X_ATOM], alter);
- break;
- }
- else if (op == BPF_MUL || op == BPF_DIV ||
- op == BPF_AND) {
- s->code = BPF_LD|BPF_IMM;
- s->k = 0;
- vstore(s, &val[A_ATOM], K(s->k), alter);
- break;
- }
- else if (op == BPF_NEG) {
- s->code = NOP;
- break;
- }
- }
- val[A_ATOM] = F(s->code, val[A_ATOM], val[X_ATOM]);
- break;
-
- case BPF_MISC|BPF_TXA:
- vstore(s, &val[A_ATOM], val[X_ATOM], alter);
- break;
-
- case BPF_LD|BPF_MEM:
- v = val[s->k];
- if (alter && vmap[v].is_const) {
- s->code = BPF_LD|BPF_IMM;
- s->k = vmap[v].const_val;
- done = 0;
- }
- vstore(s, &val[A_ATOM], v, alter);
- break;
-
- case BPF_MISC|BPF_TAX:
- vstore(s, &val[X_ATOM], val[A_ATOM], alter);
- break;
-
- case BPF_LDX|BPF_MEM:
- v = val[s->k];
- if (alter && vmap[v].is_const) {
- s->code = BPF_LDX|BPF_IMM;
- s->k = vmap[v].const_val;
- done = 0;
- }
- vstore(s, &val[X_ATOM], v, alter);
- break;
-
- case BPF_ST:
- vstore(s, &val[s->k], val[A_ATOM], alter);
- break;
-
- case BPF_STX:
- vstore(s, &val[s->k], val[X_ATOM], alter);
- break;
- }
-}
-
-static void
-deadstmt(s, last)
- register struct stmt *s;
- register struct stmt *last[];
-{
- register int atom;
-
- atom = atomuse(s);
- if (atom >= 0) {
- if (atom == AX_ATOM) {
- last[X_ATOM] = 0;
- last[A_ATOM] = 0;
- }
- else
- last[atom] = 0;
- }
- atom = atomdef(s);
- if (atom >= 0) {
- if (last[atom]) {
- done = 0;
- last[atom]->code = NOP;
- }
- last[atom] = s;
- }
-}
-
-static void
-opt_deadstores(b)
- register struct block *b;
-{
- register struct slist *s;
- register int atom;
- struct stmt *last[N_ATOMS];
-
- memset((char *)last, 0, sizeof last);
-
- for (s = b->stmts; s != 0; s = s->next)
- deadstmt(&s->s, last);
- deadstmt(&b->s, last);
-
- for (atom = 0; atom < N_ATOMS; ++atom)
- if (last[atom] && !ATOMELEM(b->out_use, atom)) {
- last[atom]->code = NOP;
- done = 0;
- }
-}
-
-static void
-opt_blk(b, do_stmts)
- struct block *b;
- int do_stmts;
-{
- struct slist *s;
- struct edge *p;
- int i;
- long aval;
-
- /*
- * Initialize the atom values.
- * If we have no predecessors, everything is undefined.
- * Otherwise, we inherent our values from our predecessors.
- * If any register has an ambiguous value (i.e. control paths are
- * merging) give it the undefined value of 0.
- */
- p = b->in_edges;
- if (p == 0)
- memset((char *)b->val, 0, sizeof(b->val));
- else {
- memcpy((char *)b->val, (char *)p->pred->val, sizeof(b->val));
- while ((p = p->next) != NULL) {
- for (i = 0; i < N_ATOMS; ++i)
- if (b->val[i] != p->pred->val[i])
- b->val[i] = 0;
- }
- }
- aval = b->val[A_ATOM];
- for (s = b->stmts; s; s = s->next)
- opt_stmt(&s->s, b->val, do_stmts);
-
- /*
- * This is a special case: if we don't use anything from this
- * block, and we load the accumulator with value that is
- * already there, eliminate all the statements.
- */
- if (do_stmts && b->out_use == 0 && aval != 0 &&
- b->val[A_ATOM] == aval)
- b->stmts = 0;
- else {
- opt_peep(b);
- opt_deadstores(b);
- }
- /*
- * Set up values for branch optimizer.
- */
- if (BPF_SRC(b->s.code) == BPF_K)
- b->oval = K(b->s.k);
- else
- b->oval = b->val[X_ATOM];
- b->et.code = b->s.code;
- b->ef.code = -b->s.code;
-}
-
-/*
- * Return true if any register that is used on exit from 'succ', has
- * an exit value that is different from the corresponding exit value
- * from 'b'.
- */
-static int
-use_conflict(b, succ)
- struct block *b, *succ;
-{
- int atom;
- atomset use = succ->out_use;
-
- if (use == 0)
- return 0;
-
- for (atom = 0; atom < N_ATOMS; ++atom)
- if (ATOMELEM(use, atom))
- if (b->val[atom] != succ->val[atom])
- return 1;
- return 0;
-}
-
-static struct block *
-fold_edge(child, ep)
- struct block *child;
- struct edge *ep;
-{
- int sense;
- int aval0, aval1, oval0, oval1;
- int code = ep->code;
-
- if (code < 0) {
- code = -code;
- sense = 0;
- } else
- sense = 1;
-
- if (child->s.code != code)
- return 0;
-
- aval0 = child->val[A_ATOM];
- oval0 = child->oval;
- aval1 = ep->pred->val[A_ATOM];
- oval1 = ep->pred->oval;
-
- if (aval0 != aval1)
- return 0;
-
- if (oval0 == oval1)
- /*
- * The operands are identical, so the
- * result is true if a true branch was
- * taken to get here, otherwise false.
- */
- return sense ? JT(child) : JF(child);
-
- if (sense && code == (BPF_JMP|BPF_JEQ|BPF_K))
- /*
- * At this point, we only know the comparison if we
- * came down the true branch, and it was an equality
- * comparison with a constant. We rely on the fact that
- * distinct constants have distinct value numbers.
- */
- return JF(child);
-
- return 0;
-}
-
-static void
-opt_j(ep)
- struct edge *ep;
-{
- register int i, k;
- register struct block *target;
-
- if (JT(ep->succ) == 0)
- return;
-
- if (JT(ep->succ) == JF(ep->succ)) {
- /*
- * Common branch targets can be eliminated, provided
- * there is no data dependency.
- */
- if (!use_conflict(ep->pred, ep->succ->et.succ)) {
- done = 0;
- ep->succ = JT(ep->succ);
- }
- }
- /*
- * For each edge dominator that matches the successor of this
- * edge, promote the edge successor to the its grandchild.
- *
- * XXX We violate the set abstraction here in favor a reasonably
- * efficient loop.
- */
- top:
- for (i = 0; i < edgewords; ++i) {
- register u_long x = ep->edom[i];
-
- while (x != 0) {
- k = ffs(x) - 1;
- x &=~ (1 << k);
- k += i * BITS_PER_WORD;
-
- target = fold_edge(ep->succ, edges[k]);
- /*
- * Check that there is no data dependency between
- * nodes that will be violated if we move the edge.
- */
- if (target != 0 && !use_conflict(ep->pred, target)) {
- done = 0;
- ep->succ = target;
- if (JT(target) != 0)
- /*
- * Start over unless we hit a leaf.
- */
- goto top;
- return;
- }
- }
- }
-}
-
-
-static void
-or_pullup(b)
- struct block *b;
-{
- int val, at_top;
- struct block *pull;
- struct block **diffp, **samep;
- struct edge *ep;
-
- ep = b->in_edges;
- if (ep == 0)
- return;
-
- /*
- * Make sure each predecessor loads the same value.
- * XXX why?
- */
- val = ep->pred->val[A_ATOM];
- for (ep = ep->next; ep != 0; ep = ep->next)
- if (val != ep->pred->val[A_ATOM])
- return;
-
- if (JT(b->in_edges->pred) == b)
- diffp = &JT(b->in_edges->pred);
- else
- diffp = &JF(b->in_edges->pred);
-
- at_top = 1;
- while (1) {
- if (*diffp == 0)
- return;
-
- if (JT(*diffp) != JT(b))
- return;
-
- if (!SET_MEMBER((*diffp)->dom, b->id))
- return;
-
- if ((*diffp)->val[A_ATOM] != val)
- break;
-
- diffp = &JF(*diffp);
- at_top = 0;
- }
- samep = &JF(*diffp);
- while (1) {
- if (*samep == 0)
- return;
-
- if (JT(*samep) != JT(b))
- return;
-
- if (!SET_MEMBER((*samep)->dom, b->id))
- return;
-
- if ((*samep)->val[A_ATOM] == val)
- break;
-
- /* XXX Need to check that there are no data dependencies
- between dp0 and dp1. Currently, the code generator
- will not produce such dependencies. */
- samep = &JF(*samep);
- }
-#ifdef notdef
- /* XXX This doesn't cover everything. */
- for (i = 0; i < N_ATOMS; ++i)
- if ((*samep)->val[i] != pred->val[i])
- return;
-#endif
- /* Pull up the node. */
- pull = *samep;
- *samep = JF(pull);
- JF(pull) = *diffp;
-
- /*
- * At the top of the chain, each predecessor needs to point at the
- * pulled up node. Inside the chain, there is only one predecessor
- * to worry about.
- */
- if (at_top) {
- for (ep = b->in_edges; ep != 0; ep = ep->next) {
- if (JT(ep->pred) == b)
- JT(ep->pred) = pull;
- else
- JF(ep->pred) = pull;
- }
- }
- else
- *diffp = pull;
-
- done = 0;
-}
-
-static void
-and_pullup(b)
- struct block *b;
-{
- int val, at_top;
- struct block *pull;
- struct block **diffp, **samep;
- struct edge *ep;
-
- ep = b->in_edges;
- if (ep == 0)
- return;
-
- /*
- * Make sure each predecessor loads the same value.
- */
- val = ep->pred->val[A_ATOM];
- for (ep = ep->next; ep != 0; ep = ep->next)
- if (val != ep->pred->val[A_ATOM])
- return;
-
- if (JT(b->in_edges->pred) == b)
- diffp = &JT(b->in_edges->pred);
- else
- diffp = &JF(b->in_edges->pred);
-
- at_top = 1;
- while (1) {
- if (*diffp == 0)
- return;
-
- if (JF(*diffp) != JF(b))
- return;
-
- if (!SET_MEMBER((*diffp)->dom, b->id))
- return;
-
- if ((*diffp)->val[A_ATOM] != val)
- break;
-
- diffp = &JT(*diffp);
- at_top = 0;
- }
- samep = &JT(*diffp);
- while (1) {
- if (*samep == 0)
- return;
-
- if (JF(*samep) != JF(b))
- return;
-
- if (!SET_MEMBER((*samep)->dom, b->id))
- return;
-
- if ((*samep)->val[A_ATOM] == val)
- break;
-
- /* XXX Need to check that there are no data dependencies
- between diffp and samep. Currently, the code generator
- will not produce such dependencies. */
- samep = &JT(*samep);
- }
-#ifdef notdef
- /* XXX This doesn't cover everything. */
- for (i = 0; i < N_ATOMS; ++i)
- if ((*samep)->val[i] != pred->val[i])
- return;
-#endif
- /* Pull up the node. */
- pull = *samep;
- *samep = JT(pull);
- JT(pull) = *diffp;
-
- /*
- * At the top of the chain, each predecessor needs to point at the
- * pulled up node. Inside the chain, there is only one predecessor
- * to worry about.
- */
- if (at_top) {
- for (ep = b->in_edges; ep != 0; ep = ep->next) {
- if (JT(ep->pred) == b)
- JT(ep->pred) = pull;
- else
- JF(ep->pred) = pull;
- }
- }
- else
- *diffp = pull;
-
- done = 0;
-}
-
-static void
-opt_blks(root, do_stmts)
- struct block *root;
- int do_stmts;
-{
- int i, maxlevel;
- struct block *p;
-
- init_val();
- maxlevel = root->level;
- for (i = maxlevel; i >= 0; --i)
- for (p = levels[i]; p; p = p->link)
- opt_blk(p, do_stmts);
-
- if (do_stmts)
- /*
- * No point trying to move branches; it can't possibly
- * make a difference at this point.
- */
- return;
-
- for (i = 1; i <= maxlevel; ++i) {
- for (p = levels[i]; p; p = p->link) {
- opt_j(&p->et);
- opt_j(&p->ef);
- }
- }
- for (i = 1; i <= maxlevel; ++i) {
- for (p = levels[i]; p; p = p->link) {
- or_pullup(p);
- and_pullup(p);
- }
- }
-}
-
-static inline void
-link_inedge(parent, child)
- struct edge *parent;
- struct block *child;
-{
- parent->next = child->in_edges;
- child->in_edges = parent;
-}
-
-static void
-find_inedges(root)
- struct block *root;
-{
- int i;
- struct block *b;
-
- for (i = 0; i < n_blocks; ++i)
- blocks[i]->in_edges = 0;
-
- /*
- * Traverse the graph, adding each edge to the predecessor
- * list of its successors. Skip the leaves (i.e. level 0).
- */
- for (i = root->level; i > 0; --i) {
- for (b = levels[i]; b != 0; b = b->link) {
- link_inedge(&b->et, JT(b));
- link_inedge(&b->ef, JF(b));
- }
- }
-}
-
-static void
-opt_root(b)
- struct block **b;
-{
- struct slist *tmp, *s;
-
- s = (*b)->stmts;
- (*b)->stmts = 0;
- while (BPF_CLASS((*b)->s.code) == BPF_JMP && JT(*b) == JF(*b))
- *b = JT(*b);
-
- tmp = (*b)->stmts;
- if (tmp != 0)
- sappend(s, tmp);
- (*b)->stmts = s;
-}
-
-static void
-opt_loop(root, do_stmts)
- struct block *root;
- int do_stmts;
-{
-
-#ifdef BDEBUG
- if (dflag > 1)
- opt_dump(root);
-#endif
- do {
- done = 1;
- find_levels(root);
- find_dom(root);
- find_closure(root);
- find_inedges(root);
- find_ud(root);
- find_edom(root);
- opt_blks(root, do_stmts);
-#ifdef BDEBUG
- if (dflag > 1)
- opt_dump(root);
-#endif
- } while (!done);
-}
-
-/*
- * Optimize the filter code in its dag representation.
- */
-void
-bpf_optimize(rootp)
- struct block **rootp;
-{
- struct block *root;
-
- root = *rootp;
-
- opt_init(root);
- opt_loop(root, 0);
- opt_loop(root, 1);
- intern_blocks(root);
- opt_root(rootp);
- opt_cleanup();
-}
-
-static void
-make_marks(p)
- struct block *p;
-{
- if (!isMarked(p)) {
- Mark(p);
- if (BPF_CLASS(p->s.code) != BPF_RET) {
- make_marks(JT(p));
- make_marks(JF(p));
- }
- }
-}
-
-/*
- * Mark code array such that isMarked(i) is true
- * only for nodes that are alive.
- */
-static void
-mark_code(p)
- struct block *p;
-{
- cur_mark += 1;
- make_marks(p);
-}
-
-/*
- * True iff the two stmt lists load the same value from the packet into
- * the accumulator.
- */
-static int
-eq_slist(x, y)
- struct slist *x, *y;
-{
- while (1) {
- while (x && x->s.code == NOP)
- x = x->next;
- while (y && y->s.code == NOP)
- y = y->next;
- if (x == 0)
- return y == 0;
- if (y == 0)
- return x == 0;
- if (x->s.code != y->s.code || x->s.k != y->s.k)
- return 0;
- x = x->next;
- y = y->next;
- }
-}
-
-static inline int
-eq_blk(b0, b1)
- struct block *b0, *b1;
-{
- if (b0->s.code == b1->s.code &&
- b0->s.k == b1->s.k &&
- b0->et.succ == b1->et.succ &&
- b0->ef.succ == b1->ef.succ)
- return eq_slist(b0->stmts, b1->stmts);
- return 0;
-}
-
-static void
-intern_blocks(root)
- struct block *root;
-{
- struct block *p;
- int i, j;
- int done;
- top:
- done = 1;
- for (i = 0; i < n_blocks; ++i)
- blocks[i]->link = 0;
-
- mark_code(root);
-
- for (i = n_blocks - 1; --i >= 0; ) {
- if (!isMarked(blocks[i]))
- continue;
- for (j = i + 1; j < n_blocks; ++j) {
- if (!isMarked(blocks[j]))
- continue;
- if (eq_blk(blocks[i], blocks[j])) {
- blocks[i]->link = blocks[j]->link ?
- blocks[j]->link : blocks[j];
- break;
- }
- }
- }
- for (i = 0; i < n_blocks; ++i) {
- p = blocks[i];
- if (JT(p) == 0)
- continue;
- if (JT(p)->link) {
- done = 0;
- JT(p) = JT(p)->link;
- }
- if (JF(p)->link) {
- done = 0;
- JF(p) = JF(p)->link;
- }
- }
- if (!done)
- goto top;
-}
-
-static void
-opt_cleanup()
-{
- free((void *)vnode_base);
- free((void *)vmap);
- free((void *)edges);
- free((void *)space);
- free((void *)levels);
- free((void *)blocks);
-}
-
-/*
- * Return the number of stmts in 's'.
- */
-static int
-slength(s)
- struct slist *s;
-{
- int n = 0;
-
- for (; s; s = s->next)
- if (s->s.code != NOP)
- ++n;
- return n;
-}
-
-/*
- * Return the number of nodes reachable by 'p'.
- * All nodes should be initially unmarked.
- */
-static int
-count_blocks(p)
- struct block *p;
-{
- if (p == 0 || isMarked(p))
- return 0;
- Mark(p);
- return count_blocks(JT(p)) + count_blocks(JF(p)) + 1;
-}
-
-/*
- * Do a depth first search on the flow graph, numbering the
- * the basic blocks, and entering them into the 'blocks' array.`
- */
-static void
-number_blks_r(p)
- struct block *p;
-{
- int n;
-
- if (p == 0 || isMarked(p))
- return;
-
- Mark(p);
- n = n_blocks++;
- p->id = n;
- blocks[n] = p;
-
- number_blks_r(JT(p));
- number_blks_r(JF(p));
-}
-
-/*
- * Return the number of stmts in the flowgraph reachable by 'p'.
- * The nodes should be unmarked before calling.
- */
-static int
-count_stmts(p)
- struct block *p;
-{
- int n;
-
- if (p == 0 || isMarked(p))
- return 0;
- Mark(p);
- n = count_stmts(JT(p)) + count_stmts(JF(p));
- return slength(p->stmts) + n + 1;
-}
-
-/*
- * Allocate memory. All allocation is done before optimization
- * is begun. A linear bound on the size of all data structures is computed
- * from the total number of blocks and/or statements.
- */
-static void
-opt_init(root)
- struct block *root;
-{
- u_long *p;
- int i, n, max_stmts;
-
- /*
- * First, count the blocks, so we can malloc an array to map
- * block number to block. Then, put the blocks into the array.
- */
- unMarkAll();
- n = count_blocks(root);
- blocks = (struct block **)malloc(n * sizeof(*blocks));
- unMarkAll();
- n_blocks = 0;
- number_blks_r(root);
-
- n_edges = 2 * n_blocks;
- edges = (struct edge **)malloc(n_edges * sizeof(*edges));
-
- /*
- * The number of levels is bounded by the number of nodes.
- */
- levels = (struct block **)malloc(n_blocks * sizeof(*levels));
-
- edgewords = n_edges / (8 * sizeof(u_long)) + 1;
- nodewords = n_blocks / (8 * sizeof(u_long)) + 1;
-
- /* XXX */
- space = (u_long *)malloc(2 * n_blocks * nodewords * sizeof(*space)
- + n_edges * edgewords * sizeof(*space));
- p = space;
- all_dom_sets = p;
- for (i = 0; i < n; ++i) {
- blocks[i]->dom = p;
- p += nodewords;
- }
- all_closure_sets = p;
- for (i = 0; i < n; ++i) {
- blocks[i]->closure = p;
- p += nodewords;
- }
- all_edge_sets = p;
- for (i = 0; i < n; ++i) {
- register struct block *b = blocks[i];
-
- b->et.edom = p;
- p += edgewords;
- b->ef.edom = p;
- p += edgewords;
- b->et.id = i;
- edges[i] = &b->et;
- b->ef.id = n_blocks + i;
- edges[n_blocks + i] = &b->ef;
- b->et.pred = b;
- b->ef.pred = b;
- }
- max_stmts = 0;
- for (i = 0; i < n; ++i)
- max_stmts += slength(blocks[i]->stmts) + 1;
- /*
- * We allocate at most 3 value numbers per statement,
- * so this is an upper bound on the number of valnodes
- * we'll need.
- */
- maxval = 3 * max_stmts;
- vmap = (struct vmapinfo *)malloc(maxval * sizeof(*vmap));
- vnode_base = (struct valnode *)malloc(maxval * sizeof(*vmap));
-}
-
-/*
- * Some pointers used to convert the basic block form of the code,
- * into the array form that BPF requires. 'fstart' will point to
- * the malloc'd array while 'ftail' is used during the recursive traversal.
- */
-static struct bpf_insn *fstart;
-static struct bpf_insn *ftail;
-
-#ifdef BDEBUG
-int bids[1000];
-#endif
-
-static void
-convert_code_r(p)
- struct block *p;
-{
- struct bpf_insn *dst;
- struct slist *src;
- int slen;
- u_int off;
-
- if (p == 0 || isMarked(p))
- return;
- Mark(p);
-
- convert_code_r(JF(p));
- convert_code_r(JT(p));
-
- slen = slength(p->stmts);
- dst = ftail -= slen + 1;
-
- p->offset = dst - fstart;
-
- for (src = p->stmts; src; src = src->next) {
- if (src->s.code == NOP)
- continue;
- dst->code = (u_short)src->s.code;
- dst->k = src->s.k;
- ++dst;
- }
-#ifdef BDEBUG
- bids[dst - fstart] = p->id + 1;
-#endif
- dst->code = (u_short)p->s.code;
- dst->k = p->s.k;
- if (JT(p)) {
- off = JT(p)->offset - (p->offset + slen) - 1;
- if (off >= 256)
- bpf_error("long jumps not supported");
- dst->jt = off;
- off = JF(p)->offset - (p->offset + slen) - 1;
- if (off >= 256)
- bpf_error("long jumps not supported");
- dst->jf = off;
- }
-}
-
-
-/*
- * Convert flowgraph intermediate representation to the
- * BPF array representation. Set *lenp to the number of instructions.
- */
-struct bpf_insn *
-icode_to_fcode(root, lenp)
- struct block *root;
- int *lenp;
-{
- int n;
- struct bpf_insn *fp;
-
- unMarkAll();
- n = *lenp = count_stmts(root);
-
- fp = (struct bpf_insn *)malloc(sizeof(*fp) * n);
- memset((char *)fp, 0, sizeof(*fp) * n);
- fstart = fp;
- ftail = fp + n;
-
- unMarkAll();
- convert_code_r(root);
-
- return fp;
-}
-
-#ifdef BDEBUG
-opt_dump(root)
- struct block *root;
-{
- struct bpf_program f;
-
- memset(bids, 0, sizeof bids);
- f.bf_insns = icode_to_fcode(root, &f.bf_len);
- bpf_dump(&f, 1);
- putchar('\n');
- free((char *)f.bf_insns);
-}
-#endif
diff --git a/lib/libpcap/pcap-bpf.c b/lib/libpcap/pcap-bpf.c
deleted file mode 100644
index b576f04..0000000
--- a/lib/libpcap/pcap-bpf.c
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * Copyright (c) 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that: (1) source code distributions
- * retain the above copyright notice and this paragraph in its entirety, (2)
- * distributions including binary code include the above copyright notice and
- * this paragraph in its entirety in the documentation or other materials
- * provided with the distribution, and (3) all advertising materials mentioning
- * features or use of this software display the following acknowledgement:
- * ``This product includes software developed by the University of California,
- * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
- * the University nor the names of its contributors may be used to endorse
- * or promote products derived from this software without specific prior
- * written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-#ifndef lint
-static char rcsid[] =
- "@(#)$Header: /home/ncvs/src/lib/libpcap/pcap-bpf.c,v 1.1.1.1 1995/01/20 04:13:03 jkh Exp $ (LBL)";
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <netdb.h>
-#include <ctype.h>
-#include <signal.h>
-#include <errno.h>
-#include <sys/param.h> /* optionally get BSD define */
-#include <sys/time.h>
-#include <sys/timeb.h>
-#include <sys/socket.h>
-#include <sys/file.h>
-#include <sys/ioctl.h>
-#include <net/bpf.h>
-#include <net/if.h>
-#include <string.h>
-
-#include "pcap-int.h"
-
-int
-pcap_stats(pcap_t *p, struct pcap_stat *ps)
-{
- struct bpf_stat s;
-
- if (ioctl(p->fd, BIOCGSTATS, &s) < 0) {
- sprintf(p->errbuf, "BIOCGSTATS: %s", pcap_strerror(errno));
- return (-1);
- }
-
- ps->ps_recv = s.bs_recv;
- ps->ps_drop = s.bs_drop;
- return (0);
-}
-
-int
-pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
-{
- int cc;
- int n = 0;
- register u_char *bp, *ep;
-
- again:
- cc = p->cc;
- if (p->cc == 0) {
- cc = read(p->fd, (char *)p->buffer, p->bufsize);
- if (cc < 0) {
- /* Don't choke when we get ptraced */
- switch (errno) {
-
- case EINTR:
- goto again;
-
- case EWOULDBLOCK:
- return (0);
-#if defined(sun) && !defined(BSD)
- /*
- * Due to a SunOS bug, after 2^31 bytes, the kernel
- * file offset overflows and read fails with EINVAL.
- * The lseek() to 0 will fix things.
- */
- case EINVAL:
- if ((long)(tell(p->fd) + p->bufsize) < 0) {
- (void)lseek(p->fd, 0, 0);
- goto again;
- }
- /* fall through */
-#endif
- }
- sprintf(p->errbuf, "read: %s", pcap_strerror(errno));
- return (-1);
- }
- bp = p->buffer;
- } else
- bp = p->bp;
-
- /*
- * Loop through each packet.
- */
-#define bhp ((struct bpf_hdr *)bp)
- ep = bp + cc;
- while (bp < ep) {
- register int caplen, hdrlen;
- caplen = bhp->bh_caplen;
- hdrlen = bhp->bh_hdrlen;
- /*
- * XXX A bpf_hdr matches a pcap_pkthdr.
- */
- (*callback)(user, (struct pcap_pkthdr*)bp, bp + hdrlen);
- bp += BPF_WORDALIGN(caplen + hdrlen);
- if (++n >= cnt && cnt > 0) {
- p->bp = bp;
- p->cc = ep - bp;
- return (n);
- }
- }
-#undef bhp
- p->cc = 0;
- return (n);
-}
-
-static inline int
-bpf_open(pcap_t *p, char *errbuf)
-{
- int fd;
- int n = 0;
- char device[sizeof "/dev/bpf000"];
-
- /*
- * Go through all the minors and find one that isn't in use.
- */
- do {
- (void)sprintf(device, "/dev/bpf%d", n++);
- fd = open(device, O_RDONLY);
- } while (fd < 0 && errno == EBUSY);
-
- /*
- * XXX better message for all minors used
- */
- if (fd < 0)
- sprintf(errbuf, "%s: %s", device, pcap_strerror(errno));
-
- return (fd);
-}
-
-pcap_t *
-pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
-{
- int fd;
- struct ifreq ifr;
- struct bpf_version bv;
- u_int v;
- pcap_t *p;
-
- p = (pcap_t *)malloc(sizeof(*p));
- if (p == NULL) {
- sprintf(ebuf, "malloc: %s", pcap_strerror(errno));
- return (NULL);
- }
- bzero(p, sizeof(*p));
- fd = bpf_open(p, ebuf);
- if (fd < 0)
- goto bad;
-
- p->fd = fd;
- p->snapshot = snaplen;
-
- if (ioctl(fd, BIOCVERSION, (caddr_t)&bv) < 0) {
- sprintf(ebuf, "BIOCVERSION: %s", pcap_strerror(errno));
- goto bad;
- }
- if (bv.bv_major != BPF_MAJOR_VERSION ||
- bv.bv_minor < BPF_MINOR_VERSION) {
- sprintf(ebuf, "kernel bpf filter out of date");
- goto bad;
- }
- (void)strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
- if (ioctl(fd, BIOCSETIF, (caddr_t)&ifr) < 0) {
- sprintf(ebuf, "%s: %s", device, pcap_strerror(errno));
- goto bad;
- }
- /* Get the data link layer type. */
- if (ioctl(fd, BIOCGDLT, (caddr_t)&v) < 0) {
- sprintf(ebuf, "BIOCGDLT: %s", pcap_strerror(errno));
- goto bad;
- }
- p->linktype = v;
-
- /* set timeout */
- if (to_ms != 0) {
- struct timeval to;
- to.tv_sec = to_ms / 1000;
- to.tv_usec = (to_ms * 1000) % 1000000;
- if (ioctl(p->fd, BIOCSRTIMEOUT, (caddr_t)&to) < 0) {
- sprintf(ebuf, "BIOCSRTIMEOUT: %s",
- pcap_strerror(errno));
- goto bad;
- }
- }
- if (promisc)
- /* set promiscuous mode, okay if it fails */
- (void)ioctl(p->fd, BIOCPROMISC, NULL);
-
- if (ioctl(fd, BIOCGBLEN, (caddr_t)&v) < 0) {
- sprintf(ebuf, "BIOCGBLEN: %s", pcap_strerror(errno));
- goto bad;
- }
- p->bufsize = v;
- p->buffer = (u_char*)malloc(p->bufsize);
- if (p->buffer == NULL) {
- sprintf(ebuf, "malloc: %s", pcap_strerror(errno));
- goto bad;
- }
-
- return (p);
- bad:
- free(p);
- return (NULL);
-}
-
-int
-pcap_setfilter(pcap_t *p, struct bpf_program *fp)
-{
- if (p->sf.rfile != NULL)
- p->fcode = *fp;
- else if (ioctl(p->fd, BIOCSETF, (caddr_t)fp) < 0) {
- sprintf(p->errbuf, "BIOCSETF: %s", pcap_strerror(errno));
- return (-1);
- }
- return (0);
-}
diff --git a/lib/libpcap/pcap-dlpi.c b/lib/libpcap/pcap-dlpi.c
deleted file mode 100644
index adcffcd..0000000
--- a/lib/libpcap/pcap-dlpi.c
+++ /dev/null
@@ -1,506 +0,0 @@
-/*
- * Copyright (c) 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that: (1) source code distributions
- * retain the above copyright notice and this paragraph in its entirety, (2)
- * distributions including binary code include the above copyright notice and
- * this paragraph in its entirety in the documentation or other materials
- * provided with the distribution, and (3) all advertising materials mentioning
- * features or use of this software display the following acknowledgement:
- * ``This product includes software developed by the University of California,
- * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
- * the University nor the names of its contributors may be used to endorse
- * or promote products derived from this software without specific prior
- * written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * This code contributed by Atanu Ghosh (atanu@cs.ucl.ac.uk),
- * University College London.
- */
-#ifndef lint
-static char rcsid[] =
- "@(#)$Header: pcap-dlpi.c,v 1.22x 94/10/12 20:08:15 leres Exp $ (LBL)";
-#endif
-
-/*
- * Packet capture routine for dlpi under SunOS 5
- *
- * Notes:
- *
- * - Apparently the DLIOCRAW ioctl() is specific to SunOS.
- *
- * - There is a bug in bufmod(7) such that setting the snapshot
- * length results in data being left of the front of the packet.
- *
- * - It might be desirable to use pfmod(7) to filter packets in the
- * kernel.
- */
-
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/bufmod.h>
-#include <sys/dlpi.h>
-#include <sys/stream.h>
-#include <sys/systeminfo.h>
-
-#include <net/bpf.h>
-
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <memory.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stropts.h>
-#include <unistd.h>
-
-#include "pcap-int.h"
-
-#define MAXDLBUF 8192
-
-/* Forwards */
-static int send_request(int, char *, int, char *, char *);
-static int dlattachreq(int, u_long, char *);
-static int dlinfoack(int, char *, char *);
-static int dlinforeq(int, char *);
-static int dlpromisconreq(int, u_long, char *);
-static int dlokack(int, char *, char *);
-static int strioctl(int, int, int, char *);
-#ifdef SOLARIS
-static char *getrelease(long *, long *, long *);
-#endif
-
-int
-pcap_stats(pcap_t *p, struct pcap_stat *ps)
-{
-
- *ps = p->md.stat;
- return (0);
-}
-
-int
-pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
-{
- register int cc, n;
- register u_char *bp, *ep, *pk;
- register struct bpf_insn *fcode;
- register struct sb_hdr *sbp;
- int flags;
- struct strbuf data;
- struct pcap_pkthdr pkthdr;
-
- flags = 0;
- cc = p->cc;
- if (cc == 0) {
- data.buf = (char *)p->buffer;
- data.maxlen = MAXDLBUF;
- data.len = 0;
- do {
- if (getmsg(p->fd, NULL, &data, &flags) < 0) {
- /* Don't choke when we get ptraced */
- if (errno == EINTR) {
- cc = 0;
- continue;
- }
- strcpy(p->errbuf, pcap_strerror(errno));
- return (-1);
- }
- cc = data.len;
- } while (cc == 0);
- bp = p->buffer;
- } else
- bp = p->bp;
-
- /* Loop through packets */
- fcode = p->fcode.bf_insns;
- ep = bp + cc;
- n = 0;
- while (bp < ep) {
- sbp = (struct sb_hdr *)bp;
- p->md.stat.ps_drop += sbp->sbh_drops;
- ++p->md.stat.ps_recv;
- pk = bp + sizeof(*sbp);
- bp += sbp->sbh_totlen;
- if (bpf_filter(fcode, pk, sbp->sbh_origlen, sbp->sbh_msglen)) {
- pkthdr.ts = sbp->sbh_timestamp;
- pkthdr.len = sbp->sbh_origlen;
- pkthdr.caplen = sbp->sbh_msglen;
- (*callback)(user, &pkthdr, pk);
- if (++n >= cnt && cnt >= 0) {
- p->cc = ep - bp;
- p->bp = bp;
- return (n);
- }
- }
- }
- p->cc = 0;
- return (n);
-}
-
-pcap_t *
-pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
-{
- register pcap_t *p;
- long buf[MAXDLBUF];
- int ppa;
- int cppa;
- register dl_info_ack_t *infop;
- u_long ss, flag;
-#ifdef SOLARIS
- char *release;
- long osmajor, osminor, osmicro;
-#endif
- char dname[100];
-
- p = (pcap_t *)malloc(sizeof(*p));
- if (p == NULL) {
- strcpy(ebuf, pcap_strerror(errno));
- return (NULL);
- }
- memset(p, 0, sizeof(*p));
-
- /*
- ** 1) In order to get the ppa take the last character of the device
- ** name if it is a number then fail the open.
- **
- ** 2) If the name starts with a '/' then this is an absolute pathname,
- ** otherwise prepend '/dev/'.
- **
- ** 3) Remove the trailing digit and try and open the device
- ** not staggeringly intuitive but it should work.
- **
- ** If there are more than 9 devices this code will fail.
- */
-
- cppa = device[strlen(device) - 1];
- if (!isdigit(cppa)) {
- sprintf(ebuf, "%c is not a digit, therefore not a valid ppa",
- cppa);
- goto bad;
- }
-
- dname[0] = '\0';
- if (device[0] != '/')
- strcpy(dname, "/dev/");
-
- strcat(dname, device);
- dname[strlen(dname) - 1] = '\0';
-
- if ((p->fd = open(dname, O_RDWR)) < 0) {
- sprintf(ebuf, "%s: %s", dname, pcap_strerror(errno));
- goto bad;
- }
- p->snapshot = snaplen;
-
- ppa = cppa - '0';
- /*
- ** Attach.
- */
- if (dlattachreq(p->fd, ppa, ebuf) < 0 ||
- dlokack(p->fd, (char *)buf, ebuf) < 0)
- goto bad;
-
- if (promisc) {
- /*
- ** enable promiscuous.
- */
- if (dlpromisconreq(p->fd, DL_PROMISC_PHYS, ebuf) < 0 ||
- dlokack(p->fd, (char *)buf, ebuf) < 0)
- goto bad;
- if (dlpromisconreq(p->fd, DL_PROMISC_SAP, ebuf) < 0 ||
- dlokack(p->fd, (char *)buf, ebuf) < 0)
- goto bad;
-
- /*
- ** enable multicast, you would have thought promiscuous
- ** would be sufficient.
- */
- if (dlpromisconreq(p->fd, DL_PROMISC_MULTI, ebuf) < 0 ||
- dlokack(p->fd, (char *)buf, ebuf) < 0)
- goto bad;
- }
-
- /*
- ** Determine link type
- */
- if (dlinforeq(p->fd, ebuf) < 0 ||
- dlinfoack(p->fd, (char *)buf, ebuf) < 0)
- goto bad;
-
- infop = &((union DL_primitives *)buf)->info_ack;
- switch (infop->dl_mac_type) {
-
- case DL_ETHER:
- p->linktype = DLT_EN10MB;
- break;
-
- case DL_FDDI:
- p->linktype = DLT_FDDI;
- break;
-
- default:
- sprintf(ebuf, "unknown mac type 0x%lu", infop->dl_mac_type);
- goto bad;
- }
-
-#ifdef DLIOCRAW
- /*
- ** This is a non standard SunOS hack to get the ethernet header.
- */
- if (strioctl(p->fd, DLIOCRAW, 0, NULL) < 0) {
- sprintf(ebuf, "DLIOCRAW: %s", pcap_strerror(errno));
- goto bad;
- }
-#endif
-
- /*
- ** Another non standard call to get the data nicely buffered
- */
- if (ioctl(p->fd, I_PUSH, "bufmod") != 0) {
- sprintf(ebuf, "I_PUSH bufmod: %s", pcap_strerror(errno));
- goto bad;
- }
-
- /*
- ** Now that the bufmod is pushed lets configure it.
- **
- ** There is a bug in bufmod(7). When dealing with messages of
- ** less than snaplen size it strips data from the beginning not
- ** the end.
- **
- ** This bug is supposed to be fixed in 5.3.2. Also, there is a
- ** patch available. Ask for bugid 1149065.
- */
- ss = snaplen;
-#ifdef SOLARIS
- release = getrelease(&osmajor, &osminor, &osmicro);
- if (osmajor == 5 && (osminor <= 2 || (osminor == 3 && osmicro < 2)) &&
- getenv("BUFMOD_FIXED") == NULL) {
- fprintf(stderr,
- "WARNING: bufmod is broken in SunOS %s; ignoring snaplen.\n",
- release);
- ss = 0;
- }
-#endif
- if (ss > 0 &&
- strioctl(p->fd, SBIOCSSNAP, sizeof(u_long), (char *)&ss) != 0) {
- sprintf(ebuf, "SBIOCSSNAP: %s", pcap_strerror(errno));
- goto bad;
- }
-
- /*
- ** Set up the bufmod flags
- */
- if (strioctl(p->fd, SBIOCGFLAGS, sizeof(u_long), (char *)&flag) < 0) {
- sprintf(ebuf, "SBIOCGFLAGS: %s", pcap_strerror(errno));
- goto bad;
- }
- flag |= SB_NO_DROPS;
- if (strioctl(p->fd, SBIOCSFLAGS, sizeof(u_long), (char *)&flag) != 0) {
- sprintf(ebuf, "SBIOCSFLAGS: %s", pcap_strerror(errno));
- goto bad;
- }
- /*
- ** Set up the bufmod timeout
- */
- if (to_ms != 0) {
- struct timeval to;
-
- to.tv_sec = to_ms / 1000;
- to.tv_usec = (to_ms * 1000) % 1000000;
- if (strioctl(p->fd, SBIOCSTIME, sizeof(to), (char *)&to) != 0) {
- sprintf(ebuf, "SBIOCSTIME: %s", pcap_strerror(errno));
- goto bad;
- }
- }
-
- /*
- ** As the last operation flush the read side.
- */
- if (ioctl(p->fd, I_FLUSH, FLUSHR) != 0) {
- sprintf(ebuf, "FLUSHR: %s", pcap_strerror(errno));
- goto bad;
- }
- /* Allocate data buffer */
- p->bufsize = MAXDLBUF * sizeof(long);
- p->buffer = (u_char *)malloc(p->bufsize);
- return (p);
-bad:
- free(p);
- return (NULL);
-}
-
-int
-pcap_setfilter(pcap_t *p, struct bpf_program *fp)
-{
-
- p->fcode = *fp;
- return (0);
-}
-
-static int
-send_request(int fd, char *ptr, int len, char *what, char *ebuf)
-{
- struct strbuf ctl;
- int flags;
-
- ctl.maxlen = 0;
- ctl.len = len;
- ctl.buf = ptr;
-
- flags = 0;
- if (putmsg(fd, &ctl, (struct strbuf *) NULL, flags) < 0) {
- sprintf(ebuf, "putmsg \"%s\"failed: %s",
- what, pcap_strerror(errno));
- return (-1);
- }
- return (0);
-}
-
-static int
-dlattachreq(int fd, u_long ppa, char *ebuf)
-{
- dl_attach_req_t req;
-
- req.dl_primitive = DL_ATTACH_REQ;
- req.dl_ppa = ppa;
-
- return (send_request(fd, (char *)&req, sizeof(req), "attach", ebuf));
-}
-
-static int
-dlpromisconreq(int fd, u_long level, char *ebuf)
-{
- dl_promiscon_req_t req;
-
- req.dl_primitive = DL_PROMISCON_REQ;
- req.dl_level = level;
-
- return (send_request(fd, (char *)&req, sizeof(req), "promiscon", ebuf));
-}
-
-static int
-dlokack(int fd, char *bufp, char *ebuf)
-{
- union DL_primitives *dlp;
- struct strbuf ctl;
- int flags;
-
- ctl.maxlen = MAXDLBUF;
- ctl.len = 0;
- ctl.buf = bufp;
-
- flags = 0;
- if (getmsg(fd, &ctl, (struct strbuf*)NULL, &flags) < 0) {
- sprintf(ebuf, "getmsg: %s", pcap_strerror(errno));
- return (-1);
- }
-
- dlp = (union DL_primitives *) ctl.buf;
-
- if (dlp->dl_primitive != DL_OK_ACK) {
- sprintf(ebuf, "dlokack unexpected primitive %d",
- dlp->dl_primitive);
- return (-1);
- }
-
- if (ctl.len != sizeof(dl_ok_ack_t)) {
- sprintf(ebuf, "dlokack incorrect size returned");
- return (-1);
- }
- return (0);
-}
-
-
-static int
-dlinforeq(int fd, char *ebuf)
-{
- dl_info_req_t req;
-
- req.dl_primitive = DL_INFO_REQ;
-
- return (send_request(fd, (char *)&req, sizeof(req), "info", ebuf));
-}
-
-static int
-dlinfoack(int fd, char *bufp, char *ebuf)
-{
- union DL_primitives *dlp;
- struct strbuf ctl;
- int flags;
-
- ctl.maxlen = MAXDLBUF;
- ctl.len = 0;
- ctl.buf = bufp;
-
- flags = 0;
- if (getmsg(fd, &ctl, (struct strbuf *)NULL, &flags) < 0) {
- sprintf(ebuf, "dlinfoack: getmsg: %s", pcap_strerror(errno));
- return (-1);
- }
-
- dlp = (union DL_primitives *) ctl.buf;
-
- if (dlp->dl_primitive != DL_INFO_ACK) {
- sprintf(ebuf, "dlinfoack: unexpected primitive %ld",
- dlp->dl_primitive);
- return (-1);
- }
-
- /* Extra stuff like the broadcast address can be returned */
- if (ctl.len < DL_INFO_ACK_SIZE) {
- sprintf(ebuf, "dlinfoack: incorrect size returned");
- return (-1);
- }
- return (0);
-}
-
-static int
-strioctl(int fd, int cmd, int len, char *dp)
-{
- struct strioctl str;
- int rc;
-
- str.ic_cmd = cmd;
- str.ic_timout = -1;
- str.ic_len = len;
- str.ic_dp = dp;
- rc = ioctl(fd, I_STR, &str);
-
- if (rc < 0)
- return (rc);
- else
- return (str.ic_len);
-}
-
-#ifdef SOLARIS
-static char *
-getrelease(long *majorp, long *minorp, long *microp)
-{
- char *cp;
- static char buf[32];
-
- *majorp = 0;
- *minorp = 0;
- *microp = 0;
- if (sysinfo(SI_RELEASE, buf, sizeof(buf)) < 0)
- return ("?");
- cp = buf;
- if (!isdigit(*cp))
- return (buf);
- *majorp = strtol(cp, &cp, 10);
- if (*cp++ != '.')
- return (buf);
- *minorp = strtol(cp, &cp, 10);
- if (*cp++ != '.')
- return (buf);
- *microp = strtol(cp, &cp, 10);
- return (buf);
-}
-#endif
diff --git a/lib/libpcap/pcap-enet.c b/lib/libpcap/pcap-enet.c
deleted file mode 100644
index cb052eb..0000000
--- a/lib/libpcap/pcap-enet.c
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * Stanford Enetfilter subroutines for tcpdump
- *
- * Based on the MERIT NNstat etherifrt.c and the Ultrix pcap-pf.c
- * subroutines.
- *
- * Rayan Zachariassen, CA*Net
- */
-
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/file.h>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-
-#include <net/if.h>
-#include <net/bpf.h>
-#include <net/enet.h>
-
-#include <netinet/in.h>
-#include <netinet/if_ether.h>
-
-#include <stdio.h>
-#include <errno.h>
-
-#include "interface.h"
-
-struct packet_header {
-#ifdef IBMRTPC
- struct LengthWords length;
- struct tap_header tap;
-#endif /* IBMRTPC */
- u_char packet[8]
-};
-
-extern int errno;
-
-#define BUFSPACE (4*1024)
-
-/* Forwards */
-static void efReadError(int, char *);
-
-void
-readloop(int cnt, int if_fd, struct bpf_program *fp, printfunc printit)
-{
-#ifdef IBMRTPC
- register struct packet_header *ph;
- register u_char *bp;
- register int inc;
-#else /* !IBMRTPC */
- static struct timeval tv = { 0 };
-#endif /* IBMRTPC */
- register int cc, caplen;
- register struct bpf_insn *fcode = fp->bf_insns;
- union {
- struct packet_header hdr;
- u_char p[BUFSPACE];
- u_short s;
- } buf;
-
- while (1) {
- if ((cc = read(if_fd, (char *)buf.p, sizeof(buf))) < 0)
- efReadError(if_fd, "reader");
-
-#ifdef IBMRTPC
- /*
- * Loop through each packet.
- */
- bp = buf.p;
- while (cc > 0) {
- ph = (struct packet_header *)bp;
- caplen = ph->tap.th_wirelen > snaplen ? snaplen : ph->tap
-.th_wirelen ;
- if (bpf_filter(fcode, (char *)ph->packet,
- ph->tap.th_wirelen, caplen)) {
- if (cnt >= 0 && --cnt < 0)
- goto out;
- (*printit)((char *)ph->packet,
- (struct timeval *)ph->tap.th_timestamp,
- ph->tap.th_wirelen, caplen);
- }
- inc = ph->length.PacketOffset;
- cc -= inc;
- bp += inc;
- }
-#else /* !IBMRTPC */
- caplen = cc > snaplen ? snaplen : cc ;
- if (bpf_filter(fcode, buf.hdr.packet, cc, caplen)) {
- if (cnt >= 0 && --cnt < 0)
- goto out;
- (*printit)(buf.hdr.packet, &tv, cc, caplen);
- }
-#endif /* IBMRTPC */
- }
- out:
- wrapup(if_fd);
-}
-
-/* Call ONLY if read() has returned an error on packet filter */
-static void
-efReadError(int fid, char *msg)
-{
- if (errno == EINVAL) { /* read MAXINT bytes already! */
- if (lseek(fid, 0, 0) < 0) {
- perror("tcpdump: efReadError/lseek");
- exit(-1);
- }
- else
- return;
- }
- else {
- (void) fprintf(stderr, "tcpdump: ");
- perror(msg);
- exit(-1);
- }
-}
-
-void
-wrapup(int fd)
-{
-#ifdef IBMRTPC
- struct enstats es;
-
- if (ioctl(fd, EIOSTATS, &es) == -1) {
- perror("tcpdump: enet ioctl EIOSTATS error");
- exit(-1);
- }
-
- fprintf(stderr, "%d packets queued", es.enStat_Rcnt);
- if (es.enStat_Rdrops > 0)
- fprintf(stderr, ", %d dropped", es.enStat_Rdrops);
- if (es.enStat_Reads > 0)
- fprintf(stderr, ", %d tcpdump %s", es.enStat_Reads,
- es.enStat_Reads > 1 ? "reads" : "read");
- if (es.enStat_MaxRead > 1)
- fprintf(stderr, ", %d packets in largest read",
- es.enStat_MaxRead);
- putc('\n', stderr);
-#endif /* IBMRTPC */
- close(fd);
-}
-
-int
-initdevice(char *device, int pflag, int *linktype)
-{
- struct eniocb ctl;
- struct enfilter filter;
- u_int maxwaiting;
- int if_fd;
-
-#ifdef IBMRTPC
- GETENETDEVICE(0, O_RDONLY, &if_fd);
-#else /* !IBMRTPC */
- if_fd = open("/dev/enet", O_RDONLY, 0);
-#endif /* IBMRTPC */
-
- if (if_fd == -1) {
- perror("tcpdump: enet open error");
- error(
-"your system may not be properly configured; see \"man enet(4)\"");
- exit(-1);
- }
-
- /* Get operating parameters. */
-
- if (ioctl(if_fd, EIOCGETP, (char *)&ctl) == -1) {
- perror("tcpdump: enet ioctl EIOCGETP error");
- exit(-1);
- }
-
- /* Set operating parameters. */
-
-#ifdef IBMRTPC
- ctl.en_rtout = 1 * ctl.en_hz;
- ctl.en_tr_etherhead = 1;
- ctl.en_tap_network = 1;
- ctl.en_multi_packet = 1;
- ctl.en_maxlen = BUFSPACE;
-#else /* !IBMRTPC */
- ctl.en_rtout = 64; /* randomly picked value for HZ */
-#endif /* IBMRTPC */
- if (ioctl(if_fd, EIOCSETP, &ctl) == -1) {
- perror("tcpdump: enet ioctl EIOCSETP error");
- exit(-1);
- }
-
- /* Flush the receive queue, since we've changed
- the operating parameters and we otherwise might
- receive data without headers. */
-
- if (ioctl(if_fd, EIOCFLUSH) == -1) {
- perror("tcpdump: enet ioctl EIOCFLUSH error");
- exit(-1);
- }
-
- /* Set the receive queue depth to its maximum. */
-
- maxwaiting = ctl.en_maxwaiting;
- if (ioctl(if_fd, EIOCSETW, &maxwaiting) == -1) {
- perror("tcpdump: enet ioctl EIOCSETW error");
- exit(-1);
- }
-
-#ifdef IBMRTPC
- /* Clear statistics. */
-
- if (ioctl(if_fd, EIOCLRSTAT, 0) == -1) {
- perror("tcpdump: enet ioctl EIOCLRSTAT error");
- exit(-1);
- }
-#endif /* IBMRTPC */
-
- /* Set the filter (accept all packets). */
-
- filter.enf_Priority = 3;
- filter.enf_FilterLen = 0;
- if (ioctl(if_fd, EIOCSETF, &filter) == -1) {
- perror("tcpdump: enet ioctl EIOCSETF error");
- exit(-1);
- }
- /*
- * "enetfilter" supports only ethernets.
- */
- *linktype = DLT_EN10MB;
-
- return(if_fd);
-}
diff --git a/lib/libpcap/pcap-int.h b/lib/libpcap/pcap-int.h
deleted file mode 100644
index db3677a..0000000
--- a/lib/libpcap/pcap-int.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (c) 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the Computer Systems
- * Engineering Group at Lawrence Berkeley Laboratory.
- * 4. Neither the name of the University nor of the Laboratory may be used
- * to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#) $Header: /home/ncvs/src/lib/libpcap/pcap-int.h,v 1.1.1.1 1995/01/20 04:13:06 jkh Exp $ (LBL)
- */
-
-#ifndef pcap_int_h
-#define pcap_int_h
-
-#include <pcap.h>
-
-/*
- * Savefile
- */
-struct pcap_sf {
- FILE *rfile;
- int swapped;
- int version_major;
- int version_minor;
- u_char *base;
-};
-
-struct pcap_md {
- struct pcap_stat stat;
-#ifdef PCAP_PF
- int use_bpf;
- 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 */
-#endif
-};
-
-struct pcap {
- int fd;
- int snapshot;
- int linktype;
- int tzoff; /* timezone offset */
-
- struct pcap_sf sf;
- struct pcap_md md;
-
- /*
- * Read buffer.
- */
- int bufsize;
- u_char *buffer;
- u_char *bp;
- int cc;
-
- /*
- * Place holder for pcap_next().
- */
- u_char *pkt;
-
-
- /*
- * Placeholder for filter code if bpf not in kernel.
- */
- struct bpf_program fcode;
-
- char errbuf[PCAP_ERRBUF_SIZE];
-};
-
-/* XXX should these be in pcap.h? */
-int pcap_offline_read(pcap_t *, int, pcap_handler, u_char *);
-int pcap_read(pcap_t *, int cnt, pcap_handler, u_char *);
-#endif
diff --git a/lib/libpcap/pcap-namedb.h b/lib/libpcap/pcap-namedb.h
deleted file mode 100644
index 3471227..0000000
--- a/lib/libpcap/pcap-namedb.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the Computer Systems
- * Engineering Group at Lawrence Berkeley Laboratory.
- * 4. Neither the name of the University nor of the Laboratory may be used
- * to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#) $Header: pcap-namedb.h,v 1.2 94/06/14 20:03:34 leres Exp $ (LBL)
- */
-
-#ifndef lib_pcap_ethers_h
-#define lib_pcap_ethers_h
-
-/*
- * As returned by the pcap_next_etherent()
- * XXX this stuff doesn't belong in this inteface, but this
- * library already must do name to address translation, so
- * on systems that don't have support for /etc/ethers, we
- * export these hooks since they'll
- */
-struct pcap_etherent {
- u_char addr[6];
- char name[122];
-};
-#ifndef PCAP_ETHERS_FILE
-#define PCAP_ETHERS_FILE "/etc/ethers"
-#endif
-struct pcap_etherent *pcap_next_etherent(FILE *);
-u_char *pcap_ether_hostton(const char*);
-u_char *pcap_ether_aton(const char *);
-
-u_long **pcap_nametoaddr(const char *);
-u_long pcap_nametonetaddr(const char *);
-
-int pcap_nametoport(const char *, int *, int *);
-int pcap_nametoproto(const char *);
-int pcap_nametoeproto(const char *);
-/*
- * If a protocol is unknown, PROTO_UNDEF is returned.
- * Also, pcap_nametoport() returns the protocol along with the port number.
- * If there are ambiguous entried in /etc/services (i.e. domain
- * can be either tcp or udp) PROTO_UNDEF is returned.
- */
-#define PROTO_UNDEF -1
-
-/* XXX move these to pcap-int.h? */
-u_long __pcap_atodn(const char *);
-u_long __pcap_atoin(const char *);
-u_short __pcap_nametodnaddr(const char *);
-
-#endif
diff --git a/lib/libpcap/pcap-nit.c b/lib/libpcap/pcap-nit.c
deleted file mode 100644
index 125e14f..0000000
--- a/lib/libpcap/pcap-nit.c
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- * Copyright (c) 1990, 1991, 1992, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that: (1) source code distributions
- * retain the above copyright notice and this paragraph in its entirety, (2)
- * distributions including binary code include the above copyright notice and
- * this paragraph in its entirety in the documentation or other materials
- * provided with the distribution, and (3) all advertising materials mentioning
- * features or use of this software display the following acknowledgement:
- * ``This product includes software developed by the University of California,
- * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
- * the University nor the names of its contributors may be used to endorse
- * or promote products derived from this software without specific prior
- * written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-#ifndef lint
-static char rcsid[] =
- "@(#)$Header: pcap-nit.c,v 1.24 94/02/10 23:02:37 leres Exp $ (LBL)";
-#endif
-
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/timeb.h>
-#include <sys/file.h>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-
-#include <net/bpf.h>
-#include <net/if.h>
-#include <net/nit.h>
-
-#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#include <netinet/if_ether.h>
-#include <netinet/ip_var.h>
-#include <netinet/udp.h>
-#include <netinet/udp_var.h>
-#include <netinet/tcp.h>
-#include <netinet/tcpip.h>
-
-#include <ctype.h>
-#include <errno.h>
-#include <stdio.h>
-
-#include "pcap-int.h"
-
-/*
- * The chunk size for NIT. This is the amount of buffering
- * done for read calls.
- */
-#define CHUNKSIZE (2*1024)
-
-/*
- * The total buffer space used by NIT.
- */
-#define BUFSPACE (4*CHUNKSIZE)
-
-/* Forwards */
-static int nit_setflags(int, int, int, char *);
-
-int
-pcap_stats(pcap_t *p, struct pcap_stat *ps)
-{
-
- *ps = p->md.stat;
- return (0);
-}
-
-int
-pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
-{
- register int cc, n;
- register struct bpf_insn *fcode = p->fcode.bf_insns;
- register u_char *bp, *cp, *ep;
- register struct nit_hdr *nh;
- register int caplen;
-
- cc = p->cc;
- if (cc == 0) {
- cc = read(p->fd, (char *)p->buffer, p->bufsize);
- if (cc < 0) {
- if (errno == EWOULDBLOCK)
- return (0);
- sprintf(p->errbuf, "pcap_read: %s",
- pcap_strerror(errno));
- return (-1);
- }
- bp = p->buffer;
- } else
- bp = p->bp;
-
- /*
- * Loop through each packet. The increment expression
- * rounds up to the next int boundary past the end of
- * the previous packet.
- */
- n = 0;
- ep = bp + cc;
- while (bp < ep) {
- nh = (struct nit_hdr *)bp;
- cp = bp + sizeof(*nh);
-
- switch (nh->nh_state) {
-
- case NIT_CATCH:
- break;
-
- case NIT_NOMBUF:
- case NIT_NOCLUSTER:
- case NIT_NOSPACE:
- p->md.stat.ps_drop = nh->nh_dropped;
- continue;
-
- case NIT_SEQNO:
- continue;
-
- default:
- sprintf(p->errbuf, "bad nit state %d", nh->nh_state);
- return (-1);
- }
- ++p->md.stat.ps_recv;
- bp += ((sizeof(struct nit_hdr) + nh->nh_datalen +
- sizeof(int) - 1) & ~(sizeof(int) - 1));
-
- caplen = nh->nh_wirelen;
- if (caplen > p->snapshot)
- caplen = p->snapshot;
- if (bpf_filter(fcode, cp, nh->nh_wirelen, caplen)) {
- struct pcap_pkthdr h;
- h.ts = nh->nh_timestamp;
- h.len = nh->nh_wirelen;
- h.caplen = caplen;
- (*callback)(user, &h, cp);
- if (++n >= cnt && cnt >= 0) {
- p->cc = ep - bp;
- p->bp = bp;
- return (n);
- }
- }
- }
- p->cc = 0;
- return (n);
-}
-
-static int
-nit_setflags(int fd, int promisc, int to_ms, char *ebuf)
-{
- struct nit_ioc nioc;
-
- bzero((char *)&nioc, 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) {
- nioc.nioc_flags |= NF_TIMEOUT;
- nioc.nioc_timeout.tv_sec = to_ms / 1000;
- nioc.nioc_timeout.tv_usec = (to_ms * 1000) % 1000000;
- }
- if (promisc)
- nioc.nioc_flags |= NF_PROMISC;
-
- if (ioctl(fd, SIOCSNIT, &nioc) < 0) {
- sprintf(ebuf, "SIOCSNIT: %s", pcap_strerror(errno));
- return (-1);
- }
- return (0);
-}
-
-pcap_t *
-pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
-{
- int fd;
- struct sockaddr_nit snit;
- register pcap_t *p;
-
- p = (pcap_t *)malloc(sizeof(*p));
- if (p == NULL) {
- strcpy(ebuf, pcap_strerror(errno));
- return (NULL);
- }
-
- if (snaplen < 96)
- /*
- * NIT requires a snapshot length of at least 96.
- */
- snaplen = 96;
-
- bzero(p, sizeof(*p));
- p->fd = fd = socket(AF_NIT, SOCK_RAW, NITPROTO_RAW);
- if (fd < 0) {
- sprintf(ebuf, "socket: %s", pcap_strerror(errno));
- goto bad;
- }
- snit.snit_family = AF_NIT;
- (void)strncpy(snit.snit_ifname, device, NITIFSIZ);
-
- if (bind(fd, (struct sockaddr *)&snit, sizeof(snit))) {
- sprintf(ebuf, "bind: %s: %s", snit.snit_ifname,
- pcap_strerror(errno));
- goto bad;
- }
- p->snapshot = snaplen;
- nit_setflags(p->fd, promisc, to_ms, ebuf);
-
- /*
- * NIT supports only ethernets.
- */
- p->linktype = DLT_EN10MB;
-
- p->bufsize = BUFSPACE;
- p->buffer = (u_char *)malloc(p->bufsize);
- if (p->buffer == NULL) {
- strcpy(ebuf, pcap_strerror(errno));
- goto bad;
- }
- return (p);
- bad:
- if (fd >= 0)
- close(fd);
- free(p);
- return (NULL);
-}
-
-int
-pcap_setfilter(pcap_t *p, struct bpf_program *fp)
-{
-
- p->fcode = *fp;
- return (0);
-}
diff --git a/lib/libpcap/pcap-nit.h b/lib/libpcap/pcap-nit.h
deleted file mode 100644
index dc1c9e8..0000000
--- a/lib/libpcap/pcap-nit.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (c) 1990, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Lawrence Berkeley Laboratory,
- * Berkeley, CA. The name of the University may not be used to
- * endorse or promote products derived from this software without
- * specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * @(#) $Header: pcap-nit.h,v 1.2 94/06/14 20:06:03 leres Exp $ (LBL)
- */
diff --git a/lib/libpcap/pcap-pf.c b/lib/libpcap/pcap-pf.c
deleted file mode 100644
index 483dc97..0000000
--- a/lib/libpcap/pcap-pf.c
+++ /dev/null
@@ -1,310 +0,0 @@
-/*
- * Copyright (c) 1990, 1991, 1992, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that: (1) source code distributions
- * retain the above copyright notice and this paragraph in its entirety, (2)
- * distributions including binary code include the above copyright notice and
- * this paragraph in its entirety in the documentation or other materials
- * provided with the distribution, and (3) all advertising materials mentioning
- * features or use of this software display the following acknowledgement:
- * ``This product includes software developed by the University of California,
- * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
- * the University nor the names of its contributors may be used to endorse
- * or promote products derived from this software without specific prior
- * written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-#ifndef lint
-static char rcsid[] =
- "@(#)$Header: pcap-pf.c,v 1.32 94/06/10 17:41:01 mccanne Exp $ (LBL)";
-#endif
-
-/*
- * packet filter subroutines for tcpdump
- * Extraction/creation by Jeffrey Mogul, DECWRL
- *
- * Extracted from tcpdump.c.
- */
-
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/timeb.h>
-#include <sys/socket.h>
-#include <sys/file.h>
-#include <sys/ioctl.h>
-#include <net/pfilt.h>
-
-#include <net/if.h>
-#include <net/bpf.h>
-
-#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#include <netinet/if_ether.h>
-#include <netinet/ip_var.h>
-#include <netinet/udp.h>
-#include <netinet/udp_var.h>
-#include <netinet/tcp.h>
-#include <netinet/tcpip.h>
-
-#include <ctype.h>
-#include <errno.h>
-#include <netdb.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "pcap-int.h"
-
-/*
- * BUFSPACE is the size in bytes of the packet read buffer. Most tcpdump
- * applications aren't going to need more than 200 bytes of packet header
- * and the read shouldn't return more packets than packetfilter's internal
- * queue limit (bounded at 256).
- */
-#define BUFSPACE (200*256)
-
-int
-pcap_read(pcap_t *pc, int cnt, pcap_handler callback, u_char *user)
-{
- u_char *p;
- struct bpf_insn *fcode;
- int cc;
- register u_char *bp;
- int buflen, inc;
- struct enstamp stamp;
- int n;
- fcode = pc->md.use_bpf ? 0 : pc->fcode.bf_insns;
- again:
- cc = pc->cc;
- if (cc == 0) {
- cc = read(pc->fd, (char *)pc->buffer, pc->bufsize);
- if (cc < 0) {
- if (errno == EWOULDBLOCK)
- return (0);
- if (errno == EINVAL &&
- (long)(tell(pc->fd) + pc->bufsize) < 0) {
- /*
- * Due to a kernel bug, after 2^31 bytes,
- * the kernel file offset overflows and
- * read fails with EINVAL. The lseek()
- * to 0 will fix things.
- */
- (void)lseek(pc->fd, 0L, 0);
- goto again;
- }
- sprintf(pc->errbuf, "pf read: %s",
- pcap_strerror(errno));
- return (-1);
- }
- bp = pc->buffer;
- } else
- bp = pc->bp;
- /*
- * Loop through each packet.
- */
- n = 0;
- while (cc > 0) {
- /* avoid alignment issues here */
- bcopy((char *)bp, (char *)&stamp, sizeof(stamp));
- if (stamp.ens_stamplen != sizeof(stamp))
- /* buffer is garbage, treat it as poison */
- break;
-
- p = bp + stamp.ens_stamplen;
-
- buflen = stamp.ens_count;
- if (buflen > pc->snapshot)
- buflen = pc->snapshot;
-
- /*
- * Short-circuit evaluation: if using BPF filter
- * in kernel, no need to do it now.
- */
- if (fcode == 0 ||
- bpf_filter(fcode, p, stamp.ens_count, buflen)) {
- struct pcap_pkthdr h;
- pc->md.TotAccepted++;
- h.ts = stamp.ens_tstamp;
- h.len = stamp.ens_count;
- h.caplen = buflen;
- (*callback)(user, &h, p);
- if (++n >= cnt && cnt > 0) {
- inc = ENALIGN(buflen + stamp.ens_stamplen);
- cc -= inc;
- bp += inc;
- pc->cc = cc;
- pc->bp = bp;
- return (n);
- }
- }
- pc->md.TotPkts++;
- pc->md.TotDrops += stamp.ens_dropped;
- pc->md.TotMissed = stamp.ens_ifoverflows;
- if (pc->md.OrigMissed < 0)
- pc->md.OrigMissed = pc->md.TotMissed;
-
- inc = ENALIGN(buflen + stamp.ens_stamplen);
- cc -= inc;
- bp += inc;
- }
- pc->cc = 0;
- return (n);
-}
-
-int
-pcap_stats(pcap_t *p, struct pcap_stat *ps)
-{
- ps->ps_recv = p->md.TotAccepted;
- ps->ps_drop = p->md.TotDrops;
- ps->ps_ifdrop = p->md.TotMissed - p->md.OrigMissed;
- return (0);
-}
-
-pcap_t *
-pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
-{
- pcap_t *p;
- short enmode;
- int backlog = -1; /* request the most */
- struct enfilter Filter;
- struct endevp devparams;
-
- p = (pcap_t *)malloc(sizeof(*p));
- if (p == 0) {
- strcpy(ebuf, "no swap");
- return (0);
- }
- bzero(p, sizeof(*p));
- p->fd = pfopen(device, 0);
- if (p->fd < 0) {
- sprintf(ebuf, "pf open: %s: %s\n\
-your system may not be properly configured; see \"man packetfilter(4)\"\n",
- device, pcap_strerror(errno));
- goto bad;
- }
- p->md.OrigMissed = -1;
- enmode = ENTSTAMP|ENBATCH|ENNONEXCL;
- if (promisc)
- enmode |= ENPROMISC;
- if (ioctl(p->fd, EIOCMBIS, (caddr_t)&enmode) < 0) {
- sprintf(ebuf, "EIOCMBIS: %s", pcap_strerror(errno));
- goto bad;
- }
-#ifdef ENCOPYALL
- /* Try to set COPYALL mode so that we see packets to ourself */
- enmode = ENCOPYALL;
- (void)ioctl(p->fd, EIOCMBIS, (caddr_t)&enmode);/* OK if this fails */
-#endif
- /* set the backlog */
- if (ioctl(p->fd, EIOCSETW, (caddr_t)&backlog) < 0) {
- sprintf(ebuf, "EIOCSETW: %s", pcap_strerror(errno));
- goto bad;
- }
- /* set truncation */
- if (ioctl(p->fd, EIOCTRUNCATE, (caddr_t)&snaplen) < 0) {
- sprintf(ebuf, "EIOCTRUNCATE: %s", pcap_strerror(errno));
- goto bad;
- }
- p->snapshot = snaplen;
- /* accept all packets */
- Filter.enf_Priority = 37; /* anything > 2 */
- Filter.enf_FilterLen = 0; /* means "always true" */
- if (ioctl(p->fd, EIOCSETF, (caddr_t)&Filter) < 0) {
- sprintf(ebuf, "EIOCSETF: %s", pcap_strerror(errno));
- goto bad;
- }
- /* discover interface type */
- if (ioctl(p->fd, EIOCDEVP, (caddr_t)&devparams) < 0) {
- sprintf(ebuf, "EIOCDEVP: %s", pcap_strerror(errno));
- goto bad;
- }
- /* HACK: to compile prior to Ultrix 4.2 */
-#ifndef ENDT_FDDI
-#define ENDT_FDDI 4
-#endif
- switch (devparams.end_dev_type) {
- case ENDT_10MB:
- p->linktype = DLT_EN10MB;
- break;
-
- case ENDT_FDDI:
- p->linktype = DLT_FDDI;
- break;
-
- default:
- /*
- * XXX
- * Currently, the Ultrix packet filter supports only
- * Ethernet and FDDI. Eventually, support for SLIP and PPP
- * (and possibly others: T1?) should be added.
- */
-#ifdef notdef
- warning(
- "Packet filter data-link type %d unknown, assuming Ethernet",
- devparams.end_dev_type);
-#endif
- p->linktype = DLT_EN10MB;
- break;
- }
-
- if (to_ms != 0) {
- struct timeval timeout;
- timeout.tv_sec = to_ms / 1000;
- timeout.tv_usec = (to_ms * 1000) % 1000000;
- if (ioctl(p->fd, EIOCSRTIMEOUT, (caddr_t)&timeout) < 0) {
- sprintf(ebuf, "EIOCSRTIMEOUT: %s",
- pcap_strerror(errno));
- goto bad;
- }
- }
- p->bufsize = BUFSPACE;
- p->buffer = (u_char*)malloc(p->bufsize);
-
- return (p);
- bad:
- free(p);
- return (0);
-}
-
-int
-pcap_setfilter(pcap_t *p, struct bpf_program *fp)
-{
- /*
- * See if BIOCSETF works. If it does, the kernel supports
- * BPF-style filters, and we do not need to do post-filtering.
- */
- p->md.use_bpf = (ioctl(p->fd, BIOCSETF, (caddr_t)fp) >= 0);
- if (p->md.use_bpf) {
- struct bpf_version bv;
-
- if (ioctl(p->fd, BIOCVERSION, (caddr_t)&bv) < 0) {
- sprintf(p->errbuf, "BIOCVERSION: %s",
- pcap_strerror(errno));
- return (-1);
- }
- else if (bv.bv_major != BPF_MAJOR_VERSION ||
- bv.bv_minor < BPF_MINOR_VERSION) {
- fprintf(stderr,
- "requires bpf language %d.%d or higher; kernel is %d.%d",
- BPF_MAJOR_VERSION, BPF_MINOR_VERSION,
- bv.bv_major, bv.bv_minor);
- /* don't give up, just be inefficient */
- p->md.use_bpf = 0;
- }
- } else
- p->fcode = *fp;
-
- /*XXX this goes in tcpdump*/
- if (p->md.use_bpf)
- fprintf(stderr, "tcpdump: Using kernel BPF filter\n");
- else
- fprintf(stderr, "tcpdump: Filtering in user process\n");
- return (0);
-}
diff --git a/lib/libpcap/pcap-pf.h b/lib/libpcap/pcap-pf.h
deleted file mode 100644
index 65ca067..0000000
--- a/lib/libpcap/pcap-pf.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (c) 1990, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Lawrence Berkeley Laboratory,
- * Berkeley, CA. The name of the University may not be used to
- * endorse or promote products derived from this software without
- * specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * @(#) $Header: pcap-pf.h,v 1.2 94/06/14 20:06:33 leres Exp $ (LBL)
- */
diff --git a/lib/libpcap/pcap-snit.c b/lib/libpcap/pcap-snit.c
deleted file mode 100644
index 562b965..0000000
--- a/lib/libpcap/pcap-snit.c
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- * Copyright (c) 1990, 1991, 1992, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that: (1) source code distributions
- * retain the above copyright notice and this paragraph in its entirety, (2)
- * distributions including binary code include the above copyright notice and
- * this paragraph in its entirety in the documentation or other materials
- * provided with the distribution, and (3) all advertising materials mentioning
- * features or use of this software display the following acknowledgement:
- * ``This product includes software developed by the University of California,
- * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
- * the University nor the names of its contributors may be used to endorse
- * or promote products derived from this software without specific prior
- * written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-#ifndef lint
-static char rcsid[] =
- "@(#)$Header: pcap-snit.c,v 1.33 94/06/23 13:51:17 leres Exp $ (LBL)";
-#endif
-
-/*
- * Modifications made to accomodate the new SunOS4.0 NIT facility by
- * Micky Liu, micky@cunixc.cc.columbia.edu, Columbia University in May, 1989.
- * This module now handles the STREAMS based NIT.
- */
-
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/timeb.h>
-#include <sys/dir.h>
-#include <sys/fcntlcom.h>
-#include <sys/file.h>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-#include <sys/stropts.h>
-
-#include <net/bpf.h>
-#include <net/if.h>
-#include <net/nit.h>
-#include <net/nit_if.h>
-#include <net/nit_pf.h>
-#include <net/nit_buf.h>
-
-#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#include <netinet/if_ether.h>
-#include <netinet/ip_var.h>
-#include <netinet/udp.h>
-#include <netinet/udp_var.h>
-#include <netinet/tcp.h>
-#include <netinet/tcpip.h>
-
-#include <ctype.h>
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "pcap-int.h"
-
-/*
- * The chunk size for NIT. This is the amount of buffering
- * done for read calls.
- */
-#define CHUNKSIZE (2*1024)
-
-/*
- * The total buffer space used by NIT.
- */
-#define BUFSPACE (4*CHUNKSIZE)
-
-/* Forwards */
-static int nit_setflags(int, int, int, char *);
-
-int
-pcap_stats(pcap_t *p, struct pcap_stat *ps)
-{
-
- *ps = p->md.stat;
- return (0);
-}
-
-int
-pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
-{
- register int cc, n;
- register struct bpf_insn *fcode = p->fcode.bf_insns;
- register u_char *bp, *cp, *ep;
- register struct nit_bufhdr *hdrp;
- register struct nit_iftime *ntp;
- register struct nit_iflen *nlp;
- register struct nit_ifdrops *ndp;
- register int caplen;
-
- cc = p->cc;
- if (cc == 0) {
- cc = read(p->fd, (char *)p->buffer, p->bufsize);
- if (cc < 0) {
- if (errno == EWOULDBLOCK)
- return (0);
- sprintf(p->errbuf, "pcap_read: %s",
- pcap_strerror(errno));
- return (-1);
- }
- bp = p->buffer;
- } else
- bp = p->bp;
-
- /*
- * loop through each snapshot in the chunk
- */
- n = 0;
- ep = bp + cc;
- while (bp < ep) {
- ++p->md.stat.ps_recv;
- cp = bp;
-
- /* get past NIT buffer */
- hdrp = (struct nit_bufhdr *)cp;
- cp += sizeof(*hdrp);
-
- /* get past NIT timer */
- ntp = (struct nit_iftime *)cp;
- cp += sizeof(*ntp);
-
- ndp = (struct nit_ifdrops *)cp;
- p->md.stat.ps_drop = ndp->nh_drops;
- cp += sizeof *ndp;
-
- /* get past packet len */
- nlp = (struct nit_iflen *)cp;
- cp += sizeof(*nlp);
-
- /* next snapshot */
- bp += hdrp->nhb_totlen;
-
- caplen = nlp->nh_pktlen;
- if (caplen > p->snapshot)
- caplen = p->snapshot;
-
- if (bpf_filter(fcode, cp, nlp->nh_pktlen, caplen)) {
- struct pcap_pkthdr h;
- h.ts = ntp->nh_timestamp;
- h.len = nlp->nh_pktlen;
- h.caplen = caplen;
- (*callback)(user, &h, cp);
- if (++n >= cnt && cnt >= 0) {
- p->cc = ep - bp;
- p->bp = bp;
- return (n);
- }
- }
- }
- p->cc = 0;
- return (n);
-}
-
-static int
-nit_setflags(int fd, int promisc, int to_ms, char *ebuf)
-{
- u_long flags;
- struct strioctl si;
- struct timeval timeout;
-
- si.ic_timout = INFTIM;
- if (to_ms != 0) {
- timeout.tv_sec = to_ms / 1000;
- timeout.tv_usec = (to_ms * 1000) % 1000000;
- si.ic_cmd = NIOCSTIME;
- si.ic_len = sizeof(timeout);
- si.ic_dp = (char *)&timeout;
- if (ioctl(fd, I_STR, (char *)&si) < 0) {
- sprintf(ebuf, "NIOCSTIME: %s", pcap_strerror(errno));
- return (-1);
- }
- }
- flags = NI_TIMESTAMP | NI_LEN | NI_DROPS;
- if (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) {
- sprintf(ebuf, "NIOCSFLAGS: %s", pcap_strerror(errno));
- return (-1);
- }
- return (0);
-}
-
-pcap_t *
-pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
-{
- struct strioctl si; /* struct for ioctl() */
- struct ifreq ifr; /* interface request struct */
- int chunksize = CHUNKSIZE;
- int fd;
- static char dev[] = "/dev/nit";
- register pcap_t *p;
-
- p = (pcap_t *)malloc(sizeof(*p));
- if (p == NULL) {
- strcpy(ebuf, pcap_strerror(errno));
- return (NULL);
- }
-
- if (snaplen < 96)
- /*
- * NIT requires a snapshot length of at least 96.
- */
- snaplen = 96;
-
- bzero(p, sizeof(*p));
- p->fd = fd = open(dev, O_RDONLY);
- if (fd < 0) {
- sprintf(ebuf, "%s: %s", dev, pcap_strerror(errno));
- goto bad;
- }
-
- /* arrange to get discrete messages from the STREAM and use NIT_BUF */
- if (ioctl(fd, I_SRDOPT, (char *)RMSGD) < 0) {
- sprintf(ebuf, "I_SRDOPT: %s", pcap_strerror(errno));
- goto bad;
- }
- if (ioctl(fd, I_PUSH, "nbuf") < 0) {
- sprintf(ebuf, "push nbuf: %s", pcap_strerror(errno));
- goto bad;
- }
- /* set the chunksize */
- si.ic_cmd = NIOCSCHUNK;
- si.ic_timout = INFTIM;
- si.ic_len = sizeof(chunksize);
- si.ic_dp = (char *)&chunksize;
- if (ioctl(fd, I_STR, (char *)&si) < 0) {
- sprintf(ebuf, "NIOCSCHUNK: %s", pcap_strerror(errno));
- goto bad;
- }
-
- /* request the interface */
- strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
- ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = ' ';
- si.ic_cmd = NIOCBIND;
- si.ic_len = sizeof(ifr);
- si.ic_dp = (char *)&ifr;
- if (ioctl(fd, I_STR, (char *)&si) < 0) {
- sprintf(ebuf, "NIOCBIND: %s: %s",
- ifr.ifr_name, pcap_strerror(errno));
- goto bad;
- }
-
- /* set the snapshot length */
- si.ic_cmd = NIOCSSNAP;
- si.ic_len = sizeof(snaplen);
- si.ic_dp = (char *)&snaplen;
- if (ioctl(fd, I_STR, (char *)&si) < 0) {
- sprintf(ebuf, "NIOCSSNAP: %s", pcap_strerror(errno));
- goto bad;
- }
- p->snapshot = snaplen;
- if (nit_setflags(p->fd, promisc, to_ms, ebuf) < 0)
- goto bad;
-
- (void)ioctl(fd, I_FLUSH, (char *)FLUSHR);
- /*
- * NIT supports only ethernets.
- */
- p->linktype = DLT_EN10MB;
-
- p->bufsize = BUFSPACE;
- p->buffer = (u_char *)malloc(p->bufsize);
- if (p->buffer == NULL) {
- strcpy(ebuf, pcap_strerror(errno));
- goto bad;
- }
- return (p);
- bad:
- if (fd >= 0)
- close(fd);
- free(p);
- return (NULL);
-}
-
-int
-pcap_setfilter(pcap_t *p, struct bpf_program *fp)
-{
-
- p->fcode = *fp;
- return (0);
-}
diff --git a/lib/libpcap/pcap-snoop.c b/lib/libpcap/pcap-snoop.c
deleted file mode 100644
index 50f9785..0000000
--- a/lib/libpcap/pcap-snoop.c
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Copyright (c) 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that: (1) source code distributions
- * retain the above copyright notice and this paragraph in its entirety, (2)
- * distributions including binary code include the above copyright notice and
- * this paragraph in its entirety in the documentation or other materials
- * provided with the distribution, and (3) all advertising materials mentioning
- * features or use of this software display the following acknowledgement:
- * ``This product includes software developed by the University of California,
- * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
- * the University nor the names of its contributors may be used to endorse
- * or promote products derived from this software without specific prior
- * written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-#ifndef lint
-static char rcsid[] =
- "@(#)$Header: pcap-snoop.c,v 1.6 94/01/31 05:26:09 leres Exp $ (LBL)";
-#endif
-
-#include <sys/param.h>
-#include <stdio.h>
-#include <netdb.h>
-#include <ctype.h>
-#include <signal.h>
-#include <errno.h>
-#include <sys/time.h>
-#include <sys/socket.h>
-#include <sys/file.h>
-#include <sys/ioctl.h>
-
-#include <net/raw.h>
-
-#include <net/if.h>
-#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#include <netinet/if_ether.h>
-#include <netinet/ip_var.h>
-#include <netinet/udp.h>
-#include <netinet/udp_var.h>
-#include <netinet/tcp.h>
-#include <netinet/tcpip.h>
-#include <net/bpf.h>
-
-#include "pcap-int.h"
-
-static int hdrpad; /* XXX */
-
-int
-pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
-{
- int cc;
- register struct snoopheader *sh;
- register int datalen;
- register int caplen;
- register u_char *cp;
- again:
- cc = read(p->fd, (char *)p->buffer, p->bufsize);
- if (cc < 0) {
- switch (errno) {
- case EWOULDBLOCK:
- return (0); /* XXX */
- }
- sprintf(p->errbuf, "read: %s", pcap_strerror(errno));
- return (-1);
- }
- sh = (struct snoopheader *)p->buffer;
- datalen = sh->snoop_packetlen;
- caplen = (datalen < p->snapshot) ? datalen : p->snapshot;
- cp = (u_char *)(sh + 1) + hdrpad; /* XXX */
-
- if (p->fcode.bf_insns == NULL ||
- bpf_filter(p->fcode.bf_insns, cp, datalen, caplen)) {
- struct pcap_pkthdr h;
- ++p->md.stat.ps_recv;
- h.ts = sh->snoop_timestamp;
- h.len = datalen;
- h.caplen = caplen;
- (*callback)(user, &h, cp);
- return (1);
- }
- return (0);
-}
-
-int
-pcap_stats(pcap_t *p, struct pcap_stat *ps)
-{
- register struct rawstats *rs;
- struct rawstats rawstats;
-
- rs = &rawstats;
- bzero((char *)rs, sizeof(*rs));
- if (ioctl(p->fd, SIOCRAWSTATS, (char *)rs) < 0) {
- sprintf(p->errbuf, "SIOCRAWSTATS: %s", pcap_strerror(errno));
- return (-1);
- }
-
- p->md.stat.ps_drop =
- rs->rs_snoop.ss_ifdrops + rs->rs_snoop.ss_sbdrops +
- rs->rs_drain.ds_ifdrops + rs->rs_drain.ds_sbdrops;
-
- *ps = p->md.stat;
- return (0);
-}
-
-/* XXX can't disable promiscuous */
-pcap_t *
-pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
-{
- pcap_t *p;
- struct sockaddr_raw sr;
- int fd;
- int v;
- struct snoopfilter sf;
-
- p = (pcap_t *)malloc(sizeof(*p));
- if (p == NULL) {
- strcpy(ebuf, "no swap");
- return (0);
- }
- bzero(p, sizeof(*p));
- p->fd = -1;
- p->bufsize = 4096; /* XXX */
- p->buffer = (u_char *)malloc(p->bufsize);
- if (p->buffer == NULL) {
- strcpy(ebuf, "no swap");
- goto bad;
- }
- fd = p->fd = socket(PF_RAW, SOCK_RAW, RAWPROTO_SNOOP);
- if (fd < 0) {
- sprintf(ebuf, "snoop socket: %s", pcap_strerror(errno));
- goto bad;
- }
- sr.sr_family = AF_RAW;
- sr.sr_port = 0;
- (void)strncpy(sr.sr_ifname, device, sizeof(sr.sr_ifname));
- if (bind(fd, (struct sockaddr *)&sr, sizeof(sr))) {
- sprintf(ebuf, "snoop bind: %s", pcap_strerror(errno));
- goto bad;
- }
- bzero((char *)&sf, sizeof(sf));
- if (ioctl(fd, SIOCADDSNOOP, &sf) < 0) {
- sprintf(ebuf, "SIOCADDSNOOP: %s", pcap_strerror(errno));
- goto bad;
- }
- v = 64 * 1024;
- (void)setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (char *)&v, sizeof(v));
- if (ioctl(fd, SIOCSNOOPLEN, &snaplen) < 0) {
- sprintf(ebuf, "SIOCSNOOPLEN: %s", pcap_strerror(errno));
- goto bad;
- }
- p->snapshot = snaplen;
- v = 1;
- if (ioctl(fd, SIOCSNOOPING, &v) < 0) {
- sprintf(ebuf, "SIOCSNOOPING: %s", pcap_strerror(errno));
- goto bad;
- }
- /*
- * XXX hack - map device name to link later type
- */
- if (strncmp("et", device, 2) == 0 ||
- strncmp("ec", device, 2) == 0) {
- p->linktype = DLT_EN10MB;
- hdrpad = RAW_HDRPAD(sizeof(struct ether_header));
- } else if (strncmp("ipg", device, 3) == 0 ||
- strncmp("xpi", device, 3) == 0) {
- p->linktype = DLT_FDDI;
- hdrpad = 3; /* XXX yeah? */
- } else {
- sprintf(ebuf, "snoop: unknown physical layer type");
- goto bad;
- }
- return (p);
- bad:
- if (fd >= 0)
- close(fd);
- if (p->buffer != NULL)
- free(p->buffer);
- free(p);
- return (0);
-}
-
-int
-pcap_setfilter(pcap_t *p, struct bpf_program *fp)
-{
-
- p->fcode = *fp;
- return (0);
-}
diff --git a/lib/libpcap/pcap.3 b/lib/libpcap/pcap.3
deleted file mode 100644
index d298b40..0000000
--- a/lib/libpcap/pcap.3
+++ /dev/null
@@ -1,325 +0,0 @@
-.\" Copyright (c) 1994
-.\" The Regents of the University of California. All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that: (1) source code distributions
-.\" retain the above copyright notice and this paragraph in its entirety, (2)
-.\" distributions including binary code include the above copyright notice and
-.\" this paragraph in its entirety in the documentation or other materials
-.\" provided with the distribution, and (3) all advertising materials mentioning
-.\" features or use of this software display the following acknowledgement:
-.\" ``This product includes software developed by the University of California,
-.\" Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
-.\" the University nor the names of its contributors may be used to endorse
-.\" or promote products derived from this software without specific prior
-.\" written permission.
-.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
-.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
-.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
-.\"
-.TH PCAP 3 "14 Jun 1994"
-.SH NAME
-pcap \- Packet Capture library
-.SH SYNOPSIS
-.nf
-.ft B
-#include <sys/types.h>
-#include <stdio.h>
-#include <pcap.h>
-.ft
-.LP
-.ft B
-pcap_t *pcap_open_live(char *device, int snaplen,
-.ti +8
-int promisc, int to_ms, char *ebuf)
-pcap_t *pcap_open_offline(char *fname, char *ebuf)
-pcap_dumper_t *pcap_dump_open(pcap_t *p, char *fname)
-.ft
-.LP
-.ft B
-char errbuf[PCAP_ERRBUF_SIZE];
-char *pcap_lookupdev(char *errbuf)
-int pcap_lookupnet(char *device, u_long *netp,
-.ti +8
-u_long *maskp, char *errbuf)
-.ft
-.LP
-.ft B
-int pcap_dispatch(pcap_t *p, int cnt,
-.ti +8
-pcap_handler callback, u_char *user)
-int pcap_loop(pcap_t *p, int cnt,
-.ti +8
-pcap_handler callback, u_char *user)
-void pcap_dump(u_char *user, struct pcap_pkthdr *h,
-.ti +8
-u_char *sp)
-.ft
-.LP
-.ft B
-int pcap_immediate(pcap_t *p)
-.ft
-.LP
-.ft B
-int pcap_compile(pcap_t *p, struct bpf_program *fp,
-.ti +8
-char *str, int optimize, u_long netmask)
-int pcap_setfilter(pcap_t *p, struct bpf_program *fp)
-.ft
-.LP
-.ft B
-u_char *pcap_next(pcap_t *p, struct pcap_pkthdr *h)
-.ft
-.LP
-.ft B
-int pcap_datalink(pcap_t *p)
-int pcap_snapshot(pcap_t *p)
-int pcap_is_swapped(pcap_t *p)
-int pcap_major_version(pcap_t *p)
-int pcap_minor_version(pcap_t *p)
-int pcap_stats(pcap_t *p, struct pcap_stat *ps)
-FILE *pcap_file(pcap_t *p)
-int pcap_fileno(pcap_t *p)
-void pcap_perror(pcap_t *p, char *prefix)
-char *pcap_geterr(pcap_t *p)
-char *pcap_strerror(int error)
-.ft
-.LP
-.ft B
-void pcap_close(pcap_t *p)
-void pcap_dump_close(pcap_dumper_t *p)
-.ft
-.fi
-.SH DESCRIPTION
-The Packet Capture library
-provides a high level interface to packet capture systems. All packets
-on the network, even those destined for other hosts, are accessible
-through this mechanism.
-.PP
-.SH ROUTINES
-.B pcap_open_live()
-is used to obtain a packet capture descriptor to look
-at packets on the network.
-.I device
-is a string that specifies the network device to open.
-.I snaplen
-specifies the maximum number of bytes to capture.
-.I to_ms
-specifies the read timeout in milliseconds.
-.I ebuf
-is used to return error text and is only set when
-.B pcap_open_live()
-fails and returns
-.BR NULL .
-.PP
-.B pcap_open_offline()
-is called to open a ``savefile'' for reading.
-.I fname
-specifies the name of the file to open. The file has
-the same format as those used by
-.B tcpdump(1)
-and
-.BR tcpslice(1) .
-The name "-" in a synonym for
-.BR stdin .
-.I ebuf
-is used to return error text and is only set when
-.B pcap_open_offline()
-fails and returns
-.BR NULL .
-.PP
-.B pcap_dump_open()
-is called to open a ``savefile'' for writing. The name "-" in a synonym
-for
-.BR stdin .
-.B NULL
-is returned on failure.
-.I p
-is a
-.I pcap
-struct as returned by
-.B pcap_open_offline()
-or
-.BR pcap_open_live() .
-.I fname
-specifies the name of the file to open.
-If
-.B NULL
-is returned,
-.B pcap_geterr()
-can be used to get the error text.
-.PP
-.B pcap_lookupdev()
-returns a pointer to a network device suitable for use with
-.B pcap_open_live()
-and
-.BR pcap_lookupnet() .
-If there is an error,
-.B NULL
-is returned and
-.I errbuf
-is filled in with with an appropriate error message.
-.PP
-.B pcap_lookupnet()
-is used to determine the network number and mask
-associated with the network device
-.BR device .
-Both
-.I netp
-and
-.I maskp
-are
-.I u_long
-pointers.
-A return of -1 indicates an error in which case
-.I errbuf
-is filled in with with an appropriate error message.
-.PP
-.B pcap_dispatch()
-is used to collect and process packets.
-.I cnt
-specifies the maximum number of packets to process before returning. A
-.I cnt
-of -1 processes all the packets received in one buffer. A
-.I cnt
-of 0 processes all packets until an error occurs (or
-.B EOF
-is reached).
-.I callback
-specifies a routine to be called with three arguments:
-a
-.I u_char
-pointer which is passed in from
-.BR pcap_dispatch() ,
-a pointer to the
-.I pcap_pkthdr
-struct (which precede the actual network headers and data),
-and a length. The number of packets read is returned.
-Zero is returned when
-.B EOF
-is reached in a ``savefile.'' A return of -1 indicates
-an error in which case
-.B pcap_perror()
-or
-.BR pcap_geterr()
-may be used to display the error text.
-.PP
-.B pcap_dump()
-outputs a packet to the ``savefile'' opened with
-.BR pcap_dump_open() .
-Note that its calling arguments are suitable for use with
-.BR pcap_dispatch() .
-.ft B
-(??? this guy is kind of weird.)
-.ft
-.PP
-.B pcap_immediate()
-sets ``immediate'' mode.
-If this isn't supported by the under lying packet capture, -1 is
-returned and the error text can be obtained with
-.B pcap_perror()
-or
-.BR pcap_geterr() .
-.PP
-.B pcap_compile()
-is used to compile the string
-.I str
-into a filter program.
-.I program
-is a pointer to a
-.I bpf_program
-struct and is filled in by
-.BR pcap_compile() .
-.I optimize
-controls whether optimization on the resulting code is performed.
-.I netmask
-specifies the netmask of the local net.
-.PP
-.B pcap_setfilter()
-is used to specify the a filter program.
-.I fp
-is a pointer to an array of
-.I bpf_program
-struct, usually the result of a call to
-.BR pcap_compile() .
-.PP
-.B pcap_loop()
-is similar to
-.B pcap_dispatch()
-except it keeps reading packets until
-.I cnt
-packets are processed or an error occurs.
-A negative
-.I cnt
-causes
-.B pcap_loop()
-to loop forever (or at least until an error occurs).
-.PP
-.B pcap_next()
-returns a
-.I u_char
-pointer to the next packet.
-.PP
-.B pcap_datalink()
-returns the link layer type, e.g.
-.BR DLT_EN10MB .
-.PP
-.B pcap_snapshot()
-returns the snapshot length specified when
-.B pcap_open_live
-was called.
-.PP
-.B pcap_is_swapped()
-returns true if the current ``savefile'' uses a different byte order
-than the current system.
-.PP
-.B pcap_major_version()
-returns the major number of the version of the pcap used to write the
-savefile.
-.PP
-.B pcap_minor_version()
-returns the major number of the version of the pcap used to write the
-savefile.
-.PP
-.B pcap_file()
-returns the name of the ``savefile.''
-.PP
-.B int pcap_stats()
-returns 0 and fills in a
-.B pcap_stat
-struct with packet statistics. If there is an error or the under lying
-packet capture doesn't support packet statistics, -1 is returned and
-the error text can be obtained with
-.B pcap_perror()
-or
-.BR pcap_geterr() .
-.PP
-.B pcap_fileno()
-returns the file descriptor number of the ``savefile.''
-.PP
-.B pcap_perror()
-prints the text of the last pcap library error on
-.BR stderr ,
-prefixed by
-.IR prefix .
-.PP
-.B pcap_geterr()
-returns the error text pertaining to the last pcap library error.
-.PP
-.B pcap_strerror()
-is provided in case
-.BR strerror (1)
-isn't available.
-.PP
-.B pcap_close()
-closes the files associated with
-.I p
-and deallocates resources.
-.PP
-.B pcap_dump_close()
-closes the ``savefile.''
-.PP
-.SH SEE ALSO
-tcpdump(1), tcpslice(1)
-.SH BUGS
-.SH HISTORY
diff --git a/lib/libpcap/pcap.c b/lib/libpcap/pcap.c
deleted file mode 100644
index 398b6f3..0000000
--- a/lib/libpcap/pcap.c
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Copyright (c) 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the Computer Systems
- * Engineering Group at Lawrence Berkeley Laboratory.
- * 4. Neither the name of the University nor of the Laboratory may be used
- * to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-static char rcsid[] =
- "@(#) $Header: /home/ncvs/src/lib/libpcap/pcap.c,v 1.3 1995/05/30 05:47:24 rgrimes Exp $ (LBL)";
-#endif
-
-#include <sys/types.h>
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-
-#include "pcap-int.h"
-
-int
-pcap_dispatch(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
-{
- if (p->sf.rfile != NULL)
- return (pcap_offline_read(p, cnt, callback, user));
- else
- return (pcap_read(p, cnt, callback, user));
-}
-
-int
-pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
-{
- for (;;) {
- int n = pcap_dispatch(p, cnt, callback, user);
- if (n < 0)
- return (n);
- if (cnt > 0) {
- cnt -= n;
- if (cnt <= 0)
- return (0);
- }
- }
-}
-
-struct singleton {
- struct pcap_pkthdr *hdr;
- const u_char *pkt;
-};
-
-
-static void
-pcap_oneshot(u_char *userData, const struct pcap_pkthdr *h, const u_char *pkt)
-{
- struct singleton *sp = (struct singleton *)userData;
- *sp->hdr = *h;
- sp->pkt = pkt;
-}
-
-const u_char *
-pcap_next(pcap_t *p, struct pcap_pkthdr *h)
-{
- struct singleton s;
-
- s.hdr = h;
- if (pcap_dispatch(p, 1, pcap_oneshot, (u_char*)&s) < 0)
- return (0);
- return (s.pkt);
-}
-
-int
-pcap_datalink(pcap_t *p)
-{
- return (p->linktype);
-}
-
-int
-pcap_snapshot(pcap_t *p)
-{
- return (p->snapshot);
-}
-
-int
-pcap_is_swapped(pcap_t *p)
-{
- return (p->sf.swapped);
-}
-
-int
-pcap_major_version(pcap_t *p)
-{
- return (p->sf.version_major);
-}
-
-int
-pcap_minor_version(pcap_t *p)
-{
- return (p->sf.version_minor);
-}
-
-FILE *
-pcap_file(pcap_t *p)
-{
- return (p->sf.rfile);
-}
-
-int
-pcap_fileno(pcap_t *p)
-{
- return (p->fd);
-}
-
-void
-pcap_perror(pcap_t *p, char *prefix)
-{
- fprintf(stderr, "%s: %s\n", prefix, p->errbuf);
-}
-
-char *
-pcap_geterr(pcap_t *p)
-{
- return (p->errbuf);
-}
-
-/*
- * Not all systems have strerror().
- */
-char *
-pcap_strerror(int errnum)
-{
- return strerror(errnum);
-}
-
-void
-pcap_close(pcap_t *p)
-{
- /*XXX*/
- if (p->fd >= 0)
- close(p->fd);
- if (p->sf.rfile != NULL) {
- fclose(p->sf.rfile);
- if (p->sf.base != NULL)
- free(p->sf.base);
- } else if (p->buffer != NULL)
- free(p->buffer);
-
- free(p);
-}
diff --git a/lib/libpcap/pcap.h b/lib/libpcap/pcap.h
deleted file mode 100644
index 506b15b..0000000
--- a/lib/libpcap/pcap.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (c) 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the Computer Systems
- * Engineering Group at Lawrence Berkeley Laboratory.
- * 4. Neither the name of the University nor of the Laboratory may be used
- * to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#) $Header: pcap.h,v 1.15 94/06/14 20:03:34 leres Exp $ (LBL)
- */
-
-#ifndef lib_pcap_h
-#define lib_pcap_h
-
-#include <sys/types.h>
-#include <sys/time.h>
-
-#include <net/bpf.h>
-
-#include <stdio.h>
-
-#define PCAP_VERSION_MAJOR 2
-#define PCAP_VERSION_MINOR 4
-
-#define PCAP_ERRBUF_SIZE 256
-
-/*
- * Compatibility for systems that have a bpf.h that
- * predates the bpf typedefs for 64-bit support.
- */
-#if BPF_RELEASE - 0 < 199406
-typedef long bpf_int32;
-typedef u_long bpf_u_int32;
-#endif
-
-typedef struct pcap pcap_t;
-typedef struct pcap_dumper pcap_dumper_t;
-
-/*
- * The first record in the file contains saved values for some
- * of the flags used in the printout phases of tcpdump.
- * Many fields here are longs so compilers won't insert unwanted
- * padding; these files need to be interchangeable across architectures.
- */
-struct pcap_file_header {
- bpf_u_int32 magic;
- u_short version_major;
- u_short version_minor;
- bpf_int32 thiszone; /* gmt to local correction */
- bpf_u_int32 sigfigs; /* accuracy of timestamps */
- bpf_u_int32 snaplen; /* max length saved portion of each pkt */
- bpf_u_int32 linktype; /* data link type (DLT_*) */
-};
-
-/*
- * Each packet in the dump file is prepended with this generic header.
- * This gets around the problem of different headers for different
- * packet interfaces.
- */
-struct pcap_pkthdr {
- struct timeval ts; /* time stamp */
- bpf_u_int32 caplen; /* length of portion present */
- bpf_u_int32 len; /* length this packet (off wire) */
-};
-
-/*
- * As returned by the pcap_stats()
- */
-struct pcap_stat {
- u_int ps_recv; /* number of packets received */
- u_int ps_drop; /* number of packets dropped */
- u_int ps_ifdrop; /* drops by interface XXX not yet supported */
-};
-
-typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *,
- const u_char *);
-
-char *pcap_lookupdev(char *);
-int pcap_lookupnet(char *, u_long *, u_long *, char *);
-pcap_t *pcap_open_live(char *, int, int, int, char *);
-pcap_t *pcap_open_offline(char *, char *);
-void pcap_close(pcap_t *);
-int pcap_loop(pcap_t *, int, pcap_handler, u_char *);
-int pcap_dispatch(pcap_t *, int, pcap_handler, u_char *);
-const u_char*
- pcap_next(pcap_t *, struct pcap_pkthdr *);
-int pcap_stats(pcap_t *, struct pcap_stat *);
-int pcap_setfilter(pcap_t *, struct bpf_program *);
-void pcap_perror(pcap_t *, char *);
-char *pcap_strerror(int);
-char *pcap_geterr(pcap_t *);
-int pcap_compile(pcap_t *, struct bpf_program *, char *, int, u_long);
-/* XXX */
-int pcap_freecode(pcap_t *, struct bpf_program *);
-int pcap_datalink(pcap_t *);
-int pcap_snapshot(pcap_t *);
-int pcap_is_swapped(pcap_t *);
-int pcap_major_version(pcap_t *);
-int pcap_minor_version(pcap_t *);
-
-/* XXX */
-FILE *pcap_file(pcap_t *);
-int pcap_fileno(pcap_t *);
-
-pcap_dumper_t *pcap_dump_open(pcap_t *, char *);
-void pcap_dump_close(pcap_dumper_t *);
-void pcap_dump(u_char *, const struct pcap_pkthdr *, const u_char *);
-
-/* XXX this guy lives in the bpf tree */
-u_int bpf_filter(struct bpf_insn *, u_char *, u_int, u_int);
-char *bpf_image(struct bpf_insn *, int);
-
-#endif
diff --git a/lib/libpcap/savefile.c b/lib/libpcap/savefile.c
deleted file mode 100644
index 90ee723..0000000
--- a/lib/libpcap/savefile.c
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * Copyright (c) 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that: (1) source code distributions
- * retain the above copyright notice and this paragraph in its entirety, (2)
- * distributions including binary code include the above copyright notice and
- * this paragraph in its entirety in the documentation or other materials
- * provided with the distribution, and (3) all advertising materials mentioning
- * features or use of this software display the following acknowledgement:
- * ``This product includes software developed by the University of California,
- * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
- * the University nor the names of its contributors may be used to endorse
- * or promote products derived from this software without specific prior
- * written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-#ifndef lint
-static char rcsid[] =
- "@(#)$Header: savefile.c,v 1.16 94/06/20 19:07:56 leres Exp $ (LBL)";
-#endif
-
-/*
- * savefile.c - supports offline use of tcpdump
- * Extraction/creation by Jeffrey Mogul, DECWRL
- * Modified by Steve McCanne, LBL.
- *
- * Used to save the received packet headers, after filtering, to
- * a file, and then read them later.
- * The first record in the file contains saved values for the machine
- * dependent values so we can print the dump file on any architecture.
- */
-
-#include <sys/types.h>
-#include <sys/time.h>
-
-#include <net/bpf.h>
-
-#include <errno.h>
-#include <memory.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include "pcap-int.h"
-
-#define TCPDUMP_MAGIC 0xa1b2c3d4
-
-/*
- * We use the "receiver-makes-right" approach to byte order,
- * because time is at a premium when we are writing the file.
- * In other words, the pcap_file_header and pcap_pkthdr,
- * records are written in host byte order.
- * Note that the packets are always written in network byte order.
- *
- * ntoh[ls] aren't sufficient because we might need to swap on a big-endian
- * machine (if the file was written in little-end order).
- */
-#define SWAPLONG(y) \
-((((y)&0xff)<<24) | (((y)&0xff00)<<8) | (((y)&0xff0000)>>8) | (((y)>>24)&0xff))
-#define SWAPSHORT(y) \
- ( (((y)&0xff)<<8) | (((y)&0xff00)>>8) )
-
-#define SFERR_TRUNC 1
-#define SFERR_BADVERSION 2
-#define SFERR_BADF 3
-#define SFERR_EOF 4 /* not really an error, just a status */
-
-static int
-sf_write_header(FILE *fp, int linktype, int thiszone, int snaplen)
-{
- struct pcap_file_header hdr;
-
- hdr.magic = TCPDUMP_MAGIC;
- hdr.version_major = PCAP_VERSION_MAJOR;
- hdr.version_minor = PCAP_VERSION_MINOR;
-
- hdr.thiszone = thiszone;
- hdr.snaplen = snaplen;
- hdr.sigfigs = 0;
- hdr.linktype = linktype;
-
- if (fwrite((char *)&hdr, sizeof(hdr), 1, fp) != 1)
- return (-1);
-
- return (0);
-}
-
-static void
-swap_hdr(struct pcap_file_header *hp)
-{
- hp->version_major = SWAPSHORT(hp->version_major);
- hp->version_minor = SWAPSHORT(hp->version_minor);
- hp->thiszone = SWAPLONG(hp->thiszone);
- hp->sigfigs = SWAPLONG(hp->sigfigs);
- hp->snaplen = SWAPLONG(hp->snaplen);
- hp->linktype = SWAPLONG(hp->linktype);
-}
-
-pcap_t *
-pcap_open_offline(char *fname, char *errbuf)
-{
- register pcap_t *p;
- register FILE *fp;
- struct pcap_file_header hdr;
- int linklen;
-
- p = (pcap_t *)malloc(sizeof(*p));
- if (p == NULL) {
- strcpy(errbuf, "out of swap");
- return (NULL);
- }
-
-#ifdef notdef
- bzero(p, sizeof(*p));
-#else
- memset(p, 0, sizeof(*p));
-#endif
- /*
- * Set this field so we don't close stdin in pcap_close!
- */
- p->fd = -1;
-
- if (fname[0] == '-' && fname[1] == '\0')
- fp = stdin;
- else {
- fp = fopen(fname, "r");
- if (fp == NULL) {
- sprintf(errbuf, "%s: %s", fname, pcap_strerror(errno));
- goto bad;
- }
- }
- if (fread((char *)&hdr, sizeof(hdr), 1, fp) != 1) {
- sprintf(errbuf, "fread: %s", pcap_strerror(errno));
- goto bad;
- }
- if (hdr.magic != TCPDUMP_MAGIC) {
- if (SWAPLONG(hdr.magic) != TCPDUMP_MAGIC) {
- sprintf(errbuf, "bad dump file format");
- goto bad;
- }
- p->sf.swapped = 1;
- swap_hdr(&hdr);
- }
- if (hdr.version_major < PCAP_VERSION_MAJOR) {
- sprintf(errbuf, "archaic file format");
- goto bad;
- }
- p->tzoff = hdr.thiszone;
- p->snapshot = hdr.snaplen;
- p->linktype = hdr.linktype;
- p->sf.rfile = fp;
- p->bufsize = hdr.snaplen;
- /* Align link header as required for proper data alignment */
- linklen = 14; /* XXX */
- p->sf.base = (u_char *)malloc(p->bufsize + BPF_ALIGNMENT);
- p->buffer = p->sf.base + BPF_ALIGNMENT - (linklen % BPF_ALIGNMENT);
- p->sf.version_major = hdr.version_major;
- p->sf.version_minor = hdr.version_minor;
-
- return (p);
- bad:
- free(p);
- return (NULL);
-}
-
-/*
- * Read sf_readfile and return the next packet. Return the header in hdr
- * and the contents in buf. Return 0 on success, SFERR_EOF if there were
- * no more packets, and SFERR_TRUNC if a partial packet was encountered.
- */
-static int
-sf_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char *buf, int buflen)
-{
- FILE *fp = p->sf.rfile;
-
- /* read the stamp */
- if (fread((char *)hdr, sizeof(struct pcap_pkthdr), 1, fp) != 1) {
- /* probably an EOF, though could be a truncated packet */
- return (1);
- }
-
- if (p->sf.swapped) {
- /* these were written in opposite byte order */
- hdr->caplen = SWAPLONG(hdr->caplen);
- hdr->len = SWAPLONG(hdr->len);
- hdr->ts.tv_sec = SWAPLONG(hdr->ts.tv_sec);
- hdr->ts.tv_usec = SWAPLONG(hdr->ts.tv_usec);
- }
- /*
- * We interchanged the caplen and len fields at version 2.3,
- * in order to match the bpf header layout. But unfortunately
- * some files were written with version 2.3 in their headers
- * but without the interchanged fields.
- */
- if (p->sf.version_minor < 3 ||
- (p->sf.version_minor == 3 && hdr->caplen > hdr->len)) {
- int t = hdr->caplen;
- hdr->caplen = hdr->len;
- hdr->len = t;
- }
-
- if (hdr->caplen > buflen) {
- sprintf(p->errbuf, "bad dump file format");
- return (-1);
- }
-
- /* read the packet itself */
-
- if (fread((char *)buf, hdr->caplen, 1, fp) != 1) {
- sprintf(p->errbuf, "truncated dump file");
- return (-1);
- }
- return (0);
-}
-
-/*
- * Print out packets stored in the file initialized by sf_read_init().
- * If cnt > 0, return after 'cnt' packets, otherwise continue until eof.
- */
-int
-pcap_offline_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
-{
- struct bpf_insn *fcode = p->fcode.bf_insns;
- int status = 0;
- int n = 0;
-
- while (status == 0) {
- struct pcap_pkthdr h;
-
- status = sf_next_packet(p, &h, p->buffer, p->bufsize);
- if (status)
- return (-1);
-
- if (fcode == NULL ||
- bpf_filter(fcode, p->buffer, h.len, h.caplen)) {
- (*callback)(user, &h, p->buffer);
- if (++n >= cnt && cnt > 0)
- break;
- }
- }
- /*XXX this breaks semantics tcpslice expects */
- return (n);
-}
-
-/*
- * Output a packet to the initialized dump file.
- */
-void
-pcap_dump(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
-{
- FILE * f = (FILE *)user;
- (void)fwrite((char *)h, sizeof(*h), 1, f);
- (void)fwrite((char *)sp, h->caplen, 1, f);
-}
-
-/*
- * Initialize so that sf_write() will output to the file named 'fname'.
- */
-pcap_dumper_t *
-pcap_dump_open(pcap_t *p, char *fname)
-{
- FILE *f;
- if (fname[0] == '-' && fname[1] == '\0')
- f = stdout;
- else {
- f = fopen(fname, "w");
- if (f == NULL) {
- sprintf(p->errbuf, "%s: %s",
- fname, pcap_strerror(errno));
- return (NULL);
- }
- }
- (void)sf_write_header(f, p->linktype, p->tzoff, p->snapshot);
- return ((pcap_dumper_t *)f);
-}
-
-void
-pcap_dump_close(pcap_dumper_t *p)
-{
- fclose((FILE *)p);
-}
diff --git a/lib/libpcap/scanner.l b/lib/libpcap/scanner.l
deleted file mode 100644
index c2ff10d..0000000
--- a/lib/libpcap/scanner.l
+++ /dev/null
@@ -1,193 +0,0 @@
-%{
-/*
- * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that: (1) source code distributions
- * retain the above copyright notice and this paragraph in its entirety, (2)
- * distributions including binary code include the above copyright notice and
- * this paragraph in its entirety in the documentation or other materials
- * provided with the distribution, and (3) all advertising materials mentioning
- * features or use of this software display the following acknowledgement:
- * ``This product includes software developed by the University of California,
- * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
- * the University nor the names of its contributors may be used to endorse
- * or promote products derived from this software without specific prior
- * written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef lint
-static char rcsid[] =
- "@(#) $Header: scanner.l,v 1.40 94/06/10 17:21:44 mccanne Exp $ (LBL)";
-#endif
-
-#include <sys/types.h>
-#include <sys/time.h>
-
-#include <ctype.h>
-#include <pcap.h>
-#include <pcap-namedb.h>
-
-#include "gencode.h"
-#include "tokdefs.h"
-
-#ifndef __GNUC__
-#define inline
-#endif
-
-static int stoi(char *);
-static inline int xdtoi(int);
-
-#ifdef FLEX_SCANNER
-#undef YY_INPUT
-#define YY_INPUT(buf, result, max)\
- {\
- char *src = in_buffer;\
- int i;\
-\
- if (*src == 0)\
- result = YY_NULL;\
- else {\
- for (i = 0; *src && i < max; ++i)\
- buf[i] = *src++;\
- in_buffer += i;\
- result = i;\
- }\
- }
-#else
-#undef getc
-#define getc(fp) (*in_buffer == 0 ? EOF : *in_buffer++)
-#endif
-
-#define yylval pcap_lval
-extern YYSTYPE yylval;
-
-static char *in_buffer;
-
-%}
-
-N ([0-9]+|(0X|0x)[0-9A-Fa-f]+)
-B ([0-9A-Fa-f][0-9A-Fa-f]?)
-
-%a 3000
-
-%%
-dst return DST;
-src return SRC;
-
-link|ether|ppp|slip return LINK;
-fddi return LINK;
-arp return ARP;
-rarp return RARP;
-ip return IP;
-tcp return TCP;
-udp return UDP;
-icmp return ICMP;
-
-decnet return DECNET;
-lat return LAT;
-moprc return MOPRC;
-mopdl return MOPDL;
-
-host return HOST;
-net return NET;
-port return PORT;
-proto return PROTO;
-
-gateway return GATEWAY;
-
-less return LESS;
-greater return GREATER;
-byte return BYTE;
-broadcast return TK_BROADCAST;
-multicast return TK_MULTICAST;
-
-and|"&&" return AND;
-or|"||" return OR;
-not return '!';
-
-len|length return LEN;
-inbound return INBOUND;
-outbound return OUTBOUND;
-
-[ \n\t] ;
-[+\-*/:\[\]!<>()&|=] return yytext[0];
-">=" return GEQ;
-"<=" return LEQ;
-"!=" return NEQ;
-"==" return '=';
-"<<" return LSH;
-">>" return RSH;
-{N} { yylval.i = stoi((char *)yytext); return NUM; }
-({N}\.{N})|({N}\.{N}\.{N})|({N}\.{N}\.{N}\.{N}) {
- yylval.s = sdup((char *)yytext); return HID;
-}
-{B}:{B}:{B}:{B}:{B}:{B} { yylval.e = pcap_ether_aton((char *)yytext);
- return EID; }
-{B}:+({B}:+)+ { bpf_error("bogus ethernet address %s", yytext); }
-[A-Za-z][-_.A-Za-z0-9]* { yylval.s = sdup((char *)yytext); return ID; }
-"\\"[^ !()\n\t]+ { yylval.s = sdup((char *)yytext + 1); return ID; }
-[^ \[\]\t\n\-_.A-Za-z0-9!<>()&|=]+ { bpf_error("illegal token: %s\n", yytext); }
-. { bpf_error("illegal char '%c'", *yytext); }
-%%
-void
-lex_init(buf)
- char *buf;
-{
- in_buffer = buf;
-}
-
-/*
- * Also define a yywrap. Note that if we're using flex, it will
- * define a macro to map this identifier to pcap_wrap.
- */
-int
-yywrap()
-{
- return 1;
-}
-
-/* Hex digit to integer. */
-static inline int
-xdtoi(c)
- register int c;
-{
- if (isdigit(c))
- return c - '0';
- else if (islower(c))
- return c - 'a' + 10;
- else
- return c - 'A' + 10;
-}
-
-/*
- * Convert string to integer. Just like atoi(), but checks for
- * preceding 0x or 0 and uses hex or octal instead of decimal.
- */
-static int
-stoi(s)
- char *s;
-{
- int base = 10;
- int n = 0;
-
- if (*s == '0') {
- if (s[1] == 'x' || s[1] == 'X') {
- s += 2;
- base = 16;
- }
- else {
- base = 8;
- s += 1;
- }
- }
- while (*s)
- n = n * base + xdtoi(*s++);
-
- return n;
-}
-
OpenPOWER on IntegriCloud