summaryrefslogtreecommitdiffstats
path: root/contrib
diff options
context:
space:
mode:
authorbms <bms@FreeBSD.org>2004-03-31 09:15:09 +0000
committerbms <bms@FreeBSD.org>2004-03-31 09:15:09 +0000
commit723e16349061e4b947ce1e5be04cdf68e1441b71 (patch)
treea52a0e75c26441516b30999e491e6efdcd6f19a7 /contrib
parent5e21f2192eb7b5433d2bcb7bd232f10e704d761e (diff)
downloadFreeBSD-src-723e16349061e4b947ce1e5be04cdf68e1441b71.zip
FreeBSD-src-723e16349061e4b947ce1e5be04cdf68e1441b71.tar.gz
Merge of libpcap 0.8.3 from tcpdump.org.
Diffstat (limited to 'contrib')
-rw-r--r--contrib/libpcap/bpf/net/bpf.h417
-rw-r--r--contrib/libpcap/gencode.c2177
-rw-r--r--contrib/libpcap/gencode.h100
-rw-r--r--contrib/libpcap/grammar.y113
-rw-r--r--contrib/libpcap/nametoaddr.c94
-rw-r--r--contrib/libpcap/nlpid.h17
-rw-r--r--contrib/libpcap/packaging/pcap.spec65
-rw-r--r--contrib/libpcap/pcap-int.h95
-rw-r--r--contrib/libpcap/pcap.3495
-rw-r--r--contrib/libpcap/pcap.h57
-rw-r--r--contrib/libpcap/scanner.l69
11 files changed, 2781 insertions, 918 deletions
diff --git a/contrib/libpcap/bpf/net/bpf.h b/contrib/libpcap/bpf/net/bpf.h
deleted file mode 100644
index 405842e..0000000
--- a/contrib/libpcap/bpf/net/bpf.h
+++ /dev/null
@@ -1,417 +0,0 @@
-/*-
- * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
- * 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.h 7.1 (Berkeley) 5/7/91
- *
- * @(#) $Header: /tcpdump/master/libpcap/bpf/net/bpf.h,v 1.51 2001/11/28 05:50:05 guy Exp $ (LBL)
- *
- * $FreeBSD$
- */
-
-#ifndef BPF_MAJOR_VERSION
-
-/* BSD style release date */
-#define BPF_RELEASE 199606
-
-typedef int bpf_int32;
-typedef u_int bpf_u_int32;
-
-/*
- * Alignment macros. BPF_WORDALIGN rounds up to the next
- * even multiple of BPF_ALIGNMENT.
- */
-#define BPF_ALIGNMENT sizeof(bpf_int32)
-#define BPF_WORDALIGN(x) (((x)+(BPF_ALIGNMENT-1))&~(BPF_ALIGNMENT-1))
-
-#define BPF_MAXINSNS 512
-#define BPF_MAXBUFSIZE 0x8000
-#define BPF_MINBUFSIZE 32
-
-/*
- * Structure for BIOCSETF.
- */
-struct bpf_program {
- u_int bf_len;
- struct bpf_insn *bf_insns;
-};
-
-/*
- * Struct returned by BIOCGSTATS.
- */
-struct bpf_stat {
- u_int bs_recv; /* number of packets received */
- u_int bs_drop; /* number of packets dropped */
-};
-
-/*
- * Struct return by BIOCVERSION. This represents the version number of
- * the filter language described by the instruction encodings below.
- * bpf understands a program iff kernel_major == filter_major &&
- * kernel_minor >= filter_minor, that is, if the value returned by the
- * running kernel has the same major number and a minor number equal
- * equal to or less than the filter being downloaded. Otherwise, the
- * results are undefined, meaning an error may be returned or packets
- * may be accepted haphazardly.
- * It has nothing to do with the source code version.
- */
-struct bpf_version {
- u_short bv_major;
- u_short bv_minor;
-};
-/* Current version number of filter architecture. */
-#define BPF_MAJOR_VERSION 1
-#define BPF_MINOR_VERSION 1
-
-/*
- * BPF ioctls
- *
- * The first set is for compatibility with Sun's pcc style
- * header files. If your using gcc, we assume that you
- * have run fixincludes so the latter set should work.
- */
-#if (defined(sun) || defined(ibm032)) && !defined(__GNUC__)
-#define BIOCGBLEN _IOR(B,102, u_int)
-#define BIOCSBLEN _IOWR(B,102, u_int)
-#define BIOCSETF _IOW(B,103, struct bpf_program)
-#define BIOCFLUSH _IO(B,104)
-#define BIOCPROMISC _IO(B,105)
-#define BIOCGDLT _IOR(B,106, u_int)
-#define BIOCGETIF _IOR(B,107, struct ifreq)
-#define BIOCSETIF _IOW(B,108, struct ifreq)
-#define BIOCSRTIMEOUT _IOW(B,109, struct timeval)
-#define BIOCGRTIMEOUT _IOR(B,110, struct timeval)
-#define BIOCGSTATS _IOR(B,111, struct bpf_stat)
-#define BIOCIMMEDIATE _IOW(B,112, u_int)
-#define BIOCVERSION _IOR(B,113, struct bpf_version)
-#define BIOCSTCPF _IOW(B,114, struct bpf_program)
-#define BIOCSUDPF _IOW(B,115, struct bpf_program)
-#else
-#define BIOCGBLEN _IOR('B',102, u_int)
-#define BIOCSBLEN _IOWR('B',102, u_int)
-#define BIOCSETF _IOW('B',103, struct bpf_program)
-#define BIOCFLUSH _IO('B',104)
-#define BIOCPROMISC _IO('B',105)
-#define BIOCGDLT _IOR('B',106, u_int)
-#define BIOCGETIF _IOR('B',107, struct ifreq)
-#define BIOCSETIF _IOW('B',108, struct ifreq)
-#define BIOCSRTIMEOUT _IOW('B',109, struct timeval)
-#define BIOCGRTIMEOUT _IOR('B',110, struct timeval)
-#define BIOCGSTATS _IOR('B',111, struct bpf_stat)
-#define BIOCIMMEDIATE _IOW('B',112, u_int)
-#define BIOCVERSION _IOR('B',113, struct bpf_version)
-#define BIOCSTCPF _IOW('B',114, struct bpf_program)
-#define BIOCSUDPF _IOW('B',115, struct bpf_program)
-#endif
-
-/*
- * Structure prepended to each packet.
- */
-struct bpf_hdr {
- struct timeval bh_tstamp; /* time stamp */
- bpf_u_int32 bh_caplen; /* length of captured portion */
- bpf_u_int32 bh_datalen; /* original length of packet */
- u_short bh_hdrlen; /* length of bpf header (this struct
- plus alignment padding) */
-};
-/*
- * Because the structure above is not a multiple of 4 bytes, some compilers
- * will insist on inserting padding; hence, sizeof(struct bpf_hdr) won't work.
- * Only the kernel needs to know about it; applications use bh_hdrlen.
- */
-#if defined(KERNEL) || defined(_KERNEL)
-#define SIZEOF_BPF_HDR 18
-#endif
-
-/*
- * Data-link level type codes.
- */
-
-/*
- * These are the types that are the same on all platforms; on other
- * platforms, a <net/bpf.h> should be supplied that defines the additional
- * DLT_* codes appropriately for that platform (the BSDs, for example,
- * should not just pick up this version of "bpf.h"; they should also define
- * the additional DLT_* codes used by their kernels, as well as the values
- * defined here - and, if the values they use for particular DLT_ types
- * differ from those here, they should use their values, not the ones
- * here).
- */
-#define DLT_NULL 0 /* no link-layer encapsulation */
-#define DLT_EN10MB 1 /* Ethernet (10Mb) */
-#define DLT_EN3MB 2 /* Experimental Ethernet (3Mb) */
-#define DLT_AX25 3 /* Amateur Radio AX.25 */
-#define DLT_PRONET 4 /* Proteon ProNET Token Ring */
-#define DLT_CHAOS 5 /* Chaos */
-#define DLT_IEEE802 6 /* IEEE 802 Networks */
-#define DLT_ARCNET 7 /* ARCNET */
-#define DLT_SLIP 8 /* Serial Line IP */
-#define DLT_PPP 9 /* Point-to-point Protocol */
-#define DLT_FDDI 10 /* FDDI */
-
-/*
- * These are values from the traditional libpcap "bpf.h".
- * Ports of this to particular platforms should replace these definitions
- * with the ones appropriate to that platform, if the values are
- * different on that platform.
- */
-#define DLT_ATM_RFC1483 11 /* LLC/SNAP encapsulated atm */
-#define DLT_RAW 12 /* raw IP */
-
-/*
- * These are values from BSD/OS's "bpf.h".
- * These are not the same as the values from the traditional libpcap
- * "bpf.h"; however, these values shouldn't be generated by any
- * OS other than BSD/OS, so the correct values to use here are the
- * BSD/OS values.
- *
- * Platforms that have already assigned these values to other
- * DLT_ codes, however, should give these codes the values
- * from that platform, so that programs that use these codes will
- * continue to compile - even though they won't correctly read
- * files of these types.
- */
-#define DLT_SLIP_BSDOS 15 /* BSD/OS Serial Line IP */
-#define DLT_PPP_BSDOS 16 /* BSD/OS Point-to-point Protocol */
-
-#define DLT_ATM_CLIP 19 /* Linux Classical-IP over ATM */
-
-/*
- * These values are defined by NetBSD; other platforms should refrain from
- * using them for other purposes, so that NetBSD savefiles with link
- * types of 50 or 51 can be read as this type on all platforms.
- */
-#define DLT_PPP_SERIAL 50 /* PPP over serial with HDLC encapsulation */
-#define DLT_PPP_ETHER 51 /* PPP over Ethernet */
-
-/*
- * Values between 100 and 103 are used in capture file headers as
- * link-layer types corresponding to DLT_ types that differ
- * between platforms; don't use those values for new DLT_ new types.
- */
-
-/*
- * This value was defined by libpcap 0.5; platforms that have defined
- * it with a different value should define it here with that value -
- * a link type of 104 in a save file will be mapped to DLT_C_HDLC,
- * whatever value that happens to be, so programs will correctly
- * handle files with that link type regardless of the value of
- * DLT_C_HDLC.
- *
- * The name DLT_C_HDLC was used by BSD/OS; we use that name for source
- * compatibility with programs written for BSD/OS.
- *
- * libpcap 0.5 defined it as DLT_CHDLC; we define DLT_CHDLC as well,
- * for source compatibility with programs written for libpcap 0.5.
- */
-#define DLT_C_HDLC 104 /* Cisco HDLC */
-#define DLT_CHDLC DLT_C_HDLC
-
-#define DLT_IEEE802_11 105 /* IEEE 802.11 wireless */
-
-/*
- * Values between 106 and 107 are used in capture file headers as
- * link-layer types corresponding to DLT_ types that might differ
- * between platforms; don't use those values for new DLT_ new types.
- */
-
-/*
- * OpenBSD DLT_LOOP, for loopback devices; it's like DLT_NULL, except
- * that the AF_ type in the link-layer header is in network byte order.
- *
- * OpenBSD defines it as 12, but that collides with DLT_RAW, so we
- * define it as 108 here. If OpenBSD picks up this file, it should
- * define DLT_LOOP as 12 in its version, as per the comment above -
- * and should not use 108 as a DLT_ value.
- */
-#define DLT_LOOP 108
-
-/*
- * Values between 109 and 112 are used in capture file headers as
- * link-layer types corresponding to DLT_ types that might differ
- * between platforms; don't use those values for new DLT_ types
- * other than the corresponding DLT_ types.
- */
-
-/*
- * This is for Linux cooked sockets.
- */
-#define DLT_LINUX_SLL 113
-
-/*
- * Apple LocalTalk hardware.
- */
-#define DLT_LTALK 114
-
-/*
- * Acorn Econet.
- */
-#define DLT_ECONET 115
-
-/*
- * Reserved for use with OpenBSD ipfilter.
- */
-#define DLT_IPFILTER 116
-
-/*
- * Reserved for use in capture-file headers as a link-layer type
- * corresponding to OpenBSD DLT_PFLOG; DLT_PFLOG is 17 in OpenBSD,
- * but that's DLT_LANE8023 in SuSE 6.3, so we can't use 17 for it
- * in capture-file headers.
- */
-#define DLT_PFLOG 117
-
-/*
- * Registered for Cisco-internal use.
- */
-#define DLT_CISCO_IOS 118
-
-/*
- * Reserved for 802.11 cards using the Prism II chips, with a link-layer
- * header including Prism monitor mode information plus an 802.11
- * header.
- */
-#define DLT_PRISM_HEADER 119
-
-/*
- * Reserved for Aironet 802.11 cards, with an Aironet link-layer header
- * (see Doug Ambrisko's FreeBSD patches).
- */
-#define DLT_AIRONET_HEADER 120
-
-/*
- * The instruction encodings.
- */
-/* instruction classes */
-#define BPF_CLASS(code) ((code) & 0x07)
-#define BPF_LD 0x00
-#define BPF_LDX 0x01
-#define BPF_ST 0x02
-#define BPF_STX 0x03
-#define BPF_ALU 0x04
-#define BPF_JMP 0x05
-#define BPF_RET 0x06
-#define BPF_MISC 0x07
-
-/* ld/ldx fields */
-#define BPF_SIZE(code) ((code) & 0x18)
-#define BPF_W 0x00
-#define BPF_H 0x08
-#define BPF_B 0x10
-#define BPF_MODE(code) ((code) & 0xe0)
-#define BPF_IMM 0x00
-#define BPF_ABS 0x20
-#define BPF_IND 0x40
-#define BPF_MEM 0x60
-#define BPF_LEN 0x80
-#define BPF_MSH 0xa0
-
-/* alu/jmp fields */
-#define BPF_OP(code) ((code) & 0xf0)
-#define BPF_ADD 0x00
-#define BPF_SUB 0x10
-#define BPF_MUL 0x20
-#define BPF_DIV 0x30
-#define BPF_OR 0x40
-#define BPF_AND 0x50
-#define BPF_LSH 0x60
-#define BPF_RSH 0x70
-#define BPF_NEG 0x80
-#define BPF_JA 0x00
-#define BPF_JEQ 0x10
-#define BPF_JGT 0x20
-#define BPF_JGE 0x30
-#define BPF_JSET 0x40
-#define BPF_SRC(code) ((code) & 0x08)
-#define BPF_K 0x00
-#define BPF_X 0x08
-
-/* ret - BPF_K and BPF_X also apply */
-#define BPF_RVAL(code) ((code) & 0x18)
-#define BPF_A 0x10
-
-/* misc */
-#define BPF_MISCOP(code) ((code) & 0xf8)
-#define BPF_TAX 0x00
-#define BPF_TXA 0x80
-
-/*
- * The instruction data structure.
- */
-struct bpf_insn {
- u_short code;
- u_char jt;
- u_char jf;
- bpf_int32 k;
-};
-
-/*
- * Macros for insn array initializers.
- */
-#define BPF_STMT(code, k) { (u_short)(code), 0, 0, k }
-#define BPF_JUMP(code, k, jt, jf) { (u_short)(code), jt, jf, k }
-
-#if defined(BSD) && (defined(KERNEL) || defined(_KERNEL))
-/*
- * Systems based on non-BSD kernels don't have ifnet's (or they don't mean
- * anything if it is in <net/if.h>) and won't work like this.
- */
-# if __STDC__
-extern void bpf_tap(struct ifnet *, u_char *, u_int);
-extern void bpf_mtap(struct ifnet *, struct mbuf *);
-extern void bpfattach(struct ifnet *, u_int, u_int);
-extern void bpfilterattach(int);
-# else
-extern void bpf_tap();
-extern void bpf_mtap();
-extern void bpfattach();
-extern void bpfilterattach();
-# endif /* __STDC__ */
-#endif /* BSD && (_KERNEL || KERNEL) */
-#if __STDC__
-extern int bpf_validate(struct bpf_insn *, int);
-extern u_int bpf_filter(struct bpf_insn *, u_char *, u_int, u_int);
-#else
-extern int bpf_validate();
-extern u_int bpf_filter();
-#endif
-
-/*
- * Number of scratch memory words (for BPF_LD|BPF_MEM and BPF_ST).
- */
-#define BPF_MEMWORDS 16
-
-#endif
diff --git a/contrib/libpcap/gencode.c b/contrib/libpcap/gencode.c
index 29eb931..41957af 100644
--- a/contrib/libpcap/gencode.c
+++ b/contrib/libpcap/gencode.c
@@ -22,27 +22,39 @@
* $FreeBSD$
*/
#ifndef lint
-static const char rcsid[] =
- "@(#) $Header: /tcpdump/master/libpcap/gencode.c,v 1.160 2001/11/30 07:25:48 guy Exp $ (LBL)";
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/libpcap/gencode.c,v 1.193.2.8 2004/03/29 20:53:47 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
+#ifdef WIN32
+#include <pcap-stdinc.h>
+#else /* WIN32 */
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
+#endif /* WIN32 */
+
+/*
+ * XXX - why was this included even on UNIX?
+ */
+#ifdef __MINGW32__
+#include "IP6_misc.h"
+#endif
+
+#ifndef WIN32
+
#ifdef __NetBSD__
#include <sys/param.h>
#endif
-struct mbuf;
-struct rtentry;
-#include <net/if.h>
-
#include <netinet/in.h>
+#endif /* WIN32 */
+
#include <stdlib.h>
#include <string.h>
#include <memory.h>
@@ -55,14 +67,21 @@ struct rtentry;
#include "nlpid.h"
#include "llc.h"
#include "gencode.h"
+#include "atmuni31.h"
+#include "sunatmpos.h"
#include "ppp.h"
#include "sll.h"
#include "arcnet.h"
-#include <pcap-namedb.h>
+#include "pf.h"
+#ifndef offsetof
+#define offsetof(s, e) ((size_t)&((s *)0)->e)
+#endif
#ifdef INET6
-#include <netdb.h>
-#include <sys/socket.h>
+#ifndef WIN32
+#include <netdb.h> /* for "struct addrinfo" */
+#endif /* WIN32 */
#endif /*INET6*/
+#include <pcap-namedb.h>
#undef ETHERMTU
#define ETHERMTU 1500
@@ -82,7 +101,7 @@ static jmp_buf top_ctx;
static pcap_t *bpf_pcap;
/* Hack for updating VLAN offsets. */
-static u_int orig_linktype = -1, orig_nl = -1;
+static u_int orig_linktype = -1, orig_nl = -1, orig_nl_nosnap = -1;
/* XXX */
#ifdef PCAP_FDDIPAD
@@ -143,11 +162,15 @@ static struct block *gen_cmp(u_int, u_int, bpf_int32);
static struct block *gen_cmp_gt(u_int, u_int, bpf_int32);
static struct block *gen_mcmp(u_int, u_int, bpf_int32, bpf_u_int32);
static struct block *gen_bcmp(u_int, u_int, const u_char *);
+static struct block *gen_ncmp(bpf_u_int32, bpf_u_int32, bpf_u_int32,
+ bpf_u_int32, bpf_u_int32, int);
static struct block *gen_uncond(int);
static inline struct block *gen_true(void);
static inline struct block *gen_false(void);
+static struct block *gen_ether_linktype(int);
static struct block *gen_linktype(int);
static struct block *gen_snap(bpf_u_int32, bpf_u_int32, u_int);
+static struct block *gen_llc(int);
static struct block *gen_hostop(bpf_u_int32, bpf_u_int32, int, int, u_int, u_int);
#ifdef INET6
static struct block *gen_hostop6(struct in6_addr *, struct in6_addr *, int, int, u_int, u_int);
@@ -156,7 +179,8 @@ static struct block *gen_ahostop(const u_char *, int);
static struct block *gen_ehostop(const u_char *, int);
static struct block *gen_fhostop(const u_char *, int);
static struct block *gen_thostop(const u_char *, int);
-static struct block *gen_whostop(const u_char *, int);
+static struct block *gen_wlanhostop(const u_char *, int);
+static struct block *gen_ipfchostop(const u_char *, int);
static struct block *gen_dnhostop(bpf_u_int32, int, u_int);
static struct block *gen_host(bpf_u_int32, bpf_u_int32, int, int);
#ifdef INET6
@@ -181,14 +205,18 @@ static struct block *gen_protochain(int, int, int);
static struct block *gen_proto(int, int, int);
static struct slist *xfer_to_x(struct arth *);
static struct slist *xfer_to_a(struct arth *);
+static struct block *gen_mac_multicast(int);
static struct block *gen_len(int, int);
+static struct block *gen_msg_abbrev(int type);
+
static void *
newchunk(n)
u_int n;
{
struct chunk *cp;
- int k, size;
+ int k;
+ size_t size;
#ifndef __NetBSD__
/* XXX Round up to nearest long. */
@@ -205,6 +233,8 @@ newchunk(n)
bpf_error("out of memory");
size = CHUNK0SIZE << k;
cp->m = (void *)malloc(size);
+ if (cp->m == NULL)
+ bpf_error("out of memory");
memset((char *)cp->m, 0, size);
cp->n_left = size;
if (n > size)
@@ -304,7 +334,7 @@ pcap_compile(pcap_t *p, struct bpf_program *program,
}
netmask = mask;
-
+
snaplen = pcap_snapshot(p);
if (snaplen == 0) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
@@ -543,13 +573,111 @@ gen_bcmp(offset, size, v)
return b;
}
+static struct block *
+gen_ncmp(datasize, offset, mask, jtype, jvalue, reverse)
+ bpf_u_int32 datasize, offset, mask, jtype, jvalue;
+ int reverse;
+{
+ struct slist *s;
+ struct block *b;
+
+ s = new_stmt(BPF_LD|datasize|BPF_ABS);
+ s->s.k = offset;
+
+ if (mask != 0xffffffff) {
+ s->next = new_stmt(BPF_ALU|BPF_AND|BPF_K);
+ s->next->s.k = mask;
+ }
+
+ b = new_block(JMP(jtype));
+ b->stmts = s;
+ b->s.k = jvalue;
+ if (reverse && (jtype == BPF_JGT || jtype == BPF_JGE))
+ gen_not(b);
+ 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.
+ * layer. These variables give the necessary offsets.
+ */
+
+/*
+ * This is the offset of the beginning of the MAC-layer header.
+ * It's usually 0, except for ATM LANE.
+ */
+static u_int off_mac;
+
+/*
+ * "off_linktype" is the offset to information in the link-layer header
+ * giving the packet type.
+ *
+ * For Ethernet, it's the offset of the Ethernet type field.
+ *
+ * For link-layer types that always use 802.2 headers, it's the
+ * offset of the LLC header.
+ *
+ * For PPP, it's the offset of the PPP type field.
+ *
+ * For Cisco HDLC, it's the offset of the CHDLC type field.
+ *
+ * For BSD loopback, it's the offset of the AF_ value.
+ *
+ * For Linux cooked sockets, it's the offset of the type field.
+ *
+ * It's set to -1 for no encapsulation, in which case, IP is assumed.
*/
static u_int off_linktype;
+
+/*
+ * TRUE if the link layer includes an ATM pseudo-header.
+ */
+static int is_atm = 0;
+
+/*
+ * TRUE if "lane" appeared in the filter; it causes us to generate
+ * code that assumes LANE rather than LLC-encapsulated traffic in SunATM.
+ */
+static int is_lane = 0;
+
+/*
+ * These are offsets for the ATM pseudo-header.
+ */
+static u_int off_vpi;
+static u_int off_vci;
+static u_int off_proto;
+
+/*
+ * This is the offset of the first byte after the ATM pseudo_header,
+ * or -1 if there is no ATM pseudo-header.
+ */
+static u_int off_payload;
+
+/*
+ * These are offsets to the beginning of the network-layer header.
+ *
+ * If the link layer never uses 802.2 LLC:
+ *
+ * "off_nl" and "off_nl_nosnap" are the same.
+ *
+ * If the link layer always uses 802.2 LLC:
+ *
+ * "off_nl" is the offset if there's a SNAP header following
+ * the 802.2 header;
+ *
+ * "off_nl_nosnap" is the offset if there's no SNAP header.
+ *
+ * If the link layer is Ethernet:
+ *
+ * "off_nl" is the offset if the packet is an Ethernet II packet
+ * (we assume no 802.3+802.2+SNAP);
+ *
+ * "off_nl_nosnap" is the offset if the packet is an 802.3 packet
+ * with an 802.2 header following it.
+ */
static u_int off_nl;
+static u_int off_nl_nosnap;
+
static int linktype;
static void
@@ -558,19 +686,39 @@ init_linktype(type)
{
linktype = type;
+ /*
+ * Assume it's not raw ATM with a pseudo-header, for now.
+ */
+ off_mac = 0;
+ is_atm = 0;
+ is_lane = 0;
+ off_vpi = -1;
+ off_vci = -1;
+ off_proto = -1;
+ off_payload = -1;
+
orig_linktype = -1;
orig_nl = -1;
+ orig_nl_nosnap = -1;
switch (type) {
case DLT_ARCNET:
off_linktype = 2;
- off_nl = 6; /* XXX in reality, variable! */
+ off_nl = 6; /* XXX in reality, variable! */
+ off_nl_nosnap = 6; /* no 802.2 LLC */
+ return;
+
+ case DLT_ARCNET_LINUX:
+ off_linktype = 4;
+ off_nl = 8; /* XXX in reality, variable! */
+ off_nl_nosnap = 8; /* no 802.2 LLC */
return;
case DLT_EN10MB:
off_linktype = 12;
- off_nl = 14;
+ off_nl = 14; /* Ethernet II */
+ off_nl_nosnap = 17; /* 802.3+802.2 */
return;
case DLT_SLIP:
@@ -580,6 +728,7 @@ init_linktype(type)
*/
off_linktype = -1;
off_nl = 16;
+ off_nl_nosnap = 16; /* no 802.2 LLC */
return;
case DLT_SLIP_BSDOS:
@@ -587,12 +736,20 @@ init_linktype(type)
off_linktype = -1;
/* XXX end */
off_nl = 24;
+ off_nl_nosnap = 24; /* no 802.2 LLC */
return;
case DLT_NULL:
case DLT_LOOP:
off_linktype = 0;
off_nl = 4;
+ off_nl_nosnap = 4; /* no 802.2 LLC */
+ return;
+
+ case DLT_ENC:
+ off_linktype = 0;
+ off_nl = 12;
+ off_nl_nosnap = 12; /* no 802.2 LLC */
return;
case DLT_PPP:
@@ -600,6 +757,7 @@ init_linktype(type)
case DLT_PPP_SERIAL: /* NetBSD sync/async serial PPP */
off_linktype = 2;
off_nl = 4;
+ off_nl_nosnap = 4; /* no 802.2 LLC */
return;
case DLT_PPP_ETHER:
@@ -609,11 +767,13 @@ init_linktype(type)
*/
off_linktype = 6;
off_nl = 8;
+ off_nl_nosnap = 8; /* no 802.2 LLC */
return;
case DLT_PPP_BSDOS:
off_linktype = 5;
off_nl = 24;
+ off_nl_nosnap = 24; /* no 802.2 LLC */
return;
case DLT_FDDI:
@@ -629,9 +789,11 @@ init_linktype(type)
#ifdef PCAP_FDDIPAD
off_linktype += pcap_fddipad;
#endif
- off_nl = 21;
+ off_nl = 21; /* FDDI+802.2+SNAP */
+ off_nl_nosnap = 16; /* FDDI+802.2 */
#ifdef PCAP_FDDIPAD
off_nl += pcap_fddipad;
+ off_nl_nosnap += pcap_fddipad;
#endif
return;
@@ -660,7 +822,8 @@ init_linktype(type)
* 8 - figure out which byte that is).
*/
off_linktype = 14;
- off_nl = 22;
+ off_nl = 22; /* Token Ring+802.2+SNAP */
+ off_nl_nosnap = 17; /* Token Ring+802.2 */
return;
case DLT_IEEE802_11:
@@ -679,7 +842,8 @@ init_linktype(type)
* it's actually supposed to be 30 bytes.
*/
off_linktype = 24;
- off_nl = 32;
+ off_nl = 32; /* 802.11+802.2+SNAP */
+ off_nl_nosnap = 27; /* 802.11+802.2 */
return;
case DLT_PRISM_HEADER:
@@ -694,31 +858,90 @@ init_linktype(type)
* the Prism header is fixed-length.
*/
off_linktype = 144+24;
- off_nl = 144+30;
+ off_nl = 144+32; /* Prism+802.11+802.2+SNAP */
+ off_nl_nosnap = 144+27; /* Prism+802.11+802.2 */
+ return;
+
+ case DLT_IEEE802_11_RADIO_AVS:
+ /*
+ * Same as 802.11, but with an additional header before
+ * the 802.11 header, containing a bunch of additional
+ * information including radio-level information.
+ *
+ * The header is 64 bytes long, at least in its
+ * current incarnation.
+ *
+ * XXX - same variable-length header problem, only
+ * more so; this header is also variable-length,
+ * with the length being the 32-bit big-endian
+ * number at an offset of 4 from the beginning
+ * of the radio header.
+ */
+ off_linktype = 64+24;
+ off_nl = 64+32; /* Radio+802.11+802.2+SNAP */
+ off_nl_nosnap = 64+27; /* Radio+802.11+802.2 */
+ return;
+
+ case DLT_IEEE802_11_RADIO:
+ /*
+ * Same as 802.11, but with an additional header before
+ * the 802.11 header, containing a bunch of additional
+ * information including radio-level information.
+ *
+ * XXX - same variable-length header problem, only
+ * even *more* so; this header is also variable-length,
+ * with the length being the 16-bit number at an offset
+ * of 2 from the beginning of the radio header, and it's
+ * device-dependent (different devices might supply
+ * different amounts of information), so we can't even
+ * assume a fixed length for the current version of the
+ * header.
+ *
+ * Therefore, currently, only raw "link[N:M]" filtering is
+ * supported.
+ */
+ off_linktype = -1;
+ off_nl = -1;
+ off_nl_nosnap = -1;
return;
case DLT_ATM_RFC1483:
+ case DLT_ATM_CLIP: /* Linux ATM defines this */
/*
* assume routed, non-ISO PDUs
* (i.e., LLC = 0xAA-AA-03, OUT = 0x00-00-00)
*/
- off_linktype = 6;
- off_nl = 8;
+ off_linktype = 0;
+ off_nl = 8; /* 802.2+SNAP */
+ off_nl_nosnap = 3; /* 802.2 */
+ return;
+
+ case DLT_SUNATM:
+ /*
+ * Full Frontal ATM; you get AALn PDUs with an ATM
+ * pseudo-header.
+ */
+ is_atm = 1;
+ off_vpi = SUNATM_VPI_POS;
+ off_vci = SUNATM_VCI_POS;
+ off_proto = PROTO_POS;
+ off_mac = -1; /* LLC-encapsulated, so no MAC-layer header */
+ off_payload = SUNATM_PKT_BEGIN_POS;
+ off_linktype = off_payload;
+ off_nl = off_payload+8; /* 802.2+SNAP */
+ off_nl_nosnap = off_payload+3; /* 802.2 */
return;
case DLT_RAW:
off_linktype = -1;
off_nl = 0;
- return;
-
- case DLT_ATM_CLIP: /* Linux ATM defines this */
- off_linktype = 6;
- off_nl = 8;
+ off_nl_nosnap = 0; /* no 802.2 LLC */
return;
case DLT_LINUX_SLL: /* fake header for Linux cooked socket */
off_linktype = 14;
off_nl = 16;
+ off_nl_nosnap = 16; /* no 802.2 LLC */
return;
case DLT_LTALK:
@@ -729,7 +952,64 @@ init_linktype(type)
*/
off_linktype = -1;
off_nl = 0;
+ off_nl_nosnap = 0; /* no 802.2 LLC */
+ return;
+
+ case DLT_IP_OVER_FC:
+ /*
+ * RFC 2625 IP-over-Fibre-Channel doesn't really have a
+ * link-level type field. We set "off_linktype" to the
+ * offset of the LLC header.
+ *
+ * To check for Ethernet types, we assume that SSAP = SNAP
+ * is being used and pick out the encapsulated Ethernet type.
+ * XXX - should we generate code to check for SNAP? RFC
+ * 2625 says SNAP should be used.
+ */
+ off_linktype = 16;
+ off_nl = 24; /* IPFC+802.2+SNAP */
+ off_nl_nosnap = 19; /* IPFC+802.2 */
+ return;
+
+ case DLT_FRELAY:
+ /*
+ * XXX - we should set this to handle SNAP-encapsulated
+ * frames (NLPID of 0x80).
+ */
+ off_linktype = -1;
+ off_nl = 0;
+ off_nl_nosnap = 0; /* no 802.2 LLC */
+ return;
+
+ case DLT_APPLE_IP_OVER_IEEE1394:
+ off_linktype = 16;
+ off_nl = 18;
+ off_nl_nosnap = 0; /* no 802.2 LLC */
+ return;
+
+ case DLT_LINUX_IRDA:
+ /*
+ * Currently, only raw "link[N:M]" filtering is supported.
+ */
+ off_linktype = -1;
+ off_nl = -1;
+ off_nl_nosnap = -1;
+ return;
+
+ case DLT_PFLOG:
+ off_linktype = 0;
+ /* XXX read from header? */
+ off_nl = PFLOG_HDRLEN;
+ off_nl_nosnap = PFLOG_HDRLEN;
+ return;
+
+#ifdef DLT_PFSYNC
+ case DLT_PFSYNC:
+ off_linktype = -1;
+ off_nl = 4;
+ off_nl_nosnap = 4;
return;
+#endif
}
bpf_error("unknown data link type %d", linktype);
/* NOTREACHED */
@@ -771,275 +1051,269 @@ gen_false()
((((y)&0xff)<<24) | (((y)&0xff00)<<8) | (((y)&0xff0000)>>8) | (((y)>>24)&0xff))
static struct block *
-gen_linktype(proto)
+gen_ether_linktype(proto)
register int proto;
{
struct block *b0, *b1;
- switch (linktype) {
+ switch (proto) {
- case DLT_EN10MB:
- switch (proto) {
+ case LLCSAP_ISONS:
+ /*
+ * OSI protocols always use 802.2 encapsulation.
+ * XXX - should we check both the DSAP and the
+ * SSAP, like this, or should we check just the
+ * DSAP?
+ */
+ b0 = gen_cmp_gt(off_linktype, BPF_H, ETHERMTU);
+ gen_not(b0);
+ b1 = gen_cmp(off_linktype + 2, BPF_H, (bpf_int32)
+ ((LLCSAP_ISONS << 8) | LLCSAP_ISONS));
+ gen_and(b0, b1);
+ return b1;
- case LLCSAP_ISONS:
- /*
- * OSI protocols always use 802.2 encapsulation.
- * XXX - should we check both the DSAP and the
- * SSAP, like this, or should we check just the
- * DSAP?
- */
- b0 = gen_cmp_gt(off_linktype, BPF_H, ETHERMTU);
- gen_not(b0);
- b1 = gen_cmp(off_linktype + 2, BPF_H, (bpf_int32)
- ((LLCSAP_ISONS << 8) | LLCSAP_ISONS));
- gen_and(b0, b1);
- return b1;
+ case LLCSAP_IP:
+ b0 = gen_cmp_gt(off_linktype, BPF_H, ETHERMTU);
+ gen_not(b0);
+ b1 = gen_cmp(off_linktype + 2, BPF_H, (bpf_int32)
+ ((LLCSAP_IP << 8) | LLCSAP_IP));
+ gen_and(b0, b1);
+ return b1;
- case LLCSAP_NETBEUI:
- /*
- * NetBEUI always uses 802.2 encapsulation.
- * XXX - should we check both the DSAP and the
- * SSAP, like this, or should we check just the
- * DSAP?
- */
- b0 = gen_cmp_gt(off_linktype, BPF_H, ETHERMTU);
- gen_not(b0);
- b1 = gen_cmp(off_linktype + 2, BPF_H, (bpf_int32)
- ((LLCSAP_NETBEUI << 8) | LLCSAP_NETBEUI));
- gen_and(b0, b1);
- return b1;
+ case LLCSAP_NETBEUI:
+ /*
+ * NetBEUI always uses 802.2 encapsulation.
+ * XXX - should we check both the DSAP and the
+ * SSAP, like this, or should we check just the
+ * DSAP?
+ */
+ b0 = gen_cmp_gt(off_linktype, BPF_H, ETHERMTU);
+ gen_not(b0);
+ b1 = gen_cmp(off_linktype + 2, BPF_H, (bpf_int32)
+ ((LLCSAP_NETBEUI << 8) | LLCSAP_NETBEUI));
+ gen_and(b0, b1);
+ return b1;
- case LLCSAP_IPX:
- /*
- * Check for;
- *
- * Ethernet_II frames, which are Ethernet
- * frames with a frame type of ETHERTYPE_IPX;
- *
- * Ethernet_802.3 frames, which are 802.3
- * frames (i.e., the type/length field is
- * a length field, <= ETHERMTU, rather than
- * a type field) with the first two bytes
- * after the Ethernet/802.3 header being
- * 0xFFFF;
- *
- * Ethernet_802.2 frames, which are 802.3
- * frames with an 802.2 LLC header and
- * with the IPX LSAP as the DSAP in the LLC
- * header;
- *
- * Ethernet_SNAP frames, which are 802.3
- * frames with an LLC header and a SNAP
- * header and with an OUI of 0x000000
- * (encapsulated Ethernet) and a protocol
- * ID of ETHERTYPE_IPX in the SNAP header.
- *
- * XXX - should we generate the same code both
- * for tests for LLCSAP_IPX and for ETHERTYPE_IPX?
- */
+ case LLCSAP_IPX:
+ /*
+ * Check for;
+ *
+ * Ethernet_II frames, which are Ethernet
+ * frames with a frame type of ETHERTYPE_IPX;
+ *
+ * Ethernet_802.3 frames, which are 802.3
+ * frames (i.e., the type/length field is
+ * a length field, <= ETHERMTU, rather than
+ * a type field) with the first two bytes
+ * after the Ethernet/802.3 header being
+ * 0xFFFF;
+ *
+ * Ethernet_802.2 frames, which are 802.3
+ * frames with an 802.2 LLC header and
+ * with the IPX LSAP as the DSAP in the LLC
+ * header;
+ *
+ * Ethernet_SNAP frames, which are 802.3
+ * frames with an LLC header and a SNAP
+ * header and with an OUI of 0x000000
+ * (encapsulated Ethernet) and a protocol
+ * ID of ETHERTYPE_IPX in the SNAP header.
+ *
+ * XXX - should we generate the same code both
+ * for tests for LLCSAP_IPX and for ETHERTYPE_IPX?
+ */
- /*
- * This generates code to check both for the
- * IPX LSAP (Ethernet_802.2) and for Ethernet_802.3.
- */
- b0 = gen_cmp(off_linktype + 2, BPF_B,
- (bpf_int32)LLCSAP_IPX);
- b1 = gen_cmp(off_linktype + 2, BPF_H,
- (bpf_int32)0xFFFF);
- gen_or(b0, b1);
+ /*
+ * This generates code to check both for the
+ * IPX LSAP (Ethernet_802.2) and for Ethernet_802.3.
+ */
+ b0 = gen_cmp(off_linktype + 2, BPF_B, (bpf_int32)LLCSAP_IPX);
+ b1 = gen_cmp(off_linktype + 2, BPF_H, (bpf_int32)0xFFFF);
+ gen_or(b0, b1);
- /*
- * Now we add code to check for SNAP frames with
- * ETHERTYPE_IPX, i.e. Ethernet_SNAP.
- */
- b0 = gen_snap(0x000000, ETHERTYPE_IPX, 14);
- gen_or(b0, b1);
+ /*
+ * Now we add code to check for SNAP frames with
+ * ETHERTYPE_IPX, i.e. Ethernet_SNAP.
+ */
+ b0 = gen_snap(0x000000, ETHERTYPE_IPX, 14);
+ gen_or(b0, b1);
- /*
- * Now we generate code to check for 802.3
- * frames in general.
- */
- b0 = gen_cmp_gt(off_linktype, BPF_H, ETHERMTU);
- gen_not(b0);
+ /*
+ * Now we generate code to check for 802.3
+ * frames in general.
+ */
+ b0 = gen_cmp_gt(off_linktype, BPF_H, ETHERMTU);
+ gen_not(b0);
- /*
- * Now add the check for 802.3 frames before the
- * check for Ethernet_802.2 and Ethernet_802.3,
- * as those checks should only be done on 802.3
- * frames, not on Ethernet frames.
- */
- gen_and(b0, b1);
+ /*
+ * Now add the check for 802.3 frames before the
+ * check for Ethernet_802.2 and Ethernet_802.3,
+ * as those checks should only be done on 802.3
+ * frames, not on Ethernet frames.
+ */
+ gen_and(b0, b1);
- /*
- * Now add the check for Ethernet_II frames, and
- * do that before checking for the other frame
- * types.
- */
- b0 = gen_cmp(off_linktype, BPF_H,
- (bpf_int32)ETHERTYPE_IPX);
- gen_or(b0, b1);
- return b1;
+ /*
+ * Now add the check for Ethernet_II frames, and
+ * do that before checking for the other frame
+ * types.
+ */
+ b0 = gen_cmp(off_linktype, BPF_H, (bpf_int32)ETHERTYPE_IPX);
+ gen_or(b0, b1);
+ return b1;
- case ETHERTYPE_ATALK:
- case ETHERTYPE_AARP:
- /*
- * EtherTalk (AppleTalk protocols on Ethernet link
- * layer) may use 802.2 encapsulation.
- */
+ case ETHERTYPE_ATALK:
+ case ETHERTYPE_AARP:
+ /*
+ * EtherTalk (AppleTalk protocols on Ethernet link
+ * layer) may use 802.2 encapsulation.
+ */
+
+ /*
+ * Check for 802.2 encapsulation (EtherTalk phase 2?);
+ * we check for an Ethernet type field less than
+ * 1500, which means it's an 802.3 length field.
+ */
+ b0 = gen_cmp_gt(off_linktype, BPF_H, ETHERMTU);
+ gen_not(b0);
+
+ /*
+ * 802.2-encapsulated ETHERTYPE_ATALK packets are
+ * SNAP packets with an organization code of
+ * 0x080007 (Apple, for Appletalk) and a protocol
+ * type of ETHERTYPE_ATALK (Appletalk).
+ *
+ * 802.2-encapsulated ETHERTYPE_AARP packets are
+ * SNAP packets with an organization code of
+ * 0x000000 (encapsulated Ethernet) and a protocol
+ * type of ETHERTYPE_AARP (Appletalk ARP).
+ */
+ if (proto == ETHERTYPE_ATALK)
+ b1 = gen_snap(0x080007, ETHERTYPE_ATALK, 14);
+ else /* proto == ETHERTYPE_AARP */
+ b1 = gen_snap(0x000000, ETHERTYPE_AARP, 14);
+ gen_and(b0, b1);
+
+ /*
+ * Check for Ethernet encapsulation (Ethertalk
+ * phase 1?); we just check for the Ethernet
+ * protocol type.
+ */
+ b0 = gen_cmp(off_linktype, BPF_H, (bpf_int32)proto);
+ gen_or(b0, b1);
+ return b1;
+
+ default:
+ if (proto <= ETHERMTU) {
/*
- * Check for 802.2 encapsulation (EtherTalk phase 2?);
- * we check for an Ethernet type field less than
- * 1500, which means it's an 802.3 length field.
+ * This is an LLC SAP value, so the frames
+ * that match would be 802.2 frames.
+ * Check that the frame is an 802.2 frame
+ * (i.e., that the length/type field is
+ * a length field, <= ETHERMTU) and
+ * then check the DSAP.
*/
b0 = gen_cmp_gt(off_linktype, BPF_H, ETHERMTU);
gen_not(b0);
-
- /*
- * 802.2-encapsulated ETHERTYPE_ATALK packets are
- * SNAP packets with an organization code of
- * 0x080007 (Apple, for Appletalk) and a protocol
- * type of ETHERTYPE_ATALK (Appletalk).
- *
- * 802.2-encapsulated ETHERTYPE_AARP packets are
- * SNAP packets with an organization code of
- * 0x000000 (encapsulated Ethernet) and a protocol
- * type of ETHERTYPE_AARP (Appletalk ARP).
- */
- if (proto == ETHERTYPE_ATALK)
- b1 = gen_snap(0x080007, ETHERTYPE_ATALK, 14);
- else /* proto == ETHERTYPE_AARP */
- b1 = gen_snap(0x000000, ETHERTYPE_AARP, 14);
+ b1 = gen_cmp(off_linktype + 2, BPF_B, (bpf_int32)proto);
gen_and(b0, b1);
-
+ return b1;
+ } else {
/*
- * Check for Ethernet encapsulation (Ethertalk
- * phase 1?); we just check for the Ethernet
- * protocol type.
+ * This is an Ethernet type, so compare
+ * the length/type field with it (if
+ * the frame is an 802.2 frame, the length
+ * field will be <= ETHERMTU, and, as
+ * "proto" is > ETHERMTU, this test
+ * will fail and the frame won't match,
+ * which is what we want).
*/
- b0 = gen_cmp(off_linktype, BPF_H, (bpf_int32)proto);
+ return gen_cmp(off_linktype, BPF_H, (bpf_int32)proto);
+ }
+ }
+}
- gen_or(b0, b1);
- return b1;
+static struct block *
+gen_linktype(proto)
+ register int proto;
+{
+ struct block *b0, *b1, *b2;
+
+ switch (linktype) {
+
+ case DLT_EN10MB:
+ return gen_ether_linktype(proto);
+ break;
+
+ case DLT_C_HDLC:
+ switch (proto) {
+
+ case LLCSAP_ISONS:
+ proto = (proto << 8 | LLCSAP_ISONS);
+ /* fall through */
default:
- if (proto <= ETHERMTU) {
- /*
- * This is an LLC SAP value, so the frames
- * that match would be 802.2 frames.
- * Check that the frame is an 802.2 frame
- * (i.e., that the length/type field is
- * a length field, <= ETHERMTU) and
- * then check the DSAP.
- */
- b0 = gen_cmp_gt(off_linktype, BPF_H, ETHERMTU);
- gen_not(b0);
- b1 = gen_cmp(off_linktype + 2, BPF_B,
- (bpf_int32)proto);
- gen_and(b0, b1);
- return b1;
- } else {
- /*
- * This is an Ethernet type, so compare
- * the length/type field with it (if
- * the frame is an 802.2 frame, the length
- * field will be <= ETHERMTU, and, as
- * "proto" is > ETHERMTU, this test
- * will fail and the frame won't match,
- * which is what we want).
- */
- return gen_cmp(off_linktype, BPF_H,
- (bpf_int32)proto);
- }
+ return gen_cmp(off_linktype, BPF_H, (bpf_int32)proto);
+ break;
}
break;
case DLT_IEEE802_11:
- return gen_snap(0x000000, proto, off_linktype);
case DLT_PRISM_HEADER:
+ case DLT_IEEE802_11_RADIO:
case DLT_FDDI:
case DLT_IEEE802:
case DLT_ATM_RFC1483:
case DLT_ATM_CLIP:
+ case DLT_IP_OVER_FC:
+ return gen_llc(proto);
+ break;
+
+ case DLT_SUNATM:
/*
- * XXX - handle token-ring variable-length header.
+ * If "is_lane" is set, check for a LANE-encapsulated
+ * version of this protocol, otherwise check for an
+ * LLC-encapsulated version of this protocol.
+ *
+ * We assume LANE means Ethernet, not Token Ring.
*/
- switch (proto) {
-
- case LLCSAP_ISONS:
- return gen_cmp(off_linktype, BPF_H, (long)
- ((LLCSAP_ISONS << 8) | LLCSAP_ISONS));
-
- case LLCSAP_NETBEUI:
- return gen_cmp(off_linktype, BPF_H, (long)
- ((LLCSAP_NETBEUI << 8) | LLCSAP_NETBEUI));
-
- case LLCSAP_IPX:
+ if (is_lane) {
/*
- * XXX - are there ever SNAP frames for IPX on
- * non-Ethernet 802.x networks?
+ * Check that the packet doesn't begin with an
+ * LE Control marker. (We've already generated
+ * a test for LANE.)
*/
- return gen_cmp(off_linktype, BPF_B,
- (bpf_int32)LLCSAP_IPX);
+ b0 = gen_cmp(SUNATM_PKT_BEGIN_POS, BPF_H, 0xFF00);
+ gen_not(b0);
- case ETHERTYPE_ATALK:
/*
- * 802.2-encapsulated ETHERTYPE_ATALK packets are
- * SNAP packets with an organization code of
- * 0x080007 (Apple, for Appletalk) and a protocol
- * type of ETHERTYPE_ATALK (Appletalk).
- *
- * XXX - check for an organization code of
- * encapsulated Ethernet as well?
+ * Now generate an Ethernet test.
*/
- return gen_snap(0x080007, ETHERTYPE_ATALK,
- off_linktype);
- break;
-
- default:
+ b1 = gen_ether_linktype(proto);
+ gen_and(b0, b1);
+ return b1;
+ } else {
/*
- * XXX - we don't have to check for IPX 802.3
- * here, but should we check for the IPX Ethertype?
+ * Check for LLC encapsulation and then check the
+ * protocol.
*/
- if (proto <= ETHERMTU) {
- /*
- * This is an LLC SAP value, so check
- * the DSAP.
- */
- return gen_cmp(off_linktype, BPF_B,
- (bpf_int32)proto);
- } else {
- /*
- * This is an Ethernet type; we assume
- * that it's unlikely that it'll
- * appear in the right place at random,
- * and therefore check only the
- * location that would hold the Ethernet
- * type in a SNAP frame with an organization
- * code of 0x000000 (encapsulated Ethernet).
- *
- * XXX - if we were to check for the SNAP DSAP
- * and LSAP, as per XXX, and were also to check
- * for an organization code of 0x000000
- * (encapsulated Ethernet), we'd do
- *
- * return gen_snap(0x000000, proto,
- * off_linktype);
- *
- * here; for now, we don't, as per the above.
- * I don't know whether it's worth the
- * extra CPU time to do the right check
- * or not.
- */
- return gen_cmp(off_linktype+6, BPF_H,
- (bpf_int32)proto);
- }
+ b0 = gen_atmfield_code(A_PROTOTYPE, PT_LLC, BPF_JEQ, 0);
+ b1 = gen_llc(proto);
+ gen_and(b0, b1);
+ return b1;
}
- break;
case DLT_LINUX_SLL:
switch (proto) {
+ case LLCSAP_IP:
+ b0 = gen_cmp(off_linktype, BPF_H, LINUX_SLL_P_802_2);
+ b1 = gen_cmp(off_linktype + 2, BPF_H, (bpf_int32)
+ ((LLCSAP_IP << 8) | LLCSAP_IP));
+ gen_and(b0, b1);
+ return b1;
+
case LLCSAP_ISONS:
/*
* OSI protocols always use 802.2 encapsulation.
@@ -1224,7 +1498,7 @@ gen_linktype(proto)
switch (proto) {
case ETHERTYPE_IP:
- proto = PPP_IP; /* XXX was 0x21 */
+ proto = PPP_IP;
break;
#ifdef INET6
@@ -1319,9 +1593,13 @@ gen_linktype(proto)
case DLT_NULL:
case DLT_LOOP:
+ case DLT_ENC:
/*
* For DLT_NULL, the link-layer header is a 32-bit
- * word containing an AF_ value in *host* byte order.
+ * word containing an AF_ value in *host* byte order,
+ * and for DLT_ENC, the link-layer header begins
+ * with a 32-bit work containing an AF_ value in
+ * host byte order.
*
* In addition, if we're reading a saved capture file,
* the host byte order in the capture may not be the
@@ -1359,7 +1637,7 @@ gen_linktype(proto)
return gen_false();
}
- if (linktype == DLT_NULL) {
+ if (linktype == DLT_NULL || linktype == DLT_ENC) {
/*
* The AF_ value is in host byte order, but
* the BPF interpreter will convert it to
@@ -1379,37 +1657,63 @@ gen_linktype(proto)
}
return (gen_cmp(0, BPF_W, (bpf_int32)proto));
+ case DLT_PFLOG:
+ /*
+ * af field is host byte order in contrast to the rest of
+ * the packet.
+ */
+ if (proto == ETHERTYPE_IP)
+ return (gen_cmp(offsetof(struct pfloghdr, af), BPF_B,
+ (bpf_int32)AF_INET));
+#ifdef INET6
+ else if (proto == ETHERTYPE_IPV6)
+ return (gen_cmp(offsetof(struct pfloghdr, af), BPF_B,
+ (bpf_int32)AF_INET6));
+#endif /* INET6 */
+ else
+ return gen_false();
+ break;
+
case DLT_ARCNET:
+ case DLT_ARCNET_LINUX:
/*
* XXX should we check for first fragment if the protocol
* uses PHDS?
*/
- switch(proto) {
+ switch (proto) {
+
default:
return gen_false();
+
#ifdef INET6
case ETHERTYPE_IPV6:
- return(gen_cmp(2, BPF_B,
- (bpf_int32)htonl(ARCTYPE_INET6)));
+ return (gen_cmp(off_linktype, BPF_B,
+ (bpf_int32)ARCTYPE_INET6));
#endif /* INET6 */
+
case ETHERTYPE_IP:
- b0 = gen_cmp(2, BPF_B, (bpf_int32)htonl(ARCTYPE_IP));
- b1 = gen_cmp(2, BPF_B,
- (bpf_int32)htonl(ARCTYPE_IP_OLD));
+ b0 = gen_cmp(off_linktype, BPF_B,
+ (bpf_int32)ARCTYPE_IP);
+ b1 = gen_cmp(off_linktype, BPF_B,
+ (bpf_int32)ARCTYPE_IP_OLD);
gen_or(b0, b1);
- return(b1);
+ return (b1);
+
case ETHERTYPE_ARP:
- b0 = gen_cmp(2, BPF_B, (bpf_int32)htonl(ARCTYPE_ARP));
- b1 = gen_cmp(2, BPF_B,
- (bpf_int32)htonl(ARCTYPE_ARP_OLD));
+ b0 = gen_cmp(off_linktype, BPF_B,
+ (bpf_int32)ARCTYPE_ARP);
+ b1 = gen_cmp(off_linktype, BPF_B,
+ (bpf_int32)ARCTYPE_ARP_OLD);
gen_or(b0, b1);
- return(b1);
+ return (b1);
+
case ETHERTYPE_REVARP:
- return(gen_cmp(2, BPF_B,
- (bpf_int32)htonl(ARCTYPE_REVARP)));
+ return (gen_cmp(off_linktype, BPF_B,
+ (bpf_int32)ARCTYPE_REVARP));
+
case ETHERTYPE_ATALK:
- return(gen_cmp(2, BPF_B,
- (bpf_int32)htonl(ARCTYPE_ATALK)));
+ return (gen_cmp(off_linktype, BPF_B,
+ (bpf_int32)ARCTYPE_ATALK));
}
break;
@@ -1421,6 +1725,54 @@ gen_linktype(proto)
return gen_false();
}
break;
+
+ case DLT_FRELAY:
+ /*
+ * XXX - assumes a 2-byte Frame Relay header with
+ * DLCI and flags. What if the address is longer?
+ */
+ switch (proto) {
+
+ case ETHERTYPE_IP:
+ /*
+ * Check for the special NLPID for IP.
+ */
+ return gen_cmp(2, BPF_H, (0x03<<8) | 0xcc);
+
+#ifdef INET6
+ case ETHERTYPE_IPV6:
+ /*
+ * Check for the special NLPID for IPv6.
+ */
+ return gen_cmp(2, BPF_H, (0x03<<8) | 0x8e);
+#endif
+
+ case LLCSAP_ISONS:
+ /*
+ * Check for several OSI protocols.
+ *
+ * Frame Relay packets typically have an OSI
+ * NLPID at the beginning; we check for each
+ * of them.
+ *
+ * What we check for is the NLPID and a frame
+ * control field of UI, i.e. 0x03 followed
+ * by the NLPID.
+ */
+ b0 = gen_cmp(2, BPF_H, (0x03<<8) | ISO8473_CLNP);
+ b1 = gen_cmp(2, BPF_H, (0x03<<8) | ISO9542_ESIS);
+ b2 = gen_cmp(2, BPF_H, (0x03<<8) | ISO10589_ISIS);
+ gen_or(b1, b2);
+ gen_or(b0, b2);
+ return b2;
+
+ default:
+ return gen_false();
+ }
+ break;
+
+ case DLT_LINUX_IRDA:
+ bpf_error("IrDA link-layer type filtering not implemented");
}
/*
@@ -1433,7 +1785,7 @@ gen_linktype(proto)
*
* Therefore, if "off_linktype" is -1, there's an error.
*/
- if (off_linktype == -1)
+ if (off_linktype == (u_int)-1)
abort();
/*
@@ -1465,7 +1817,7 @@ gen_snap(orgcode, ptype, offset)
snapblock[0] = LLCSAP_SNAP; /* DSAP = SNAP */
snapblock[1] = LLCSAP_SNAP; /* SSAP = SNAP */
- snapblock[2] = 0x03; /* control = UI */
+ snapblock[2] = 0x03; /* control = UI */
snapblock[3] = (orgcode >> 16); /* upper 8 bits of organization code */
snapblock[4] = (orgcode >> 8); /* middle 8 bits of organization code */
snapblock[5] = (orgcode >> 0); /* lower 8 bits of organization code */
@@ -1474,6 +1826,86 @@ gen_snap(orgcode, ptype, offset)
return gen_bcmp(offset, 8, snapblock);
}
+/*
+ * Check for a given protocol value assuming an 802.2 LLC header.
+ */
+static struct block *
+gen_llc(proto)
+ int proto;
+{
+ /*
+ * XXX - handle token-ring variable-length header.
+ */
+ switch (proto) {
+
+ case LLCSAP_IP:
+ return gen_cmp(off_linktype, BPF_H, (long)
+ ((LLCSAP_IP << 8) | LLCSAP_IP));
+
+ case LLCSAP_ISONS:
+ return gen_cmp(off_linktype, BPF_H, (long)
+ ((LLCSAP_ISONS << 8) | LLCSAP_ISONS));
+
+ case LLCSAP_NETBEUI:
+ return gen_cmp(off_linktype, BPF_H, (long)
+ ((LLCSAP_NETBEUI << 8) | LLCSAP_NETBEUI));
+
+ case LLCSAP_IPX:
+ /*
+ * XXX - are there ever SNAP frames for IPX on
+ * non-Ethernet 802.x networks?
+ */
+ return gen_cmp(off_linktype, BPF_B, (bpf_int32)LLCSAP_IPX);
+
+ case ETHERTYPE_ATALK:
+ /*
+ * 802.2-encapsulated ETHERTYPE_ATALK packets are
+ * SNAP packets with an organization code of
+ * 0x080007 (Apple, for Appletalk) and a protocol
+ * type of ETHERTYPE_ATALK (Appletalk).
+ *
+ * XXX - check for an organization code of
+ * encapsulated Ethernet as well?
+ */
+ return gen_snap(0x080007, ETHERTYPE_ATALK, off_linktype);
+
+ default:
+ /*
+ * XXX - we don't have to check for IPX 802.3
+ * here, but should we check for the IPX Ethertype?
+ */
+ if (proto <= ETHERMTU) {
+ /*
+ * This is an LLC SAP value, so check
+ * the DSAP.
+ */
+ return gen_cmp(off_linktype, BPF_B, (bpf_int32)proto);
+ } else {
+ /*
+ * This is an Ethernet type; we assume that it's
+ * unlikely that it'll appear in the right place
+ * at random, and therefore check only the
+ * location that would hold the Ethernet type
+ * in a SNAP frame with an organization code of
+ * 0x000000 (encapsulated Ethernet).
+ *
+ * XXX - if we were to check for the SNAP DSAP and
+ * LSAP, as per XXX, and were also to check for an
+ * organization code of 0x000000 (encapsulated
+ * Ethernet), we'd do
+ *
+ * return gen_snap(0x000000, proto,
+ * off_linktype);
+ *
+ * here; for now, we don't, as per the above.
+ * I don't know whether it's worth the extra CPU
+ * time to do the right check or not.
+ */
+ return gen_cmp(off_linktype+6, BPF_H, (bpf_int32)proto);
+ }
+ }
+}
+
static struct block *
gen_hostop(addr, mask, dir, proto, src_off, dst_off)
bpf_u_int32 addr;
@@ -1579,10 +2011,10 @@ gen_ehostop(eaddr, dir)
switch (dir) {
case Q_SRC:
- return gen_bcmp(6, 6, eaddr);
+ return gen_bcmp(off_mac + 6, 6, eaddr);
case Q_DST:
- return gen_bcmp(0, 6, eaddr);
+ return gen_bcmp(off_mac + 0, 6, eaddr);
case Q_AND:
b0 = gen_ehostop(eaddr, Q_SRC);
@@ -1678,10 +2110,318 @@ gen_thostop(eaddr, dir)
}
/*
- * Like gen_ehostop, but for DLT_IEEE802_11 (Wireless)
+ * Like gen_ehostop, but for DLT_IEEE802_11 (802.11 wireless LAN)
+ */
+static struct block *
+gen_wlanhostop(eaddr, dir)
+ register const u_char *eaddr;
+ register int dir;
+{
+ register struct block *b0, *b1, *b2;
+ register struct slist *s;
+
+ switch (dir) {
+ case Q_SRC:
+ /*
+ * Oh, yuk.
+ *
+ * For control frames, there is no SA.
+ *
+ * For management frames, SA is at an
+ * offset of 10 from the beginning of
+ * the packet.
+ *
+ * For data frames, SA is at an offset
+ * of 10 from the beginning of the packet
+ * if From DS is clear, at an offset of
+ * 16 from the beginning of the packet
+ * if From DS is set and To DS is clear,
+ * and an offset of 24 from the beginning
+ * of the packet if From DS is set and To DS
+ * is set.
+ */
+
+ /*
+ * Generate the tests to be done for data frames
+ * with From DS set.
+ *
+ * First, check for To DS set, i.e. check "link[1] & 0x01".
+ */
+ s = new_stmt(BPF_LD|BPF_B|BPF_ABS);
+ s->s.k = 1;
+ b1 = new_block(JMP(BPF_JSET));
+ b1->s.k = 0x01; /* To DS */
+ b1->stmts = s;
+
+ /*
+ * If To DS is set, the SA is at 24.
+ */
+ b0 = gen_bcmp(24, 6, eaddr);
+ gen_and(b1, b0);
+
+ /*
+ * Now, check for To DS not set, i.e. check
+ * "!(link[1] & 0x01)".
+ */
+ s = new_stmt(BPF_LD|BPF_B|BPF_ABS);
+ s->s.k = 1;
+ b2 = new_block(JMP(BPF_JSET));
+ b2->s.k = 0x01; /* To DS */
+ b2->stmts = s;
+ gen_not(b2);
+
+ /*
+ * If To DS is not set, the SA is at 16.
+ */
+ b1 = gen_bcmp(16, 6, eaddr);
+ gen_and(b2, b1);
+
+ /*
+ * Now OR together the last two checks. That gives
+ * the complete set of checks for data frames with
+ * From DS set.
+ */
+ gen_or(b1, b0);
+
+ /*
+ * Now check for From DS being set, and AND that with
+ * the ORed-together checks.
+ */
+ s = new_stmt(BPF_LD|BPF_B|BPF_ABS);
+ s->s.k = 1;
+ b1 = new_block(JMP(BPF_JSET));
+ b1->s.k = 0x02; /* From DS */
+ b1->stmts = s;
+ gen_and(b1, b0);
+
+ /*
+ * Now check for data frames with From DS not set.
+ */
+ s = new_stmt(BPF_LD|BPF_B|BPF_ABS);
+ s->s.k = 1;
+ b2 = new_block(JMP(BPF_JSET));
+ b2->s.k = 0x02; /* From DS */
+ b2->stmts = s;
+ gen_not(b2);
+
+ /*
+ * If From DS isn't set, the SA is at 10.
+ */
+ b1 = gen_bcmp(10, 6, eaddr);
+ gen_and(b2, b1);
+
+ /*
+ * Now OR together the checks for data frames with
+ * From DS not set and for data frames with From DS
+ * set; that gives the checks done for data frames.
+ */
+ gen_or(b1, b0);
+
+ /*
+ * Now check for a data frame.
+ * I.e, check "link[0] & 0x08".
+ */
+ s = new_stmt(BPF_LD|BPF_B|BPF_ABS);
+ s->s.k = 0;
+ b1 = new_block(JMP(BPF_JSET));
+ b1->s.k = 0x08;
+ b1->stmts = s;
+
+ /*
+ * AND that with the checks done for data frames.
+ */
+ gen_and(b1, b0);
+
+ /*
+ * If the high-order bit of the type value is 0, this
+ * is a management frame.
+ * I.e, check "!(link[0] & 0x08)".
+ */
+ s = new_stmt(BPF_LD|BPF_B|BPF_ABS);
+ s->s.k = 0;
+ b2 = new_block(JMP(BPF_JSET));
+ b2->s.k = 0x08;
+ b2->stmts = s;
+ gen_not(b2);
+
+ /*
+ * For management frames, the SA is at 10.
+ */
+ b1 = gen_bcmp(10, 6, eaddr);
+ gen_and(b2, b1);
+
+ /*
+ * OR that with the checks done for data frames.
+ * That gives the checks done for management and
+ * data frames.
+ */
+ gen_or(b1, b0);
+
+ /*
+ * If the low-order bit of the type value is 1,
+ * this is either a control frame or a frame
+ * with a reserved type, and thus not a
+ * frame with an SA.
+ *
+ * I.e., check "!(link[0] & 0x04)".
+ */
+ s = new_stmt(BPF_LD|BPF_B|BPF_ABS);
+ s->s.k = 0;
+ b1 = new_block(JMP(BPF_JSET));
+ b1->s.k = 0x04;
+ b1->stmts = s;
+ gen_not(b1);
+
+ /*
+ * AND that with the checks for data and management
+ * frames.
+ */
+ gen_and(b1, b0);
+ return b0;
+
+ case Q_DST:
+ /*
+ * Oh, yuk.
+ *
+ * For control frames, there is no DA.
+ *
+ * For management frames, DA is at an
+ * offset of 4 from the beginning of
+ * the packet.
+ *
+ * For data frames, DA is at an offset
+ * of 4 from the beginning of the packet
+ * if To DS is clear and at an offset of
+ * 16 from the beginning of the packet
+ * if To DS is set.
+ */
+
+ /*
+ * Generate the tests to be done for data frames.
+ *
+ * First, check for To DS set, i.e. "link[1] & 0x01".
+ */
+ s = new_stmt(BPF_LD|BPF_B|BPF_ABS);
+ s->s.k = 1;
+ b1 = new_block(JMP(BPF_JSET));
+ b1->s.k = 0x01; /* To DS */
+ b1->stmts = s;
+
+ /*
+ * If To DS is set, the DA is at 16.
+ */
+ b0 = gen_bcmp(16, 6, eaddr);
+ gen_and(b1, b0);
+
+ /*
+ * Now, check for To DS not set, i.e. check
+ * "!(link[1] & 0x01)".
+ */
+ s = new_stmt(BPF_LD|BPF_B|BPF_ABS);
+ s->s.k = 1;
+ b2 = new_block(JMP(BPF_JSET));
+ b2->s.k = 0x01; /* To DS */
+ b2->stmts = s;
+ gen_not(b2);
+
+ /*
+ * If To DS is not set, the DA is at 4.
+ */
+ b1 = gen_bcmp(4, 6, eaddr);
+ gen_and(b2, b1);
+
+ /*
+ * Now OR together the last two checks. That gives
+ * the complete set of checks for data frames.
+ */
+ gen_or(b1, b0);
+
+ /*
+ * Now check for a data frame.
+ * I.e, check "link[0] & 0x08".
+ */
+ s = new_stmt(BPF_LD|BPF_B|BPF_ABS);
+ s->s.k = 0;
+ b1 = new_block(JMP(BPF_JSET));
+ b1->s.k = 0x08;
+ b1->stmts = s;
+
+ /*
+ * AND that with the checks done for data frames.
+ */
+ gen_and(b1, b0);
+
+ /*
+ * If the high-order bit of the type value is 0, this
+ * is a management frame.
+ * I.e, check "!(link[0] & 0x08)".
+ */
+ s = new_stmt(BPF_LD|BPF_B|BPF_ABS);
+ s->s.k = 0;
+ b2 = new_block(JMP(BPF_JSET));
+ b2->s.k = 0x08;
+ b2->stmts = s;
+ gen_not(b2);
+
+ /*
+ * For management frames, the DA is at 4.
+ */
+ b1 = gen_bcmp(4, 6, eaddr);
+ gen_and(b2, b1);
+
+ /*
+ * OR that with the checks done for data frames.
+ * That gives the checks done for management and
+ * data frames.
+ */
+ gen_or(b1, b0);
+
+ /*
+ * If the low-order bit of the type value is 1,
+ * this is either a control frame or a frame
+ * with a reserved type, and thus not a
+ * frame with an SA.
+ *
+ * I.e., check "!(link[0] & 0x04)".
+ */
+ s = new_stmt(BPF_LD|BPF_B|BPF_ABS);
+ s->s.k = 0;
+ b1 = new_block(JMP(BPF_JSET));
+ b1->s.k = 0x04;
+ b1->stmts = s;
+ gen_not(b1);
+
+ /*
+ * AND that with the checks for data and management
+ * frames.
+ */
+ gen_and(b1, b0);
+ return b0;
+
+ case Q_AND:
+ b0 = gen_wlanhostop(eaddr, Q_SRC);
+ b1 = gen_wlanhostop(eaddr, Q_DST);
+ gen_and(b0, b1);
+ return b1;
+
+ case Q_DEFAULT:
+ case Q_OR:
+ b0 = gen_wlanhostop(eaddr, Q_SRC);
+ b1 = gen_wlanhostop(eaddr, Q_DST);
+ gen_or(b0, b1);
+ return b1;
+ }
+ abort();
+ /* NOTREACHED */
+}
+
+/*
+ * Like gen_ehostop, but for RFC 2625 IP-over-Fibre-Channel.
+ * (We assume that the addresses are IEEE 48-bit MAC addresses,
+ * as the RFC states.)
*/
static struct block *
-gen_whostop(eaddr, dir)
+gen_ipfchostop(eaddr, dir)
register const u_char *eaddr;
register int dir;
{
@@ -1692,18 +2432,18 @@ gen_whostop(eaddr, dir)
return gen_bcmp(10, 6, eaddr);
case Q_DST:
- return gen_bcmp(4, 6, eaddr);
+ return gen_bcmp(2, 6, eaddr);
case Q_AND:
- b0 = gen_whostop(eaddr, Q_SRC);
- b1 = gen_whostop(eaddr, Q_DST);
+ b0 = gen_ipfchostop(eaddr, Q_SRC);
+ b1 = gen_ipfchostop(eaddr, Q_DST);
gen_and(b0, b1);
return b1;
case Q_DEFAULT:
case Q_OR:
- b0 = gen_whostop(eaddr, Q_SRC);
- b1 = gen_whostop(eaddr, Q_DST);
+ b0 = gen_ipfchostop(eaddr, Q_SRC);
+ b1 = gen_ipfchostop(eaddr, Q_DST);
gen_or(b0, b1);
return b1;
}
@@ -1768,7 +2508,7 @@ gen_dnhostop(addr, dir, base_off)
case Q_ISO:
bpf_error("ISO host filtering not implemented");
-
+
default:
abort();
}
@@ -1815,7 +2555,7 @@ gen_host(addr, mask, proto, dir)
case Q_DEFAULT:
b0 = gen_host(addr, mask, Q_IP, dir);
- if (off_linktype != -1) {
+ if (off_linktype != (u_int)-1) {
b1 = gen_host(addr, mask, Q_ARP, dir);
gen_or(b0, b1);
b0 = gen_host(addr, mask, Q_RARP, dir);
@@ -2054,10 +2794,26 @@ gen_gateway(eaddr, alist, proto, dir)
else if (linktype == DLT_IEEE802)
b0 = gen_thostop(eaddr, Q_OR);
else if (linktype == DLT_IEEE802_11)
- b0 = gen_whostop(eaddr, Q_OR);
+ b0 = gen_wlanhostop(eaddr, Q_OR);
+ else if (linktype == DLT_SUNATM && is_lane) {
+ /*
+ * Check that the packet doesn't begin with an
+ * LE Control marker. (We've already generated
+ * a test for LANE.)
+ */
+ b1 = gen_cmp(SUNATM_PKT_BEGIN_POS, BPF_H, 0xFF00);
+ gen_not(b1);
+
+ /*
+ * Now check the MAC address.
+ */
+ b0 = gen_ehostop(eaddr, Q_OR);
+ gen_and(b1, b0);
+ } else if (linktype == DLT_IP_OVER_FC)
+ b0 = gen_ipfchostop(eaddr, Q_OR);
else
bpf_error(
- "'gateway' supported only on ethernet, FDDI or token ring");
+ "'gateway' supported only on ethernet/FDDI/token ring/802.11/Fibre Channel");
b1 = gen_host(**alist++, 0xffffffff, proto, Q_OR);
while (*alist) {
@@ -2078,9 +2834,7 @@ struct block *
gen_proto_abbrev(proto)
int proto;
{
-#ifdef INET6
struct block *b0;
-#endif
struct block *b1;
switch (proto) {
@@ -2238,6 +2992,66 @@ gen_proto_abbrev(proto)
b1 = gen_proto(ISO10589_ISIS, Q_ISO, Q_DEFAULT);
break;
+ case Q_ISIS_L1: /* all IS-IS Level1 PDU-Types */
+ b0 = gen_proto(ISIS_L1_LAN_IIH, Q_ISIS, Q_DEFAULT);
+ b1 = gen_proto(ISIS_PTP_IIH, Q_ISIS, Q_DEFAULT); /* FIXME extract the circuit-type bits */
+ gen_or(b0, b1);
+ b0 = gen_proto(ISIS_L1_LSP, Q_ISIS, Q_DEFAULT);
+ gen_or(b0, b1);
+ b0 = gen_proto(ISIS_L1_CSNP, Q_ISIS, Q_DEFAULT);
+ gen_or(b0, b1);
+ b0 = gen_proto(ISIS_L1_PSNP, Q_ISIS, Q_DEFAULT);
+ gen_or(b0, b1);
+ break;
+
+ case Q_ISIS_L2: /* all IS-IS Level2 PDU-Types */
+ b0 = gen_proto(ISIS_L2_LAN_IIH, Q_ISIS, Q_DEFAULT);
+ b1 = gen_proto(ISIS_PTP_IIH, Q_ISIS, Q_DEFAULT); /* FIXME extract the circuit-type bits */
+ gen_or(b0, b1);
+ b0 = gen_proto(ISIS_L2_LSP, Q_ISIS, Q_DEFAULT);
+ gen_or(b0, b1);
+ b0 = gen_proto(ISIS_L2_CSNP, Q_ISIS, Q_DEFAULT);
+ gen_or(b0, b1);
+ b0 = gen_proto(ISIS_L2_PSNP, Q_ISIS, Q_DEFAULT);
+ gen_or(b0, b1);
+ break;
+
+ case Q_ISIS_IIH: /* all IS-IS Hello PDU-Types */
+ b0 = gen_proto(ISIS_L1_LAN_IIH, Q_ISIS, Q_DEFAULT);
+ b1 = gen_proto(ISIS_L2_LAN_IIH, Q_ISIS, Q_DEFAULT);
+ gen_or(b0, b1);
+ b0 = gen_proto(ISIS_PTP_IIH, Q_ISIS, Q_DEFAULT);
+ gen_or(b0, b1);
+ break;
+
+ case Q_ISIS_LSP:
+ b0 = gen_proto(ISIS_L1_LSP, Q_ISIS, Q_DEFAULT);
+ b1 = gen_proto(ISIS_L2_LSP, Q_ISIS, Q_DEFAULT);
+ gen_or(b0, b1);
+ break;
+
+ case Q_ISIS_SNP:
+ b0 = gen_proto(ISIS_L1_CSNP, Q_ISIS, Q_DEFAULT);
+ b1 = gen_proto(ISIS_L2_CSNP, Q_ISIS, Q_DEFAULT);
+ gen_or(b0, b1);
+ b0 = gen_proto(ISIS_L1_PSNP, Q_ISIS, Q_DEFAULT);
+ gen_or(b0, b1);
+ b0 = gen_proto(ISIS_L2_PSNP, Q_ISIS, Q_DEFAULT);
+ gen_or(b0, b1);
+ break;
+
+ case Q_ISIS_CSNP:
+ b0 = gen_proto(ISIS_L1_CSNP, Q_ISIS, Q_DEFAULT);
+ b1 = gen_proto(ISIS_L2_CSNP, Q_ISIS, Q_DEFAULT);
+ gen_or(b0, b1);
+ break;
+
+ case Q_ISIS_PSNP:
+ b0 = gen_proto(ISIS_L1_PSNP, Q_ISIS, Q_DEFAULT);
+ b1 = gen_proto(ISIS_L2_PSNP, Q_ISIS, Q_DEFAULT);
+ gen_or(b0, b1);
+ break;
+
case Q_CLNP:
b1 = gen_proto(ISO8473_CLNP, Q_ISO, Q_DEFAULT);
break;
@@ -2357,7 +3171,23 @@ gen_port(port, ip_proto, dir)
{
struct block *b0, *b1, *tmp;
- /* ether proto ip */
+ /*
+ * ether proto ip
+ *
+ * For FDDI, RFC 1188 says that SNAP encapsulation is used,
+ * not LLC encapsulation with LLCSAP_IP.
+ *
+ * For IEEE 802 networks - which includes 802.5 token ring
+ * (which is what DLT_IEEE802 means) and 802.11 - RFC 1042
+ * says that SNAP encapsulation is used, not LLC encapsulation
+ * with LLCSAP_IP.
+ *
+ * For LLC-encapsulated ATM/"Classical IP", RFC 1483 and
+ * RFC 2225 say that SNAP encapsulation is used, not LLC
+ * encapsulation with LLCSAP_IP.
+ *
+ * So we always check for ETHERTYPE_IP.
+ */
b0 = gen_linktype(ETHERTYPE_IP);
switch (ip_proto) {
@@ -2822,6 +3652,21 @@ gen_proto(v, proto, dir)
/*FALLTHROUGH*/
#endif
case Q_IP:
+ /*
+ * For FDDI, RFC 1188 says that SNAP encapsulation is used,
+ * not LLC encapsulation with LLCSAP_IP.
+ *
+ * For IEEE 802 networks - which includes 802.5 token ring
+ * (which is what DLT_IEEE802 means) and 802.11 - RFC 1042
+ * says that SNAP encapsulation is used, not LLC encapsulation
+ * with LLCSAP_IP.
+ *
+ * For LLC-encapsulated ATM/"Classical IP", RFC 1483 and
+ * RFC 2225 say that SNAP encapsulation is used, not LLC
+ * encapsulation with LLCSAP_IP.
+ *
+ * So we always check for ETHERTYPE_IP.
+ */
b0 = gen_linktype(ETHERTYPE_IP);
#ifndef CHASE_CHAIN
b1 = gen_cmp(off_nl + 9, BPF_B, (bpf_int32)v);
@@ -2832,8 +3677,55 @@ gen_proto(v, proto, dir)
return b1;
case Q_ISO:
- b0 = gen_linktype(LLCSAP_ISONS);
- b1 = gen_cmp(off_nl + 3, BPF_B, (long)v);
+ switch (linktype) {
+
+ case DLT_FRELAY:
+ /*
+ * Frame Relay packets typically have an OSI
+ * NLPID at the beginning; "gen_linktype(LLCSAP_ISONS)"
+ * generates code to check for all the OSI
+ * NLPIDs, so calling it and then adding a check
+ * for the particular NLPID for which we're
+ * looking is bogus, as we can just check for
+ * the NLPID.
+ *
+ * What we check for is the NLPID and a frame
+ * control field value of UI, i.e. 0x03 followed
+ * by the NLPID.
+ *
+ * XXX - assumes a 2-byte Frame Relay header with
+ * DLCI and flags. What if the address is longer?
+ *
+ * XXX - what about SNAP-encapsulated frames?
+ */
+ return gen_cmp(2, BPF_H, (0x03<<8) | v);
+ break;
+
+ case DLT_C_HDLC:
+ /*
+ * Cisco uses an Ethertype lookalike - for OSI,
+ * it's 0xfefe.
+ */
+ b0 = gen_linktype(LLCSAP_ISONS<<8 | LLCSAP_ISONS);
+ /* OSI in C-HDLC is stuffed with a fudge byte */
+ b1 = gen_cmp(off_nl_nosnap+1, BPF_B, (long)v);
+ gen_and(b0, b1);
+ return b1;
+
+ default:
+ b0 = gen_linktype(LLCSAP_ISONS);
+ b1 = gen_cmp(off_nl_nosnap, BPF_B, (long)v);
+ gen_and(b0, b1);
+ return b1;
+ }
+
+ case Q_ISIS:
+ b0 = gen_proto(ISO10589_ISIS, Q_ISO, Q_DEFAULT);
+ /*
+ * 4 is the offset of the PDU type relative to the IS-IS
+ * header.
+ */
+ b1 = gen_cmp(off_nl_nosnap+4, BPF_B, (long)v);
gen_and(b0, b1);
return b1;
@@ -3013,16 +3905,44 @@ gen_scode(name, q)
eaddr = pcap_ether_hostton(name);
if (eaddr == NULL)
bpf_error(
- "unknown ether host '%s'", name);
- b = gen_whostop(eaddr, dir);
+ "unknown 802.11 host '%s'", name);
+ b = gen_wlanhostop(eaddr, dir);
+ free(eaddr);
+ return b;
+
+ case DLT_IP_OVER_FC:
+ eaddr = pcap_ether_hostton(name);
+ if (eaddr == NULL)
+ bpf_error(
+ "unknown Fibre Channel host '%s'", name);
+ b = gen_ipfchostop(eaddr, dir);
free(eaddr);
return b;
- default:
- bpf_error(
- "only ethernet/FDDI/token ring supports link-level host name");
- break;
+ case DLT_SUNATM:
+ if (!is_lane)
+ break;
+
+ /*
+ * Check that the packet doesn't begin
+ * with an LE Control marker. (We've
+ * already generated a test for LANE.)
+ */
+ tmp = gen_cmp(SUNATM_PKT_BEGIN_POS, BPF_H,
+ 0xFF00);
+ gen_not(tmp);
+
+ eaddr = pcap_ether_hostton(name);
+ if (eaddr == NULL)
+ bpf_error(
+ "unknown ether host '%s'", name);
+ b = gen_ehostop(eaddr, dir);
+ gen_and(tmp, b);
+ free(eaddr);
+ return b;
}
+
+ bpf_error("only ethernet/FDDI/token ring/802.11/ATM LANE/Fibre Channel supports link-level host name");
} else if (proto == Q_DECNET) {
unsigned short dn_addr = __pcap_nametodnaddr(name);
/*
@@ -3036,7 +3956,7 @@ gen_scode(name, q)
if (alist == NULL || *alist == NULL)
bpf_error("unknown host '%s'", name);
tproto = proto;
- if (off_linktype == -1 && tproto == Q_DEFAULT)
+ if (off_linktype == (u_int)-1 && tproto == Q_DEFAULT)
tproto = Q_IP;
b = gen_host(**alist++, 0xffffffff, tproto, dir);
while (*alist) {
@@ -3372,6 +4292,8 @@ gen_ecode(eaddr, q)
register const u_char *eaddr;
struct qual q;
{
+ struct block *b, *tmp;
+
if ((q.addr == Q_HOST || q.addr == Q_DEFAULT) && q.proto == Q_LINK) {
if (linktype == DLT_EN10MB)
return gen_ehostop(eaddr, (int)q.dir);
@@ -3380,8 +4302,26 @@ gen_ecode(eaddr, q)
if (linktype == DLT_IEEE802)
return gen_thostop(eaddr, (int)q.dir);
if (linktype == DLT_IEEE802_11)
- return gen_whostop(eaddr, (int)q.dir);
- bpf_error("ethernet addresses supported only on ethernet, FDDI or token ring");
+ return gen_wlanhostop(eaddr, (int)q.dir);
+ if (linktype == DLT_SUNATM && is_lane) {
+ /*
+ * Check that the packet doesn't begin with an
+ * LE Control marker. (We've already generated
+ * a test for LANE.)
+ */
+ tmp = gen_cmp(SUNATM_PKT_BEGIN_POS, BPF_H, 0xFF00);
+ gen_not(tmp);
+
+ /*
+ * Now check the MAC address.
+ */
+ b = gen_ehostop(eaddr, (int)q.dir);
+ gen_and(tmp, b);
+ return b;
+ }
+ if (linktype == DLT_IP_OVER_FC)
+ return gen_ipfchostop(eaddr, (int)q.dir);
+ bpf_error("ethernet addresses supported only on ethernet/FDDI/token ring/802.11/ATM LANE/Fibre Channel");
}
bpf_error("ethernet address used in non-ether expression");
/* NOTREACHED */
@@ -3455,6 +4395,14 @@ gen_load(proto, index, size)
bpf_error("unsupported index operation");
case Q_LINK:
+ /*
+ * XXX - what about ATM LANE? Should the index be
+ * relative to the beginning of the AAL5 frame, so
+ * that 0 refers to the beginning of the LE Control
+ * field, or relative to the beginning of the LAN
+ * frame, so that 0 refers, for Ethernet LANE, to
+ * the beginning of the destination address?
+ */
s = xfer_to_x(index);
tmp = new_stmt(BPF_LD|BPF_IND|size);
sappend(s, tmp);
@@ -3536,16 +4484,16 @@ gen_relation(code, a0, a1, reversed)
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 (code == BPF_JGT || code == BPF_JGE) {
- reversed = !reversed;
- b->s.k = 0x80000000;
+ if (code == BPF_JEQ) {
+ s2 = new_stmt(BPF_ALU|BPF_SUB|BPF_X);
+ b = new_block(JMP(code));
+ sappend(s1, s2);
}
+ else
+ b = new_block(BPF_JMP|code|BPF_X);
if (reversed)
gen_not(b);
- sappend(s1, s2);
sappend(s0, s1);
sappend(a1->s, s0);
sappend(a0->s, a1->s);
@@ -3643,6 +4591,7 @@ gen_arth(code, a0, a1)
sappend(a1->s, s0);
sappend(a0->s, a1->s);
+ free_reg(a0->regno);
free_reg(a1->regno);
s0 = new_stmt(BPF_ST);
@@ -3782,7 +4731,7 @@ gen_broadcast(proto)
case Q_DEFAULT:
case Q_LINK:
- if (linktype == DLT_ARCNET)
+ if (linktype == DLT_ARCNET || linktype == DLT_ARCNET_LINUX)
return gen_ahostop(abroadcast, Q_DST);
if (linktype == DLT_EN10MB)
return gen_ehostop(ebroadcast, Q_DST);
@@ -3791,7 +4740,25 @@ gen_broadcast(proto)
if (linktype == DLT_IEEE802)
return gen_thostop(ebroadcast, Q_DST);
if (linktype == DLT_IEEE802_11)
- return gen_whostop(ebroadcast, Q_DST);
+ return gen_wlanhostop(ebroadcast, Q_DST);
+ if (linktype == DLT_IP_OVER_FC)
+ return gen_ipfchostop(ebroadcast, Q_DST);
+ if (linktype == DLT_SUNATM && is_lane) {
+ /*
+ * Check that the packet doesn't begin with an
+ * LE Control marker. (We've already generated
+ * a test for LANE.)
+ */
+ b1 = gen_cmp(SUNATM_PKT_BEGIN_POS, BPF_H, 0xFF00);
+ gen_not(b1);
+
+ /*
+ * Now check the MAC address.
+ */
+ b0 = gen_ehostop(ebroadcast, Q_DST);
+ gen_and(b1, b0);
+ return b0;
+ }
bpf_error("not a broadcast link");
break;
@@ -3805,47 +4772,203 @@ gen_broadcast(proto)
gen_and(b0, b2);
return b2;
}
- bpf_error("only ether/ip broadcast filters supported");
+ bpf_error("only link-layer/IP broadcast filters supported");
+}
+
+/*
+ * Generate code to test the low-order bit of a MAC address (that's
+ * the bottom bit of the *first* byte).
+ */
+static struct block *
+gen_mac_multicast(offset)
+ int offset;
+{
+ register struct block *b0;
+ register struct slist *s;
+
+ /* link[offset] & 1 != 0 */
+ s = new_stmt(BPF_LD|BPF_B|BPF_ABS);
+ s->s.k = offset;
+ b0 = new_block(JMP(BPF_JSET));
+ b0->s.k = 1;
+ b0->stmts = s;
+ return b0;
}
struct block *
gen_multicast(proto)
int proto;
{
- register struct block *b0, *b1;
+ register struct block *b0, *b1, *b2;
register struct slist *s;
switch (proto) {
case Q_DEFAULT:
case Q_LINK:
- if (linktype == DLT_ARCNET)
+ if (linktype == DLT_ARCNET || linktype == DLT_ARCNET_LINUX)
/* all ARCnet multicasts use the same address */
return gen_ahostop(abroadcast, Q_DST);
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;
+ return gen_mac_multicast(0);
}
if (linktype == DLT_FDDI) {
- /* XXX TEST THIS: MIGHT NOT PORT PROPERLY XXX */
+ /*
+ * XXX TEST THIS: MIGHT NOT PORT PROPERLY XXX
+ *
+ * XXX - was that referring to bit-order issues?
+ */
/* fddi[1] & 1 != 0 */
+ return gen_mac_multicast(1);
+ }
+
+ if (linktype == DLT_IEEE802) {
+ /* tr[2] & 1 != 0 */
+ return gen_mac_multicast(2);
+ }
+
+ if (linktype == DLT_IEEE802_11) {
+ /*
+ * Oh, yuk.
+ *
+ * For control frames, there is no DA.
+ *
+ * For management frames, DA is at an
+ * offset of 4 from the beginning of
+ * the packet.
+ *
+ * For data frames, DA is at an offset
+ * of 4 from the beginning of the packet
+ * if To DS is clear and at an offset of
+ * 16 from the beginning of the packet
+ * if To DS is set.
+ */
+
+ /*
+ * Generate the tests to be done for data frames.
+ *
+ * First, check for To DS set, i.e. "link[1] & 0x01".
+ */
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;
+ b1 = new_block(JMP(BPF_JSET));
+ b1->s.k = 0x01; /* To DS */
+ b1->stmts = s;
+
+ /*
+ * If To DS is set, the DA is at 16.
+ */
+ b0 = gen_mac_multicast(16);
+ gen_and(b1, b0);
+
+ /*
+ * Now, check for To DS not set, i.e. check
+ * "!(link[1] & 0x01)".
+ */
+ s = new_stmt(BPF_LD|BPF_B|BPF_ABS);
+ s->s.k = 1;
+ b2 = new_block(JMP(BPF_JSET));
+ b2->s.k = 0x01; /* To DS */
+ b2->stmts = s;
+ gen_not(b2);
+
+ /*
+ * If To DS is not set, the DA is at 4.
+ */
+ b1 = gen_mac_multicast(4);
+ gen_and(b2, b1);
+
+ /*
+ * Now OR together the last two checks. That gives
+ * the complete set of checks for data frames.
+ */
+ gen_or(b1, b0);
+
+ /*
+ * Now check for a data frame.
+ * I.e, check "link[0] & 0x08".
+ */
+ s = new_stmt(BPF_LD|BPF_B|BPF_ABS);
+ s->s.k = 0;
+ b1 = new_block(JMP(BPF_JSET));
+ b1->s.k = 0x08;
+ b1->stmts = s;
+
+ /*
+ * AND that with the checks done for data frames.
+ */
+ gen_and(b1, b0);
+
+ /*
+ * If the high-order bit of the type value is 0, this
+ * is a management frame.
+ * I.e, check "!(link[0] & 0x08)".
+ */
+ s = new_stmt(BPF_LD|BPF_B|BPF_ABS);
+ s->s.k = 0;
+ b2 = new_block(JMP(BPF_JSET));
+ b2->s.k = 0x08;
+ b2->stmts = s;
+ gen_not(b2);
+
+ /*
+ * For management frames, the DA is at 4.
+ */
+ b1 = gen_mac_multicast(4);
+ gen_and(b2, b1);
+
+ /*
+ * OR that with the checks done for data frames.
+ * That gives the checks done for management and
+ * data frames.
+ */
+ gen_or(b1, b0);
+
+ /*
+ * If the low-order bit of the type value is 1,
+ * this is either a control frame or a frame
+ * with a reserved type, and thus not a
+ * frame with an SA.
+ *
+ * I.e., check "!(link[0] & 0x04)".
+ */
+ s = new_stmt(BPF_LD|BPF_B|BPF_ABS);
+ s->s.k = 0;
+ b1 = new_block(JMP(BPF_JSET));
+ b1->s.k = 0x04;
+ b1->stmts = s;
+ gen_not(b1);
+
+ /*
+ * AND that with the checks for data and management
+ * frames.
+ */
+ gen_and(b1, b0);
+ return b0;
+ }
+
+ if (linktype == DLT_IP_OVER_FC) {
+ b0 = gen_mac_multicast(2);
return b0;
}
- /* TODO - check how token ring handles multicast */
- /* if (linktype == DLT_IEEE802) ... */
+ if (linktype == DLT_SUNATM && is_lane) {
+ /*
+ * Check that the packet doesn't begin with an
+ * LE Control marker. (We've already generated
+ * a test for LANE.)
+ */
+ b1 = gen_cmp(SUNATM_PKT_BEGIN_POS, BPF_H, 0xFF00);
+ gen_not(b1);
+
+ /* ether[off_mac] & 1 != 0 */
+ b0 = gen_mac_multicast(off_mac);
+ gen_and(b1, b0);
+ return b0;
+ }
/* Link not known to support multicasts */
break;
@@ -3865,7 +4988,7 @@ gen_multicast(proto)
return b1;
#endif /* INET6 */
}
- bpf_error("only IP multicast filters supported on ethernet/FDDI");
+ bpf_error("link-layer multicast filters supported only on ethernet/FDDI/token ring/ARCNET/802.11/ATM LANE/Fibre Channel");
}
/*
@@ -3884,15 +5007,40 @@ gen_inbound(dir)
*/
switch (linktype) {
case DLT_SLIP:
- case DLT_PPP:
b0 = gen_relation(BPF_JEQ,
gen_load(Q_LINK, gen_loadi(0), 1),
gen_loadi(0),
dir);
break;
+ case DLT_LINUX_SLL:
+ if (dir) {
+ /*
+ * Match packets sent by this machine.
+ */
+ b0 = gen_cmp(0, BPF_H, LINUX_SLL_OUTGOING);
+ } else {
+ /*
+ * Match packets sent to this machine.
+ * (No broadcast or multicast packets, or
+ * packets sent to some other machine and
+ * received promiscuously.)
+ *
+ * XXX - packets sent to other machines probably
+ * shouldn't be matched, but what about broadcast
+ * or multicast packets we received?
+ */
+ b0 = gen_cmp(0, BPF_H, LINUX_SLL_HOST);
+ }
+ break;
+
+ case DLT_PFLOG:
+ b0 = gen_cmp(offsetof(struct pfloghdr, dir), BPF_B,
+ (bpf_int32)((dir == 0) ? PF_IN : PF_OUT));
+ break;
+
default:
- bpf_error("inbound/outbound not supported on linktype %d\n",
+ bpf_error("inbound/outbound not supported on linktype %d",
linktype);
b0 = NULL;
/* NOTREACHED */
@@ -3900,13 +5048,123 @@ gen_inbound(dir)
return (b0);
}
+/* PF firewall log matched interface */
+struct block *
+gen_pf_ifname(const char *ifname)
+{
+ struct block *b0;
+ u_int len, off;
+
+ if (linktype == DLT_PFLOG) {
+ len = sizeof(((struct pfloghdr *)0)->ifname);
+ off = offsetof(struct pfloghdr, ifname);
+ } else {
+ bpf_error("ifname not supported on linktype 0x%x", linktype);
+ /* NOTREACHED */
+ }
+ if (strlen(ifname) >= len) {
+ bpf_error("ifname interface names can only be %d characters",
+ len-1);
+ /* NOTREACHED */
+ }
+ b0 = gen_bcmp(off, strlen(ifname), ifname);
+ return (b0);
+}
+
+/* PF firewall log matched interface */
+struct block *
+gen_pf_ruleset(char *ruleset)
+{
+ struct block *b0;
+
+ if (linktype != DLT_PFLOG) {
+ bpf_error("ruleset not supported on linktype 0x%x", linktype);
+ /* NOTREACHED */
+ }
+ if (strlen(ruleset) >= sizeof(((struct pfloghdr *)0)->ruleset)) {
+ bpf_error("ruleset names can only be %ld characters",
+ (long)(sizeof(((struct pfloghdr *)0)->ruleset) - 1));
+ /* NOTREACHED */
+ }
+ b0 = gen_bcmp(offsetof(struct pfloghdr, ruleset),
+ strlen(ruleset), ruleset);
+ return (b0);
+}
+
+/* PF firewall log rule number */
+struct block *
+gen_pf_rnr(int rnr)
+{
+ struct block *b0;
+
+ if (linktype == DLT_PFLOG) {
+ b0 = gen_cmp(offsetof(struct pfloghdr, rulenr), BPF_W,
+ (bpf_int32)rnr);
+ } else {
+ bpf_error("rnr not supported on linktype 0x%x", linktype);
+ /* NOTREACHED */
+ }
+
+ return (b0);
+}
+
+/* PF firewall log sub-rule number */
+struct block *
+gen_pf_srnr(int srnr)
+{
+ struct block *b0;
+
+ if (linktype != DLT_PFLOG) {
+ bpf_error("srnr not supported on linktype 0x%x", linktype);
+ /* NOTREACHED */
+ }
+
+ b0 = gen_cmp(offsetof(struct pfloghdr, subrulenr), BPF_W,
+ (bpf_int32)srnr);
+ return (b0);
+}
+
+/* PF firewall log reason code */
+struct block *
+gen_pf_reason(int reason)
+{
+ struct block *b0;
+
+ if (linktype == DLT_PFLOG) {
+ b0 = gen_cmp(offsetof(struct pfloghdr, reason), BPF_B,
+ (bpf_int32)reason);
+ } else {
+ bpf_error("reason not supported on linktype 0x%x", linktype);
+ /* NOTREACHED */
+ }
+
+ return (b0);
+}
+
+/* PF firewall log action */
+struct block *
+gen_pf_action(int action)
+{
+ struct block *b0;
+
+ if (linktype == DLT_PFLOG) {
+ b0 = gen_cmp(offsetof(struct pfloghdr, action), BPF_B,
+ (bpf_int32)action);
+ } else {
+ bpf_error("action not supported on linktype 0x%x", linktype);
+ /* NOTREACHED */
+ }
+
+ return (b0);
+}
+
struct block *
gen_acode(eaddr, q)
register const u_char *eaddr;
struct qual q;
{
if ((q.addr == Q_HOST || q.addr == Q_DEFAULT) && q.proto == Q_LINK) {
- if (linktype == DLT_ARCNET)
+ if (linktype == DLT_ARCNET || linktype == DLT_ARCNET_LINUX)
return gen_ahostop(eaddr, (int)q.dir);
}
bpf_error("ARCnet address used in non-arc expression");
@@ -3961,11 +5219,13 @@ gen_vlan(vlan_num)
if (orig_nl == (u_int)-1) {
orig_linktype = off_linktype; /* save original values */
orig_nl = off_nl;
+ orig_nl_nosnap = off_nl_nosnap;
switch (linktype) {
case DLT_EN10MB:
off_linktype = 16;
+ off_nl_nosnap = 18;
off_nl = 18;
break;
@@ -3990,3 +5250,274 @@ gen_vlan(vlan_num)
return (b0);
}
+
+struct block *
+gen_atmfield_code(atmfield, jvalue, jtype, reverse)
+ int atmfield;
+ bpf_u_int32 jvalue;
+ bpf_u_int32 jtype;
+ int reverse;
+{
+ struct block *b0;
+
+ switch (atmfield) {
+
+ case A_VPI:
+ if (!is_atm)
+ bpf_error("'vpi' supported only on raw ATM");
+ if (off_vpi == (u_int)-1)
+ abort();
+ b0 = gen_ncmp(BPF_B, off_vpi, 0xffffffff, (u_int)jtype,
+ (u_int)jvalue, reverse);
+ break;
+
+ case A_VCI:
+ if (!is_atm)
+ bpf_error("'vci' supported only on raw ATM");
+ if (off_vci == (u_int)-1)
+ abort();
+ b0 = gen_ncmp(BPF_H, off_vci, 0xffffffff, (u_int)jtype,
+ (u_int)jvalue, reverse);
+ break;
+
+ case A_PROTOTYPE:
+ if (off_proto == (u_int)-1)
+ abort(); /* XXX - this isn't on FreeBSD */
+ b0 = gen_ncmp(BPF_B, off_proto, 0x0f, (u_int)jtype,
+ (u_int)jvalue, reverse);
+ break;
+
+ case A_MSGTYPE:
+ if (off_payload == (u_int)-1)
+ abort();
+ b0 = gen_ncmp(BPF_B, off_payload + MSG_TYPE_POS, 0xffffffff,
+ (u_int)jtype, (u_int)jvalue, reverse);
+ break;
+
+ case A_CALLREFTYPE:
+ if (!is_atm)
+ bpf_error("'callref' supported only on raw ATM");
+ if (off_proto == (u_int)-1)
+ abort();
+ b0 = gen_ncmp(BPF_B, off_proto, 0xffffffff, (u_int)jtype,
+ (u_int)jvalue, reverse);
+ break;
+
+ default:
+ abort();
+ }
+ return b0;
+}
+
+struct block *
+gen_atmtype_abbrev(type)
+ int type;
+{
+ struct block *b0, *b1;
+
+ switch (type) {
+
+ case A_METAC:
+ /* Get all packets in Meta signalling Circuit */
+ if (!is_atm)
+ bpf_error("'metac' supported only on raw ATM");
+ b0 = gen_atmfield_code(A_VPI, 0, BPF_JEQ, 0);
+ b1 = gen_atmfield_code(A_VCI, 1, BPF_JEQ, 0);
+ gen_and(b0, b1);
+ break;
+
+ case A_BCC:
+ /* Get all packets in Broadcast Circuit*/
+ if (!is_atm)
+ bpf_error("'bcc' supported only on raw ATM");
+ b0 = gen_atmfield_code(A_VPI, 0, BPF_JEQ, 0);
+ b1 = gen_atmfield_code(A_VCI, 2, BPF_JEQ, 0);
+ gen_and(b0, b1);
+ break;
+
+ case A_OAMF4SC:
+ /* Get all cells in Segment OAM F4 circuit*/
+ if (!is_atm)
+ bpf_error("'oam4sc' supported only on raw ATM");
+ b0 = gen_atmfield_code(A_VPI, 0, BPF_JEQ, 0);
+ b1 = gen_atmfield_code(A_VCI, 3, BPF_JEQ, 0);
+ gen_and(b0, b1);
+ break;
+
+ case A_OAMF4EC:
+ /* Get all cells in End-to-End OAM F4 Circuit*/
+ if (!is_atm)
+ bpf_error("'oam4ec' supported only on raw ATM");
+ b0 = gen_atmfield_code(A_VPI, 0, BPF_JEQ, 0);
+ b1 = gen_atmfield_code(A_VCI, 4, BPF_JEQ, 0);
+ gen_and(b0, b1);
+ break;
+
+ case A_SC:
+ /* Get all packets in connection Signalling Circuit */
+ if (!is_atm)
+ bpf_error("'sc' supported only on raw ATM");
+ b0 = gen_atmfield_code(A_VPI, 0, BPF_JEQ, 0);
+ b1 = gen_atmfield_code(A_VCI, 5, BPF_JEQ, 0);
+ gen_and(b0, b1);
+ break;
+
+ case A_ILMIC:
+ /* Get all packets in ILMI Circuit */
+ if (!is_atm)
+ bpf_error("'ilmic' supported only on raw ATM");
+ b0 = gen_atmfield_code(A_VPI, 0, BPF_JEQ, 0);
+ b1 = gen_atmfield_code(A_VCI, 16, BPF_JEQ, 0);
+ gen_and(b0, b1);
+ break;
+
+ case A_LANE:
+ /* Get all LANE packets */
+ if (!is_atm)
+ bpf_error("'lane' supported only on raw ATM");
+ b1 = gen_atmfield_code(A_PROTOTYPE, PT_LANE, BPF_JEQ, 0);
+
+ /*
+ * Arrange that all subsequent tests assume LANE
+ * rather than LLC-encapsulated packets, and set
+ * the offsets appropriately for LANE-encapsulated
+ * Ethernet.
+ *
+ * "off_mac" is the offset of the Ethernet header,
+ * which is 2 bytes past the ATM pseudo-header
+ * (skipping the pseudo-header and 2-byte LE Client
+ * field). The other offsets are Ethernet offsets
+ * relative to "off_mac".
+ */
+ is_lane = 1;
+ off_mac = off_payload + 2; /* MAC header */
+ off_linktype = off_mac + 12;
+ off_nl = off_mac + 14; /* Ethernet II */
+ off_nl_nosnap = off_mac + 17; /* 802.3+802.2 */
+ break;
+
+ case A_LLC:
+ /* Get all LLC-encapsulated packets */
+ if (!is_atm)
+ bpf_error("'llc' supported only on raw ATM");
+ b1 = gen_atmfield_code(A_PROTOTYPE, PT_LLC, BPF_JEQ, 0);
+ is_lane = 0;
+ break;
+
+ default:
+ abort();
+ }
+ return b1;
+}
+
+
+static struct block *
+gen_msg_abbrev(type)
+ int type;
+{
+ struct block *b1;
+
+ /*
+ * Q.2931 signalling protocol messages for handling virtual circuits
+ * establishment and teardown
+ */
+ switch (type) {
+
+ case A_SETUP:
+ b1 = gen_atmfield_code(A_MSGTYPE, SETUP, BPF_JEQ, 0);
+ break;
+
+ case A_CALLPROCEED:
+ b1 = gen_atmfield_code(A_MSGTYPE, CALL_PROCEED, BPF_JEQ, 0);
+ break;
+
+ case A_CONNECT:
+ b1 = gen_atmfield_code(A_MSGTYPE, CONNECT, BPF_JEQ, 0);
+ break;
+
+ case A_CONNECTACK:
+ b1 = gen_atmfield_code(A_MSGTYPE, CONNECT_ACK, BPF_JEQ, 0);
+ break;
+
+ case A_RELEASE:
+ b1 = gen_atmfield_code(A_MSGTYPE, RELEASE, BPF_JEQ, 0);
+ break;
+
+ case A_RELEASE_DONE:
+ b1 = gen_atmfield_code(A_MSGTYPE, RELEASE_DONE, BPF_JEQ, 0);
+ break;
+
+ default:
+ abort();
+ }
+ return b1;
+}
+
+struct block *
+gen_atmmulti_abbrev(type)
+ int type;
+{
+ struct block *b0, *b1;
+
+ switch (type) {
+
+ case A_OAM:
+ if (!is_atm)
+ bpf_error("'oam' supported only on raw ATM");
+ b1 = gen_atmmulti_abbrev(A_OAMF4);
+ break;
+
+ case A_OAMF4:
+ if (!is_atm)
+ bpf_error("'oamf4' supported only on raw ATM");
+ /* OAM F4 type */
+ b0 = gen_atmfield_code(A_VCI, 3, BPF_JEQ, 0);
+ b1 = gen_atmfield_code(A_VCI, 4, BPF_JEQ, 0);
+ gen_or(b0, b1);
+ b0 = gen_atmfield_code(A_VPI, 0, BPF_JEQ, 0);
+ gen_and(b0, b1);
+ break;
+
+ case A_CONNECTMSG:
+ /*
+ * Get Q.2931 signalling messages for switched
+ * virtual connection
+ */
+ if (!is_atm)
+ bpf_error("'connectmsg' supported only on raw ATM");
+ b0 = gen_msg_abbrev(A_SETUP);
+ b1 = gen_msg_abbrev(A_CALLPROCEED);
+ gen_or(b0, b1);
+ b0 = gen_msg_abbrev(A_CONNECT);
+ gen_or(b0, b1);
+ b0 = gen_msg_abbrev(A_CONNECTACK);
+ gen_or(b0, b1);
+ b0 = gen_msg_abbrev(A_RELEASE);
+ gen_or(b0, b1);
+ b0 = gen_msg_abbrev(A_RELEASE_DONE);
+ gen_or(b0, b1);
+ b0 = gen_atmtype_abbrev(A_SC);
+ gen_and(b0, b1);
+ break;
+
+ case A_METACONNECT:
+ if (!is_atm)
+ bpf_error("'metaconnect' supported only on raw ATM");
+ b0 = gen_msg_abbrev(A_SETUP);
+ b1 = gen_msg_abbrev(A_CALLPROCEED);
+ gen_or(b0, b1);
+ b0 = gen_msg_abbrev(A_CONNECT);
+ gen_or(b0, b1);
+ b0 = gen_msg_abbrev(A_RELEASE);
+ gen_or(b0, b1);
+ b0 = gen_msg_abbrev(A_RELEASE_DONE);
+ gen_or(b0, b1);
+ b0 = gen_atmtype_abbrev(A_METAC);
+ gen_and(b0, b1);
+ break;
+
+ default:
+ abort();
+ }
+ return b1;
+}
diff --git a/contrib/libpcap/gencode.h b/contrib/libpcap/gencode.h
index c790547..fccdf3c 100644
--- a/contrib/libpcap/gencode.h
+++ b/contrib/libpcap/gencode.h
@@ -18,9 +18,42 @@
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * @(#) $Header: /tcpdump/master/libpcap/gencode.h,v 1.53 2001/05/10 14:48:02 fenner Exp $ (LBL)
- *
* $FreeBSD$
+ * @(#) $Header: /tcpdump/master/libpcap/gencode.h,v 1.58.2.1 2004/03/28 21:45:31 fenner Exp $ (LBL)
+ */
+
+/*
+ * ATM support:
+ *
+ * Copyright (c) 1997 Yen Yen Lim and North Dakota State University
+ * 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 Yen Yen Lim and
+ * North Dakota State University
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
*/
/* Address qualifiers. */
@@ -75,6 +108,18 @@
#define Q_NETBEUI 30
+/* IS-IS Levels */
+#define Q_ISIS_L1 31
+#define Q_ISIS_L2 32
+/* PDU types */
+#define Q_ISIS_IIH 33
+#define Q_ISIS_LAN_IIH 34
+#define Q_ISIS_PTP_IIH 35
+#define Q_ISIS_SNP 36
+#define Q_ISIS_CSNP 37
+#define Q_ISIS_PSNP 38
+#define Q_ISIS_LSP 39
+
/* Directional qualifiers. */
#define Q_SRC 1
@@ -85,6 +130,43 @@
#define Q_DEFAULT 0
#define Q_UNDEF 255
+/* ATM types */
+#define A_METAC 22 /* Meta signalling Circuit */
+#define A_BCC 23 /* Broadcast Circuit */
+#define A_OAMF4SC 24 /* Segment OAM F4 Circuit */
+#define A_OAMF4EC 25 /* End-to-End OAM F4 Circuit */
+#define A_SC 26 /* Signalling Circuit*/
+#define A_ILMIC 27 /* ILMI Circuit */
+#define A_OAM 28 /* OAM cells : F4 only */
+#define A_OAMF4 29 /* OAM F4 cells: Segment + End-to-end */
+#define A_LANE 30 /* LANE traffic */
+#define A_LLC 31 /* LLC-encapsulated traffic */
+
+/* Based on Q.2931 signalling protocol */
+#define A_SETUP 41 /* Setup message */
+#define A_CALLPROCEED 42 /* Call proceeding message */
+#define A_CONNECT 43 /* Connect message */
+#define A_CONNECTACK 44 /* Connect Ack message */
+#define A_RELEASE 45 /* Release message */
+#define A_RELEASE_DONE 46 /* Release message */
+
+/* ATM field types */
+#define A_VPI 51
+#define A_VCI 52
+#define A_PROTOTYPE 53
+#define A_MSGTYPE 54
+#define A_CALLREFTYPE 55
+
+#define A_CONNECTMSG 70 /* returns Q.2931 signalling messages for
+ establishing and destroying switched
+ virtual connection */
+#define A_METACONNECT 71 /* returns Q.2931 signalling messages for
+ establishing and destroying predefined
+ virtual circuits, such as broadcast
+ circuit, oamf4 segment circuit, oamf4
+ end-to-end circuits, ILMI circuits or
+ connection signalling circuit. */
+
struct slist;
struct stmt {
@@ -99,7 +181,7 @@ struct slist {
struct slist *next;
};
-/*
+/*
* A bit vector to represent definition sets. We assume TOT_REGISTERS
* is smaller than 8*sizeof(atomset).
*/
@@ -193,6 +275,18 @@ struct block *gen_inbound(int);
struct block *gen_vlan(int);
+struct block *gen_atmfield_code(int atmfield, bpf_u_int32 jvalue, bpf_u_int32 jtype, int reverse);
+struct block *gen_atmtype_abbrev(int type);
+struct block *gen_atmmulti_abbrev(int type);
+
+struct block *gen_pf_ifname(const char *);
+struct block *gen_pf_rnr(int);
+struct block *gen_pf_srnr(int);
+struct block *gen_pf_ruleset(char *);
+struct block *gen_pf_reason(int);
+struct block *gen_pf_action(int);
+struct block *gen_pf_dir(int);
+
void bpf_optimize(struct block **);
void bpf_error(const char *, ...)
#if HAVE___ATTRIBUTE__
diff --git a/contrib/libpcap/grammar.y b/contrib/libpcap/grammar.y
index ea75012..63ca863 100644
--- a/contrib/libpcap/grammar.y
+++ b/contrib/libpcap/grammar.y
@@ -22,33 +22,40 @@
* $FreeBSD$
*/
#ifndef lint
-static const char rcsid[] =
- "@(#) $Header: /tcpdump/master/libpcap/grammar.y,v 1.71 2001/07/03 19:15:48 guy Exp $ (LBL)";
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/libpcap/grammar.y,v 1.79.2.3 2004/03/28 21:45:32 fenner Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
+#ifdef WIN32
+#include <pcap-stdinc.h>
+#else /* WIN32 */
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
+#endif /* WIN32 */
+
#include <stdlib.h>
+#ifndef WIN32
#if __STDC__
struct mbuf;
struct rtentry;
#endif
-#include <net/if.h>
-
#include <netinet/in.h>
+#endif /* WIN32 */
#include <stdio.h>
+#include <strings.h>
#include "pcap-int.h"
#include "gencode.h"
+#include "pf.h"
#include <pcap-namedb.h>
#ifdef HAVE_OS_PROTO_H
@@ -92,6 +99,7 @@ pcap_parse()
struct arth *a;
struct {
struct qual q;
+ int atmfieldtype;
struct block *b;
} blk;
struct block *rblk;
@@ -103,14 +111,18 @@ pcap_parse()
%type <a> arth narth
%type <i> byteop pname pnum relop irelop
%type <blk> and or paren not null prog
-%type <rblk> other
+%type <rblk> other pfvar
+%type <i> atmtype atmmultitype
+%type <blk> atmfield
+%type <blk> atmfieldvalue atmvalue atmlistvalue
%token DST SRC HOST GATEWAY
-%token NET MASK PORT LESS GREATER PROTO PROTOCHAIN BYTE
+%token NET NETMASK PORT LESS GREATER PROTO PROTOCHAIN CBYTE
%token ARP RARP IP SCTP TCP UDP ICMP IGMP IGRP PIM VRRP
%token ATALK AARP DECNET LAT SCA MOPRC MOPDL
%token TK_BROADCAST TK_MULTICAST
%token NUM INBOUND OUTBOUND
+%token PF_IFNAME PF_RSET PF_RNR PF_SRNR PF_REASON PF_ACTION
%token LINK
%token GEQ LEQ NEQ
%token ID EID HID HID6 AID
@@ -118,16 +130,19 @@ pcap_parse()
%token LEN
%token IPV6 ICMPV6 AH ESP
%token VLAN
-%token ISO ESIS ISIS CLNP
+%token ISO ESIS CLNP ISIS L1 L2 IIH LSP SNP CSNP PSNP
%token STP
%token IPX
%token NETBEUI
+%token LANE LLC METAC BCC SC ILMIC OAMF4EC OAMF4SC
+%token OAM OAMF4 CONNECTMSG METACONNECT
+%token VPI VCI
%type <s> ID
%type <e> EID
%type <e> AID
%type <s> HID HID6
-%type <i> NUM
+%type <i> NUM action reason
%left OR AND
%nonassoc '!'
@@ -164,7 +179,7 @@ id: nid
nid: ID { $$.b = gen_scode($1, $$.q = $<blk>0.q); }
| HID '/' NUM { $$.b = gen_mcode($1, NULL, $3,
$$.q = $<blk>0.q); }
- | HID MASK HID { $$.b = gen_mcode($1, $3, 0,
+ | HID NETMASK HID { $$.b = gen_mcode($1, $3, 0,
$$.q = $<blk>0.q); }
| HID {
/* Decide how to parse HID based on proto */
@@ -239,6 +254,9 @@ rterm: head id { $$ = $2; }
| arth irelop arth { $$.b = gen_relation($2, $1, $3, 1);
$$.q = qerr; }
| other { $$.b = $1; $$.q = qerr; }
+ | atmtype { $$.b = gen_atmtype_abbrev($1); $$.q = qerr; }
+ | atmmultitype { $$.b = gen_atmmulti_abbrev($1); $$.q = qerr; }
+ | atmfield atmvalue { $$.b = $2.b; $$.q = qerr; }
;
/* protocol level qualifiers */
pqual: pname
@@ -286,6 +304,13 @@ pname: LINK { $$ = Q_LINK; }
| ISO { $$ = Q_ISO; }
| ESIS { $$ = Q_ESIS; }
| ISIS { $$ = Q_ISIS; }
+ | L1 { $$ = Q_ISIS_L1; }
+ | L2 { $$ = Q_ISIS_L2; }
+ | IIH { $$ = Q_ISIS_IIH; }
+ | LSP { $$ = Q_ISIS_LSP; }
+ | SNP { $$ = Q_ISIS_SNP; }
+ | PSNP { $$ = Q_ISIS_PSNP; }
+ | CSNP { $$ = Q_ISIS_CSNP; }
| CLNP { $$ = Q_CLNP; }
| STP { $$ = Q_STP; }
| IPX { $$ = Q_IPX; }
@@ -295,12 +320,47 @@ 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); }
+ | CBYTE NUM byteop NUM { $$ = gen_byteop($3, $2, $4); }
| INBOUND { $$ = gen_inbound(0); }
| OUTBOUND { $$ = gen_inbound(1); }
| VLAN pnum { $$ = gen_vlan($2); }
| VLAN { $$ = gen_vlan(-1); }
+ | pfvar { $$ = $1; }
;
+
+pfvar: PF_IFNAME ID { $$ = gen_pf_ifname($2); }
+ | PF_RSET ID { $$ = gen_pf_ruleset($2); }
+ | PF_RNR NUM { $$ = gen_pf_rnr($2); }
+ | PF_SRNR NUM { $$ = gen_pf_srnr($2); }
+ | PF_REASON reason { $$ = gen_pf_reason($2); }
+ | PF_ACTION action { $$ = gen_pf_action($2); }
+ ;
+
+reason: NUM { $$ = $1; }
+ | ID { const char *reasons[] = PFRES_NAMES;
+ int i;
+ for (i = 0; reasons[i]; i++) {
+ if (pcap_strcasecmp($1, reasons[i]) == 0) {
+ $$ = i;
+ break;
+ }
+ }
+ if (reasons[i] == NULL)
+ bpf_error("unknown PF reason");
+ }
+ ;
+
+action: ID { if (pcap_strcasecmp($1, "pass") == 0 ||
+ pcap_strcasecmp($1, "accept") == 0)
+ $$ = PF_PASS;
+ else if (pcap_strcasecmp($1, "drop") == 0 ||
+ pcap_strcasecmp($1, "block") == 0)
+ $$ = PF_DROP;
+ else
+ bpf_error("unknown PF action");
+ }
+ ;
+
relop: '>' { $$ = BPF_JGT; }
| GEQ { $$ = BPF_JGE; }
| '=' { $$ = BPF_JEQ; }
@@ -335,4 +395,37 @@ byteop: '&' { $$ = '&'; }
pnum: NUM
| paren pnum ')' { $$ = $2; }
;
+atmtype: LANE { $$ = A_LANE; }
+ | LLC { $$ = A_LLC; }
+ | METAC { $$ = A_METAC; }
+ | BCC { $$ = A_BCC; }
+ | OAMF4EC { $$ = A_OAMF4EC; }
+ | OAMF4SC { $$ = A_OAMF4SC; }
+ | SC { $$ = A_SC; }
+ | ILMIC { $$ = A_ILMIC; }
+ ;
+atmmultitype: OAM { $$ = A_OAM; }
+ | OAMF4 { $$ = A_OAMF4; }
+ | CONNECTMSG { $$ = A_CONNECTMSG; }
+ | METACONNECT { $$ = A_METACONNECT; }
+ ;
+ /* ATM field types quantifier */
+atmfield: VPI { $$.atmfieldtype = A_VPI; }
+ | VCI { $$.atmfieldtype = A_VCI; }
+ ;
+atmvalue: atmfieldvalue
+ | relop NUM { $$.b = gen_atmfield_code($<blk>0.atmfieldtype, (u_int)$2, (u_int)$1, 0); }
+ | irelop NUM { $$.b = gen_atmfield_code($<blk>0.atmfieldtype, (u_int)$2, (u_int)$1, 1); }
+ | paren atmlistvalue ')' { $$.b = $2.b; $$.q = qerr; }
+ ;
+atmfieldvalue: NUM {
+ $$.atmfieldtype = $<blk>0.atmfieldtype;
+ if ($$.atmfieldtype == A_VPI ||
+ $$.atmfieldtype == A_VCI)
+ $$.b = gen_atmfield_code($$.atmfieldtype, (u_int) $1, BPF_JEQ, 0);
+ }
+ ;
+atmlistvalue: atmfieldvalue
+ | atmlistvalue or atmfieldvalue { gen_or($1.b, $3.b); $$ = $3; }
+ ;
%%
diff --git a/contrib/libpcap/nametoaddr.c b/contrib/libpcap/nametoaddr.c
index 3043a58..678163e 100644
--- a/contrib/libpcap/nametoaddr.c
+++ b/contrib/libpcap/nametoaddr.c
@@ -25,37 +25,51 @@
*/
#ifndef lint
-static const char rcsid[] =
- "@(#) $Header: /tcpdump/master/libpcap/nametoaddr.c,v 1.60 2001/07/28 22:56:35 guy Exp $ (LBL)";
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/libpcap/nametoaddr.c,v 1.68.2.3 2003/11/19 18:13:48 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
+#ifdef WIN32
+#include <pcap-stdinc.h>
+
+#else /* WIN32 */
+
#include <sys/param.h>
#include <sys/types.h> /* concession to AIX */
#include <sys/socket.h>
#include <sys/time.h>
-struct mbuf;
-struct rtentry;
-#include <net/if.h>
#include <netinet/in.h>
+#endif /* WIN32 */
+
+/*
+ * XXX - why was this included even on UNIX?
+ */
+#ifdef __MINGW32__
+#include "IP6_misc.h"
+#endif
+
+#ifndef WIN32
+#ifdef HAVE_ETHER_HOSTTON
#ifdef HAVE_NETINET_IF_ETHER_H
+struct mbuf; /* Squelch compiler warnings on some platforms for */
+struct rtentry; /* declarations in <net/if.h> */
+#include <net/if.h> /* for "struct ifnet" in "struct arpcom" on Solaris */
#include <netinet/if_ether.h>
-#endif
+#endif /* HAVE_NETINET_IF_ETHER_H */
+#endif /* HAVE_ETHER_HOSTTON */
#include <arpa/inet.h>
-#ifdef INET6
#include <netdb.h>
-#include <sys/socket.h>
-#endif /*INET6*/
+#endif /* WIN32 */
#include <ctype.h>
#include <errno.h>
#include <stdlib.h>
#include <memory.h>
-#include <netdb.h>
#include <stdio.h>
#include "pcap-int.h"
@@ -127,12 +141,19 @@ pcap_nametoaddrinfo(const char *name)
bpf_u_int32
pcap_nametonetaddr(const char *name)
{
+#ifndef WIN32
struct netent *np;
if ((np = getnetbyname(name)) != NULL)
return np->n_net;
else
return 0;
+#else
+ /*
+ * There's no "getnetbyname()" on Windows.
+ */
+ return 0;
+#endif
}
/*
@@ -144,38 +165,40 @@ 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);
+ int tcp_port = -1;
+ int udp_port = -1;
+
+ /*
+ * 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.
+ */
+ sp = getservbyname(name, "tcp");
+ if (sp != NULL) tcp_port = ntohs(sp->s_port);
+ sp = getservbyname(name, "udp");
+ if (sp != NULL) udp_port = ntohs(sp->s_port);
+ if (tcp_port >= 0) {
+ *port = tcp_port;
+ *proto = IPPROTO_TCP;
+ if (udp_port >= 0) {
+ if (udp_port == tcp_port)
+ *proto = PROTO_UNDEF;
#ifdef notdef
- if (*port != sp->s_port)
+ else
/* Can't handle ambiguous names that refer
to different port numbers. */
warning("ambiguous port %s in /etc/services",
name);
#endif
- *proto = PROTO_UNDEF;
}
return 1;
}
+ if (udp_port >= 0) {
+ *port = udp_port;
+ *proto = IPPROTO_UDP;
+ return 1;
+ }
#if defined(ultrix) || defined(__osf__)
/* Special hack in case NFS isn't in /etc/services */
if (strcmp(name, "nfs") == 0) {
@@ -353,7 +376,7 @@ pcap_ether_hostton(const char *name)
return (NULL);
else
rewind(fp);
-
+
while ((ep = pcap_next_etherent(fp)) != NULL) {
if (strcmp(ep->name, name) == 0) {
ap = (u_char *)malloc(6);
@@ -377,7 +400,8 @@ pcap_ether_hostton(const char *name)
* "const char *", so no matter how we declare it here, it'll fail to
* compile on one of 3.x or 4.x).
*/
-#if !defined(sgi) && !defined(__NetBSD__) && !defined(__FreeBSD__)
+#if !defined(sgi) && !defined(__NetBSD__) && !defined(__FreeBSD__) && \
+ !defined(_UNICOSMP)
extern int ether_hostton(char *, struct ether_addr *);
#endif
diff --git a/contrib/libpcap/nlpid.h b/contrib/libpcap/nlpid.h
index 907af29..7ea2963 100644
--- a/contrib/libpcap/nlpid.h
+++ b/contrib/libpcap/nlpid.h
@@ -16,7 +16,7 @@
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $FreeBSD$
- * @(#) $Header: /tcpdump/master/libpcap/nlpid.h,v 1.1 2000/10/28 09:30:22 guy Exp $ (Juniper)
+ * @(#) $Header: /tcpdump/master/libpcap/nlpid.h,v 1.2 2002/12/06 00:01:34 hannes Exp $ (Juniper)
*/
/* Types missing from some systems */
@@ -36,6 +36,21 @@
#ifndef ISO10589_ISIS
#define ISO10589_ISIS 0x83
#endif
+/*
+ * this does not really belong in the nlpid.h file
+ * however we need it for generating nice
+ * IS-IS related BPF filters
+ */
+#define ISIS_L1_LAN_IIH 15
+#define ISIS_L2_LAN_IIH 16
+#define ISIS_PTP_IIH 17
+#define ISIS_L1_LSP 18
+#define ISIS_L2_LSP 20
+#define ISIS_L1_CSNP 24
+#define ISIS_L2_CSNP 25
+#define ISIS_L1_PSNP 26
+#define ISIS_L2_PSNP 27
+
#ifndef ISO8878A_CONS
#define ISO8878A_CONS 0x84
#endif
diff --git a/contrib/libpcap/packaging/pcap.spec b/contrib/libpcap/packaging/pcap.spec
deleted file mode 100644
index e9ff7cf..0000000
--- a/contrib/libpcap/packaging/pcap.spec
+++ /dev/null
@@ -1,65 +0,0 @@
-%define prefix /usr
-%define version 0.8
-
-Summary: packet capture library
-Name: libpcap
-Version: %version
-Release: 1
-Group: Development/Libraries
-Copyright: BSD
-Source: libpcap-0.8.tar.gz
-BuildRoot: /tmp/%{name}-buildroot
-URL: http://www.tcpdump.org
-
-%description
-Packet-capture library LIBPCAP 0.8
-Now maintained by "The Tcpdump Group"
-See http://www.tcpdump.org
-Please send inquiries/comments/reports to tcpdump-workers@tcpdump.org
-
-%prep
-%setup
-
-%post
-ldconfig
-
-%build
-CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=%prefix
-make
-
-%install
-rm -rf $RPM_BUILD_ROOT
-mkdir -p $RPM_BUILD_ROOT/usr/{lib,include}
-mkdir -p $RPM_BUILD_ROOT/usr/share/man
-mkdir -p $RPM_BUILD_ROOT/usr/include/net
-mkdir -p $RPM_BUILD_ROOT/usr/man/man3
-make install DESTDIR=$RPM_BUILD_ROOT mandir=/usr/share/man
-cd $RPM_BUILD_ROOT/usr/lib
-V1=`echo 0.8 | sed 's/\\.[^\.]*$//g'`
-V2=`echo 0.8 | sed 's/\\.[^\.]*\.[^\.]*$//g'`
-ln -sf libpcap.so.0.8 libpcap.so.$V1
-if test "$V2" -ne "$V1"; then
- ln -sf libpcap.so.$V1 libpcap.so.$V2
- ln -sf libpcap.so.$V2 libpcap.so
-else
- ln -sf libpcap.so.$V1 libpcap.so
-fi
-
-#install -m 755 -o root libpcap.a $RPM_BUILD_ROOT/usr/lib
-#install -m 644 -o root pcap.3 $RPM_BUILD_ROOT/usr/man/man3
-#install -m 644 -o root pcap.h $RPM_BUILD_ROOT/usr/include
-#install -m 644 -o root pcap-bpf.h $RPM_BUILD_ROOT/usr/include/net
-#install -m 644 -o root pcap-namedb.h $RPM_BUILD_ROOT/usr/include
-
-%clean
-rm -rf $RPM_BUILD_ROOT
-
-%files
-%defattr(-,root,root)
-%doc LICENSE CHANGES INSTALL.txt README.linux TODO VERSION CREDITS packaging/pcap.spec
-/usr/lib/libpcap.a
-/usr/share/man/man3/*
-/usr/include/pcap.h
-/usr/include/pcap-bpf.h
-/usr/include/pcap-namedb.h
-/usr/lib/libpcap.so*
diff --git a/contrib/libpcap/pcap-int.h b/contrib/libpcap/pcap-int.h
index 7e54052..4a5a288 100644
--- a/contrib/libpcap/pcap-int.h
+++ b/contrib/libpcap/pcap-int.h
@@ -30,9 +30,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#) $Header: /tcpdump/master/libpcap/pcap-int.h,v 1.33 2001/08/24 07:46:52 guy Exp $ (LBL)
- *
* $FreeBSD$
+ * @(#) $Header: /tcpdump/master/libpcap/pcap-int.h,v 1.55.2.4 2003/12/15 01:42:24 guy Exp $ (LBL)
*/
#ifndef pcap_int_h
@@ -44,13 +43,24 @@ extern "C" {
#include <pcap.h>
+#ifdef WIN32
+#include <packet32.h>
+#endif /* WIN32 */
+
/*
* Savefile
*/
+typedef enum {
+ NOT_SWAPPED,
+ SWAPPED,
+ MAYBE_SWAPPED
+} swapped_type_t;
+
struct pcap_sf {
FILE *rfile;
int swapped;
int hdrsize;
+ swapped_type_t lengths_swapped;
int version_major;
int version_minor;
u_char *base;
@@ -71,18 +81,36 @@ struct pcap_md {
int clear_promisc; /* must clear promiscuous mode when we close */
int cooked; /* using SOCK_DGRAM rather than SOCK_RAW */
int lo_ifindex; /* interface index of the loopback device */
- char *device; /* device name */
+ char *device; /* device name */
struct pcap *next; /* list of open promiscuous sock_packet pcaps */
#endif
+
+#ifdef HAVE_DAG_API
+ void *dag_mem_base; /* DAG card memory base address */
+ u_int dag_mem_bottom; /* DAG card current memory bottom pointer */
+ u_int dag_mem_top; /* DAG card current memory top pointer */
+ int dag_fcs_bits; /* Number of checksum bits from link layer */
+ int dag_offset_flags; /* Flags to pass to dag_offset(). */
+#endif
};
struct pcap {
+#ifdef WIN32
+ ADAPTER *adapter;
+ LPPACKET Packet;
+ int timeout;
+ int nonblock;
+#else
int fd;
+ int selectable_fd;
+#endif /* WIN32 */
int snapshot;
int linktype;
int tzoff; /* timezone offset */
int offset; /* offset for proper alignment */
+ int break_loop; /* flag set to force break from packet-reading loop */
+
struct pcap_sf sf;
struct pcap_md md;
@@ -99,15 +127,27 @@ struct pcap {
*/
u_char *pkt;
-
+ /*
+ * Methods.
+ */
+ int (*read_op)(pcap_t *, int cnt, pcap_handler, u_char *);
+ int (*setfilter_op)(pcap_t *, struct bpf_program *);
+ int (*set_datalink_op)(pcap_t *, int);
+ int (*getnonblock_op)(pcap_t *, char *);
+ int (*setnonblock_op)(pcap_t *, int, char *);
+ int (*stats_op)(pcap_t *, struct pcap_stat *);
+ void (*close_op)(pcap_t *);
+
/*
* Placeholder for filter code if bpf not in kernel.
*/
struct bpf_program fcode;
- char errbuf[PCAP_ERRBUF_SIZE];
+ char errbuf[PCAP_ERRBUF_SIZE + 1];
int dlt_count;
int *dlt_list;
+
+ struct pcap_pkthdr pcap_header; /* This is needed for the pcap_next_ex() to work */
};
/*
@@ -182,6 +222,7 @@ int yylex(void);
int pcap_offline_read(pcap_t *, int, pcap_handler, u_char *);
int pcap_read(pcap_t *, int cnt, pcap_handler, u_char *);
+
/*
* Ultrix, DEC OSF/1^H^H^H^H^H^H^H^H^HDigital UNIX^H^H^H^H^H^H^H^H^H^H^H^H
* Tru64 UNIX, and NetBSD pad to make everything line up on a nice boundary.
@@ -197,8 +238,46 @@ int pcap_read(pcap_t *, int cnt, pcap_handler, u_char *);
strlen((y)))
#endif
-#ifdef linux
-void pcap_close_linux(pcap_t *);
+#include <stdarg.h>
+
+#if !defined(HAVE_SNPRINTF)
+#define snprintf pcap_snprintf
+extern int snprintf (char *, size_t, const char *, ...);
+#endif
+
+#if !defined(HAVE_VSNPRINTF)
+#define vsnprintf pcap_vsnprintf
+extern int vsnprintf (char *, size_t, const char *, va_list ap);
+#endif
+
+/*
+ * Routines that most pcap implementations can use for non-blocking mode.
+ */
+#ifndef WIN32
+int pcap_getnonblock_fd(pcap_t *, char *);
+int pcap_setnonblock_fd(pcap_t *p, int, char *);
+#endif
+
+/*
+ * Internal interfaces for "pcap_findalldevs()".
+ *
+ * "pcap_platform_finddevs()" is a platform-dependent routine to
+ * add devices not found by the "standard" mechanisms (SIOCGIFCONF,
+ * "getifaddrs()", etc..
+ *
+ * "pcap_add_if()" adds an interface to the list of interfaces.
+ */
+int pcap_platform_finddevs(pcap_if_t **, char *);
+int add_addr_to_iflist(pcap_if_t **, char *, u_int, struct sockaddr *,
+ size_t, struct sockaddr *, size_t, struct sockaddr *, size_t,
+ struct sockaddr *, size_t, char *);
+int pcap_add_if(pcap_if_t **, char *, u_int, const char *, char *);
+struct sockaddr *dup_sockaddr(struct sockaddr *, size_t);
+int add_or_find_if(pcap_if_t **, pcap_if_t **, const char *, u_int,
+ const char *, char *);
+
+#ifdef WIN32
+char *pcap_win32strerror(void);
#endif
/* XXX */
@@ -206,6 +285,8 @@ extern int pcap_fddipad;
int install_bpf_program(pcap_t *, struct bpf_program *);
+int pcap_strcasecmp(const char *, const char *);
+
#ifdef __cplusplus
}
#endif
diff --git a/contrib/libpcap/pcap.3 b/contrib/libpcap/pcap.3
index 9eb2627..807d1c7 100644
--- a/contrib/libpcap/pcap.3
+++ b/contrib/libpcap/pcap.3
@@ -1,4 +1,4 @@
-.\" @(#) $Header: /tcpdump/master/libpcap/pcap.3,v 1.31 2001/12/29 21:57:07 guy Exp $
+.\" @(#) $Header: /tcpdump/master/libpcap/pcap.3,v 1.51.2.9 2004/03/28 21:45:32 fenner Exp $
.\"
.\" Copyright (c) 1994, 1996, 1997
.\" The Regents of the University of California. All rights reserved.
@@ -21,7 +21,7 @@
.\"
.\" $FreeBSD$
.\"
-.TH PCAP 3 "3 January 2001"
+.TH PCAP 3 "27 February 2004"
.SH NAME
pcap \- Packet Capture library
.SH SYNOPSIS
@@ -36,12 +36,12 @@ char errbuf[PCAP_ERRBUF_SIZE];
.ft
.LP
.ft B
-pcap_t *pcap_open_live(char *device, int snaplen,
+pcap_t *pcap_open_live(const char *device, int snaplen,
.ti +8
int promisc, int to_ms, char *errbuf)
pcap_t *pcap_open_dead(int linktype, int snaplen)
-pcap_t *pcap_open_offline(char *fname, char *errbuf)
-pcap_dumper_t *pcap_dump_open(pcap_t *p, char *fname)
+pcap_t *pcap_open_offline(const char *fname, char *errbuf)
+pcap_dumper_t *pcap_dump_open(pcap_t *p, const char *fname)
.ft
.LP
.ft B
@@ -51,9 +51,9 @@ int pcap_getnonblock(pcap_t *p, char *errbuf);
.LP
.ft B
int pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
-void pcap_freealldevs(pcap_if_t *)
+void pcap_freealldevs(pcap_if_t *alldevs)
char *pcap_lookupdev(char *errbuf)
-int pcap_lookupnet(char *device, bpf_u_int32 *netp,
+int pcap_lookupnet(const char *device, bpf_u_int32 *netp,
.ti +8
bpf_u_int32 *maskp, char *errbuf)
.ft
@@ -79,13 +79,23 @@ void pcap_freecode(struct bpf_program *);
.ft
.LP
.ft B
-u_char *pcap_next(pcap_t *p, struct pcap_pkthdr *h)
+const u_char *pcap_next(pcap_t *p, struct pcap_pkthdr *h)
+int pcap_next_ex(pcap_t *p, struct pcap_pkthdr **pkt_header,
+.ti +8
+const u_char **pkt_data)
+.ft
+.LP
+.ft B
+void pcap_breakloop(pcap_t *)
.ft
.LP
.ft B
int pcap_datalink(pcap_t *p)
int pcap_list_datalinks(pcap_t *p, int **dlt_buf);
int pcap_set_datalink(pcap_t *p, int dlt);
+int pcap_datalink_name_to_val(const char *name);
+const char *pcap_datalink_val_to_name(int dlt);
+const char *pcap_datalink_val_to_description(int dlt);
int pcap_snapshot(pcap_t *p)
int pcap_is_swapped(pcap_t *p)
int pcap_major_version(pcap_t *p)
@@ -93,13 +103,17 @@ 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)
+int pcap_get_selectable_fd(pcap_t *p)
void pcap_perror(pcap_t *p, char *prefix)
char *pcap_geterr(pcap_t *p)
char *pcap_strerror(int error)
+const char *pcap_lib_version(void)
.ft
.LP
.ft B
void pcap_close(pcap_t *p)
+int pcap_dump_flush(pcap_dumper_t *p)
+FILE *pcap_dump_file(pcap_dumper_t *p)
void pcap_dump_close(pcap_dumper_t *p)
.ft
.fi
@@ -137,7 +151,12 @@ argument of "any" or
.B NULL
can be used to capture packets from all interfaces.
.I snaplen
-specifies the maximum number of bytes to capture.
+specifies the maximum number of bytes to capture. If this value is less
+than the size of a packet that is captured, only the first
+.I snaplen
+bytes of that packet will be captured and provided as packet data. A
+value of 65535 should be sufficient, on most if not all networks, to
+capture all the data available from the packet.
.I promisc
specifies if the interface is to be put into promiscuous mode.
(Note that even if this parameter is false, the interface
@@ -152,7 +171,11 @@ arrange that the read not necessarily return immediately when a packet
is seen, but that it wait for some amount of time to allow more packets
to arrive and to read multiple packets from the OS kernel in one
operation. Not all platforms support a read timeout; on platforms that
-don't, the read timeout is ignored.
+don't, the read timeout is ignored. A zero value for
+.IR to_ms ,
+on platforms that support a read timeout,
+will cause a read to wait forever to allow enough packets to
+arrive, with no timeout.
.I errbuf
is used to return error or warning text. It will be set to error text when
.B pcap_open_live()
@@ -333,6 +356,13 @@ to by
may be null if the interface isn't a point-to-point interface
.RE
.PP
+.B \-1
+is returned on failure, in which case
+.B errbuf
+is filled in with an appropriate error message;
+.B 0
+is returned on success.
+.PP
.B pcap_freealldevs()
is used to free a list allocated by
.BR pcap_findalldevs() .
@@ -381,12 +411,45 @@ 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),
+a
+.I const struct pcap_pkthdr
+pointer to a structure with the following members:
+.RS
+.TP
+.B ts
+a
+.I struct timeval
+containing the time when the packet was captured
+.TP
+.B caplen
+a
+.I bpf_u_int32
+giving the number of bytes of the packet that are available from the
+capture
+.TP
+.B len
+a
+.I bpf_u_int32
+giving the length of the packet, in bytes (which might be more than the
+number of bytes available from the capture, if the length of the packet
+is larger than the maximum number of bytes to capture)
+.RE
+.PP
and a
-.I u_char
-pointer to the packet data.
+.I const u_char
+pointer to the first
+.B caplen
+(as given in the
+.I struct pcap_pkthdr
+a pointer to which is passed to the callback routine)
+bytes of data from the packet (which won't necessarily be the entire
+packet; to capture the entire packet, you will have to provide a value
+for
+.I snaplen
+in your call to
+.B pcap_open_live()
+that is sufficiently large to get all of the packet's data - a value of
+65535 should be sufficient on most if not all networks).
.PP
The number of packets read is returned.
0 is returned if no packets were read from a live capture (if, for
@@ -401,6 +464,14 @@ an error in which case
or
.B pcap_geterr()
may be used to display the error text.
+A return of \-2 indicates that the loop terminated due to a call to
+.B pcap_breakloop()
+before any packets were processed.
+.ft B
+If your application uses pcap_breakloop(),
+make sure that you explicitly check for \-1 and \-2, rather than just
+checking for a return value < 0.
+.ft R
.PP
.BR NOTE :
when reading a live capture,
@@ -435,7 +506,17 @@ A negative
.I cnt
causes
.B pcap_loop()
-to loop forever (or at least until an error occurs).
+to loop forever (or at least until an error occurs). \-1 is returned on
+an error; 0 is returned if
+.I cnt
+is exhausted; \-2 is returned if the loop terminated due to a call to
+.B pcap_breakloop()
+before any packets were processed.
+.ft B
+If your application uses pcap_breakloop(),
+make sure that you explicitly check for \-1 and \-2, rather than just
+checking for a return value < 0.
+.ft R
.PP
.B pcap_next()
reads the next packet (by calling
@@ -447,6 +528,107 @@ of 1) and returns a
pointer to the data in that packet. (The
.I pcap_pkthdr
struct for that packet is not supplied.)
+.B NULL
+is returned if an error occured, or if no packets were read from a live
+capture (if, for example, they were discarded because they didn't pass
+the packet filter, or if, on platforms that support a read timeout that
+starts before any packets arrive, the timeout expires before any packets
+arrive, or if the file descriptor for the capture device is in
+non-blocking mode and no packets were available to be read), or if no
+more packets are available in a ``savefile.'' Unfortunately, there is
+no way to determine whether an error occured or not.
+.PP
+.B pcap_next_ex()
+reads the next packet and returns a success/failure indication:
+.RS
+.TP
+1
+the packet was read without problems
+.TP
+0
+packets are being read from a live capture, and the timeout expired
+.TP
+\-1
+an error occurred while reading the packet
+.TP
+\-2
+packets are being read from a ``savefile'', and there are no more
+packets to read from the savefile.
+.RE
+.PP
+If the packet was read without problems, the pointer pointed to by the
+.I pkt_header
+argument is set to point to the
+.I pcap_pkthdr
+struct for the packet, and the
+pointer pointed to by the
+.I pkt_data
+argument is set to point to the data in the packet.
+.PP
+.B pcap_breakloop()
+sets a flag that will force
+.B pcap_dispatch()
+or
+.B pcap_loop()
+to return rather than looping; they will return the number of packets
+that have been processed so far, or \-2 if no packets have been
+processed so far.
+.PP
+This routine is safe to use inside a signal handler on UNIX or a console
+control handler on Windows, as it merely sets a flag that is checked
+within the loop.
+.PP
+The flag is checked in loops reading packets from the OS - a signal by
+itself will not necessarily terminate those loops - as well as in loops
+processing a set of packets returned by the OS.
+.ft B
+Note that if you are catching signals on UNIX systems that support
+restarting system calls after a signal, and calling pcap_breakloop()
+in the signal handler, you must specify, when catching those signals,
+that system calls should NOT be restarted by that signal. Otherwise,
+if the signal interrupted a call reading packets in a live capture,
+when your signal handler returns after calling pcap_breakloop(), the
+call will be restarted, and the loop will not terminate until more
+packets arrive and the call completes.
+.PP
+Note also that, in a multi-threaded application, if one thread is
+blocked in
+.BR pcap_dispatch() ,
+.BR pcap_loop() ,
+.BR pcap_next() ,
+or
+.BR pcap_next_ex() ,
+a call to
+.B pcap_breakloop()
+in a different thread will not unblock that thread; you will need to use
+whatever mechanism the OS provides for breaking a thread out of blocking
+calls in order to unblock the thread, such as thread cancellation in
+systems that support POSIX threads.
+.ft R
+.PP
+Note that
+.B pcap_next()
+will, on some platforms, loop reading packets from the OS; that loop
+will not necessarily be terminated by a signal, so
+.B pcap_breakloop()
+should be used to terminate packet processing even if
+.B pcap_next()
+is being used.
+.PP
+.B pcap_breakloop()
+does not guarantee that no further packets will be processed by
+.B pcap_dispatch()
+or
+.B pcap_loop()
+after it is called; at most one more packet might be processed.
+.PP
+If \-2 is returned from
+.B pcap_dispatch()
+or
+.BR pcap_loop() ,
+the flag is cleared, so a subsequent call will resume reading packets.
+If a positive number is returned, the flag is not cleared, so a
+subsequent call will return \-2 and clear the flag.
.PP
.B pcap_dump()
outputs a packet to the ``savefile'' opened with
@@ -474,8 +656,14 @@ struct and is filled in by
.I optimize
controls whether optimization on the resulting code is performed.
.I netmask
-specifies the netmask of the local net.
-A return of \-1 indicates an error in which case
+specifies the IPv4 netmask of the network on which packets are being
+captured; it is used only when checking for IPv4 broadcast addresses in
+the filter program. If the netmask of the network on which packets are
+being captured isn't known to the program, or if packets are being
+captured on the Linux "any" pseudo-interface that can capture on more
+than one network, a value of 0 can be supplied; tests for IPv4 broadcast
+addreses won't be done correctly, but all other tests in the filter
+program will be OK. A return of \-1 indicates an error in which case
.BR pcap_geterr()
may be used to display the error text.
.PP
@@ -531,7 +719,7 @@ BSD loopback encapsulation; the link layer header is a 4-byte field, in
.I host
byte order, containing a PF_ value from
.B socket.h
-for the network-layer protocol of the packet
+for the network-layer protocol of the packet.
.IP
Note that ``host byte order'' is the byte order of the machine on which
the packets are captured, and the PF_ values are for the OS of the
@@ -581,45 +769,48 @@ COMPRESSED_TCP, the compressed TCP/IP datagram header;
.RE
.RS 5
.LP
-for a total of 16 bytes; the uncompressed IP datagram follows the header
+for a total of 16 bytes; the uncompressed IP datagram follows the header.
.RE
.TP 5
.B DLT_PPP
PPP; if the first 2 bytes are 0xff and 0x03, it's PPP in HDLC-like
framing, with the PPP header following those two bytes, otherwise it's
-PPP without framing, and the packet begins with the PPP header
+PPP without framing, and the packet begins with the PPP header.
.TP 5
.B DLT_FDDI
FDDI
.TP 5
.B DLT_ATM_RFC1483
RFC 1483 LLC/SNAP-encapsulated ATM; the packet begins with an IEEE 802.2
-LLC header
+LLC header.
.TP 5
.B DLT_RAW
-raw IP; the packet begins with an IP header
+raw IP; the packet begins with an IP header.
.TP 5
.B DLT_PPP_SERIAL
PPP in HDLC-like framing, as per RFC 1662, or Cisco PPP with HDLC
framing, as per section 4.3.1 of RFC 1547; the first byte will be 0xFF
for PPP in HDLC-like framing, and will be 0x0F or 0x8F for Cisco PPP
-with HDLC framing
+with HDLC framing.
.TP 5
.B DLT_PPP_ETHER
-PPPoE; the packet begins with a PPPoE header, as per RFC 2516
+PPPoE; the packet begins with a PPPoE header, as per RFC 2516.
.TP 5
.B DLT_C_HDLC
-Cisco PPP with HDLC framing, as per section 4.3.1 of RFC 1547
+Cisco PPP with HDLC framing, as per section 4.3.1 of RFC 1547.
.TP 5
.B DLT_IEEE802_11
IEEE 802.11 wireless LAN
.TP 5
+.B DLT_FRELAY
+Frame Relay
+.TP 5
.B DLT_LOOP
OpenBSD loopback encapsulation; the link layer header is a 4-byte field, in
.I network
byte order, containing a PF_ value from OpenBSD's
.B socket.h
-for the network-layer protocol of the packet
+for the network-layer protocol of the packet.
.IP
Note that, if a ``savefile'' is being read, those PF_ values are
.I not
@@ -664,8 +855,168 @@ header or 4 for frames beginning with an 802.2 LLC header.
.RE
.TP 5
.B DLT_LTALK
-Apple LocalTalk; the packet begins with an AppleTalk LLAP header
+Apple LocalTalk; the packet begins with an AppleTalk LLAP header.
+.TP 5
+.B DLT_PFLOG
+OpenBSD pflog; the link layer header contains, in order:
+.RS 10
+.LP
+a 1-byte header length, in host byte order;
+.LP
+a 4-byte PF_ value, in host byte order;
+.LP
+a 2-byte action code, in network byte order, which is one of:
+.RS 5
+.TP 5
+0
+passed
+.TP 5
+1
+dropped
+.TP 5
+2
+scrubbed
.RE
+.LP
+a 2-byte reason code, in network byte order, which is one of:
+.RS 5
+.TP 5
+0
+match
+.TP 5
+1
+bad offset
+.TP 5
+2
+fragment
+.TP 5
+3
+short
+.TP 5
+4
+normalize
+.TP 5
+5
+memory
+.RE
+.LP
+a 16-character interface name;
+.LP
+a 16-character ruleset name (only meaningful if subrule is set);
+.LP
+a 4-byte rule number, in network byte order;
+.LP
+a 4-byte subrule number, in network byte order;
+.LP
+a 1-byte direction, in network byte order, which is one of:
+.RS 5
+.TP 5
+0
+incoming or outgoing
+.TP 5
+1
+incoming
+.TP 5
+2
+outgoing
+.RE
+.RE
+.TP 5
+.B DLT_PRISM_HEADER
+Prism monitor mode information followed by an 802.11 header.
+.TP 5
+.B DLT_IP_OVER_FC
+RFC 2625 IP-over-Fibre Channel, with the link-layer header being the
+Network_Header as described in that RFC.
+.TP 5
+.B DLT_SUNATM
+SunATM devices; the link layer header contains, in order:
+.RS 10
+.LP
+a 1-byte flag field, containing a direction flag in the uppermost bit,
+which is set for packets transmitted by the machine and clear for
+packets received by the machine, and a 4-byte traffic type in the
+low-order 4 bits, which is one of:
+.RS 5
+.TP 5
+0
+raw traffic
+.TP 5
+1
+LANE traffic
+.TP 5
+2
+LLC-encapsulated traffic
+.TP 5
+3
+MARS traffic
+.TP 5
+4
+IFMP traffic
+.TP 5
+5
+ILMI traffic
+.TP 5
+6
+Q.2931 traffic
+.RE
+.LP
+a 1-byte VPI value;
+.LP
+a 2-byte VCI field, in network byte order.
+.RE
+.TP 5
+.B DLT_IEEE802_11_RADIO
+link-layer information followed by an 802.11 header - see
+http://www.shaftnet.org/~pizza/software/capturefrm.txt for a description
+of the link-layer information.
+.TP 5
+.B DLT_ARCNET_LINUX
+ARCNET, with no exception frames, reassembled packets rather than raw
+frames, and an extra 16-bit offset field between the destination host
+and type bytes.
+.TP 5
+.B DLT_LINUX_IRDA
+Linux-IrDA packets, with a
+.B DLT_LINUX_SLL
+header followed by the IrLAP header.
+.RE
+.PP
+.B pcap_list_datalinks()
+is used to get a list of the supported data link types of the interface
+associated with the pcap descriptor.
+.B pcap_list_datalinks()
+allocates an array to hold the list and sets
+.IR *dlt_buf .
+The caller is responsible for freeing the array.
+.B \-1
+is returned on failure;
+otherwise, the number of data link types in the array is returned.
+.PP
+.B pcap_set_datalink()
+is used to set the current data link type of the pcap descriptor
+to the type specified by
+.IR dlt .
+.B \-1
+is returned on failure.
+.PP
+.B pcap_datalink_name_to_val()
+translates a data link type name, which is a
+.B DLT_
+name with the
+.B DLT_
+removed, to the corresponding data link type value. The translation
+is case-insensitive.
+.B \-1
+is returned on failure.
+.PP
+.B pcap_datalink_val_to_name()
+translates a data link type value to the corresponding data link type
+name. NULL is returned on failure.
+.PP
+.B pcap_datalink_val_to_description()
+translates a data link type value to a short description of that data
+link type. NULL is returned on failure.
.PP
.B pcap_list_datalinks()
is used to get a list of the supported data link types of the interface
@@ -687,7 +1038,7 @@ is returned on failure.
.PP
.B pcap_snapshot()
returns the snapshot length specified when
-.B pcap_open_live
+.B pcap_open_live()
was called.
.PP
.B pcap_is_swapped()
@@ -695,12 +1046,10 @@ 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
+returns the major number of the file format of the savefile;
.B pcap_minor_version()
-returns the minor number of the version of the pcap used to write the
-savefile.
+returns the minor number of the file format of the savefile. The
+version number is stored in the header of the savefile.
.PP
.B pcap_file()
returns the standard I/O stream of the ``savefile,'' if a ``savefile''
@@ -731,6 +1080,67 @@ if a network device was opened with
or \-1, if a ``savefile'' was opened with
.BR pcap_open_offline() .
.PP
+.B pcap_get_selectable_fd()
+returns, on UNIX, a file descriptor number for a file descriptor on
+which one can
+do a
+.B select()
+or
+.B poll()
+to wait for it to be possible to read packets without blocking, if such
+a descriptor exists, or \-1, if no such descriptor exists. Some network
+devices opened with
+.B pcap_open_live()
+do not support
+.B select()
+or
+.B poll()
+(for example, regular network devices on FreeBSD 4.3 and 4.4, and Endace
+DAG devices), so \-1 is returned for those devices.
+.PP
+Note that on most versions of most BSDs (including Mac OS X)
+.B select()
+and
+.B poll()
+do not work correctly on BPF devices;
+.B pcap_get_selectable_fd()
+will return a file descriptor on most of those versions (the exceptions
+being FreeBSD 4.3 and 4.4), a simple
+.B select()
+or
+.B poll()
+will not return even after a timeout specified in
+.B pcap_open_live()
+expires. To work around this, an application that uses
+.B select()
+or
+.B poll()
+to wait for packets to arrive must put the
+.B pcap_t
+in non-blocking mode, and must arrange that the
+.B select()
+or
+.B poll()
+have a timeout less than or equal to the timeout specified in
+.BR pcap_open_live() ,
+and must try to read packets after that timeout expires, regardless of
+whether
+.B select()
+or
+.B poll()
+indicated that the file descriptor for the
+.B pcap_t
+is ready to be read or not. (That workaround will not work in FreeBSD
+4.3 and later; however, in FreeBSD 4.6 and later,
+.B select()
+and
+.B poll()
+work correctly on BPF devices, so the workaround isn't necessary,
+although it does no harm.)
+.PP
+.B pcap_get_selectable_fd()
+is not available on Windows.
+.PP
.B pcap_perror()
prints the text of the last pcap library error on
.BR stderr ,
@@ -752,11 +1162,28 @@ is provided in case
.BR strerror (1)
isn't available.
.PP
+.B pcap_lib_version()
+returns a pointer to a string giving information about the version of
+the libpcap library being used; note that it contains more information
+than just a version number.
+.PP
.B pcap_close()
closes the files associated with
.I p
and deallocates resources.
.PP
+.B pcap_dump_file()
+returns the standard I/O stream of the ``savefile'' opened by
+.BR pcap_dump_open().
+.PP
+.B pcap_dump_flush()
+flushes the output buffer to the ``savefile,'' so that any packets
+written with
+.B pcap_dump()
+but not yet written to the ``savefile'' will be written.
+.B \-1
+is returned on error, 0 on success.
+.PP
.B pcap_dump_close()
closes the ``savefile.''
.PP
diff --git a/contrib/libpcap/pcap.h b/contrib/libpcap/pcap.h
index aeaae49..ea2c4e9 100644
--- a/contrib/libpcap/pcap.h
+++ b/contrib/libpcap/pcap.h
@@ -31,18 +31,23 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#) $Header: /tcpdump/master/libpcap/pcap.h,v 1.34 2001/12/09 05:10:03 guy Exp $ (LBL)
- *
* $FreeBSD$
+ * @(#) $Header: /tcpdump/master/libpcap/pcap.h,v 1.45.2.4 2004/01/27 22:56:20 guy Exp $ (LBL)
*/
#ifndef lib_pcap_h
#define lib_pcap_h
+#ifdef WIN32
+#include <pcap-stdinc.h>
+#else /* WIN32 */
#include <sys/types.h>
#include <sys/time.h>
+#endif /* WIN32 */
-#include <net/bpf.h>
+#ifndef PCAP_DONT_INCLUDE_PCAP_BPF_H
+#include <pcap-bpf.h>
+#endif
#include <stdio.h>
@@ -131,6 +136,9 @@ 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 */
+#ifdef WIN32
+ u_int bs_capt; /* number of packets that reach the application */
+#endif /* WIN32 */
};
/*
@@ -141,7 +149,7 @@ struct pcap_if {
char *name; /* name to hand to "pcap_open_live()" */
char *description; /* textual description of interface, or NULL */
struct pcap_addr *addresses;
- u_int flags; /* PCAP_IF_ interface flags */
+ bpf_u_int32 flags; /* PCAP_IF_ interface flags */
};
#define PCAP_IF_LOOPBACK 0x00000001 /* interface is loopback */
@@ -161,8 +169,8 @@ typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *,
const u_char *);
char *pcap_lookupdev(char *);
-int pcap_lookupnet(char *, bpf_u_int32 *, bpf_u_int32 *, char *);
-pcap_t *pcap_open_live(char *, int, int, int, char *);
+int pcap_lookupnet(const char *, bpf_u_int32 *, bpf_u_int32 *, char *);
+pcap_t *pcap_open_live(const char *, int, int, int, char *);
pcap_t *pcap_open_dead(int, int);
pcap_t *pcap_open_offline(const char *, char *);
void pcap_close(pcap_t *);
@@ -170,6 +178,8 @@ 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_next_ex(pcap_t *, struct pcap_pkthdr **, const u_char **);
+void pcap_breakloop(pcap_t *);
int pcap_stats(pcap_t *, struct pcap_stat *);
int pcap_setfilter(pcap_t *, struct bpf_program *);
int pcap_getnonblock(pcap_t *, char *);
@@ -185,6 +195,9 @@ void pcap_freecode(struct bpf_program *);
int pcap_datalink(pcap_t *);
int pcap_list_datalinks(pcap_t *, int **);
int pcap_set_datalink(pcap_t *, int);
+int pcap_datalink_name_to_val(const char *);
+const char *pcap_datalink_val_to_name(int);
+const char *pcap_datalink_val_to_description(int);
int pcap_snapshot(pcap_t *);
int pcap_is_swapped(pcap_t *);
int pcap_major_version(pcap_t *);
@@ -195,18 +208,50 @@ FILE *pcap_file(pcap_t *);
int pcap_fileno(pcap_t *);
pcap_dumper_t *pcap_dump_open(pcap_t *, const char *);
+int pcap_dump_flush(pcap_dumper_t *);
void pcap_dump_close(pcap_dumper_t *);
void pcap_dump(u_char *, const struct pcap_pkthdr *, const u_char *);
+FILE *pcap_dump_file(pcap_dumper_t *);
int pcap_findalldevs(pcap_if_t **, char *);
void pcap_freealldevs(pcap_if_t *);
+const char *pcap_lib_version(void);
+
/* XXX this guy lives in the bpf tree */
u_int bpf_filter(struct bpf_insn *, u_char *, u_int, u_int);
int bpf_validate(struct bpf_insn *f, int len);
char *bpf_image(struct bpf_insn *, int);
void bpf_dump(struct bpf_program *, int);
+#ifdef WIN32
+/*
+ * Win32 definitions
+ */
+
+int pcap_setbuff(pcap_t *p, int dim);
+int pcap_setmode(pcap_t *p, int mode);
+int pcap_sendpacket(pcap_t *p, u_char *buf, int size);
+int pcap_setmintocopy(pcap_t *p, int size);
+
+#ifdef WPCAP
+/* Include file with the wpcap-specific extensions */
+#include <Win32-Extensions.h>
+#endif
+
+#define MODE_CAPT 0
+#define MODE_STAT 1
+#define MODE_MON 2
+
+#else
+/*
+ * UN*X definitions
+ */
+
+int pcap_get_selectable_fd(pcap_t *);
+
+#endif /* WIN32 */
+
#ifdef __cplusplus
}
#endif
diff --git a/contrib/libpcap/scanner.l b/contrib/libpcap/scanner.l
index e680163..21e8002 100644
--- a/contrib/libpcap/scanner.l
+++ b/contrib/libpcap/scanner.l
@@ -23,33 +23,38 @@
*/
#ifndef lint
-static const char rcsid[] =
- "@(#) $Header: /tcpdump/master/libpcap/scanner.l,v 1.81 2001/09/14 01:40:57 fenner Exp $ (LBL)";
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/libpcap/scanner.l,v 1.95.2.3 2004/03/28 21:45:33 fenner Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
-#include <sys/types.h>
-#include <sys/time.h>
-
#include <ctype.h>
-#include <unistd.h>
#include <string.h>
#include "pcap-int.h"
#include "gencode.h"
-#include <pcap-namedb.h>
#ifdef INET6
-#include <netdb.h>
-#include <sys/socket.h>
+#ifdef WIN32
+#include <pcap-stdinc.h>
+
+#ifdef __MINGW32__
+#include "IP6_misc.h"
+#endif
+#else /* WIN32 */
+#include <sys/socket.h> /* for "struct sockaddr" in "struct addrinfo" */
+#include <netdb.h> /* for "struct addrinfo" */
+#endif /* WIN32 */
+
/* Workaround for AIX 4.3 */
#if !defined(AI_NUMERICHOST)
#define AI_NUMERICHOST 0x04
#endif
#endif /*INET6*/
+#include <pcap-namedb.h>
#include "tokdefs.h"
#ifdef HAVE_OS_PROTO_H
@@ -77,11 +82,11 @@ N ([0-9]+|(0X|0x)[0-9A-Fa-f]+)
B ([0-9A-Fa-f][0-9A-Fa-f]?)
W ([0-9A-Fa-f][0-9A-Fa-f]?[0-9A-Fa-f]?[0-9A-Fa-f]?)
-%a 15000
-%o 17000
+%a 16000
+%o 19000
%e 6000
%k 4000
-%p 19000
+%p 25000
%n 2000
V680 {W}:{W}:{W}:{W}:{W}:{W}:{W}:{W}
@@ -167,7 +172,7 @@ dst return DST;
src return SRC;
link|ether|ppp|slip return LINK;
-fddi|tr return LINK;
+fddi|tr|wlan return LINK;
arp return ARP;
rarp return RARP;
ip return IP;
@@ -210,6 +215,14 @@ esis return ESIS;
es-is return ESIS;
isis return ISIS;
is-is return ISIS;
+l1 return L1;
+l2 return L2;
+iih return IIH;
+lsp return LSP;
+snp return SNP;
+csnp return CSNP;
+psnp return PSNP;
+
clnp return CLNP;
stp return STP;
@@ -220,7 +233,7 @@ netbeui return NETBEUI;
host return HOST;
net return NET;
-mask return MASK;
+mask return NETMASK;
port return PORT;
proto return PROTO;
protochain {
@@ -235,7 +248,7 @@ gateway return GATEWAY;
less return LESS;
greater return GREATER;
-byte return BYTE;
+byte return CBYTE;
broadcast return TK_BROADCAST;
multicast return TK_MULTICAST;
@@ -249,7 +262,29 @@ outbound return OUTBOUND;
vlan return VLAN;
-[ \n\t] ;
+lane return LANE;
+llc return LLC;
+metac return METAC;
+bcc return BCC;
+oam return OAM;
+oamf4 return OAMF4;
+oamf4ec return OAMF4EC;
+oamf4sc return OAMF4SC;
+sc return SC;
+ilmic return ILMIC;
+vpi return VPI;
+vci return VCI;
+connectmsg return CONNECTMSG;
+metaconnect return METACONNECT;
+
+on|ifname return PF_IFNAME;
+rset|ruleset return PF_RSET;
+rnr|rulenum return PF_RNR;
+srnr|subrulenum return PF_SRNR;
+reason return PF_REASON;
+action return PF_ACTION;
+
+[ \r\n\t] ;
[+\-*/:\[\]!<>()&|=] return yytext[0];
">=" return GEQ;
"<=" return LEQ;
@@ -273,7 +308,7 @@ ${B} { yylval.e = pcap_ether_aton(((char *)yytext)+1);
if (getaddrinfo(yytext, NULL, &hints, &res))
bpf_error("bogus IPv6 address %s", yytext);
else {
- yylval.e = sdup((char *)yytext); return HID6;
+ yylval.s = sdup((char *)yytext); return HID6;
}
#else
bpf_error("IPv6 address %s not supported", yytext);
OpenPOWER on IntegriCloud