diff options
author | mlaier <mlaier@FreeBSD.org> | 2007-10-16 02:07:55 +0000 |
---|---|---|
committer | mlaier <mlaier@FreeBSD.org> | 2007-10-16 02:07:55 +0000 |
commit | 298dfd4f7489b7259511f0c690a5b04de77b0f77 (patch) | |
tree | 03bad2e07204c8bfa6cd8122c786eb4c73a5cdc9 /contrib/libpcap | |
parent | 55470a45cf732a145a7cfbf802f951a937eadee2 (diff) | |
download | FreeBSD-src-298dfd4f7489b7259511f0c690a5b04de77b0f77.zip FreeBSD-src-298dfd4f7489b7259511f0c690a5b04de77b0f77.tar.gz |
Resolve merge conflicts
Approved by: re (kensmith)
Obtained from: tcpdump.org
Diffstat (limited to 'contrib/libpcap')
-rw-r--r-- | contrib/libpcap/INSTALL | 342 | ||||
-rw-r--r-- | contrib/libpcap/gencode.c | 1163 | ||||
-rw-r--r-- | contrib/libpcap/gencode.h | 20 | ||||
-rw-r--r-- | contrib/libpcap/grammar.y | 90 | ||||
-rw-r--r-- | contrib/libpcap/lbl/gnuc.h | 43 | ||||
-rw-r--r-- | contrib/libpcap/nametoaddr.c | 8 | ||||
-rw-r--r-- | contrib/libpcap/pcap-bpf.c | 13 | ||||
-rw-r--r-- | contrib/libpcap/pcap-int.h | 37 | ||||
-rw-r--r-- | contrib/libpcap/pcap.3 | 22 | ||||
-rw-r--r-- | contrib/libpcap/pcap.h | 25 | ||||
-rw-r--r-- | contrib/libpcap/pf.h | 77 | ||||
-rw-r--r-- | contrib/libpcap/scanner.l | 18 |
12 files changed, 965 insertions, 893 deletions
diff --git a/contrib/libpcap/INSTALL b/contrib/libpcap/INSTALL deleted file mode 100644 index e8d8d96..0000000 --- a/contrib/libpcap/INSTALL +++ /dev/null @@ -1,342 +0,0 @@ -@(#) $Header: /tcpdump/master/libpcap/INSTALL,v 1.46 2000/12/16 09:05:11 guy Exp $ (LBL) - -To build libpcap, run "./configure" (a shell script). The configure -script will determine your system attributes and generate an -appropriate Makefile from Makefile.in. Next run "make". If everything -goes well you can su to root and run "make install". However, you need -not install libpcap if you just want to build tcpdump; just make sure -the tcpdump and libpcap directory trees have the same parent -directory. - -If configure says: - - configure: warning: cannot determine packet capture interface - configure: warning: (see INSTALL for more info) - -then your system either does not support packet capture or your system -does support packet capture but libpcap does not support that -particular type. (If you have HP-UX, see below.) If your system uses a -packet capture not supported by libpcap, please send us patches; don't -forget to include an autoconf fragment suitable for use in -configure.in. - -It is possible to override the default packet capture type, although -the circumstance where this works are limited. For example if you have -installed bpf under SunOS 4 and wish to build a snit libpcap: - - ./configure --with-pcap=snit - -Another example is to force a supported packet capture type in the case -where the configure scripts fails to detect it. - -You will need an ANSI C compiler to build libpcap. The configure script -will abort if your compiler is not ANSI compliant. If this happens, use -the GNU C compiler, available via anonymous ftp: - - ftp://ftp.gnu.org/pub/gnu/gcc/ - -If you use flex, you must use version 2.4.6 or higher. The configure -script automatically detects the version of flex and will not use it -unless it is new enough. You can use "flex -V" to see what version you -have (unless it's really old). The current version of flex is available -via anonymous ftp: - - ftp://ftp.ee.lbl.gov/flex-*.tar.Z - -As of this writing, the current version is 2.5.4. - -If you use bison, you must use flex (and visa versa). The configure -script automatically falls back to lex and yacc if both flex and bison -are not found. - -Sometimes the stock C compiler does not interact well with flex and -bison. The list of problems includes undefined references for alloca. -You can get around this by installing gcc or manually disabling flex -and bison with: - - ./configure --without-flex --without-bison - -If your system only has AT&T lex, this is okay unless your libpcap -program uses other lex/yacc generated code. (Although it's possible to -map the yy* identifiers with a script, we use flex and bison so we -don't feel this is necessary.) - -Some systems support the Berkeley Packet Filter natively; for example -out of the box OSF and BSD/OS have bpf. If your system does not support -bpf, you will need to pick up: - - ftp://ftp.ee.lbl.gov/bpf-*.tar.Z - -Note well: you MUST have kernel source for your operating system in -order to install bpf. An exception is SunOS 4; the bpf distribution -includes replacement kernel objects for some of the standard SunOS 4 -network device drivers. See the bpf INSTALL document for more -information. - -If you use Solaris, there is a bug with bufmod(7) that is fixed in -Solaris 2.3.2 (aka SunOS 5.3.2). Setting a snapshot length with the -broken bufmod(7) results in data be truncated from the FRONT of the -packet instead of the end. The work around is to not set a snapshot -length but this results in performance problems since the entire packet -is copied to user space. If you must run an older version of Solaris, -there is a patch available from Sun; ask for bugid 1149065. After -installing the patch, use "setenv BUFMOD_FIXED" to enable use of -bufmod(7). However, we recommend you run a more current release of -Solaris. - -If you use the SPARCompiler, you must be careful to not use the -/usr/ucb/cc interface. If you do, you will get bogus warnings and -perhaps errors. Either make sure your path has /opt/SUNWspro/bin -before /usr/ucb or else: - - setenv CC /opt/SUNWspro/bin/cc - -before running configure. (You might have to do a "make distclean" -if you already ran configure once). - -Also note that "make depend" won't work; while all of the known -universe uses -M, the SPARCompiler uses -xM to generate makefile -dependencies. - -If you are trying to do packet capture with a FORE ATM card, you may or -may not be able to. They usually only release their driver in object -code so unless their driver supports packet capture, there's not much -libpcap can do. - -If you get an error like: - - tcpdump: recv_ack: bind error 0x??? - -when using DLPI, look for the DL_ERROR_ACK error return values, usually -in /usr/include/sys/dlpi.h, and find the corresponding value. - -Under {DEC OSF/1, Digital UNIX, Tru64 UNIX}, packet capture must be -enabled before it can be used. For instructions on how to enable packet -filter support, see: - - ftp://ftp.digital.com/pub/Digital/dec-faq/Digital-UNIX - -Look for the "How do I configure the Berkeley Packet Filter and capture -tcpdump traces?" item. - -Once you enable packet filter support, your OSF system will support bpf -natively. - -Under Ultrix, packet capture must be enabled before it can be used. For -instructions on how to enable packet filter support, see: - - ftp://ftp.digital.com/pub/Digital/dec-faq/ultrix - -If you use HP-UX, you must have at least version 9 and either the -version of cc that supports ANSI C (cc -Aa) or else use the GNU C -compiler. You must also buy the optional streams package. If you don't -have: - - /usr/include/sys/dlpi.h - /usr/include/sys/dlpi_ext.h - -then you don't have the streams package. In addition, we believe you -need to install the "9.X LAN and DLPI drivers cumulative" patch -(PHNE_6855) to make the version 9 DLPI work with libpcap. - -The DLPI streams package is standard starting with HP-UX 10. - -The HP implementation of DLPI is a little bit eccentric. Unlike -Solaris, you must attach /dev/dlpi instead of the specific /dev/* -network pseudo device entry in order to capture packets. The PPA is -based on the ifnet "index" number. Under HP-UX 9, it is necessary to -read /dev/kmem and the kernel symbol file (/hp-ux). Under HP-UX 10, -DLPI can provide information for determining the PPA. It does not seem -to be possible to trace the loopback interface. Unlike other DLPI -implementations, PHYS implies MULTI and SAP and you get an error if you -try to enable more than one promiscuous mode at a time. - -It is impossible to capture outbound packets on HP-UX 9. To do so on -HP-UX 10, you will, apparently, need a late "LAN products cumulative -patch" (at one point, it was claimed that this would be PHNE_18173 for -s700/10.20; at another point, it was claimed that the required patches -were PHNE_20892, PHNE_20725 and PHCO_10947, or newer patches), and to do -so on HP-UX 11 you will, apparently, need the latest lancommon/DLPI -patches and the latest driver patch for the interface(s) in use on HP-UX -11 (at one point, it was claimed that patches PHNE_19766, PHNE_19826, -PHNE_20008, and PHNE_20735 did the trick). - -Furthermore, on HP-UX 10, you will need to turn on a kernel switch by -doing - - echo 'lanc_outbound_promisc_flag/W 1' | adb -w /stand/vmunix /dev/mem - -You would have to arrange that this happen on reboots; the right way to -do that would probably be to put it into an executable script file -"/sbin/init.d/outbound_promisc" and making -"/sbin/rc2.d/S350outbound_promisc" a symbolic link to that script. - -Finally, testing shows that there can't be more than one simultaneous -DLPI user per network interface. - -If you use Linux, this version of libpcap is known to compile and run -under Red Hat 4.0 with the 2.0.25 kernel. It may work with earlier 2.X -versions but is guaranteed not to work with 1.X kernels. Running more -than one libpcap program at a time, on a system with a 2.0.X kernel, can -cause problems since promiscuous mode is implemented by twiddling the -interface flags from the libpcap application; the packet capture -mechanism in the 2.2 and later kernels doesn't have this problem. Also, -packet timestamps aren't very good. This appears to be due to haphazard -handling of the timestamp in the kernel. - -Note well: there is rumoured to be a version of tcpdump floating around -called 3.0.3 that includes libpcap and is supposed to support Linux. -You should be advised that neither the Network Research Group at LBNL -nor the Tcpdump Group ever generated a release with this version number. -The LBNL Network Research Group notes with interest that a standard -cracker trick to get people to install trojans is to distribute bogus -packages that have a version number higher than the current release. -They also noted with annoyance that 90% of the Linux related bug reports -they got are due to changes made to unofficial versions of their page. -If you are having trouble but aren't using a version that came from -tcpdump.org, please try that before submitting a bug report! - -On Linux, libpcap will not work if the kernel does not have the packet -socket option enabled; see the README.linux file for information about -this. - -If you use AIX, you may not be able to build libpcap from this release. -libpcap. We do not have an AIX system in house so it's impossible for -us to test AIX patches submitted to us. We are told that you must link -against /lib/pse.exp, that you must use AIX cc or a GNU C compiler -newer than 2.7.2 and that you may need to run strload before running a -libpcap application. - -Read the README.aix file for information on installing libpcap and -configuring your system to be able to support libpcap. - -If you use NeXTSTEP, you will not be able to build libpcap from this -release. We hope to support this operating system in some future -release of libpcap. - -If you use SINIX, you should be able to build libpcap from this -release. It is known to compile and run on SINIX-Y/N 5.42 with the C-DS -V1.0 or V1.1 compiler. But note that in some releases of SINIX, yacc -emits incorrect code; if grammar.y fails to compile, change every -occurence of: - - #ifdef YYDEBUG - -to: - #if YYDEBUG - -Another workaround is to use flex and bison. - -If you use SCO, you might have trouble building libpcap from this -release. We do not have a machine running SCO and have not had reports -of anyone successfully building on it. Since SCO apparently supports -DLPI, it's possible the current version works. Meanwhile, SCO provides -a tcpdump binary as part of their "Network/Security Tools" package: - - http://www.sco.com/technology/internet/goodies/#SECURITY - -There is also a README that explains how to enable packet capture. - -If you use UnixWare, you will not be able to build libpcap from this -release. We hope to support this operating system in some future -release of libpcap. Meanwhile, there appears to be an UnixWare port of -libpcap 0.0 (and tcpdump 3.0) in: - - ftp://ftp1.freebird.org/pub/mirror/freebird/internet/systools/ - -UnixWare appears to use a hacked version of DLPI. - -If linking tcpdump fails with "Undefined: _alloca" when using bison on -a Sun4, your version of bison is broken. In any case version 1.16 or -higher is recommended (1.14 is known to cause problems 1.16 is known to -work). Either pick up a current version from: - - ftp://ftp.gnu.org/pub/gnu/bison - -or hack around it by inserting the lines: - - #ifdef __GNUC__ - #define alloca __builtin_alloca - #else - #ifdef sparc - #include <alloca.h> - #else - char *alloca (); - #endif - #endif - -right after the (100 line!) GNU license comment in bison.simple, remove -grammar.[co] and fire up make again. - -If you use SunOS 4, your kernel must support streams NIT. If you run a -libpcap program and it dies with: - - /dev/nit: No such device - -You must add streams NIT support to your kernel configuration, run -config and boot the new kernel. - -If you are running a version of SunOS earlier than 4.1, you will need -to replace the Sun supplied /sys/sun{3,4,4c}/OBJ/nit_if.o with the -appropriate version from this distribution's SUNOS4 subdirectory and -build a new kernel: - - nit_if.o.sun3-sunos4 (any flavor of sun3) - nit_if.o.sun4c-sunos4.0.3c (SS1, SS1+, IPC, SLC, etc.) - nit_if.o.sun4-sunos4 (Sun4's not covered by - nit_if.o.sun4c-sunos4.0.3c) - -These nit replacements fix a bug that makes nit essentially unusable in -pre-SunOS 4.1. In addition, our sun4c-sunos4.0.3c nit gives you -timestamps to the resolution of the SS-1 clock (1 us) rather than the -lousy 20ms timestamps Sun gives you (tcpdump will print out the full -timestamp resolution if it finds it's running on a SS-1). - -FILES ------ -CHANGES - description of differences between releases -FILES - list of files exported as part of the distribution -INSTALL - this file -Makefile.in - compilation rules (input to the configure script) -README - description of distribution -SUNOS4 - pre-SunOS 4.1 replacement kernel nit modules -VERSION - version of this release -aclocal.m4 - autoconf macros -bpf/net - copies of bpf_filter.c and bpf.h -bpf_filter.c - symlink to bpf/net/bpf_filter.c -bpf_image.c - bpf disassembly routine -config.guess - autoconf support -config.sub - autoconf support -configure - configure script (run this first) -configure.in - configure script source -etherent.c - /etc/ethers support routines -ethertype.h - ethernet protocol types and names definitions -gencode.c - bpf code generation routines -gencode.h - bpf code generation definitions -grammar.y - filter string grammar -inet.c - network routines -install-sh - BSD style install script -lbl/gnuc.h - gcc macros and defines -lbl/os-*.h - os dependent defines and prototypes -mkdep - construct Makefile dependency list -nametoaddr.c - hostname to address routines -net - symlink to bpf/net -optimize.c - bpf optimization routines -pcap-bpf.c - BSD Packet Filter support -pcap-dlpi.c - Data Link Provider Interface support -pcap-enet.c - enet support -pcap-int.h - internal libpcap definitions -pcap-namedb.h - public libpcap name database definitions -pcap-nit.c - Network Interface Tap support -pcap-nit.h - Network Interface Tap definitions -pcap-null.c - dummy monitor support (allows offline use of libpcap) -pcap-pf.c - Packet Filter support -pcap-pf.h - Packet Filter definitions -pcap-snit.c - Streams based Network Interface Tap support -pcap-snoop.c - Snoop network monitoring support -pcap.3 - manual entry -pcap.c - pcap utility routines -pcap.h - public libpcap definitions -ppp.h - Point to Point Protocol definitions -savefile.c - offline support -scanner.l - filter string scanner diff --git a/contrib/libpcap/gencode.c b/contrib/libpcap/gencode.c index b2981f5..b2d8222 100644 --- a/contrib/libpcap/gencode.c +++ b/contrib/libpcap/gencode.c @@ -23,7 +23,7 @@ */ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/libpcap/gencode.c,v 1.221.2.34 2005/09/05 09:08:04 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/gencode.c,v 1.221.2.53 2007/09/12 19:17:24 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -75,7 +75,12 @@ static const char rcsid[] _U_ = #include "ppp.h" #include "sll.h" #include "arcnet.h" -#include "pf.h" +#ifdef HAVE_NET_PFVAR_H +#include <sys/socket.h> +#include <net/if.h> +#include <net/pfvar.h> +#include <net/if_pflog.h> +#endif #ifndef offsetof #define offsetof(s, e) ((size_t)&((s *)0)->e) #endif @@ -102,8 +107,12 @@ static const char rcsid[] _U_ = static jmp_buf top_ctx; static pcap_t *bpf_pcap; +#ifdef WIN32 /* Hack for updating VLAN, MPLS, and PPPoE offsets. */ +static u_int orig_linktype = (u_int)-1, orig_nl = (u_int)-1, label_stack_depth = (u_int)-1; +#else static u_int orig_linktype = -1U, orig_nl = -1U, label_stack_depth = -1U; +#endif /* XXX */ #ifdef PCAP_FDDIPAD @@ -191,6 +200,7 @@ static inline struct block *gen_false(void); static struct block *gen_ether_linktype(int); static struct block *gen_linux_sll_linktype(int); static void insert_radiotap_load_llprefixlen(struct block *); +static void insert_ppi_load_llprefixlen(struct block *); static void insert_load_llprefixlen(struct block *); static struct slist *gen_llprefixlen(void); static struct block *gen_linktype(int); @@ -208,9 +218,9 @@ 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); static struct block *gen_mpls_linktype(int); -static struct block *gen_host(bpf_u_int32, bpf_u_int32, int, int); +static struct block *gen_host(bpf_u_int32, bpf_u_int32, int, int, int); #ifdef INET6 -static struct block *gen_host6(struct in6_addr *, struct in6_addr *, int, int); +static struct block *gen_host6(struct in6_addr *, struct in6_addr *, int, int, int); #endif #ifndef INET6 static struct block *gen_gateway(const u_char *, bpf_u_int32 **, int, int); @@ -240,6 +250,7 @@ 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_ppi_dlt_check(void); static struct block *gen_msg_abbrev(int type); static void * @@ -350,9 +361,10 @@ int no_optimize; int pcap_compile(pcap_t *p, struct bpf_program *program, - char *buf, int optimize, bpf_u_int32 mask) + const char *buf, int optimize, bpf_u_int32 mask) { extern int n_errors; + const char * volatile xbuf = buf; int len; no_optimize = 0; @@ -374,7 +386,7 @@ pcap_compile(pcap_t *p, struct bpf_program *program, return -1; } - lex_init(buf ? buf : ""); + lex_init(xbuf ? xbuf : ""); init_linktype(p); (void)pcap_parse(); @@ -405,7 +417,7 @@ pcap_compile(pcap_t *p, struct bpf_program *program, int pcap_compile_nopcap(int snaplen_arg, int linktype_arg, struct bpf_program *program, - char *buf, int optimize, bpf_u_int32 mask) + const char *buf, int optimize, bpf_u_int32 mask) { pcap_t *p; int ret; @@ -474,10 +486,20 @@ merge(b0, b1) *p = b1; } + void finish_parse(p) struct block *p; { + struct block *ppi_dlt_check; + + ppi_dlt_check = gen_ppi_dlt_check(); + + if (ppi_dlt_check != NULL) + { + gen_and(ppi_dlt_check, p); + } + backpatch(p, gen_retblk(snaplen)); p->sense = !p->sense; backpatch(p, gen_retblk(0)); @@ -498,6 +520,7 @@ finish_parse(p) * require the length of that header, doing more for that * header length isn't really worth the effort. */ + insert_load_llprefixlen(root); } @@ -670,20 +693,26 @@ gen_ncmp(offrel, offset, size, mask, jtype, reverse, v) static int reg_ll_size; /* - * This is the offset of the beginning of the link-layer header. + * This is the offset of the beginning of the link-layer header from + * the beginning of the raw packet data. + * * It's usually 0, except for 802.11 with a fixed-length radio header. + * (For 802.11 with a variable-length radio header, we have to generate + * code to compute that offset; off_ll is 0 in that case.) */ static u_int off_ll; /* * This is the offset of the beginning of the MAC-layer header. - * It's usually 0, except for ATM LANE. + * It's usually 0, except for ATM LANE, where it's the offset, relative + * to the beginning of the raw packet data, of the Ethernet header. */ static u_int off_mac; /* * "off_linktype" is the offset to information in the link-layer header - * giving the packet type. + * giving the packet type. This offset is relative to the beginning + * of the link-layer header (i.e., it doesn't include off_ll). * * For Ethernet, it's the offset of the Ethernet type field. * @@ -721,6 +750,11 @@ static u_int off_vci; static u_int off_proto; /* + * These are offsets for the MTP2 fields. + */ +static u_int off_li; + +/* * These are offsets for the MTP3 fields. */ static u_int off_sio; @@ -736,6 +770,8 @@ static u_int off_payload; /* * These are offsets to the beginning of the network-layer header. + * They are relative to the beginning of the link-layer header (i.e., + * they don't include off_ll). * * If the link layer never uses 802.2 LLC: * @@ -784,6 +820,7 @@ init_linktype(p) /* * And assume we're not doing SS7. */ + off_li = -1; off_sio = -1; off_opc = -1; off_dpc = -1; @@ -958,9 +995,9 @@ init_linktype(p) * the Prism header is fixed-length. */ off_ll = 144; - off_linktype = 144+24; - off_nl = 144+32; /* Prism+802.11+802.2+SNAP */ - off_nl_nosnap = 144+27; /* Prism+802.11+802.2 */ + off_linktype = 24; + off_nl = 32; /* Prism+802.11+802.2+SNAP */ + off_nl_nosnap = 27; /* Prism+802.11+802.2 */ return; case DLT_IEEE802_11_RADIO_AVS: @@ -976,14 +1013,35 @@ init_linktype(p) * 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. + * of the radio header. We should handle that the + * same way we handle the length at the beginning + * of the radiotap header. + * + * XXX - in Linux, do any drivers that supply an AVS + * header supply a link-layer type other than + * ARPHRD_IEEE80211_PRISM? If so, we should map that + * to DLT_IEEE802_11_RADIO_AVS; if not, or if there are + * any drivers that supply an AVS header but supply + * an ARPHRD value of ARPHRD_IEEE80211_PRISM, we'll + * have to check the header in the generated code to + * determine whether it's Prism or AVS. */ off_ll = 64; - off_linktype = 64+24; - off_nl = 64+32; /* Radio+802.11+802.2+SNAP */ - off_nl_nosnap = 64+27; /* Radio+802.11+802.2 */ + off_linktype = 24; + off_nl = 32; /* Radio+802.11+802.2+SNAP */ + off_nl_nosnap = 27; /* Radio+802.11+802.2 */ return; + + /* + * At the moment we treat PPI as normal Radiotap encoded + * packets. The difference is in the function that generates + * the code at the beginning to compute the header length. + * Since this code generator of PPI supports bare 802.11 + * encapsulation only (i.e. the encapsulated DLT should be + * DLT_IEEE802_11) we generate code to check for this too. + */ + case DLT_PPI: case DLT_IEEE802_11_RADIO: /* * Same as 802.11, but with an additional header before @@ -1083,6 +1141,17 @@ init_linktype(p) off_nl_nosnap = 0; /* no 802.2 LLC */ return; + /* + * the only BPF-interesting FRF.16 frames are non-control frames; + * Frame Relay has a variable length link-layer + * so lets start with offset 4 for now and increments later on (FIXME); + */ + case DLT_MFR: + off_linktype = -1; + off_nl = 4; + off_nl_nosnap = 0; /* XXX - for now -> no 802.2 LLC */ + return; + case DLT_APPLE_IP_OVER_IEEE1394: off_linktype = 16; off_nl = 18; @@ -1113,12 +1182,13 @@ init_linktype(p) off_nl_nosnap = 44; /* XXX - what does it do with 802.3 packets? */ return; +#ifdef HAVE_NET_PFVAR_H case DLT_PFLOG: off_linktype = 0; - /* XXX read this from pf.h? */ off_nl = PFLOG_HDRLEN; off_nl_nosnap = PFLOG_HDRLEN; /* no 802.2 LLC */ return; +#endif case DLT_JUNIPER_MFR: case DLT_JUNIPER_MLFR: @@ -1182,7 +1252,14 @@ init_linktype(p) off_nl_nosnap = -1; /* no 802.2 LLC */ return; + case DLT_JUNIPER_VP: + off_linktype = 18; + off_nl = -1; + off_nl_nosnap = -1; + return; + case DLT_MTP2: + off_li = 2; off_sio = 3; off_opc = 4; off_dpc = 4; @@ -1192,6 +1269,17 @@ init_linktype(p) off_nl_nosnap = -1; return; + case DLT_MTP2_WITH_PHDR: + off_li = 6; + off_sio = 7; + off_opc = 8; + off_dpc = 8; + off_sls = 11; + off_linktype = -1; + off_nl = -1; + off_nl_nosnap = -1; + return; + #ifdef DLT_PFSYNC case DLT_PFSYNC: off_linktype = -1; @@ -1208,6 +1296,24 @@ init_linktype(p) off_nl = -1; off_nl_nosnap = -1; return; + + case DLT_USB: + /* + * Currently, only raw "link[N:M]" filtering is supported. + */ + off_linktype = -1; + off_nl = -1; + off_nl_nosnap = -1; + return; + + case DLT_BLUETOOTH_HCI_H4: + /* + * Currently, only raw "link[N:M]" filtering is supported. + */ + off_linktype = -1; + off_nl = -1; + off_nl_nosnap = -1; + return; } bpf_error("unknown data link type %d", linktype); /* NOTREACHED */ @@ -1231,18 +1337,34 @@ gen_load_llrel(offset, size) * If "s" is non-null, it has code to arrange that the X register * contains the length of the prefix preceding the link-layer * header. + * + * Otherwise, the length of the prefix preceding the link-layer + * header is "off_ll". */ if (s != NULL) { + /* + * There's a variable-length prefix preceding the + * link-layer header. "s" points to a list of statements + * that put the length of that prefix into the X register. + * do an indirect load, to use the X register as an offset. + */ s2 = new_stmt(BPF_LD|BPF_IND|size); s2->s.k = offset; sappend(s, s2); } else { + /* + * There is no variable-length header preceding the + * link-layer header; add in off_ll, which, if there's + * a fixed-length header preceding the link-layer header, + * is the length of that header. + */ s = new_stmt(BPF_LD|BPF_ABS|size); - s->s.k = offset; + s->s.k = offset + off_ll; } return s; } + /* * Load a value relative to the beginning of the specified header. */ @@ -1256,11 +1378,12 @@ gen_load_a(offrel, offset, size) switch (offrel) { case OR_PACKET: - s = gen_load_llrel(offset, size); + s = new_stmt(BPF_LD|BPF_ABS|size); + s->s.k = offset; break; case OR_LINK: - s = gen_load_llrel(off_ll + offset, size); + s = gen_load_llrel(offset, size); break; case OR_NET: @@ -1273,17 +1396,24 @@ gen_load_a(offrel, offset, size) case OR_TRAN_IPV4: /* - * Load the X register with the length of the IPv4 header, - * in bytes. + * Load the X register with the length of the IPv4 header + * (plus the offset of the link-layer header, if it's + * preceded by a variable-length header such as a radio + * header), in bytes. */ s = gen_loadx_iphdrlen(); /* - * Load the item at {length of the link-layer header} + - * {length of the IPv4 header} + {specified offset}. + * Load the item at {offset of the link-layer header} + + * {offset, relative to the start of the link-layer + * header, of the IPv4 header} + {length of the IPv4 header} + + * {specified offset}. + * + * (If the link-layer is variable-length, it's included + * in the value in the X register, and off_ll is 0.) */ s2 = new_stmt(BPF_LD|BPF_IND|size); - s2->s.k = off_nl + offset; + s2->s.k = off_ll + off_nl + offset; sappend(s, s2); break; @@ -1341,12 +1471,12 @@ gen_loadx_iphdrlen() } else { /* * There is no variable-length header preceding the - * link-layer header; if there's a fixed-length - * header preceding it, its length is included in - * the off_ variables, so it doesn't need to be added. + * link-layer header; add in off_ll, which, if there's + * a fixed-length header preceding the link-layer header, + * is the length of that header. */ s = new_stmt(BPF_LDX|BPF_MSH|BPF_B); - s->s.k = off_nl; + s->s.k = off_ll + off_nl; } return s; } @@ -1796,6 +1926,104 @@ insert_radiotap_load_llprefixlen(b) } } +/* + * At the moment we treat PPI as normal Radiotap encoded + * packets. The difference is in the function that generates + * the code at the beginning to compute the header length. + * Since this code generator of PPI supports bare 802.11 + * encapsulation only (i.e. the encapsulated DLT should be + * DLT_IEEE802_11) we generate code to check for this too. + */ +static void +insert_ppi_load_llprefixlen(b) + struct block *b; +{ + struct slist *s1, *s2; + + /* + * Prepend to the statements in this block code to load the + * length of the radiotap header into the register assigned + * to hold that length, if one has been assigned. + */ + if (reg_ll_size != -1) { + /* + * The 2 bytes at offsets of 2 and 3 from the beginning + * of the radiotap header are the length of the radiotap + * header; unfortunately, it's little-endian, so we have + * to load it a byte at a time and construct the value. + */ + + /* + * Load the high-order byte, at an offset of 3, shift it + * left a byte, and put the result in the X register. + */ + s1 = new_stmt(BPF_LD|BPF_B|BPF_ABS); + s1->s.k = 3; + s2 = new_stmt(BPF_ALU|BPF_LSH|BPF_K); + sappend(s1, s2); + s2->s.k = 8; + s2 = new_stmt(BPF_MISC|BPF_TAX); + sappend(s1, s2); + + /* + * Load the next byte, at an offset of 2, and OR the + * value from the X register into it. + */ + s2 = new_stmt(BPF_LD|BPF_B|BPF_ABS); + sappend(s1, s2); + s2->s.k = 2; + s2 = new_stmt(BPF_ALU|BPF_OR|BPF_X); + sappend(s1, s2); + + /* + * Now allocate a register to hold that value and store + * it. + */ + s2 = new_stmt(BPF_ST); + s2->s.k = reg_ll_size; + sappend(s1, s2); + + /* + * Now move it into the X register. + */ + s2 = new_stmt(BPF_MISC|BPF_TAX); + sappend(s1, s2); + + /* + * Now append all the existing statements in this + * block to these statements. + */ + sappend(s1, b->stmts); + b->stmts = s1; + + } +} + +static struct block * +gen_ppi_dlt_check(void) +{ + struct slist *s_load_dlt; + struct block *b; + + if (linktype == DLT_PPI) + { + /* Create the statements that check for the DLT + */ + s_load_dlt = new_stmt(BPF_LD|BPF_W|BPF_ABS); + s_load_dlt->s.k = 4; + + b = new_block(JMP(BPF_JEQ)); + + b->stmts = s_load_dlt; + b->s.k = SWAPLONG(DLT_IEEE802_11); + } + else + { + b = NULL; + } + + return b; +} static void insert_load_llprefixlen(b) @@ -1803,8 +2031,21 @@ insert_load_llprefixlen(b) { switch (linktype) { + /* + * At the moment we treat PPI as normal Radiotap encoded + * packets. The difference is in the function that generates + * the code at the beginning to compute the header length. + * Since this code generator of PPI supports bare 802.11 + * encapsulation only (i.e. the encapsulated DLT should be + * DLT_IEEE802_11) we generate code to check for this too. + */ + case DLT_PPI: + insert_ppi_load_llprefixlen(b); + break; + case DLT_IEEE802_11_RADIO: insert_radiotap_load_llprefixlen(b); + break; } } @@ -1831,6 +2072,38 @@ gen_radiotap_llprefixlen(void) return s; } +/* + * At the moment we treat PPI as normal Radiotap encoded + * packets. The difference is in the function that generates + * the code at the beginning to compute the header length. + * Since this code generator of PPI supports bare 802.11 + * encapsulation only (i.e. the encapsulated DLT should be + * DLT_IEEE802_11) we generate code to check for this too. + */ +static struct slist * +gen_ppi_llprefixlen(void) +{ + struct slist *s; + + if (reg_ll_size == -1) { + /* + * We haven't yet assigned a register for the length + * of the radiotap header; allocate one. + */ + reg_ll_size = alloc_reg(); + } + + /* + * Load the register containing the radiotap length + * into the X register. + */ + s = new_stmt(BPF_LDX|BPF_MEM); + s->s.k = reg_ll_size; + return s; +} + + + /* * Generate code to compute the link-layer header length, if necessary, * putting it into the X register, and to return either a pointer to a @@ -1842,6 +2115,10 @@ gen_llprefixlen(void) { switch (linktype) { + case DLT_PPI: + return gen_ppi_llprefixlen(); + + case DLT_IEEE802_11_RADIO: return gen_radiotap_llprefixlen(); @@ -1904,6 +2181,7 @@ gen_linktype(proto) } break; + case DLT_PPI: case DLT_FDDI: case DLT_IEEE802: case DLT_IEEE802_11: @@ -1964,7 +2242,7 @@ gen_linktype(proto) case DLT_RAW: /* * These types don't provide any type field; packets - * are always IP. + * are always IPv4 or IPv6. * * XXX - for IPv4, check for a version number of 4, and, * for IPv6, check for a version number of 6? @@ -1972,10 +2250,13 @@ gen_linktype(proto) switch (proto) { case ETHERTYPE_IP: + /* Check for a version number of 4. */ + return gen_mcmp(OR_LINK, 0, BPF_B, 0x40, 0xF0); #ifdef INET6 case ETHERTYPE_IPV6: + /* Check for a version number of 6. */ + return gen_mcmp(OR_LINK, 0, BPF_B, 0x60, 0xF0); #endif - return gen_true(); /* always true */ default: return gen_false(); /* always false */ @@ -2153,6 +2434,7 @@ gen_linktype(proto) } return (gen_cmp(OR_LINK, 0, BPF_W, (bpf_int32)proto)); +#ifdef HAVE_NET_PFVAR_H case DLT_PFLOG: /* * af field is host byte order in contrast to the rest of @@ -2170,6 +2452,7 @@ gen_linktype(proto) return gen_false(); /*NOTREACHED*/ break; +#endif /* HAVE_NET_PFVAR_H */ case DLT_ARCNET: case DLT_ARCNET_LINUX: @@ -2286,6 +2569,7 @@ gen_linktype(proto) case DLT_JUNIPER_PPP: case DLT_JUNIPER_FRELAY: case DLT_JUNIPER_CHDLC: + case DLT_JUNIPER_VP: /* just lets verify the magic number for now - * on ATM we may have up to 6 different encapsulations on the wire * and need a lot of heuristics to figure out that the payload @@ -3046,22 +3330,22 @@ gen_dnhostop(addr, dir) tmp = gen_mcmp(OR_NET, 2, BPF_H, (bpf_int32)ntohs(0x0681), (bpf_int32)ntohs(0x07FF)); b1 = gen_cmp(OR_NET, 2 + 1 + offset_lh, - BPF_H, (bpf_int32)ntohs(addr)); + BPF_H, (bpf_int32)ntohs((u_short)addr)); gen_and(tmp, b1); /* Check for pad = 0, long header case */ tmp = gen_mcmp(OR_NET, 2, BPF_B, (bpf_int32)0x06, (bpf_int32)0x7); - b2 = gen_cmp(OR_NET, 2 + offset_lh, BPF_H, (bpf_int32)ntohs(addr)); + b2 = gen_cmp(OR_NET, 2 + offset_lh, BPF_H, (bpf_int32)ntohs((u_short)addr)); gen_and(tmp, b2); gen_or(b2, b1); /* Check for pad = 1, short header case */ tmp = gen_mcmp(OR_NET, 2, BPF_H, (bpf_int32)ntohs(0x0281), (bpf_int32)ntohs(0x07FF)); - b2 = gen_cmp(OR_NET, 2 + 1 + offset_sh, BPF_H, (bpf_int32)ntohs(addr)); + b2 = gen_cmp(OR_NET, 2 + 1 + offset_sh, BPF_H, (bpf_int32)ntohs((u_short)addr)); gen_and(tmp, b2); gen_or(b2, b1); /* Check for pad = 0, short header case */ tmp = gen_mcmp(OR_NET, 2, BPF_B, (bpf_int32)0x02, (bpf_int32)0x7); - b2 = gen_cmp(OR_NET, 2 + offset_sh, BPF_H, (bpf_int32)ntohs(addr)); + b2 = gen_cmp(OR_NET, 2 + offset_sh, BPF_H, (bpf_int32)ntohs((u_short)addr)); gen_and(tmp, b2); gen_or(b2, b1); @@ -3105,26 +3389,33 @@ gen_mpls_linktype(proto) } static struct block * -gen_host(addr, mask, proto, dir) +gen_host(addr, mask, proto, dir, type) bpf_u_int32 addr; bpf_u_int32 mask; int proto; int dir; + int type; { struct block *b0, *b1; + const char *typestr; + + if (type == Q_NET) + typestr = "net"; + else + typestr = "host"; switch (proto) { case Q_DEFAULT: - b0 = gen_host(addr, mask, Q_IP, dir); + b0 = gen_host(addr, mask, Q_IP, dir, type); /* * Only check for non-IPv4 addresses if we're not * checking MPLS-encapsulated packets. */ if (label_stack_depth == 0) { - b1 = gen_host(addr, mask, Q_ARP, dir); + b1 = gen_host(addr, mask, Q_ARP, dir, type); gen_or(b0, b1); - b0 = gen_host(addr, mask, Q_RARP, dir); + b0 = gen_host(addr, mask, Q_RARP, dir, type); gen_or(b1, b0); } return b0; @@ -3139,28 +3430,28 @@ gen_host(addr, mask, proto, dir) return gen_hostop(addr, mask, dir, ETHERTYPE_ARP, 14, 24); case Q_TCP: - bpf_error("'tcp' modifier applied to host"); + bpf_error("'tcp' modifier applied to %s", typestr); case Q_SCTP: - bpf_error("'sctp' modifier applied to host"); + bpf_error("'sctp' modifier applied to %s", typestr); case Q_UDP: - bpf_error("'udp' modifier applied to host"); + bpf_error("'udp' modifier applied to %s", typestr); case Q_ICMP: - bpf_error("'icmp' modifier applied to host"); + bpf_error("'icmp' modifier applied to %s", typestr); case Q_IGMP: - bpf_error("'igmp' modifier applied to host"); + bpf_error("'igmp' modifier applied to %s", typestr); case Q_IGRP: - bpf_error("'igrp' modifier applied to host"); + bpf_error("'igrp' modifier applied to %s", typestr); case Q_PIM: - bpf_error("'pim' modifier applied to host"); + bpf_error("'pim' modifier applied to %s", typestr); case Q_VRRP: - bpf_error("'vrrp' modifier applied to host"); + bpf_error("'vrrp' modifier applied to %s", typestr); case Q_ATALK: bpf_error("ATALK host filtering not implemented"); @@ -3188,38 +3479,38 @@ gen_host(addr, mask, proto, dir) bpf_error("'ip6' modifier applied to ip host"); case Q_ICMPV6: - bpf_error("'icmp6' modifier applied to host"); + bpf_error("'icmp6' modifier applied to %s", typestr); #endif /* INET6 */ case Q_AH: - bpf_error("'ah' modifier applied to host"); + bpf_error("'ah' modifier applied to %s", typestr); case Q_ESP: - bpf_error("'esp' modifier applied to host"); + bpf_error("'esp' modifier applied to %s", typestr); case Q_ISO: bpf_error("ISO host filtering not implemented"); case Q_ESIS: - bpf_error("'esis' modifier applied to host"); + bpf_error("'esis' modifier applied to %s", typestr); case Q_ISIS: - bpf_error("'isis' modifier applied to host"); + bpf_error("'isis' modifier applied to %s", typestr); case Q_CLNP: - bpf_error("'clnp' modifier applied to host"); + bpf_error("'clnp' modifier applied to %s", typestr); case Q_STP: - bpf_error("'stp' modifier applied to host"); + bpf_error("'stp' modifier applied to %s", typestr); case Q_IPX: bpf_error("IPX host filtering not implemented"); case Q_NETBEUI: - bpf_error("'netbeui' modifier applied to host"); + bpf_error("'netbeui' modifier applied to %s", typestr); case Q_RADIO: - bpf_error("'radio' modifier applied to host"); + bpf_error("'radio' modifier applied to %s", typestr); default: abort(); @@ -3229,49 +3520,57 @@ gen_host(addr, mask, proto, dir) #ifdef INET6 static struct block * -gen_host6(addr, mask, proto, dir) +gen_host6(addr, mask, proto, dir, type) struct in6_addr *addr; struct in6_addr *mask; int proto; int dir; + int type; { + const char *typestr; + + if (type == Q_NET) + typestr = "net"; + else + typestr = "host"; + switch (proto) { case Q_DEFAULT: - return gen_host6(addr, mask, Q_IPV6, dir); + return gen_host6(addr, mask, Q_IPV6, dir, type); case Q_IP: - bpf_error("'ip' modifier applied to ip6 host"); + bpf_error("'ip' modifier applied to ip6 %s", typestr); case Q_RARP: - bpf_error("'rarp' modifier applied to ip6 host"); + bpf_error("'rarp' modifier applied to ip6 %s", typestr); case Q_ARP: - bpf_error("'arp' modifier applied to ip6 host"); + bpf_error("'arp' modifier applied to ip6 %s", typestr); case Q_SCTP: - bpf_error("'sctp' modifier applied to host"); + bpf_error("'sctp' modifier applied to %s", typestr); case Q_TCP: - bpf_error("'tcp' modifier applied to host"); + bpf_error("'tcp' modifier applied to %s", typestr); case Q_UDP: - bpf_error("'udp' modifier applied to host"); + bpf_error("'udp' modifier applied to %s", typestr); case Q_ICMP: - bpf_error("'icmp' modifier applied to host"); + bpf_error("'icmp' modifier applied to %s", typestr); case Q_IGMP: - bpf_error("'igmp' modifier applied to host"); + bpf_error("'igmp' modifier applied to %s", typestr); case Q_IGRP: - bpf_error("'igrp' modifier applied to host"); + bpf_error("'igrp' modifier applied to %s", typestr); case Q_PIM: - bpf_error("'pim' modifier applied to host"); + bpf_error("'pim' modifier applied to %s", typestr); case Q_VRRP: - bpf_error("'vrrp' modifier applied to host"); + bpf_error("'vrrp' modifier applied to %s", typestr); case Q_ATALK: bpf_error("ATALK host filtering not implemented"); @@ -3280,7 +3579,7 @@ gen_host6(addr, mask, proto, dir) bpf_error("AARP host filtering not implemented"); case Q_DECNET: - bpf_error("'decnet' modifier applied to ip6 host"); + bpf_error("'decnet' modifier applied to ip6 %s", typestr); case Q_SCA: bpf_error("SCA host filtering not implemented"); @@ -3298,37 +3597,37 @@ gen_host6(addr, mask, proto, dir) return gen_hostop6(addr, mask, dir, ETHERTYPE_IPV6, 8, 24); case Q_ICMPV6: - bpf_error("'icmp6' modifier applied to host"); + bpf_error("'icmp6' modifier applied to %s", typestr); case Q_AH: - bpf_error("'ah' modifier applied to host"); + bpf_error("'ah' modifier applied to %s", typestr); case Q_ESP: - bpf_error("'esp' modifier applied to host"); + bpf_error("'esp' modifier applied to %s", typestr); case Q_ISO: bpf_error("ISO host filtering not implemented"); case Q_ESIS: - bpf_error("'esis' modifier applied to host"); + bpf_error("'esis' modifier applied to %s", typestr); case Q_ISIS: - bpf_error("'isis' modifier applied to host"); + bpf_error("'isis' modifier applied to %s", typestr); case Q_CLNP: - bpf_error("'clnp' modifier applied to host"); + bpf_error("'clnp' modifier applied to %s", typestr); case Q_STP: - bpf_error("'stp' modifier applied to host"); + bpf_error("'stp' modifier applied to %s", typestr); case Q_IPX: bpf_error("IPX host filtering not implemented"); case Q_NETBEUI: - bpf_error("'netbeui' modifier applied to host"); + bpf_error("'netbeui' modifier applied to %s", typestr); case Q_RADIO: - bpf_error("'radio' modifier applied to host"); + bpf_error("'radio' modifier applied to %s", typestr); default: abort(); @@ -3355,18 +3654,25 @@ gen_gateway(eaddr, alist, proto, dir) case Q_IP: case Q_ARP: case Q_RARP: - if (linktype == DLT_EN10MB) - b0 = gen_ehostop(eaddr, Q_OR); - else if (linktype == DLT_FDDI) - b0 = gen_fhostop(eaddr, Q_OR); - else if (linktype == DLT_IEEE802) - b0 = gen_thostop(eaddr, Q_OR); - else if (linktype == DLT_IEEE802_11 || - linktype == DLT_IEEE802_11_RADIO_AVS || - linktype == DLT_IEEE802_11_RADIO || - linktype == DLT_PRISM_HEADER) - b0 = gen_wlanhostop(eaddr, Q_OR); - else if (linktype == DLT_SUNATM && is_lane) { + switch (linktype) { + case DLT_EN10MB: + b0 = gen_ehostop(eaddr, Q_OR); + break; + case DLT_FDDI: + b0 = gen_fhostop(eaddr, Q_OR); + break; + case DLT_IEEE802: + b0 = gen_thostop(eaddr, Q_OR); + break; + case DLT_IEEE802_11: + case DLT_IEEE802_11_RADIO_AVS: + case DLT_PPI: + case DLT_IEEE802_11_RADIO: + case DLT_PRISM_HEADER: + b0 = gen_wlanhostop(eaddr, Q_OR); + break; + case DLT_SUNATM: + if (is_lane) { /* * Check that the packet doesn't begin with an * LE Control marker. (We've already generated @@ -3381,15 +3687,19 @@ gen_gateway(eaddr, alist, proto, dir) */ 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( + } + break; + case DLT_IP_OVER_FC: + b0 = gen_ipfchostop(eaddr, Q_OR); + break; + default: + bpf_error( "'gateway' supported only on ethernet/FDDI/token ring/802.11/Fibre Channel"); - - b1 = gen_host(**alist++, 0xffffffff, proto, Q_OR); + } + b1 = gen_host(**alist++, 0xffffffff, proto, Q_OR, Q_HOST); while (*alist) { - tmp = gen_host(**alist++, 0xffffffff, proto, Q_OR); + tmp = gen_host(**alist++, 0xffffffff, proto, Q_OR, + Q_HOST); gen_or(b1, tmp); b1 = tmp; } @@ -4162,6 +4472,9 @@ gen_protochain(v, proto, dir) if (linktype == DLT_IEEE802_11_RADIO) bpf_error("'protochain' not supported with radiotap headers"); + if (linktype == DLT_PPI) + bpf_error("'protochain' not supported with PPI headers"); + no_optimize = 1; /*this code is not compatible with optimzer yet */ /* @@ -4179,11 +4492,11 @@ gen_protochain(v, proto, dir) /* A = ip->ip_p */ s[i] = new_stmt(BPF_LD|BPF_ABS|BPF_B); - s[i]->s.k = off_nl + 9; + s[i]->s.k = off_ll + off_nl + 9; i++; /* X = ip->ip_hl << 2 */ s[i] = new_stmt(BPF_LDX|BPF_MSH|BPF_B); - s[i]->s.k = off_nl; + s[i]->s.k = off_ll + off_nl; i++; break; #ifdef INET6 @@ -4192,7 +4505,7 @@ gen_protochain(v, proto, dir) /* A = ip6->ip_nxt */ s[i] = new_stmt(BPF_LD|BPF_ABS|BPF_B); - s[i]->s.k = off_nl + 6; + s[i]->s.k = off_ll + off_nl + 6; i++; /* X = sizeof(struct ip6_hdr) */ s[i] = new_stmt(BPF_LDX|BPF_IMM); @@ -4272,7 +4585,7 @@ gen_protochain(v, proto, dir) i++; /* A = P[X + packet head] */ s[i] = new_stmt(BPF_LD|BPF_IND|BPF_B); - s[i]->s.k = off_nl; + s[i]->s.k = off_ll + off_nl; i++; /* MEM[reg2] = A */ s[i] = new_stmt(BPF_ST); @@ -4290,7 +4603,7 @@ gen_protochain(v, proto, dir) i++; /* A = P[X + packet head]; */ s[i] = new_stmt(BPF_LD|BPF_IND|BPF_B); - s[i]->s.k = off_nl; + s[i]->s.k = off_ll + off_nl; i++; /* A += 1 */ s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K); @@ -4349,7 +4662,7 @@ gen_protochain(v, proto, dir) i++; /* A = P[X + packet head]; */ s[i] = new_stmt(BPF_LD|BPF_IND|BPF_B); - s[i]->s.k = off_nl; + s[i]->s.k = off_ll + off_nl; i++; /* MEM[reg2] = A */ s[i] = new_stmt(BPF_ST); @@ -4367,7 +4680,7 @@ gen_protochain(v, proto, dir) i++; /* A = P[X + packet head] */ s[i] = new_stmt(BPF_LD|BPF_IND|BPF_B); - s[i]->s.k = off_nl; + s[i]->s.k = off_ll + off_nl; i++; /* A += 2 */ s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K); @@ -4421,6 +4734,7 @@ gen_protochain(v, proto, dir) #endif } + /* * Generate code that checks whether the packet is a packet for protocol * <proto> and whether the type field in that protocol's header has @@ -4467,7 +4781,6 @@ gen_proto(v, proto, dir) * * So we always check for ETHERTYPE_IP. */ - b0 = gen_linktype(ETHERTYPE_IP); #ifndef CHASE_CHAIN b1 = gen_cmp(OR_NET, 9, BPF_B, (bpf_int32)v); @@ -4652,7 +4965,7 @@ gen_scode(name, q) bpf_u_int32 **alist; #else int tproto6; - struct sockaddr_in *sin; + struct sockaddr_in *sin4; struct sockaddr_in6 *sin6; struct addrinfo *res, *res0; struct in6_addr mask128; @@ -4673,7 +4986,7 @@ gen_scode(name, q) addr <<= 8; mask <<= 8; } - return gen_host(addr, mask, proto, dir); + return gen_host(addr, mask, proto, dir, q.addr); case Q_DEFAULT: case Q_HOST: @@ -4711,6 +5024,7 @@ gen_scode(name, q) case DLT_IEEE802_11_RADIO_AVS: case DLT_IEEE802_11_RADIO: case DLT_PRISM_HEADER: + case DLT_PPI: eaddr = pcap_ether_hostton(name); if (eaddr == NULL) bpf_error( @@ -4758,7 +5072,7 @@ gen_scode(name, q) * I don't think DECNET hosts can be multihomed, so * there is no need to build up a list of addresses */ - return (gen_host(dn_addr, 0, proto, dir)); + return (gen_host(dn_addr, 0, proto, dir, q.addr)); } else { #ifndef INET6 alist = pcap_nametoaddr(name); @@ -4767,10 +5081,10 @@ gen_scode(name, q) tproto = proto; if (off_linktype == (u_int)-1 && tproto == Q_DEFAULT) tproto = Q_IP; - b = gen_host(**alist++, 0xffffffff, tproto, dir); + b = gen_host(**alist++, 0xffffffff, tproto, dir, q.addr); while (*alist) { tmp = gen_host(**alist++, 0xffffffff, - tproto, dir); + tproto, dir, q.addr); gen_or(b, tmp); b = tmp; } @@ -4792,10 +5106,10 @@ gen_scode(name, q) if (tproto == Q_IPV6) continue; - sin = (struct sockaddr_in *) + sin4 = (struct sockaddr_in *) res->ai_addr; - tmp = gen_host(ntohl(sin->sin_addr.s_addr), - 0xffffffff, tproto, dir); + tmp = gen_host(ntohl(sin4->sin_addr.s_addr), + 0xffffffff, tproto, dir, q.addr); break; case AF_INET6: if (tproto6 == Q_IP) @@ -4804,7 +5118,7 @@ gen_scode(name, q) sin6 = (struct sockaddr_in6 *) res->ai_addr; tmp = gen_host6(&sin6->sin6_addr, - &mask128, tproto6, dir); + &mask128, tproto6, dir, q.addr); break; default: continue; @@ -4862,12 +5176,9 @@ gen_scode(name, q) #ifndef INET6 return gen_port(port, real_proto, dir); #else - { - struct block *b; b = gen_port(port, real_proto, dir); gen_or(gen_port6(port, real_proto, dir), b); return b; - } #endif /* INET6 */ case Q_PORTRANGE: @@ -4906,12 +5217,9 @@ gen_scode(name, q) #ifndef INET6 return gen_portrange(port1, port2, real_proto, dir); #else - { - struct block *b; b = gen_portrange(port1, port2, real_proto, dir); gen_or(gen_portrange6(port1, port2, real_proto, dir), b); return b; - } #endif /* INET6 */ case Q_GATEWAY: @@ -4977,7 +5285,14 @@ gen_mcode(s1, s2, masklen, q) /* Convert mask len to mask */ if (masklen > 32) bpf_error("mask length must be <= 32"); - m = 0xffffffff << (32 - masklen); + if (masklen == 0) { + /* + * X << 32 is not guaranteed by C to be 0; it's + * undefined. + */ + m = 0; + } else + m = 0xffffffff << (32 - masklen); if ((n & ~m) != 0) bpf_error("non-network bits set in \"%s/%d\"", s1, masklen); @@ -4986,13 +5301,14 @@ gen_mcode(s1, s2, masklen, q) switch (q.addr) { case Q_NET: - return gen_host(n, m, q.proto, q.dir); + return gen_host(n, m, q.proto, q.dir, q.addr); default: bpf_error("Mask syntax for networks only"); /* NOTREACHED */ } /* NOTREACHED */ + return NULL; } struct block * @@ -5019,7 +5335,7 @@ gen_ncode(s, v, q) case Q_HOST: case Q_NET: if (proto == Q_DECNET) - return gen_host(v, 0, proto, dir); + return gen_host(v, 0, proto, dir, q.addr); else if (proto == Q_LINK) { bpf_error("illegal link layer address"); } else { @@ -5035,7 +5351,7 @@ gen_ncode(s, v, q) v <<= 32 - vlen; mask <<= 32 - vlen; } - return gen_host(v, mask, proto, dir); + return gen_host(v, mask, proto, dir, q.addr); } case Q_PORT: @@ -5153,7 +5469,7 @@ gen_mcode6(s1, s2, masklen, q) /* FALLTHROUGH */ case Q_NET: - b = gen_host6(addr, &mask, q.proto, q.dir); + b = gen_host6(addr, &mask, q.proto, q.dir, q.addr); freeaddrinfo(res); return b; @@ -5161,6 +5477,7 @@ gen_mcode6(s1, s2, masklen, q) bpf_error("invalid qualifier against IPv6 address"); /* NOTREACHED */ } + return NULL; } #endif /*INET6*/ @@ -5172,40 +5489,48 @@ gen_ecode(eaddr, 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); - if (linktype == DLT_FDDI) - return gen_fhostop(eaddr, (int)q.dir); - if (linktype == DLT_IEEE802) - return gen_thostop(eaddr, (int)q.dir); - if (linktype == DLT_IEEE802_11 || - linktype == DLT_IEEE802_11_RADIO_AVS || - linktype == DLT_IEEE802_11_RADIO || - linktype == DLT_PRISM_HEADER) - 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(OR_LINK, 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"); + switch (linktype) { + case DLT_EN10MB: + return gen_ehostop(eaddr, (int)q.dir); + case DLT_FDDI: + return gen_fhostop(eaddr, (int)q.dir); + case DLT_IEEE802: + return gen_thostop(eaddr, (int)q.dir); + case DLT_IEEE802_11: + case DLT_IEEE802_11_RADIO_AVS: + case DLT_IEEE802_11_RADIO: + case DLT_PRISM_HEADER: + case DLT_PPI: + return gen_wlanhostop(eaddr, (int)q.dir); + case DLT_SUNATM: + if (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(OR_LINK, 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; + } + break; + case DLT_IP_OVER_FC: + return gen_ipfchostop(eaddr, (int)q.dir); + default: + bpf_error("ethernet addresses supported only on ethernet/FDDI/token ring/802.11/ATM LANE/Fibre Channel"); + break; + } } bpf_error("ethernet address used in non-ether expression"); /* NOTREACHED */ + return NULL; } void @@ -5251,16 +5576,16 @@ xfer_to_a(a) * for "index". */ struct arth * -gen_load(proto, index, size) +gen_load(proto, inst, size) int proto; - struct arth *index; + struct arth *inst; int size; { struct slist *s, *tmp; struct block *b; int regno = alloc_reg(); - free_reg(index->regno); + free_reg(inst->regno); switch (size) { default: @@ -5297,14 +5622,14 @@ gen_load(proto, index, size) * Load into the X register the offset computed into the * register specifed by "index". */ - s = xfer_to_x(index); + s = xfer_to_x(inst); /* * Load the item at that offset. */ tmp = new_stmt(BPF_LD|BPF_IND|size); sappend(s, tmp); - sappend(index->s, s); + sappend(inst->s, s); break; case Q_LINK: @@ -5331,11 +5656,11 @@ gen_load(proto, index, size) * by "index". */ if (s != NULL) { - sappend(s, xfer_to_a(index)); + sappend(s, xfer_to_a(inst)); sappend(s, new_stmt(BPF_ALU|BPF_ADD|BPF_X)); sappend(s, new_stmt(BPF_MISC|BPF_TAX)); } else - s = xfer_to_x(index); + s = xfer_to_x(inst); /* * Load the item at the sum of the offset we've put in the @@ -5347,7 +5672,7 @@ gen_load(proto, index, size) tmp = new_stmt(BPF_LD|BPF_IND|size); tmp->s.k = off_ll; sappend(s, tmp); - sappend(index->s, s); + sappend(inst->s, s); break; case Q_IP: @@ -5380,30 +5705,33 @@ gen_load(proto, index, size) * by "index". */ if (s != NULL) { - sappend(s, xfer_to_a(index)); + sappend(s, xfer_to_a(inst)); sappend(s, new_stmt(BPF_ALU|BPF_ADD|BPF_X)); sappend(s, new_stmt(BPF_MISC|BPF_TAX)); } else - s = xfer_to_x(index); + s = xfer_to_x(inst); /* * Load the item at the sum of the offset we've put in the - * X register and the offset of the start of the network - * layer header. + * X register, the offset of the start of the network + * layer header, and the offset of the start of the link + * layer header (which is 0 if the radio header is + * variable-length; that header length is what we put + * into the X register and then added to the index). */ tmp = new_stmt(BPF_LD|BPF_IND|size); - tmp->s.k = off_nl; + tmp->s.k = off_ll + off_nl; sappend(s, tmp); - sappend(index->s, s); + sappend(inst->s, s); /* * Do the computation only if the packet contains * the protocol in question. */ b = gen_proto_abbrev(proto); - if (index->b) - gen_and(index->b, b); - index->b = b; + if (inst->b) + gen_and(inst->b, b); + inst->b = b; break; case Q_SCTP: @@ -5417,6 +5745,11 @@ gen_load(proto, index, size) /* * The offset is relative to the beginning of * the transport-layer header. + * + * Load the X register with the length of the IPv4 header + * (plus the offset of the link-layer header, if it's + * a variable-length header), in bytes. + * * XXX - are there any cases where we want * off_nl_nosnap? * XXX - we should, if we're built with @@ -5426,23 +5759,25 @@ gen_load(proto, index, size) s = gen_loadx_iphdrlen(); /* - * The X register now contains the sum of the offset - * of the beginning of the link-layer header and - * the length of the network-layer header. Load - * into the A register the offset relative to + * The X register now contains the sum of the length + * of any variable-length header preceding the link-layer + * header and the length of the network-layer header. + * Load into the A register the offset relative to * the beginning of the transport layer header, * add the X register to that, move that to the * X register, and load with an offset from the * X register equal to the offset of the network * layer header relative to the beginning of - * the link-layer header. + * the link-layer header plus the length of any + * fixed-length header preceding the link-layer + * header. */ - sappend(s, xfer_to_a(index)); + sappend(s, xfer_to_a(inst)); sappend(s, new_stmt(BPF_ALU|BPF_ADD|BPF_X)); sappend(s, new_stmt(BPF_MISC|BPF_TAX)); sappend(s, tmp = new_stmt(BPF_LD|BPF_IND|size)); - tmp->s.k = off_nl; - sappend(index->s, s); + tmp->s.k = off_ll + off_nl; + sappend(inst->s, s); /* * Do the computation only if the packet contains @@ -5451,12 +5786,12 @@ gen_load(proto, index, size) * only fragment of that datagram. */ gen_and(gen_proto_abbrev(proto), b = gen_ipfrag()); - if (index->b) - gen_and(index->b, b); + if (inst->b) + gen_and(inst->b, b); #ifdef INET6 gen_and(gen_proto_abbrev(Q_IP), b); #endif - index->b = b; + inst->b = b; break; #ifdef INET6 case Q_ICMPV6: @@ -5464,12 +5799,12 @@ gen_load(proto, index, size) /*NOTREACHED*/ #endif } - index->regno = regno; + inst->regno = regno; s = new_stmt(BPF_ST); s->s.k = regno; - sappend(index->s, s); + sappend(inst->s, s); - return index; + return inst; } struct block * @@ -5625,6 +5960,7 @@ alloc_reg() } bpf_error("too many registers needed to evaluate expression"); /* NOTREACHED */ + return 0; } /* @@ -5737,22 +6073,26 @@ gen_broadcast(proto) case Q_DEFAULT: case Q_LINK: - if (linktype == DLT_ARCNET || linktype == DLT_ARCNET_LINUX) - return gen_ahostop(abroadcast, Q_DST); - if (linktype == DLT_EN10MB) - return gen_ehostop(ebroadcast, Q_DST); - if (linktype == DLT_FDDI) - return gen_fhostop(ebroadcast, Q_DST); - if (linktype == DLT_IEEE802) - return gen_thostop(ebroadcast, Q_DST); - if (linktype == DLT_IEEE802_11 || - linktype == DLT_IEEE802_11_RADIO_AVS || - linktype == DLT_IEEE802_11_RADIO || - linktype == DLT_PRISM_HEADER) - return gen_wlanhostop(ebroadcast, Q_DST); - if (linktype == DLT_IP_OVER_FC) - return gen_ipfchostop(ebroadcast, Q_DST); - if (linktype == DLT_SUNATM && is_lane) { + switch (linktype) { + case DLT_ARCNET: + case DLT_ARCNET_LINUX: + return gen_ahostop(abroadcast, Q_DST); + case DLT_EN10MB: + return gen_ehostop(ebroadcast, Q_DST); + case DLT_FDDI: + return gen_fhostop(ebroadcast, Q_DST); + case DLT_IEEE802: + return gen_thostop(ebroadcast, Q_DST); + case DLT_IEEE802_11: + case DLT_IEEE802_11_RADIO_AVS: + case DLT_IEEE802_11_RADIO: + case DLT_PPI: + case DLT_PRISM_HEADER: + return gen_wlanhostop(ebroadcast, Q_DST); + case DLT_IP_OVER_FC: + return gen_ipfchostop(ebroadcast, Q_DST); + case DLT_SUNATM: + if (is_lane) { /* * Check that the packet doesn't begin with an * LE Control marker. (We've already generated @@ -5768,8 +6108,11 @@ gen_broadcast(proto) b0 = gen_ehostop(ebroadcast, Q_DST); gen_and(b1, b0); return b0; - } - bpf_error("not a broadcast link"); + } + break; + default: + bpf_error("not a broadcast link"); + } break; case Q_IP: @@ -5784,6 +6127,7 @@ gen_broadcast(proto) } bpf_error("only link-layer/IP broadcast filters supported"); /* NOTREACHED */ + return NULL; } /* @@ -5816,154 +6160,147 @@ gen_multicast(proto) case Q_DEFAULT: case Q_LINK: - 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 */ - return gen_mac_multicast(0); - } - - if (linktype == DLT_FDDI) { - /* - * 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 || - linktype == DLT_IEEE802_11_RADIO_AVS || - linktype == DLT_IEEE802_11_RADIO || - linktype == DLT_PRISM_HEADER) { - /* - * 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 = gen_load_a(OR_LINK, 1, BPF_B); - 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 = gen_load_a(OR_LINK, 1, BPF_B); - 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 = gen_load_a(OR_LINK, 0, BPF_B); - 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 = gen_load_a(OR_LINK, 0, BPF_B); - 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 = gen_load_a(OR_LINK, 0, BPF_B); - 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; - } - - if (linktype == DLT_SUNATM && is_lane) { + switch (linktype) { + case DLT_ARCNET: + case DLT_ARCNET_LINUX: + /* all ARCnet multicasts use the same address */ + return gen_ahostop(abroadcast, Q_DST); + case DLT_EN10MB: + /* ether[0] & 1 != 0 */ + return gen_mac_multicast(0); + case DLT_FDDI: + /* + * 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); + case DLT_IEEE802: + /* tr[2] & 1 != 0 */ + return gen_mac_multicast(2); + case DLT_IEEE802_11: + case DLT_IEEE802_11_RADIO_AVS: + case DLT_PPI: + case DLT_IEEE802_11_RADIO: + case DLT_PRISM_HEADER: + /* + * 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 = gen_load_a(OR_LINK, 1, BPF_B); + 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 = gen_load_a(OR_LINK, 1, BPF_B); + 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 = gen_load_a(OR_LINK, 0, BPF_B); + 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 = gen_load_a(OR_LINK, 0, BPF_B); + 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 = gen_load_a(OR_LINK, 0, BPF_B); + 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 DLT_IP_OVER_FC: + b0 = gen_mac_multicast(2); + return b0; + case DLT_SUNATM: + if (is_lane) { /* * Check that the packet doesn't begin with an * LE Control marker. (We've already generated @@ -5977,10 +6314,13 @@ gen_multicast(proto) b0 = gen_mac_multicast(off_mac); gen_and(b1, b0); return b0; - } - - /* Link not known to support multicasts */ - break; + } + break; + default: + break; + } + /* Link not known to support multicasts */ + break; case Q_IP: b0 = gen_linktype(ETHERTYPE_IP); @@ -5998,6 +6338,7 @@ gen_multicast(proto) } bpf_error("link-layer multicast filters supported only on ethernet/FDDI/token ring/ARCNET/802.11/ATM LANE/Fibre Channel"); /* NOTREACHED */ + return NULL; } /* @@ -6043,10 +6384,12 @@ gen_inbound(dir) } break; +#ifdef HAVE_NET_PFVAR_H case DLT_PFLOG: b0 = gen_cmp(OR_LINK, offsetof(struct pfloghdr, dir), BPF_B, (bpf_int32)((dir == 0) ? PF_IN : PF_OUT)); break; +#endif case DLT_PPP_PPPD: if (dir) { @@ -6073,6 +6416,7 @@ gen_inbound(dir) case DLT_JUNIPER_PPP: case DLT_JUNIPER_FRELAY: case DLT_JUNIPER_CHDLC: + case DLT_JUNIPER_VP: /* juniper flags (including direction) are stored * the byte after the 3-byte magic number */ if (dir) { @@ -6093,6 +6437,7 @@ gen_inbound(dir) return (b0); } +#ifdef HAVE_NET_PFVAR_H /* PF firewall log matched interface */ struct block * gen_pf_ifname(const char *ifname) @@ -6202,6 +6547,55 @@ gen_pf_action(int action) return (b0); } +#else /* !HAVE_NET_PFVAR_H */ +struct block * +gen_pf_ifname(const char *ifname) +{ + bpf_error("libpcap was compiled without pf support"); + /* NOTREACHED */ + return (NULL); +} + +struct block * +gen_pf_ruleset(char *ruleset) +{ + bpf_error("libpcap was compiled on a machine without pf support"); + /* NOTREACHED */ + return (NULL); +} + +struct block * +gen_pf_rnr(int rnr) +{ + bpf_error("libpcap was compiled on a machine without pf support"); + /* NOTREACHED */ + return (NULL); +} + +struct block * +gen_pf_srnr(int srnr) +{ + bpf_error("libpcap was compiled on a machine without pf support"); + /* NOTREACHED */ + return (NULL); +} + +struct block * +gen_pf_reason(int reason) +{ + bpf_error("libpcap was compiled on a machine without pf support"); + /* NOTREACHED */ + return (NULL); +} + +struct block * +gen_pf_action(int action) +{ + bpf_error("libpcap was compiled on a machine without pf support"); + /* NOTREACHED */ + return (NULL); +} +#endif /* HAVE_NET_PFVAR_H */ struct block * gen_acode(eaddr, q) @@ -6214,6 +6608,7 @@ gen_acode(eaddr, q) } bpf_error("ARCnet address used in non-arc expression"); /* NOTREACHED */ + return NULL; } static struct block * @@ -6356,13 +6751,11 @@ gen_mpls(label_num) case DLT_C_HDLC: /* fall through */ case DLT_EN10MB: - b0 = gen_cmp(OR_LINK, off_linktype, BPF_H, - (bpf_int32)ETHERTYPE_MPLS); + b0 = gen_linktype(ETHERTYPE_MPLS); break; case DLT_PPP: - b0 = gen_cmp(OR_LINK, off_linktype, BPF_H, - (bpf_int32)PPP_MPLS_UCAST); + b0 = gen_linktype(PPP_MPLS_UCAST); break; /* FIXME add other DLT_s ... @@ -6624,6 +7017,50 @@ gen_atmtype_abbrev(type) return b1; } +/* + * Filtering for MTP2 messages based on li value + * FISU, length is null + * LSSU, length is 1 or 2 + * MSU, length is 3 or more + */ +struct block * +gen_mtp2type_abbrev(type) + int type; +{ + struct block *b0, *b1; + + switch (type) { + + case M_FISU: + if ( (linktype != DLT_MTP2) && + (linktype != DLT_MTP2_WITH_PHDR) ) + bpf_error("'fisu' supported only on MTP2"); + /* gen_ncmp(offrel, offset, size, mask, jtype, reverse, value) */ + b0 = gen_ncmp(OR_PACKET, off_li, BPF_B, 0x3f, BPF_JEQ, 0, 0); + break; + + case M_LSSU: + if ( (linktype != DLT_MTP2) && + (linktype != DLT_MTP2_WITH_PHDR) ) + bpf_error("'lssu' supported only on MTP2"); + b0 = gen_ncmp(OR_PACKET, off_li, BPF_B, 0x3f, BPF_JGT, 1, 2); + b1 = gen_ncmp(OR_PACKET, off_li, BPF_B, 0x3f, BPF_JGT, 0, 0); + gen_and(b1, b0); + break; + + case M_MSU: + if ( (linktype != DLT_MTP2) && + (linktype != DLT_MTP2_WITH_PHDR) ) + bpf_error("'msu' supported only on MTP2"); + b0 = gen_ncmp(OR_PACKET, off_li, BPF_B, 0x3f, BPF_JGT, 0, 2); + break; + + default: + abort(); + } + return b0; +} + struct block * gen_mtp3field_code(mtp3field, jvalue, jtype, reverse) int mtp3field; diff --git a/contrib/libpcap/gencode.h b/contrib/libpcap/gencode.h index 15aef6d..9363a42 100644 --- a/contrib/libpcap/gencode.h +++ b/contrib/libpcap/gencode.h @@ -19,7 +19,7 @@ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * * $FreeBSD$ - * @(#) $Header: /tcpdump/master/libpcap/gencode.h,v 1.60.2.6 2005/09/05 09:08:06 guy Exp $ (LBL) + * @(#) $Header: /tcpdump/master/libpcap/gencode.h,v 1.60.2.11 2007/06/11 09:52:04 guy Exp $ (LBL) */ /* @@ -174,11 +174,16 @@ end-to-end circuits, ILMI circuits or connection signalling circuit. */ -/*MTP3 field types */ -#define M_SIO 1 -#define M_OPC 2 -#define M_DPC 3 -#define M_SLS 4 +/* MTP2 types */ +#define M_FISU 22 /* FISU */ +#define M_LSSU 23 /* LSSU */ +#define M_MSU 24 /* MSU */ + +/* MTP3 field types */ +#define M_SIO 1 +#define M_OPC 2 +#define M_DPC 3 +#define M_SLS 4 struct slist; @@ -297,6 +302,7 @@ struct block *gen_atmfield_code(int atmfield, bpf_int32 jvalue, bpf_u_int32 jtyp struct block *gen_atmtype_abbrev(int type); struct block *gen_atmmulti_abbrev(int type); +struct block *gen_mtp2type_abbrev(int type); struct block *gen_mtp3field_code(int mtp3field, bpf_u_int32 jvalue, bpf_u_int32 jtype, int reverse); struct block *gen_pf_ifname(const char *); @@ -316,7 +322,7 @@ char *sdup(const char *); struct bpf_insn *icode_to_fcode(struct block *, int *); int pcap_parse(void); -void lex_init(char *); +void lex_init(const char *); void lex_cleanup(void); void sappend(struct slist *, struct slist *); diff --git a/contrib/libpcap/grammar.y b/contrib/libpcap/grammar.y index 1072f96..9d9b202 100644 --- a/contrib/libpcap/grammar.y +++ b/contrib/libpcap/grammar.y @@ -23,7 +23,7 @@ */ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/libpcap/grammar.y,v 1.86.2.5 2005/09/05 09:08:06 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/grammar.y,v 1.86.2.9 2007/09/12 19:17:25 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -53,7 +53,11 @@ struct rtentry; #include "pcap-int.h" #include "gencode.h" -#include "pf.h" +#ifdef HAVE_NET_PFVAR_H +#include <net/if.h> +#include <net/pfvar.h> +#include <net/if_pflog.h> +#endif #include <pcap-namedb.h> #ifdef HAVE_OS_PROTO_H @@ -69,7 +73,7 @@ int n_errors = 0; static struct qual qerr = { Q_UNDEF, Q_UNDEF, Q_UNDEF, Q_UNDEF }; static void -yyerror(char *msg) +yyerror(const char *msg) { ++n_errors; bpf_error("%s", msg); @@ -86,6 +90,50 @@ pcap_parse() } #endif +#ifdef HAVE_NET_PFVAR_H +static int +pfreason_to_num(const char *reason) +{ + const char *reasons[] = PFRES_NAMES; + int i; + + for (i = 0; reasons[i]; i++) { + if (pcap_strcasecmp(reason, reasons[i]) == 0) + return (i); + } + bpf_error("unknown PF reason"); + /*NOTREACHED*/ +} + +static int +pfaction_to_num(const char *action) +{ + if (pcap_strcasecmp(action, "pass") == 0 || + pcap_strcasecmp(action, "accept") == 0) + return (PF_PASS); + else if (pcap_strcasecmp(action, "drop") == 0 || + pcap_strcasecmp(action, "block") == 0) + return (PF_DROP); + else { + bpf_error("unknown PF action"); + /*NOTREACHED*/ + } +} +#else /* !HAVE_NET_PFVAR_H */ +static int +pfreason_to_num(const char *reason) +{ + bpf_error("libpcap was compiled on a machine without pf support"); + /*NOTREACHED*/ +} + +static int +pfaction_to_num(const char *action) +{ + bpf_error("libpcap was compiled on a machine without pf support"); + /*NOTREACHED*/ +} +#endif /* HAVE_NET_PFVAR_H */ %} %union { @@ -114,8 +162,9 @@ pcap_parse() %type <i> atmtype atmmultitype %type <blk> atmfield %type <blk> atmfieldvalue atmvalue atmlistvalue -%type <blk> mtp3field -%type <blk> mtp3fieldvalue mtp3value mtp3listvalue +%type <i> mtp2type +%type <blk> mtp3field +%type <blk> mtp3fieldvalue mtp3value mtp3listvalue %token DST SRC HOST GATEWAY @@ -141,7 +190,8 @@ pcap_parse() %token OAM OAMF4 CONNECTMSG METACONNECT %token VPI VCI %token RADIO -%token SIO OPC DPC SLS +%token FISU LSSU MSU +%token SIO OPC DPC SLS %type <s> ID %type <e> EID @@ -262,6 +312,7 @@ rterm: head id { $$ = $2; } | atmtype { $$.b = gen_atmtype_abbrev($1); $$.q = qerr; } | atmmultitype { $$.b = gen_atmmulti_abbrev($1); $$.q = qerr; } | atmfield atmvalue { $$.b = $2.b; $$.q = qerr; } + | mtp2type { $$.b = gen_mtp2type_abbrev($1); $$.q = qerr; } | mtp3field mtp3value { $$.b = $2.b; $$.q = qerr; } ; /* protocol level qualifiers */ @@ -349,28 +400,10 @@ pfvar: PF_IFNAME ID { $$ = gen_pf_ifname($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"); - } + | ID { $$ = pfreason_to_num($1); } ; -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"); - } +action: ID { $$ = pfaction_to_num($1); } ; relop: '>' { $$ = BPF_JGT; } @@ -440,6 +473,11 @@ atmfieldvalue: NUM { atmlistvalue: atmfieldvalue | atmlistvalue or atmfieldvalue { gen_or($1.b, $3.b); $$ = $3; } ; + /* MTP2 types quantifier */ +mtp2type: FISU { $$ = M_FISU; } + | LSSU { $$ = M_LSSU; } + | MSU { $$ = M_MSU; } + ; /* MTP3 field types quantifier */ mtp3field: SIO { $$.mtp3fieldtype = M_SIO; } | OPC { $$.mtp3fieldtype = M_OPC; } diff --git a/contrib/libpcap/lbl/gnuc.h b/contrib/libpcap/lbl/gnuc.h deleted file mode 100644 index 37d0094..0000000 --- a/contrib/libpcap/lbl/gnuc.h +++ /dev/null @@ -1,43 +0,0 @@ -/* @(#) $Header: /tcpdump/master/libpcap/lbl/gnuc.h,v 1.3.1.1 1999/10/07 23:46:41 mcr Exp $ (LBL) */ - -/* Define __P() macro, if necessary */ -#ifndef __P -#if __STDC__ -#define __P(protos) protos -#else -#define __P(protos) () -#endif -#endif - -/* inline foo */ -#ifdef __GNUC__ -#define inline __inline -#else -#define inline -#endif - -/* - * Handle new and old "dead" routine prototypes - * - * For example: - * - * __dead void foo(void) __attribute__((volatile)); - * - */ -#ifdef __GNUC__ -#ifndef __dead -#define __dead volatile -#endif -#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) -#ifndef __attribute__ -#define __attribute__(args) -#endif -#endif -#else -#ifndef __dead -#define __dead -#endif -#ifndef __attribute__ -#define __attribute__(args) -#endif -#endif diff --git a/contrib/libpcap/nametoaddr.c b/contrib/libpcap/nametoaddr.c index fe4c582..791c281 100644 --- a/contrib/libpcap/nametoaddr.c +++ b/contrib/libpcap/nametoaddr.c @@ -26,7 +26,7 @@ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/libpcap/nametoaddr.c,v 1.77.2.3 2005/04/20 11:13:51 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/nametoaddr.c,v 1.77.2.4 2007/06/11 09:52:05 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -278,7 +278,7 @@ pcap_nametoproto(const char *str) #include "ethertype.h" struct eproto { - char *s; + const char *s; u_short p; }; @@ -399,7 +399,7 @@ __pcap_atodn(const char *s, bpf_u_int32 *addr) u_int node, area; - if (sscanf((char *)s, "%d.%d", &area, &node) != 2) + if (sscanf(s, "%d.%d", &area, &node) != 2) bpf_error("malformed decnet address '%s'", s); *addr = (area << AREASHIFT) & AREAMASK; @@ -485,7 +485,7 @@ pcap_ether_hostton(const char *name) u_char a[6]; ap = NULL; - if (ether_hostton((char *)name, (struct ether_addr *)a) == 0) { + if (ether_hostton(name, (struct ether_addr *)a) == 0) { ap = (u_char *)malloc(6); if (ap != NULL) memcpy((char *)ap, (char *)a, 6); diff --git a/contrib/libpcap/pcap-bpf.c b/contrib/libpcap/pcap-bpf.c index e8492d3..91bfdcb 100644 --- a/contrib/libpcap/pcap-bpf.c +++ b/contrib/libpcap/pcap-bpf.c @@ -22,7 +22,7 @@ */ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/libpcap/pcap-bpf.c,v 1.86.2.8 2005/07/10 10:55:31 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/pcap-bpf.c,v 1.86.2.12 2007/06/15 17:57:27 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -525,8 +525,12 @@ static inline int bpf_open(pcap_t *p, char *errbuf) { int fd; +#ifdef HAVE_CLONING_BPF + static const char device[] = "/dev/bpf"; +#else int n = 0; char device[sizeof "/dev/bpf0000000000"]; +#endif #ifdef _AIX /* @@ -538,6 +542,12 @@ bpf_open(pcap_t *p, char *errbuf) return (-1); #endif +#ifdef HAVE_CLONING_BPF + if ((fd = open(device, O_RDWR)) == -1 && + (errno != EACCES || (fd = open(device, O_RDONLY)) == -1)) + snprintf(errbuf, PCAP_ERRBUF_SIZE, + "(cannot open device) %s: %s", device, pcap_strerror(errno)); +#else /* * Go through all the minors and find one that isn't in use. */ @@ -568,6 +578,7 @@ bpf_open(pcap_t *p, char *errbuf) if (fd < 0) snprintf(errbuf, PCAP_ERRBUF_SIZE, "(no devices found) %s: %s", device, pcap_strerror(errno)); +#endif return (fd); } diff --git a/contrib/libpcap/pcap-int.h b/contrib/libpcap/pcap-int.h index 5ca621a..fbab8e9 100644 --- a/contrib/libpcap/pcap-int.h +++ b/contrib/libpcap/pcap-int.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * $FreeBSD$ - * @(#) $Header: /tcpdump/master/libpcap/pcap-int.h,v 1.68.2.6 2005/07/07 06:56:04 guy Exp $ (LBL) + * @(#) $Header: /tcpdump/master/libpcap/pcap-int.h,v 1.68.2.11 2007/06/22 06:43:58 guy Exp $ (LBL) */ #ifndef pcap_int_h @@ -44,7 +44,7 @@ extern "C" { #include <pcap.h> #ifdef WIN32 -#include <packet32.h> +#include <Packet32.h> #endif /* WIN32 */ #ifdef MSDOS @@ -53,6 +53,19 @@ extern "C" { #endif /* + * Swap byte ordering of unsigned long long timestamp on a big endian + * machine. + */ +#define SWAPLL(ull) ((ull & 0xff00000000000000LL) >> 56) | \ + ((ull & 0x00ff000000000000LL) >> 40) | \ + ((ull & 0x0000ff0000000000LL) >> 24) | \ + ((ull & 0x000000ff00000000LL) >> 8) | \ + ((ull & 0x00000000ff000000LL) << 8) | \ + ((ull & 0x0000000000ff0000LL) << 24) | \ + ((ull & 0x000000000000ff00LL) << 40) | \ + ((ull & 0x00000000000000ffLL) << 56) + +/* * Savefile */ typedef enum { @@ -89,6 +102,7 @@ struct pcap_md { int ifindex; /* interface index of device we're bound to */ int lo_ifindex; /* interface index of the loopback device */ struct pcap *next; /* list of open promiscuous sock_packet pcaps */ + u_int packets_read; /* count of packets read with recvfrom() */ #endif #ifdef HAVE_DAG_API @@ -111,8 +125,13 @@ struct pcap_md { /* * 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. + * Tru64 UNIX, and some versions of NetBSD pad FDDI packets to make everything + * line up on a nice boundary. */ +#ifdef __NetBSD__ +#include <sys/param.h> /* needed to declare __NetBSD_Version__ */ +#endif + #if defined(ultrix) || defined(__osf__) || (defined(__NetBSD__) && __NetBSD_Version__ > 106000000) #define PCAP_FDDIPAD 3 #endif @@ -189,9 +208,13 @@ struct pcap { }; /* - * This is a timeval as stored in disk in a dumpfile. + * This is a timeval as stored in a savefile. * It has to use the same types everywhere, independent of the actual - * `struct timeval' + * `struct timeval'; `struct timeval' has 32-bit tv_sec values on some + * platforms and 64-bit tv_sec values on other platforms, and writing + * out native `struct timeval' values would mean files could only be + * read on systems with the same tv_sec size as the system on which + * the file was written. */ struct pcap_timeval { @@ -200,7 +223,7 @@ struct pcap_timeval { }; /* - * How a `pcap_pkthdr' is actually stored in the dumpfile. + * This is a `pcap_pkthdr' as actually stored in a savefile. * * Do not change the format of this structure, in any way (this includes * changes that only affect the length of fields in this structure), @@ -232,7 +255,7 @@ struct pcap_sf_pkthdr { }; /* - * How a `pcap_pkthdr' is actually stored in dumpfiles written + * How a `pcap_pkthdr' is actually stored in savefiles written * by some patched versions of libpcap (e.g. the ones in Red * Hat Linux 6.1 and 6.2). * diff --git a/contrib/libpcap/pcap.3 b/contrib/libpcap/pcap.3 index 6fd0a07..14b9368 100644 --- a/contrib/libpcap/pcap.3 +++ b/contrib/libpcap/pcap.3 @@ -1,4 +1,4 @@ -.\" @(#) $Header: /tcpdump/master/libpcap/pcap.3,v 1.64.2.8 2005/09/07 08:29:17 guy Exp $ +.\" @(#) $Header: /tcpdump/master/libpcap/pcap.3,v 1.64.2.11 2007/06/11 09:52:05 guy Exp $ .\" .\" Copyright (c) 1994, 1996, 1997 .\" The Regents of the University of California. All rights reserved. @@ -79,7 +79,7 @@ u_char *sp) .ft B int pcap_compile(pcap_t *p, struct bpf_program *fp, .ti +8 -char *str, int optimize, bpf_u_int32 netmask) +const char *str, int optimize, bpf_u_int32 netmask) int pcap_setfilter(pcap_t *p, struct bpf_program *fp) void pcap_freecode(struct bpf_program *) int pcap_setdirection(pcap_t *p, pcap_direction_t d) @@ -118,7 +118,7 @@ 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_strerror(int error) const char *pcap_lib_version(void) .ft .LP @@ -1081,6 +1081,11 @@ and type bytes. Linux-IrDA packets, with a .B DLT_LINUX_SLL header followed by the IrLAP header. +.TP 5 +.B DLT_LINUX_LAPD +LAPD (Q.921) frames, with a +.B DLT_LINUX_SLL +header captured via vISDN. .RE .PP .B pcap_list_datalinks() @@ -1160,12 +1165,13 @@ or NULL, if a network device was opened with .BR pcap_open_live() . .PP .B pcap_stats() -returns 0 and fills in a +returns 0 and fills in the .B pcap_stat -struct. The values represent packet statistics from the start of the -run to the time of the call. If there is an error or the underlying -packet capture doesn't support packet statistics, \-1 is returned and -the error text can be obtained with +structure pointed to by its second argument. The values represent +packet statistics from the start of the run to the time of the call. If +there is an error or the underlying packet capture doesn't support +packet statistics, \-1 is returned and the error text can be obtained +with .B pcap_perror() or .BR pcap_geterr() . diff --git a/contrib/libpcap/pcap.h b/contrib/libpcap/pcap.h index e91b9d5..f6815aa 100644 --- a/contrib/libpcap/pcap.h +++ b/contrib/libpcap/pcap.h @@ -32,7 +32,7 @@ * SUCH DAMAGE. * * $FreeBSD$ - * @(#) $Header: /tcpdump/master/libpcap/pcap.h,v 1.52.2.5 2005/07/07 02:04:36 guy Exp $ (LBL) + * @(#) $Header: /tcpdump/master/libpcap/pcap.h,v 1.52.2.7 2007/06/11 09:52:05 guy Exp $ (LBL) */ #ifndef lib_pcap_h @@ -41,7 +41,9 @@ #include <sys/types.h> #include <sys/time.h> -#include <net/bpf.h> +#ifndef PCAP_DONT_INCLUDE_PCAP_BPF_H +#include <pcap-bpf.h> +#endif #include <stdio.h> @@ -119,9 +121,16 @@ typedef enum { } pcap_direction_t; /* - * Each packet in the dump file is prepended with this generic header. - * This gets around the problem of different headers for different - * packet interfaces. + * Generic per-packet information, as supplied by libpcap. + * + * The time stamp can and should be a "struct timeval", regardless of + * whether your system supports 32-bit tv_sec in "struct timeval", + * 64-bit tv_sec in "struct timeval", or both if it supports both 32-bit + * and 64-bit applications. The on-disk format of savefiles uses 32-bit + * tv_sec (and tv_usec); this structure is irrelevant to that. 32-bit + * and 64-bit versions of libpcap, even if they're on the same platform, + * should supply the appropriate version of "struct timeval", even if + * that's not what the underlying packet capture mechanism supplies. */ struct pcap_pkthdr { struct timeval ts; /* time stamp */ @@ -222,12 +231,12 @@ int pcap_setnonblock(pcap_t *, int, char *); void pcap_perror(pcap_t *, char *); int pcap_inject(pcap_t *, const void *, size_t); int pcap_sendpacket(pcap_t *, const u_char *, int); -char *pcap_strerror(int); +const char *pcap_strerror(int); char *pcap_geterr(pcap_t *); -int pcap_compile(pcap_t *, struct bpf_program *, char *, int, +int pcap_compile(pcap_t *, struct bpf_program *, const char *, int, bpf_u_int32); int pcap_compile_nopcap(int, int, struct bpf_program *, - char *, int, bpf_u_int32); + const char *, int, bpf_u_int32); void pcap_freecode(struct bpf_program *); int pcap_datalink(pcap_t *); int pcap_list_datalinks(pcap_t *, int **); diff --git a/contrib/libpcap/pf.h b/contrib/libpcap/pf.h deleted file mode 100644 index a9b127a..0000000 --- a/contrib/libpcap/pf.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2001 Daniel Hartmeier - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 - * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * @(#) $Header: /tcpdump/master/libpcap/pf.h,v 1.3 2004/04/02 06:33:30 guy Exp $ (LBL) - */ - -/* from $OpenBSD: pfvar.h,v 1.170 2003/08/22 21:50:34 david Exp $ */ - -enum { PF_INOUT=0, PF_IN=1, PF_OUT=2 }; -enum { PF_PASS=0, PF_DROP=1, PF_SCRUB=2, PF_NAT=3, PF_NONAT=4, - PF_BINAT=5, PF_NOBINAT=6, PF_RDR=7, PF_NORDR=8, PF_SYNPROXY_DROP=9 }; - -/* Reasons code for passing/dropping a packet */ -#define PFRES_MATCH 0 /* Explicit match of a rule */ -#define PFRES_BADOFF 1 /* Bad offset for pull_hdr */ -#define PFRES_FRAG 2 /* Dropping following fragment */ -#define PFRES_SHORT 3 /* Dropping short packet */ -#define PFRES_NORM 4 /* Dropping by normalizer */ -#define PFRES_MEMORY 5 /* Dropped due to lacking mem */ -#define PFRES_MAX 6 /* total+1 */ - -#define PFRES_NAMES { \ - "match", \ - "bad-offset", \ - "fragment", \ - "short", \ - "normalize", \ - "memory", \ - NULL \ -} - -#define PF_RULESET_NAME_SIZE 16 - -/* from $OpenBSD: if_pflog.h,v 1.9 2003/07/15 20:27:27 dhartmei Exp $ */ - -#ifndef IFNAMSIZ -#define IFNAMSIZ 16 -#endif - -struct pfloghdr { - u_int8_t length; - u_int8_t af; - u_int8_t action; - u_int8_t reason; - char ifname[IFNAMSIZ]; - char ruleset[PF_RULESET_NAME_SIZE]; - u_int32_t rulenr; - u_int32_t subrulenr; - u_int8_t dir; - u_int8_t pad[3]; -}; -#define PFLOG_HDRLEN sizeof(struct pfloghdr) diff --git a/contrib/libpcap/scanner.l b/contrib/libpcap/scanner.l index e231b0b..ff8ae63 100644 --- a/contrib/libpcap/scanner.l +++ b/contrib/libpcap/scanner.l @@ -24,7 +24,7 @@ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/libpcap/scanner.l,v 1.99.2.4 2005/09/05 09:08:07 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/scanner.l,v 1.99.2.9 2007/06/11 09:52:05 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -82,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 16000 -%o 19000 -%e 6000 -%k 4000 -%p 25000 +%a 18400 +%o 21500 +%e 7600 +%k 4550 +%p 27600 %n 2000 V680 {W}:{W}:{W}:{W}:{W}:{W}:{W}:{W} @@ -289,6 +289,10 @@ srnr|subrulenum return PF_SRNR; reason return PF_REASON; action return PF_ACTION; +fisu return FISU; +lssu return LSSU; +lsu return LSSU; +msu return MSU; sio return SIO; opc return OPC; dpc return DPC; @@ -358,7 +362,7 @@ tcp-urg { yylval.i = 0x20; return NUM; } %% void lex_init(buf) - char *buf; + const char *buf; { #ifdef FLEX_SCANNER in_buffer = yy_scan_string(buf); |