From b784546c222e9ff428eae62a8066011b3d439171 Mon Sep 17 00:00:00 2001 From: Peter Avalos Date: Sat, 4 Jul 2009 10:17:05 -1000 Subject: [PATCH] Remove old versions of libpcap. --- contrib/libpcap-0.8.3/CHANGES | 386 -- contrib/libpcap-0.8.3/CREDITS | 88 - contrib/libpcap-0.8.3/FILES | 104 - contrib/libpcap-0.8.3/LICENSE | 19 - contrib/libpcap-0.8.3/README | 94 - contrib/libpcap-0.8.3/README.DELETED | 22 - contrib/libpcap-0.8.3/README.DRAGONFLY | 6 - contrib/libpcap-0.8.3/TODO | 42 - contrib/libpcap-0.8.3/VERSION | 1 - contrib/libpcap-0.8.3/arcnet.h | 52 - contrib/libpcap-0.8.3/atmuni31.h | 87 - contrib/libpcap-0.8.3/bpf/net/bpf_filter.c | 565 -- contrib/libpcap-0.8.3/bpf_dump.c | 62 - contrib/libpcap-0.8.3/bpf_image.c | 288 - contrib/libpcap-0.8.3/etherent.c | 162 - contrib/libpcap-0.8.3/ethertype.h | 107 - contrib/libpcap-0.8.3/fad-getad.c | 243 - contrib/libpcap-0.8.3/fad-gifc.c | 502 -- contrib/libpcap-0.8.3/fad-glifc.c | 325 -- contrib/libpcap-0.8.3/fad-null.c | 65 - contrib/libpcap-0.8.3/fad-win32.c | 291 -- contrib/libpcap-0.8.3/gencode.c | 5520 -------------------- contrib/libpcap-0.8.3/gencode.h | 309 -- contrib/libpcap-0.8.3/grammar.y | 430 -- contrib/libpcap-0.8.3/inet.c | 693 --- contrib/libpcap-0.8.3/llc.h | 69 - contrib/libpcap-0.8.3/nametoaddr.c | 433 -- contrib/libpcap-0.8.3/nlpid.h | 58 - contrib/libpcap-0.8.3/optimize.c | 2165 -------- contrib/libpcap-0.8.3/pcap-bpf.c | 910 ---- contrib/libpcap-0.8.3/pcap-bpf.h | 596 --- contrib/libpcap-0.8.3/pcap-dag.c | 710 --- contrib/libpcap-0.8.3/pcap-dag.h | 14 - contrib/libpcap-0.8.3/pcap-dlpi.c | 1521 ------ contrib/libpcap-0.8.3/pcap-enet.c | 235 - contrib/libpcap-0.8.3/pcap-int.h | 293 -- contrib/libpcap-0.8.3/pcap-linux.c | 1999 ------- contrib/libpcap-0.8.3/pcap-namedb.h | 87 - contrib/libpcap-0.8.3/pcap-nit.c | 308 -- contrib/libpcap-0.8.3/pcap-nit.h | 19 - contrib/libpcap-0.8.3/pcap-null.c | 54 - contrib/libpcap-0.8.3/pcap-pf.c | 538 -- contrib/libpcap-0.8.3/pcap-pf.h | 19 - contrib/libpcap-0.8.3/pcap-snit.c | 367 -- contrib/libpcap-0.8.3/pcap-snoop.c | 350 -- contrib/libpcap-0.8.3/pcap-stdinc.h | 61 - contrib/libpcap-0.8.3/pcap-win32.c | 446 -- contrib/libpcap-0.8.3/pcap.3 | 1196 ----- contrib/libpcap-0.8.3/pcap.c | 772 --- contrib/libpcap-0.8.3/pcap.h | 258 - contrib/libpcap-0.8.3/pf.h | 77 - contrib/libpcap-0.8.3/ppp.h | 52 - contrib/libpcap-0.8.3/rawss7.h | 105 - contrib/libpcap-0.8.3/savefile.c | 1035 ---- contrib/libpcap-0.8.3/scanner.l | 420 -- contrib/libpcap-0.8.3/sll.h | 124 - contrib/libpcap-0.8.3/snprintf.c | 632 --- contrib/libpcap-0.8.3/sunatmpos.h | 45 - 58 files changed, 26431 deletions(-) delete mode 100644 contrib/libpcap-0.8.3/CHANGES delete mode 100644 contrib/libpcap-0.8.3/CREDITS delete mode 100644 contrib/libpcap-0.8.3/FILES delete mode 100644 contrib/libpcap-0.8.3/LICENSE delete mode 100644 contrib/libpcap-0.8.3/README delete mode 100644 contrib/libpcap-0.8.3/README.DELETED delete mode 100644 contrib/libpcap-0.8.3/README.DRAGONFLY delete mode 100644 contrib/libpcap-0.8.3/TODO delete mode 100644 contrib/libpcap-0.8.3/VERSION delete mode 100644 contrib/libpcap-0.8.3/arcnet.h delete mode 100644 contrib/libpcap-0.8.3/atmuni31.h delete mode 100644 contrib/libpcap-0.8.3/bpf/net/bpf_filter.c delete mode 100644 contrib/libpcap-0.8.3/bpf_dump.c delete mode 100644 contrib/libpcap-0.8.3/bpf_image.c delete mode 100644 contrib/libpcap-0.8.3/etherent.c delete mode 100644 contrib/libpcap-0.8.3/ethertype.h delete mode 100644 contrib/libpcap-0.8.3/fad-getad.c delete mode 100644 contrib/libpcap-0.8.3/fad-gifc.c delete mode 100644 contrib/libpcap-0.8.3/fad-glifc.c delete mode 100644 contrib/libpcap-0.8.3/fad-null.c delete mode 100644 contrib/libpcap-0.8.3/fad-win32.c delete mode 100644 contrib/libpcap-0.8.3/gencode.c delete mode 100644 contrib/libpcap-0.8.3/gencode.h delete mode 100644 contrib/libpcap-0.8.3/grammar.y delete mode 100644 contrib/libpcap-0.8.3/inet.c delete mode 100644 contrib/libpcap-0.8.3/llc.h delete mode 100644 contrib/libpcap-0.8.3/nametoaddr.c delete mode 100644 contrib/libpcap-0.8.3/nlpid.h delete mode 100644 contrib/libpcap-0.8.3/optimize.c delete mode 100644 contrib/libpcap-0.8.3/pcap-bpf.c delete mode 100644 contrib/libpcap-0.8.3/pcap-bpf.h delete mode 100644 contrib/libpcap-0.8.3/pcap-dag.c delete mode 100644 contrib/libpcap-0.8.3/pcap-dag.h delete mode 100644 contrib/libpcap-0.8.3/pcap-dlpi.c delete mode 100644 contrib/libpcap-0.8.3/pcap-enet.c delete mode 100644 contrib/libpcap-0.8.3/pcap-int.h delete mode 100644 contrib/libpcap-0.8.3/pcap-linux.c delete mode 100644 contrib/libpcap-0.8.3/pcap-namedb.h delete mode 100644 contrib/libpcap-0.8.3/pcap-nit.c delete mode 100644 contrib/libpcap-0.8.3/pcap-nit.h delete mode 100644 contrib/libpcap-0.8.3/pcap-null.c delete mode 100644 contrib/libpcap-0.8.3/pcap-pf.c delete mode 100644 contrib/libpcap-0.8.3/pcap-pf.h delete mode 100644 contrib/libpcap-0.8.3/pcap-snit.c delete mode 100644 contrib/libpcap-0.8.3/pcap-snoop.c delete mode 100644 contrib/libpcap-0.8.3/pcap-stdinc.h delete mode 100644 contrib/libpcap-0.8.3/pcap-win32.c delete mode 100644 contrib/libpcap-0.8.3/pcap.3 delete mode 100644 contrib/libpcap-0.8.3/pcap.c delete mode 100644 contrib/libpcap-0.8.3/pcap.h delete mode 100644 contrib/libpcap-0.8.3/pf.h delete mode 100644 contrib/libpcap-0.8.3/ppp.h delete mode 100644 contrib/libpcap-0.8.3/rawss7.h delete mode 100644 contrib/libpcap-0.8.3/savefile.c delete mode 100644 contrib/libpcap-0.8.3/scanner.l delete mode 100644 contrib/libpcap-0.8.3/sll.h delete mode 100644 contrib/libpcap-0.8.3/snprintf.c delete mode 100644 contrib/libpcap-0.8.3/sunatmpos.h diff --git a/contrib/libpcap-0.8.3/CHANGES b/contrib/libpcap-0.8.3/CHANGES deleted file mode 100644 index 01b1581e80..0000000000 --- a/contrib/libpcap-0.8.3/CHANGES +++ /dev/null @@ -1,386 +0,0 @@ -@(#) $Header: /tcpdump/master/libpcap/CHANGES,v 1.56.4.3 2004/03/30 14:29:16 mcr Exp $ (LBL) - -Tue. March 30, 2004. mcr@sandelman.ottawa.on.ca. Summary for 3.8.3 release - - Fixed minor problem in gencode.c that would appear on 64-bit - platforms. - Version number is now sane. - -Mon. March 29, 2004. mcr@sandelman.ottawa.on.ca. Summary for 3.8.2 release - - updates for autoconf 2.5 - fixes for ppp interfaces for freebsd 4.1 - pcap gencode can generate code for 802.11, IEEE1394, and pflog. - -Wed. November 12, 2003. mcr@sandelman.ottawa.on.ca. Summary for 0.8 release - - added pcap_findalldevs() - Win32 patches from NetGroup, Politecnico di Torino (Italy) - OpenBSD pf, DLT_PFLOG added - Many changes to ATM support. - lookup pcap_lookupnet() - Added DLT_ARCNET_LINUX, DLT_ENC, DLT_IEEE802_11_RADIO, DLT_SUNATM, - DLT_IP_OVER_FC, DLT_FRELAY, others. - Sigh. More AIX wonderfulness. - Document updates. - Changes to API: pcap_next_ex(), pcap_breakloop(), pcap_dump_flush(), - pcap_list_datalinks(), pcap_set_datalink(), - pcap_lib_version(), pcap_datalink_val_to_name(), - pcap_datalink_name_to_val(), new error returns. - -Tuesday, February 25, 2003. fenner@research.att.com. 0.7.2 release - - Support link types that use 802.2 always, never, and sometimes. - Don't decrease the size of the BPF buffer from the default. - Support frame relay. - Handle 32-bit timestamps in DLPI, and pass the right buffer size. - Handle Linux systems with modern kernel but without - SOL_PACKET in the userland headers. - Linux support for ARPHRD_RAWHDLC. - Handle 32-bit timestamps in snoop. - Support eg (Octane/O2xxx/O3xxx Gigabit) devices. - Add new reserved DLT types. - -Monday October 23, 2001. mcr@sandelman.ottawa.on.ca. Summary for 0.7 release - - Added pcap_findalldevs() call to get list of interfaces in a MI way. - - pcap_stats() has been documented as to what its counters mean on - each platform. - -Tuesday January 9, 2001. guy@alum.mit.edu. Summary for 0.6 release - - New Linux libpcap implementation, which, in 2.2 and later - kernels, uses PF_PACKET sockets and supports kernel packet - filtering (if compiled into the kernel), and supports the "any" - device for capturing on all interfaces. Cleans up promiscuous - mode better on pre-2.2 kernels, and has various other fixes - (handles 2.4 ARPHRD_IEEE802_TR, handles ISDN devices better, - doesn't show duplicate packets on loopback interface, etc.). - - Fixed HP-UX libpcap implementation to correctly get the PPA for - an interface, to allow interfaces to be opened by interface name. - - libpcap savefiles have system-independent link-layer type values - in the header, rather than sometimes platform-dependent DLT_ - values, to make it easier to exchange capture files between - different OSes. - - Non-standard capture files produced by some Linux tcpdumps, e.g. - the one from Red Hat Linux 6.2 and later, can now be read. - - Updated autoconf stock files. - - Filter expressions can filter on VLAN IDs and various OSI - protocols, and work on Token Ring (with non-source-routed - packets). - - "pcap_open_dead()" added to allow compiling filter expressions - to pcap code without opening a capture device or capture file. - - Header files fixed to allow use in C++ programs. - - Removed dependancy on native headers for packet layout. - Removed Linux specific headers that were shipped. - - Security fixes: Strcpy replaced with strlcpy, sprintf replaced - with snprintf. - - Fixed bug that could cause subsequent "pcap_compile()"s to fail - erroneously after one compile failed. - - Assorted other bug fixes. - - README.aix and README.linux files added to describe - platform-specific issues. - - "getifaddrs()" rather than SIOCGIFCONF used, if available. - -v0.5 Sat Jun 10 11:09:15 PDT 2000 - -itojun@iijlab.net -- Brought in KAME IPv6/IPsec bpf compiler. -- Fixes for NetBSD. -- Support added for OpenBSD DLT_LOOP and BSD/OS DLT_C_HDLC (Cisco HDLC), - and changes to work around different BSDs having different DLT_ types - with the same numeric value. - -Assar Westerlund -- Building outside the source code tree fixed. -- Changed to write out time stamps with 32-bit seconds and microseconds - fields, regardless of whether those fields are 32 bits or 64 bits in - the OS's native "struct timeval". -- Changed "pcap_lookupdev()" to dynamically grow the buffer into which - the list of interfaces is read as necessary in order to hold the - entire list. - -Greg Troxel -- Added a new "pcap_compile_nopcap()", which lets you compile a filter - expression into a BPF program without having an open live capture or - capture file. - -v0.4 Sat Jul 25 12:40:09 PDT 1998 - -- Fix endian problem with DLT_NULL devices. From FreeBSD via Bill - Fenner (fenner@parc.xerox.com) - -- Fix alignment problem with FDDI under DLPI. This was causing core - dumps under Solaris. - -- Added configure options to disable flex and bison. Resulted from a - bug report by barnett@grymoire.crd.ge.com (Bruce Barnett). Also added - options to disable gcc and to force a particular packet capture type. - -- Added support for Fore ATM interfaces (qaa and fa) under IRIX. Thanks - to John Hawkinson (jhawk@mit.edu) - -- Change Linux PPP and SLIP to use DLT_RAW since the kernel does not - supply any "link layer" data. - -- Change Linux to use SIOCGIFHWADDR ioctl to determine link layer type. - Thanks to Thomas Sailer (sailer@ife.ee.ethz.ch) - -- Change IRIX PPP to use DLT_RAW since the kernel does not supply any - "link layer" data. - -- Modified to support the new BSD/OS 2.1 PPP and SLIP link layer header - formats. - -- Added some new SGI snoop interface types. Thanks to Steve Alexander - (sca@refugee.engr.sgi.com) - -- Fixes for HP-UX 10.20 (which is similar to HP-UX 9). Thanks to - Richard Allen (ra@hp.is) and Steinar Haug (sthaug@nethelp.no) - -- Fddi supports broadcast as reported by Jeff Macdonald - (jeff@iacnet.com). Also correct ieee802 and arcnet. - -- Determine Linux pcap buffer size at run time or else it might not be - big enough for some interface types (e.g. FDDI). Thanks to Jes - Sorensen (Jes.Sorensen@cern.ch) - -- Fix some linux alignment problems. - -- Document promisc argument to pcap_open_live(). Reported by Ian Marsh - (ianm@sics.se) - -- Support Metricom radio packets under Linux. Thanks to Kevin Lai - (laik@gunpowder.stanford.edu) - -- Bind to interface name under Linux to avoid packets from multiple - interfaces on multi-homed hosts. Thanks to Kevin Lai - (laik@gunpowder.stanford.edu) - -- Change L_SET to SEEK_SET for HP-UX. Thanks to Roland Roberts - (rroberts@muller.com) - -- Fixed an uninitialized memory reference found by Kent Vander Velden - (graphix@iastate.edu) - -- Fixed lex pattern for IDs to allow leading digits. As reported by - Theo de Raadt (deraadt@cvs.openbsd.org) - -- Fixed Linux include file problems when using GNU libc. - -- Ifdef ARPHRD_FDDI since not all versions of the Linux kernel have it. - Reported reported by Eric Jacksch (jacksch@tenebris.ca) - -- Fixed bug in pcap_dispatch() that kept it from returning on packet - timeouts. - -- Changed ISLOOPBACK() macro when IFF_LOOPBACK isn't available to check - for "lo" followed by an eos or digit (newer versions of Linux - apparently call the loopback "lo" instead of "lo0"). - -- Fixed Linux networking include files to use ints instead of longs to - avoid problems with 64 bit longs on the alpha. Thanks to Cristian - Gafton (gafton@redhat.com) - -v0.3 Sat Nov 30 20:56:27 PST 1996 - -- Added Linux support. - -- Fixed savefile bugs. - -- Solaris x86 fix from Tim Rylance (t.rylance@elsevier.nl) - -- Add support for bpf kernel port filters. - -- Remove duplicate atalk protocol table entry. Thanks to Christian - Hopps (chopps@water.emich.edu) - -- Fixed pcap_lookupdev() to ignore nonexistent devices. This was - reported to happen under BSD/OS by David Vincenzetti - (vince@cryptonet.it) - -- Avoid solaris compiler warnings. Thanks to Bruce Barnett - (barnett@grymoire.crd.ge.com) - -v0.2.1 Sun Jul 14 03:02:26 PDT 1996 - -- Fixes for HP-UX 10. Thanks in part to to Thomas Wolfram - (wolf@prz.tu-berlin.de) and Rick Jones (raj@hpisrdq.cup.hp.com) - -- Added support for SINIX. Thanks to Andrej Borsenkow - (borsenkow.msk@sni.de) - -- Fixes for AIX (although this system is not yet supported). Thanks to - John Hawkinson (jhawk@mit.edu) - -- Use autoconf's idea of the top level directory in install targets. - Thanks to John Hawkinson. - -- Add missing autoconf packet capture result message. Thanks to Bill - Fenner (fenner@parc.xerox.com) - -- Fixed padding problems in the pf module. - -- Fixed some more alignment problems on the alpha. - -- Added explicit netmask support. Thanks to Steve Nuchia - (steve@research.oknet.com) - -- Fixed to handle raw ip addresses such as 0.0.0.1 without "left - justifing" - -- Add "sca" keyword (for DEC cluster services) as suggested by Terry - Kennedy (terry@spcvxa.spc.edu) - -- Add "atalk" keyword as suggested by John Hawkinson. - -- Add "igrp" keyword. - -- Fixed HID definition in grammar.y to be a string, not a value. - -- Use $CC when checking gcc version. Thanks to Carl Lindberg - (carl_lindberg@blacksmith.com) - -- Removed obsolete reference to pcap_immediate() from the man page. - Michael Stolarchuk (mts@terminator.rs.itd.umich.edu) - -- DLT_NULL has a 4 byte family header. Thanks to Jeffrey Honig - (jch@bsdi.com) - -v0.2 Sun Jun 23 02:28:42 PDT 1996 - -- Add support for HP-UX. Resulted from code contributed by Tom Murray - (tmurray@hpindck.cup.hp.com) and Philippe-Andri Prindeville - (philipp@res.enst.fr) - -- Update INSTALL with a reminder to install include files. Thanks to - Mark Andrews (mandrews@aw.sgi.com) - -- Fix bpf compiler alignment bug on the alpha. - -- Use autoconf to detect architectures that can't handle misaligned - accesses. - -- Added loopback support for snoop. Resulted from report Steve - Alexander (sca@engr.sgi.com) - -v0.1 Fri Apr 28 18:11:03 PDT 1995 - -- Fixed compiler and optimizer bugs. The BPF filter engine uses unsigned - comparison operators, while the code generator and optimizer assumed - signed semantics in several places. Thanks to Charlie Slater - (cslater@imatek.com) for pointing this out. - -- Removed FDDI ifdef's, they aren't really needed. Resulted from report - by Gary Veum (veum@boa.gsfc.nasa.gov). - -- Add pcap-null.c which allows offline use of libpcap on systems that - don't support live package capture. This feature resulting from a - request from Jan van Oorschot (j.p.m.voorschot@et.tudelft.nl). - -- Make bpf_compile() reentrant. Fix thanks to Pascal Hennequin - (Pascal.Hennequin@hugo.int-evry.fr). - -- Port to GNU autoconf. - -- Fix pcap-dlpi.c to work with isdn. Resulted from report by Flemming - Johansen (fsj@csd.cri.dk). - -- Handle multi-digit interface unit numbers (aka ppa's) under dlpi. - Resulted from report by Daniel Ehrlich (ehrlich@cse.psu.edu). - -- Fix pcap-dlpi.c to work in non-promiscuous mode. Resulted from report - by Jeff Murphy (jcmurphy@acsu.buffalo.edu). - -- Add support for "long jumps". Thanks to Jeffrey Mogul - (mogul@pa.dec.com). - -- Fix minor problems when compiling with BDEBUG as noticed by Scott - Bertilson (scott@unet.umn.edu). - -- Declare sys_errlist "const char *const" to avoid problems under - FreeBSD. Resulted from report by jher@eden.com. - -v0.0.6 Fri Apr 28 04:07:13 PDT 1995 - -- Add missing variable declaration missing from 0.0.6 - -v0.0.5 Fri Apr 28 00:22:21 PDT 1995 - -- Workaround for problems when pcap_read() returns 0 due to the timeout - expiring. - -v0.0.4 Thu Apr 20 20:41:48 PDT 1995 - -- Change configuration to not use gcc v2 flags with gcc v1. - -- Fixed a bug in pcap_next(); if pcap_dispatch() returns 0, pcap_next() - should also return 0. Thanks to Richard Stevens (rstevens@noao.edu). - -- Fixed configure to test for snoop before dlpi to avoid problems under - IRIX 5. Thanks to J. Eric Townsend (jet@abulafia.genmagic.com). - -- Hack around deficiency in Ultrix's make. - -- Fix two bugs related to the Solaris pre-5.3.2 bufmod bug; handle - savefiles that have more than snapshot bytes of data in them (so we - can read old savefiles) and avoid writing such files. - -- Added checkioctl which is used with gcc to check that the - "fixincludes" script has been run. - -v0.0.3 Tue Oct 18 18:13:46 PDT 1994 - -- Fixed configure to test for snoop before dlpi to avoid problems under - IRIX 5. Thanks to J. Eric Townsend (jet@abulafia.genmagic.com). - -v0.0.2 Wed Oct 12 20:56:37 PDT 1994 - -- Implement timeout in the dlpi pcap_open_live(). Thanks to Richard - Stevens. - -- Determine pcap link type from dlpi media type. Resulted from report - by Mahesh Jethanandani (mahesh@npix.com). - -v0.0.1 Fri Jun 24 14:50:57 PDT 1994 - -- Fixed bug in nit_setflags() in pcap-snit.c. The streams ioctl timeout - wasn't being initialized sometimes resulting in an "NIOCSFLAGS: - Invalid argument" error under OSF/1. Reported by Matt Day - (mday@artisoft.com) and Danny Mitzel (dmitzel@whitney.hitc.com). - -- Turn on FDDI support by default. - -v0.0 Mon Jun 20 19:20:16 PDT 1994 - -- Initial release. - -- Fixed bug with greater/less keywords, reported by Mark Andrews - (mandrews@alias.com). - -- Fix bug where '|' was defined as BPF_AND instead of BPF_OR, reported - by Elan Amir (elan@leeb.cs.berkeley.edu). - -- Machines with little-endian byte ordering are supported thanks to - Jeff Mogul. - -- Add hack for version 2.3 savefiles which don't have caplen and len - swapped thanks to Vern Paxson. - -- Added "&&" and "||" aliases for "and" and "or" thanks to Vern Paxson. - -- Added length, inbound and outbound keywords. diff --git a/contrib/libpcap-0.8.3/CREDITS b/contrib/libpcap-0.8.3/CREDITS deleted file mode 100644 index fadf77f545..0000000000 --- a/contrib/libpcap-0.8.3/CREDITS +++ /dev/null @@ -1,88 +0,0 @@ -This file lists people who have contributed to libpcap: - -The current maintainers: - Bill Fenner - Fulvio Risso - Guy Harris - Hannes Gredler - Jun-ichiro itojun Hagino - Michael Richardson - -Additional people who have contributed patches: - - Alan Bawden - Alexey Kuznetsov - Albert Chin - Andrew Brown - Antti Kantee - Arkadiusz Miskiewicz - Armando L. Caro Jr. - Assar Westerlund - Brian Ginsbach - Charles M. Hannum - Chris G. Demetriou - Chris Pepper - Darren Reed - David Kaelbling - David Young - Don Ebright - Eric Anderson - Franz Schaefer - Gianluca Varenni - Gisle Vanem - Graeme Hewson - Greg Stark - Greg Troxel - Guillaume Pelat - Hyung Sik Yoon - Igor Khristophorov - Jan-Philip Velders - Jason R. Thorpe - Javier Achirica - Jean Tourrilhes - Jefferson Ogata - Jesper Peterson - John Bankier - Jon Lindgren - Juergen Schoenwaelder - Kazushi Sugyo - Klaus Klein - Koryn Grant - Krzysztof Halasa - Lorenzo Cavallaro - Loris Degioanni - Love Hörnquist-Åstrand - Maciej W. Rozycki - Marcus Felipe Pereira - Martin Husemann - Mike Wiacek - Monroe Williams - Octavian Cerna - Olaf Kirch - Onno van der Linden - Paul Mundt - Pavel Kankovsky - Peter Fales - Peter Jeremy - Phil Wood - Rafal Maszkowski - Rick Jones - Scott Barron - Scott Gifford - Sebastian Krahmer - Shaun Clowes - Solomon Peachy - Stefan Hudson - Takashi Yamamoto - Tony Li - Torsten Landschoff - Uns Lider - Uwe Girlich - Xianjie Zhang - Yen Yen Lim - Yoann Vandoorselaere - -The original LBL crew: - Steve McCanne - Craig Leres - Van Jacobson diff --git a/contrib/libpcap-0.8.3/FILES b/contrib/libpcap-0.8.3/FILES deleted file mode 100644 index 4f8193c604..0000000000 --- a/contrib/libpcap-0.8.3/FILES +++ /dev/null @@ -1,104 +0,0 @@ -CHANGES -CREDITS -FILES -INSTALL.txt -LICENSE -Makefile.in -README -README.aix -README.dag -README.hpux -README.linux -README.tru64 -README.Win32 -SUNOS4/nit_if.o.sparc -SUNOS4/nit_if.o.sun3 -SUNOS4/nit_if.o.sun4c.4.0.3c -TODO -VERSION -acconfig.h -aclocal.m4 -arcnet.h -atmuni31.h -bpf/net/bpf_filter.c -bpf_dump.c -bpf_image.c -config.guess -config.h.in -config.sub -configure -configure.in -etherent.c -ethertype.h -fad-getad.c -fad-gifc.c -fad-glifc.c -fad-null.c -fad-win32.c -gencode.c -gencode.h -grammar.y -inet.c -install-sh -lbl/os-aix4.h -lbl/os-hpux11.h -lbl/os-osf4.h -lbl/os-osf5.h -lbl/os-solaris2.h -lbl/os-sunos4.h -lbl/os-ultrix4.h -llc.h -mkdep -nametoaddr.c -nlpid.h -optimize.c -packaging/pcap.spec -pcap-bpf.c -pcap-bpf.h -pcap-dag.c -pcap-dag.h -pcap-dlpi.c -pcap-enet.c -pcap-int.h -pcap-linux.c -pcap-namedb.h -pcap-nit.c -pcap-nit.h -pcap-null.c -pcap-pf.c -pcap-pf.h -pcap-stdinc.h -pcap-snit.c -pcap-snoop.c -pcap-win32.c -pcap.3 -pcap.c -pcap.h -pf.h -ppp.h -rawss7.h -savefile.c -scanner.l -sll.h -snprintf.c -sunatmpos.h -Win32/Include/Gnuc.h -Win32/Include/addrinfo.h -Win32/Include/bittypes.h -Win32/Include/cdecl_ext.h -Win32/Include/inetprivate.h -Win32/Include/ip6_misc.h -Win32/Include/sockstorage.h -Win32/Include/arpa/nameser.h -Win32/Include/net/if.h -Win32/Include/net/netdb.h -Win32/Include/net/paths.h -Win32/Src/ffs.c -Win32/Src/getaddrinfo.c -Win32/Src/getnetbynm.c -Win32/Src/getnetent.c -Win32/Src/getopt.c -Win32/Src/getservent.c -Win32/Src/inet_aton.c -Win32/Src/inet_net.c -Win32/Src/inet_pton.c diff --git a/contrib/libpcap-0.8.3/LICENSE b/contrib/libpcap-0.8.3/LICENSE deleted file mode 100644 index dea5f7d54d..0000000000 --- a/contrib/libpcap-0.8.3/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -License: BSD - -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. The names of the authors may not be used to endorse or promote - products derived from this software without specific prior - written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR -IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. diff --git a/contrib/libpcap-0.8.3/README b/contrib/libpcap-0.8.3/README deleted file mode 100644 index 35ab2f8aca..0000000000 --- a/contrib/libpcap-0.8.3/README +++ /dev/null @@ -1,94 +0,0 @@ -@(#) $Header: /tcpdump/master/libpcap/README,v 1.27.2.1 2003/11/15 23:29:19 guy Exp $ (LBL) - -LIBPCAP 0.8 -Now maintained by "The Tcpdump Group" -See www.tcpdump.org - -Please send inquiries/comments/reports to tcpdump-workers@tcpdump.org - -Anonymous CVS is available via: - cvs -d :pserver:tcpdump@cvs.tcpdump.org:/tcpdump/master login - (password "anoncvs") - cvs -d :pserver:tcpdump@cvs.tcpdump.org:/tcpdump/master checkout libpcap - -Version 0.8 of LIBPCAP can be retrieved with the CVS tag "libpcap_0_8rel1": - cvs -d :pserver:tcpdump@cvs.tcpdump.org:/tcpdump/master checkout -r libpcap_0_8rel1 libpcap - -Please send patches against the master copy to patches@tcpdump.org. - -formerly from Lawrence Berkeley National Laboratory - Network Research Group - ftp://ftp.ee.lbl.gov/libpcap.tar.Z (0.4) - -This directory contains source code for libpcap, a system-independent -interface for user-level packet capture. libpcap provides a portable -framework for low-level network monitoring. Applications include -network statistics collection, security monitoring, network debugging, -etc. Since almost every system vendor provides a different interface -for packet capture, and since we've developed several tools that -require this functionality, we've created this system-independent API -to ease in porting and to alleviate the need for several -system-dependent packet capture modules in each application. - -Note well: this interface is new and is likely to change. - -For some platforms there are README.{system} files that discuss issues -with the OS's interface for packet capture on those platforms, such as -how to enable support for that interface in the OS, if it's not built in -by default. - -The libpcap interface supports a filtering mechanism based on the -architecture in the BSD packet filter. BPF is described in the 1993 -Winter Usenix paper ``The BSD Packet Filter: A New Architecture for -User-level Packet Capture''. A compressed PostScript version can be -found at - - ftp://ftp.ee.lbl.gov/papers/bpf-usenix93.ps.Z - -or - - http://www.tcpdump.org/papers/bpf-usenix93.ps.Z - -and a gzipped version can be found at - - http://www.tcpdump.org/papers/bpf-usenix93.ps.gz - -A PDF version can be found at - - http://www.tcpdump.org/papers/bpf-usenix93.pdf - -Although most packet capture interfaces support in-kernel filtering, -libpcap utilizes in-kernel filtering only for the BPF interface. -On systems that don't have BPF, all packets are read into user-space -and the BPF filters are evaluated in the libpcap library, incurring -added overhead (especially, for selective filters). Ideally, libpcap -would translate BPF filters into a filter program that is compatible -with the underlying kernel subsystem, but this is not yet implemented. - -BPF is standard in 4.4BSD, BSD/OS, NetBSD, FreeBSD, and OpenBSD. DEC -OSF/1/Digital UNIX/Tru64 UNIX uses the packetfilter interface but has -been extended to accept BPF filters (which libpcap utilizes). Also, you -can add BPF filter support to Ultrix using the kernel source and/or -object patches available in: - - ftp://gatekeeper.dec.com/pub/DEC/net/bpfext42.tar.Z. - -Linux, in the 2.2 kernel and later kernels, has a "Socket Filter" -mechanism that accepts BPF filters; see the README.linux file for -information on configuring that option. - -Problems, bugs, questions, desirable enhancements, etc. should be sent -to the address "tcpdump-workers@tcpdump.org". Bugs, support requests, -and feature requests may also be submitted on the SourceForge site for -libpcap at - - http://sourceforge.net/projects/libpcap/ - -Source code contributions, etc. should be sent to the email address -"patches@tcpdump.org", or submitted as patches on the SourceForge site -for libpcap. - -Current versions can be found at www.tcpdump.org, or the SourceForge -site for libpcap. - - - The TCPdump team diff --git a/contrib/libpcap-0.8.3/README.DELETED b/contrib/libpcap-0.8.3/README.DELETED deleted file mode 100644 index 1854b7505b..0000000000 --- a/contrib/libpcap-0.8.3/README.DELETED +++ /dev/null @@ -1,22 +0,0 @@ -SUNOS4/ -Win32/ -lbl/ -packaging/ -INSTALL.txt -README.Win32 -README.aix -README.dag -README.hpux -README.linux -README.tru64 -Makefile.in -acconfig.h -aclocal.m4 -config.guess -config.h.in -config.sub -configure -configure.in -install-sh -mkdep -.cvsignore diff --git a/contrib/libpcap-0.8.3/README.DRAGONFLY b/contrib/libpcap-0.8.3/README.DRAGONFLY deleted file mode 100644 index c55b8f9363..0000000000 --- a/contrib/libpcap-0.8.3/README.DRAGONFLY +++ /dev/null @@ -1,6 +0,0 @@ - -Original source can be downloaded from: -http://www.tcpdump.org/release/libpcap-0.8.3.tar.gz -MD5 (libpcap-0.8.3.tar.gz) = 56a9d4615d8354fcfe8cff8c8443c77b - -A list of files and directories removed is in README.DELETED diff --git a/contrib/libpcap-0.8.3/TODO b/contrib/libpcap-0.8.3/TODO deleted file mode 100644 index 633a776a6d..0000000000 --- a/contrib/libpcap-0.8.3/TODO +++ /dev/null @@ -1,42 +0,0 @@ - TODO list for libpcap -======================= - -Important stuff (to be done before the next release) ---------------- - -General - -- configure should not be in the CVS. Most open source projects have an - autogen.sh script to run autoconf etc. after checkout. I think we - should stick to the standard. - -- The source files should be better documented. There is no official - design guideline for what is done where. There should be a common coding - style (okay, you can guess that by looking at the code) and a guide for - what needs to be documented. - -Linux kernel interface - -- Currently there is a race condition in that a socket is activated at the - same time it is opened - before applying a filter. This has to - be corrected so that capture starts when pcap_read is called for the - first time. - -Less urgent items ------------------ - -- Better documentation and cleanup of the interface. I am seeing a few - problems at the first glance which needs fixing: - + pcap_lookupnet makes little to no sense with protocols != IPv4 - + not very well suited for interactive programs (think ethereal). There - should be a way for the application to get a file descriptor which it - has to monitor and a callback in pcap which has to be called on - activity (XXX - "pcap_fileno()" handles the first part, although - "select()" and "poll()" don't work on BPF devices on most BSDs, and - you can call "pcap_dispatch()" as the dispatch routine after putting - the descriptor into non-blocking mode) - + too many functions. There are a lot of functions for everything which - violates the KISS principle. Why do we need pcap_strerror, pcap_perror - and pcap_geterr? - + the manpage has a brief description of each function but where is the - big picture? Seems like you need to buy UNP for that... diff --git a/contrib/libpcap-0.8.3/VERSION b/contrib/libpcap-0.8.3/VERSION deleted file mode 100644 index ee94dd834b..0000000000 --- a/contrib/libpcap-0.8.3/VERSION +++ /dev/null @@ -1 +0,0 @@ -0.8.3 diff --git a/contrib/libpcap-0.8.3/arcnet.h b/contrib/libpcap-0.8.3/arcnet.h deleted file mode 100644 index dce73353e5..0000000000 --- a/contrib/libpcap-0.8.3/arcnet.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 1982, 1986, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the 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. - * - * @(#) $Id: arcnet.h,v 1.2 2001/04/24 02:17:52 guy Exp $ (LBL) - * - * from: NetBSD: if_arc.h,v 1.13 1999/11/19 20:41:19 thorpej Exp - */ - -/* RFC 1051 */ -#define ARCTYPE_IP_OLD 240 /* IP protocol */ -#define ARCTYPE_ARP_OLD 241 /* address resolution protocol */ - -/* RFC 1201 */ -#define ARCTYPE_IP 212 /* IP protocol */ -#define ARCTYPE_ARP 213 /* address resolution protocol */ -#define ARCTYPE_REVARP 214 /* reverse addr resolution protocol */ - -#define ARCTYPE_ATALK 221 /* Appletalk */ -#define ARCTYPE_BANIAN 247 /* Banyan Vines */ -#define ARCTYPE_IPX 250 /* Novell IPX */ - -#define ARCTYPE_INET6 0xc4 /* IPng */ -#define ARCTYPE_DIAGNOSE 0x80 /* as per ANSI/ATA 878.1 */ diff --git a/contrib/libpcap-0.8.3/atmuni31.h b/contrib/libpcap-0.8.3/atmuni31.h deleted file mode 100644 index 877ed6879c..0000000000 --- a/contrib/libpcap-0.8.3/atmuni31.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * 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. - * - * @(#) $Header: /tcpdump/master/libpcap/atmuni31.h,v 1.1 2002/07/11 09:06:32 guy Exp $ (LBL) - */ - -/* Based on UNI3.1 standard by ATM Forum */ - -/* ATM traffic types based on VPI=0 and (the following VCI */ -#define PPC 0x05 /* Point-to-point signal msg */ -#define BCC 0x02 /* Broadcast signal msg */ -#define OAMF4SC 0x03 /* Segment OAM F4 flow cell */ -#define OAMF4EC 0x04 /* End-to-end OAM F4 flow cell */ -#define METAC 0x01 /* Meta signal msg */ -#define ILMIC 0x10 /* ILMI msg */ - -/* Q.2931 signalling messages */ -#define CALL_PROCEED 0x02 /* call proceeding */ -#define CONNECT 0x07 /* connect */ -#define CONNECT_ACK 0x0f /* connect_ack */ -#define SETUP 0x05 /* setup */ -#define RELEASE 0x4d /* release */ -#define RELEASE_DONE 0x5a /* release_done */ -#define RESTART 0x46 /* restart */ -#define RESTART_ACK 0x4e /* restart ack */ -#define STATUS 0x7d /* status */ -#define STATUS_ENQ 0x75 /* status ack */ -#define ADD_PARTY 0x80 /* add party */ -#define ADD_PARTY_ACK 0x81 /* add party ack */ -#define ADD_PARTY_REJ 0x82 /* add party rej */ -#define DROP_PARTY 0x83 /* drop party */ -#define DROP_PARTY_ACK 0x84 /* drop party ack */ - -/* Information Element Parameters in the signalling messages */ -#define CAUSE 0x08 /* cause */ -#define ENDPT_REF 0x54 /* endpoint reference */ -#define AAL_PARA 0x58 /* ATM adaptation layer parameters */ -#define TRAFF_DESCRIP 0x59 /* atm traffic descriptors */ -#define CONNECT_ID 0x5a /* connection identifier */ -#define QOS_PARA 0x5c /* quality of service parameters */ -#define B_HIGHER 0x5d /* broadband higher layer information */ -#define B_BEARER 0x5e /* broadband bearer capability */ -#define B_LOWER 0x5f /* broadband lower information */ -#define CALLING_PARTY 0x6c /* calling party number */ -#define CALLED_PARTY 0x70 /* called party nmber */ - -#define Q2931 0x09 - -/* Q.2931 signalling general messages format */ -#define PROTO_POS 0 /* offset of protocol discriminator */ -#define CALL_REF_POS 2 /* offset of call reference value */ -#define MSG_TYPE_POS 5 /* offset of message type */ -#define MSG_LEN_POS 7 /* offset of mesage length */ -#define IE_BEGIN_POS 9 /* offset of first information element */ - -/* format of signalling messages */ -#define TYPE_POS 0 -#define LEN_POS 2 -#define FIELD_BEGIN_POS 4 diff --git a/contrib/libpcap-0.8.3/bpf/net/bpf_filter.c b/contrib/libpcap-0.8.3/bpf/net/bpf_filter.c deleted file mode 100644 index a2cfbc19df..0000000000 --- a/contrib/libpcap-0.8.3/bpf/net/bpf_filter.c +++ /dev/null @@ -1,565 +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.c 7.5 (Berkeley) 7/15/91 - */ - -#if !(defined(lint) || defined(KERNEL) || defined(_KERNEL)) -static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/libpcap/bpf/net/bpf_filter.c,v 1.43.2.1 2003/11/15 23:26:49 guy Exp $ (LBL)"; -#endif - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifdef WIN32 - -#include - -#else /* WIN32 */ - -#include -#include -#include - -#define SOLARIS (defined(sun) && (defined(__SVR4) || defined(__svr4__))) -#if defined(__hpux) || SOLARIS -# include -# include -# define mbuf msgb -# define m_next b_cont -# define MLEN(m) ((m)->b_wptr - (m)->b_rptr) -# define mtod(m,t) ((t)(m)->b_rptr) -#else -# define MLEN(m) ((m)->m_len) -#endif - -#endif /* WIN32 */ - -#include - -#if !defined(KERNEL) && !defined(_KERNEL) -#include -#endif - -#define int32 bpf_int32 -#define u_int32 bpf_u_int32 - -#ifndef LBL_ALIGN -/* - * XXX - IA-64? If not, this probably won't work on Win64 IA-64 - * systems, unless LBL_ALIGN is defined elsewhere for them. - * XXX - SuperH? If not, this probably won't work on WinCE SuperH - * systems, unless LBL_ALIGN is defined elsewhere for them. - */ -#if defined(sparc) || defined(__sparc__) || defined(mips) || \ - defined(ibm032) || defined(__alpha) || defined(__hpux) || \ - defined(__arm__) -#define LBL_ALIGN -#endif -#endif - -#ifndef LBL_ALIGN -#ifndef WIN32 -#include -#endif - -#define EXTRACT_SHORT(p) ((u_short)ntohs(*(u_short *)p)) -#define EXTRACT_LONG(p) (ntohl(*(u_int32 *)p)) -#else -#define EXTRACT_SHORT(p)\ - ((u_short)\ - ((u_short)*((u_char *)p+0)<<8|\ - (u_short)*((u_char *)p+1)<<0)) -#define EXTRACT_LONG(p)\ - ((u_int32)*((u_char *)p+0)<<24|\ - (u_int32)*((u_char *)p+1)<<16|\ - (u_int32)*((u_char *)p+2)<<8|\ - (u_int32)*((u_char *)p+3)<<0) -#endif - -#if defined(KERNEL) || defined(_KERNEL) -# if !defined(__hpux) && !SOLARIS -#include -# endif -#define MINDEX(len, _m, _k) \ -{ \ - len = MLEN(m); \ - while ((_k) >= len) { \ - (_k) -= len; \ - (_m) = (_m)->m_next; \ - if ((_m) == 0) \ - return 0; \ - len = MLEN(m); \ - } \ -} - -static int -m_xword(m, k, err) - register struct mbuf *m; - register int k, *err; -{ - register int len; - register u_char *cp, *np; - register struct mbuf *m0; - - MINDEX(len, m, k); - cp = mtod(m, u_char *) + k; - if (len - k >= 4) { - *err = 0; - return EXTRACT_LONG(cp); - } - m0 = m->m_next; - if (m0 == 0 || MLEN(m0) + len - k < 4) - goto bad; - *err = 0; - np = mtod(m0, u_char *); - switch (len - k) { - - case 1: - return (cp[0] << 24) | (np[0] << 16) | (np[1] << 8) | np[2]; - - case 2: - return (cp[0] << 24) | (cp[1] << 16) | (np[0] << 8) | np[1]; - - default: - return (cp[0] << 24) | (cp[1] << 16) | (cp[2] << 8) | np[0]; - } - bad: - *err = 1; - return 0; -} - -static int -m_xhalf(m, k, err) - register struct mbuf *m; - register int k, *err; -{ - register int len; - register u_char *cp; - register struct mbuf *m0; - - MINDEX(len, m, k); - cp = mtod(m, u_char *) + k; - if (len - k >= 2) { - *err = 0; - return EXTRACT_SHORT(cp); - } - m0 = m->m_next; - if (m0 == 0) - goto bad; - *err = 0; - return (cp[0] << 8) | mtod(m0, u_char *)[0]; - bad: - *err = 1; - return 0; -} -#endif - -/* - * Execute the filter program starting at pc on the packet p - * wirelen is the length of the original packet - * buflen is the amount of data present - * For the kernel, p is assumed to be a pointer to an mbuf if buflen is 0, - * in all other cases, p is a pointer to a buffer and buflen is its size. - */ -u_int -bpf_filter(pc, p, wirelen, buflen) - register struct bpf_insn *pc; - register u_char *p; - u_int wirelen; - register u_int buflen; -{ - register u_int32 A, X; - register int k; - int32 mem[BPF_MEMWORDS]; -#if defined(KERNEL) || defined(_KERNEL) - struct mbuf *m, *n; - int merr, len; - - if (buflen == 0) { - m = (struct mbuf *)p; - p = mtod(m, u_char *); - buflen = MLEN(m); - } else - m = NULL; -#endif - - if (pc == 0) - /* - * No filter means accept all. - */ - return (u_int)-1; - A = 0; - X = 0; - --pc; - while (1) { - ++pc; - switch (pc->code) { - - default: -#if defined(KERNEL) || defined(_KERNEL) - return 0; -#else - abort(); -#endif - case BPF_RET|BPF_K: - return (u_int)pc->k; - - case BPF_RET|BPF_A: - return (u_int)A; - - case BPF_LD|BPF_W|BPF_ABS: - k = pc->k; - if (k + sizeof(int32) > buflen) { -#if defined(KERNEL) || defined(_KERNEL) - if (m == NULL) - return 0; - A = m_xword(m, k, &merr); - if (merr != 0) - return 0; - continue; -#else - return 0; -#endif - } - A = EXTRACT_LONG(&p[k]); - continue; - - case BPF_LD|BPF_H|BPF_ABS: - k = pc->k; - if (k + sizeof(short) > buflen) { -#if defined(KERNEL) || defined(_KERNEL) - if (m == NULL) - return 0; - A = m_xhalf(m, k, &merr); - if (merr != 0) - return 0; - continue; -#else - return 0; -#endif - } - A = EXTRACT_SHORT(&p[k]); - continue; - - case BPF_LD|BPF_B|BPF_ABS: - k = pc->k; - if (k >= buflen) { -#if defined(KERNEL) || defined(_KERNEL) - if (m == NULL) - return 0; - n = m; - MINDEX(len, n, k); - A = mtod(n, u_char *)[k]; - continue; -#else - return 0; -#endif - } - A = p[k]; - continue; - - case BPF_LD|BPF_W|BPF_LEN: - A = wirelen; - continue; - - case BPF_LDX|BPF_W|BPF_LEN: - X = wirelen; - continue; - - case BPF_LD|BPF_W|BPF_IND: - k = X + pc->k; - if (k + sizeof(int32) > buflen) { -#if defined(KERNEL) || defined(_KERNEL) - if (m == NULL) - return 0; - A = m_xword(m, k, &merr); - if (merr != 0) - return 0; - continue; -#else - return 0; -#endif - } - A = EXTRACT_LONG(&p[k]); - continue; - - case BPF_LD|BPF_H|BPF_IND: - k = X + pc->k; - if (k + sizeof(short) > buflen) { -#if defined(KERNEL) || defined(_KERNEL) - if (m == NULL) - return 0; - A = m_xhalf(m, k, &merr); - if (merr != 0) - return 0; - continue; -#else - return 0; -#endif - } - A = EXTRACT_SHORT(&p[k]); - continue; - - case BPF_LD|BPF_B|BPF_IND: - k = X + pc->k; - if (k >= buflen) { -#if defined(KERNEL) || defined(_KERNEL) - if (m == NULL) - return 0; - n = m; - MINDEX(len, n, k); - A = mtod(n, u_char *)[k]; - continue; -#else - return 0; -#endif - } - A = p[k]; - continue; - - case BPF_LDX|BPF_MSH|BPF_B: - k = pc->k; - if (k >= buflen) { -#if defined(KERNEL) || defined(_KERNEL) - if (m == NULL) - return 0; - n = m; - MINDEX(len, n, k); - X = (mtod(n, char *)[k] & 0xf) << 2; - continue; -#else - return 0; -#endif - } - X = (p[pc->k] & 0xf) << 2; - continue; - - case BPF_LD|BPF_IMM: - A = pc->k; - continue; - - case BPF_LDX|BPF_IMM: - X = pc->k; - continue; - - case BPF_LD|BPF_MEM: - A = mem[pc->k]; - continue; - - case BPF_LDX|BPF_MEM: - X = mem[pc->k]; - continue; - - case BPF_ST: - mem[pc->k] = A; - continue; - - case BPF_STX: - mem[pc->k] = X; - continue; - - case BPF_JMP|BPF_JA: - pc += pc->k; - continue; - - case BPF_JMP|BPF_JGT|BPF_K: - pc += (A > pc->k) ? pc->jt : pc->jf; - continue; - - case BPF_JMP|BPF_JGE|BPF_K: - pc += (A >= pc->k) ? pc->jt : pc->jf; - continue; - - case BPF_JMP|BPF_JEQ|BPF_K: - pc += (A == pc->k) ? pc->jt : pc->jf; - continue; - - case BPF_JMP|BPF_JSET|BPF_K: - pc += (A & pc->k) ? pc->jt : pc->jf; - continue; - - case BPF_JMP|BPF_JGT|BPF_X: - pc += (A > X) ? pc->jt : pc->jf; - continue; - - case BPF_JMP|BPF_JGE|BPF_X: - pc += (A >= X) ? pc->jt : pc->jf; - continue; - - case BPF_JMP|BPF_JEQ|BPF_X: - pc += (A == X) ? pc->jt : pc->jf; - continue; - - case BPF_JMP|BPF_JSET|BPF_X: - pc += (A & X) ? pc->jt : pc->jf; - continue; - - case BPF_ALU|BPF_ADD|BPF_X: - A += X; - continue; - - case BPF_ALU|BPF_SUB|BPF_X: - A -= X; - continue; - - case BPF_ALU|BPF_MUL|BPF_X: - A *= X; - continue; - - case BPF_ALU|BPF_DIV|BPF_X: - if (X == 0) - return 0; - A /= X; - continue; - - case BPF_ALU|BPF_AND|BPF_X: - A &= X; - continue; - - case BPF_ALU|BPF_OR|BPF_X: - A |= X; - continue; - - case BPF_ALU|BPF_LSH|BPF_X: - A <<= X; - continue; - - case BPF_ALU|BPF_RSH|BPF_X: - A >>= X; - continue; - - case BPF_ALU|BPF_ADD|BPF_K: - A += pc->k; - continue; - - case BPF_ALU|BPF_SUB|BPF_K: - A -= pc->k; - continue; - - case BPF_ALU|BPF_MUL|BPF_K: - A *= pc->k; - continue; - - case BPF_ALU|BPF_DIV|BPF_K: - A /= pc->k; - continue; - - case BPF_ALU|BPF_AND|BPF_K: - A &= pc->k; - continue; - - case BPF_ALU|BPF_OR|BPF_K: - A |= pc->k; - continue; - - case BPF_ALU|BPF_LSH|BPF_K: - A <<= pc->k; - continue; - - case BPF_ALU|BPF_RSH|BPF_K: - A >>= pc->k; - continue; - - case BPF_ALU|BPF_NEG: - A = -A; - continue; - - case BPF_MISC|BPF_TAX: - X = A; - continue; - - case BPF_MISC|BPF_TXA: - A = X; - continue; - } - } -} - - -/* - * Return true if the 'fcode' is a valid filter program. - * The constraints are that each jump be forward and to a valid - * code. The code must terminate with either an accept or reject. - * 'valid' is an array for use by the routine (it must be at least - * 'len' bytes long). - * - * The kernel needs to be able to verify an application's filter code. - * Otherwise, a bogus program could easily crash the system. - */ -int -bpf_validate(f, len) - struct bpf_insn *f; - int len; -{ - register int i; - register struct bpf_insn *p; - - for (i = 0; i < len; ++i) { - /* - * Check that that jumps are forward, and within - * the code block. - */ - p = &f[i]; - if (BPF_CLASS(p->code) == BPF_JMP) { - register int from = i + 1; - - if (BPF_OP(p->code) == BPF_JA) { - if (from + p->k >= (unsigned)len) - return 0; - } - else if (from + p->jt >= len || from + p->jf >= len) - return 0; - } - /* - * Check that memory operations use valid addresses. - */ - if ((BPF_CLASS(p->code) == BPF_ST || - (BPF_CLASS(p->code) == BPF_LD && - (p->code & 0xe0) == BPF_MEM)) && - (p->k >= BPF_MEMWORDS || p->k < 0)) - return 0; - /* - * Check for constant division by 0. - */ - if (p->code == (BPF_ALU|BPF_DIV|BPF_K) && p->k == 0) - return 0; - } - return BPF_CLASS(f[len - 1].code) == BPF_RET; -} diff --git a/contrib/libpcap-0.8.3/bpf_dump.c b/contrib/libpcap-0.8.3/bpf_dump.c deleted file mode 100644 index 99aa0a0157..0000000000 --- a/contrib/libpcap-0.8.3/bpf_dump.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 1992, 1993, 1994, 1995, 1996 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that: (1) source code distributions - * retain the above copyright notice and this paragraph in its entirety, (2) - * distributions including binary code include the above copyright notice and - * this paragraph in its entirety in the documentation or other materials - * provided with the distribution, and (3) all advertising materials mentioning - * features or use of this software display the following acknowledgement: - * ``This product includes software developed by the University of California, - * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of - * the University nor the names of its contributors may be used to endorse - * or promote products derived from this software without specific prior - * written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ -#ifndef lint -static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/libpcap/bpf_dump.c,v 1.13.2.1 2003/11/15 23:26:37 guy Exp $ (LBL)"; -#endif - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include - -void -bpf_dump(struct bpf_program *p, int option) -{ - struct bpf_insn *insn; - int i; - int n = p->bf_len; - - insn = p->bf_insns; - if (option > 2) { - printf("%d\n", n); - for (i = 0; i < n; ++insn, ++i) { - printf("%u %u %u %u\n", insn->code, - insn->jt, insn->jf, insn->k); - } - return ; - } - if (option > 1) { - for (i = 0; i < n; ++insn, ++i) - printf("{ 0x%x, %d, %d, 0x%08x },\n", - insn->code, insn->jt, insn->jf, insn->k); - return; - } - for (i = 0; i < n; ++insn, ++i) { -#ifdef BDEBUG - extern int bids[]; - printf(bids[i] > 0 ? "[%02d]" : " -- ", bids[i] - 1); -#endif - puts(bpf_image(insn, i)); - } -} diff --git a/contrib/libpcap-0.8.3/bpf_image.c b/contrib/libpcap-0.8.3/bpf_image.c deleted file mode 100644 index b1d76fe7d8..0000000000 --- a/contrib/libpcap-0.8.3/bpf_image.c +++ /dev/null @@ -1,288 +0,0 @@ -/* - * Copyright (c) 1990, 1991, 1992, 1994, 1995, 1996 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that: (1) source code distributions - * retain the above copyright notice and this paragraph in its entirety, (2) - * distributions including binary code include the above copyright notice and - * this paragraph in its entirety in the documentation or other materials - * provided with the distribution, and (3) all advertising materials mentioning - * features or use of this software display the following acknowledgement: - * ``This product includes software developed by the University of California, - * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of - * the University nor the names of its contributors may be used to endorse - * or promote products derived from this software without specific prior - * written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#ifndef lint -static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/libpcap/bpf_image.c,v 1.25.2.1 2003/11/15 23:26:38 guy Exp $ (LBL)"; -#endif - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include - -#include "pcap-int.h" - -#ifdef HAVE_OS_PROTO_H -#include "os-proto.h" -#endif - -char * -bpf_image(p, n) - struct bpf_insn *p; - int n; -{ - int v; - char *fmt, *op; - static char image[256]; - char operand[64]; - - v = p->k; - switch (p->code) { - - default: - op = "unimp"; - fmt = "0x%x"; - v = p->code; - break; - - case BPF_RET|BPF_K: - op = "ret"; - fmt = "#%d"; - break; - - case BPF_RET|BPF_A: - op = "ret"; - fmt = ""; - break; - - case BPF_LD|BPF_W|BPF_ABS: - op = "ld"; - fmt = "[%d]"; - break; - - case BPF_LD|BPF_H|BPF_ABS: - op = "ldh"; - fmt = "[%d]"; - break; - - case BPF_LD|BPF_B|BPF_ABS: - op = "ldb"; - fmt = "[%d]"; - break; - - case BPF_LD|BPF_W|BPF_LEN: - op = "ld"; - fmt = "#pktlen"; - break; - - case BPF_LD|BPF_W|BPF_IND: - op = "ld"; - fmt = "[x + %d]"; - break; - - case BPF_LD|BPF_H|BPF_IND: - op = "ldh"; - fmt = "[x + %d]"; - break; - - case BPF_LD|BPF_B|BPF_IND: - op = "ldb"; - fmt = "[x + %d]"; - break; - - case BPF_LD|BPF_IMM: - op = "ld"; - fmt = "#0x%x"; - break; - - case BPF_LDX|BPF_IMM: - op = "ldx"; - fmt = "#0x%x"; - break; - - case BPF_LDX|BPF_MSH|BPF_B: - op = "ldxb"; - fmt = "4*([%d]&0xf)"; - break; - - case BPF_LD|BPF_MEM: - op = "ld"; - fmt = "M[%d]"; - break; - - case BPF_LDX|BPF_MEM: - op = "ldx"; - fmt = "M[%d]"; - break; - - case BPF_ST: - op = "st"; - fmt = "M[%d]"; - break; - - case BPF_STX: - op = "stx"; - fmt = "M[%d]"; - break; - - case BPF_JMP|BPF_JA: - op = "ja"; - fmt = "%d"; - v = n + 1 + p->k; - break; - - case BPF_JMP|BPF_JGT|BPF_K: - op = "jgt"; - fmt = "#0x%x"; - break; - - case BPF_JMP|BPF_JGE|BPF_K: - op = "jge"; - fmt = "#0x%x"; - break; - - case BPF_JMP|BPF_JEQ|BPF_K: - op = "jeq"; - fmt = "#0x%x"; - break; - - case BPF_JMP|BPF_JSET|BPF_K: - op = "jset"; - fmt = "#0x%x"; - break; - - case BPF_JMP|BPF_JGT|BPF_X: - op = "jgt"; - fmt = "x"; - break; - - case BPF_JMP|BPF_JGE|BPF_X: - op = "jge"; - fmt = "x"; - break; - - case BPF_JMP|BPF_JEQ|BPF_X: - op = "jeq"; - fmt = "x"; - break; - - case BPF_JMP|BPF_JSET|BPF_X: - op = "jset"; - fmt = "x"; - break; - - case BPF_ALU|BPF_ADD|BPF_X: - op = "add"; - fmt = "x"; - break; - - case BPF_ALU|BPF_SUB|BPF_X: - op = "sub"; - fmt = "x"; - break; - - case BPF_ALU|BPF_MUL|BPF_X: - op = "mul"; - fmt = "x"; - break; - - case BPF_ALU|BPF_DIV|BPF_X: - op = "div"; - fmt = "x"; - break; - - case BPF_ALU|BPF_AND|BPF_X: - op = "and"; - fmt = "x"; - break; - - case BPF_ALU|BPF_OR|BPF_X: - op = "or"; - fmt = "x"; - break; - - case BPF_ALU|BPF_LSH|BPF_X: - op = "lsh"; - fmt = "x"; - break; - - case BPF_ALU|BPF_RSH|BPF_X: - op = "rsh"; - fmt = "x"; - break; - - case BPF_ALU|BPF_ADD|BPF_K: - op = "add"; - fmt = "#%d"; - break; - - case BPF_ALU|BPF_SUB|BPF_K: - op = "sub"; - fmt = "#%d"; - break; - - case BPF_ALU|BPF_MUL|BPF_K: - op = "mul"; - fmt = "#%d"; - break; - - case BPF_ALU|BPF_DIV|BPF_K: - op = "div"; - fmt = "#%d"; - break; - - case BPF_ALU|BPF_AND|BPF_K: - op = "and"; - fmt = "#0x%x"; - break; - - case BPF_ALU|BPF_OR|BPF_K: - op = "or"; - fmt = "#0x%x"; - break; - - case BPF_ALU|BPF_LSH|BPF_K: - op = "lsh"; - fmt = "#%d"; - break; - - case BPF_ALU|BPF_RSH|BPF_K: - op = "rsh"; - fmt = "#%d"; - break; - - case BPF_ALU|BPF_NEG: - op = "neg"; - fmt = ""; - break; - - case BPF_MISC|BPF_TAX: - op = "tax"; - fmt = ""; - break; - - case BPF_MISC|BPF_TXA: - op = "txa"; - fmt = ""; - break; - } - (void)snprintf(operand, sizeof operand, fmt, v); - (void)snprintf(image, sizeof image, - (BPF_CLASS(p->code) == BPF_JMP && - BPF_OP(p->code) != BPF_JA) ? - "(%03d) %-8s %-16s jt %d\tjf %d" - : "(%03d) %-8s %s", - n, op, operand, n + 1 + p->jt, n + 1 + p->jf); - return image; -} diff --git a/contrib/libpcap-0.8.3/etherent.c b/contrib/libpcap-0.8.3/etherent.c deleted file mode 100644 index 11f34f2e16..0000000000 --- a/contrib/libpcap-0.8.3/etherent.c +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (c) 1990, 1993, 1994, 1995, 1996 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that: (1) source code distributions - * retain the above copyright notice and this paragraph in its entirety, (2) - * distributions including binary code include the above copyright notice and - * this paragraph in its entirety in the documentation or other materials - * provided with the distribution, and (3) all advertising materials mentioning - * features or use of this software display the following acknowledgement: - * ``This product includes software developed by the University of California, - * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of - * the University nor the names of its contributors may be used to endorse - * or promote products derived from this software without specific prior - * written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#ifndef lint -static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/libpcap/etherent.c,v 1.21.6.1 2003/11/15 23:26:38 guy Exp $ (LBL)"; -#endif - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include -#include -#include -#include - -#include "pcap-int.h" - -#include - -#ifdef HAVE_OS_PROTO_H -#include "os-proto.h" -#endif - -static inline int xdtoi(int); -static inline int skip_space(FILE *); -static inline int skip_line(FILE *); - -/* Hex digit to integer. */ -static inline int -xdtoi(c) - register int c; -{ - if (isdigit(c)) - return c - '0'; - else if (islower(c)) - return c - 'a' + 10; - else - return c - 'A' + 10; -} - -static inline int -skip_space(f) - FILE *f; -{ - int c; - - do { - c = getc(f); - } while (isspace(c) && c != '\n'); - - return c; -} - -static inline int -skip_line(f) - FILE *f; -{ - int c; - - do - c = getc(f); - while (c != '\n' && c != EOF); - - return c; -} - -struct pcap_etherent * -pcap_next_etherent(FILE *fp) -{ - register int c, d, i; - char *bp; - static struct pcap_etherent e; - - memset((char *)&e, 0, sizeof(e)); - do { - /* Find addr */ - c = skip_space(fp); - if (c == '\n') - continue; - - /* If this is a comment, or first thing on line - cannot be etehrnet address, skip the line. */ - if (!isxdigit(c)) { - c = skip_line(fp); - continue; - } - - /* must be the start of an address */ - for (i = 0; i < 6; i += 1) { - d = xdtoi(c); - c = getc(fp); - if (isxdigit(c)) { - d <<= 4; - d |= xdtoi(c); - c = getc(fp); - } - e.addr[i] = d; - if (c != ':') - break; - c = getc(fp); - } - if (c == EOF) - break; - - /* Must be whitespace */ - if (!isspace(c)) { - c = skip_line(fp); - continue; - } - c = skip_space(fp); - - /* hit end of line... */ - if (c == '\n') - continue; - - if (c == '#') { - c = skip_line(fp); - continue; - } - - /* pick up name */ - bp = e.name; - /* Use 'd' to prevent buffer overflow. */ - d = sizeof(e.name) - 1; - do { - *bp++ = c; - c = getc(fp); - } while (!isspace(c) && c != EOF && --d > 0); - *bp = '\0'; - - /* Eat trailing junk */ - if (c != '\n') - (void)skip_line(fp); - - return &e; - - } while (c != EOF); - - return (NULL); -} diff --git a/contrib/libpcap-0.8.3/ethertype.h b/contrib/libpcap-0.8.3/ethertype.h deleted file mode 100644 index 3af5576e81..0000000000 --- a/contrib/libpcap-0.8.3/ethertype.h +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (c) 1993, 1994, 1996 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that: (1) source code distributions - * retain the above copyright notice and this paragraph in its entirety, (2) - * distributions including binary code include the above copyright notice and - * this paragraph in its entirety in the documentation or other materials - * provided with the distribution, and (3) all advertising materials mentioning - * features or use of this software display the following acknowledgement: - * ``This product includes software developed by the University of California, - * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of - * the University nor the names of its contributors may be used to endorse - * or promote products derived from this software without specific prior - * written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * @(#) $Header: /tcpdump/master/libpcap/ethertype.h,v 1.12 2001/01/14 21:26:52 guy Exp $ (LBL) - */ - -/* - * Ethernet types. - * - * We wrap the declarations with #ifdef, so that if a file includes - * , which may declare some of these, we don't - * get a bunch of complaints from the C compiler about redefinitions - * of these values. - * - * We declare all of them here so that no file has to include - * if all it needs are ETHERTYPE_ values. - */ - -#ifndef ETHERTYPE_PUP -#define ETHERTYPE_PUP 0x0200 /* PUP protocol */ -#endif -#ifndef ETHERTYPE_IP -#define ETHERTYPE_IP 0x0800 /* IP protocol */ -#endif -#ifndef ETHERTYPE_ARP -#define ETHERTYPE_ARP 0x0806 /* Addr. resolution protocol */ -#endif -#ifndef ETHERTYPE_REVARP -#define ETHERTYPE_REVARP 0x8035 /* reverse Addr. resolution protocol */ -#endif -#ifndef ETHERTYPE_NS -#define ETHERTYPE_NS 0x0600 -#endif -#ifndef ETHERTYPE_SPRITE -#define ETHERTYPE_SPRITE 0x0500 -#endif -#ifndef ETHERTYPE_TRAIL -#define ETHERTYPE_TRAIL 0x1000 -#endif -#ifndef ETHERTYPE_MOPDL -#define ETHERTYPE_MOPDL 0x6001 -#endif -#ifndef ETHERTYPE_MOPRC -#define ETHERTYPE_MOPRC 0x6002 -#endif -#ifndef ETHERTYPE_DN -#define ETHERTYPE_DN 0x6003 -#endif -#ifndef ETHERTYPE_LAT -#define ETHERTYPE_LAT 0x6004 -#endif -#ifndef ETHERTYPE_SCA -#define ETHERTYPE_SCA 0x6007 -#endif -#ifndef ETHERTYPE_REVARP -#define ETHERTYPE_REVARP 0x8035 -#endif -#ifndef ETHERTYPE_LANBRIDGE -#define ETHERTYPE_LANBRIDGE 0x8038 -#endif -#ifndef ETHERTYPE_DECDNS -#define ETHERTYPE_DECDNS 0x803c -#endif -#ifndef ETHERTYPE_DECDTS -#define ETHERTYPE_DECDTS 0x803e -#endif -#ifndef ETHERTYPE_VEXP -#define ETHERTYPE_VEXP 0x805b -#endif -#ifndef ETHERTYPE_VPROD -#define ETHERTYPE_VPROD 0x805c -#endif -#ifndef ETHERTYPE_ATALK -#define ETHERTYPE_ATALK 0x809b -#endif -#ifndef ETHERTYPE_AARP -#define ETHERTYPE_AARP 0x80f3 -#endif -#ifndef ETHERTYPE_8021Q -#define ETHERTYPE_8021Q 0x8100 -#endif -#ifndef ETHERTYPE_IPX -#define ETHERTYPE_IPX 0x8137 -#endif -#ifndef ETHERTYPE_IPV6 -#define ETHERTYPE_IPV6 0x86dd -#endif -#ifndef ETHERTYPE_LOOPBACK -#define ETHERTYPE_LOOPBACK 0x9000 -#endif diff --git a/contrib/libpcap-0.8.3/fad-getad.c b/contrib/libpcap-0.8.3/fad-getad.c deleted file mode 100644 index 55a6bf13b7..0000000000 --- a/contrib/libpcap-0.8.3/fad-getad.c +++ /dev/null @@ -1,243 +0,0 @@ -/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */ -/* - * Copyright (c) 1994, 1995, 1996, 1997, 1998 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the Computer Systems - * Engineering Group at Lawrence Berkeley Laboratory. - * 4. Neither the name of the University nor of the Laboratory may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef lint -static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/libpcap/fad-getad.c,v 1.7.2.2 2004/03/11 23:04:52 guy Exp $ (LBL)"; -#endif - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include - -#include - -#include -#include -#include -#include - -#include "pcap-int.h" - -#ifdef HAVE_OS_PROTO_H -#include "os-proto.h" -#endif - -/* - * This is fun. - * - * In older BSD systems, socket addresses were fixed-length, and - * "sizeof (struct sockaddr)" gave the size of the structure. - * All addresses fit within a "struct sockaddr". - * - * In newer BSD systems, the socket address is variable-length, and - * there's an "sa_len" field giving the length of the structure; - * this allows socket addresses to be longer than 2 bytes of family - * and 14 bytes of data. - * - * Some commercial UNIXes use the old BSD scheme, some use the RFC 2553 - * variant of the old BSD scheme (with "struct sockaddr_storage" rather - * than "struct sockaddr"), and some use the new BSD scheme. - * - * Some versions of GNU libc use neither scheme, but has an "SA_LEN()" - * macro that determines the size based on the address family. Other - * versions don't have "SA_LEN()" (as it was in drafts of RFC 2553 - * but not in the final version). On the latter systems, we explicitly - * check the AF_ type to determine the length; we assume that on - * all those systems we have "struct sockaddr_storage". - */ -#ifndef SA_LEN -#ifdef HAVE_SOCKADDR_SA_LEN -#define SA_LEN(addr) ((addr)->sa_len) -#else /* HAVE_SOCKADDR_SA_LEN */ -#ifdef HAVE_SOCKADDR_STORAGE -static size_t -get_sa_len(struct sockaddr *addr) -{ - switch (addr->sa_family) { - -#ifdef AF_INET - case AF_INET: - return (sizeof (struct sockaddr_in)); -#endif - -#ifdef AF_INET6 - case AF_INET6: - return (sizeof (struct sockaddr_in6)); -#endif - - default: - return (sizeof (struct sockaddr)); - } -} -#define SA_LEN(addr) (get_sa_len(addr)) -#else /* HAVE_SOCKADDR_STORAGE */ -#define SA_LEN(addr) (sizeof (struct sockaddr)) -#endif /* HAVE_SOCKADDR_STORAGE */ -#endif /* HAVE_SOCKADDR_SA_LEN */ -#endif /* SA_LEN */ - -/* - * Get a list of all interfaces that are up and that we can open. - * Returns -1 on error, 0 otherwise. - * The list, as returned through "alldevsp", may be null if no interfaces - * were up and could be opened. - * - * This is the implementation used on platforms that have "getifaddrs()". - */ -int -pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) -{ - pcap_if_t *devlist = NULL; - struct ifaddrs *ifap, *ifa; - struct sockaddr *addr, *netmask, *broadaddr, *dstaddr; - size_t addr_size, broadaddr_size, dstaddr_size; - int ret = 0; - - /* - * Get the list of interface addresses. - * - * Note: this won't return information about interfaces - * with no addresses; are there any such interfaces - * that would be capable of receiving packets? - * (Interfaces incapable of receiving packets aren't - * very interesting from libpcap's point of view.) - * - * LAN interfaces will probably have link-layer - * addresses; I don't know whether all implementations - * of "getifaddrs()" now, or in the future, will return - * those. - */ - if (getifaddrs(&ifap) != 0) { - (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, - "getifaddrs: %s", pcap_strerror(errno)); - return (-1); - } - for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) { - /* - * Is this interface up? - */ - if (!(ifa->ifa_flags & IFF_UP)) { - /* - * No, so don't add it to the list. - */ - continue; - } - - /* - * "ifa_addr" was apparently null on at least one - * interface on some system. - * - * "ifa_broadaddr" may be non-null even on - * non-broadcast interfaces, and was null on - * at least one OpenBSD 3.4 system on at least - * one interface with IFF_BROADCAST set. - * - * "ifa_dstaddr" was, on at least one FreeBSD 4.1 - * system, non-null on a non-point-to-point - * interface. - * - * Therefore, we supply the address and netmask only - * if "ifa_addr" is non-null (if there's no address, - * there's obviously no netmask), and supply the - * broadcast and destination addresses if the appropriate - * flag is set *and* the appropriate "ifa_" entry doesn't - * evaluate to a null pointer. - */ - if (ifa->ifa_addr != NULL) { - addr = ifa->ifa_addr; - addr_size = SA_LEN(addr); - netmask = ifa->ifa_netmask; - } else { - addr = NULL; - addr_size = 0; - netmask = NULL; - } - if (ifa->ifa_flags & IFF_BROADCAST && - ifa->ifa_broadaddr != NULL) { - broadaddr = ifa->ifa_broadaddr; - broadaddr_size = SA_LEN(broadaddr); - } else { - broadaddr = NULL; - broadaddr_size = 0; - } - if (ifa->ifa_flags & IFF_POINTOPOINT && - ifa->ifa_dstaddr != NULL) { - dstaddr = ifa->ifa_dstaddr; - dstaddr_size = SA_LEN(ifa->ifa_dstaddr); - } else { - dstaddr = NULL; - dstaddr_size = 0; - } - - /* - * Add information for this address to the list. - */ - if (add_addr_to_iflist(&devlist, ifa->ifa_name, - ifa->ifa_flags, addr, addr_size, netmask, addr_size, - broadaddr, broadaddr_size, dstaddr, dstaddr_size, - errbuf) < 0) { - ret = -1; - break; - } - } - - freeifaddrs(ifap); - - if (ret != -1) { - /* - * We haven't had any errors yet; do any platform-specific - * operations to add devices. - */ - if (pcap_platform_finddevs(&devlist, errbuf) < 0) - ret = -1; - } - - if (ret == -1) { - /* - * We had an error; free the list we've been constructing. - */ - if (devlist != NULL) { - pcap_freealldevs(devlist); - devlist = NULL; - } - } - - *alldevsp = devlist; - return (ret); -} diff --git a/contrib/libpcap-0.8.3/fad-gifc.c b/contrib/libpcap-0.8.3/fad-gifc.c deleted file mode 100644 index 0214d59d02..0000000000 --- a/contrib/libpcap-0.8.3/fad-gifc.c +++ /dev/null @@ -1,502 +0,0 @@ -/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */ -/* - * Copyright (c) 1994, 1995, 1996, 1997, 1998 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the Computer Systems - * Engineering Group at Lawrence Berkeley Laboratory. - * 4. Neither the name of the University nor of the Laboratory may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef lint -static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/libpcap/fad-gifc.c,v 1.4.2.1 2003/11/15 23:26:39 guy Exp $ (LBL)"; -#endif - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#include -#ifdef HAVE_SYS_SOCKIO_H -#include -#endif -#include /* concession to AIX */ - -struct mbuf; /* Squelch compiler warnings on some platforms for */ -struct rtentry; /* declarations in */ -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "pcap-int.h" - -#ifdef HAVE_OS_PROTO_H -#include "os-proto.h" -#endif - -/* - * This is fun. - * - * In older BSD systems, socket addresses were fixed-length, and - * "sizeof (struct sockaddr)" gave the size of the structure. - * All addresses fit within a "struct sockaddr". - * - * In newer BSD systems, the socket address is variable-length, and - * there's an "sa_len" field giving the length of the structure; - * this allows socket addresses to be longer than 2 bytes of family - * and 14 bytes of data. - * - * Some commercial UNIXes use the old BSD scheme, some use the RFC 2553 - * variant of the old BSD scheme (with "struct sockaddr_storage" rather - * than "struct sockaddr"), and some use the new BSD scheme. - * - * Some versions of GNU libc use neither scheme, but has an "SA_LEN()" - * macro that determines the size based on the address family. Other - * versions don't have "SA_LEN()" (as it was in drafts of RFC 2553 - * but not in the final version). - * - * We assume that a UNIX that doesn't have "getifaddrs()" and doesn't have - * SIOCGLIFCONF, but has SIOCGIFCONF, uses "struct sockaddr" for the - * address in an entry returned by SIOCGIFCONF. - */ -#ifndef SA_LEN -#ifdef HAVE_SOCKADDR_SA_LEN -#define SA_LEN(addr) ((addr)->sa_len) -#else /* HAVE_SOCKADDR_SA_LEN */ -#define SA_LEN(addr) (sizeof (struct sockaddr)) -#endif /* HAVE_SOCKADDR_SA_LEN */ -#endif /* SA_LEN */ - -#ifdef HAVE_PROC_NET_DEV -/* - * Get from "/proc/net/dev" all interfaces listed there; if they're - * already in the list of interfaces we have, that won't add another - * instance, but if they're not, that'll add them. - * - * We don't bother getting any addresses for them; it appears you can't - * use SIOCGIFADDR on Linux to get IPv6 addresses for interfaces, and, - * although some other types of addresses can be fetched with SIOCGIFADDR, - * we don't bother with them for now. - * - * We also don't fail if we couldn't open "/proc/net/dev"; we just leave - * the list of interfaces as is. - */ -static int -scan_proc_net_dev(pcap_if_t **devlistp, int fd, char *errbuf) -{ - FILE *proc_net_f; - char linebuf[512]; - int linenum; - unsigned char *p; - char name[512]; /* XXX - pick a size */ - char *q, *saveq; - struct ifreq ifrflags; - int ret = 0; - - proc_net_f = fopen("/proc/net/dev", "r"); - if (proc_net_f == NULL) - return (0); - - for (linenum = 1; - fgets(linebuf, sizeof linebuf, proc_net_f) != NULL; linenum++) { - /* - * Skip the first two lines - they're headers. - */ - if (linenum <= 2) - continue; - - p = &linebuf[0]; - - /* - * Skip leading white space. - */ - while (*p != '\0' && isspace(*p)) - p++; - if (*p == '\0' || *p == '\n') - continue; /* blank line */ - - /* - * Get the interface name. - */ - q = &name[0]; - while (*p != '\0' && !isspace(*p)) { - if (*p == ':') { - /* - * This could be the separator between a - * name and an alias number, or it could be - * the separator between a name with no - * alias number and the next field. - * - * If there's a colon after digits, it - * separates the name and the alias number, - * otherwise it separates the name and the - * next field. - */ - saveq = q; - while (isdigit(*p)) - *q++ = *p++; - if (*p != ':') { - /* - * That was the next field, - * not the alias number. - */ - q = saveq; - } - break; - } else - *q++ = *p++; - } - *q = '\0'; - - /* - * Get the flags for this interface, and skip it if - * it's not up. - */ - strncpy(ifrflags.ifr_name, name, sizeof(ifrflags.ifr_name)); - if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifrflags) < 0) { - if (errno == ENXIO) - continue; - (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, - "SIOCGIFFLAGS: %.*s: %s", - (int)sizeof(ifrflags.ifr_name), - ifrflags.ifr_name, - pcap_strerror(errno)); - ret = -1; - break; - } - if (!(ifrflags.ifr_flags & IFF_UP)) - continue; - - /* - * Add an entry for this interface, with no addresses. - */ - if (pcap_add_if(devlistp, name, ifrflags.ifr_flags, NULL, - errbuf) == -1) { - /* - * Failure. - */ - ret = -1; - break; - } - } - if (ret != -1) { - /* - * Well, we didn't fail for any other reason; did we - * fail due to an error reading the file? - */ - if (ferror(proc_net_f)) { - (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, - "Error reading /proc/net/dev: %s", - pcap_strerror(errno)); - ret = -1; - } - } - - (void)fclose(proc_net_f); - return (ret); -} -#endif /* HAVE_PROC_NET_DEV */ - -/* - * Get a list of all interfaces that are up and that we can open. - * Returns -1 on error, 0 otherwise. - * The list, as returned through "alldevsp", may be null if no interfaces - * were up and could be opened. - * - * This is the implementation used on platforms that have SIOCGIFCONF but - * don't have any other mechanism for getting a list of interfaces. - * - * XXX - or platforms that have other, better mechanisms but for which - * we don't yet have code to use that mechanism; I think there's a better - * way on Linux, for example. - */ -int -pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) -{ - pcap_if_t *devlist = NULL; - register int fd; - register struct ifreq *ifrp, *ifend, *ifnext; - int n; - struct ifconf ifc; - char *buf = NULL; - unsigned buf_size; - struct ifreq ifrflags, ifrnetmask, ifrbroadaddr, ifrdstaddr; - struct sockaddr *netmask, *broadaddr, *dstaddr; - size_t netmask_size, broadaddr_size, dstaddr_size; - int ret = 0; - - /* - * Create a socket from which to fetch the list of interfaces. - */ - fd = socket(AF_INET, SOCK_DGRAM, 0); - if (fd < 0) { - (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, - "socket: %s", pcap_strerror(errno)); - return (-1); - } - - /* - * Start with an 8K buffer, and keep growing the buffer until - * we get the entire interface list or fail to get it for some - * reason other than EINVAL (which is presumed here to mean - * "buffer is too small"). - */ - buf_size = 8192; - for (;;) { - buf = malloc(buf_size); - if (buf == NULL) { - (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, - "malloc: %s", pcap_strerror(errno)); - (void)close(fd); - return (-1); - } - - ifc.ifc_len = buf_size; - ifc.ifc_buf = buf; - memset(buf, 0, buf_size); - if (ioctl(fd, SIOCGIFCONF, (char *)&ifc) < 0 - && errno != EINVAL) { - (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, - "SIOCGIFCONF: %s", pcap_strerror(errno)); - (void)close(fd); - free(buf); - return (-1); - } - if (ifc.ifc_len < buf_size) - break; - free(buf); - buf_size *= 2; - } - - ifrp = (struct ifreq *)buf; - ifend = (struct ifreq *)(buf + ifc.ifc_len); - - for (; ifrp < ifend; ifrp = ifnext) { - /* - * XXX - what if this isn't an IPv4 address? Can - * we still get the netmask, etc. with ioctls on - * an IPv4 socket? - * - * The answer is probably platform-dependent, and - * if the answer is "no" on more than one platform, - * the way you work around it is probably platform- - * dependent as well. - */ - n = SA_LEN(&ifrp->ifr_addr) + sizeof(ifrp->ifr_name); - if (n < sizeof(*ifrp)) - ifnext = ifrp + 1; - else - ifnext = (struct ifreq *)((char *)ifrp + n); - - /* - * Get the flags for this interface, and skip it if it's - * not up. - */ - strncpy(ifrflags.ifr_name, ifrp->ifr_name, - sizeof(ifrflags.ifr_name)); - if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifrflags) < 0) { - if (errno == ENXIO) - continue; - (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, - "SIOCGIFFLAGS: %.*s: %s", - (int)sizeof(ifrflags.ifr_name), - ifrflags.ifr_name, - pcap_strerror(errno)); - ret = -1; - break; - } - if (!(ifrflags.ifr_flags & IFF_UP)) - continue; - - /* - * Get the netmask for this address on this interface. - */ - strncpy(ifrnetmask.ifr_name, ifrp->ifr_name, - sizeof(ifrnetmask.ifr_name)); - memcpy(&ifrnetmask.ifr_addr, &ifrp->ifr_addr, - sizeof(ifrnetmask.ifr_addr)); - if (ioctl(fd, SIOCGIFNETMASK, (char *)&ifrnetmask) < 0) { - if (errno == EADDRNOTAVAIL) { - /* - * Not available. - */ - netmask = NULL; - netmask_size = 0; - } else { - (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, - "SIOCGIFNETMASK: %.*s: %s", - (int)sizeof(ifrnetmask.ifr_name), - ifrnetmask.ifr_name, - pcap_strerror(errno)); - ret = -1; - break; - } - } else { - netmask = &ifrnetmask.ifr_addr; - netmask_size = SA_LEN(netmask); - } - - /* - * Get the broadcast address for this address on this - * interface (if any). - */ - if (ifrflags.ifr_flags & IFF_BROADCAST) { - strncpy(ifrbroadaddr.ifr_name, ifrp->ifr_name, - sizeof(ifrbroadaddr.ifr_name)); - memcpy(&ifrbroadaddr.ifr_addr, &ifrp->ifr_addr, - sizeof(ifrbroadaddr.ifr_addr)); - if (ioctl(fd, SIOCGIFBRDADDR, - (char *)&ifrbroadaddr) < 0) { - if (errno == EADDRNOTAVAIL) { - /* - * Not available. - */ - broadaddr = NULL; - broadaddr_size = 0; - } else { - (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, - "SIOCGIFBRDADDR: %.*s: %s", - (int)sizeof(ifrbroadaddr.ifr_name), - ifrbroadaddr.ifr_name, - pcap_strerror(errno)); - ret = -1; - break; - } - } else { - broadaddr = &ifrbroadaddr.ifr_broadaddr; - broadaddr_size = SA_LEN(broadaddr); - } - } else { - /* - * Not a broadcast interface, so no broadcast - * address. - */ - broadaddr = NULL; - broadaddr_size = 0; - } - - /* - * Get the destination address for this address on this - * interface (if any). - */ - if (ifrflags.ifr_flags & IFF_POINTOPOINT) { - strncpy(ifrdstaddr.ifr_name, ifrp->ifr_name, - sizeof(ifrdstaddr.ifr_name)); - memcpy(&ifrdstaddr.ifr_addr, &ifrp->ifr_addr, - sizeof(ifrdstaddr.ifr_addr)); - if (ioctl(fd, SIOCGIFDSTADDR, - (char *)&ifrdstaddr) < 0) { - if (errno == EADDRNOTAVAIL) { - /* - * Not available. - */ - dstaddr = NULL; - dstaddr_size = 0; - } else { - (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, - "SIOCGIFDSTADDR: %.*s: %s", - (int)sizeof(ifrdstaddr.ifr_name), - ifrdstaddr.ifr_name, - pcap_strerror(errno)); - ret = -1; - break; - } - } else { - dstaddr = &ifrdstaddr.ifr_dstaddr; - dstaddr_size = SA_LEN(dstaddr); - } - } else { - /* - * Not a point-to-point interface, so no destination - * address. - */ - dstaddr = NULL; - dstaddr_size = 0; - } - - /* - * Add information for this address to the list. - */ - if (add_addr_to_iflist(&devlist, ifrp->ifr_name, - ifrflags.ifr_flags, &ifrp->ifr_addr, - SA_LEN(&ifrp->ifr_addr), netmask, netmask_size, - broadaddr, broadaddr_size, dstaddr, dstaddr_size, - errbuf) < 0) { - ret = -1; - break; - } - } - free(buf); - -#ifdef HAVE_PROC_NET_DEV - if (ret != -1) { - /* - * We haven't had any errors yet; now read "/proc/net/dev", - * and add to the list of interfaces all interfaces listed - * there that we don't already have, because, on Linux, - * SIOCGIFCONF reports only interfaces with IPv4 addresses, - * so you need to read "/proc/net/dev" to get the names of - * the rest of the interfaces. - */ - ret = scan_proc_net_dev(&devlist, fd, errbuf); - } -#endif - (void)close(fd); - - if (ret != -1) { - /* - * We haven't had any errors yet; do any platform-specific - * operations to add devices. - */ - if (pcap_platform_finddevs(&devlist, errbuf) < 0) - ret = -1; - } - - if (ret == -1) { - /* - * We had an error; free the list we've been constructing. - */ - if (devlist != NULL) { - pcap_freealldevs(devlist); - devlist = NULL; - } - } - - *alldevsp = devlist; - return (ret); -} diff --git a/contrib/libpcap-0.8.3/fad-glifc.c b/contrib/libpcap-0.8.3/fad-glifc.c deleted file mode 100644 index d365ae1aa0..0000000000 --- a/contrib/libpcap-0.8.3/fad-glifc.c +++ /dev/null @@ -1,325 +0,0 @@ -/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */ -/* - * Copyright (c) 1994, 1995, 1996, 1997, 1998 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the Computer Systems - * Engineering Group at Lawrence Berkeley Laboratory. - * 4. Neither the name of the University nor of the Laboratory may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef lint -static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/libpcap/fad-glifc.c,v 1.2.2.1 2003/11/15 23:26:39 guy Exp $ (LBL)"; -#endif - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#include -#ifdef HAVE_SYS_SOCKIO_H -#include -#endif -#include /* concession to AIX */ - -struct mbuf; /* Squelch compiler warnings on some platforms for */ -struct rtentry; /* declarations in */ -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "pcap-int.h" - -#ifdef HAVE_OS_PROTO_H -#include "os-proto.h" -#endif - -/* - * Get a list of all interfaces that are up and that we can open. - * Returns -1 on error, 0 otherwise. - * The list, as returned through "alldevsp", may be null if no interfaces - * were up and could be opened. - * - * This is the implementation used on platforms that have SIOCLGIFCONF - * but don't have "getifaddrs()". (Solaris 8 and later; we use - * SIOCLGIFCONF rather than SIOCGIFCONF in order to get IPv6 addresses.) - */ -int -pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) -{ - pcap_if_t *devlist = NULL; - register int fd4, fd6, fd; - register struct lifreq *ifrp, *ifend; - struct lifnum ifn; - struct lifconf ifc; - char *buf = NULL; - unsigned buf_size; - struct lifreq ifrflags, ifrnetmask, ifrbroadaddr, ifrdstaddr; - struct sockaddr *netmask, *broadaddr, *dstaddr; - int ret = 0; - - /* - * Create a socket from which to fetch the list of interfaces, - * and from which to fetch IPv4 information. - */ - fd4 = socket(AF_INET, SOCK_DGRAM, 0); - if (fd4 < 0) { - (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, - "socket: %s", pcap_strerror(errno)); - return (-1); - } - - /* - * Create a socket from which to fetch IPv6 information. - */ - fd6 = socket(AF_INET6, SOCK_DGRAM, 0); - if (fd6 < 0) { - (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, - "socket: %s", pcap_strerror(errno)); - (void)close(fd4); - return (-1); - } - - /* - * How many entries will SIOCGLIFCONF return? - */ - ifn.lifn_family = AF_UNSPEC; - ifn.lifn_flags = 0; - ifn.lifn_count = 0; - if (ioctl(fd4, SIOCGLIFNUM, (char *)&ifn) < 0) { - (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, - "SIOCGLIFNUM: %s", pcap_strerror(errno)); - (void)close(fd6); - (void)close(fd4); - return (-1); - } - - /* - * Allocate a buffer for those entries. - */ - buf_size = ifn.lifn_count * sizeof (struct lifreq); - buf = malloc(buf_size); - if (buf == NULL) { - (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, - "malloc: %s", pcap_strerror(errno)); - (void)close(fd6); - (void)close(fd4); - return (-1); - } - - /* - * Get the entries. - */ - ifc.lifc_len = buf_size; - ifc.lifc_buf = buf; - ifc.lifc_family = AF_UNSPEC; - ifc.lifc_flags = 0; - memset(buf, 0, buf_size); - if (ioctl(fd4, SIOCGLIFCONF, (char *)&ifc) < 0) { - (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, - "SIOCGLIFCONF: %s", pcap_strerror(errno)); - (void)close(fd6); - (void)close(fd4); - free(buf); - return (-1); - } - - /* - * Loop over the entries. - */ - ifrp = (struct lifreq *)buf; - ifend = (struct lifreq *)(buf + ifc.lifc_len); - - for (; ifrp < ifend; ifrp++) { - /* - * IPv6 or not? - */ - if (((struct sockaddr *)&ifrp->lifr_addr)->sa_family == AF_INET6) - fd = fd6; - else - fd = fd4; - - /* - * Get the flags for this interface, and skip it if it's - * not up. - */ - strncpy(ifrflags.lifr_name, ifrp->lifr_name, - sizeof(ifrflags.lifr_name)); - if (ioctl(fd, SIOCGLIFFLAGS, (char *)&ifrflags) < 0) { - if (errno == ENXIO) - continue; - (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, - "SIOCGLIFFLAGS: %.*s: %s", - (int)sizeof(ifrflags.lifr_name), - ifrflags.lifr_name, - pcap_strerror(errno)); - ret = -1; - break; - } - if (!(ifrflags.lifr_flags & IFF_UP)) - continue; - - /* - * Get the netmask for this address on this interface. - */ - strncpy(ifrnetmask.lifr_name, ifrp->lifr_name, - sizeof(ifrnetmask.lifr_name)); - memcpy(&ifrnetmask.lifr_addr, &ifrp->lifr_addr, - sizeof(ifrnetmask.lifr_addr)); - if (ioctl(fd, SIOCGLIFNETMASK, (char *)&ifrnetmask) < 0) { - if (errno == EADDRNOTAVAIL) { - /* - * Not available. - */ - netmask = NULL; - } else { - (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, - "SIOCGLIFNETMASK: %.*s: %s", - (int)sizeof(ifrnetmask.lifr_name), - ifrnetmask.lifr_name, - pcap_strerror(errno)); - ret = -1; - break; - } - } else - netmask = (struct sockaddr *)&ifrnetmask.lifr_addr; - - /* - * Get the broadcast address for this address on this - * interface (if any). - */ - if (ifrflags.lifr_flags & IFF_BROADCAST) { - strncpy(ifrbroadaddr.lifr_name, ifrp->lifr_name, - sizeof(ifrbroadaddr.lifr_name)); - memcpy(&ifrbroadaddr.lifr_addr, &ifrp->lifr_addr, - sizeof(ifrbroadaddr.lifr_addr)); - if (ioctl(fd, SIOCGLIFBRDADDR, - (char *)&ifrbroadaddr) < 0) { - if (errno == EADDRNOTAVAIL) { - /* - * Not available. - */ - broadaddr = NULL; - } else { - (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, - "SIOCGLIFBRDADDR: %.*s: %s", - (int)sizeof(ifrbroadaddr.lifr_name), - ifrbroadaddr.lifr_name, - pcap_strerror(errno)); - ret = -1; - break; - } - } else - broadaddr = (struct sockaddr *)&ifrbroadaddr.lifr_broadaddr; - } else { - /* - * Not a broadcast interface, so no broadcast - * address. - */ - broadaddr = NULL; - } - - /* - * Get the destination address for this address on this - * interface (if any). - */ - if (ifrflags.lifr_flags & IFF_POINTOPOINT) { - strncpy(ifrdstaddr.lifr_name, ifrp->lifr_name, - sizeof(ifrdstaddr.lifr_name)); - memcpy(&ifrdstaddr.lifr_addr, &ifrp->lifr_addr, - sizeof(ifrdstaddr.lifr_addr)); - if (ioctl(fd, SIOCGLIFDSTADDR, - (char *)&ifrdstaddr) < 0) { - if (errno == EADDRNOTAVAIL) { - /* - * Not available. - */ - dstaddr = NULL; - } else { - (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, - "SIOCGLIFDSTADDR: %.*s: %s", - (int)sizeof(ifrdstaddr.lifr_name), - ifrdstaddr.lifr_name, - pcap_strerror(errno)); - ret = -1; - break; - } - } else - dstaddr = (struct sockaddr *)&ifrdstaddr.lifr_dstaddr; - } else - dstaddr = NULL; - - /* - * Add information for this address to the list. - */ - if (add_addr_to_iflist(&devlist, ifrp->lifr_name, - ifrflags.lifr_flags, (struct sockaddr *)&ifrp->lifr_addr, - sizeof (struct sockaddr_storage), - netmask, sizeof (struct sockaddr_storage), - broadaddr, sizeof (struct sockaddr_storage), - dstaddr, sizeof (struct sockaddr_storage), errbuf) < 0) { - ret = -1; - break; - } - } - free(buf); - (void)close(fd6); - (void)close(fd4); - - if (ret != -1) { - /* - * We haven't had any errors yet; do any platform-specific - * operations to add devices. - */ - if (pcap_platform_finddevs(&devlist, errbuf) < 0) - ret = -1; - } - - if (ret == -1) { - /* - * We had an error; free the list we've been constructing. - */ - if (devlist != NULL) { - pcap_freealldevs(devlist); - devlist = NULL; - } - } - - *alldevsp = devlist; - return (ret); -} diff --git a/contrib/libpcap-0.8.3/fad-null.c b/contrib/libpcap-0.8.3/fad-null.c deleted file mode 100644 index be1a0edcc8..0000000000 --- a/contrib/libpcap-0.8.3/fad-null.c +++ /dev/null @@ -1,65 +0,0 @@ -/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */ -/* - * Copyright (c) 1994, 1995, 1996, 1997, 1998 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the Computer Systems - * Engineering Group at Lawrence Berkeley Laboratory. - * 4. Neither the name of the University nor of the Laboratory may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef lint -static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/libpcap/fad-null.c,v 1.1.2.1 2003/11/15 23:26:39 guy Exp $ (LBL)"; -#endif - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -/* - * Get a list of all interfaces that are up and that we can open. - * Returns -1 on error, 0 otherwise. - * The list, as returned through "alldevsp", may be null if no interfaces - * were up and could be opened. - * - * This is the implementation used on platforms that have no support for - * packet capture. - */ -int -pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) -{ - /* - * Succeed, but don't return any interfaces; we return only those - * we can open, and we can't open any if there's no support - * for packet capture. - */ - *alldevsp = NULL; - return (0); -} diff --git a/contrib/libpcap-0.8.3/fad-win32.c b/contrib/libpcap-0.8.3/fad-win32.c deleted file mode 100644 index cc2ce5a9af..0000000000 --- a/contrib/libpcap-0.8.3/fad-win32.c +++ /dev/null @@ -1,291 +0,0 @@ -/* - * Copyright (c) 2002 - 2003 - * NetGroup, Politecnico di Torino (Italy) - * 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. Neither the name of the Politecnico di Torino 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 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 - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#ifndef lint -static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/libpcap/fad-win32.c,v 1.7.2.1 2003/11/15 23:26:40 guy Exp $ (LBL)"; -#endif - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include - -#include - -/* - * Add an entry to the list of addresses for an interface. - * "curdev" is the entry for that interface. - */ -static int -add_addr_to_list(pcap_if_t *curdev, struct sockaddr *addr, - struct sockaddr *netmask, struct sockaddr *broadaddr, - struct sockaddr *dstaddr, char *errbuf) -{ - pcap_addr_t *curaddr, *prevaddr, *nextaddr; - - /* - * Allocate the new entry and fill it in. - */ - curaddr = (pcap_addr_t*)malloc(sizeof(pcap_addr_t)); - if (curaddr == NULL) { - (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, - "malloc: %s", pcap_strerror(errno)); - return (-1); - } - - curaddr->next = NULL; - if (addr != NULL) { - curaddr->addr = (struct sockaddr*)dup_sockaddr(addr, sizeof(struct sockaddr_storage)); - if (curaddr->addr == NULL) { - (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, - "malloc: %s", pcap_strerror(errno)); - free(curaddr); - return (-1); - } - } else - curaddr->addr = NULL; - - if (netmask != NULL) { - curaddr->netmask = (struct sockaddr*)dup_sockaddr(netmask, sizeof(struct sockaddr_storage)); - if (curaddr->netmask == NULL) { - (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, - "malloc: %s", pcap_strerror(errno)); - free(curaddr); - return (-1); - } - } else - curaddr->netmask = NULL; - - if (broadaddr != NULL) { - curaddr->broadaddr = (struct sockaddr*)dup_sockaddr(broadaddr, sizeof(struct sockaddr_storage)); - if (curaddr->broadaddr == NULL) { - (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, - "malloc: %s", pcap_strerror(errno)); - free(curaddr); - return (-1); - } - } else - curaddr->broadaddr = NULL; - - if (dstaddr != NULL) { - curaddr->dstaddr = (struct sockaddr*)dup_sockaddr(dstaddr, sizeof(struct sockaddr_storage)); - if (curaddr->dstaddr == NULL) { - (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, - "malloc: %s", pcap_strerror(errno)); - free(curaddr); - return (-1); - } - } else - curaddr->dstaddr = NULL; - - /* - * Find the end of the list of addresses. - */ - for (prevaddr = curdev->addresses; prevaddr != NULL; prevaddr = nextaddr) { - nextaddr = prevaddr->next; - if (nextaddr == NULL) { - /* - * This is the end of the list. - */ - break; - } - } - - if (prevaddr == NULL) { - /* - * The list was empty; this is the first member. - */ - curdev->addresses = curaddr; - } else { - /* - * "prevaddr" is the last member of the list; append - * this member to it. - */ - prevaddr->next = curaddr; - } - - return (0); -} - - -static int -pcap_add_if_win32(pcap_if_t **devlist, char *name, const char *desc, - char *errbuf) -{ - pcap_if_t *curdev; - npf_if_addr if_addrs[MAX_NETWORK_ADDRESSES]; - LONG if_addr_size; - int res = 0; - - if_addr_size = MAX_NETWORK_ADDRESSES; - - /* - * Add an entry for this interface, with no addresses. - */ - if (add_or_find_if(&curdev, devlist, (char *)name, 0, (char *)desc, - errbuf) == -1) { - /* - * Failure. - */ - return (-1); - } - - /* - * Get the list of addresses for the interface. - */ - if (!PacketGetNetInfoEx((void *)name, if_addrs, &if_addr_size)) { - /* - * Failure. - * - * We don't return an error, because this can happen with - * NdisWan interfaces, and we want to supply them even - * if we can't supply their addresses. - * - * We return an entry with an empty address list. - */ - return (0); - } - - /* - * Now add the addresses. - */ - while (if_addr_size-- > 0) { - /* - * "curdev" is an entry for this interface; add an entry for - * this address to its list of addresses. - */ - if(curdev == NULL) - break; - res = add_addr_to_list(curdev, - (struct sockaddr *)&if_addrs[if_addr_size].IPAddress, - (struct sockaddr *)&if_addrs[if_addr_size].SubnetMask, - (struct sockaddr *)&if_addrs[if_addr_size].Broadcast, - NULL, - errbuf); - if (res == -1) { - /* - * Failure. - */ - break; - } - } - - return (res); -} - - -/* - * Get a list of all interfaces that are up and that we can open. - * Returns -1 on error, 0 otherwise. - * The list, as returned through "alldevsp", may be null if no interfaces - * were up and could be opened. - * - * Win32 implementation, based on WinPcap - */ -int -pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) -{ - pcap_if_t *devlist = NULL; - int ret = 0; - const char *desc; - char AdaptersName[8192]; - ULONG NameLength = 8192; - char *name; - - if (!PacketGetAdapterNames(AdaptersName, &NameLength)) { - snprintf(errbuf, PCAP_ERRBUF_SIZE, - "PacketGetAdapterNames: %s", - pcap_win32strerror()); - return (-1); - } - - /* - * "PacketGetAdapterNames()" returned a list of - * null-terminated ASCII interface name strings, - * terminated by a null string, followed by a list - * of null-terminated ASCII interface description - * strings, terminated by a null string. - * This means there are two ASCII nulls at the end - * of the first list. - * - * Find the end of the first list; that's the - * beginning of the second list. - */ - desc = &AdaptersName[0]; - while (*desc != '\0' || *(desc + 1) != '\0') - desc++; - - /* - * Found it - "desc" points to the first of the two - * nulls at the end of the list of names, so the - * first byte of the list of descriptions is two bytes - * after it. - */ - desc += 2; - - /* - * Loop over the elements in the first list. - */ - name = &AdaptersName[0]; - while (*name != '\0') { - /* - * Add an entry for this interface. - */ - if (pcap_add_if_win32(&devlist, name, desc, - errbuf) == -1) { - /* - * Failure. - */ - ret = -1; - break; - } - name += strlen(name) + 1; - desc += strlen(desc) + 1; - } - - if (ret == -1) { - /* - * We had an error; free the list we've been constructing. - */ - if (devlist != NULL) { - pcap_freealldevs(devlist); - devlist = NULL; - } - } - - *alldevsp = devlist; - return (ret); -} diff --git a/contrib/libpcap-0.8.3/gencode.c b/contrib/libpcap-0.8.3/gencode.c deleted file mode 100644 index 33f5a50ff9..0000000000 --- a/contrib/libpcap-0.8.3/gencode.c +++ /dev/null @@ -1,5520 +0,0 @@ -/*#define CHASE_CHAIN*/ -/* - * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that: (1) source code distributions - * retain the above copyright notice and this paragraph in its entirety, (2) - * distributions including binary code include the above copyright notice and - * this paragraph in its entirety in the documentation or other materials - * provided with the distribution, and (3) all advertising materials mentioning - * features or use of this software display the following acknowledgement: - * ``This product includes software developed by the University of California, - * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of - * the University nor the names of its contributors may be used to endorse - * or promote products derived from this software without specific prior - * written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ -#ifndef lint -static 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 -#else /* WIN32 */ -#include -#include -#include -#endif /* WIN32 */ - -/* - * XXX - why was this included even on UNIX? - */ -#ifdef __MINGW32__ -#include "IP6_misc.h" -#endif - -#ifndef WIN32 - -#ifdef __NetBSD__ -#include -#endif - -#include - -#endif /* WIN32 */ - -#include -#include -#include -#include -#include - -#include "pcap-int.h" - -#include "ethertype.h" -#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 "pf.h" -#ifndef offsetof -#define offsetof(s, e) ((size_t)&((s *)0)->e) -#endif -#ifdef INET6 -#ifndef WIN32 -#include /* for "struct addrinfo" */ -#endif /* WIN32 */ -#endif /*INET6*/ -#include - -#define ETHERMTU 1500 - -#ifndef IPPROTO_SCTP -#define IPPROTO_SCTP 132 -#endif - -#ifdef HAVE_OS_PROTO_H -#include "os-proto.h" -#endif - -#define JMP(c) ((c)|BPF_JMP|BPF_K) - -/* Locals */ -static jmp_buf top_ctx; -static pcap_t *bpf_pcap; - -/* Hack for updating VLAN offsets. */ -static u_int orig_linktype = -1, orig_nl = -1, orig_nl_nosnap = -1; - -/* XXX */ -#ifdef PCAP_FDDIPAD -int pcap_fddipad = PCAP_FDDIPAD; -#else -int pcap_fddipad; -#endif - -/* VARARGS */ -void -bpf_error(const char *fmt, ...) - -{ - va_list ap; - - va_start(ap, fmt); - if (bpf_pcap != NULL) - (void)vsnprintf(pcap_geterr(bpf_pcap), PCAP_ERRBUF_SIZE, - fmt, ap); - va_end(ap); - longjmp(top_ctx, 1); - /* NOTREACHED */ -} - -static void init_linktype(int); - -static int alloc_reg(void); -static void free_reg(int); - -static struct block *root; - -/* - * We divy out chunks of memory rather than call malloc each time so - * we don't have to worry about leaking memory. It's probably - * not a big deal if all this memory was wasted but it this ever - * goes into a library that would probably not be a good idea. - */ -#define NCHUNKS 16 -#define CHUNK0SIZE 1024 -struct chunk { - u_int n_left; - void *m; -}; - -static struct chunk chunks[NCHUNKS]; -static int cur_chunk; - -static void *newchunk(u_int); -static void freechunks(void); -static inline struct block *new_block(int); -static inline struct slist *new_stmt(int); -static struct block *gen_retblk(int); -static inline void syntax(void); - -static void backpatch(struct block *, struct block *); -static void merge(struct block *, struct block *); -static struct block *gen_cmp(u_int, u_int, 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); -#endif -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_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 -static struct block *gen_host6(struct in6_addr *, struct in6_addr *, int, int); -#endif -#ifndef INET6 -static struct block *gen_gateway(const u_char *, bpf_u_int32 **, int, int); -#endif -static struct block *gen_ipfrag(void); -static struct block *gen_portatom(int, bpf_int32); -#ifdef INET6 -static struct block *gen_portatom6(int, bpf_int32); -#endif -struct block *gen_portop(int, int, int); -static struct block *gen_port(int, int, int); -#ifdef INET6 -struct block *gen_portop6(int, int, int); -static struct block *gen_port6(int, int, int); -#endif -static int lookup_proto(const char *, int); -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_t size; - -#ifndef __NetBSD__ - /* XXX Round up to nearest long. */ - n = (n + sizeof(long) - 1) & ~(sizeof(long) - 1); -#else - /* XXX Round up to structure boundary. */ - n = ALIGN(n); -#endif - - cp = &chunks[cur_chunk]; - if (n > cp->n_left) { - ++cp, k = ++cur_chunk; - if (k >= NCHUNKS) - bpf_error("out of memory"); - size = CHUNK0SIZE << k; - cp->m = (void *)malloc(size); - if (cp->m == NULL) - bpf_error("out of memory"); - memset((char *)cp->m, 0, size); - cp->n_left = size; - if (n > size) - bpf_error("out of memory"); - } - cp->n_left -= n; - return (void *)((char *)cp->m + cp->n_left); -} - -static void -freechunks() -{ - int i; - - cur_chunk = 0; - for (i = 0; i < NCHUNKS; ++i) - if (chunks[i].m != NULL) { - free(chunks[i].m); - chunks[i].m = NULL; - } -} - -/* - * A strdup whose allocations are freed after code generation is over. - */ -char * -sdup(s) - register const char *s; -{ - int n = strlen(s) + 1; - char *cp = newchunk(n); - - strlcpy(cp, s, n); - return (cp); -} - -static inline struct block * -new_block(code) - int code; -{ - struct block *p; - - p = (struct block *)newchunk(sizeof(*p)); - p->s.code = code; - p->head = p; - - return p; -} - -static inline struct slist * -new_stmt(code) - int code; -{ - struct slist *p; - - p = (struct slist *)newchunk(sizeof(*p)); - p->s.code = code; - - return p; -} - -static struct block * -gen_retblk(v) - int v; -{ - struct block *b = new_block(BPF_RET|BPF_K); - - b->s.k = v; - return b; -} - -static inline void -syntax() -{ - bpf_error("syntax error in filter expression"); -} - -static bpf_u_int32 netmask; -static int snaplen; -int no_optimize; - -int -pcap_compile(pcap_t *p, struct bpf_program *program, - char *buf, int optimize, bpf_u_int32 mask) -{ - extern int n_errors; - int len; - - no_optimize = 0; - n_errors = 0; - root = NULL; - bpf_pcap = p; - if (setjmp(top_ctx)) { - lex_cleanup(); - freechunks(); - return (-1); - } - - netmask = mask; - - snaplen = pcap_snapshot(p); - if (snaplen == 0) { - snprintf(p->errbuf, PCAP_ERRBUF_SIZE, - "snaplen of 0 rejects all packets"); - return -1; - } - - lex_init(buf ? buf : ""); - init_linktype(pcap_datalink(p)); - (void)pcap_parse(); - - if (n_errors) - syntax(); - - if (root == NULL) - root = gen_retblk(snaplen); - - if (optimize && !no_optimize) { - bpf_optimize(&root); - if (root == NULL || - (root->s.code == (BPF_RET|BPF_K) && root->s.k == 0)) - bpf_error("expression rejects all packets"); - } - program->bf_insns = icode_to_fcode(root, &len); - program->bf_len = len; - - lex_cleanup(); - freechunks(); - return (0); -} - -/* - * entry point for using the compiler with no pcap open - * pass in all the stuff that is needed explicitly instead. - */ -int -pcap_compile_nopcap(int snaplen_arg, int linktype_arg, - struct bpf_program *program, - char *buf, int optimize, bpf_u_int32 mask) -{ - pcap_t *p; - int ret; - - p = pcap_open_dead(linktype_arg, snaplen_arg); - if (p == NULL) - return (-1); - ret = pcap_compile(p, program, buf, optimize, mask); - pcap_close(p); - return (ret); -} - -/* - * Clean up a "struct bpf_program" by freeing all the memory allocated - * in it. - */ -void -pcap_freecode(struct bpf_program *program) -{ - program->bf_len = 0; - if (program->bf_insns != NULL) { - free((char *)program->bf_insns); - program->bf_insns = NULL; - } -} - -/* - * Backpatch the blocks in 'list' to 'target'. The 'sense' field indicates - * which of the jt and jf fields has been resolved and which is a pointer - * back to another unresolved block (or nil). At least one of the fields - * in each block is already resolved. - */ -static void -backpatch(list, target) - struct block *list, *target; -{ - struct block *next; - - while (list) { - if (!list->sense) { - next = JT(list); - JT(list) = target; - } else { - next = JF(list); - JF(list) = target; - } - list = next; - } -} - -/* - * Merge the lists in b0 and b1, using the 'sense' field to indicate - * which of jt and jf is the link. - */ -static void -merge(b0, b1) - struct block *b0, *b1; -{ - register struct block **p = &b0; - - /* Find end of list. */ - while (*p) - p = !((*p)->sense) ? &JT(*p) : &JF(*p); - - /* Concatenate the lists. */ - *p = b1; -} - -void -finish_parse(p) - struct block *p; -{ - backpatch(p, gen_retblk(snaplen)); - p->sense = !p->sense; - backpatch(p, gen_retblk(0)); - root = p->head; -} - -void -gen_and(b0, b1) - struct block *b0, *b1; -{ - backpatch(b0, b1->head); - b0->sense = !b0->sense; - b1->sense = !b1->sense; - merge(b1, b0); - b1->sense = !b1->sense; - b1->head = b0->head; -} - -void -gen_or(b0, b1) - struct block *b0, *b1; -{ - b0->sense = !b0->sense; - backpatch(b0, b1->head); - b0->sense = !b0->sense; - merge(b1, b0); - b1->head = b0->head; -} - -void -gen_not(b) - struct block *b; -{ - b->sense = !b->sense; -} - -static struct block * -gen_cmp(offset, size, v) - u_int offset, size; - bpf_int32 v; -{ - struct slist *s; - struct block *b; - - s = new_stmt(BPF_LD|BPF_ABS|size); - s->s.k = offset; - - b = new_block(JMP(BPF_JEQ)); - b->stmts = s; - b->s.k = v; - - return b; -} - -static struct block * -gen_cmp_gt(offset, size, v) - u_int offset, size; - bpf_int32 v; -{ - struct slist *s; - struct block *b; - - s = new_stmt(BPF_LD|BPF_ABS|size); - s->s.k = offset; - - b = new_block(JMP(BPF_JGT)); - b->stmts = s; - b->s.k = v; - - return b; -} - -static struct block * -gen_mcmp(offset, size, v, mask) - u_int offset, size; - bpf_int32 v; - bpf_u_int32 mask; -{ - struct block *b = gen_cmp(offset, size, v); - struct slist *s; - - if (mask != 0xffffffff) { - s = new_stmt(BPF_ALU|BPF_AND|BPF_K); - s->s.k = mask; - b->stmts->next = s; - } - return b; -} - -static struct block * -gen_bcmp(offset, size, v) - register u_int offset, size; - register const u_char *v; -{ - register struct block *b, *tmp; - - b = NULL; - while (size >= 4) { - register const u_char *p = &v[size - 4]; - bpf_int32 w = ((bpf_int32)p[0] << 24) | - ((bpf_int32)p[1] << 16) | ((bpf_int32)p[2] << 8) | p[3]; - - tmp = gen_cmp(offset + size - 4, BPF_W, w); - if (b != NULL) - gen_and(b, tmp); - b = tmp; - size -= 4; - } - while (size >= 2) { - register const u_char *p = &v[size - 2]; - bpf_int32 w = ((bpf_int32)p[0] << 8) | p[1]; - - tmp = gen_cmp(offset + size - 2, BPF_H, w); - if (b != NULL) - gen_and(b, tmp); - b = tmp; - size -= 2; - } - if (size > 0) { - tmp = gen_cmp(offset, BPF_B, (bpf_int32)v[0]); - if (b != NULL) - gen_and(b, tmp); - b = tmp; - } - 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. - */ - -/* - * 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 -init_linktype(type) - int 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_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; /* Ethernet II */ - off_nl_nosnap = 17; /* 802.3+802.2 */ - return; - - case DLT_SLIP: - /* - * SLIP doesn't have a link level type. The 16 byte - * header is hacked into our SLIP driver. - */ - off_linktype = -1; - off_nl = 16; - off_nl_nosnap = 16; /* no 802.2 LLC */ - return; - - case DLT_SLIP_BSDOS: - /* XXX this may be the same as the DLT_PPP_BSDOS case */ - 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: - case DLT_C_HDLC: /* BSD/OS Cisco HDLC */ - 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: - /* - * This does no include the Ethernet header, and - * only covers session state. - */ - 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: - /* - * FDDI 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? - */ - off_linktype = 13; -#ifdef PCAP_FDDIPAD - off_linktype += pcap_fddipad; -#endif - 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; - - case DLT_IEEE802: - /* - * Token Ring 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? - * - * XXX - the header is actually variable-length. - * Some various Linux patched versions gave 38 - * as "off_linktype" and 40 as "off_nl"; however, - * if a token ring packet has *no* routing - * information, i.e. is not source-routed, the correct - * values are 20 and 22, as they are in the vanilla code. - * - * A packet is source-routed iff the uppermost bit - * of the first byte of the source address, at an - * offset of 8, has the uppermost bit set. If the - * packet is source-routed, the total number of bytes - * of routing information is 2 plus bits 0x1F00 of - * the 16-bit value at an offset of 14 (shifted right - * 8 - figure out which byte that is). - */ - off_linktype = 14; - off_nl = 22; /* Token Ring+802.2+SNAP */ - off_nl_nosnap = 17; /* Token Ring+802.2 */ - return; - - case DLT_IEEE802_11: - /* - * 802.11 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? - * - * XXX - the header is actually variable-length. We - * assume a 24-byte link-layer header, as appears in - * data frames in networks with no bridges. If the - * fromds and tods 802.11 header bits are both set, - * it's actually supposed to be 30 bytes. - */ - off_linktype = 24; - off_nl = 32; /* 802.11+802.2+SNAP */ - off_nl_nosnap = 27; /* 802.11+802.2 */ - return; - - case DLT_PRISM_HEADER: - /* - * 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 144 bytes long. - * - * XXX - same variable-length header problem; at least - * the Prism header is fixed-length. - */ - off_linktype = 144+24; - 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 = 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; - 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: - /* - * LocalTalk does have a 1-byte type field in the LLAP header, - * but really it just indicates whether there is a "short" or - * "long" DDP packet following. - */ - 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 */ -} - -static struct block * -gen_uncond(rsense) - int rsense; -{ - struct block *b; - struct slist *s; - - s = new_stmt(BPF_LD|BPF_IMM); - s->s.k = !rsense; - b = new_block(JMP(BPF_JEQ)); - b->stmts = s; - - return b; -} - -static inline struct block * -gen_true() -{ - return gen_uncond(1); -} - -static inline struct block * -gen_false() -{ - return gen_uncond(0); -} - -/* - * Byte-swap a 32-bit number. - * ("htonl()" or "ntohl()" won't work - we want to byte-swap even on - * big-endian platforms.) - */ -#define SWAPLONG(y) \ -((((y)&0xff)<<24) | (((y)&0xff00)<<8) | (((y)&0xff0000)>>8) | (((y)>>24)&0xff)) - -static struct block * -gen_ether_linktype(proto) - register int proto; -{ - struct block *b0, *b1; - - 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_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_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); - - /* - * 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 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; - - 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) { - /* - * 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); - } - } -} - -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: - return gen_cmp(off_linktype, BPF_H, (bpf_int32)proto); - break; - } - break; - - case DLT_IEEE802_11: - 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: - /* - * 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. - */ - if (is_lane) { - /* - * Check that the packet doesn't begin with an - * LE Control marker. (We've already generated - * a test for LANE.) - */ - b0 = gen_cmp(SUNATM_PKT_BEGIN_POS, BPF_H, 0xFF00); - gen_not(b0); - - /* - * Now generate an Ethernet test. - */ - b1 = gen_ether_linktype(proto); - gen_and(b0, b1); - return b1; - } else { - /* - * Check for LLC encapsulation and then check the - * protocol. - */ - b0 = gen_atmfield_code(A_PROTOTYPE, PT_LLC, BPF_JEQ, 0); - b1 = gen_llc(proto); - gen_and(b0, b1); - return b1; - } - - 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. - * XXX - should we check both the DSAP and the - * LSAP, like this, or should we check just the - * DSAP? - */ - b0 = gen_cmp(off_linktype, BPF_H, LINUX_SLL_P_802_2); - b1 = gen_cmp(off_linktype + 2, BPF_H, (bpf_int32) - ((LLCSAP_ISONS << 8) | LLCSAP_ISONS)); - gen_and(b0, b1); - return b1; - - case LLCSAP_NETBEUI: - /* - * NetBEUI always uses 802.2 encapsulation. - * XXX - should we check both the DSAP and the - * LSAP, like this, or should we check just the - * DSAP? - */ - b0 = gen_cmp(off_linktype, BPF_H, LINUX_SLL_P_802_2); - b1 = gen_cmp(off_linktype + 2, BPF_H, (bpf_int32) - ((LLCSAP_NETBEUI << 8) | LLCSAP_NETBEUI)); - gen_and(b0, b1); - return b1; - - case LLCSAP_IPX: - /* - * Ethernet_II frames, which are Ethernet - * frames with a frame type of ETHERTYPE_IPX; - * - * Ethernet_802.3 frames, which have a frame - * type of LINUX_SLL_P_802_3; - * - * Ethernet_802.2 frames, which are 802.3 - * frames with an 802.2 LLC header (i.e, have - * a frame type of LINUX_SLL_P_802_2) 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. - * - * First, do the checks on LINUX_SLL_P_802_2 - * frames; generate the check for either - * Ethernet_802.2 or Ethernet_SNAP frames, and - * then put a check for LINUX_SLL_P_802_2 frames - * before it. - */ - b0 = gen_cmp(off_linktype + 2, BPF_B, - (bpf_int32)LLCSAP_IPX); - b1 = gen_snap(0x000000, ETHERTYPE_IPX, - off_linktype + 2); - gen_or(b0, b1); - b0 = gen_cmp(off_linktype, BPF_H, LINUX_SLL_P_802_2); - gen_and(b0, b1); - - /* - * Now check for 802.3 frames and OR that with - * the previous test. - */ - b0 = gen_cmp(off_linktype, BPF_H, LINUX_SLL_P_802_3); - gen_or(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; - - 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 the 802.2 protocol type in the - * "Ethernet type" field. - */ - b0 = gen_cmp(off_linktype, BPF_H, LINUX_SLL_P_802_2); - - /* - * 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, - off_linktype + 2); - else /* proto == ETHERTYPE_AARP */ - b1 = gen_snap(0x000000, ETHERTYPE_AARP, - off_linktype + 2); - 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) { - /* - * This is an LLC SAP value, so the frames - * that match would be 802.2 frames. - * Check for the 802.2 protocol type - * in the "Ethernet type" field, and - * then check the DSAP. - */ - b0 = gen_cmp(off_linktype, BPF_H, - LINUX_SLL_P_802_2); - 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); - } - } - break; - - case DLT_SLIP: - case DLT_SLIP_BSDOS: - case DLT_RAW: - /* - * These types don't provide any type field; packets - * are always IP. - * - * XXX - for IPv4, check for a version number of 4, and, - * for IPv6, check for a version number of 6? - */ - switch (proto) { - - case ETHERTYPE_IP: -#ifdef INET6 - case ETHERTYPE_IPV6: -#endif - return gen_true(); /* always true */ - - default: - return gen_false(); /* always false */ - } - break; - - case DLT_PPP: - case DLT_PPP_SERIAL: - case DLT_PPP_ETHER: - /* - * We use Ethernet protocol types inside libpcap; - * map them to the corresponding PPP protocol types. - */ - switch (proto) { - - case ETHERTYPE_IP: - proto = PPP_IP; - break; - -#ifdef INET6 - case ETHERTYPE_IPV6: - proto = PPP_IPV6; - break; -#endif - - case ETHERTYPE_DN: - proto = PPP_DECNET; - break; - - case ETHERTYPE_ATALK: - proto = PPP_APPLE; - break; - - case ETHERTYPE_NS: - proto = PPP_NS; - break; - - case LLCSAP_ISONS: - proto = PPP_OSI; - break; - - case LLCSAP_8021D: - /* - * I'm assuming the "Bridging PDU"s that go - * over PPP are Spanning Tree Protocol - * Bridging PDUs. - */ - proto = PPP_BRPDU; - break; - - case LLCSAP_IPX: - proto = PPP_IPX; - break; - } - break; - - case DLT_PPP_BSDOS: - /* - * We use Ethernet protocol types inside libpcap; - * map them to the corresponding PPP protocol types. - */ - switch (proto) { - - case ETHERTYPE_IP: - b0 = gen_cmp(off_linktype, BPF_H, PPP_IP); - b1 = gen_cmp(off_linktype, BPF_H, PPP_VJC); - gen_or(b0, b1); - b0 = gen_cmp(off_linktype, BPF_H, PPP_VJNC); - gen_or(b1, b0); - return b0; - -#ifdef INET6 - case ETHERTYPE_IPV6: - proto = PPP_IPV6; - /* more to go? */ - break; -#endif - - case ETHERTYPE_DN: - proto = PPP_DECNET; - break; - - case ETHERTYPE_ATALK: - proto = PPP_APPLE; - break; - - case ETHERTYPE_NS: - proto = PPP_NS; - break; - - case LLCSAP_ISONS: - proto = PPP_OSI; - break; - - case LLCSAP_8021D: - /* - * I'm assuming the "Bridging PDU"s that go - * over PPP are Spanning Tree Protocol - * Bridging PDUs. - */ - proto = PPP_BRPDU; - break; - - case LLCSAP_IPX: - proto = PPP_IPX; - break; - } - break; - - 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, - * 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 - * same as the host byte order on this machine. - * - * For DLT_LOOP, the link-layer header is a 32-bit - * word containing an AF_ value in *network* byte order. - * - * XXX - AF_ values may, unfortunately, be platform- - * dependent; for example, FreeBSD's AF_INET6 is 24 - * whilst NetBSD's and OpenBSD's is 26. - * - * This means that, when reading a capture file, just - * checking for our AF_INET6 value won't work if the - * capture file came from another OS. - */ - switch (proto) { - - case ETHERTYPE_IP: - proto = AF_INET; - break; - -#ifdef INET6 - case ETHERTYPE_IPV6: - proto = AF_INET6; - break; -#endif - - default: - /* - * Not a type on which we support filtering. - * XXX - support those that have AF_ values - * #defined on this platform, at least? - */ - return gen_false(); - } - - if (linktype == DLT_NULL || linktype == DLT_ENC) { - /* - * The AF_ value is in host byte order, but - * the BPF interpreter will convert it to - * network byte order. - * - * If this is a save file, and it's from a - * machine with the opposite byte order to - * ours, we byte-swap the AF_ value. - * - * Then we run it through "htonl()", and - * generate code to compare against the result. - */ - if (bpf_pcap->sf.rfile != NULL && - bpf_pcap->sf.swapped) - proto = SWAPLONG(proto); - proto = htonl(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) { - - default: - return gen_false(); - -#ifdef INET6 - case ETHERTYPE_IPV6: - return (gen_cmp(off_linktype, BPF_B, - (bpf_int32)ARCTYPE_INET6)); -#endif /* INET6 */ - - case ETHERTYPE_IP: - 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); - - case ETHERTYPE_ARP: - 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); - - case ETHERTYPE_REVARP: - return (gen_cmp(off_linktype, BPF_B, - (bpf_int32)ARCTYPE_REVARP)); - - case ETHERTYPE_ATALK: - return (gen_cmp(off_linktype, BPF_B, - (bpf_int32)ARCTYPE_ATALK)); - } - break; - - case DLT_LTALK: - switch (proto) { - case ETHERTYPE_ATALK: - return gen_true(); - default: - 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"); - } - - /* - * All the types that have no encapsulation should either be - * handled as DLT_SLIP, DLT_SLIP_BSDOS, and DLT_RAW are, if - * all packets are IP packets, or should be handled in some - * special case, if none of them are (if some are and some - * aren't, the lack of encapsulation is a problem, as we'd - * have to find some other way of determining the packet type). - * - * Therefore, if "off_linktype" is -1, there's an error. - */ - if (off_linktype == (u_int)-1) - abort(); - - /* - * Any type not handled above should always have an Ethernet - * type at an offset of "off_linktype". (PPP is partially - * handled above - the protocol type is mapped from the - * Ethernet and LLC types we use internally to the corresponding - * PPP type - but the PPP type is always specified by a value - * at "off_linktype", so we don't have to do the code generation - * above.) - */ - return gen_cmp(off_linktype, BPF_H, (bpf_int32)proto); -} - -/* - * Check for an LLC SNAP packet with a given organization code and - * protocol type; we check the entire contents of the 802.2 LLC and - * snap headers, checking for DSAP and SSAP of SNAP and a control - * field of 0x03 in the LLC header, and for the specified organization - * code and protocol type in the SNAP header. - */ -static struct block * -gen_snap(orgcode, ptype, offset) - bpf_u_int32 orgcode; - bpf_u_int32 ptype; - u_int offset; -{ - u_char snapblock[8]; - - snapblock[0] = LLCSAP_SNAP; /* DSAP = SNAP */ - snapblock[1] = LLCSAP_SNAP; /* SSAP = SNAP */ - 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 */ - snapblock[6] = (ptype >> 8); /* upper 8 bits of protocol type */ - snapblock[7] = (ptype >> 0); /* lower 8 bits of protocol type */ - 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; - bpf_u_int32 mask; - int dir, proto; - u_int src_off, dst_off; -{ - struct block *b0, *b1; - u_int offset; - - switch (dir) { - - case Q_SRC: - offset = src_off; - break; - - case Q_DST: - offset = dst_off; - break; - - case Q_AND: - b0 = gen_hostop(addr, mask, Q_SRC, proto, src_off, dst_off); - b1 = gen_hostop(addr, mask, Q_DST, proto, src_off, dst_off); - gen_and(b0, b1); - return b1; - - case Q_OR: - case Q_DEFAULT: - b0 = gen_hostop(addr, mask, Q_SRC, proto, src_off, dst_off); - b1 = gen_hostop(addr, mask, Q_DST, proto, src_off, dst_off); - gen_or(b0, b1); - return b1; - - default: - abort(); - } - b0 = gen_linktype(proto); - b1 = gen_mcmp(offset, BPF_W, (bpf_int32)addr, mask); - gen_and(b0, b1); - return b1; -} - -#ifdef INET6 -static struct block * -gen_hostop6(addr, mask, dir, proto, src_off, dst_off) - struct in6_addr *addr; - struct in6_addr *mask; - int dir, proto; - u_int src_off, dst_off; -{ - struct block *b0, *b1; - u_int offset; - u_int32_t *a, *m; - - switch (dir) { - - case Q_SRC: - offset = src_off; - break; - - case Q_DST: - offset = dst_off; - break; - - case Q_AND: - b0 = gen_hostop6(addr, mask, Q_SRC, proto, src_off, dst_off); - b1 = gen_hostop6(addr, mask, Q_DST, proto, src_off, dst_off); - gen_and(b0, b1); - return b1; - - case Q_OR: - case Q_DEFAULT: - b0 = gen_hostop6(addr, mask, Q_SRC, proto, src_off, dst_off); - b1 = gen_hostop6(addr, mask, Q_DST, proto, src_off, dst_off); - gen_or(b0, b1); - return b1; - - default: - abort(); - } - /* this order is important */ - a = (u_int32_t *)addr; - m = (u_int32_t *)mask; - b1 = gen_mcmp(offset + 12, BPF_W, ntohl(a[3]), ntohl(m[3])); - b0 = gen_mcmp(offset + 8, BPF_W, ntohl(a[2]), ntohl(m[2])); - gen_and(b0, b1); - b0 = gen_mcmp(offset + 4, BPF_W, ntohl(a[1]), ntohl(m[1])); - gen_and(b0, b1); - b0 = gen_mcmp(offset + 0, BPF_W, ntohl(a[0]), ntohl(m[0])); - gen_and(b0, b1); - b0 = gen_linktype(proto); - gen_and(b0, b1); - return b1; -} -#endif /*INET6*/ - -static struct block * -gen_ehostop(eaddr, dir) - register const u_char *eaddr; - register int dir; -{ - register struct block *b0, *b1; - - switch (dir) { - case Q_SRC: - return gen_bcmp(off_mac + 6, 6, eaddr); - - case Q_DST: - return gen_bcmp(off_mac + 0, 6, eaddr); - - case Q_AND: - b0 = gen_ehostop(eaddr, Q_SRC); - b1 = gen_ehostop(eaddr, Q_DST); - gen_and(b0, b1); - return b1; - - case Q_DEFAULT: - case Q_OR: - b0 = gen_ehostop(eaddr, Q_SRC); - b1 = gen_ehostop(eaddr, Q_DST); - gen_or(b0, b1); - return b1; - } - abort(); - /* NOTREACHED */ -} - -/* - * Like gen_ehostop, but for DLT_FDDI - */ -static struct block * -gen_fhostop(eaddr, dir) - register const u_char *eaddr; - register int dir; -{ - struct block *b0, *b1; - - switch (dir) { - case Q_SRC: -#ifdef PCAP_FDDIPAD - return gen_bcmp(6 + 1 + pcap_fddipad, 6, eaddr); -#else - return gen_bcmp(6 + 1, 6, eaddr); -#endif - - case Q_DST: -#ifdef PCAP_FDDIPAD - return gen_bcmp(0 + 1 + pcap_fddipad, 6, eaddr); -#else - return gen_bcmp(0 + 1, 6, eaddr); -#endif - - case Q_AND: - b0 = gen_fhostop(eaddr, Q_SRC); - b1 = gen_fhostop(eaddr, Q_DST); - gen_and(b0, b1); - return b1; - - case Q_DEFAULT: - case Q_OR: - b0 = gen_fhostop(eaddr, Q_SRC); - b1 = gen_fhostop(eaddr, Q_DST); - gen_or(b0, b1); - return b1; - } - abort(); - /* NOTREACHED */ -} - -/* - * Like gen_ehostop, but for DLT_IEEE802 (Token Ring) - */ -static struct block * -gen_thostop(eaddr, dir) - register const u_char *eaddr; - register int dir; -{ - register struct block *b0, *b1; - - switch (dir) { - case Q_SRC: - return gen_bcmp(8, 6, eaddr); - - case Q_DST: - return gen_bcmp(2, 6, eaddr); - - case Q_AND: - b0 = gen_thostop(eaddr, Q_SRC); - b1 = gen_thostop(eaddr, Q_DST); - gen_and(b0, b1); - return b1; - - case Q_DEFAULT: - case Q_OR: - b0 = gen_thostop(eaddr, Q_SRC); - b1 = gen_thostop(eaddr, Q_DST); - gen_or(b0, b1); - return b1; - } - abort(); - /* NOTREACHED */ -} - -/* - * 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_ipfchostop(eaddr, dir) - register const u_char *eaddr; - register int dir; -{ - register struct block *b0, *b1; - - switch (dir) { - case Q_SRC: - return gen_bcmp(10, 6, eaddr); - - case Q_DST: - return gen_bcmp(2, 6, eaddr); - - case Q_AND: - 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_ipfchostop(eaddr, Q_SRC); - b1 = gen_ipfchostop(eaddr, Q_DST); - gen_or(b0, b1); - return b1; - } - abort(); - /* NOTREACHED */ -} - -/* - * This is quite tricky because there may be pad bytes in front of the - * DECNET header, and then there are two possible data packet formats that - * carry both src and dst addresses, plus 5 packet types in a format that - * carries only the src node, plus 2 types that use a different format and - * also carry just the src node. - * - * Yuck. - * - * Instead of doing those all right, we just look for data packets with - * 0 or 1 bytes of padding. If you want to look at other packets, that - * will require a lot more hacking. - * - * To add support for filtering on DECNET "areas" (network numbers) - * one would want to add a "mask" argument to this routine. That would - * make the filter even more inefficient, although one could be clever - * and not generate masking instructions if the mask is 0xFFFF. - */ -static struct block * -gen_dnhostop(addr, dir, base_off) - bpf_u_int32 addr; - int dir; - u_int base_off; -{ - struct block *b0, *b1, *b2, *tmp; - u_int offset_lh; /* offset if long header is received */ - u_int offset_sh; /* offset if short header is received */ - - switch (dir) { - - case Q_DST: - offset_sh = 1; /* follows flags */ - offset_lh = 7; /* flgs,darea,dsubarea,HIORD */ - break; - - case Q_SRC: - offset_sh = 3; /* follows flags, dstnode */ - offset_lh = 15; /* flgs,darea,dsubarea,did,sarea,ssub,HIORD */ - break; - - case Q_AND: - /* Inefficient because we do our Calvinball dance twice */ - b0 = gen_dnhostop(addr, Q_SRC, base_off); - b1 = gen_dnhostop(addr, Q_DST, base_off); - gen_and(b0, b1); - return b1; - - case Q_OR: - case Q_DEFAULT: - /* Inefficient because we do our Calvinball dance twice */ - b0 = gen_dnhostop(addr, Q_SRC, base_off); - b1 = gen_dnhostop(addr, Q_DST, base_off); - gen_or(b0, b1); - return b1; - - case Q_ISO: - bpf_error("ISO host filtering not implemented"); - - default: - abort(); - } - b0 = gen_linktype(ETHERTYPE_DN); - /* Check for pad = 1, long header case */ - tmp = gen_mcmp(base_off + 2, BPF_H, - (bpf_int32)ntohs(0x0681), (bpf_int32)ntohs(0x07FF)); - b1 = gen_cmp(base_off + 2 + 1 + offset_lh, - BPF_H, (bpf_int32)ntohs(addr)); - gen_and(tmp, b1); - /* Check for pad = 0, long header case */ - tmp = gen_mcmp(base_off + 2, BPF_B, (bpf_int32)0x06, (bpf_int32)0x7); - b2 = gen_cmp(base_off + 2 + offset_lh, BPF_H, (bpf_int32)ntohs(addr)); - gen_and(tmp, b2); - gen_or(b2, b1); - /* Check for pad = 1, short header case */ - tmp = gen_mcmp(base_off + 2, BPF_H, - (bpf_int32)ntohs(0x0281), (bpf_int32)ntohs(0x07FF)); - b2 = gen_cmp(base_off + 2 + 1 + offset_sh, - BPF_H, (bpf_int32)ntohs(addr)); - gen_and(tmp, b2); - gen_or(b2, b1); - /* Check for pad = 0, short header case */ - tmp = gen_mcmp(base_off + 2, BPF_B, (bpf_int32)0x02, (bpf_int32)0x7); - b2 = gen_cmp(base_off + 2 + offset_sh, BPF_H, (bpf_int32)ntohs(addr)); - gen_and(tmp, b2); - gen_or(b2, b1); - - /* Combine with test for linktype */ - gen_and(b0, b1); - return b1; -} - -static struct block * -gen_host(addr, mask, proto, dir) - bpf_u_int32 addr; - bpf_u_int32 mask; - int proto; - int dir; -{ - struct block *b0, *b1; - - switch (proto) { - - case Q_DEFAULT: - b0 = gen_host(addr, mask, Q_IP, dir); - 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); - gen_or(b1, b0); - } - return b0; - - case Q_IP: - return gen_hostop(addr, mask, dir, ETHERTYPE_IP, - off_nl + 12, off_nl + 16); - - case Q_RARP: - return gen_hostop(addr, mask, dir, ETHERTYPE_REVARP, - off_nl + 14, off_nl + 24); - - case Q_ARP: - return gen_hostop(addr, mask, dir, ETHERTYPE_ARP, - off_nl + 14, off_nl + 24); - - case Q_TCP: - bpf_error("'tcp' modifier applied to host"); - - case Q_SCTP: - bpf_error("'sctp' modifier applied to host"); - - case Q_UDP: - bpf_error("'udp' modifier applied to host"); - - case Q_ICMP: - bpf_error("'icmp' modifier applied to host"); - - case Q_IGMP: - bpf_error("'igmp' modifier applied to host"); - - case Q_IGRP: - bpf_error("'igrp' modifier applied to host"); - - case Q_PIM: - bpf_error("'pim' modifier applied to host"); - - case Q_VRRP: - bpf_error("'vrrp' modifier applied to host"); - - case Q_ATALK: - bpf_error("ATALK host filtering not implemented"); - - case Q_AARP: - bpf_error("AARP host filtering not implemented"); - - case Q_DECNET: - return gen_dnhostop(addr, dir, off_nl); - - case Q_SCA: - bpf_error("SCA host filtering not implemented"); - - case Q_LAT: - bpf_error("LAT host filtering not implemented"); - - case Q_MOPDL: - bpf_error("MOPDL host filtering not implemented"); - - case Q_MOPRC: - bpf_error("MOPRC host filtering not implemented"); - -#ifdef INET6 - case Q_IPV6: - bpf_error("'ip6' modifier applied to ip host"); - - case Q_ICMPV6: - bpf_error("'icmp6' modifier applied to host"); -#endif /* INET6 */ - - case Q_AH: - bpf_error("'ah' modifier applied to host"); - - case Q_ESP: - bpf_error("'esp' modifier applied to host"); - - case Q_ISO: - bpf_error("ISO host filtering not implemented"); - - case Q_ESIS: - bpf_error("'esis' modifier applied to host"); - - case Q_ISIS: - bpf_error("'isis' modifier applied to host"); - - case Q_CLNP: - bpf_error("'clnp' modifier applied to host"); - - case Q_STP: - bpf_error("'stp' modifier applied to host"); - - case Q_IPX: - bpf_error("IPX host filtering not implemented"); - - case Q_NETBEUI: - bpf_error("'netbeui' modifier applied to host"); - - default: - abort(); - } - /* NOTREACHED */ -} - -#ifdef INET6 -static struct block * -gen_host6(addr, mask, proto, dir) - struct in6_addr *addr; - struct in6_addr *mask; - int proto; - int dir; -{ - switch (proto) { - - case Q_DEFAULT: - return gen_host6(addr, mask, Q_IPV6, dir); - - case Q_IP: - bpf_error("'ip' modifier applied to ip6 host"); - - case Q_RARP: - bpf_error("'rarp' modifier applied to ip6 host"); - - case Q_ARP: - bpf_error("'arp' modifier applied to ip6 host"); - - case Q_SCTP: - bpf_error("'sctp' modifier applied to host"); - - case Q_TCP: - bpf_error("'tcp' modifier applied to host"); - - case Q_UDP: - bpf_error("'udp' modifier applied to host"); - - case Q_ICMP: - bpf_error("'icmp' modifier applied to host"); - - case Q_IGMP: - bpf_error("'igmp' modifier applied to host"); - - case Q_IGRP: - bpf_error("'igrp' modifier applied to host"); - - case Q_PIM: - bpf_error("'pim' modifier applied to host"); - - case Q_VRRP: - bpf_error("'vrrp' modifier applied to host"); - - case Q_ATALK: - bpf_error("ATALK host filtering not implemented"); - - case Q_AARP: - bpf_error("AARP host filtering not implemented"); - - case Q_DECNET: - bpf_error("'decnet' modifier applied to ip6 host"); - - case Q_SCA: - bpf_error("SCA host filtering not implemented"); - - case Q_LAT: - bpf_error("LAT host filtering not implemented"); - - case Q_MOPDL: - bpf_error("MOPDL host filtering not implemented"); - - case Q_MOPRC: - bpf_error("MOPRC host filtering not implemented"); - - case Q_IPV6: - return gen_hostop6(addr, mask, dir, ETHERTYPE_IPV6, - off_nl + 8, off_nl + 24); - - case Q_ICMPV6: - bpf_error("'icmp6' modifier applied to host"); - - case Q_AH: - bpf_error("'ah' modifier applied to host"); - - case Q_ESP: - bpf_error("'esp' modifier applied to host"); - - case Q_ISO: - bpf_error("ISO host filtering not implemented"); - - case Q_ESIS: - bpf_error("'esis' modifier applied to host"); - - case Q_ISIS: - bpf_error("'isis' modifier applied to host"); - - case Q_CLNP: - bpf_error("'clnp' modifier applied to host"); - - case Q_STP: - bpf_error("'stp' modifier applied to host"); - - case Q_IPX: - bpf_error("IPX host filtering not implemented"); - - case Q_NETBEUI: - bpf_error("'netbeui' modifier applied to host"); - - default: - abort(); - } - /* NOTREACHED */ -} -#endif /*INET6*/ - -#ifndef INET6 -static struct block * -gen_gateway(eaddr, alist, proto, dir) - const u_char *eaddr; - bpf_u_int32 **alist; - int proto; - int dir; -{ - struct block *b0, *b1, *tmp; - - if (dir != 0) - bpf_error("direction applied to 'gateway'"); - - switch (proto) { - case Q_DEFAULT: - case Q_IP: - case Q_ARP: - case Q_RARP: - if (linktype == DLT_EN10MB) - b0 = gen_ehostop(eaddr, Q_OR); - 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) - 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/token ring/802.11/Fibre Channel"); - - b1 = gen_host(**alist++, 0xffffffff, proto, Q_OR); - while (*alist) { - tmp = gen_host(**alist++, 0xffffffff, proto, Q_OR); - gen_or(b1, tmp); - b1 = tmp; - } - gen_not(b1); - gen_and(b0, b1); - return b1; - } - bpf_error("illegal modifier of 'gateway'"); - /* NOTREACHED */ -} -#endif - -struct block * -gen_proto_abbrev(proto) - int proto; -{ - struct block *b0; - struct block *b1; - - switch (proto) { - - case Q_SCTP: - b1 = gen_proto(IPPROTO_SCTP, Q_IP, Q_DEFAULT); -#ifdef INET6 - b0 = gen_proto(IPPROTO_SCTP, Q_IPV6, Q_DEFAULT); - gen_or(b0, b1); -#endif - break; - - case Q_TCP: - b1 = gen_proto(IPPROTO_TCP, Q_IP, Q_DEFAULT); -#ifdef INET6 - b0 = gen_proto(IPPROTO_TCP, Q_IPV6, Q_DEFAULT); - gen_or(b0, b1); -#endif - break; - - case Q_UDP: - b1 = gen_proto(IPPROTO_UDP, Q_IP, Q_DEFAULT); -#ifdef INET6 - b0 = gen_proto(IPPROTO_UDP, Q_IPV6, Q_DEFAULT); - gen_or(b0, b1); -#endif - break; - - case Q_ICMP: - b1 = gen_proto(IPPROTO_ICMP, Q_IP, Q_DEFAULT); - break; - -#ifndef IPPROTO_IGMP -#define IPPROTO_IGMP 2 -#endif - - case Q_IGMP: - b1 = gen_proto(IPPROTO_IGMP, Q_IP, Q_DEFAULT); - break; - -#ifndef IPPROTO_IGRP -#define IPPROTO_IGRP 9 -#endif - case Q_IGRP: - b1 = gen_proto(IPPROTO_IGRP, Q_IP, Q_DEFAULT); - break; - -#ifndef IPPROTO_PIM -#define IPPROTO_PIM 103 -#endif - - case Q_PIM: - b1 = gen_proto(IPPROTO_PIM, Q_IP, Q_DEFAULT); -#ifdef INET6 - b0 = gen_proto(IPPROTO_PIM, Q_IPV6, Q_DEFAULT); - gen_or(b0, b1); -#endif - break; - -#ifndef IPPROTO_VRRP -#define IPPROTO_VRRP 112 -#endif - - case Q_VRRP: - b1 = gen_proto(IPPROTO_VRRP, Q_IP, Q_DEFAULT); - break; - - case Q_IP: - b1 = gen_linktype(ETHERTYPE_IP); - break; - - case Q_ARP: - b1 = gen_linktype(ETHERTYPE_ARP); - break; - - case Q_RARP: - b1 = gen_linktype(ETHERTYPE_REVARP); - break; - - case Q_LINK: - bpf_error("link layer applied in wrong context"); - - case Q_ATALK: - b1 = gen_linktype(ETHERTYPE_ATALK); - break; - - case Q_AARP: - b1 = gen_linktype(ETHERTYPE_AARP); - break; - - case Q_DECNET: - b1 = gen_linktype(ETHERTYPE_DN); - break; - - case Q_SCA: - b1 = gen_linktype(ETHERTYPE_SCA); - break; - - case Q_LAT: - b1 = gen_linktype(ETHERTYPE_LAT); - break; - - case Q_MOPDL: - b1 = gen_linktype(ETHERTYPE_MOPDL); - break; - - case Q_MOPRC: - b1 = gen_linktype(ETHERTYPE_MOPRC); - break; - -#ifdef INET6 - case Q_IPV6: - b1 = gen_linktype(ETHERTYPE_IPV6); - break; - -#ifndef IPPROTO_ICMPV6 -#define IPPROTO_ICMPV6 58 -#endif - case Q_ICMPV6: - b1 = gen_proto(IPPROTO_ICMPV6, Q_IPV6, Q_DEFAULT); - break; -#endif /* INET6 */ - -#ifndef IPPROTO_AH -#define IPPROTO_AH 51 -#endif - case Q_AH: - b1 = gen_proto(IPPROTO_AH, Q_IP, Q_DEFAULT); -#ifdef INET6 - b0 = gen_proto(IPPROTO_AH, Q_IPV6, Q_DEFAULT); - gen_or(b0, b1); -#endif - break; - -#ifndef IPPROTO_ESP -#define IPPROTO_ESP 50 -#endif - case Q_ESP: - b1 = gen_proto(IPPROTO_ESP, Q_IP, Q_DEFAULT); -#ifdef INET6 - b0 = gen_proto(IPPROTO_ESP, Q_IPV6, Q_DEFAULT); - gen_or(b0, b1); -#endif - break; - - case Q_ISO: - b1 = gen_linktype(LLCSAP_ISONS); - break; - - case Q_ESIS: - b1 = gen_proto(ISO9542_ESIS, Q_ISO, Q_DEFAULT); - break; - - case Q_ISIS: - 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; - - case Q_STP: - b1 = gen_linktype(LLCSAP_8021D); - break; - - case Q_IPX: - b1 = gen_linktype(LLCSAP_IPX); - break; - - case Q_NETBEUI: - b1 = gen_linktype(LLCSAP_NETBEUI); - break; - - default: - abort(); - } - return b1; -} - -static struct block * -gen_ipfrag() -{ - struct slist *s; - struct block *b; - - /* not ip frag */ - s = new_stmt(BPF_LD|BPF_H|BPF_ABS); - s->s.k = off_nl + 6; - b = new_block(JMP(BPF_JSET)); - b->s.k = 0x1fff; - b->stmts = s; - gen_not(b); - - return b; -} - -static struct block * -gen_portatom(off, v) - int off; - bpf_int32 v; -{ - struct slist *s; - struct block *b; - - s = new_stmt(BPF_LDX|BPF_MSH|BPF_B); - s->s.k = off_nl; - - s->next = new_stmt(BPF_LD|BPF_IND|BPF_H); - s->next->s.k = off_nl + off; - - b = new_block(JMP(BPF_JEQ)); - b->stmts = s; - b->s.k = v; - - return b; -} - -#ifdef INET6 -static struct block * -gen_portatom6(off, v) - int off; - bpf_int32 v; -{ - return gen_cmp(off_nl + 40 + off, BPF_H, v); -} -#endif/*INET6*/ - -struct block * -gen_portop(port, proto, dir) - int port, proto, dir; -{ - struct block *b0, *b1, *tmp; - - /* ip proto 'proto' */ - tmp = gen_cmp(off_nl + 9, BPF_B, (bpf_int32)proto); - b0 = gen_ipfrag(); - gen_and(tmp, b0); - - switch (dir) { - case Q_SRC: - b1 = gen_portatom(0, (bpf_int32)port); - break; - - case Q_DST: - b1 = gen_portatom(2, (bpf_int32)port); - break; - - case Q_OR: - case Q_DEFAULT: - tmp = gen_portatom(0, (bpf_int32)port); - b1 = gen_portatom(2, (bpf_int32)port); - gen_or(tmp, b1); - break; - - case Q_AND: - tmp = gen_portatom(0, (bpf_int32)port); - b1 = gen_portatom(2, (bpf_int32)port); - gen_and(tmp, b1); - break; - - default: - abort(); - } - gen_and(b0, b1); - - return b1; -} - -static struct block * -gen_port(port, ip_proto, dir) - int port; - int ip_proto; - int dir; -{ - struct block *b0, *b1, *tmp; - - /* - * ether proto ip - * - * 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) { - case IPPROTO_UDP: - case IPPROTO_TCP: - case IPPROTO_SCTP: - b1 = gen_portop(port, ip_proto, dir); - break; - - case PROTO_UNDEF: - tmp = gen_portop(port, IPPROTO_TCP, dir); - b1 = gen_portop(port, IPPROTO_UDP, dir); - gen_or(tmp, b1); - tmp = gen_portop(port, IPPROTO_SCTP, dir); - gen_or(tmp, b1); - break; - - default: - abort(); - } - gen_and(b0, b1); - return b1; -} - -#ifdef INET6 -struct block * -gen_portop6(port, proto, dir) - int port, proto, dir; -{ - struct block *b0, *b1, *tmp; - - /* ip proto 'proto' */ - b0 = gen_cmp(off_nl + 6, BPF_B, (bpf_int32)proto); - - switch (dir) { - case Q_SRC: - b1 = gen_portatom6(0, (bpf_int32)port); - break; - - case Q_DST: - b1 = gen_portatom6(2, (bpf_int32)port); - break; - - case Q_OR: - case Q_DEFAULT: - tmp = gen_portatom6(0, (bpf_int32)port); - b1 = gen_portatom6(2, (bpf_int32)port); - gen_or(tmp, b1); - break; - - case Q_AND: - tmp = gen_portatom6(0, (bpf_int32)port); - b1 = gen_portatom6(2, (bpf_int32)port); - gen_and(tmp, b1); - break; - - default: - abort(); - } - gen_and(b0, b1); - - return b1; -} - -static struct block * -gen_port6(port, ip_proto, dir) - int port; - int ip_proto; - int dir; -{ - struct block *b0, *b1, *tmp; - - /* ether proto ip */ - b0 = gen_linktype(ETHERTYPE_IPV6); - - switch (ip_proto) { - case IPPROTO_UDP: - case IPPROTO_TCP: - case IPPROTO_SCTP: - b1 = gen_portop6(port, ip_proto, dir); - break; - - case PROTO_UNDEF: - tmp = gen_portop6(port, IPPROTO_TCP, dir); - b1 = gen_portop6(port, IPPROTO_UDP, dir); - gen_or(tmp, b1); - tmp = gen_portop6(port, IPPROTO_SCTP, dir); - gen_or(tmp, b1); - break; - - default: - abort(); - } - gen_and(b0, b1); - return b1; -} -#endif /* INET6 */ - -static int -lookup_proto(name, proto) - register const char *name; - register int proto; -{ - register int v; - - switch (proto) { - - case Q_DEFAULT: - case Q_IP: - case Q_IPV6: - v = pcap_nametoproto(name); - if (v == PROTO_UNDEF) - bpf_error("unknown ip proto '%s'", name); - break; - - case Q_LINK: - /* XXX should look up h/w protocol type based on linktype */ - v = pcap_nametoeproto(name); - if (v == PROTO_UNDEF) - bpf_error("unknown ether proto '%s'", name); - break; - - case Q_ISO: - if (strcmp(name, "esis") == 0) - v = ISO9542_ESIS; - else if (strcmp(name, "isis") == 0) - v = ISO10589_ISIS; - else if (strcmp(name, "clnp") == 0) - v = ISO8473_CLNP; - else - bpf_error("unknown osi proto '%s'", name); - break; - - default: - v = PROTO_UNDEF; - break; - } - return v; -} - -#if 0 -struct stmt * -gen_joinsp(s, n) - struct stmt **s; - int n; -{ - return NULL; -} -#endif - -static struct block * -gen_protochain(v, proto, dir) - int v; - int proto; - int dir; -{ -#ifdef NO_PROTOCHAIN - return gen_proto(v, proto, dir); -#else - struct block *b0, *b; - struct slist *s[100]; - int fix2, fix3, fix4, fix5; - int ahcheck, again, end; - int i, max; - int reg2 = alloc_reg(); - - memset(s, 0, sizeof(s)); - fix2 = fix3 = fix4 = fix5 = 0; - - switch (proto) { - case Q_IP: - case Q_IPV6: - break; - case Q_DEFAULT: - b0 = gen_protochain(v, Q_IP, dir); - b = gen_protochain(v, Q_IPV6, dir); - gen_or(b0, b); - return b; - default: - bpf_error("bad protocol applied for 'protochain'"); - /*NOTREACHED*/ - } - - no_optimize = 1; /*this code is not compatible with optimzer yet */ - - /* - * s[0] is a dummy entry to protect other BPF insn from damaged - * by s[fix] = foo with uninitialized variable "fix". It is somewhat - * hard to find interdependency made by jump table fixup. - */ - i = 0; - s[i] = new_stmt(0); /*dummy*/ - i++; - - switch (proto) { - case Q_IP: - b0 = gen_linktype(ETHERTYPE_IP); - - /* A = ip->ip_p */ - s[i] = new_stmt(BPF_LD|BPF_ABS|BPF_B); - s[i]->s.k = 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; - i++; - break; -#ifdef INET6 - case Q_IPV6: - b0 = gen_linktype(ETHERTYPE_IPV6); - - /* A = ip6->ip_nxt */ - s[i] = new_stmt(BPF_LD|BPF_ABS|BPF_B); - s[i]->s.k = off_nl + 6; - i++; - /* X = sizeof(struct ip6_hdr) */ - s[i] = new_stmt(BPF_LDX|BPF_IMM); - s[i]->s.k = 40; - i++; - break; -#endif - default: - bpf_error("unsupported proto to gen_protochain"); - /*NOTREACHED*/ - } - - /* again: if (A == v) goto end; else fall through; */ - again = i; - s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K); - s[i]->s.k = v; - s[i]->s.jt = NULL; /*later*/ - s[i]->s.jf = NULL; /*update in next stmt*/ - fix5 = i; - i++; - -#ifndef IPPROTO_NONE -#define IPPROTO_NONE 59 -#endif - /* if (A == IPPROTO_NONE) goto end */ - s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K); - s[i]->s.jt = NULL; /*later*/ - s[i]->s.jf = NULL; /*update in next stmt*/ - s[i]->s.k = IPPROTO_NONE; - s[fix5]->s.jf = s[i]; - fix2 = i; - i++; - -#ifdef INET6 - if (proto == Q_IPV6) { - int v6start, v6end, v6advance, j; - - v6start = i; - /* if (A == IPPROTO_HOPOPTS) goto v6advance */ - s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K); - s[i]->s.jt = NULL; /*later*/ - s[i]->s.jf = NULL; /*update in next stmt*/ - s[i]->s.k = IPPROTO_HOPOPTS; - s[fix2]->s.jf = s[i]; - i++; - /* if (A == IPPROTO_DSTOPTS) goto v6advance */ - s[i - 1]->s.jf = s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K); - s[i]->s.jt = NULL; /*later*/ - s[i]->s.jf = NULL; /*update in next stmt*/ - s[i]->s.k = IPPROTO_DSTOPTS; - i++; - /* if (A == IPPROTO_ROUTING) goto v6advance */ - s[i - 1]->s.jf = s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K); - s[i]->s.jt = NULL; /*later*/ - s[i]->s.jf = NULL; /*update in next stmt*/ - s[i]->s.k = IPPROTO_ROUTING; - i++; - /* if (A == IPPROTO_FRAGMENT) goto v6advance; else goto ahcheck; */ - s[i - 1]->s.jf = s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K); - s[i]->s.jt = NULL; /*later*/ - s[i]->s.jf = NULL; /*later*/ - s[i]->s.k = IPPROTO_FRAGMENT; - fix3 = i; - v6end = i; - i++; - - /* v6advance: */ - v6advance = i; - - /* - * in short, - * A = P[X]; - * X = X + (P[X + 1] + 1) * 8; - */ - /* A = X */ - s[i] = new_stmt(BPF_MISC|BPF_TXA); - i++; - /* A = P[X + packet head] */ - s[i] = new_stmt(BPF_LD|BPF_IND|BPF_B); - s[i]->s.k = off_nl; - i++; - /* MEM[reg2] = A */ - s[i] = new_stmt(BPF_ST); - s[i]->s.k = reg2; - i++; - /* A = X */ - s[i] = new_stmt(BPF_MISC|BPF_TXA); - i++; - /* A += 1 */ - s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K); - s[i]->s.k = 1; - i++; - /* X = A */ - s[i] = new_stmt(BPF_MISC|BPF_TAX); - i++; - /* A = P[X + packet head]; */ - s[i] = new_stmt(BPF_LD|BPF_IND|BPF_B); - s[i]->s.k = off_nl; - i++; - /* A += 1 */ - s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K); - s[i]->s.k = 1; - i++; - /* A *= 8 */ - s[i] = new_stmt(BPF_ALU|BPF_MUL|BPF_K); - s[i]->s.k = 8; - i++; - /* X = A; */ - s[i] = new_stmt(BPF_MISC|BPF_TAX); - i++; - /* A = MEM[reg2] */ - s[i] = new_stmt(BPF_LD|BPF_MEM); - s[i]->s.k = reg2; - i++; - - /* goto again; (must use BPF_JA for backward jump) */ - s[i] = new_stmt(BPF_JMP|BPF_JA); - s[i]->s.k = again - i - 1; - s[i - 1]->s.jf = s[i]; - i++; - - /* fixup */ - for (j = v6start; j <= v6end; j++) - s[j]->s.jt = s[v6advance]; - } else -#endif - { - /* nop */ - s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K); - s[i]->s.k = 0; - s[fix2]->s.jf = s[i]; - i++; - } - - /* ahcheck: */ - ahcheck = i; - /* if (A == IPPROTO_AH) then fall through; else goto end; */ - s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K); - s[i]->s.jt = NULL; /*later*/ - s[i]->s.jf = NULL; /*later*/ - s[i]->s.k = IPPROTO_AH; - if (fix3) - s[fix3]->s.jf = s[ahcheck]; - fix4 = i; - i++; - - /* - * in short, - * A = P[X]; - * X = X + (P[X + 1] + 2) * 4; - */ - /* A = X */ - s[i - 1]->s.jt = s[i] = new_stmt(BPF_MISC|BPF_TXA); - i++; - /* A = P[X + packet head]; */ - s[i] = new_stmt(BPF_LD|BPF_IND|BPF_B); - s[i]->s.k = off_nl; - i++; - /* MEM[reg2] = A */ - s[i] = new_stmt(BPF_ST); - s[i]->s.k = reg2; - i++; - /* A = X */ - s[i - 1]->s.jt = s[i] = new_stmt(BPF_MISC|BPF_TXA); - i++; - /* A += 1 */ - s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K); - s[i]->s.k = 1; - i++; - /* X = A */ - s[i] = new_stmt(BPF_MISC|BPF_TAX); - i++; - /* A = P[X + packet head] */ - s[i] = new_stmt(BPF_LD|BPF_IND|BPF_B); - s[i]->s.k = off_nl; - i++; - /* A += 2 */ - s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K); - s[i]->s.k = 2; - i++; - /* A *= 4 */ - s[i] = new_stmt(BPF_ALU|BPF_MUL|BPF_K); - s[i]->s.k = 4; - i++; - /* X = A; */ - s[i] = new_stmt(BPF_MISC|BPF_TAX); - i++; - /* A = MEM[reg2] */ - s[i] = new_stmt(BPF_LD|BPF_MEM); - s[i]->s.k = reg2; - i++; - - /* goto again; (must use BPF_JA for backward jump) */ - s[i] = new_stmt(BPF_JMP|BPF_JA); - s[i]->s.k = again - i - 1; - i++; - - /* end: nop */ - end = i; - s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K); - s[i]->s.k = 0; - s[fix2]->s.jt = s[end]; - s[fix4]->s.jf = s[end]; - s[fix5]->s.jt = s[end]; - i++; - - /* - * make slist chain - */ - max = i; - for (i = 0; i < max - 1; i++) - s[i]->next = s[i + 1]; - s[max - 1]->next = NULL; - - /* - * emit final check - */ - b = new_block(JMP(BPF_JEQ)); - b->stmts = s[1]; /*remember, s[0] is dummy*/ - b->s.k = v; - - free_reg(reg2); - - gen_and(b0, b); - return b; -#endif -} - -static struct block * -gen_proto(v, proto, dir) - int v; - int proto; - int dir; -{ - struct block *b0, *b1; - - if (dir != Q_DEFAULT) - bpf_error("direction applied to 'proto'"); - - switch (proto) { - case Q_DEFAULT: -#ifdef INET6 - b0 = gen_proto(v, Q_IP, dir); - b1 = gen_proto(v, Q_IPV6, dir); - gen_or(b0, b1); - return b1; -#else - /*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); -#else - b1 = gen_protochain(v, Q_IP); -#endif - gen_and(b0, b1); - return b1; - - case Q_ISO: - 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; - - case Q_ARP: - bpf_error("arp does not encapsulate another protocol"); - /* NOTREACHED */ - - case Q_RARP: - bpf_error("rarp does not encapsulate another protocol"); - /* NOTREACHED */ - - case Q_ATALK: - bpf_error("atalk encapsulation is not specifiable"); - /* NOTREACHED */ - - case Q_DECNET: - bpf_error("decnet encapsulation is not specifiable"); - /* NOTREACHED */ - - case Q_SCA: - bpf_error("sca does not encapsulate another protocol"); - /* NOTREACHED */ - - case Q_LAT: - bpf_error("lat does not encapsulate another protocol"); - /* NOTREACHED */ - - case Q_MOPRC: - bpf_error("moprc does not encapsulate another protocol"); - /* NOTREACHED */ - - case Q_MOPDL: - bpf_error("mopdl does not encapsulate another protocol"); - /* NOTREACHED */ - - case Q_LINK: - return gen_linktype(v); - - case Q_UDP: - bpf_error("'udp proto' is bogus"); - /* NOTREACHED */ - - case Q_TCP: - bpf_error("'tcp proto' is bogus"); - /* NOTREACHED */ - - case Q_SCTP: - bpf_error("'sctp proto' is bogus"); - /* NOTREACHED */ - - case Q_ICMP: - bpf_error("'icmp proto' is bogus"); - /* NOTREACHED */ - - case Q_IGMP: - bpf_error("'igmp proto' is bogus"); - /* NOTREACHED */ - - case Q_IGRP: - bpf_error("'igrp proto' is bogus"); - /* NOTREACHED */ - - case Q_PIM: - bpf_error("'pim proto' is bogus"); - /* NOTREACHED */ - - case Q_VRRP: - bpf_error("'vrrp proto' is bogus"); - /* NOTREACHED */ - -#ifdef INET6 - case Q_IPV6: - b0 = gen_linktype(ETHERTYPE_IPV6); -#ifndef CHASE_CHAIN - b1 = gen_cmp(off_nl + 6, BPF_B, (bpf_int32)v); -#else - b1 = gen_protochain(v, Q_IPV6); -#endif - gen_and(b0, b1); - return b1; - - case Q_ICMPV6: - bpf_error("'icmp6 proto' is bogus"); -#endif /* INET6 */ - - case Q_AH: - bpf_error("'ah proto' is bogus"); - - case Q_ESP: - bpf_error("'ah proto' is bogus"); - - case Q_STP: - bpf_error("'stp proto' is bogus"); - - case Q_IPX: - bpf_error("'ipx proto' is bogus"); - - case Q_NETBEUI: - bpf_error("'netbeui proto' is bogus"); - - default: - abort(); - /* NOTREACHED */ - } - /* NOTREACHED */ -} - -struct block * -gen_scode(name, q) - register const char *name; - struct qual q; -{ - int proto = q.proto; - int dir = q.dir; - int tproto; - u_char *eaddr; - bpf_u_int32 mask, addr; -#ifndef INET6 - bpf_u_int32 **alist; -#else - int tproto6; - struct sockaddr_in *sin; - struct sockaddr_in6 *sin6; - struct addrinfo *res, *res0; - struct in6_addr mask128; -#endif /*INET6*/ - struct block *b, *tmp; - int port, real_proto; - - switch (q.addr) { - - case Q_NET: - addr = pcap_nametonetaddr(name); - if (addr == 0) - bpf_error("unknown network '%s'", name); - /* Left justify network addr and calculate its network mask */ - mask = 0xffffffff; - while (addr && (addr & 0xff000000) == 0) { - addr <<= 8; - mask <<= 8; - } - return gen_host(addr, mask, proto, dir); - - case Q_DEFAULT: - case Q_HOST: - if (proto == Q_LINK) { - switch (linktype) { - - case DLT_EN10MB: - eaddr = pcap_ether_hostton(name); - if (eaddr == NULL) - bpf_error( - "unknown ether host '%s'", name); - b = gen_ehostop(eaddr, dir); - free(eaddr); - return b; - - case DLT_FDDI: - eaddr = pcap_ether_hostton(name); - if (eaddr == NULL) - bpf_error( - "unknown FDDI host '%s'", name); - b = gen_fhostop(eaddr, dir); - free(eaddr); - return b; - - case DLT_IEEE802: - eaddr = pcap_ether_hostton(name); - if (eaddr == NULL) - bpf_error( - "unknown token ring host '%s'", name); - b = gen_thostop(eaddr, dir); - free(eaddr); - return b; - - case DLT_IEEE802_11: - eaddr = pcap_ether_hostton(name); - if (eaddr == NULL) - bpf_error( - "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; - - 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); - /* - * I don't think DECNET hosts can be multihomed, so - * there is no need to build up a list of addresses - */ - return (gen_host(dn_addr, 0, proto, dir)); - } else { -#ifndef INET6 - alist = pcap_nametoaddr(name); - if (alist == NULL || *alist == NULL) - bpf_error("unknown host '%s'", name); - tproto = proto; - if (off_linktype == (u_int)-1 && tproto == Q_DEFAULT) - tproto = Q_IP; - b = gen_host(**alist++, 0xffffffff, tproto, dir); - while (*alist) { - tmp = gen_host(**alist++, 0xffffffff, - tproto, dir); - gen_or(b, tmp); - b = tmp; - } - return b; -#else - memset(&mask128, 0xff, sizeof(mask128)); - res0 = res = pcap_nametoaddrinfo(name); - if (res == NULL) - bpf_error("unknown host '%s'", name); - b = tmp = NULL; - tproto = tproto6 = proto; - if (off_linktype == -1 && tproto == Q_DEFAULT) { - tproto = Q_IP; - tproto6 = Q_IPV6; - } - for (res = res0; res; res = res->ai_next) { - switch (res->ai_family) { - case AF_INET: - if (tproto == Q_IPV6) - continue; - - sin = (struct sockaddr_in *) - res->ai_addr; - tmp = gen_host(ntohl(sin->sin_addr.s_addr), - 0xffffffff, tproto, dir); - break; - case AF_INET6: - if (tproto6 == Q_IP) - continue; - - sin6 = (struct sockaddr_in6 *) - res->ai_addr; - tmp = gen_host6(&sin6->sin6_addr, - &mask128, tproto6, dir); - break; - default: - continue; - } - if (b) - gen_or(b, tmp); - b = tmp; - } - freeaddrinfo(res0); - if (b == NULL) { - bpf_error("unknown host '%s'%s", name, - (proto == Q_DEFAULT) - ? "" - : " for specified address family"); - } - return b; -#endif /*INET6*/ - } - - case Q_PORT: - if (proto != Q_DEFAULT && - proto != Q_UDP && proto != Q_TCP && proto != Q_SCTP) - bpf_error("illegal qualifier of 'port'"); - if (pcap_nametoport(name, &port, &real_proto) == 0) - bpf_error("unknown port '%s'", name); - if (proto == Q_UDP) { - if (real_proto == IPPROTO_TCP) - bpf_error("port '%s' is tcp", name); - else if (real_proto == IPPROTO_SCTP) - bpf_error("port '%s' is sctp", name); - else - /* override PROTO_UNDEF */ - real_proto = IPPROTO_UDP; - } - if (proto == Q_TCP) { - if (real_proto == IPPROTO_UDP) - bpf_error("port '%s' is udp", name); - - else if (real_proto == IPPROTO_SCTP) - bpf_error("port '%s' is sctp", name); - else - /* override PROTO_UNDEF */ - real_proto = IPPROTO_TCP; - } - if (proto == Q_SCTP) { - if (real_proto == IPPROTO_UDP) - bpf_error("port '%s' is udp", name); - - else if (real_proto == IPPROTO_TCP) - bpf_error("port '%s' is tcp", name); - else - /* override PROTO_UNDEF */ - real_proto = IPPROTO_SCTP; - } -#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_GATEWAY: -#ifndef INET6 - eaddr = pcap_ether_hostton(name); - if (eaddr == NULL) - bpf_error("unknown ether host: %s", name); - - alist = pcap_nametoaddr(name); - if (alist == NULL || *alist == NULL) - bpf_error("unknown host '%s'", name); - b = gen_gateway(eaddr, alist, proto, dir); - free(eaddr); - return b; -#else - bpf_error("'gateway' not supported in this configuration"); -#endif /*INET6*/ - - case Q_PROTO: - real_proto = lookup_proto(name, proto); - if (real_proto >= 0) - return gen_proto(real_proto, proto, dir); - else - bpf_error("unknown protocol: %s", name); - - case Q_PROTOCHAIN: - real_proto = lookup_proto(name, proto); - if (real_proto >= 0) - return gen_protochain(real_proto, proto, dir); - else - bpf_error("unknown protocol: %s", name); - - - case Q_UNDEF: - syntax(); - /* NOTREACHED */ - } - abort(); - /* NOTREACHED */ -} - -struct block * -gen_mcode(s1, s2, masklen, q) - register const char *s1, *s2; - register int masklen; - struct qual q; -{ - register int nlen, mlen; - bpf_u_int32 n, m; - - nlen = __pcap_atoin(s1, &n); - /* Promote short ipaddr */ - n <<= 32 - nlen; - - if (s2 != NULL) { - mlen = __pcap_atoin(s2, &m); - /* Promote short ipaddr */ - m <<= 32 - mlen; - if ((n & ~m) != 0) - bpf_error("non-network bits set in \"%s mask %s\"", - s1, s2); - } else { - /* Convert mask len to mask */ - if (masklen > 32) - bpf_error("mask length must be <= 32"); - m = 0xffffffff << (32 - masklen); - if ((n & ~m) != 0) - bpf_error("non-network bits set in \"%s/%d\"", - s1, masklen); - } - - switch (q.addr) { - - case Q_NET: - return gen_host(n, m, q.proto, q.dir); - - default: - bpf_error("Mask syntax for networks only"); - /* NOTREACHED */ - } -} - -struct block * -gen_ncode(s, v, q) - register const char *s; - bpf_u_int32 v; - struct qual q; -{ - bpf_u_int32 mask; - int proto = q.proto; - int dir = q.dir; - register int vlen; - - if (s == NULL) - vlen = 32; - else if (q.proto == Q_DECNET) - vlen = __pcap_atodn(s, &v); - else - vlen = __pcap_atoin(s, &v); - - switch (q.addr) { - - case Q_DEFAULT: - case Q_HOST: - case Q_NET: - if (proto == Q_DECNET) - return gen_host(v, 0, proto, dir); - else if (proto == Q_LINK) { - bpf_error("illegal link layer address"); - } else { - mask = 0xffffffff; - if (s == NULL && q.addr == Q_NET) { - /* Promote short net number */ - while (v && (v & 0xff000000) == 0) { - v <<= 8; - mask <<= 8; - } - } else { - /* Promote short ipaddr */ - v <<= 32 - vlen; - mask <<= 32 - vlen; - } - return gen_host(v, mask, proto, dir); - } - - case Q_PORT: - if (proto == Q_UDP) - proto = IPPROTO_UDP; - else if (proto == Q_TCP) - proto = IPPROTO_TCP; - else if (proto == Q_SCTP) - proto = IPPROTO_SCTP; - else if (proto == Q_DEFAULT) - proto = PROTO_UNDEF; - else - bpf_error("illegal qualifier of 'port'"); - -#ifndef INET6 - return gen_port((int)v, proto, dir); -#else - { - struct block *b; - b = gen_port((int)v, proto, dir); - gen_or(gen_port6((int)v, proto, dir), b); - return b; - } -#endif /* INET6 */ - - case Q_GATEWAY: - bpf_error("'gateway' requires a name"); - /* NOTREACHED */ - - case Q_PROTO: - return gen_proto((int)v, proto, dir); - - case Q_PROTOCHAIN: - return gen_protochain((int)v, proto, dir); - - case Q_UNDEF: - syntax(); - /* NOTREACHED */ - - default: - abort(); - /* NOTREACHED */ - } - /* NOTREACHED */ -} - -#ifdef INET6 -struct block * -gen_mcode6(s1, s2, masklen, q) - register const char *s1, *s2; - register int masklen; - struct qual q; -{ - struct addrinfo *res; - struct in6_addr *addr; - struct in6_addr mask; - struct block *b; - u_int32_t *a, *m; - - if (s2) - bpf_error("no mask %s supported", s2); - - res = pcap_nametoaddrinfo(s1); - if (!res) - bpf_error("invalid ip6 address %s", s1); - if (res->ai_next) - bpf_error("%s resolved to multiple address", s1); - addr = &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr; - - if (sizeof(mask) * 8 < masklen) - bpf_error("mask length must be <= %u", (unsigned int)(sizeof(mask) * 8)); - memset(&mask, 0, sizeof(mask)); - memset(&mask, 0xff, masklen / 8); - if (masklen % 8) { - mask.s6_addr[masklen / 8] = - (0xff << (8 - masklen % 8)) & 0xff; - } - - a = (u_int32_t *)addr; - m = (u_int32_t *)&mask; - if ((a[0] & ~m[0]) || (a[1] & ~m[1]) - || (a[2] & ~m[2]) || (a[3] & ~m[3])) { - bpf_error("non-network bits set in \"%s/%d\"", s1, masklen); - } - - switch (q.addr) { - - case Q_DEFAULT: - case Q_HOST: - if (masklen != 128) - bpf_error("Mask syntax for networks only"); - /* FALLTHROUGH */ - - case Q_NET: - b = gen_host6(addr, &mask, q.proto, q.dir); - freeaddrinfo(res); - return b; - - default: - bpf_error("invalid qualifier against IPv6 address"); - /* NOTREACHED */ - } -} -#endif /*INET6*/ - -struct block * -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); - 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) - 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 */ -} - -void -sappend(s0, s1) - struct slist *s0, *s1; -{ - /* - * This is definitely not the best way to do this, but the - * lists will rarely get long. - */ - while (s0->next) - s0 = s0->next; - s0->next = s1; -} - -static struct slist * -xfer_to_x(a) - struct arth *a; -{ - struct slist *s; - - s = new_stmt(BPF_LDX|BPF_MEM); - s->s.k = a->regno; - return s; -} - -static struct slist * -xfer_to_a(a) - struct arth *a; -{ - struct slist *s; - - s = new_stmt(BPF_LD|BPF_MEM); - s->s.k = a->regno; - return s; -} - -struct arth * -gen_load(proto, index, size) - int proto; - struct arth *index; - int size; -{ - struct slist *s, *tmp; - struct block *b; - int regno = alloc_reg(); - - free_reg(index->regno); - switch (size) { - - default: - bpf_error("data size must be 1, 2, or 4"); - - case 1: - size = BPF_B; - break; - - case 2: - size = BPF_H; - break; - - case 4: - size = BPF_W; - break; - } - switch (proto) { - default: - bpf_error("unsupported index operation"); - - case Q_LINK: - /* - * 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); - sappend(index->s, s); - break; - - case Q_IP: - case Q_ARP: - case Q_RARP: - case Q_ATALK: - case Q_DECNET: - case Q_SCA: - case Q_LAT: - case Q_MOPRC: - case Q_MOPDL: -#ifdef INET6 - case Q_IPV6: -#endif - /* XXX Note that we assume a fixed link header here. */ - s = xfer_to_x(index); - tmp = new_stmt(BPF_LD|BPF_IND|size); - tmp->s.k = off_nl; - sappend(s, tmp); - sappend(index->s, s); - - b = gen_proto_abbrev(proto); - if (index->b) - gen_and(index->b, b); - index->b = b; - break; - - case Q_SCTP: - case Q_TCP: - case Q_UDP: - case Q_ICMP: - case Q_IGMP: - case Q_IGRP: - case Q_PIM: - case Q_VRRP: - s = new_stmt(BPF_LDX|BPF_MSH|BPF_B); - s->s.k = off_nl; - sappend(s, xfer_to_a(index)); - sappend(s, new_stmt(BPF_ALU|BPF_ADD|BPF_X)); - sappend(s, new_stmt(BPF_MISC|BPF_TAX)); - sappend(s, tmp = new_stmt(BPF_LD|BPF_IND|size)); - tmp->s.k = off_nl; - sappend(index->s, s); - - gen_and(gen_proto_abbrev(proto), b = gen_ipfrag()); - if (index->b) - gen_and(index->b, b); -#ifdef INET6 - gen_and(gen_proto_abbrev(Q_IP), b); -#endif - index->b = b; - break; -#ifdef INET6 - case Q_ICMPV6: - bpf_error("IPv6 upper-layer protocol is not supported by proto[x]"); - /*NOTREACHED*/ -#endif - } - index->regno = regno; - s = new_stmt(BPF_ST); - s->s.k = regno; - sappend(index->s, s); - - return index; -} - -struct block * -gen_relation(code, a0, a1, reversed) - int code; - struct arth *a0, *a1; - int reversed; -{ - struct slist *s0, *s1, *s2; - struct block *b, *tmp; - - s0 = xfer_to_x(a1); - s1 = xfer_to_a(a0); - 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(s0, s1); - sappend(a1->s, s0); - sappend(a0->s, a1->s); - - b->stmts = a0->s; - - free_reg(a0->regno); - free_reg(a1->regno); - - /* 'and' together protocol checks */ - if (a0->b) { - if (a1->b) { - gen_and(a0->b, tmp = a1->b); - } - else - tmp = a0->b; - } else - tmp = a1->b; - - if (tmp) - gen_and(tmp, b); - - return b; -} - -struct arth * -gen_loadlen() -{ - int regno = alloc_reg(); - struct arth *a = (struct arth *)newchunk(sizeof(*a)); - struct slist *s; - - s = new_stmt(BPF_LD|BPF_LEN); - s->next = new_stmt(BPF_ST); - s->next->s.k = regno; - a->s = s; - a->regno = regno; - - return a; -} - -struct arth * -gen_loadi(val) - int val; -{ - struct arth *a; - struct slist *s; - int reg; - - a = (struct arth *)newchunk(sizeof(*a)); - - reg = alloc_reg(); - - s = new_stmt(BPF_LD|BPF_IMM); - s->s.k = val; - s->next = new_stmt(BPF_ST); - s->next->s.k = reg; - a->s = s; - a->regno = reg; - - return a; -} - -struct arth * -gen_neg(a) - struct arth *a; -{ - struct slist *s; - - s = xfer_to_a(a); - sappend(a->s, s); - s = new_stmt(BPF_ALU|BPF_NEG); - s->s.k = 0; - sappend(a->s, s); - s = new_stmt(BPF_ST); - s->s.k = a->regno; - sappend(a->s, s); - - return a; -} - -struct arth * -gen_arth(code, a0, a1) - int code; - struct arth *a0, *a1; -{ - struct slist *s0, *s1, *s2; - - s0 = xfer_to_x(a1); - s1 = xfer_to_a(a0); - s2 = new_stmt(BPF_ALU|BPF_X|code); - - sappend(s1, s2); - sappend(s0, s1); - sappend(a1->s, s0); - sappend(a0->s, a1->s); - - free_reg(a0->regno); - free_reg(a1->regno); - - s0 = new_stmt(BPF_ST); - a0->regno = s0->s.k = alloc_reg(); - sappend(a0->s, s0); - - return a0; -} - -/* - * Here we handle simple allocation of the scratch registers. - * If too many registers are alloc'd, the allocator punts. - */ -static int regused[BPF_MEMWORDS]; -static int curreg; - -/* - * Return the next free register. - */ -static int -alloc_reg() -{ - int n = BPF_MEMWORDS; - - while (--n >= 0) { - if (regused[curreg]) - curreg = (curreg + 1) % BPF_MEMWORDS; - else { - regused[curreg] = 1; - return curreg; - } - } - bpf_error("too many registers needed to evaluate expression"); - /* NOTREACHED */ -} - -/* - * Return a register to the table so it can - * be used later. - */ -static void -free_reg(n) - int n; -{ - regused[n] = 0; -} - -static struct block * -gen_len(jmp, n) - int jmp, n; -{ - struct slist *s; - struct block *b; - - s = new_stmt(BPF_LD|BPF_LEN); - b = new_block(JMP(jmp)); - b->stmts = s; - b->s.k = n; - - return b; -} - -struct block * -gen_greater(n) - int n; -{ - return gen_len(BPF_JGE, n); -} - -/* - * Actually, this is less than or equal. - */ -struct block * -gen_less(n) - int n; -{ - struct block *b; - - b = gen_len(BPF_JGT, n); - gen_not(b); - - return b; -} - -struct block * -gen_byteop(op, idx, val) - int op, idx, val; -{ - struct block *b; - struct slist *s; - - switch (op) { - default: - abort(); - - case '=': - return gen_cmp((u_int)idx, BPF_B, (bpf_int32)val); - - case '<': - b = gen_cmp((u_int)idx, BPF_B, (bpf_int32)val); - b->s.code = JMP(BPF_JGE); - gen_not(b); - return b; - - case '>': - b = gen_cmp((u_int)idx, BPF_B, (bpf_int32)val); - b->s.code = JMP(BPF_JGT); - return b; - - case '|': - s = new_stmt(BPF_ALU|BPF_OR|BPF_K); - break; - - case '&': - s = new_stmt(BPF_ALU|BPF_AND|BPF_K); - break; - } - s->s.k = val; - b = new_block(JMP(BPF_JEQ)); - b->stmts = s; - gen_not(b); - - return b; -} - -static u_char abroadcast[] = { 0x0 }; - -struct block * -gen_broadcast(proto) - int proto; -{ - bpf_u_int32 hostmask; - struct block *b0, *b1, *b2; - static u_char ebroadcast[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; - - switch (proto) { - - case Q_DEFAULT: - case Q_LINK: - if (linktype == DLT_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) - 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; - - case Q_IP: - b0 = gen_linktype(ETHERTYPE_IP); - hostmask = ~netmask; - b1 = gen_mcmp(off_nl + 16, BPF_W, (bpf_int32)0, hostmask); - b2 = gen_mcmp(off_nl + 16, BPF_W, - (bpf_int32)(~0 & hostmask), hostmask); - gen_or(b1, b2); - gen_and(b0, b2); - return b2; - } - 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, *b2; - register struct slist *s; - - switch (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) { - /* - * 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_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; - } - - 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; - - case Q_IP: - b0 = gen_linktype(ETHERTYPE_IP); - b1 = gen_cmp(off_nl + 16, BPF_B, (bpf_int32)224); - b1->s.code = JMP(BPF_JGE); - gen_and(b0, b1); - return b1; - -#ifdef INET6 - case Q_IPV6: - b0 = gen_linktype(ETHERTYPE_IPV6); - b1 = gen_cmp(off_nl + 24, BPF_B, (bpf_int32)255); - gen_and(b0, b1); - return b1; -#endif /* INET6 */ - } - bpf_error("link-layer multicast filters supported only on ethernet/FDDI/token ring/ARCNET/802.11/ATM LANE/Fibre Channel"); -} - -/* - * generate command for inbound/outbound. It's here so we can - * make it link-type specific. 'dir' = 0 implies "inbound", - * = 1 implies "outbound". - */ -struct block * -gen_inbound(dir) - int dir; -{ - register struct block *b0; - - /* - * Only some data link types support inbound/outbound qualifiers. - */ - switch (linktype) { - case DLT_SLIP: - 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", - linktype); - b0 = NULL; - /* NOTREACHED */ - } - 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 || linktype == DLT_ARCNET_LINUX) - return gen_ahostop(eaddr, (int)q.dir); - } - bpf_error("ARCnet address used in non-arc expression"); - /* NOTREACHED */ -} - -static struct block * -gen_ahostop(eaddr, dir) - register const u_char *eaddr; - register int dir; -{ - register struct block *b0, *b1; - - switch (dir) { - /* src comes first, different from Ethernet */ - case Q_SRC: - return gen_bcmp(0, 1, eaddr); - - case Q_DST: - return gen_bcmp(1, 1, eaddr); - - case Q_AND: - b0 = gen_ahostop(eaddr, Q_SRC); - b1 = gen_ahostop(eaddr, Q_DST); - gen_and(b0, b1); - return b1; - - case Q_DEFAULT: - case Q_OR: - b0 = gen_ahostop(eaddr, Q_SRC); - b1 = gen_ahostop(eaddr, Q_DST); - gen_or(b0, b1); - return b1; - } - abort(); - /* NOTREACHED */ -} - -/* - * support IEEE 802.1Q VLAN trunk over ethernet - */ -struct block * -gen_vlan(vlan_num) - int vlan_num; -{ - struct block *b0; - - /* - * Change the offsets to point to the type and data fields within - * the VLAN packet. This is somewhat of a kludge. - */ - 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; - - default: - bpf_error("no VLAN support for data link type %d", - linktype); - /*NOTREACHED*/ - } - } - - /* check for VLAN */ - b0 = gen_cmp(orig_linktype, BPF_H, (bpf_int32)ETHERTYPE_8021Q); - - /* If a specific VLAN is requested, check VLAN id */ - if (vlan_num >= 0) { - struct block *b1; - - b1 = gen_cmp(orig_nl, BPF_H, (bpf_int32)vlan_num); - gen_and(b0, b1); - b0 = b1; - } - - 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-0.8.3/gencode.h b/contrib/libpcap-0.8.3/gencode.h deleted file mode 100644 index 205b29d98a..0000000000 --- a/contrib/libpcap-0.8.3/gencode.h +++ /dev/null @@ -1,309 +0,0 @@ -/* - * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that: (1) source code distributions - * retain the above copyright notice and this paragraph in its entirety, (2) - * distributions including binary code include the above copyright notice and - * this paragraph in its entirety in the documentation or other materials - * provided with the distribution, and (3) all advertising materials mentioning - * features or use of this software display the following acknowledgement: - * ``This product includes software developed by the University of California, - * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of - * the University nor the names of its contributors may be used to endorse - * or promote products derived from this software without specific prior - * written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * @(#) $Header: /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. */ - -#define Q_HOST 1 -#define Q_NET 2 -#define Q_PORT 3 -#define Q_GATEWAY 4 -#define Q_PROTO 5 -#define Q_PROTOCHAIN 6 - -/* Protocol qualifiers. */ - -#define Q_LINK 1 -#define Q_IP 2 -#define Q_ARP 3 -#define Q_RARP 4 -#define Q_SCTP 5 -#define Q_TCP 6 -#define Q_UDP 7 -#define Q_ICMP 8 -#define Q_IGMP 9 -#define Q_IGRP 10 - - -#define Q_ATALK 11 -#define Q_DECNET 12 -#define Q_LAT 13 -#define Q_SCA 14 -#define Q_MOPRC 15 -#define Q_MOPDL 16 - - -#define Q_IPV6 17 -#define Q_ICMPV6 18 -#define Q_AH 19 -#define Q_ESP 20 - -#define Q_PIM 21 -#define Q_VRRP 22 - -#define Q_AARP 23 - -#define Q_ISO 24 -#define Q_ESIS 25 -#define Q_ISIS 26 -#define Q_CLNP 27 - -#define Q_STP 28 - -#define Q_IPX 29 - -#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 -#define Q_DST 2 -#define Q_OR 3 -#define Q_AND 4 - -#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 { - int code; - struct slist *jt; /*only for relative jump in block*/ - struct slist *jf; /*only for relative jump in block*/ - bpf_int32 k; -}; - -struct slist { - struct stmt s; - struct slist *next; -}; - -/* - * A bit vector to represent definition sets. We assume TOT_REGISTERS - * is smaller than 8*sizeof(atomset). - */ -typedef bpf_u_int32 atomset; -#define ATOMMASK(n) (1 << (n)) -#define ATOMELEM(d, n) (d & ATOMMASK(n)) - -/* - * An unbounded set. - */ -typedef bpf_u_int32 *uset; - -/* - * Total number of atomic entities, including accumulator (A) and index (X). - * We treat all these guys similarly during flow analysis. - */ -#define N_ATOMS (BPF_MEMWORDS+2) - -struct edge { - int id; - int code; - uset edom; - struct block *succ; - struct block *pred; - struct edge *next; /* link list of incoming edges for a node */ -}; - -struct block { - int id; - struct slist *stmts; /* side effect stmts */ - struct stmt s; /* branch stmt */ - int mark; - int longjt; /* jt branch requires long jump */ - int longjf; /* jf branch requires long jump */ - int level; - int offset; - int sense; - struct edge et; - struct edge ef; - struct block *head; - struct block *link; /* link field used by optimizer */ - uset dom; - uset closure; - struct edge *in_edges; - atomset def, kill; - atomset in_use; - atomset out_use; - int oval; - int val[N_ATOMS]; -}; - -struct arth { - struct block *b; /* protocol checks */ - struct slist *s; /* stmt list */ - int regno; /* virtual register number of result */ -}; - -struct qual { - unsigned char addr; - unsigned char proto; - unsigned char dir; - unsigned char pad; -}; - -struct arth *gen_loadi(int); -struct arth *gen_load(int, struct arth *, int); -struct arth *gen_loadlen(void); -struct arth *gen_neg(struct arth *); -struct arth *gen_arth(int, struct arth *, struct arth *); - -void gen_and(struct block *, struct block *); -void gen_or(struct block *, struct block *); -void gen_not(struct block *); - -struct block *gen_scode(const char *, struct qual); -struct block *gen_ecode(const u_char *, struct qual); -struct block *gen_acode(const u_char *, struct qual); -struct block *gen_mcode(const char *, const char *, int, struct qual); -#ifdef INET6 -struct block *gen_mcode6(const char *, const char *, int, struct qual); -#endif -struct block *gen_ncode(const char *, bpf_u_int32, struct qual); -struct block *gen_proto_abbrev(int); -struct block *gen_relation(int, struct arth *, struct arth *, int); -struct block *gen_less(int); -struct block *gen_greater(int); -struct block *gen_byteop(int, int, int); -struct block *gen_broadcast(int); -struct block *gen_multicast(int); -struct block *gen_inbound(int); - -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__ - __attribute__((noreturn, format (printf, 1, 2))) -#endif -; - -void finish_parse(struct block *); -char *sdup(const char *); - -struct bpf_insn *icode_to_fcode(struct block *, int *); -int pcap_parse(void); -void lex_init(char *); -void lex_cleanup(void); -void sappend(struct slist *, struct slist *); - -/* XXX */ -#define JT(b) ((b)->et.succ) -#define JF(b) ((b)->ef.succ) - -extern int no_optimize; diff --git a/contrib/libpcap-0.8.3/grammar.y b/contrib/libpcap-0.8.3/grammar.y deleted file mode 100644 index dc63e322a9..0000000000 --- a/contrib/libpcap-0.8.3/grammar.y +++ /dev/null @@ -1,430 +0,0 @@ -%{ -/* - * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that: (1) source code distributions - * retain the above copyright notice and this paragraph in its entirety, (2) - * distributions including binary code include the above copyright notice and - * this paragraph in its entirety in the documentation or other materials - * provided with the distribution, and (3) all advertising materials mentioning - * features or use of this software display the following acknowledgement: - * ``This product includes software developed by the University of California, - * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of - * the University nor the names of its contributors may be used to endorse - * or promote products derived from this software without specific prior - * written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - */ -#ifndef lint -static 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 -#else /* WIN32 */ -#include -#include -#include -#endif /* WIN32 */ - -#include - -#ifndef WIN32 -#if __STDC__ -struct mbuf; -struct rtentry; -#endif - -#include -#endif /* WIN32 */ - -#include -#include - -#include "pcap-int.h" - -#include "gencode.h" -#include "pf.h" -#include - -#ifdef HAVE_OS_PROTO_H -#include "os-proto.h" -#endif - -#define QSET(q, p, d, a) (q).proto = (p),\ - (q).dir = (d),\ - (q).addr = (a) - -int n_errors = 0; - -static struct qual qerr = { Q_UNDEF, Q_UNDEF, Q_UNDEF, Q_UNDEF }; - -static void -yyerror(char *msg) -{ - ++n_errors; - bpf_error("%s", msg); - /* NOTREACHED */ -} - -#ifndef YYBISON -int yyparse(void); - -int -pcap_parse() -{ - return (yyparse()); -} -#endif - -%} - -%union { - int i; - bpf_u_int32 h; - u_char *e; - char *s; - struct stmt *stmt; - struct arth *a; - struct { - struct qual q; - int atmfieldtype; - struct block *b; - } blk; - struct block *rblk; -} - -%type expr id nid pid term rterm qid -%type head -%type pqual dqual aqual ndaqual -%type arth narth -%type byteop pname pnum relop irelop -%type and or paren not null prog -%type other pfvar -%type atmtype atmmultitype -%type atmfield -%type atmfieldvalue atmvalue atmlistvalue - -%token DST SRC HOST GATEWAY -%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 -%token LSH RSH -%token LEN -%token IPV6 ICMPV6 AH ESP -%token VLAN -%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 ID -%type EID -%type AID -%type HID HID6 -%type NUM action reason - -%left OR AND -%nonassoc '!' -%left '|' -%left '&' -%left LSH RSH -%left '+' '-' -%left '*' '/' -%nonassoc UMINUS -%% -prog: null expr -{ - finish_parse($2.b); -} - | null - ; -null: /* null */ { $$.q = qerr; } - ; -expr: term - | expr and term { gen_and($1.b, $3.b); $$ = $3; } - | expr and id { gen_and($1.b, $3.b); $$ = $3; } - | expr or term { gen_or($1.b, $3.b); $$ = $3; } - | expr or id { gen_or($1.b, $3.b); $$ = $3; } - ; -and: AND { $$ = $0; } - ; -or: OR { $$ = $0; } - ; -id: nid - | pnum { $$.b = gen_ncode(NULL, (bpf_u_int32)$1, - $$.q = $0.q); } - | paren pid ')' { $$ = $2; } - ; -nid: ID { $$.b = gen_scode($1, $$.q = $0.q); } - | HID '/' NUM { $$.b = gen_mcode($1, NULL, $3, - $$.q = $0.q); } - | HID NETMASK HID { $$.b = gen_mcode($1, $3, 0, - $$.q = $0.q); } - | HID { - /* Decide how to parse HID based on proto */ - $$.q = $0.q; - $$.b = gen_ncode($1, 0, $$.q); - } - | HID6 '/' NUM { -#ifdef INET6 - $$.b = gen_mcode6($1, NULL, $3, - $$.q = $0.q); -#else - bpf_error("'ip6addr/prefixlen' not supported " - "in this configuration"); -#endif /*INET6*/ - } - | HID6 { -#ifdef INET6 - $$.b = gen_mcode6($1, 0, 128, - $$.q = $0.q); -#else - bpf_error("'ip6addr' not supported " - "in this configuration"); -#endif /*INET6*/ - } - | EID { - $$.b = gen_ecode($1, $$.q = $0.q); - /* - * $1 was allocated by "pcap_ether_aton()", - * so we must free it now that we're done - * with it. - */ - free($1); - } - | AID { - $$.b = gen_acode($1, $$.q = $0.q); - /* - * $1 was allocated by "pcap_ether_aton()", - * so we must free it now that we're done - * with it. - */ - free($1); - } - | not id { gen_not($2.b); $$ = $2; } - ; -not: '!' { $$ = $0; } - ; -paren: '(' { $$ = $0; } - ; -pid: nid - | qid and id { gen_and($1.b, $3.b); $$ = $3; } - | qid or id { gen_or($1.b, $3.b); $$ = $3; } - ; -qid: pnum { $$.b = gen_ncode(NULL, (bpf_u_int32)$1, - $$.q = $0.q); } - | pid - ; -term: rterm - | not term { gen_not($2.b); $$ = $2; } - ; -head: pqual dqual aqual { QSET($$.q, $1, $2, $3); } - | pqual dqual { QSET($$.q, $1, $2, Q_DEFAULT); } - | pqual aqual { QSET($$.q, $1, Q_DEFAULT, $2); } - | pqual PROTO { QSET($$.q, $1, Q_DEFAULT, Q_PROTO); } - | pqual PROTOCHAIN { QSET($$.q, $1, Q_DEFAULT, Q_PROTOCHAIN); } - | pqual ndaqual { QSET($$.q, $1, Q_DEFAULT, $2); } - ; -rterm: head id { $$ = $2; } - | paren expr ')' { $$.b = $2.b; $$.q = $1.q; } - | pname { $$.b = gen_proto_abbrev($1); $$.q = qerr; } - | arth relop arth { $$.b = gen_relation($2, $1, $3, 0); - $$.q = qerr; } - | arth irelop arth { $$.b = gen_relation($2, $1, $3, 1); - $$.q = qerr; } - | other { $$.b = $1; $$.q = qerr; } - | 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 - | { $$ = Q_DEFAULT; } - ; -/* 'direction' qualifiers */ -dqual: SRC { $$ = Q_SRC; } - | DST { $$ = Q_DST; } - | SRC OR DST { $$ = Q_OR; } - | DST OR SRC { $$ = Q_OR; } - | SRC AND DST { $$ = Q_AND; } - | DST AND SRC { $$ = Q_AND; } - ; -/* address type qualifiers */ -aqual: HOST { $$ = Q_HOST; } - | NET { $$ = Q_NET; } - | PORT { $$ = Q_PORT; } - ; -/* non-directional address type qualifiers */ -ndaqual: GATEWAY { $$ = Q_GATEWAY; } - ; -pname: LINK { $$ = Q_LINK; } - | IP { $$ = Q_IP; } - | ARP { $$ = Q_ARP; } - | RARP { $$ = Q_RARP; } - | SCTP { $$ = Q_SCTP; } - | TCP { $$ = Q_TCP; } - | UDP { $$ = Q_UDP; } - | ICMP { $$ = Q_ICMP; } - | IGMP { $$ = Q_IGMP; } - | IGRP { $$ = Q_IGRP; } - | PIM { $$ = Q_PIM; } - | VRRP { $$ = Q_VRRP; } - | ATALK { $$ = Q_ATALK; } - | AARP { $$ = Q_AARP; } - | DECNET { $$ = Q_DECNET; } - | LAT { $$ = Q_LAT; } - | SCA { $$ = Q_SCA; } - | MOPDL { $$ = Q_MOPDL; } - | MOPRC { $$ = Q_MOPRC; } - | IPV6 { $$ = Q_IPV6; } - | ICMPV6 { $$ = Q_ICMPV6; } - | AH { $$ = Q_AH; } - | ESP { $$ = Q_ESP; } - | 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; } - | NETBEUI { $$ = Q_NETBEUI; } - ; -other: pqual TK_BROADCAST { $$ = gen_broadcast($1); } - | pqual TK_MULTICAST { $$ = gen_multicast($1); } - | LESS NUM { $$ = gen_less($2); } - | GREATER NUM { $$ = gen_greater($2); } - | 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; } - ; -irelop: LEQ { $$ = BPF_JGT; } - | '<' { $$ = BPF_JGE; } - | NEQ { $$ = BPF_JEQ; } - ; -arth: pnum { $$ = gen_loadi($1); } - | narth - ; -narth: pname '[' arth ']' { $$ = gen_load($1, $3, 1); } - | pname '[' arth ':' NUM ']' { $$ = gen_load($1, $3, $5); } - | arth '+' arth { $$ = gen_arth(BPF_ADD, $1, $3); } - | arth '-' arth { $$ = gen_arth(BPF_SUB, $1, $3); } - | arth '*' arth { $$ = gen_arth(BPF_MUL, $1, $3); } - | arth '/' arth { $$ = gen_arth(BPF_DIV, $1, $3); } - | arth '&' arth { $$ = gen_arth(BPF_AND, $1, $3); } - | arth '|' arth { $$ = gen_arth(BPF_OR, $1, $3); } - | arth LSH arth { $$ = gen_arth(BPF_LSH, $1, $3); } - | arth RSH arth { $$ = gen_arth(BPF_RSH, $1, $3); } - | '-' arth %prec UMINUS { $$ = gen_neg($2); } - | paren narth ')' { $$ = $2; } - | LEN { $$ = gen_loadlen(); } - ; -byteop: '&' { $$ = '&'; } - | '|' { $$ = '|'; } - | '<' { $$ = '<'; } - | '>' { $$ = '>'; } - | '=' { $$ = '='; } - ; -pnum: NUM - | paren pnum ')' { $$ = $2; } - ; -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($0.atmfieldtype, (u_int)$2, (u_int)$1, 0); } - | irelop NUM { $$.b = gen_atmfield_code($0.atmfieldtype, (u_int)$2, (u_int)$1, 1); } - | paren atmlistvalue ')' { $$.b = $2.b; $$.q = qerr; } - ; -atmfieldvalue: NUM { - $$.atmfieldtype = $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-0.8.3/inet.c b/contrib/libpcap-0.8.3/inet.c deleted file mode 100644 index 43eafe7fb6..0000000000 --- a/contrib/libpcap-0.8.3/inet.c +++ /dev/null @@ -1,693 +0,0 @@ -/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */ -/* - * Copyright (c) 1994, 1995, 1996, 1997, 1998 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the Computer Systems - * Engineering Group at Lawrence Berkeley Laboratory. - * 4. Neither the name of the University nor of the Laboratory may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef lint -static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/libpcap/inet.c,v 1.58.2.1 2003/11/15 23:26:41 guy Exp $ (LBL)"; -#endif - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifdef WIN32 -#include -#else /* WIN32 */ - -#include -#include -#include -#include -#ifdef HAVE_SYS_SOCKIO_H -#include -#endif -#include /* concession to AIX */ - -struct mbuf; /* Squelch compiler warnings on some platforms for */ -struct rtentry; /* declarations in */ -#include -#include -#endif /* WIN32 */ - -#include -#include -#include -#include -#include -#include -#ifndef WIN32 -#include -#endif /* WIN32 */ -#ifdef HAVE_LIMITS_H -#include -#else -#define INT_MAX 2147483647 -#endif -#ifdef HAVE_IFADDRS_H -#include -#endif - -#include "pcap-int.h" - -#ifdef HAVE_OS_PROTO_H -#include "os-proto.h" -#endif - -/* Not all systems have IFF_LOOPBACK */ -#ifdef IFF_LOOPBACK -#define ISLOOPBACK(name, flags) ((flags) & IFF_LOOPBACK) -#else -#define ISLOOPBACK(name, flags) ((name)[0] == 'l' && (name)[1] == 'o' && \ - (isdigit((unsigned char)((name)[2])) || (name)[2] == '\0')) -#endif - -struct sockaddr * -dup_sockaddr(struct sockaddr *sa, size_t sa_length) -{ - struct sockaddr *newsa; - - if ((newsa = malloc(sa_length)) == NULL) - return (NULL); - return (memcpy(newsa, sa, sa_length)); -} - -static int -get_instance(const char *name) -{ - const char *cp, *endcp; - int n; - - if (strcmp(name, "any") == 0) { - /* - * Give the "any" device an artificially high instance - * number, so it shows up after all other non-loopback - * interfaces. - */ - return INT_MAX; - } - - endcp = name + strlen(name); - for (cp = name; cp < endcp && !isdigit((unsigned char)*cp); ++cp) - continue; - - if (isdigit((unsigned char)*cp)) - n = atoi(cp); - else - n = 0; - return (n); -} - -int -add_or_find_if(pcap_if_t **curdev_ret, pcap_if_t **alldevs, const char *name, - u_int flags, const char *description, char *errbuf) -{ - pcap_if_t *curdev, *prevdev, *nextdev; - int this_instance; - - /* - * Is there already an entry in the list for this interface? - */ - for (curdev = *alldevs; curdev != NULL; curdev = curdev->next) { - if (strcmp(name, curdev->name) == 0) - break; /* yes, we found it */ - } - if (curdev == NULL) { - /* - * No, we didn't find it. - * Allocate a new entry. - */ - curdev = malloc(sizeof(pcap_if_t)); - if (curdev == NULL) { - (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, - "malloc: %s", pcap_strerror(errno)); - return (-1); - } - - /* - * Fill in the entry. - */ - curdev->next = NULL; - curdev->name = malloc(strlen(name) + 1); - strcpy(curdev->name, name); - if (description != NULL) { - /* - * We have a description for this interface. - */ - curdev->description = malloc(strlen(description) + 1); - strcpy(curdev->description, description); - } else { - /* - * We don't. - */ - curdev->description = NULL; - } - curdev->addresses = NULL; /* list starts out as empty */ - curdev->flags = 0; - if (ISLOOPBACK(name, flags)) - curdev->flags |= PCAP_IF_LOOPBACK; - - /* - * Add it to the list, in the appropriate location. - * First, get the instance number of this interface. - */ - this_instance = get_instance(name); - - /* - * Now look for the last interface with an instance number - * less than or equal to the new interface's instance - * number - except that non-loopback interfaces are - * arbitrarily treated as having interface numbers less - * than those of loopback interfaces, so the loopback - * interfaces are put at the end of the list. - * - * We start with "prevdev" being NULL, meaning we're before - * the first element in the list. - */ - prevdev = NULL; - for (;;) { - /* - * Get the interface after this one. - */ - if (prevdev == NULL) { - /* - * The next element is the first element. - */ - nextdev = *alldevs; - } else - nextdev = prevdev->next; - - /* - * Are we at the end of the list? - */ - if (nextdev == NULL) { - /* - * Yes - we have to put the new entry - * after "prevdev". - */ - break; - } - - /* - * Is the new interface a non-loopback interface - * and the next interface a loopback interface? - */ - if (!(curdev->flags & PCAP_IF_LOOPBACK) && - (nextdev->flags & PCAP_IF_LOOPBACK)) { - /* - * Yes, we should put the new entry - * before "nextdev", i.e. after "prevdev". - */ - break; - } - - /* - * Is the new interface's instance number less - * than the next interface's instance number, - * and is it the case that the new interface is a - * non-loopback interface or the next interface is - * a loopback interface? - * - * (The goal of both loopback tests is to make - * sure that we never put a loopback interface - * before any non-loopback interface and that we - * always put a non-loopback interface before all - * loopback interfaces.) - */ - if (this_instance < get_instance(nextdev->name) && - (!(curdev->flags & PCAP_IF_LOOPBACK) || - (nextdev->flags & PCAP_IF_LOOPBACK))) { - /* - * Yes - we should put the new entry - * before "nextdev", i.e. after "prevdev". - */ - break; - } - - prevdev = nextdev; - } - - /* - * Insert before "nextdev". - */ - curdev->next = nextdev; - - /* - * Insert after "prevdev" - unless "prevdev" is null, - * in which case this is the first interface. - */ - if (prevdev == NULL) { - /* - * This is the first interface. Pass back a - * pointer to it, and put "curdev" before - * "nextdev". - */ - *alldevs = curdev; - } else - prevdev->next = curdev; - } - - *curdev_ret = curdev; - return (0); -} - -int -add_addr_to_iflist(pcap_if_t **alldevs, char *name, u_int flags, - struct sockaddr *addr, size_t addr_size, - struct sockaddr *netmask, size_t netmask_size, - struct sockaddr *broadaddr, size_t broadaddr_size, - struct sockaddr *dstaddr, size_t dstaddr_size, - char *errbuf) -{ - pcap_if_t *curdev; - pcap_addr_t *curaddr, *prevaddr, *nextaddr; - - if (add_or_find_if(&curdev, alldevs, name, flags, NULL, errbuf) == -1) { - /* - * Error - give up. - */ - return (-1); - } - if (curdev == NULL) { - /* - * Device wasn't added because it can't be opened. - * Not a fatal error. - */ - return (0); - } - - /* - * "curdev" is an entry for this interface; add an entry for this - * address to its list of addresses. - * - * Allocate the new entry and fill it in. - */ - curaddr = malloc(sizeof(pcap_addr_t)); - if (curaddr == NULL) { - (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, - "malloc: %s", pcap_strerror(errno)); - return (-1); - } - - curaddr->next = NULL; - if (addr != NULL) { - curaddr->addr = dup_sockaddr(addr, addr_size); - if (curaddr->addr == NULL) { - (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, - "malloc: %s", pcap_strerror(errno)); - free(curaddr); - return (-1); - } - } else - curaddr->addr = NULL; - - if (netmask != NULL) { - curaddr->netmask = dup_sockaddr(netmask, netmask_size); - if (curaddr->netmask == NULL) { - (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, - "malloc: %s", pcap_strerror(errno)); - free(curaddr); - return (-1); - } - } else - curaddr->netmask = NULL; - - if (broadaddr != NULL) { - curaddr->broadaddr = dup_sockaddr(broadaddr, broadaddr_size); - if (curaddr->broadaddr == NULL) { - (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, - "malloc: %s", pcap_strerror(errno)); - free(curaddr); - return (-1); - } - } else - curaddr->broadaddr = NULL; - - if (dstaddr != NULL) { - curaddr->dstaddr = dup_sockaddr(dstaddr, dstaddr_size); - if (curaddr->dstaddr == NULL) { - (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, - "malloc: %s", pcap_strerror(errno)); - free(curaddr); - return (-1); - } - } else - curaddr->dstaddr = NULL; - - /* - * Find the end of the list of addresses. - */ - for (prevaddr = curdev->addresses; prevaddr != NULL; prevaddr = nextaddr) { - nextaddr = prevaddr->next; - if (nextaddr == NULL) { - /* - * This is the end of the list. - */ - break; - } - } - - if (prevaddr == NULL) { - /* - * The list was empty; this is the first member. - */ - curdev->addresses = curaddr; - } else { - /* - * "prevaddr" is the last member of the list; append - * this member to it. - */ - prevaddr->next = curaddr; - } - - return (0); -} - -int -pcap_add_if(pcap_if_t **devlist, char *name, u_int flags, - const char *description, char *errbuf) -{ - pcap_if_t *curdev; - - return (add_or_find_if(&curdev, devlist, name, flags, description, - errbuf)); -} - - -/* - * Free a list of interfaces. - */ -void -pcap_freealldevs(pcap_if_t *alldevs) -{ - pcap_if_t *curdev, *nextdev; - pcap_addr_t *curaddr, *nextaddr; - - for (curdev = alldevs; curdev != NULL; curdev = nextdev) { - nextdev = curdev->next; - - /* - * Free all addresses. - */ - for (curaddr = curdev->addresses; curaddr != NULL; curaddr = nextaddr) { - nextaddr = curaddr->next; - if (curaddr->addr) - free(curaddr->addr); - if (curaddr->netmask) - free(curaddr->netmask); - if (curaddr->broadaddr) - free(curaddr->broadaddr); - if (curaddr->dstaddr) - free(curaddr->dstaddr); - free(curaddr); - } - - /* - * Free the name string. - */ - free(curdev->name); - - /* - * Free the description string, if any. - */ - if (curdev->description != NULL) - free(curdev->description); - - /* - * Free the interface. - */ - free(curdev); - } -} - -#ifndef WIN32 - -/* - * Return the name of a network interface attached to the system, or NULL - * if none can be found. The interface must be configured up; the - * lowest unit number is preferred; loopback is ignored. - */ -char * -pcap_lookupdev(errbuf) - register char *errbuf; -{ - pcap_if_t *alldevs; -/* for old BSD systems, including bsdi3 */ -#ifndef IF_NAMESIZE -#define IF_NAMESIZE IFNAMSIZ -#endif - static char device[IF_NAMESIZE + 1]; - char *ret; - - if (pcap_findalldevs(&alldevs, errbuf) == -1) - return (NULL); - - if (alldevs == NULL || (alldevs->flags & PCAP_IF_LOOPBACK)) { - /* - * There are no devices on the list, or the first device - * on the list is a loopback device, which means there - * are no non-loopback devices on the list. This means - * we can't return any device. - * - * XXX - why not return a loopback device? If we can't - * capture on it, it won't be on the list, and if it's - * on the list, there aren't any non-loopback devices, - * so why not just supply it as the default device? - */ - (void)strlcpy(errbuf, "no suitable device found", - PCAP_ERRBUF_SIZE); - ret = NULL; - } else { - /* - * Return the name of the first device on the list. - */ - (void)strlcpy(device, alldevs->name, sizeof(device)); - ret = device; - } - - pcap_freealldevs(alldevs); - return (ret); -} - -int -pcap_lookupnet(device, netp, maskp, errbuf) - register const char *device; - register bpf_u_int32 *netp, *maskp; - register char *errbuf; -{ - register int fd; - register struct sockaddr_in *sin; - struct ifreq ifr; - - /* - * The pseudo-device "any" listens on all interfaces and therefore - * has the network address and -mask "0.0.0.0" therefore catching - * all traffic. Using NULL for the interface is the same as "any". - */ - if (!device || strcmp(device, "any") == 0 -#ifdef HAVE_DAG_API - || strstr(device, "dag") != NULL -#endif - ) { - *netp = *maskp = 0; - return 0; - } - - fd = socket(AF_INET, SOCK_DGRAM, 0); - if (fd < 0) { - (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, "socket: %s", - pcap_strerror(errno)); - return (-1); - } - memset(&ifr, 0, sizeof(ifr)); -#ifdef linux - /* XXX Work around Linux kernel bug */ - ifr.ifr_addr.sa_family = AF_INET; -#endif - (void)strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); - if (ioctl(fd, SIOCGIFADDR, (char *)&ifr) < 0) { - if (errno == EADDRNOTAVAIL) { - (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, - "%s: no IPv4 address assigned", device); - } else { - (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, - "SIOCGIFADDR: %s: %s", - device, pcap_strerror(errno)); - } - (void)close(fd); - return (-1); - } - sin = (struct sockaddr_in *)&ifr.ifr_addr; - *netp = sin->sin_addr.s_addr; - if (ioctl(fd, SIOCGIFNETMASK, (char *)&ifr) < 0) { - (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, - "SIOCGIFNETMASK: %s: %s", device, pcap_strerror(errno)); - (void)close(fd); - return (-1); - } - (void)close(fd); - *maskp = sin->sin_addr.s_addr; - if (*maskp == 0) { - if (IN_CLASSA(*netp)) - *maskp = IN_CLASSA_NET; - else if (IN_CLASSB(*netp)) - *maskp = IN_CLASSB_NET; - else if (IN_CLASSC(*netp)) - *maskp = IN_CLASSC_NET; - else { - (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, - "inet class for 0x%x unknown", *netp); - return (-1); - } - } - *netp &= *maskp; - return (0); -} - -#else /* WIN32 */ - -/* - * Return the name of a network interface attached to the system, or NULL - * if none can be found. The interface must be configured up; the - * lowest unit number is preferred; loopback is ignored. - */ -char * -pcap_lookupdev(errbuf) - register char *errbuf; -{ - DWORD dwVersion; - DWORD dwWindowsMajorVersion; - dwVersion = GetVersion(); /* get the OS version */ - dwWindowsMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion))); - - if (dwVersion >= 0x80000000 && dwWindowsMajorVersion >= 4) { - /* - * Windows 95, 98, ME. - */ - ULONG NameLength = 8192; - static char AdaptersName[8192]; - - PacketGetAdapterNames(AdaptersName,&NameLength); - - return (AdaptersName); - } else { - /* - * Windows NT (NT 4.0, W2K, WXP). Convert the names to UNICODE for backward compatibility - */ - ULONG NameLength = 8192; - static WCHAR AdaptersName[8192]; - char *tAstr; - WCHAR *tUstr; - WCHAR *TAdaptersName = (WCHAR*)malloc(8192 * sizeof(WCHAR)); - int NAdapts = 0; - - if(TAdaptersName == NULL) - { - (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, "memory allocation failure"); - return NULL; - } - - PacketGetAdapterNames((PTSTR)TAdaptersName,&NameLength); - - tAstr = (char*)TAdaptersName; - tUstr = (WCHAR*)AdaptersName; - - /* - * Convert and copy the device names - */ - while(sscanf(tAstr, "%S", tUstr) > 0) - { - tAstr += strlen(tAstr) + 1; - tUstr += wcslen(tUstr) + 1; - NAdapts ++; - } - - tAstr++; - *tUstr = 0; - tUstr++; - - /* - * Copy the descriptions - */ - while(NAdapts--) - { - strcpy((char*)tUstr, tAstr); - (char*)tUstr += strlen(tAstr) + 1;; - tAstr += strlen(tAstr) + 1; - } - - return (char *)(AdaptersName); - } -} - - -int -pcap_lookupnet(device, netp, maskp, errbuf) - const register char *device; - register bpf_u_int32 *netp, *maskp; - register char *errbuf; -{ - /* - * We need only the first IPv4 address, so we must scan the array returned by PacketGetNetInfo() - * in order to skip non IPv4 (i.e. IPv6 addresses) - */ - npf_if_addr if_addrs[MAX_NETWORK_ADDRESSES]; - LONG if_addr_size = 1; - struct sockaddr_in *t_addr; - unsigned int i; - - if (!PacketGetNetInfoEx((void *)device, if_addrs, &if_addr_size)) { - *netp = *maskp = 0; - return (0); - } - - for(i=0; isin_addr.S_un.S_addr; - t_addr = (struct sockaddr_in *) &(if_addrs[i].SubnetMask); - *maskp = t_addr->sin_addr.S_un.S_addr; - - *netp &= *maskp; - return (0); - } - - } - - *netp = *maskp = 0; - return (0); -} - -#endif /* WIN32 */ diff --git a/contrib/libpcap-0.8.3/llc.h b/contrib/libpcap-0.8.3/llc.h deleted file mode 100644 index ffd3a60143..0000000000 --- a/contrib/libpcap-0.8.3/llc.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 1993, 1994, 1997 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that: (1) source code distributions - * retain the above copyright notice and this paragraph in its entirety, (2) - * distributions including binary code include the above copyright notice and - * this paragraph in its entirety in the documentation or other materials - * provided with the distribution, and (3) all advertising materials mentioning - * features or use of this software display the following acknowledgement: - * ``This product includes software developed by the University of California, - * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of - * the University nor the names of its contributors may be used to endorse - * or promote products derived from this software without specific prior - * written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * @(#) $Header: /tcpdump/master/libpcap/llc.h,v 1.2 2001/01/28 09:44:50 guy Exp $ (LBL) - */ - -/* - * 802.2 LLC SAP values. - */ - -#ifndef LLCSAP_NULL -#define LLCSAP_NULL 0x00 -#endif -#ifndef LLCSAP_GLOBAL -#define LLCSAP_GLOBAL 0xff -#endif -#ifndef LLCSAP_8021B -#define LLCSAP_8021B_I 0x02 -#endif -#ifndef LLCSAP_8021B -#define LLCSAP_8021B_G 0x03 -#endif -#ifndef LLCSAP_IP -#define LLCSAP_IP 0x06 -#endif -#ifndef LLCSAP_PROWAYNM -#define LLCSAP_PROWAYNM 0x0e -#endif -#ifndef LLCSAP_8021D -#define LLCSAP_8021D 0x42 -#endif -#ifndef LLCSAP_RS511 -#define LLCSAP_RS511 0x4e -#endif -#ifndef LLCSAP_ISO8208 -#define LLCSAP_ISO8208 0x7e -#endif -#ifndef LLCSAP_PROWAY -#define LLCSAP_PROWAY 0x8e -#endif -#ifndef LLCSAP_SNAP -#define LLCSAP_SNAP 0xaa -#endif -#ifndef LLCSAP_IPX -#define LLCSAP_IPX 0xe0 -#endif -#ifndef LLCSAP_NETBEUI -#define LLCSAP_NETBEUI 0xf0 -#endif -#ifndef LLCSAP_ISONS -#define LLCSAP_ISONS 0xfe -#endif diff --git a/contrib/libpcap-0.8.3/nametoaddr.c b/contrib/libpcap-0.8.3/nametoaddr.c deleted file mode 100644 index f9d6a4f507..0000000000 --- a/contrib/libpcap-0.8.3/nametoaddr.c +++ /dev/null @@ -1,433 +0,0 @@ -/* - * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that: (1) source code distributions - * retain the above copyright notice and this paragraph in its entirety, (2) - * distributions including binary code include the above copyright notice and - * this paragraph in its entirety in the documentation or other materials - * provided with the distribution, and (3) all advertising materials mentioning - * features or use of this software display the following acknowledgement: - * ``This product includes software developed by the University of California, - * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of - * the University nor the names of its contributors may be used to endorse - * or promote products derived from this software without specific prior - * written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * Name to id translation routines used by the scanner. - * These functions are not time critical. - */ - -#ifndef lint -static 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 - -#else /* WIN32 */ - -#include -#include /* concession to AIX */ -#include -#include - -#include -#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 */ -#include /* for "struct ifnet" in "struct arpcom" on Solaris */ -#include -#endif /* HAVE_NETINET_IF_ETHER_H */ -#endif /* HAVE_ETHER_HOSTTON */ -#include -#include -#endif /* WIN32 */ - -#include -#include -#include -#include -#include - -#include "pcap-int.h" - -#include "gencode.h" -#include - -#ifdef HAVE_OS_PROTO_H -#include "os-proto.h" -#endif - -#ifndef NTOHL -#define NTOHL(x) (x) = ntohl(x) -#define NTOHS(x) (x) = ntohs(x) -#endif - -static inline int xdtoi(int); - -/* - * Convert host name to internet address. - * Return 0 upon failure. - */ -bpf_u_int32 ** -pcap_nametoaddr(const char *name) -{ -#ifndef h_addr - static bpf_u_int32 *hlist[2]; -#endif - bpf_u_int32 **p; - struct hostent *hp; - - if ((hp = gethostbyname(name)) != NULL) { -#ifndef h_addr - hlist[0] = (bpf_u_int32 *)hp->h_addr; - NTOHL(hp->h_addr); - return hlist; -#else - for (p = (bpf_u_int32 **)hp->h_addr_list; *p; ++p) - NTOHL(**p); - return (bpf_u_int32 **)hp->h_addr_list; -#endif - } - else - return 0; -} - -#ifdef INET6 -struct addrinfo * -pcap_nametoaddrinfo(const char *name) -{ - struct addrinfo hints, *res; - int error; - - memset(&hints, 0, sizeof(hints)); - hints.ai_family = PF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; /*not really*/ - error = getaddrinfo(name, NULL, &hints, &res); - if (error) - return NULL; - else - return res; -} -#endif /*INET6*/ - -/* - * Convert net name to internet address. - * Return 0 upon failure. - */ -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 -} - -/* - * Convert a port name to its port and protocol numbers. - * We assume only TCP or UDP. - * Return 0 upon failure. - */ -int -pcap_nametoport(const char *name, int *port, int *proto) -{ - struct servent *sp; - 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 - else - /* Can't handle ambiguous names that refer - to different port numbers. */ - warning("ambiguous port %s in /etc/services", - name); -#endif - } - 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) { - *port = 2049; - *proto = PROTO_UNDEF; - return 1; - } -#endif - return 0; -} - -int -pcap_nametoproto(const char *str) -{ - struct protoent *p; - - p = getprotobyname(str); - if (p != 0) - return p->p_proto; - else - return PROTO_UNDEF; -} - -#include "ethertype.h" - -struct eproto { - char *s; - u_short p; -}; - -/* Static data base of ether protocol types. */ -struct eproto eproto_db[] = { - { "pup", ETHERTYPE_PUP }, - { "xns", ETHERTYPE_NS }, - { "ip", ETHERTYPE_IP }, -#ifdef INET6 - { "ip6", ETHERTYPE_IPV6 }, -#endif - { "arp", ETHERTYPE_ARP }, - { "rarp", ETHERTYPE_REVARP }, - { "sprite", ETHERTYPE_SPRITE }, - { "mopdl", ETHERTYPE_MOPDL }, - { "moprc", ETHERTYPE_MOPRC }, - { "decnet", ETHERTYPE_DN }, - { "lat", ETHERTYPE_LAT }, - { "sca", ETHERTYPE_SCA }, - { "lanbridge", ETHERTYPE_LANBRIDGE }, - { "vexp", ETHERTYPE_VEXP }, - { "vprod", ETHERTYPE_VPROD }, - { "atalk", ETHERTYPE_ATALK }, - { "atalkarp", ETHERTYPE_AARP }, - { "loopback", ETHERTYPE_LOOPBACK }, - { "decdts", ETHERTYPE_DECDTS }, - { "decdns", ETHERTYPE_DECDNS }, - { (char *)0, 0 } -}; - -int -pcap_nametoeproto(const char *s) -{ - struct eproto *p = eproto_db; - - while (p->s != 0) { - if (strcmp(p->s, s) == 0) - return p->p; - p += 1; - } - return PROTO_UNDEF; -} - -/* Hex digit to integer. */ -static inline int -xdtoi(c) - register int c; -{ - if (isdigit(c)) - return c - '0'; - else if (islower(c)) - return c - 'a' + 10; - else - return c - 'A' + 10; -} - -int -__pcap_atoin(const char *s, bpf_u_int32 *addr) -{ - u_int n; - int len; - - *addr = 0; - len = 0; - while (1) { - n = 0; - while (*s && *s != '.') - n = n * 10 + *s++ - '0'; - *addr <<= 8; - *addr |= n & 0xff; - len += 8; - if (*s == '\0') - return len; - ++s; - } - /* NOTREACHED */ -} - -int -__pcap_atodn(const char *s, bpf_u_int32 *addr) -{ -#define AREASHIFT 10 -#define AREAMASK 0176000 -#define NODEMASK 01777 - - u_int node, area; - - if (sscanf((char *)s, "%d.%d", &area, &node) != 2) - bpf_error("malformed decnet address '%s'", s); - - *addr = (area << AREASHIFT) & AREAMASK; - *addr |= (node & NODEMASK); - - return(32); -} - -/* - * Convert 's' which has the form "xx:xx:xx:xx:xx:xx" into a new - * ethernet address. Assumes 's' is well formed. - */ -u_char * -pcap_ether_aton(const char *s) -{ - register u_char *ep, *e; - register u_int d; - - e = ep = (u_char *)malloc(6); - - while (*s) { - if (*s == ':') - s += 1; - d = xdtoi(*s++); - if (isxdigit((unsigned char)*s)) { - d <<= 4; - d |= xdtoi(*s++); - } - *ep++ = d; - } - - return (e); -} - -#ifndef HAVE_ETHER_HOSTTON -/* Roll our own */ -u_char * -pcap_ether_hostton(const char *name) -{ - register struct pcap_etherent *ep; - register u_char *ap; - static FILE *fp = NULL; - static int init = 0; - - if (!init) { - fp = fopen(PCAP_ETHERS_FILE, "r"); - ++init; - if (fp == NULL) - return (NULL); - } else if (fp == NULL) - return (NULL); - else - rewind(fp); - - while ((ep = pcap_next_etherent(fp)) != NULL) { - if (strcmp(ep->name, name) == 0) { - ap = (u_char *)malloc(6); - if (ap != NULL) { - memcpy(ap, ep->addr, 6); - return (ap); - } - break; - } - } - return (NULL); -} -#else - -/* - * XXX - perhaps this should, instead, be declared in "lbl/os-XXX.h" files, - * for those OS versions that don't declare it, rather than being declared - * here? That way, for example, we could declare it on FreeBSD 2.x (which - * doesn't declare it), but not on FreeBSD 3.x (which declares it like - * this) or FreeBSD 4.x (which declares it with its first argument as - * "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__) && \ - !defined(_UNICOSMP) -extern int ether_hostton(char *, struct ether_addr *); -#endif - -/* Use the os supplied routines */ -u_char * -pcap_ether_hostton(const char *name) -{ - register u_char *ap; - u_char a[6]; - - ap = NULL; - if (ether_hostton((char *)name, (struct ether_addr *)a) == 0) { - ap = (u_char *)malloc(6); - if (ap != NULL) - memcpy((char *)ap, (char *)a, 6); - } - return (ap); -} -#endif - -u_short -__pcap_nametodnaddr(const char *name) -{ -#ifdef DECNETLIB - struct nodeent *getnodebyname(); - struct nodeent *nep; - unsigned short res; - - nep = getnodebyname(name); - if (nep == ((struct nodeent *)0)) - bpf_error("unknown decnet host name '%s'\n", name); - - memcpy((char *)&res, (char *)nep->n_addr, sizeof(unsigned short)); - return(res); -#else - bpf_error("decnet name support not included, '%s' cannot be translated\n", - name); - return(0); -#endif -} diff --git a/contrib/libpcap-0.8.3/nlpid.h b/contrib/libpcap-0.8.3/nlpid.h deleted file mode 100644 index c3ab8c2cb3..0000000000 --- a/contrib/libpcap-0.8.3/nlpid.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 1996 - * Juniper Networks, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that: (1) source code distributions - * retain the above copyright notice and this paragraph in its entirety, (2) - * distributions including binary code include the above copyright notice and - * this paragraph in its entirety in the documentation or other materials - * provided with the distribution. The name of Juniper Networks may not - * be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * @(#) $Header: /tcpdump/master/libpcap/nlpid.h,v 1.2 2002/12/06 00:01:34 hannes Exp $ (Juniper) - */ - -/* Types missing from some systems */ - -/* - * Network layer prototocol identifiers - */ -#ifndef ISO8473_CLNP -#define ISO8473_CLNP 0x81 -#endif -#ifndef ISO9542_ESIS -#define ISO9542_ESIS 0x82 -#endif -#ifndef ISO9542X25_ESIS -#define ISO9542X25_ESIS 0x8a -#endif -#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 -#ifndef ISO10747_IDRP -#define ISO10747_IDRP 0x85 -#endif diff --git a/contrib/libpcap-0.8.3/optimize.c b/contrib/libpcap-0.8.3/optimize.c deleted file mode 100644 index ea9f50d2f0..0000000000 --- a/contrib/libpcap-0.8.3/optimize.c +++ /dev/null @@ -1,2165 +0,0 @@ -/* - * Copyright (c) 1988, 1989, 1990, 1991, 1993, 1994, 1995, 1996 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that: (1) source code distributions - * retain the above copyright notice and this paragraph in its entirety, (2) - * distributions including binary code include the above copyright notice and - * this paragraph in its entirety in the documentation or other materials - * provided with the distribution, and (3) all advertising materials mentioning - * features or use of this software display the following acknowledgement: - * ``This product includes software developed by the University of California, - * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of - * the University nor the names of its contributors may be used to endorse - * or promote products derived from this software without specific prior - * written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * Optimization module for tcpdump intermediate representation. - */ -#ifndef lint -static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/libpcap/optimize.c,v 1.76.2.3 2003/12/22 00:26:36 guy Exp $ (LBL)"; -#endif - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include - -#include - -#include "pcap-int.h" - -#include "gencode.h" - -#ifdef HAVE_OS_PROTO_H -#include "os-proto.h" -#endif - -#ifdef BDEBUG -extern int dflag; -#endif - -#define A_ATOM BPF_MEMWORDS -#define X_ATOM (BPF_MEMWORDS+1) - -#define NOP -1 - -/* - * This define is used to represent *both* the accumulator and - * x register in use-def computations. - * Currently, the use-def code assumes only one definition per instruction. - */ -#define AX_ATOM N_ATOMS - -/* - * A flag to indicate that further optimization is needed. - * Iterative passes are continued until a given pass yields no - * branch movement. - */ -static int done; - -/* - * A block is marked if only if its mark equals the current mark. - * Rather than traverse the code array, marking each item, 'cur_mark' is - * incremented. This automatically makes each element unmarked. - */ -static int cur_mark; -#define isMarked(p) ((p)->mark == cur_mark) -#define unMarkAll() cur_mark += 1 -#define Mark(p) ((p)->mark = cur_mark) - -static void opt_init(struct block *); -static void opt_cleanup(void); - -static void make_marks(struct block *); -static void mark_code(struct block *); - -static void intern_blocks(struct block *); - -static int eq_slist(struct slist *, struct slist *); - -static void find_levels_r(struct block *); - -static void find_levels(struct block *); -static void find_dom(struct block *); -static void propedom(struct edge *); -static void find_edom(struct block *); -static void find_closure(struct block *); -static int atomuse(struct stmt *); -static int atomdef(struct stmt *); -static void compute_local_ud(struct block *); -static void find_ud(struct block *); -static void init_val(void); -static int F(int, int, int); -static inline void vstore(struct stmt *, int *, int, int); -static void opt_blk(struct block *, int); -static int use_conflict(struct block *, struct block *); -static void opt_j(struct edge *); -static void or_pullup(struct block *); -static void and_pullup(struct block *); -static void opt_blks(struct block *, int); -static inline void link_inedge(struct edge *, struct block *); -static void find_inedges(struct block *); -static void opt_root(struct block **); -static void opt_loop(struct block *, int); -static void fold_op(struct stmt *, int, int); -static inline struct slist *this_op(struct slist *); -static void opt_not(struct block *); -static void opt_peep(struct block *); -static void opt_stmt(struct stmt *, int[], int); -static void deadstmt(struct stmt *, struct stmt *[]); -static void opt_deadstores(struct block *); -static struct block *fold_edge(struct block *, struct edge *); -static inline int eq_blk(struct block *, struct block *); -static int slength(struct slist *); -static int count_blocks(struct block *); -static void number_blks_r(struct block *); -static int count_stmts(struct block *); -static int convert_code_r(struct block *); -#ifdef BDEBUG -static void opt_dump(struct block *); -#endif - -static int n_blocks; -struct block **blocks; -static int n_edges; -struct edge **edges; - -/* - * A bit vector set representation of the dominators. - * We round up the set size to the next power of two. - */ -static int nodewords; -static int edgewords; -struct block **levels; -bpf_u_int32 *space; -#define BITS_PER_WORD (8*sizeof(bpf_u_int32)) -/* - * True if a is in uset {p} - */ -#define SET_MEMBER(p, a) \ -((p)[(unsigned)(a) / BITS_PER_WORD] & (1 << ((unsigned)(a) % BITS_PER_WORD))) - -/* - * Add 'a' to uset p. - */ -#define SET_INSERT(p, a) \ -(p)[(unsigned)(a) / BITS_PER_WORD] |= (1 << ((unsigned)(a) % BITS_PER_WORD)) - -/* - * Delete 'a' from uset p. - */ -#define SET_DELETE(p, a) \ -(p)[(unsigned)(a) / BITS_PER_WORD] &= ~(1 << ((unsigned)(a) % BITS_PER_WORD)) - -/* - * a := a intersect b - */ -#define SET_INTERSECT(a, b, n)\ -{\ - register bpf_u_int32 *_x = a, *_y = b;\ - register int _n = n;\ - while (--_n >= 0) *_x++ &= *_y++;\ -} - -/* - * a := a - b - */ -#define SET_SUBTRACT(a, b, n)\ -{\ - register bpf_u_int32 *_x = a, *_y = b;\ - register int _n = n;\ - while (--_n >= 0) *_x++ &=~ *_y++;\ -} - -/* - * a := a union b - */ -#define SET_UNION(a, b, n)\ -{\ - register bpf_u_int32 *_x = a, *_y = b;\ - register int _n = n;\ - while (--_n >= 0) *_x++ |= *_y++;\ -} - -static uset all_dom_sets; -static uset all_closure_sets; -static uset all_edge_sets; - -#ifndef MAX -#define MAX(a,b) ((a)>(b)?(a):(b)) -#endif - -static void -find_levels_r(b) - struct block *b; -{ - int level; - - if (isMarked(b)) - return; - - Mark(b); - b->link = 0; - - if (JT(b)) { - find_levels_r(JT(b)); - find_levels_r(JF(b)); - level = MAX(JT(b)->level, JF(b)->level) + 1; - } else - level = 0; - b->level = level; - b->link = levels[level]; - levels[level] = b; -} - -/* - * Level graph. The levels go from 0 at the leaves to - * N_LEVELS at the root. The levels[] array points to the - * first node of the level list, whose elements are linked - * with the 'link' field of the struct block. - */ -static void -find_levels(root) - struct block *root; -{ - memset((char *)levels, 0, n_blocks * sizeof(*levels)); - unMarkAll(); - find_levels_r(root); -} - -/* - * Find dominator relationships. - * Assumes graph has been leveled. - */ -static void -find_dom(root) - struct block *root; -{ - int i; - struct block *b; - bpf_u_int32 *x; - - /* - * Initialize sets to contain all nodes. - */ - x = all_dom_sets; - i = n_blocks * nodewords; - while (--i >= 0) - *x++ = ~0; - /* Root starts off empty. */ - for (i = nodewords; --i >= 0;) - root->dom[i] = 0; - - /* root->level is the highest level no found. */ - for (i = root->level; i >= 0; --i) { - for (b = levels[i]; b; b = b->link) { - SET_INSERT(b->dom, b->id); - if (JT(b) == 0) - continue; - SET_INTERSECT(JT(b)->dom, b->dom, nodewords); - SET_INTERSECT(JF(b)->dom, b->dom, nodewords); - } - } -} - -static void -propedom(ep) - struct edge *ep; -{ - SET_INSERT(ep->edom, ep->id); - if (ep->succ) { - SET_INTERSECT(ep->succ->et.edom, ep->edom, edgewords); - SET_INTERSECT(ep->succ->ef.edom, ep->edom, edgewords); - } -} - -/* - * Compute edge dominators. - * Assumes graph has been leveled and predecessors established. - */ -static void -find_edom(root) - struct block *root; -{ - int i; - uset x; - struct block *b; - - x = all_edge_sets; - for (i = n_edges * edgewords; --i >= 0; ) - x[i] = ~0; - - /* root->level is the highest level no found. */ - memset(root->et.edom, 0, edgewords * sizeof(*(uset)0)); - memset(root->ef.edom, 0, edgewords * sizeof(*(uset)0)); - for (i = root->level; i >= 0; --i) { - for (b = levels[i]; b != 0; b = b->link) { - propedom(&b->et); - propedom(&b->ef); - } - } -} - -/* - * Find the backwards transitive closure of the flow graph. These sets - * are backwards in the sense that we find the set of nodes that reach - * a given node, not the set of nodes that can be reached by a node. - * - * Assumes graph has been leveled. - */ -static void -find_closure(root) - struct block *root; -{ - int i; - struct block *b; - - /* - * Initialize sets to contain no nodes. - */ - memset((char *)all_closure_sets, 0, - n_blocks * nodewords * sizeof(*all_closure_sets)); - - /* root->level is the highest level no found. */ - for (i = root->level; i >= 0; --i) { - for (b = levels[i]; b; b = b->link) { - SET_INSERT(b->closure, b->id); - if (JT(b) == 0) - continue; - SET_UNION(JT(b)->closure, b->closure, nodewords); - SET_UNION(JF(b)->closure, b->closure, nodewords); - } - } -} - -/* - * Return the register number that is used by s. If A and X are both - * used, return AX_ATOM. If no register is used, return -1. - * - * The implementation should probably change to an array access. - */ -static int -atomuse(s) - struct stmt *s; -{ - register int c = s->code; - - if (c == NOP) - return -1; - - switch (BPF_CLASS(c)) { - - case BPF_RET: - return (BPF_RVAL(c) == BPF_A) ? A_ATOM : - (BPF_RVAL(c) == BPF_X) ? X_ATOM : -1; - - case BPF_LD: - case BPF_LDX: - return (BPF_MODE(c) == BPF_IND) ? X_ATOM : - (BPF_MODE(c) == BPF_MEM) ? s->k : -1; - - case BPF_ST: - return A_ATOM; - - case BPF_STX: - return X_ATOM; - - case BPF_JMP: - case BPF_ALU: - if (BPF_SRC(c) == BPF_X) - return AX_ATOM; - return A_ATOM; - - case BPF_MISC: - return BPF_MISCOP(c) == BPF_TXA ? X_ATOM : A_ATOM; - } - abort(); - /* NOTREACHED */ -} - -/* - * Return the register number that is defined by 's'. We assume that - * a single stmt cannot define more than one register. If no register - * is defined, return -1. - * - * The implementation should probably change to an array access. - */ -static int -atomdef(s) - struct stmt *s; -{ - if (s->code == NOP) - return -1; - - switch (BPF_CLASS(s->code)) { - - case BPF_LD: - case BPF_ALU: - return A_ATOM; - - case BPF_LDX: - return X_ATOM; - - case BPF_ST: - case BPF_STX: - return s->k; - - case BPF_MISC: - return BPF_MISCOP(s->code) == BPF_TAX ? X_ATOM : A_ATOM; - } - return -1; -} - -static void -compute_local_ud(b) - struct block *b; -{ - struct slist *s; - atomset def = 0, use = 0, kill = 0; - int atom; - - for (s = b->stmts; s; s = s->next) { - if (s->s.code == NOP) - continue; - atom = atomuse(&s->s); - if (atom >= 0) { - if (atom == AX_ATOM) { - if (!ATOMELEM(def, X_ATOM)) - use |= ATOMMASK(X_ATOM); - if (!ATOMELEM(def, A_ATOM)) - use |= ATOMMASK(A_ATOM); - } - else if (atom < N_ATOMS) { - if (!ATOMELEM(def, atom)) - use |= ATOMMASK(atom); - } - else - abort(); - } - atom = atomdef(&s->s); - if (atom >= 0) { - if (!ATOMELEM(use, atom)) - kill |= ATOMMASK(atom); - def |= ATOMMASK(atom); - } - } - if (!ATOMELEM(def, A_ATOM) && BPF_CLASS(b->s.code) == BPF_JMP) - use |= ATOMMASK(A_ATOM); - - b->def = def; - b->kill = kill; - b->in_use = use; -} - -/* - * Assume graph is already leveled. - */ -static void -find_ud(root) - struct block *root; -{ - int i, maxlevel; - struct block *p; - - /* - * root->level is the highest level no found; - * count down from there. - */ - maxlevel = root->level; - for (i = maxlevel; i >= 0; --i) - for (p = levels[i]; p; p = p->link) { - compute_local_ud(p); - p->out_use = 0; - } - - for (i = 1; i <= maxlevel; ++i) { - for (p = levels[i]; p; p = p->link) { - p->out_use |= JT(p)->in_use | JF(p)->in_use; - p->in_use |= p->out_use &~ p->kill; - } - } -} - -/* - * These data structures are used in a Cocke and Shwarz style - * value numbering scheme. Since the flowgraph is acyclic, - * exit values can be propagated from a node's predecessors - * provided it is uniquely defined. - */ -struct valnode { - int code; - int v0, v1; - int val; - struct valnode *next; -}; - -#define MODULUS 213 -static struct valnode *hashtbl[MODULUS]; -static int curval; -static int maxval; - -/* Integer constants mapped with the load immediate opcode. */ -#define K(i) F(BPF_LD|BPF_IMM|BPF_W, i, 0L) - -struct vmapinfo { - int is_const; - bpf_int32 const_val; -}; - -struct vmapinfo *vmap; -struct valnode *vnode_base; -struct valnode *next_vnode; - -static void -init_val() -{ - curval = 0; - next_vnode = vnode_base; - memset((char *)vmap, 0, maxval * sizeof(*vmap)); - memset((char *)hashtbl, 0, sizeof hashtbl); -} - -/* Because we really don't have an IR, this stuff is a little messy. */ -static int -F(code, v0, v1) - int code; - int v0, v1; -{ - u_int hash; - int val; - struct valnode *p; - - hash = (u_int)code ^ (v0 << 4) ^ (v1 << 8); - hash %= MODULUS; - - for (p = hashtbl[hash]; p; p = p->next) - if (p->code == code && p->v0 == v0 && p->v1 == v1) - return p->val; - - val = ++curval; - if (BPF_MODE(code) == BPF_IMM && - (BPF_CLASS(code) == BPF_LD || BPF_CLASS(code) == BPF_LDX)) { - vmap[val].const_val = v0; - vmap[val].is_const = 1; - } - p = next_vnode++; - p->val = val; - p->code = code; - p->v0 = v0; - p->v1 = v1; - p->next = hashtbl[hash]; - hashtbl[hash] = p; - - return val; -} - -static inline void -vstore(s, valp, newval, alter) - struct stmt *s; - int *valp; - int newval; - int alter; -{ - if (alter && *valp == newval) - s->code = NOP; - else - *valp = newval; -} - -static void -fold_op(s, v0, v1) - struct stmt *s; - int v0, v1; -{ - bpf_int32 a, b; - - a = vmap[v0].const_val; - b = vmap[v1].const_val; - - switch (BPF_OP(s->code)) { - case BPF_ADD: - a += b; - break; - - case BPF_SUB: - a -= b; - break; - - case BPF_MUL: - a *= b; - break; - - case BPF_DIV: - if (b == 0) - bpf_error("division by zero"); - a /= b; - break; - - case BPF_AND: - a &= b; - break; - - case BPF_OR: - a |= b; - break; - - case BPF_LSH: - a <<= b; - break; - - case BPF_RSH: - a >>= b; - break; - - case BPF_NEG: - a = -a; - break; - - default: - abort(); - } - s->k = a; - s->code = BPF_LD|BPF_IMM; - done = 0; -} - -static inline struct slist * -this_op(s) - struct slist *s; -{ - while (s != 0 && s->s.code == NOP) - s = s->next; - return s; -} - -static void -opt_not(b) - struct block *b; -{ - struct block *tmp = JT(b); - - JT(b) = JF(b); - JF(b) = tmp; -} - -static void -opt_peep(b) - struct block *b; -{ - struct slist *s; - struct slist *next, *last; - int val; - - s = b->stmts; - if (s == 0) - return; - - last = s; - while (1) { - s = this_op(s); - if (s == 0) - break; - next = this_op(s->next); - if (next == 0) - break; - last = next; - - /* - * st M[k] --> st M[k] - * ldx M[k] tax - */ - if (s->s.code == BPF_ST && - next->s.code == (BPF_LDX|BPF_MEM) && - s->s.k == next->s.k) { - done = 0; - next->s.code = BPF_MISC|BPF_TAX; - } - /* - * ld #k --> ldx #k - * tax txa - */ - if (s->s.code == (BPF_LD|BPF_IMM) && - next->s.code == (BPF_MISC|BPF_TAX)) { - s->s.code = BPF_LDX|BPF_IMM; - next->s.code = BPF_MISC|BPF_TXA; - done = 0; - } - /* - * This is an ugly special case, but it happens - * when you say tcp[k] or udp[k] where k is a constant. - */ - if (s->s.code == (BPF_LD|BPF_IMM)) { - struct slist *add, *tax, *ild; - - /* - * Check that X isn't used on exit from this - * block (which the optimizer might cause). - * We know the code generator won't generate - * any local dependencies. - */ - if (ATOMELEM(b->out_use, X_ATOM)) - break; - - if (next->s.code != (BPF_LDX|BPF_MSH|BPF_B)) - add = next; - else - add = this_op(next->next); - if (add == 0 || add->s.code != (BPF_ALU|BPF_ADD|BPF_X)) - break; - - tax = this_op(add->next); - if (tax == 0 || tax->s.code != (BPF_MISC|BPF_TAX)) - break; - - ild = this_op(tax->next); - if (ild == 0 || BPF_CLASS(ild->s.code) != BPF_LD || - BPF_MODE(ild->s.code) != BPF_IND) - break; - /* - * XXX We need to check that X is not - * subsequently used. We know we can eliminate the - * accumulator modifications since it is defined - * by the last stmt of this sequence. - * - * We want to turn this sequence: - * - * (004) ldi #0x2 {s} - * (005) ldxms [14] {next} -- optional - * (006) addx {add} - * (007) tax {tax} - * (008) ild [x+0] {ild} - * - * into this sequence: - * - * (004) nop - * (005) ldxms [14] - * (006) nop - * (007) nop - * (008) ild [x+2] - * - */ - ild->s.k += s->s.k; - s->s.code = NOP; - add->s.code = NOP; - tax->s.code = NOP; - done = 0; - } - s = next; - } - /* - * If we have a subtract to do a comparison, and the X register - * is a known constant, we can merge this value into the - * comparison. - */ - if (BPF_OP(b->s.code) == BPF_JEQ) { - if (last->s.code == (BPF_ALU|BPF_SUB|BPF_X) && - !ATOMELEM(b->out_use, A_ATOM)) { - val = b->val[X_ATOM]; - if (vmap[val].is_const) { - /* - * sub x -> nop - * jeq #y jeq #(x+y) - */ - b->s.k += vmap[val].const_val; - last->s.code = NOP; - done = 0; - } else if (b->s.k == 0) { - /* - * sub #x -> nop - * jeq #0 jeq #x - */ - last->s.code = NOP; - b->s.code = BPF_CLASS(b->s.code) | - BPF_OP(b->s.code) | BPF_X; - done = 0; - } - } - /* - * Likewise, a constant subtract can be simplified. - */ - else if (last->s.code == (BPF_ALU|BPF_SUB|BPF_K) && - !ATOMELEM(b->out_use, A_ATOM)) { - - last->s.code = NOP; - b->s.k += last->s.k; - done = 0; - } - } - /* - * and #k nop - * jeq #0 -> jset #k - */ - if (last->s.code == (BPF_ALU|BPF_AND|BPF_K) && - !ATOMELEM(b->out_use, A_ATOM) && b->s.k == 0) { - b->s.k = last->s.k; - b->s.code = BPF_JMP|BPF_K|BPF_JSET; - last->s.code = NOP; - done = 0; - opt_not(b); - } - /* - * jset #0 -> never - * jset #ffffffff -> always - */ - if (b->s.code == (BPF_JMP|BPF_K|BPF_JSET)) { - if (b->s.k == 0) - JT(b) = JF(b); - if (b->s.k == 0xffffffff) - JF(b) = JT(b); - } - /* - * If the accumulator is a known constant, we can compute the - * comparison result. - */ - val = b->val[A_ATOM]; - if (vmap[val].is_const && BPF_SRC(b->s.code) == BPF_K) { - bpf_int32 v = vmap[val].const_val; - switch (BPF_OP(b->s.code)) { - - case BPF_JEQ: - v = v == b->s.k; - break; - - case BPF_JGT: - v = (unsigned)v > b->s.k; - break; - - case BPF_JGE: - v = (unsigned)v >= b->s.k; - break; - - case BPF_JSET: - v &= b->s.k; - break; - - default: - abort(); - } - if (JF(b) != JT(b)) - done = 0; - if (v) - JF(b) = JT(b); - else - JT(b) = JF(b); - } -} - -/* - * Compute the symbolic value of expression of 's', and update - * anything it defines in the value table 'val'. If 'alter' is true, - * do various optimizations. This code would be cleaner if symbolic - * evaluation and code transformations weren't folded together. - */ -static void -opt_stmt(s, val, alter) - struct stmt *s; - int val[]; - int alter; -{ - int op; - int v; - - switch (s->code) { - - case BPF_LD|BPF_ABS|BPF_W: - case BPF_LD|BPF_ABS|BPF_H: - case BPF_LD|BPF_ABS|BPF_B: - v = F(s->code, s->k, 0L); - vstore(s, &val[A_ATOM], v, alter); - break; - - case BPF_LD|BPF_IND|BPF_W: - case BPF_LD|BPF_IND|BPF_H: - case BPF_LD|BPF_IND|BPF_B: - v = val[X_ATOM]; - if (alter && vmap[v].is_const) { - s->code = BPF_LD|BPF_ABS|BPF_SIZE(s->code); - s->k += vmap[v].const_val; - v = F(s->code, s->k, 0L); - done = 0; - } - else - v = F(s->code, s->k, v); - vstore(s, &val[A_ATOM], v, alter); - break; - - case BPF_LD|BPF_LEN: - v = F(s->code, 0L, 0L); - vstore(s, &val[A_ATOM], v, alter); - break; - - case BPF_LD|BPF_IMM: - v = K(s->k); - vstore(s, &val[A_ATOM], v, alter); - break; - - case BPF_LDX|BPF_IMM: - v = K(s->k); - vstore(s, &val[X_ATOM], v, alter); - break; - - case BPF_LDX|BPF_MSH|BPF_B: - v = F(s->code, s->k, 0L); - vstore(s, &val[X_ATOM], v, alter); - break; - - case BPF_ALU|BPF_NEG: - if (alter && vmap[val[A_ATOM]].is_const) { - s->code = BPF_LD|BPF_IMM; - s->k = -vmap[val[A_ATOM]].const_val; - val[A_ATOM] = K(s->k); - } - else - val[A_ATOM] = F(s->code, val[A_ATOM], 0L); - break; - - case BPF_ALU|BPF_ADD|BPF_K: - case BPF_ALU|BPF_SUB|BPF_K: - case BPF_ALU|BPF_MUL|BPF_K: - case BPF_ALU|BPF_DIV|BPF_K: - case BPF_ALU|BPF_AND|BPF_K: - case BPF_ALU|BPF_OR|BPF_K: - case BPF_ALU|BPF_LSH|BPF_K: - case BPF_ALU|BPF_RSH|BPF_K: - op = BPF_OP(s->code); - if (alter) { - if (s->k == 0) { - /* don't optimize away "sub #0" - * as it may be needed later to - * fixup the generated math code */ - if (op == BPF_ADD || - op == BPF_LSH || op == BPF_RSH || - op == BPF_OR) { - s->code = NOP; - break; - } - if (op == BPF_MUL || op == BPF_AND) { - s->code = BPF_LD|BPF_IMM; - val[A_ATOM] = K(s->k); - break; - } - } - if (vmap[val[A_ATOM]].is_const) { - fold_op(s, val[A_ATOM], K(s->k)); - val[A_ATOM] = K(s->k); - break; - } - } - val[A_ATOM] = F(s->code, val[A_ATOM], K(s->k)); - break; - - case BPF_ALU|BPF_ADD|BPF_X: - case BPF_ALU|BPF_SUB|BPF_X: - case BPF_ALU|BPF_MUL|BPF_X: - case BPF_ALU|BPF_DIV|BPF_X: - case BPF_ALU|BPF_AND|BPF_X: - case BPF_ALU|BPF_OR|BPF_X: - case BPF_ALU|BPF_LSH|BPF_X: - case BPF_ALU|BPF_RSH|BPF_X: - op = BPF_OP(s->code); - if (alter && vmap[val[X_ATOM]].is_const) { - if (vmap[val[A_ATOM]].is_const) { - fold_op(s, val[A_ATOM], val[X_ATOM]); - val[A_ATOM] = K(s->k); - } - else { - s->code = BPF_ALU|BPF_K|op; - s->k = vmap[val[X_ATOM]].const_val; - done = 0; - val[A_ATOM] = - F(s->code, val[A_ATOM], K(s->k)); - } - break; - } - /* - * Check if we're doing something to an accumulator - * that is 0, and simplify. This may not seem like - * much of a simplification but it could open up further - * optimizations. - * XXX We could also check for mul by 1, etc. - */ - if (alter && vmap[val[A_ATOM]].is_const - && vmap[val[A_ATOM]].const_val == 0) { - if (op == BPF_ADD || op == BPF_OR) { - s->code = BPF_MISC|BPF_TXA; - vstore(s, &val[A_ATOM], val[X_ATOM], alter); - break; - } - else if (op == BPF_MUL || op == BPF_DIV || - op == BPF_AND || op == BPF_LSH || op == BPF_RSH) { - s->code = BPF_LD|BPF_IMM; - s->k = 0; - vstore(s, &val[A_ATOM], K(s->k), alter); - break; - } - else if (op == BPF_NEG) { - s->code = NOP; - break; - } - } - val[A_ATOM] = F(s->code, val[A_ATOM], val[X_ATOM]); - break; - - case BPF_MISC|BPF_TXA: - vstore(s, &val[A_ATOM], val[X_ATOM], alter); - break; - - case BPF_LD|BPF_MEM: - v = val[s->k]; - if (alter && vmap[v].is_const) { - s->code = BPF_LD|BPF_IMM; - s->k = vmap[v].const_val; - done = 0; - } - vstore(s, &val[A_ATOM], v, alter); - break; - - case BPF_MISC|BPF_TAX: - vstore(s, &val[X_ATOM], val[A_ATOM], alter); - break; - - case BPF_LDX|BPF_MEM: - v = val[s->k]; - if (alter && vmap[v].is_const) { - s->code = BPF_LDX|BPF_IMM; - s->k = vmap[v].const_val; - done = 0; - } - vstore(s, &val[X_ATOM], v, alter); - break; - - case BPF_ST: - vstore(s, &val[s->k], val[A_ATOM], alter); - break; - - case BPF_STX: - vstore(s, &val[s->k], val[X_ATOM], alter); - break; - } -} - -static void -deadstmt(s, last) - register struct stmt *s; - register struct stmt *last[]; -{ - register int atom; - - atom = atomuse(s); - if (atom >= 0) { - if (atom == AX_ATOM) { - last[X_ATOM] = 0; - last[A_ATOM] = 0; - } - else - last[atom] = 0; - } - atom = atomdef(s); - if (atom >= 0) { - if (last[atom]) { - done = 0; - last[atom]->code = NOP; - } - last[atom] = s; - } -} - -static void -opt_deadstores(b) - register struct block *b; -{ - register struct slist *s; - register int atom; - struct stmt *last[N_ATOMS]; - - memset((char *)last, 0, sizeof last); - - for (s = b->stmts; s != 0; s = s->next) - deadstmt(&s->s, last); - deadstmt(&b->s, last); - - for (atom = 0; atom < N_ATOMS; ++atom) - if (last[atom] && !ATOMELEM(b->out_use, atom)) { - last[atom]->code = NOP; - done = 0; - } -} - -static void -opt_blk(b, do_stmts) - struct block *b; - int do_stmts; -{ - struct slist *s; - struct edge *p; - int i; - bpf_int32 aval; - -#if 0 - for (s = b->stmts; s && s->next; s = s->next) - if (BPF_CLASS(s->s.code) == BPF_JMP) { - do_stmts = 0; - break; - } -#endif - - /* - * Initialize the atom values. - * If we have no predecessors, everything is undefined. - * Otherwise, we inherent our values from our predecessors. - * If any register has an ambiguous value (i.e. control paths are - * merging) give it the undefined value of 0. - */ - p = b->in_edges; - if (p == 0) - memset((char *)b->val, 0, sizeof(b->val)); - else { - memcpy((char *)b->val, (char *)p->pred->val, sizeof(b->val)); - while ((p = p->next) != NULL) { - for (i = 0; i < N_ATOMS; ++i) - if (b->val[i] != p->pred->val[i]) - b->val[i] = 0; - } - } - aval = b->val[A_ATOM]; - for (s = b->stmts; s; s = s->next) - opt_stmt(&s->s, b->val, do_stmts); - - /* - * This is a special case: if we don't use anything from this - * block, and we load the accumulator with value that is - * already there, or if this block is a return, - * eliminate all the statements. - */ - if (do_stmts && - ((b->out_use == 0 && aval != 0 &&b->val[A_ATOM] == aval) || - BPF_CLASS(b->s.code) == BPF_RET)) { - if (b->stmts != 0) { - b->stmts = 0; - done = 0; - } - } else { - opt_peep(b); - opt_deadstores(b); - } - /* - * Set up values for branch optimizer. - */ - if (BPF_SRC(b->s.code) == BPF_K) - b->oval = K(b->s.k); - else - b->oval = b->val[X_ATOM]; - b->et.code = b->s.code; - b->ef.code = -b->s.code; -} - -/* - * Return true if any register that is used on exit from 'succ', has - * an exit value that is different from the corresponding exit value - * from 'b'. - */ -static int -use_conflict(b, succ) - struct block *b, *succ; -{ - int atom; - atomset use = succ->out_use; - - if (use == 0) - return 0; - - for (atom = 0; atom < N_ATOMS; ++atom) - if (ATOMELEM(use, atom)) - if (b->val[atom] != succ->val[atom]) - return 1; - return 0; -} - -static struct block * -fold_edge(child, ep) - struct block *child; - struct edge *ep; -{ - int sense; - int aval0, aval1, oval0, oval1; - int code = ep->code; - - if (code < 0) { - code = -code; - sense = 0; - } else - sense = 1; - - if (child->s.code != code) - return 0; - - aval0 = child->val[A_ATOM]; - oval0 = child->oval; - aval1 = ep->pred->val[A_ATOM]; - oval1 = ep->pred->oval; - - if (aval0 != aval1) - return 0; - - if (oval0 == oval1) - /* - * The operands are identical, so the - * result is true if a true branch was - * taken to get here, otherwise false. - */ - return sense ? JT(child) : JF(child); - - if (sense && code == (BPF_JMP|BPF_JEQ|BPF_K)) - /* - * At this point, we only know the comparison if we - * came down the true branch, and it was an equality - * comparison with a constant. We rely on the fact that - * distinct constants have distinct value numbers. - */ - return JF(child); - - return 0; -} - -static void -opt_j(ep) - struct edge *ep; -{ - register int i, k; - register struct block *target; - - if (JT(ep->succ) == 0) - return; - - if (JT(ep->succ) == JF(ep->succ)) { - /* - * Common branch targets can be eliminated, provided - * there is no data dependency. - */ - if (!use_conflict(ep->pred, ep->succ->et.succ)) { - done = 0; - ep->succ = JT(ep->succ); - } - } - /* - * For each edge dominator that matches the successor of this - * edge, promote the edge successor to the its grandchild. - * - * XXX We violate the set abstraction here in favor a reasonably - * efficient loop. - */ - top: - for (i = 0; i < edgewords; ++i) { - register bpf_u_int32 x = ep->edom[i]; - - while (x != 0) { - k = ffs(x) - 1; - x &=~ (1 << k); - k += i * BITS_PER_WORD; - - target = fold_edge(ep->succ, edges[k]); - /* - * Check that there is no data dependency between - * nodes that will be violated if we move the edge. - */ - if (target != 0 && !use_conflict(ep->pred, target)) { - done = 0; - ep->succ = target; - if (JT(target) != 0) - /* - * Start over unless we hit a leaf. - */ - goto top; - return; - } - } - } -} - - -static void -or_pullup(b) - struct block *b; -{ - int val, at_top; - struct block *pull; - struct block **diffp, **samep; - struct edge *ep; - - ep = b->in_edges; - if (ep == 0) - return; - - /* - * Make sure each predecessor loads the same value. - * XXX why? - */ - val = ep->pred->val[A_ATOM]; - for (ep = ep->next; ep != 0; ep = ep->next) - if (val != ep->pred->val[A_ATOM]) - return; - - if (JT(b->in_edges->pred) == b) - diffp = &JT(b->in_edges->pred); - else - diffp = &JF(b->in_edges->pred); - - at_top = 1; - while (1) { - if (*diffp == 0) - return; - - if (JT(*diffp) != JT(b)) - return; - - if (!SET_MEMBER((*diffp)->dom, b->id)) - return; - - if ((*diffp)->val[A_ATOM] != val) - break; - - diffp = &JF(*diffp); - at_top = 0; - } - samep = &JF(*diffp); - while (1) { - if (*samep == 0) - return; - - if (JT(*samep) != JT(b)) - return; - - if (!SET_MEMBER((*samep)->dom, b->id)) - return; - - if ((*samep)->val[A_ATOM] == val) - break; - - /* XXX Need to check that there are no data dependencies - between dp0 and dp1. Currently, the code generator - will not produce such dependencies. */ - samep = &JF(*samep); - } -#ifdef notdef - /* XXX This doesn't cover everything. */ - for (i = 0; i < N_ATOMS; ++i) - if ((*samep)->val[i] != pred->val[i]) - return; -#endif - /* Pull up the node. */ - pull = *samep; - *samep = JF(pull); - JF(pull) = *diffp; - - /* - * At the top of the chain, each predecessor needs to point at the - * pulled up node. Inside the chain, there is only one predecessor - * to worry about. - */ - if (at_top) { - for (ep = b->in_edges; ep != 0; ep = ep->next) { - if (JT(ep->pred) == b) - JT(ep->pred) = pull; - else - JF(ep->pred) = pull; - } - } - else - *diffp = pull; - - done = 0; -} - -static void -and_pullup(b) - struct block *b; -{ - int val, at_top; - struct block *pull; - struct block **diffp, **samep; - struct edge *ep; - - ep = b->in_edges; - if (ep == 0) - return; - - /* - * Make sure each predecessor loads the same value. - */ - val = ep->pred->val[A_ATOM]; - for (ep = ep->next; ep != 0; ep = ep->next) - if (val != ep->pred->val[A_ATOM]) - return; - - if (JT(b->in_edges->pred) == b) - diffp = &JT(b->in_edges->pred); - else - diffp = &JF(b->in_edges->pred); - - at_top = 1; - while (1) { - if (*diffp == 0) - return; - - if (JF(*diffp) != JF(b)) - return; - - if (!SET_MEMBER((*diffp)->dom, b->id)) - return; - - if ((*diffp)->val[A_ATOM] != val) - break; - - diffp = &JT(*diffp); - at_top = 0; - } - samep = &JT(*diffp); - while (1) { - if (*samep == 0) - return; - - if (JF(*samep) != JF(b)) - return; - - if (!SET_MEMBER((*samep)->dom, b->id)) - return; - - if ((*samep)->val[A_ATOM] == val) - break; - - /* XXX Need to check that there are no data dependencies - between diffp and samep. Currently, the code generator - will not produce such dependencies. */ - samep = &JT(*samep); - } -#ifdef notdef - /* XXX This doesn't cover everything. */ - for (i = 0; i < N_ATOMS; ++i) - if ((*samep)->val[i] != pred->val[i]) - return; -#endif - /* Pull up the node. */ - pull = *samep; - *samep = JT(pull); - JT(pull) = *diffp; - - /* - * At the top of the chain, each predecessor needs to point at the - * pulled up node. Inside the chain, there is only one predecessor - * to worry about. - */ - if (at_top) { - for (ep = b->in_edges; ep != 0; ep = ep->next) { - if (JT(ep->pred) == b) - JT(ep->pred) = pull; - else - JF(ep->pred) = pull; - } - } - else - *diffp = pull; - - done = 0; -} - -static void -opt_blks(root, do_stmts) - struct block *root; - int do_stmts; -{ - int i, maxlevel; - struct block *p; - - init_val(); - maxlevel = root->level; - - find_inedges(root); - for (i = maxlevel; i >= 0; --i) - for (p = levels[i]; p; p = p->link) - opt_blk(p, do_stmts); - - if (do_stmts) - /* - * No point trying to move branches; it can't possibly - * make a difference at this point. - */ - return; - - for (i = 1; i <= maxlevel; ++i) { - for (p = levels[i]; p; p = p->link) { - opt_j(&p->et); - opt_j(&p->ef); - } - } - - find_inedges(root); - for (i = 1; i <= maxlevel; ++i) { - for (p = levels[i]; p; p = p->link) { - or_pullup(p); - and_pullup(p); - } - } -} - -static inline void -link_inedge(parent, child) - struct edge *parent; - struct block *child; -{ - parent->next = child->in_edges; - child->in_edges = parent; -} - -static void -find_inedges(root) - struct block *root; -{ - int i; - struct block *b; - - for (i = 0; i < n_blocks; ++i) - blocks[i]->in_edges = 0; - - /* - * Traverse the graph, adding each edge to the predecessor - * list of its successors. Skip the leaves (i.e. level 0). - */ - for (i = root->level; i > 0; --i) { - for (b = levels[i]; b != 0; b = b->link) { - link_inedge(&b->et, JT(b)); - link_inedge(&b->ef, JF(b)); - } - } -} - -static void -opt_root(b) - struct block **b; -{ - struct slist *tmp, *s; - - s = (*b)->stmts; - (*b)->stmts = 0; - while (BPF_CLASS((*b)->s.code) == BPF_JMP && JT(*b) == JF(*b)) - *b = JT(*b); - - tmp = (*b)->stmts; - if (tmp != 0) - sappend(s, tmp); - (*b)->stmts = s; - - /* - * If the root node is a return, then there is no - * point executing any statements (since the bpf machine - * has no side effects). - */ - if (BPF_CLASS((*b)->s.code) == BPF_RET) - (*b)->stmts = 0; -} - -static void -opt_loop(root, do_stmts) - struct block *root; - int do_stmts; -{ - -#ifdef BDEBUG - if (dflag > 1) { - printf("opt_loop(root, %d) begin\n", do_stmts); - opt_dump(root); - } -#endif - do { - done = 1; - find_levels(root); - find_dom(root); - find_closure(root); - find_ud(root); - find_edom(root); - opt_blks(root, do_stmts); -#ifdef BDEBUG - if (dflag > 1) { - printf("opt_loop(root, %d) bottom, done=%d\n", do_stmts, done); - opt_dump(root); - } -#endif - } while (!done); -} - -/* - * Optimize the filter code in its dag representation. - */ -void -bpf_optimize(rootp) - struct block **rootp; -{ - struct block *root; - - root = *rootp; - - opt_init(root); - opt_loop(root, 0); - opt_loop(root, 1); - intern_blocks(root); -#ifdef BDEBUG - if (dflag > 1) { - printf("after intern_blocks()\n"); - opt_dump(root); - } -#endif - opt_root(rootp); -#ifdef BDEBUG - if (dflag > 1) { - printf("after opt_root()\n"); - opt_dump(root); - } -#endif - opt_cleanup(); -} - -static void -make_marks(p) - struct block *p; -{ - if (!isMarked(p)) { - Mark(p); - if (BPF_CLASS(p->s.code) != BPF_RET) { - make_marks(JT(p)); - make_marks(JF(p)); - } - } -} - -/* - * Mark code array such that isMarked(i) is true - * only for nodes that are alive. - */ -static void -mark_code(p) - struct block *p; -{ - cur_mark += 1; - make_marks(p); -} - -/* - * True iff the two stmt lists load the same value from the packet into - * the accumulator. - */ -static int -eq_slist(x, y) - struct slist *x, *y; -{ - while (1) { - while (x && x->s.code == NOP) - x = x->next; - while (y && y->s.code == NOP) - y = y->next; - if (x == 0) - return y == 0; - if (y == 0) - return x == 0; - if (x->s.code != y->s.code || x->s.k != y->s.k) - return 0; - x = x->next; - y = y->next; - } -} - -static inline int -eq_blk(b0, b1) - struct block *b0, *b1; -{ - if (b0->s.code == b1->s.code && - b0->s.k == b1->s.k && - b0->et.succ == b1->et.succ && - b0->ef.succ == b1->ef.succ) - return eq_slist(b0->stmts, b1->stmts); - return 0; -} - -static void -intern_blocks(root) - struct block *root; -{ - struct block *p; - int i, j; - int done; - top: - done = 1; - for (i = 0; i < n_blocks; ++i) - blocks[i]->link = 0; - - mark_code(root); - - for (i = n_blocks - 1; --i >= 0; ) { - if (!isMarked(blocks[i])) - continue; - for (j = i + 1; j < n_blocks; ++j) { - if (!isMarked(blocks[j])) - continue; - if (eq_blk(blocks[i], blocks[j])) { - blocks[i]->link = blocks[j]->link ? - blocks[j]->link : blocks[j]; - break; - } - } - } - for (i = 0; i < n_blocks; ++i) { - p = blocks[i]; - if (JT(p) == 0) - continue; - if (JT(p)->link) { - done = 0; - JT(p) = JT(p)->link; - } - if (JF(p)->link) { - done = 0; - JF(p) = JF(p)->link; - } - } - if (!done) - goto top; -} - -static void -opt_cleanup() -{ - free((void *)vnode_base); - free((void *)vmap); - free((void *)edges); - free((void *)space); - free((void *)levels); - free((void *)blocks); -} - -/* - * Return the number of stmts in 's'. - */ -static int -slength(s) - struct slist *s; -{ - int n = 0; - - for (; s; s = s->next) - if (s->s.code != NOP) - ++n; - return n; -} - -/* - * Return the number of nodes reachable by 'p'. - * All nodes should be initially unmarked. - */ -static int -count_blocks(p) - struct block *p; -{ - if (p == 0 || isMarked(p)) - return 0; - Mark(p); - return count_blocks(JT(p)) + count_blocks(JF(p)) + 1; -} - -/* - * Do a depth first search on the flow graph, numbering the - * the basic blocks, and entering them into the 'blocks' array.` - */ -static void -number_blks_r(p) - struct block *p; -{ - int n; - - if (p == 0 || isMarked(p)) - return; - - Mark(p); - n = n_blocks++; - p->id = n; - blocks[n] = p; - - number_blks_r(JT(p)); - number_blks_r(JF(p)); -} - -/* - * Return the number of stmts in the flowgraph reachable by 'p'. - * The nodes should be unmarked before calling. - * - * Note that "stmts" means "instructions", and that this includes - * - * side-effect statements in 'p' (slength(p->stmts)); - * - * statements in the true branch from 'p' (count_stmts(JT(p))); - * - * statements in the false branch from 'p' (count_stmts(JF(p))); - * - * the conditional jump itself (1); - * - * an extra long jump if the true branch requires it (p->longjt); - * - * an extra long jump if the false branch requires it (p->longjf). - */ -static int -count_stmts(p) - struct block *p; -{ - int n; - - if (p == 0 || isMarked(p)) - return 0; - Mark(p); - n = count_stmts(JT(p)) + count_stmts(JF(p)); - return slength(p->stmts) + n + 1 + p->longjt + p->longjf; -} - -/* - * Allocate memory. All allocation is done before optimization - * is begun. A linear bound on the size of all data structures is computed - * from the total number of blocks and/or statements. - */ -static void -opt_init(root) - struct block *root; -{ - bpf_u_int32 *p; - int i, n, max_stmts; - - /* - * First, count the blocks, so we can malloc an array to map - * block number to block. Then, put the blocks into the array. - */ - unMarkAll(); - n = count_blocks(root); - blocks = (struct block **)malloc(n * sizeof(*blocks)); - if (blocks == NULL) - bpf_error("malloc"); - unMarkAll(); - n_blocks = 0; - number_blks_r(root); - - n_edges = 2 * n_blocks; - edges = (struct edge **)malloc(n_edges * sizeof(*edges)); - if (edges == NULL) - bpf_error("malloc"); - - /* - * The number of levels is bounded by the number of nodes. - */ - levels = (struct block **)malloc(n_blocks * sizeof(*levels)); - if (levels == NULL) - bpf_error("malloc"); - - edgewords = n_edges / (8 * sizeof(bpf_u_int32)) + 1; - nodewords = n_blocks / (8 * sizeof(bpf_u_int32)) + 1; - - /* XXX */ - space = (bpf_u_int32 *)malloc(2 * n_blocks * nodewords * sizeof(*space) - + n_edges * edgewords * sizeof(*space)); - if (space == NULL) - bpf_error("malloc"); - p = space; - all_dom_sets = p; - for (i = 0; i < n; ++i) { - blocks[i]->dom = p; - p += nodewords; - } - all_closure_sets = p; - for (i = 0; i < n; ++i) { - blocks[i]->closure = p; - p += nodewords; - } - all_edge_sets = p; - for (i = 0; i < n; ++i) { - register struct block *b = blocks[i]; - - b->et.edom = p; - p += edgewords; - b->ef.edom = p; - p += edgewords; - b->et.id = i; - edges[i] = &b->et; - b->ef.id = n_blocks + i; - edges[n_blocks + i] = &b->ef; - b->et.pred = b; - b->ef.pred = b; - } - max_stmts = 0; - for (i = 0; i < n; ++i) - max_stmts += slength(blocks[i]->stmts) + 1; - /* - * We allocate at most 3 value numbers per statement, - * so this is an upper bound on the number of valnodes - * we'll need. - */ - maxval = 3 * max_stmts; - vmap = (struct vmapinfo *)malloc(maxval * sizeof(*vmap)); - vnode_base = (struct valnode *)malloc(maxval * sizeof(*vnode_base)); - if (vmap == NULL || vnode_base == NULL) - bpf_error("malloc"); -} - -/* - * Some pointers used to convert the basic block form of the code, - * into the array form that BPF requires. 'fstart' will point to - * the malloc'd array while 'ftail' is used during the recursive traversal. - */ -static struct bpf_insn *fstart; -static struct bpf_insn *ftail; - -#ifdef BDEBUG -int bids[1000]; -#endif - -/* - * Returns true if successful. Returns false if a branch has - * an offset that is too large. If so, we have marked that - * branch so that on a subsequent iteration, it will be treated - * properly. - */ -static int -convert_code_r(p) - struct block *p; -{ - struct bpf_insn *dst; - struct slist *src; - int slen; - u_int off; - int extrajmps; /* number of extra jumps inserted */ - struct slist **offset = NULL; - - if (p == 0 || isMarked(p)) - return (1); - Mark(p); - - if (convert_code_r(JF(p)) == 0) - return (0); - if (convert_code_r(JT(p)) == 0) - return (0); - - slen = slength(p->stmts); - dst = ftail -= (slen + 1 + p->longjt + p->longjf); - /* inflate length by any extra jumps */ - - p->offset = dst - fstart; - - /* generate offset[] for convenience */ - if (slen) { - offset = (struct slist **)calloc(slen, sizeof(struct slist *)); - if (!offset) { - bpf_error("not enough core"); - /*NOTREACHED*/ - } - } - src = p->stmts; - for (off = 0; off < slen && src; off++) { -#if 0 - printf("off=%d src=%x\n", off, src); -#endif - offset[off] = src; - src = src->next; - } - - off = 0; - for (src = p->stmts; src; src = src->next) { - if (src->s.code == NOP) - continue; - dst->code = (u_short)src->s.code; - dst->k = src->s.k; - - /* fill block-local relative jump */ - if (BPF_CLASS(src->s.code) != BPF_JMP || src->s.code == (BPF_JMP|BPF_JA)) { -#if 0 - if (src->s.jt || src->s.jf) { - bpf_error("illegal jmp destination"); - /*NOTREACHED*/ - } -#endif - goto filled; - } - if (off == slen - 2) /*???*/ - goto filled; - - { - int i; - int jt, jf; - char *ljerr = "%s for block-local relative jump: off=%d"; - -#if 0 - printf("code=%x off=%d %x %x\n", src->s.code, - off, src->s.jt, src->s.jf); -#endif - - if (!src->s.jt || !src->s.jf) { - bpf_error(ljerr, "no jmp destination", off); - /*NOTREACHED*/ - } - - jt = jf = 0; - for (i = 0; i < slen; i++) { - if (offset[i] == src->s.jt) { - if (jt) { - bpf_error(ljerr, "multiple matches", off); - /*NOTREACHED*/ - } - - dst->jt = i - off - 1; - jt++; - } - if (offset[i] == src->s.jf) { - if (jf) { - bpf_error(ljerr, "multiple matches", off); - /*NOTREACHED*/ - } - dst->jf = i - off - 1; - jf++; - } - } - if (!jt || !jf) { - bpf_error(ljerr, "no destination found", off); - /*NOTREACHED*/ - } - } -filled: - ++dst; - ++off; - } - if (offset) - free(offset); - -#ifdef BDEBUG - bids[dst - fstart] = p->id + 1; -#endif - dst->code = (u_short)p->s.code; - dst->k = p->s.k; - if (JT(p)) { - extrajmps = 0; - off = JT(p)->offset - (p->offset + slen) - 1; - if (off >= 256) { - /* offset too large for branch, must add a jump */ - if (p->longjt == 0) { - /* mark this instruction and retry */ - p->longjt++; - return(0); - } - /* branch if T to following jump */ - dst->jt = extrajmps; - extrajmps++; - dst[extrajmps].code = BPF_JMP|BPF_JA; - dst[extrajmps].k = off - extrajmps; - } - else - dst->jt = off; - off = JF(p)->offset - (p->offset + slen) - 1; - if (off >= 256) { - /* offset too large for branch, must add a jump */ - if (p->longjf == 0) { - /* mark this instruction and retry */ - p->longjf++; - return(0); - } - /* branch if F to following jump */ - /* if two jumps are inserted, F goes to second one */ - dst->jf = extrajmps; - extrajmps++; - dst[extrajmps].code = BPF_JMP|BPF_JA; - dst[extrajmps].k = off - extrajmps; - } - else - dst->jf = off; - } - return (1); -} - - -/* - * Convert flowgraph intermediate representation to the - * BPF array representation. Set *lenp to the number of instructions. - */ -struct bpf_insn * -icode_to_fcode(root, lenp) - struct block *root; - int *lenp; -{ - int n; - struct bpf_insn *fp; - - /* - * Loop doing convert_code_r() until no branches remain - * with too-large offsets. - */ - while (1) { - unMarkAll(); - n = *lenp = count_stmts(root); - - fp = (struct bpf_insn *)malloc(sizeof(*fp) * n); - if (fp == NULL) - bpf_error("malloc"); - memset((char *)fp, 0, sizeof(*fp) * n); - fstart = fp; - ftail = fp + n; - - unMarkAll(); - if (convert_code_r(root)) - break; - free(fp); - } - - return fp; -} - -/* - * Make a copy of a BPF program and put it in the "fcode" member of - * a "pcap_t". - * - * If we fail to allocate memory for the copy, fill in the "errbuf" - * member of the "pcap_t" with an error message, and return -1; - * otherwise, return 0. - */ -int -install_bpf_program(pcap_t *p, struct bpf_program *fp) -{ - size_t prog_size; - - /* - * Free up any already installed program. - */ - pcap_freecode(&p->fcode); - - prog_size = sizeof(*fp->bf_insns) * fp->bf_len; - p->fcode.bf_len = fp->bf_len; - p->fcode.bf_insns = (struct bpf_insn *)malloc(prog_size); - if (p->fcode.bf_insns == NULL) { - snprintf(p->errbuf, sizeof(p->errbuf), - "malloc: %s", pcap_strerror(errno)); - return (-1); - } - memcpy(p->fcode.bf_insns, fp->bf_insns, prog_size); - return (0); -} - -#ifdef BDEBUG -static void -opt_dump(root) - struct block *root; -{ - struct bpf_program f; - - memset(bids, 0, sizeof bids); - f.bf_insns = icode_to_fcode(root, &f.bf_len); - bpf_dump(&f, 1); - putchar('\n'); - free((char *)f.bf_insns); -} -#endif diff --git a/contrib/libpcap-0.8.3/pcap-bpf.c b/contrib/libpcap-0.8.3/pcap-bpf.c deleted file mode 100644 index 5b0eab6528..0000000000 --- a/contrib/libpcap-0.8.3/pcap-bpf.c +++ /dev/null @@ -1,910 +0,0 @@ -/* - * Copyright (c) 1993, 1994, 1995, 1996, 1998 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that: (1) source code distributions - * retain the above copyright notice and this paragraph in its entirety, (2) - * distributions including binary code include the above copyright notice and - * this paragraph in its entirety in the documentation or other materials - * provided with the distribution, and (3) all advertising materials mentioning - * features or use of this software display the following acknowledgement: - * ``This product includes software developed by the University of California, - * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of - * the University nor the names of its contributors may be used to endorse - * or promote products derived from this software without specific prior - * written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ -#ifndef lint -static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/libpcap/pcap-bpf.c,v 1.67.2.4 2003/11/22 00:06:28 guy Exp $ (LBL)"; -#endif - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include /* optionally get BSD define */ -#include -#include -#include -#include -#include -#include - -#include - -#ifdef _AIX - -/* - * Make "pcap.h" not include "pcap-bpf.h"; we are going to include the - * native OS version, as we need "struct bpf_config" from it. - */ -#define PCAP_DONT_INCLUDE_PCAP_BPF_H - -#include - -/* - * Prevent bpf.h from redefining the DLT_ values to their - * IFT_ values, as we're going to return the standard libpcap - * values, not IBM's non-standard IFT_ values. - */ -#undef _AIX -#include -#define _AIX - -#include /* for IFT_ values */ -#include -#include -#include -#include - -#ifdef __64BIT__ -#define domakedev makedev64 -#define getmajor major64 -#define bpf_hdr bpf_hdr32 -#else /* __64BIT__ */ -#define domakedev makedev -#define getmajor major -#endif /* __64BIT__ */ - -#define BPF_NAME "bpf" -#define BPF_MINORS 4 -#define DRIVER_PATH "/usr/lib/drivers" -#define BPF_NODE "/dev/bpf" -static int bpfloadedflag = 0; -static int odmlockid = 0; - -#else /* _AIX */ - -#include - -#endif /* _AIX */ - -#include -#include -#include -#include -#include -#include -#include - -#include "pcap-int.h" - -#ifdef HAVE_DAG_API -#include "pcap-dag.h" -#endif /* HAVE_DAG_API */ - -#ifdef HAVE_OS_PROTO_H -#include "os-proto.h" -#endif - -#include "gencode.h" /* for "no_optimize" */ - -static int pcap_setfilter_bpf(pcap_t *p, struct bpf_program *fp); -static int pcap_set_datalink_bpf(pcap_t *p, int dlt); - -static int -pcap_stats_bpf(pcap_t *p, struct pcap_stat *ps) -{ - struct bpf_stat s; - - /* - * "ps_recv" counts packets handed to the filter, not packets - * that passed the filter. This includes packets later dropped - * because we ran out of buffer space. - * - * "ps_drop" counts packets dropped inside the BPF device - * because we ran out of buffer space. It doesn't count - * packets dropped by the interface driver. It counts - * only packets that passed the filter. - * - * Both statistics include packets not yet read from the kernel - * by libpcap, and thus not yet seen by the application. - */ - if (ioctl(p->fd, BIOCGSTATS, (caddr_t)&s) < 0) { - snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCGSTATS: %s", - pcap_strerror(errno)); - return (-1); - } - - ps->ps_recv = s.bs_recv; - ps->ps_drop = s.bs_drop; - return (0); -} - -static int -pcap_read_bpf(pcap_t *p, int cnt, pcap_handler callback, u_char *user) -{ - int cc; - int n = 0; - register u_char *bp, *ep; - struct bpf_insn *fcode; - - fcode = p->md.use_bpf ? NULL : p->fcode.bf_insns; - again: - /* - * Has "pcap_breakloop()" been called? - */ - if (p->break_loop) { - /* - * Yes - clear the flag that indicates that it - * has, and return -2 to indicate that we were - * told to break out of the loop. - */ - p->break_loop = 0; - return (-2); - } - cc = p->cc; - if (p->cc == 0) { - cc = read(p->fd, (char *)p->buffer, p->bufsize); - if (cc < 0) { - /* Don't choke when we get ptraced */ - switch (errno) { - - case EINTR: - goto again; - -#ifdef _AIX - case EFAULT: - /* - * Sigh. More AIX wonderfulness. - * - * For some unknown reason the uiomove() - * operation in the bpf kernel extension - * used to copy the buffer into user - * space sometimes returns EFAULT. I have - * no idea why this is the case given that - * a kernel debugger shows the user buffer - * is correct. This problem appears to - * be mostly mitigated by the memset of - * the buffer before it is first used. - * Very strange.... Shaun Clowes - * - * In any case this means that we shouldn't - * treat EFAULT as a fatal error; as we - * don't have an API for returning - * a "some packets were dropped since - * the last packet you saw" indication, - * we just ignore EFAULT and keep reading. - */ - goto again; -#endif - - case EWOULDBLOCK: - return (0); -#if defined(sun) && !defined(BSD) - /* - * Due to a SunOS bug, after 2^31 bytes, the kernel - * file offset overflows and read fails with EINVAL. - * The lseek() to 0 will fix things. - */ - case EINVAL: - if (lseek(p->fd, 0L, SEEK_CUR) + - p->bufsize < 0) { - (void)lseek(p->fd, 0L, SEEK_SET); - goto again; - } - /* fall through */ -#endif - } - snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read: %s", - pcap_strerror(errno)); - return (-1); - } - bp = p->buffer; - } else - bp = p->bp; - - /* - * Loop through each packet. - */ -#define bhp ((struct bpf_hdr *)bp) - ep = bp + cc; - while (bp < ep) { - register int caplen, hdrlen; - - /* - * Has "pcap_breakloop()" been called? - * If so, return immediately - if we haven't read any - * packets, clear the flag and return -2 to indicate - * that we were told to break out of the loop, otherwise - * leave the flag set, so that the *next* call will break - * out of the loop without having read any packets, and - * return the number of packets we've processed so far. - */ - if (p->break_loop) { - if (n == 0) { - p->break_loop = 0; - return (-2); - } else { - p->bp = bp; - p->cc = ep - bp; - return (n); - } - } - - caplen = bhp->bh_caplen; - hdrlen = bhp->bh_hdrlen; - /* - * Short-circuit evaluation: if using BPF filter - * in kernel, no need to do it now. - */ - if (fcode == NULL || - bpf_filter(fcode, bp + hdrlen, bhp->bh_datalen, caplen)) { -#ifdef _AIX - /* - * AIX's BPF returns seconds/nanoseconds time - * stamps, not seconds/microseconds time stamps. - * - * XXX - I'm guessing here that it's a "struct - * timestamp"; if not, this code won't compile, - * but, if not, you want to send us a bug report - * and fall back on using DLPI. It's not as if - * BPF used to work right on AIX before this - * change; this change attempts to fix the fact - * that it didn't.... - */ - bhp->bh_tstamp.tv_usec = bhp->bh_tstamp.tv_usec/1000; -#endif - /* - * XXX A bpf_hdr matches a pcap_pkthdr. - */ - (*callback)(user, (struct pcap_pkthdr*)bp, bp + hdrlen); - bp += BPF_WORDALIGN(caplen + hdrlen); - if (++n >= cnt && cnt > 0) { - p->bp = bp; - p->cc = ep - bp; - return (n); - } - } else { - /* - * Skip this packet. - */ - bp += BPF_WORDALIGN(caplen + hdrlen); - } - } -#undef bhp - p->cc = 0; - return (n); -} - -#ifdef _AIX -static int -bpf_odminit(char *errbuf) -{ - char *errstr; - - if (odm_initialize() == -1) { - if (odm_err_msg(odmerrno, &errstr) == -1) - errstr = "Unknown error"; - snprintf(errbuf, PCAP_ERRBUF_SIZE, - "bpf_load: odm_initialize failed: %s", - errstr); - return (-1); - } - - if ((odmlockid = odm_lock("/etc/objrepos/config_lock", ODM_WAIT)) == -1) { - if (odm_err_msg(odmerrno, &errstr) == -1) - errstr = "Unknown error"; - snprintf(errbuf, PCAP_ERRBUF_SIZE, - "bpf_load: odm_lock of /etc/objrepos/config_lock failed: %s", - errstr); - return (-1); - } - - return (0); -} - -static int -bpf_odmcleanup(char *errbuf) -{ - char *errstr; - - if (odm_unlock(odmlockid) == -1) { - if (odm_err_msg(odmerrno, &errstr) == -1) - errstr = "Unknown error"; - snprintf(errbuf, PCAP_ERRBUF_SIZE, - "bpf_load: odm_unlock failed: %s", - errstr); - return (-1); - } - - if (odm_terminate() == -1) { - if (odm_err_msg(odmerrno, &errstr) == -1) - errstr = "Unknown error"; - snprintf(errbuf, PCAP_ERRBUF_SIZE, - "bpf_load: odm_terminate failed: %s", - errstr); - return (-1); - } - - return (0); -} - -static int -bpf_load(char *errbuf) -{ - long major; - int *minors; - int numminors, i, rc; - char buf[1024]; - struct stat sbuf; - struct bpf_config cfg_bpf; - struct cfg_load cfg_ld; - struct cfg_kmod cfg_km; - - /* - * This is very very close to what happens in the real implementation - * but I've fixed some (unlikely) bug situations. - */ - if (bpfloadedflag) - return (0); - - if (bpf_odminit(errbuf) != 0) - return (-1); - - major = genmajor(BPF_NAME); - if (major == -1) { - snprintf(errbuf, PCAP_ERRBUF_SIZE, - "bpf_load: genmajor failed: %s", pcap_strerror(errno)); - return (-1); - } - - minors = getminor(major, &numminors, BPF_NAME); - if (!minors) { - minors = genminor("bpf", major, 0, BPF_MINORS, 1, 1); - if (!minors) { - snprintf(errbuf, PCAP_ERRBUF_SIZE, - "bpf_load: genminor failed: %s", - pcap_strerror(errno)); - return (-1); - } - } - - if (bpf_odmcleanup(errbuf)) - return (-1); - - rc = stat(BPF_NODE "0", &sbuf); - if (rc == -1 && errno != ENOENT) { - snprintf(errbuf, PCAP_ERRBUF_SIZE, - "bpf_load: can't stat %s: %s", - BPF_NODE "0", pcap_strerror(errno)); - return (-1); - } - - if (rc == -1 || getmajor(sbuf.st_rdev) != major) { - for (i = 0; i < BPF_MINORS; i++) { - sprintf(buf, "%s%d", BPF_NODE, i); - unlink(buf); - if (mknod(buf, S_IRUSR | S_IFCHR, domakedev(major, i)) == -1) { - snprintf(errbuf, PCAP_ERRBUF_SIZE, - "bpf_load: can't mknod %s: %s", - buf, pcap_strerror(errno)); - return (-1); - } - } - } - - /* Check if the driver is loaded */ - memset(&cfg_ld, 0x0, sizeof(cfg_ld)); - cfg_ld.path = buf; - sprintf(cfg_ld.path, "%s/%s", DRIVER_PATH, BPF_NAME); - if ((sysconfig(SYS_QUERYLOAD, (void *)&cfg_ld, sizeof(cfg_ld)) == -1) || - (cfg_ld.kmid == 0)) { - /* Driver isn't loaded, load it now */ - if (sysconfig(SYS_SINGLELOAD, (void *)&cfg_ld, sizeof(cfg_ld)) == -1) { - snprintf(errbuf, PCAP_ERRBUF_SIZE, - "bpf_load: could not load driver: %s", - strerror(errno)); - return (-1); - } - } - - /* Configure the driver */ - cfg_km.cmd = CFG_INIT; - cfg_km.kmid = cfg_ld.kmid; - cfg_km.mdilen = sizeof(cfg_bpf); - cfg_km.mdiptr = (void *)&cfg_bpf; - for (i = 0; i < BPF_MINORS; i++) { - cfg_bpf.devno = domakedev(major, i); - if (sysconfig(SYS_CFGKMOD, (void *)&cfg_km, sizeof(cfg_km)) == -1) { - snprintf(errbuf, PCAP_ERRBUF_SIZE, - "bpf_load: could not configure driver: %s", - strerror(errno)); - return (-1); - } - } - - bpfloadedflag = 1; - - return (0); -} -#endif - -static inline int -bpf_open(pcap_t *p, char *errbuf) -{ - int fd; - int n = 0; - char device[sizeof "/dev/bpf0000000000"]; - -#ifdef _AIX - /* - * Load the bpf driver, if it isn't already loaded, - * and create the BPF device entries, if they don't - * already exist. - */ - if (bpf_load(errbuf) == -1) - return (-1); -#endif - - /* - * Go through all the minors and find one that isn't in use. - */ - do { - (void)snprintf(device, sizeof(device), "/dev/bpf%d", n++); - fd = open(device, O_RDONLY); - } while (fd < 0 && errno == EBUSY); - - /* - * XXX better message for all minors used - */ - if (fd < 0) - snprintf(errbuf, PCAP_ERRBUF_SIZE, "(no devices found) %s: %s", - device, pcap_strerror(errno)); - - return (fd); -} - -static void -pcap_close_bpf(pcap_t *p) -{ - if (p->buffer != NULL) - free(p->buffer); - if (p->fd >= 0) - close(p->fd); -} - -/* - * XXX - on AIX, IBM's tcpdump (and perhaps the incompatible-with-everybody- - * else's libpcap in AIX 5.1) appears to forcibly load the BPF driver - * if it's not already loaded, and to create the BPF devices if they - * don't exist. - * - * It'd be nice if we could do the same, although the code to do so - * might be version-dependent, alas (the way to do it isn't necessarily - * documented). - */ -pcap_t * -pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, - char *ebuf) -{ - int fd; - struct ifreq ifr; - struct bpf_version bv; -#ifdef BIOCGDLTLIST - struct bpf_dltlist bdl; -#endif - u_int v; - pcap_t *p; - struct utsname osinfo; - -#ifdef HAVE_DAG_API - if (strstr(device, "dag")) { - return dag_open_live(device, snaplen, promisc, to_ms, ebuf); - } -#endif /* HAVE_DAG_API */ - -#ifdef BIOCGDLTLIST - memset(&bdl, 0, sizeof(bdl)); -#endif - - p = (pcap_t *)malloc(sizeof(*p)); - if (p == NULL) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", - pcap_strerror(errno)); - return (NULL); - } - memset(p, 0, sizeof(*p)); - fd = bpf_open(p, ebuf); - if (fd < 0) - goto bad; - - p->fd = fd; - p->snapshot = snaplen; - - if (ioctl(fd, BIOCVERSION, (caddr_t)&bv) < 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCVERSION: %s", - pcap_strerror(errno)); - goto bad; - } - if (bv.bv_major != BPF_MAJOR_VERSION || - bv.bv_minor < BPF_MINOR_VERSION) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, - "kernel bpf filter out of date"); - goto bad; - } - - /* - * Try finding a good size for the buffer; 32768 may be too - * big, so keep cutting it in half until we find a size - * that works, or run out of sizes to try. If the default - * is larger, don't make it smaller. - * - * XXX - there should be a user-accessible hook to set the - * initial buffer size. - */ - if ((ioctl(fd, BIOCGBLEN, (caddr_t)&v) < 0) || v < 32768) - v = 32768; - for ( ; v != 0; v >>= 1) { - /* Ignore the return value - this is because the call fails - * on BPF systems that don't have kernel malloc. And if - * the call fails, it's no big deal, we just continue to - * use the standard buffer size. - */ - (void) ioctl(fd, BIOCSBLEN, (caddr_t)&v); - - (void)strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); - if (ioctl(fd, BIOCSETIF, (caddr_t)&ifr) >= 0) - break; /* that size worked; we're done */ - - if (errno != ENOBUFS) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCSETIF: %s: %s", - device, pcap_strerror(errno)); - goto bad; - } - } - - if (v == 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, - "BIOCSBLEN: %s: No buffer size worked", device); - goto bad; - } - - /* Get the data link layer type. */ - if (ioctl(fd, BIOCGDLT, (caddr_t)&v) < 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCGDLT: %s", - pcap_strerror(errno)); - goto bad; - } -#ifdef _AIX - /* - * AIX's BPF returns IFF_ types, not DLT_ types, in BIOCGDLT. - */ - switch (v) { - - case IFT_ETHER: - case IFT_ISO88023: - v = DLT_EN10MB; - break; - - case IFT_FDDI: - v = DLT_FDDI; - break; - - case IFT_ISO88025: - v = DLT_IEEE802; - break; - - case IFT_LOOP: - v = DLT_NULL; - break; - - default: - /* - * We don't know what to map this to yet. - */ - snprintf(ebuf, PCAP_ERRBUF_SIZE, "unknown interface type %u", - v); - goto bad; - } -#endif -#if _BSDI_VERSION - 0 >= 199510 - /* The SLIP and PPP link layer header changed in BSD/OS 2.1 */ - switch (v) { - - case DLT_SLIP: - v = DLT_SLIP_BSDOS; - break; - - case DLT_PPP: - v = DLT_PPP_BSDOS; - break; - - case 11: /*DLT_FR*/ - v = DLT_FRELAY; - break; - - case 12: /*DLT_C_HDLC*/ - v = DLT_CHDLC; - break; - } -#endif - p->linktype = v; - -#ifdef BIOCGDLTLIST - /* - * We know the default link type -- now determine all the DLTs - * this interface supports. If this fails with EINVAL, it's - * not fatal; we just don't get to use the feature later. - */ - if (ioctl(fd, BIOCGDLTLIST, (caddr_t)&bdl) == 0) { - bdl.bfl_list = (u_int *) malloc(sizeof(u_int) * bdl.bfl_len); - if (bdl.bfl_list == NULL) { - (void)snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", - pcap_strerror(errno)); - goto bad; - } - - if (ioctl(fd, BIOCGDLTLIST, (caddr_t)&bdl) < 0) { - (void)snprintf(ebuf, PCAP_ERRBUF_SIZE, - "BIOCGDLTLIST: %s", pcap_strerror(errno)); - goto bad; - } - - p->dlt_count = bdl.bfl_len; - p->dlt_list = bdl.bfl_list; - } else { - if (errno != EINVAL) { - (void)snprintf(ebuf, PCAP_ERRBUF_SIZE, - "BIOCGDLTLIST: %s", pcap_strerror(errno)); - goto bad; - } - } -#endif - - /* set timeout */ - if (to_ms != 0) { - /* - * XXX - is this seconds/nanoseconds in AIX? - * (Treating it as such doesn't fix the timeout - * problem described below.) - */ - struct timeval to; - to.tv_sec = to_ms / 1000; - to.tv_usec = (to_ms * 1000) % 1000000; - if (ioctl(p->fd, BIOCSRTIMEOUT, (caddr_t)&to) < 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCSRTIMEOUT: %s", - pcap_strerror(errno)); - goto bad; - } - } - -#ifdef _AIX -#ifdef BIOCIMMEDIATE - /* - * Darren Reed notes that - * - * On AIX (4.2 at least), if BIOCIMMEDIATE is not set, the - * timeout appears to be ignored and it waits until the buffer - * is filled before returning. The result of not having it - * set is almost worse than useless if your BPF filter - * is reducing things to only a few packets (i.e. one every - * second or so). - * - * so we turn BIOCIMMEDIATE mode on if this is AIX. - * - * We don't turn it on for other platforms, as that means we - * get woken up for every packet, which may not be what we want; - * in the Winter 1993 USENIX paper on BPF, they say: - * - * Since a process might want to look at every packet on a - * network and the time between packets can be only a few - * microseconds, it is not possible to do a read system call - * per packet and BPF must collect the data from several - * packets and return it as a unit when the monitoring - * application does a read. - * - * which I infer is the reason for the timeout - it means we - * wait that amount of time, in the hopes that more packets - * will arrive and we'll get them all with one read. - * - * Setting BIOCIMMEDIATE mode on FreeBSD (and probably other - * BSDs) causes the timeout to be ignored. - * - * On the other hand, some platforms (e.g., Linux) don't support - * timeouts, they just hand stuff to you as soon as it arrives; - * if that doesn't cause a problem on those platforms, it may - * be OK to have BIOCIMMEDIATE mode on BSD as well. - * - * (Note, though, that applications may depend on the read - * completing, even if no packets have arrived, when the timeout - * expires, e.g. GUI applications that have to check for input - * while waiting for packets to arrive; a non-zero timeout - * prevents "select()" from working right on FreeBSD and - * possibly other BSDs, as the timer doesn't start until a - * "read()" is done, so the timer isn't in effect if the - * application is blocked on a "select()", and the "select()" - * doesn't get woken up for a BPF device until the buffer - * fills up.) - */ - v = 1; - if (ioctl(p->fd, BIOCIMMEDIATE, &v) < 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCIMMEDIATE: %s", - pcap_strerror(errno)); - goto bad; - } -#endif /* BIOCIMMEDIATE */ -#endif /* _AIX */ - - if (promisc) { - /* set promiscuous mode, okay if it fails */ - if (ioctl(p->fd, BIOCPROMISC, NULL) < 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCPROMISC: %s", - pcap_strerror(errno)); - } - } - - if (ioctl(fd, BIOCGBLEN, (caddr_t)&v) < 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCGBLEN: %s", - pcap_strerror(errno)); - goto bad; - } - p->bufsize = v; - p->buffer = (u_char *)malloc(p->bufsize); - if (p->buffer == NULL) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", - pcap_strerror(errno)); - goto bad; - } -#ifdef _AIX - /* For some strange reason this seems to prevent the EFAULT - * problems we have experienced from AIX BPF. */ - memset(p->buffer, 0x0, p->bufsize); -#endif - - /* - * On most BPF platforms, either you can do a "select()" or - * "poll()" on a BPF file descriptor and it works correctly, - * or you can do it and it will return "readable" if the - * hold buffer is full but not if the timeout expires *and* - * a non-blocking read will, if the hold buffer is empty - * but the store buffer isn't empty, rotate the buffers - * and return what packets are available. - * - * In the latter case, the fact that a non-blocking read - * will give you the available packets means you can work - * around the failure of "select()" and "poll()" to wake up - * and return "readable" when the timeout expires by using - * the timeout as the "select()" or "poll()" timeout, putting - * the BPF descriptor into non-blocking mode, and read from - * it regardless of whether "select()" reports it as readable - * or not. - * - * However, in FreeBSD 4.3 and 4.4, "select()" and "poll()" - * won't wake up and return "readable" if the timer expires - * and non-blocking reads return EWOULDBLOCK if the hold - * buffer is empty, even if the store buffer is non-empty. - * - * This means the workaround in question won't work. - * - * Therefore, on FreeBSD 4.3 and 4.4, we set "p->selectable_fd" - * to -1, which means "sorry, you can't use 'select()' or 'poll()' - * here". On all other BPF platforms, we set it to the FD for - * the BPF device; in NetBSD, OpenBSD, and Darwin, a non-blocking - * read will, if the hold buffer is empty and the store buffer - * isn't empty, rotate the buffers and return what packets are - * there (and in sufficiently recent versions of OpenBSD - * "select()" and "poll()" should work correctly). - * - * XXX - what about AIX? - */ - if (uname(&osinfo) == 0) { - /* - * We can check what OS this is. - */ - if (strcmp(osinfo.sysname, "FreeBSD") == 0 && - (strcmp(osinfo.release, "4.3") == 0 || - strcmp(osinfo.release, "4.4") == 0)) - p->selectable_fd = -1; - else - p->selectable_fd = p->fd; - } else { - /* - * We can't find out what OS this is, so assume we can - * do a "select()" or "poll()". - */ - p->selectable_fd = p->fd; - } - - p->read_op = pcap_read_bpf; - p->setfilter_op = pcap_setfilter_bpf; - p->set_datalink_op = pcap_set_datalink_bpf; - p->getnonblock_op = pcap_getnonblock_fd; - p->setnonblock_op = pcap_setnonblock_fd; - p->stats_op = pcap_stats_bpf; - p->close_op = pcap_close_bpf; - - return (p); - bad: - (void)close(fd); -#ifdef BIOCGDLTLIST - if (bdl.bfl_list != NULL) - free(bdl.bfl_list); -#endif - free(p); - return (NULL); -} - -int -pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf) -{ -#ifdef HAVE_DAG_API - if (dag_platform_finddevs(alldevsp, errbuf) < 0) - return (-1); -#endif /* HAVE_DAG_API */ - - return (0); -} - -static int -pcap_setfilter_bpf(pcap_t *p, struct bpf_program *fp) -{ - /* - * It looks that BPF code generated by gen_protochain() is not - * compatible with some of kernel BPF code (for example BSD/OS 3.1). - * Take a safer side for now. - */ - if (no_optimize) { - /* - * XXX - what if we already have a filter in the kernel? - */ - if (install_bpf_program(p, fp) < 0) - return (-1); - p->md.use_bpf = 0; /* filtering in userland */ - return (0); - } - - /* - * Free any user-mode filter we might happen to have installed. - */ - pcap_freecode(&p->fcode); - - /* - * Try to install the kernel filter. - */ - if (ioctl(p->fd, BIOCSETF, (caddr_t)fp) < 0) { - snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCSETF: %s", - pcap_strerror(errno)); - return (-1); - } - p->md.use_bpf = 1; /* filtering in the kernel */ - return (0); -} - -static int -pcap_set_datalink_bpf(pcap_t *p, int dlt) -{ -#ifdef BIOCSDLT - if (ioctl(p->fd, BIOCSDLT, &dlt) == -1) { - (void) snprintf(p->errbuf, sizeof(p->errbuf), - "Cannot set DLT %d: %s", dlt, strerror(errno)); - return (-1); - } -#endif - return (0); -} diff --git a/contrib/libpcap-0.8.3/pcap-bpf.h b/contrib/libpcap-0.8.3/pcap-bpf.h deleted file mode 100644 index 80d589df13..0000000000 --- a/contrib/libpcap-0.8.3/pcap-bpf.h +++ /dev/null @@ -1,596 +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/pcap-bpf.h,v 1.9.2.9 2004/03/28 21:45:32 fenner Exp $ (LBL) - */ - -/* - * This is libpcap's cut-down version of bpf.h; it includes only - * the stuff needed for the code generator and the userland BPF - * interpreter, and the libpcap APIs for setting filters, etc.. - * - * "pcap-bpf.c" will include the native OS version, as it deals with - * the OS's BPF implementation. - * - * XXX - should this all just be moved to "pcap.h"? - */ - -#ifndef BPF_MAJOR_VERSION - -#ifdef __cplusplus -extern "C" { -#endif - -/* 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. - */ -#ifndef __NetBSD__ -#define BPF_ALIGNMENT sizeof(bpf_int32) -#else -#define BPF_ALIGNMENT sizeof(long) -#endif -#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 "pcap_compile()", "pcap_setfilter()", etc.. - */ -struct bpf_program { - u_int bf_len; - struct bpf_insn *bf_insns; -}; - -/* - * 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 - -/* - * Data-link level type codes. - * - * Do *NOT* add new values to this list without asking - * "tcpdump-workers@tcpdump.org" for a value. Otherwise, you run the - * risk of using a value that's already being used for some other purpose, - * and of having tools that read libpcap-format captures not being able - * to handle captures with your new DLT_ value, with no hope that they - * will ever be changed to do so (as that would destroy their ability - * to read captures using that value for that other purpose). - */ - -/* - * These are the types that are the same on all platforms, and that - * have been defined by for ages. - */ -#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, with BSD-style header */ -#define DLT_SLIP 8 /* Serial Line IP */ -#define DLT_PPP 9 /* Point-to-point Protocol */ -#define DLT_FDDI 10 /* FDDI */ - -/* - * These are types that are different on some platforms, and that - * have been defined by for ages. We use #ifdefs to - * detect the BSDs that define them differently from the traditional - * libpcap - * - * XXX - DLT_ATM_RFC1483 is 13 in BSD/OS, and DLT_RAW is 14 in BSD/OS, - * but I don't know what the right #define is for BSD/OS. - */ -#define DLT_ATM_RFC1483 11 /* LLC/SNAP encapsulated atm */ - -#ifdef __OpenBSD__ -#define DLT_RAW 14 /* raw IP */ -#else -#define DLT_RAW 12 /* raw IP */ -#endif - -/* - * Given that the only OS that currently generates BSD/OS SLIP or PPP - * is, well, BSD/OS, arguably everybody should have chosen its values - * for DLT_SLIP_BSDOS and DLT_PPP_BSDOS, which are 15 and 16, but they - * didn't. So it goes. - */ -#if defined(__NetBSD__) || defined(__FreeBSD__) -#ifndef DLT_SLIP_BSDOS -#define DLT_SLIP_BSDOS 13 /* BSD/OS Serial Line IP */ -#define DLT_PPP_BSDOS 14 /* BSD/OS Point-to-point Protocol */ -#endif -#else -#define DLT_SLIP_BSDOS 15 /* BSD/OS Serial Line IP */ -#define DLT_PPP_BSDOS 16 /* BSD/OS Point-to-point Protocol */ -#endif - -/* - * 17 is used for DLT_OLD_PFLOG in OpenBSD; - * OBSOLETE: DLT_PFLOG is 117 in OpenBSD now as well. See below. - * 18 is used for DLT_PFSYNC in OpenBSD; don't use it for anything else. - */ - -#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 */ - -/* - * The Axent Raptor firewall - now the Symantec Enterprise Firewall - uses - * a link-layer type of 99 for the tcpdump it supplies. The link-layer - * header has 6 bytes of unknown data, something that appears to be an - * Ethernet type, and 36 bytes that appear to be 0 in at least one capture - * I've seen. - */ -#define DLT_SYMANTEC_FIREWALL 99 - -/* - * 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 */ - -/* - * 106 is reserved for Linux Classical IP over ATM; it's like DLT_RAW, - * except when it isn't. (I.e., sometimes it's just raw IP, and - * sometimes it isn't.) We currently handle it as DLT_LINUX_SLL, - * so that we don't have to worry about the link-layer header.) - */ - -/* - * Frame Relay; BSD/OS has a DLT_FR with a value of 11, but that collides - * with other values. - * DLT_FR and DLT_FRELAY packets start with the Q.922 Frame Relay header - * (DLCI, etc.). - */ -#define DLT_FRELAY 107 - -/* - * 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 - -/* - * Encapsulated packets for IPsec; DLT_ENC is 13 in OpenBSD, but that's - * DLT_SLIP_BSDOS in NetBSD, so we don't use 13 for it in OSes other - * than OpenBSD. - */ -#ifdef __OpenBSD__ -#define DLT_ENC 13 -#else -#define DLT_ENC 109 -#endif - -/* - * Values between 110 and 112 are reserved for use 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 - -/* - * 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. - * - * XXX: is there a conflict with DLT_PFSYNC 18 as well? - */ -#ifdef __OpenBSD__ -#define DLT_OLD_PFLOG 17 -#define DLT_PFSYNC 18 -#endif -#define DLT_PFLOG 117 - -/* - * Registered for Cisco-internal use. - */ -#define DLT_CISCO_IOS 118 - -/* - * 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 - -/* - * Reserved for Siemens HiPath HDLC. - */ -#define DLT_HHDLC 121 - -/* - * This is for RFC 2625 IP-over-Fibre Channel. - * - * This is not for use with raw Fibre Channel, where the link-layer - * header starts with a Fibre Channel frame header; it's for IP-over-FC, - * where the link-layer header starts with an RFC 2625 Network_Header - * field. - */ -#define DLT_IP_OVER_FC 122 - -/* - * This is for Full Frontal ATM on Solaris with SunATM, with a - * pseudo-header followed by an AALn PDU. - * - * There may be other forms of Full Frontal ATM on other OSes, - * with different pseudo-headers. - * - * If ATM software returns a pseudo-header with VPI/VCI information - * (and, ideally, packet type information, e.g. signalling, ILMI, - * LANE, LLC-multiplexed traffic, etc.), it should not use - * DLT_ATM_RFC1483, but should get a new DLT_ value, so tcpdump - * and the like don't have to infer the presence or absence of a - * pseudo-header and the form of the pseudo-header. - */ -#define DLT_SUNATM 123 /* Solaris+SunATM */ - -/* - * Reserved as per request from Kent Dahlgren - * for private use. - */ -#define DLT_RIO 124 /* RapidIO */ -#define DLT_PCI_EXP 125 /* PCI Express */ -#define DLT_AURORA 126 /* Xilinx Aurora link layer */ - -/* - * BSD header for 802.11 plus a number of bits of link-layer information - * including radio information. - */ -#define DLT_IEEE802_11_RADIO 127 /* 802.11 plus BSD radio header */ - -/* - * Reserved for the TZSP encapsulation, as per request from - * Chris Waters - * TZSP is a generic encapsulation for any other link type, - * which includes a means to include meta-information - * with the packet, e.g. signal strength and channel - * for 802.11 packets. - */ -#define DLT_TZSP 128 /* Tazmen Sniffer Protocol */ - -/* - * BSD's ARCNET headers have the source host, destination host, - * and type at the beginning of the packet; that's what's handed - * up to userland via BPF. - * - * Linux's ARCNET headers, however, have a 2-byte offset field - * between the host IDs and the type; that's what's handed up - * to userland via PF_PACKET sockets. - * - * We therefore have to have separate DLT_ values for them. - */ -#define DLT_ARCNET_LINUX 129 /* ARCNET */ - -/* - * Juniper-private data link types, as per request from - * Hannes Gredler . The DLT_s are used - * for passing on chassis-internal metainformation such as - * QOS profiles, etc.. - */ -#define DLT_JUNIPER_MLPPP 130 -#define DLT_JUNIPER_MLFR 131 -#define DLT_JUNIPER_ES 132 -#define DLT_JUNIPER_GGSN 133 -#define DLT_JUNIPER_MFR 134 -#define DLT_JUNIPER_ATM2 135 -#define DLT_JUNIPER_SERVICES 136 -#define DLT_JUNIPER_ATM1 137 - -/* - * Apple IP-over-IEEE 1394, as per a request from Dieter Siegmund - * . The header that's presented is an Ethernet-like - * header: - * - * #define FIREWIRE_EUI64_LEN 8 - * struct firewire_header { - * u_char firewire_dhost[FIREWIRE_EUI64_LEN]; - * u_char firewire_shost[FIREWIRE_EUI64_LEN]; - * u_short firewire_type; - * }; - * - * with "firewire_type" being an Ethernet type value, rather than, - * for example, raw GASP frames being handed up. - */ -#define DLT_APPLE_IP_OVER_IEEE1394 138 - -/* - * 139 through 142 are reserved for SS7. - */ - -/* - * Reserved for DOCSIS MAC frames. - */ -#define DLT_DOCSIS 143 - -/* - * Linux-IrDA packets. Protocol defined at http://www.irda.org. - * Those packets include IrLAP headers and above (IrLMP...), but - * don't include Phy framing (SOF/EOF/CRC & byte stuffing), because Phy - * framing can be handled by the hardware and depend on the bitrate. - * This is exactly the format you would get capturing on a Linux-IrDA - * interface (irdaX), but not on a raw serial port. - * Note the capture is done in "Linux-cooked" mode, so each packet include - * a fake packet header (struct sll_header). This is because IrDA packet - * decoding is dependant on the direction of the packet (incomming or - * outgoing). - * When/if other platform implement IrDA capture, we may revisit the - * issue and define a real DLT_IRDA... - * Jean II - */ -#define DLT_LINUX_IRDA 144 - -/* - * Reserved for IBM SP switch and IBM Next Federation switch. - */ -#define DLT_IBM_SP 145 -#define DLT_IBM_SN 146 - -/* - * Reserved for private use. If you have some link-layer header type - * that you want to use within your organization, with the capture files - * using that link-layer header type not ever be sent outside your - * organization, you can use these values. - * - * No libpcap release will use these for any purpose, nor will any - * tcpdump release use them, either. - * - * Do *NOT* use these in capture files that you expect anybody not using - * your private versions of capture-file-reading tools to read; in - * particular, do *NOT* use them in products, otherwise you may find that - * people won't be able to use tcpdump, or snort, or Ethereal, or... to - * read capture files from your firewall/intrusion detection/traffic - * monitoring/etc. appliance, or whatever product uses that DLT_ value, - * and you may also find that the developers of those applications will - * not accept patches to let them read those files. - * - * Also, do not use them if somebody might send you a capture using them - * for *their* private type and tools using them for *your* private type - * would have to read them. - * - * Instead, ask "tcpdump-workers@tcpdump.org" for a new DLT_ value, - * as per the comment above, and use the type you're given. - */ -#define DLT_USER0 147 -#define DLT_USER1 148 -#define DLT_USER2 149 -#define DLT_USER3 150 -#define DLT_USER4 151 -#define DLT_USER5 152 -#define DLT_USER6 153 -#define DLT_USER7 154 -#define DLT_USER8 155 -#define DLT_USER9 156 -#define DLT_USER10 157 -#define DLT_USER11 158 -#define DLT_USER12 159 -#define DLT_USER13 160 -#define DLT_USER14 161 -#define DLT_USER15 162 - -/* - * For future use with 802.11 captures - defined by AbsoluteValue - * Systems to store a number of bits of link-layer information - * including radio information: - * - * http://www.shaftnet.org/~pizza/software/capturefrm.txt - * - * but could and arguably should also be used by non-AVS Linux - * 802.11 drivers; that may happen in the future. - */ -#define DLT_IEEE802_11_RADIO_AVS 163 /* 802.11 plus AVS radio header */ - -/* - * Juniper-private data link type, as per request from - * Hannes Gredler . The DLT_s are used - * for passing on chassis-internal metainformation such as - * QOS profiles, etc.. - */ -#define DLT_JUNIPER_MONITOR 164 - -/* - * 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 __STDC__ || defined(__cplusplus) -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 - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/contrib/libpcap-0.8.3/pcap-dag.c b/contrib/libpcap-0.8.3/pcap-dag.c deleted file mode 100644 index 67ffaa7a35..0000000000 --- a/contrib/libpcap-0.8.3/pcap-dag.c +++ /dev/null @@ -1,710 +0,0 @@ -/* - * pcap-dag.c: Packet capture interface for Endace DAG card. - * - * The functionality of this code attempts to mimic that of pcap-linux as much - * as possible. This code is compiled in several different ways depending on - * whether DAG_ONLY and HAVE_DAG_API are defined. If HAVE_DAG_API is not - * defined it should not get compiled in, otherwise if DAG_ONLY is defined then - * the 'dag_' function calls are renamed to 'pcap_' equivalents. If DAG_ONLY - * is not defined then nothing is altered - the dag_ functions will be - * called as required from their pcap-linux/bpf equivalents. - * - * Author: Richard Littin, Sean Irvine ({richard,sean}@reeltwo.com) - * - * Modifications: - * 2003 May - Jesper Peterson - * Code shuffled around to suit fad-xxx.c structure - * Added atexit() handler to stop DAG if application is too lazy - * 2003 September - Koryn Grant - * Added support for nonblocking operation. - * Added support for processing more than a single packet in pcap_dispatch(). - * Fixed bug in loss counter code. - * Improved portability of loss counter code (e.g. use UINT_MAX instead of 0xffff). - * Removed unused local variables. - * Added required headers (ctype.h, limits.h, unistd.h, netinet/in.h). - * 2003 October - Koryn Grant - * Changed semantics to match those of standard pcap on linux. - * - packets rejected by the filter are not counted. - */ - -#ifndef lint -static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/libpcap/pcap-dag.c,v 1.10.2.4 2003/11/21 10:20:45 guy Exp $ (LBL)"; -#endif - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include /* optionally get BSD define */ - -#include -#include -#include - -#include "pcap-int.h" - -#include -#include -#include -#include -#include -#include - -struct mbuf; /* Squelch compiler warnings on some platforms for */ -struct rtentry; /* declarations in */ -#include - -#include -#include - -#define MIN_DAG_SNAPLEN 12 -#define MAX_DAG_SNAPLEN 2040 -#define ATM_SNAPLEN 48 - -typedef struct pcap_dag_node { - struct pcap_dag_node *next; - pcap_t *p; - pid_t pid; -} pcap_dag_node_t; - -static pcap_dag_node_t *pcap_dags = NULL; -static int atexit_handler_installed = 0; -static const unsigned short endian_test_word = 0x0100; - -#define IS_BIGENDIAN() (*((unsigned char *)&endian_test_word)) - -/* - * Swap byte ordering of unsigned long long timestamp on a big endian - * machine. - */ -#define SWAP_TS(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) - - -#ifdef DAG_ONLY -/* This code is required when compiling for a DAG device only. */ -#include "pcap-dag.h" - -/* Replace dag function names with pcap equivalent. */ -#define dag_open_live pcap_open_live -#define dag_platform_finddevs pcap_platform_finddevs -#endif /* DAG_ONLY */ - -static int dag_setfilter(pcap_t *p, struct bpf_program *fp); -static int dag_stats(pcap_t *p, struct pcap_stat *ps); -static int dag_set_datalink(pcap_t *p, int dlt); -static int dag_get_datalink(pcap_t *p); -static int dag_setnonblock(pcap_t *p, int nonblock, char *errbuf); - -static void delete_pcap_dag(pcap_t *p) { - pcap_dag_node_t *curr = NULL, *prev = NULL; - - for (prev = NULL, curr = pcap_dags; - curr != NULL && curr->p != p; - prev = curr, curr = curr->next) { - /* empty */ - } - - if (curr != NULL && curr->p == p) { - if (prev != NULL) { - prev->next = curr->next; - } else { - pcap_dags = curr->next; - } - } -} - -/* - * Performs a graceful shutdown of the DAG card, frees dynamic memory held - * in the pcap_t structure, and closes the file descriptor for the DAG card. - */ - -static void dag_platform_close(pcap_t *p) { - -#ifdef linux - if (p != NULL && p->md.device != NULL) { - if(dag_stop(p->fd) < 0) - fprintf(stderr,"dag_stop %s: %s\n", p->md.device, strerror(errno)); - if(dag_close(p->fd) < 0) - fprintf(stderr,"dag_close %s: %s\n", p->md.device, strerror(errno)); - - free(p->md.device); - } -#else - if (p != NULL) { - if(dag_stop(p->fd) < 0) - fprintf(stderr,"dag_stop: %s\n", strerror(errno)); - if(dag_close(p->fd) < 0) - fprintf(stderr,"dag_close: %s\n", strerror(errno)); - } -#endif - delete_pcap_dag(p); - /* Note: don't need to call close(p->fd) here as dag_close(p->fd) does this. */ -} - -static void atexit_handler(void) { - while (pcap_dags != NULL) { - if (pcap_dags->pid == getpid()) { - dag_platform_close(pcap_dags->p); - } else { - delete_pcap_dag(pcap_dags->p); - } - } -} - -static int new_pcap_dag(pcap_t *p) { - pcap_dag_node_t *node = NULL; - - if ((node = malloc(sizeof(pcap_dag_node_t))) == NULL) { - return -1; - } - - if (!atexit_handler_installed) { - atexit(atexit_handler); - atexit_handler_installed = 1; - } - - node->next = pcap_dags; - node->p = p; - node->pid = getpid(); - - pcap_dags = node; - - return 0; -} - -/* - * Read at most max_packets from the capture stream and call the callback - * for each of them. Returns the number of packets handled, -1 if an - * error occured, or -2 if we were told to break out of the loop. - */ -static int dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) { - unsigned int processed = 0; - int flags = p->md.dag_offset_flags; - unsigned int nonblocking = flags & DAGF_NONBLOCK; - - for (;;) - { - /* Get the next bufferful of packets (if necessary). */ - while (p->md.dag_mem_top - p->md.dag_mem_bottom < dag_record_size) { - - /* - * Has "pcap_breakloop()" been called? - */ - if (p->break_loop) { - /* - * Yes - clear the flag that indicates that - * it has, and return -2 to indicate that - * we were told to break out of the loop. - */ - p->break_loop = 0; - return -2; - } - - p->md.dag_mem_top = dag_offset(p->fd, &(p->md.dag_mem_bottom), flags); - if ((p->md.dag_mem_top - p->md.dag_mem_bottom < dag_record_size) && nonblocking) - { - /* Pcap is configured to process only available packets, and there aren't any. */ - return 0; - } - } - - /* Process the packets. */ - while (p->md.dag_mem_top - p->md.dag_mem_bottom >= dag_record_size) { - - unsigned short packet_len = 0; - int caplen = 0; - struct pcap_pkthdr pcap_header; - - dag_record_t *header = (dag_record_t *)(p->md.dag_mem_base + p->md.dag_mem_bottom); - u_char *dp = ((u_char *)header) + dag_record_size; - unsigned short rlen; - - /* - * Has "pcap_breakloop()" been called? - */ - if (p->break_loop) { - /* - * Yes - clear the flag that indicates that - * it has, and return -2 to indicate that - * we were told to break out of the loop. - */ - p->break_loop = 0; - return -2; - } - - if (IS_BIGENDIAN()) - { - rlen = header->rlen; - } - else - { - rlen = ntohs(header->rlen); - } - p->md.dag_mem_bottom += rlen; - - switch(header->type) { - case TYPE_ATM: - packet_len = ATM_SNAPLEN; - caplen = ATM_SNAPLEN; - dp += 4; - break; - - case TYPE_ETH: - if (IS_BIGENDIAN()) - { - packet_len = header->wlen; - } - else - { - packet_len = ntohs(header->wlen); - } - packet_len -= (p->md.dag_fcs_bits >> 3); - caplen = rlen - dag_record_size - 2; - if (caplen > packet_len) - { - caplen = packet_len; - } - dp += 2; - break; - - case TYPE_HDLC_POS: - if (IS_BIGENDIAN()) - { - packet_len = header->wlen; - } - else - { - packet_len = ntohs(header->wlen); - } - packet_len -= (p->md.dag_fcs_bits >> 3); - caplen = rlen - dag_record_size; - if (caplen > packet_len) - { - caplen = packet_len; - } - break; - } - - if (caplen > p->snapshot) - caplen = p->snapshot; - - /* Count lost packets. */ - if (header->lctr) { - if (p->md.stat.ps_drop > (UINT_MAX - header->lctr)) { - p->md.stat.ps_drop = UINT_MAX; - } else { - p->md.stat.ps_drop += header->lctr; - } - } - - /* Run the packet filter if there is one. */ - if ((p->fcode.bf_insns == NULL) || bpf_filter(p->fcode.bf_insns, dp, packet_len, caplen)) { - - /* convert between timestamp formats */ - register unsigned long long ts; - - if (IS_BIGENDIAN()) - { - ts = SWAP_TS(header->ts); - } - else - { - ts = header->ts; - } - - pcap_header.ts.tv_sec = ts >> 32; - ts = (ts & 0xffffffffULL) * 1000000; - ts += 0x80000000; /* rounding */ - pcap_header.ts.tv_usec = ts >> 32; - if (pcap_header.ts.tv_usec >= 1000000) { - pcap_header.ts.tv_usec -= 1000000; - pcap_header.ts.tv_sec++; - } - - /* Fill in our own header data */ - pcap_header.caplen = caplen; - pcap_header.len = packet_len; - - /* Count the packet. */ - p->md.stat.ps_recv++; - - /* Call the user supplied callback function */ - callback(user, &pcap_header, dp); - - /* Only count packets that pass the filter, for consistency with standard Linux behaviour. */ - processed++; - if (processed == cnt) - { - /* Reached the user-specified limit. */ - return cnt; - } - } - } - - if (nonblocking || processed) - { - return processed; - } - } - - return processed; -} - -/* - * Get a handle for a live capture from the given DAG device. Passing a NULL - * device will result in a failure. The promisc flag is ignored because DAG - * cards are always promiscuous. The to_ms parameter is also ignored as it is - * not supported in hardware. - * - * See also pcap(3). - */ -pcap_t *dag_open_live(const char *device, int snaplen, int promisc, int to_ms, char *ebuf) { - char conf[30]; /* dag configure string */ - pcap_t *handle; - char *s; - int n; - - if (device == NULL) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "device is NULL: %s", pcap_strerror(errno)); - return NULL; - } - /* Allocate a handle for this session. */ - - handle = malloc(sizeof(*handle)); - if (handle == NULL) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc %s: %s", device, pcap_strerror(errno)); - return NULL; - } - - /* Initialize some components of the pcap structure. */ - - memset(handle, 0, sizeof(*handle)); - - if (strstr(device, "/dev") == NULL) { - char * newDev = (char *)malloc(strlen(device) + 6); - newDev[0] = '\0'; - strcat(newDev, "/dev/"); - strcat(newDev,device); - device = newDev; - } else { - device = strdup(device); - } - - if (device == NULL) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "str_dup: %s\n", pcap_strerror(errno)); - goto fail; - } - - /* setup device parameters */ - if((handle->fd = dag_open((char *)device)) < 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "dag_open %s: %s", device, pcap_strerror(errno)); - goto fail; - } - - /* set the card snap length to the specified snaplen parameter */ - if (snaplen == 0 || snaplen > MAX_DAG_SNAPLEN) { - snaplen = MAX_DAG_SNAPLEN; - } else if (snaplen < MIN_DAG_SNAPLEN) { - snaplen = MIN_DAG_SNAPLEN; - } - /* snap len has to be a multiple of 4 */ - snprintf(conf, 30, "varlen slen=%d", (snaplen + 3) & ~3); - - fprintf(stderr, "Configuring DAG with '%s'.\n", conf); - if(dag_configure(handle->fd, conf) < 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE,"dag_configure %s: %s\n", device, pcap_strerror(errno)); - goto fail; - } - - if((handle->md.dag_mem_base = dag_mmap(handle->fd)) == MAP_FAILED) { - snprintf(ebuf, PCAP_ERRBUF_SIZE,"dag_mmap %s: %s\n", device, pcap_strerror(errno)); - goto fail; - } - - if(dag_start(handle->fd) < 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "dag_start %s: %s\n", device, pcap_strerror(errno)); - goto fail; - } - - /* - * Important! You have to ensure bottom is properly - * initialized to zero on startup, it won't give you - * a compiler warning if you make this mistake! - */ - handle->md.dag_mem_bottom = 0; - handle->md.dag_mem_top = 0; - - /* TODO: query the card */ - handle->md.dag_fcs_bits = 32; - if ((s = getenv("ERF_FCS_BITS")) != NULL) { - if ((n = atoi(s)) == 0 || n == 16|| n == 32) { - handle->md.dag_fcs_bits = n; - } else { - snprintf(ebuf, PCAP_ERRBUF_SIZE, - "pcap_open_live %s: bad ERF_FCS_BITS value (%d) in environment\n", device, n); - goto fail; - } - } - - handle->snapshot = snaplen; - /*handle->md.timeout = to_ms; */ - - if ((handle->linktype = dag_get_datalink(handle)) < 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "dag_get_linktype %s: unknown linktype\n", device); - goto fail; - } - - handle->bufsize = 0; - - if (new_pcap_dag(handle) < 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "new_pcap_dag %s: %s\n", device, pcap_strerror(errno)); - goto fail; - } - - /* - * "select()" and "poll()" don't (yet) work on DAG device descriptors. - */ - handle->selectable_fd = -1; - -#ifdef linux - handle->md.device = (char *)device; -#else - free((char *)device); - device = NULL; -#endif - - handle->read_op = dag_read; - handle->setfilter_op = dag_setfilter; - handle->set_datalink_op = dag_set_datalink; - handle->getnonblock_op = pcap_getnonblock_fd; - handle->setnonblock_op = dag_setnonblock; - handle->stats_op = dag_stats; - handle->close_op = dag_platform_close; - - return handle; - -fail: - if (device != NULL) { - free((char *)device); - } - if (handle != NULL) { - free(handle); - } - - return NULL; -} - -static int dag_stats(pcap_t *p, struct pcap_stat *ps) { - /* This needs to be filled out correctly. Hopefully a dagapi call will - provide all necessary information. - */ - /*p->md.stat.ps_recv = 0;*/ - /*p->md.stat.ps_drop = 0;*/ - - *ps = p->md.stat; - - return 0; -} - -/* - * Get from "/proc/dag" all interfaces listed there; if they're - * already in the list of interfaces we have, that won't add another - * instance, but if they're not, that'll add them. - * - * We don't bother getting any addresses for them. - * - * We also don't fail if we couldn't open "/proc/dag"; we just leave - * the list of interfaces as is. - */ -int -dag_platform_finddevs(pcap_if_t **devlistp, char *errbuf) -{ - FILE *proc_dag_f; - char linebuf[512]; - int linenum; - unsigned char *p; - char name[512]; /* XXX - pick a size */ - char *q; - int ret = 0; - - /* Quick exit if /proc/dag not readable */ - proc_dag_f = fopen("/proc/dag", "r"); - if (proc_dag_f == NULL) - { - int i; - char dev[16] = "dagx"; - - for (i = '0'; ret == 0 && i <= '9'; i++) { - dev[3] = i; - if (pcap_add_if(devlistp, dev, 0, NULL, errbuf) == -1) { - /* - * Failure. - */ - ret = -1; - } - } - - return (ret); - } - - for (linenum = 1; - fgets(linebuf, sizeof linebuf, proc_dag_f) != NULL; linenum++) { - - /* - * Skip the first two lines - they're headers. - */ - if (linenum <= 2) - continue; - - p = &linebuf[0]; - - if (*p == '\0' || *p == '\n' || *p != 'D') - continue; /* not a Dag line */ - - /* - * Get the interface name. - */ - q = &name[0]; - while (*p != '\0' && *p != ':') { - if (*p != ' ') - *q++ = tolower(*p++); - else - p++; - } - *q = '\0'; - - /* - * Add an entry for this interface, with no addresses. - */ - p[strlen(p) - 1] = '\0'; /* get rid of \n */ - if (pcap_add_if(devlistp, name, 0, strdup(p + 2), errbuf) == -1) { - /* - * Failure. - */ - ret = -1; - break; - } - } - if (ret != -1) { - /* - * Well, we didn't fail for any other reason; did we - * fail due to an error reading the file? - */ - if (ferror(proc_dag_f)) { - (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, - "Error reading /proc/dag: %s", - pcap_strerror(errno)); - ret = -1; - } - } - - (void)fclose(proc_dag_f); - return (ret); -} - -/* - * Installs the given bpf filter program in the given pcap structure. There is - * no attempt to store the filter in kernel memory as that is not supported - * with DAG cards. - */ -static int dag_setfilter(pcap_t *p, struct bpf_program *fp) { - if (!p) - return -1; - if (!fp) { - strncpy(p->errbuf, "setfilter: No filter specified", - sizeof(p->errbuf)); - return -1; - } - - /* Make our private copy of the filter */ - - if (install_bpf_program(p, fp) < 0) { - snprintf(p->errbuf, sizeof(p->errbuf), - "malloc: %s", pcap_strerror(errno)); - return -1; - } - - p->md.use_bpf = 0; - - return (0); -} - -static int -dag_set_datalink(pcap_t *p, int dlt) -{ - return (0); -} - -static int -dag_setnonblock(pcap_t *p, int nonblock, char *errbuf) -{ - /* - * Set non-blocking mode on the FD. - * XXX - is that necessary? If not, don't bother calling it, - * and have a "dag_getnonblock()" function that looks at - * "p->md.dag_offset_flags". - */ - if (pcap_setnonblock_fd(p, nonblock, errbuf) < 0) - return (-1); - - if (nonblock) { - p->md.dag_offset_flags |= DAGF_NONBLOCK; - } else { - p->md.dag_offset_flags &= ~DAGF_NONBLOCK; - } - return (0); -} - -static int -dag_get_datalink(pcap_t *p) -{ - int linktype = -1; - - /* Check the type through a dagapi call. - */ - switch(dag_linktype(p->fd)) { - case TYPE_HDLC_POS: { - dag_record_t *record; - - /* peek at the first available record to see if it is PPP */ - while ((p->md.dag_mem_top - p->md.dag_mem_bottom) < (dag_record_size + 4)) { - p->md.dag_mem_top = dag_offset(p->fd, &(p->md.dag_mem_bottom), 0); - } - record = (dag_record_t *)(p->md.dag_mem_base + p->md.dag_mem_bottom); - - if ((ntohl(record->rec.pos.hdlc) & 0xffff0000) == 0xff030000) { - linktype = DLT_PPP_SERIAL; - fprintf(stderr, "Set DAG linktype to %d (DLT_PPP_SERIAL)\n", linktype); - } else { - linktype = DLT_CHDLC; - fprintf(stderr, "Set DAG linktype to %d (DLT_CHDLC)\n", linktype); - } - break; - } - case TYPE_ETH: - linktype = DLT_EN10MB; - fprintf(stderr, "Set DAG linktype to %d (DLT_EN10MB)\n", linktype); - break; - case TYPE_ATM: - linktype = DLT_ATM_RFC1483; - fprintf(stderr, "Set DAG linktype to %d (DLT_ATM_RFC1483)\n", linktype); - break; - case TYPE_LEGACY: - linktype = DLT_NULL; - fprintf(stderr, "Set DAG linktype to %d (DLT_NULL)\n", linktype); - break; - default: - fprintf(stderr, "Unknown DAG linktype %d\n", dag_linktype(p->fd)); - break; - } - - return linktype; -} diff --git a/contrib/libpcap-0.8.3/pcap-dag.h b/contrib/libpcap-0.8.3/pcap-dag.h deleted file mode 100644 index 64e4f4643d..0000000000 --- a/contrib/libpcap-0.8.3/pcap-dag.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * pcap-dag.c: Packet capture interface for Endace DAG card. - * - * The functionality of this code attempts to mimic that of pcap-linux as much - * as possible. This code is only needed when compiling in the DAG card code - * at the same time as another type of device. - * - * Author: Richard Littin, Sean Irvine ({richard,sean}@reeltwo.com) - * - * @(#) $Header: /tcpdump/master/libpcap/pcap-dag.h,v 1.3 2003/07/25 05:32:03 guy Exp $ (LBL) - */ - -pcap_t *dag_open_live(const char *device, int snaplen, int promisc, int to_ms, char *ebuf); - diff --git a/contrib/libpcap-0.8.3/pcap-dlpi.c b/contrib/libpcap-0.8.3/pcap-dlpi.c deleted file mode 100644 index f8a917a7eb..0000000000 --- a/contrib/libpcap-0.8.3/pcap-dlpi.c +++ /dev/null @@ -1,1521 +0,0 @@ -/* - * Copyright (c) 1993, 1994, 1995, 1996, 1997 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that: (1) source code distributions - * retain the above copyright notice and this paragraph in its entirety, (2) - * distributions including binary code include the above copyright notice and - * this paragraph in its entirety in the documentation or other materials - * provided with the distribution, and (3) all advertising materials mentioning - * features or use of this software display the following acknowledgement: - * ``This product includes software developed by the University of California, - * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of - * the University nor the names of its contributors may be used to endorse - * or promote products derived from this software without specific prior - * written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * This code contributed by Atanu Ghosh (atanu@cs.ucl.ac.uk), - * University College London. - */ - -/* - * Packet capture routine for DLPI under SunOS 5, HP-UX 9/10/11, and AIX. - * - * Notes: - * - * - Apparently the DLIOCRAW ioctl() is specific to SunOS. - * - * - There is a bug in bufmod(7) such that setting the snapshot - * length results in data being left of the front of the packet. - * - * - It might be desirable to use pfmod(7) to filter packets in the - * kernel when possible. - */ - -#ifndef lint -static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/libpcap/pcap-dlpi.c,v 1.91.2.3 2003/11/21 10:20:46 guy Exp $ (LBL)"; -#endif - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#ifdef HAVE_SYS_BUFMOD_H -#include -#endif -#include -#ifdef HAVE_SYS_DLPI_EXT_H -#include -#endif -#ifdef HAVE_HPUX9 -#include -#endif -#ifdef DL_HP_PPA_ACK_OBS -#include -#endif -#include -#if defined(HAVE_SOLARIS) && defined(HAVE_SYS_BUFMOD_H) -#include -#endif - -#ifdef HAVE_HPUX9 -#include -#endif - -#include -#ifdef HAVE_HPUX9 -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include - -#include "pcap-int.h" - -#ifdef HAVE_OS_PROTO_H -#include "os-proto.h" -#endif - -#ifndef PCAP_DEV_PREFIX -#ifdef _AIX -#define PCAP_DEV_PREFIX "/dev/dlpi" -#else -#define PCAP_DEV_PREFIX "/dev" -#endif -#endif - -#define MAXDLBUF 8192 - -#ifdef HAVE_SYS_BUFMOD_H - -/* - * Size of a bufmod chunk to pass upstream; that appears to be the biggest - * value to which you can set it, and setting it to that value (which - * is bigger than what appears to be the Solaris default of 8192) - * reduces the number of packet drops. - */ -#define CHUNKSIZE 65536 - -/* - * Size of the buffer to allocate for packet data we read; it must be - * large enough to hold a chunk. - */ -#define PKTBUFSIZE CHUNKSIZE - -#else /* HAVE_SYS_BUFMOD_H */ - -/* - * Size of the buffer to allocate for packet data we read; this is - * what the value used to be - there's no particular reason why it - * should be tied to MAXDLBUF, but we'll leave it as this for now. - */ -#define PKTBUFSIZE (MAXDLBUF * sizeof(bpf_u_int32)) - -#endif - -/* Forwards */ -static char *split_dname(char *, int *, char *); -static int dlattachreq(int, bpf_u_int32, char *); -static int dlbindack(int, char *, char *); -static int dlbindreq(int, bpf_u_int32, char *); -static int dlinfoack(int, char *, char *); -static int dlinforeq(int, char *); -static int dlokack(int, const char *, char *, char *); -static int recv_ack(int, int, const char *, char *, char *); -static char *dlstrerror(bpf_u_int32); -static char *dlprim(bpf_u_int32); -static int dlpromisconreq(int, bpf_u_int32, char *); -#if defined(HAVE_SOLARIS) && defined(HAVE_SYS_BUFMOD_H) -static char *get_release(bpf_u_int32 *, bpf_u_int32 *, bpf_u_int32 *); -#endif -static int send_request(int, char *, int, char *, char *); -#ifdef HAVE_SYS_BUFMOD_H -static int strioctl(int, int, int, char *); -#endif -#ifdef HAVE_HPUX9 -static int dlpi_kread(int, off_t, void *, u_int, char *); -#endif -#ifdef HAVE_DEV_DLPI -static int get_dlpi_ppa(int, const char *, int, char *); -#endif - -static int -pcap_stats_dlpi(pcap_t *p, struct pcap_stat *ps) -{ - - /* - * "ps_recv" counts packets handed to the filter, not packets - * that passed the filter. As filtering is done in userland, - * this does not include packets dropped because we ran out - * of buffer space. - * - * "ps_drop" counts packets dropped inside the DLPI service - * provider device device because of flow control requirements - * or resource exhaustion; it doesn't count packets dropped by - * the interface driver, or packets dropped upstream. As - * filtering is done in userland, it counts packets regardless - * of whether they would've passed the filter. - * - * These statistics don't include packets not yet read from - * the kernel by libpcap, but they may include packets not - * yet read from libpcap by the application. - */ - *ps = p->md.stat; - return (0); -} - -/* XXX Needed by HP-UX (at least) */ -static bpf_u_int32 ctlbuf[MAXDLBUF]; -static struct strbuf ctl = { - MAXDLBUF, - 0, - (char *)ctlbuf -}; - -static int -pcap_read_dlpi(pcap_t *p, int cnt, pcap_handler callback, u_char *user) -{ - register int cc, n, caplen, origlen; - register u_char *bp, *ep, *pk; - register struct bpf_insn *fcode; -#ifdef HAVE_SYS_BUFMOD_H - register struct sb_hdr *sbp; -#ifdef LBL_ALIGN - struct sb_hdr sbhdr; -#endif -#endif - int flags; - struct strbuf data; - struct pcap_pkthdr pkthdr; - - flags = 0; - cc = p->cc; - if (cc == 0) { - data.buf = (char *)p->buffer + p->offset; - data.maxlen = p->bufsize; - data.len = 0; - do { - /* - * Has "pcap_breakloop()" been called? - */ - if (p->break_loop) { - /* - * Yes - clear the flag that indicates - * that it has, and return -2 to - * indicate that we were told to - * break out of the loop. - */ - p->break_loop = 0; - return (-2); - } - if (getmsg(p->fd, &ctl, &data, &flags) < 0) { - /* Don't choke when we get ptraced */ - if (errno == EINTR) { - cc = 0; - continue; - } - strlcpy(p->errbuf, pcap_strerror(errno), - sizeof(p->errbuf)); - return (-1); - } - cc = data.len; - } while (cc == 0); - bp = p->buffer + p->offset; - } else - bp = p->bp; - - /* Loop through packets */ - fcode = p->fcode.bf_insns; - ep = bp + cc; - n = 0; -#ifdef HAVE_SYS_BUFMOD_H - while (bp < ep) { - /* - * Has "pcap_breakloop()" been called? - * If so, return immediately - if we haven't read any - * packets, clear the flag and return -2 to indicate - * that we were told to break out of the loop, otherwise - * leave the flag set, so that the *next* call will break - * out of the loop without having read any packets, and - * return the number of packets we've processed so far. - */ - if (p->break_loop) { - if (n == 0) { - p->break_loop = 0; - return (-2); - } else { - p->bp = bp; - p->cc = ep - bp; - return (n); - } - } -#ifdef LBL_ALIGN - if ((long)bp & 3) { - sbp = &sbhdr; - memcpy(sbp, bp, sizeof(*sbp)); - } else -#endif - sbp = (struct sb_hdr *)bp; - p->md.stat.ps_drop = sbp->sbh_drops; - pk = bp + sizeof(*sbp); - bp += sbp->sbh_totlen; - origlen = sbp->sbh_origlen; - caplen = sbp->sbh_msglen; -#else - origlen = cc; - caplen = min(p->snapshot, cc); - pk = bp; - bp += caplen; -#endif - ++p->md.stat.ps_recv; - if (bpf_filter(fcode, pk, origlen, caplen)) { -#ifdef HAVE_SYS_BUFMOD_H - pkthdr.ts.tv_sec = sbp->sbh_timestamp.tv_sec; - pkthdr.ts.tv_usec = sbp->sbh_timestamp.tv_usec; -#else - (void)gettimeofday(&pkthdr.ts, NULL); -#endif - pkthdr.len = origlen; - pkthdr.caplen = caplen; - /* Insure caplen does not exceed snapshot */ - if (pkthdr.caplen > p->snapshot) - pkthdr.caplen = p->snapshot; - (*callback)(user, &pkthdr, pk); - if (++n >= cnt && cnt >= 0) { - p->cc = ep - bp; - p->bp = bp; - return (n); - } - } -#ifdef HAVE_SYS_BUFMOD_H - } -#endif - p->cc = 0; - return (n); -} - -#ifndef DL_IPATM -#define DL_IPATM 0x12 /* ATM Classical IP interface */ -#endif - -#ifdef HAVE_SOLARIS -/* - * For SunATM. - */ -#ifndef A_GET_UNITS -#define A_GET_UNITS (('A'<<8)|118) -#endif /* A_GET_UNITS */ -#ifndef A_PROMISCON_REQ -#define A_PROMISCON_REQ (('A'<<8)|121) -#endif /* A_PROMISCON_REQ */ -#endif /* HAVE_SOLARIS */ - -static void -pcap_close_dlpi(pcap_t *p) -{ - if (p->buffer != NULL) - free(p->buffer); - if (p->fd >= 0) - close(p->fd); -} - -pcap_t * -pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, - char *ebuf) -{ - register char *cp; - register pcap_t *p; - int ppa; -#ifdef HAVE_SOLARIS - int isatm = 0; -#endif - register dl_info_ack_t *infop; -#ifdef HAVE_SYS_BUFMOD_H - bpf_u_int32 ss, chunksize; -#ifdef HAVE_SOLARIS - register char *release; - bpf_u_int32 osmajor, osminor, osmicro; -#endif -#endif - bpf_u_int32 buf[MAXDLBUF]; - char dname[100]; -#ifndef HAVE_DEV_DLPI - char dname2[100]; -#endif - - p = (pcap_t *)malloc(sizeof(*p)); - if (p == NULL) { - strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE); - return (NULL); - } - memset(p, 0, sizeof(*p)); - p->fd = -1; /* indicate that it hasn't been opened yet */ - -#ifdef HAVE_DEV_DLPI - /* - ** Remove any "/dev/" on the front of the device. - */ - cp = strrchr(device, '/'); - if (cp == NULL) - strlcpy(dname, device, sizeof(dname)); - else - strlcpy(dname, cp + 1, sizeof(dname)); - - /* - * Split the device name into a device type name and a unit number; - * chop off the unit number, so "dname" is just a device type name. - */ - cp = split_dname(dname, &ppa, ebuf); - if (cp == NULL) - goto bad; - *cp = '\0'; - - /* - * Use "/dev/dlpi" as the device. - * - * XXX - HP's DLPI Programmer's Guide for HP-UX 11.00 says that - * the "dl_mjr_num" field is for the "major number of interface - * driver"; that's the major of "/dev/dlpi" on the system on - * which I tried this, but there may be DLPI devices that - * use a different driver, in which case we may need to - * search "/dev" for the appropriate device with that major - * device number, rather than hardwiring "/dev/dlpi". - */ - cp = "/dev/dlpi"; - if ((p->fd = open(cp, O_RDWR)) < 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, - "%s: %s", cp, pcap_strerror(errno)); - goto bad; - } - - /* - * Get a table of all PPAs for that device, and search that - * table for the specified device type name and unit number. - */ - ppa = get_dlpi_ppa(p->fd, dname, ppa, ebuf); - if (ppa < 0) - goto bad; -#else - /* - * If the device name begins with "/", assume it begins with - * the pathname of the directory containing the device to open; - * otherwise, concatenate the device directory name and the - * device name. - */ - if (*device == '/') - strlcpy(dname, device, sizeof(dname)); - else - snprintf(dname, sizeof(dname), "%s/%s", PCAP_DEV_PREFIX, - device); - - /* - * Get the unit number, and a pointer to the end of the device - * type name. - */ - cp = split_dname(dname, &ppa, ebuf); - if (cp == NULL) - goto bad; - - /* - * Make a copy of the device pathname, and then remove the unit - * number from the device pathname. - */ - strlcpy(dname2, dname, sizeof(dname)); - *cp = '\0'; - - /* Try device without unit number */ - if ((p->fd = open(dname, O_RDWR)) < 0) { - if (errno != ENOENT) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s: %s", dname, - pcap_strerror(errno)); - goto bad; - } - - /* Try again with unit number */ - if ((p->fd = open(dname2, O_RDWR)) < 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s: %s", dname2, - pcap_strerror(errno)); - goto bad; - } - /* XXX Assume unit zero */ - ppa = 0; - } -#endif - - p->snapshot = snaplen; - - /* - ** Attach if "style 2" provider - */ - if (dlinforeq(p->fd, ebuf) < 0 || - dlinfoack(p->fd, (char *)buf, ebuf) < 0) - goto bad; - infop = &((union DL_primitives *)buf)->info_ack; -#ifdef HAVE_SOLARIS - if (infop->dl_mac_type == DL_IPATM) - isatm = 1; -#endif - if (infop->dl_provider_style == DL_STYLE2 && - (dlattachreq(p->fd, ppa, ebuf) < 0 || - dlokack(p->fd, "attach", (char *)buf, ebuf) < 0)) - goto bad; - /* - ** Bind (defer if using HP-UX 9 or HP-UX 10.20, totally skip if - ** using SINIX) - */ -#if !defined(HAVE_HPUX9) && !defined(HAVE_HPUX10_20) && !defined(sinix) -#ifdef _AIX - /* According to IBM's AIX Support Line, the dl_sap value - ** should not be less than 0x600 (1536) for standard Ethernet. - ** However, we seem to get DL_BADADDR - "DLSAP addr in improper - ** format or invalid" - errors if we use 1537 on the "tr0" - ** device, which, given that its name starts with "tr" and that - ** it's IBM, probably means a Token Ring device. (Perhaps we - ** need to use 1537 on "/dev/dlpi/en" because that device is for - ** D/I/X Ethernet, the "SAP" is actually an Ethernet type, and - ** it rejects invalid Ethernet types.) - ** - ** So if 1537 fails, we try 2, as Hyung Sik Yoon of IBM Korea - ** says that works on Token Ring (he says that 0 does *not* - ** work; perhaps that's considered an invalid LLC SAP value - I - ** assume the SAP value in a DLPI bind is an LLC SAP for network - ** types that use 802.2 LLC). - */ - if ((dlbindreq(p->fd, 1537, ebuf) < 0 && - dlbindreq(p->fd, 2, ebuf) < 0) || -#else - if (dlbindreq(p->fd, 0, ebuf) < 0 || -#endif - dlbindack(p->fd, (char *)buf, ebuf) < 0) - goto bad; -#endif - -#ifdef HAVE_SOLARIS - if (isatm) { - /* - ** Have to turn on some special ATM promiscuous mode - ** for SunATM. - ** Do *NOT* turn regular promiscuous mode on; it doesn't - ** help, and may break things. - */ - if (strioctl(p->fd, A_PROMISCON_REQ, 0, NULL) < 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "A_PROMISCON_REQ: %s", - pcap_strerror(errno)); - goto bad; - } - } else -#endif - if (promisc) { - /* - ** Enable promiscuous - */ - if (dlpromisconreq(p->fd, DL_PROMISC_PHYS, ebuf) < 0 || - dlokack(p->fd, "promisc_phys", (char *)buf, ebuf) < 0) - goto bad; - - /* - ** Try to enable multicast (you would have thought - ** promiscuous would be sufficient). (Skip if using - ** HP-UX or SINIX) - */ -#if !defined(__hpux) && !defined(sinix) - if (dlpromisconreq(p->fd, DL_PROMISC_MULTI, ebuf) < 0 || - dlokack(p->fd, "promisc_multi", (char *)buf, ebuf) < 0) - fprintf(stderr, - "WARNING: DL_PROMISC_MULTI failed (%s)\n", ebuf); -#endif - } - /* - ** Try to enable sap (when not in promiscuous mode when using - ** using HP-UX, when not doing SunATM on Solaris, and never - ** under SINIX) - */ -#ifndef sinix - if ( -#ifdef __hpux - !promisc && -#endif -#ifdef HAVE_SOLARIS - !isatm && -#endif - (dlpromisconreq(p->fd, DL_PROMISC_SAP, ebuf) < 0 || - dlokack(p->fd, "promisc_sap", (char *)buf, ebuf) < 0)) { - /* Not fatal if promisc since the DL_PROMISC_PHYS worked */ - if (promisc) - fprintf(stderr, - "WARNING: DL_PROMISC_SAP failed (%s)\n", ebuf); - else - goto bad; - } -#endif - - /* - ** HP-UX 9 and HP-UX 10.20 must bind after setting promiscuous - ** options) - */ -#if defined(HAVE_HPUX9) || defined(HAVE_HPUX10_20) - if (dlbindreq(p->fd, 0, ebuf) < 0 || - dlbindack(p->fd, (char *)buf, ebuf) < 0) - goto bad; -#endif - - /* - ** Determine link type - */ - if (dlinforeq(p->fd, ebuf) < 0 || - dlinfoack(p->fd, (char *)buf, ebuf) < 0) - goto bad; - - infop = &((union DL_primitives *)buf)->info_ack; - switch (infop->dl_mac_type) { - - case DL_CSMACD: - case DL_ETHER: - p->linktype = DLT_EN10MB; - p->offset = 2; - break; - - case DL_FDDI: - p->linktype = DLT_FDDI; - p->offset = 3; - break; - - case DL_TPR: - p->linktype = DLT_IEEE802; - p->offset = 2; - break; - -#ifdef HAVE_SOLARIS - case DL_IPATM: - p->linktype = DLT_SUNATM; - p->offset = 0; /* works for LANE and LLC encapsulation */ - break; -#endif - - default: - snprintf(ebuf, PCAP_ERRBUF_SIZE, "unknown mac type %lu", - (unsigned long)infop->dl_mac_type); - goto bad; - } - -#ifdef DLIOCRAW - /* - ** This is a non standard SunOS hack to get the full raw link-layer - ** header. - */ - if (strioctl(p->fd, DLIOCRAW, 0, NULL) < 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "DLIOCRAW: %s", - pcap_strerror(errno)); - goto bad; - } -#endif - -#ifdef HAVE_SYS_BUFMOD_H - /* - ** Another non standard call to get the data nicely buffered - */ - if (ioctl(p->fd, I_PUSH, "bufmod") != 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "I_PUSH bufmod: %s", - pcap_strerror(errno)); - goto bad; - } - - /* - ** Now that the bufmod is pushed lets configure it. - ** - ** There is a bug in bufmod(7). When dealing with messages of - ** less than snaplen size it strips data from the beginning not - ** the end. - ** - ** This bug is supposed to be fixed in 5.3.2. Also, there is a - ** patch available. Ask for bugid 1149065. - */ - ss = snaplen; -#ifdef HAVE_SOLARIS - release = get_release(&osmajor, &osminor, &osmicro); - if (osmajor == 5 && (osminor <= 2 || (osminor == 3 && osmicro < 2)) && - getenv("BUFMOD_FIXED") == NULL) { - fprintf(stderr, - "WARNING: bufmod is broken in SunOS %s; ignoring snaplen.\n", - release); - ss = 0; - } -#endif - if (ss > 0 && - strioctl(p->fd, SBIOCSSNAP, sizeof(ss), (char *)&ss) != 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "SBIOCSSNAP: %s", - pcap_strerror(errno)); - goto bad; - } - - /* - ** Set up the bufmod timeout - */ - if (to_ms != 0) { - struct timeval to; - - to.tv_sec = to_ms / 1000; - to.tv_usec = (to_ms * 1000) % 1000000; - if (strioctl(p->fd, SBIOCSTIME, sizeof(to), (char *)&to) != 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "SBIOCSTIME: %s", - pcap_strerror(errno)); - goto bad; - } - } - - /* - ** Set the chunk length. - */ - chunksize = CHUNKSIZE; - if (strioctl(p->fd, SBIOCSCHUNK, sizeof(chunksize), (char *)&chunksize) - != 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "SBIOCSCHUNKP: %s", - pcap_strerror(errno)); - goto bad; - } -#endif - - /* - ** As the last operation flush the read side. - */ - if (ioctl(p->fd, I_FLUSH, FLUSHR) != 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "FLUSHR: %s", - pcap_strerror(errno)); - goto bad; - } - - /* Allocate data buffer */ - p->bufsize = PKTBUFSIZE; - p->buffer = (u_char *)malloc(p->bufsize + p->offset); - if (p->buffer == NULL) { - strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE); - goto bad; - } - - /* - * "p->fd" is an FD for a STREAMS device, so "select()" and - * "poll()" should work on it. - */ - p->selectable_fd = p->fd; - - p->read_op = pcap_read_dlpi; - p->setfilter_op = install_bpf_program; /* no kernel filtering */ - p->set_datalink_op = NULL; /* can't change data link type */ - p->getnonblock_op = pcap_getnonblock_fd; - p->setnonblock_op = pcap_setnonblock_fd; - p->stats_op = pcap_stats_dlpi; - p->close_op = pcap_close_dlpi; - - return (p); -bad: - if (p->fd >= 0) - close(p->fd); - free(p); - return (NULL); -} - -/* - * Split a device name into a device type name and a unit number; - * return the a pointer to the beginning of the unit number, which - * is the end of the device type name, and set "*unitp" to the unit - * number. - * - * Returns NULL on error, and fills "ebuf" with an error message. - */ -static char * -split_dname(char *device, int *unitp, char *ebuf) -{ - char *cp; - char *eos; - int unit; - - /* - * Look for a number at the end of the device name string. - */ - cp = device + strlen(device) - 1; - if (*cp < '0' || *cp > '9') { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s missing unit number", - device); - return (NULL); - } - - /* Digits at end of string are unit number */ - while (cp-1 >= device && *(cp-1) >= '0' && *(cp-1) <= '9') - cp--; - - unit = strtol(cp, &eos, 10); - if (*eos != '\0') { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s bad unit number", device); - return (NULL); - } - *unitp = unit; - return (cp); -} - -int -pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf) -{ -#ifdef HAVE_SOLARIS - int fd; - union { - u_int nunits; - char pad[516]; /* XXX - must be at least 513; is 516 - in "atmgetunits" */ - } buf; - char baname[2+1+1]; - u_int i; - - /* - * We may have to do special magic to get ATM devices. - */ - if ((fd = open("/dev/ba", O_RDWR)) < 0) { - /* - * We couldn't open the "ba" device. - * For now, just give up; perhaps we should - * return an error if the problem is neither - * a "that device doesn't exist" error (ENOENT, - * ENXIO, etc.) or a "you're not allowed to do - * that" error (EPERM, EACCES). - */ - return (0); - } - - if (strioctl(fd, A_GET_UNITS, sizeof(buf), (char *)&buf) < 0) { - snprintf(errbuf, PCAP_ERRBUF_SIZE, "A_GET_UNITS: %s", - pcap_strerror(errno)); - return (-1); - } - for (i = 0; i < buf.nunits; i++) { - snprintf(baname, sizeof baname, "ba%u", i); - if (pcap_add_if(alldevsp, baname, 0, NULL, errbuf) < 0) - return (-1); - } -#endif - - return (0); -} - -static int -send_request(int fd, char *ptr, int len, char *what, char *ebuf) -{ - struct strbuf ctl; - int flags; - - ctl.maxlen = 0; - ctl.len = len; - ctl.buf = ptr; - - flags = 0; - if (putmsg(fd, &ctl, (struct strbuf *) NULL, flags) < 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, - "send_request: putmsg \"%s\": %s", - what, pcap_strerror(errno)); - return (-1); - } - return (0); -} - -static int -recv_ack(int fd, int size, const char *what, char *bufp, char *ebuf) -{ - union DL_primitives *dlp; - struct strbuf ctl; - int flags; - - ctl.maxlen = MAXDLBUF; - ctl.len = 0; - ctl.buf = bufp; - - flags = 0; - if (getmsg(fd, &ctl, (struct strbuf*)NULL, &flags) < 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "recv_ack: %s getmsg: %s", - what, pcap_strerror(errno)); - return (-1); - } - - dlp = (union DL_primitives *) ctl.buf; - switch (dlp->dl_primitive) { - - case DL_INFO_ACK: - case DL_BIND_ACK: - case DL_OK_ACK: -#ifdef DL_HP_PPA_ACK - case DL_HP_PPA_ACK: -#endif - /* These are OK */ - break; - - case DL_ERROR_ACK: - switch (dlp->error_ack.dl_errno) { - - case DL_SYSERR: - snprintf(ebuf, PCAP_ERRBUF_SIZE, - "recv_ack: %s: UNIX error - %s", - what, pcap_strerror(dlp->error_ack.dl_unix_errno)); - break; - - default: - snprintf(ebuf, PCAP_ERRBUF_SIZE, "recv_ack: %s: %s", - what, dlstrerror(dlp->error_ack.dl_errno)); - break; - } - return (-1); - - default: - snprintf(ebuf, PCAP_ERRBUF_SIZE, - "recv_ack: %s: Unexpected primitive ack %s", - what, dlprim(dlp->dl_primitive)); - return (-1); - } - - if (ctl.len < size) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, - "recv_ack: %s: Ack too small (%d < %d)", - what, ctl.len, size); - return (-1); - } - return (ctl.len); -} - -static char * -dlstrerror(bpf_u_int32 dl_errno) -{ - static char errstring[6+2+8+1]; - - switch (dl_errno) { - - case DL_ACCESS: - return ("Improper permissions for request"); - - case DL_BADADDR: - return ("DLSAP addr in improper format or invalid"); - - case DL_BADCORR: - return ("Seq number not from outstand DL_CONN_IND"); - - case DL_BADDATA: - return ("User data exceeded provider limit"); - - case DL_BADPPA: -#ifdef HAVE_DEV_DLPI - /* - * With a single "/dev/dlpi" device used for all - * DLPI providers, PPAs have nothing to do with - * unit numbers. - */ - return ("Specified PPA was invalid"); -#else - /* - * We have separate devices for separate devices; - * the PPA is just the unit number. - */ - return ("Specified PPA (device unit) was invalid"); -#endif - - case DL_BADPRIM: - return ("Primitive received not known by provider"); - - case DL_BADQOSPARAM: - return ("QOS parameters contained invalid values"); - - case DL_BADQOSTYPE: - return ("QOS structure type is unknown/unsupported"); - - case DL_BADSAP: - return ("Bad LSAP selector"); - - case DL_BADTOKEN: - return ("Token used not an active stream"); - - case DL_BOUND: - return ("Attempted second bind with dl_max_conind"); - - case DL_INITFAILED: - return ("Physical link initialization failed"); - - case DL_NOADDR: - return ("Provider couldn't allocate alternate address"); - - case DL_NOTINIT: - return ("Physical link not initialized"); - - case DL_OUTSTATE: - return ("Primitive issued in improper state"); - - case DL_SYSERR: - return ("UNIX system error occurred"); - - case DL_UNSUPPORTED: - return ("Requested service not supplied by provider"); - - case DL_UNDELIVERABLE: - return ("Previous data unit could not be delivered"); - - case DL_NOTSUPPORTED: - return ("Primitive is known but not supported"); - - case DL_TOOMANY: - return ("Limit exceeded"); - - case DL_NOTENAB: - return ("Promiscuous mode not enabled"); - - case DL_BUSY: - return ("Other streams for PPA in post-attached"); - - case DL_NOAUTO: - return ("Automatic handling XID&TEST not supported"); - - case DL_NOXIDAUTO: - return ("Automatic handling of XID not supported"); - - case DL_NOTESTAUTO: - return ("Automatic handling of TEST not supported"); - - case DL_XIDAUTO: - return ("Automatic handling of XID response"); - - case DL_TESTAUTO: - return ("Automatic handling of TEST response"); - - case DL_PENDING: - return ("Pending outstanding connect indications"); - - default: - sprintf(errstring, "Error %02x", dl_errno); - return (errstring); - } -} - -static char * -dlprim(bpf_u_int32 prim) -{ - static char primbuf[80]; - - switch (prim) { - - case DL_INFO_REQ: - return ("DL_INFO_REQ"); - - case DL_INFO_ACK: - return ("DL_INFO_ACK"); - - case DL_ATTACH_REQ: - return ("DL_ATTACH_REQ"); - - case DL_DETACH_REQ: - return ("DL_DETACH_REQ"); - - case DL_BIND_REQ: - return ("DL_BIND_REQ"); - - case DL_BIND_ACK: - return ("DL_BIND_ACK"); - - case DL_UNBIND_REQ: - return ("DL_UNBIND_REQ"); - - case DL_OK_ACK: - return ("DL_OK_ACK"); - - case DL_ERROR_ACK: - return ("DL_ERROR_ACK"); - - case DL_SUBS_BIND_REQ: - return ("DL_SUBS_BIND_REQ"); - - case DL_SUBS_BIND_ACK: - return ("DL_SUBS_BIND_ACK"); - - case DL_UNITDATA_REQ: - return ("DL_UNITDATA_REQ"); - - case DL_UNITDATA_IND: - return ("DL_UNITDATA_IND"); - - case DL_UDERROR_IND: - return ("DL_UDERROR_IND"); - - case DL_UDQOS_REQ: - return ("DL_UDQOS_REQ"); - - case DL_CONNECT_REQ: - return ("DL_CONNECT_REQ"); - - case DL_CONNECT_IND: - return ("DL_CONNECT_IND"); - - case DL_CONNECT_RES: - return ("DL_CONNECT_RES"); - - case DL_CONNECT_CON: - return ("DL_CONNECT_CON"); - - case DL_TOKEN_REQ: - return ("DL_TOKEN_REQ"); - - case DL_TOKEN_ACK: - return ("DL_TOKEN_ACK"); - - case DL_DISCONNECT_REQ: - return ("DL_DISCONNECT_REQ"); - - case DL_DISCONNECT_IND: - return ("DL_DISCONNECT_IND"); - - case DL_RESET_REQ: - return ("DL_RESET_REQ"); - - case DL_RESET_IND: - return ("DL_RESET_IND"); - - case DL_RESET_RES: - return ("DL_RESET_RES"); - - case DL_RESET_CON: - return ("DL_RESET_CON"); - - default: - (void) sprintf(primbuf, "unknown primitive 0x%x", prim); - return (primbuf); - } -} - -static int -dlattachreq(int fd, bpf_u_int32 ppa, char *ebuf) -{ - dl_attach_req_t req; - - req.dl_primitive = DL_ATTACH_REQ; - req.dl_ppa = ppa; - - return (send_request(fd, (char *)&req, sizeof(req), "attach", ebuf)); -} - -static int -dlbindreq(int fd, bpf_u_int32 sap, char *ebuf) -{ - - dl_bind_req_t req; - - memset((char *)&req, 0, sizeof(req)); - req.dl_primitive = DL_BIND_REQ; -#ifdef DL_HP_RAWDLS - req.dl_max_conind = 1; /* XXX magic number */ - /* 22 is INSAP as per the HP-UX DLPI Programmer's Guide */ - req.dl_sap = 22; - req.dl_service_mode = DL_HP_RAWDLS; -#else - req.dl_sap = sap; -#ifdef DL_CLDLS - req.dl_service_mode = DL_CLDLS; -#endif -#endif - - return (send_request(fd, (char *)&req, sizeof(req), "bind", ebuf)); -} - -static int -dlbindack(int fd, char *bufp, char *ebuf) -{ - - return (recv_ack(fd, DL_BIND_ACK_SIZE, "bind", bufp, ebuf)); -} - -static int -dlpromisconreq(int fd, bpf_u_int32 level, char *ebuf) -{ - dl_promiscon_req_t req; - - req.dl_primitive = DL_PROMISCON_REQ; - req.dl_level = level; - - return (send_request(fd, (char *)&req, sizeof(req), "promiscon", ebuf)); -} - -static int -dlokack(int fd, const char *what, char *bufp, char *ebuf) -{ - - return (recv_ack(fd, DL_OK_ACK_SIZE, what, bufp, ebuf)); -} - - -static int -dlinforeq(int fd, char *ebuf) -{ - dl_info_req_t req; - - req.dl_primitive = DL_INFO_REQ; - - return (send_request(fd, (char *)&req, sizeof(req), "info", ebuf)); -} - -static int -dlinfoack(int fd, char *bufp, char *ebuf) -{ - - return (recv_ack(fd, DL_INFO_ACK_SIZE, "info", bufp, ebuf)); -} - -#ifdef HAVE_SYS_BUFMOD_H -static int -strioctl(int fd, int cmd, int len, char *dp) -{ - struct strioctl str; - int rc; - - str.ic_cmd = cmd; - str.ic_timout = -1; - str.ic_len = len; - str.ic_dp = dp; - rc = ioctl(fd, I_STR, &str); - - if (rc < 0) - return (rc); - else - return (str.ic_len); -} -#endif - -#if defined(HAVE_SOLARIS) && defined(HAVE_SYS_BUFMOD_H) -static char * -get_release(bpf_u_int32 *majorp, bpf_u_int32 *minorp, bpf_u_int32 *microp) -{ - char *cp; - static char buf[32]; - - *majorp = 0; - *minorp = 0; - *microp = 0; - if (sysinfo(SI_RELEASE, buf, sizeof(buf)) < 0) - return ("?"); - cp = buf; - if (!isdigit((unsigned char)*cp)) - return (buf); - *majorp = strtol(cp, &cp, 10); - if (*cp++ != '.') - return (buf); - *minorp = strtol(cp, &cp, 10); - if (*cp++ != '.') - return (buf); - *microp = strtol(cp, &cp, 10); - return (buf); -} -#endif - -#ifdef DL_HP_PPA_ACK_OBS -/* - * Under HP-UX 10 and HP-UX 11, we can ask for the ppa - */ - - -/* - * Determine ppa number that specifies ifname. - * - * If the "dl_hp_ppa_info_t" doesn't have a "dl_module_id_1" member, - * the code that's used here is the old code for HP-UX 10.x. - * - * However, HP-UX 10.20, at least, appears to have such a member - * in its "dl_hp_ppa_info_t" structure, so the new code is used. - * The new code didn't work on an old 10.20 system on which Rick - * Jones of HP tried it, but with later patches installed, it - * worked - it appears that the older system had those members but - * didn't put anything in them, so, if the search by name fails, we - * do the old search. - * - * Rick suggests that making sure your system is "up on the latest - * lancommon/DLPI/driver patches" is probably a good idea; it'd fix - * that problem, as well as allowing libpcap to see packets sent - * from the system on which the libpcap application is being run. - * (On 10.20, in addition to getting the latest patches, you need - * to turn the kernel "lanc_outbound_promisc_flag" flag on with ADB; - * a posting to "comp.sys.hp.hpux" at - * - * http://www.deja.com/[ST_rn=ps]/getdoc.xp?AN=558092266 - * - * says that, to see the machine's outgoing traffic, you'd need to - * apply the right patches to your system, and also set that variable - * with: - -echo 'lanc_outbound_promisc_flag/W1' | /usr/bin/adb -w /stand/vmunix /dev/kmem - - * which could be put in, for example, "/sbin/init.d/lan". - * - * Setting the variable is not necessary on HP-UX 11.x. - */ -static int -get_dlpi_ppa(register int fd, register const char *device, register int unit, - register char *ebuf) -{ - register dl_hp_ppa_ack_t *ap; - register dl_hp_ppa_info_t *ipstart, *ip; - register int i; - char dname[100]; - register u_long majdev; - struct stat statbuf; - dl_hp_ppa_req_t req; - char buf[MAXDLBUF]; - char *ppa_data_buf; - dl_hp_ppa_ack_t *dlp; - struct strbuf ctl; - int flags; - int ppa; - - memset((char *)&req, 0, sizeof(req)); - req.dl_primitive = DL_HP_PPA_REQ; - - memset((char *)buf, 0, sizeof(buf)); - if (send_request(fd, (char *)&req, sizeof(req), "hpppa", ebuf) < 0) - return (-1); - - ctl.maxlen = DL_HP_PPA_ACK_SIZE; - ctl.len = 0; - ctl.buf = (char *)buf; - - flags = 0; - /* - * DLPI may return a big chunk of data for a DL_HP_PPA_REQ. The normal - * recv_ack will fail because it set the maxlen to MAXDLBUF (8192) - * which is NOT big enough for a DL_HP_PPA_REQ. - * - * This causes libpcap applications to fail on a system with HP-APA - * installed. - * - * To figure out how big the returned data is, we first call getmsg - * to get the small head and peek at the head to get the actual data - * length, and then issue another getmsg to get the actual PPA data. - */ - /* get the head first */ - if (getmsg(fd, &ctl, (struct strbuf *)NULL, &flags) < 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, - "get_dlpi_ppa: hpppa getmsg: %s", pcap_strerror(errno)); - return (-1); - } - - dlp = (dl_hp_ppa_ack_t *)ctl.buf; - if (dlp->dl_primitive != DL_HP_PPA_ACK) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, - "get_dlpi_ppa: hpppa unexpected primitive ack 0x%x", - (bpf_u_int32)dlp->dl_primitive); - return (-1); - } - - if (ctl.len < DL_HP_PPA_ACK_SIZE) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, - "get_dlpi_ppa: hpppa ack too small (%d < %lu)", - ctl.len, (unsigned long)DL_HP_PPA_ACK_SIZE); - return (-1); - } - - /* allocate buffer */ - if ((ppa_data_buf = (char *)malloc(dlp->dl_length)) == NULL) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, - "get_dlpi_ppa: hpppa malloc: %s", pcap_strerror(errno)); - return (-1); - } - ctl.maxlen = dlp->dl_length; - ctl.len = 0; - ctl.buf = (char *)ppa_data_buf; - /* get the data */ - if (getmsg(fd, &ctl, (struct strbuf *)NULL, &flags) < 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, - "get_dlpi_ppa: hpppa getmsg: %s", pcap_strerror(errno)); - free(ppa_data_buf); - return (-1); - } - if (ctl.len < dlp->dl_length) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, - "get_dlpi_ppa: hpppa ack too small (%d < %d)", - ctl.len, dlp->dl_length); - free(ppa_data_buf); - return (-1); - } - - ap = (dl_hp_ppa_ack_t *)buf; - ipstart = (dl_hp_ppa_info_t *)ppa_data_buf; - ip = ipstart; - -#ifdef HAVE_HP_PPA_INFO_T_DL_MODULE_ID_1 - /* - * The "dl_hp_ppa_info_t" structure has a "dl_module_id_1" - * member that should, in theory, contain the part of the - * name for the device that comes before the unit number, - * and should also have a "dl_module_id_2" member that may - * contain an alternate name (e.g., I think Ethernet devices - * have both "lan", for "lanN", and "snap", for "snapN", with - * the former being for Ethernet packets and the latter being - * for 802.3/802.2 packets). - * - * Search for the device that has the specified name and - * instance number. - */ - for (i = 0; i < ap->dl_count; i++) { - if ((strcmp((const char *)ip->dl_module_id_1, device) == 0 || - strcmp((const char *)ip->dl_module_id_2, device) == 0) && - ip->dl_instance_num == unit) - break; - - ip = (dl_hp_ppa_info_t *)((u_char *)ipstart + ip->dl_next_offset); - } -#else - /* - * We don't have that member, so the search is impossible; make it - * look as if the search failed. - */ - i = ap->dl_count; -#endif - - if (i == ap->dl_count) { - /* - * Well, we didn't, or can't, find the device by name. - * - * HP-UX 10.20, whilst it has "dl_module_id_1" and - * "dl_module_id_2" fields in the "dl_hp_ppa_info_t", - * doesn't seem to fill them in unless the system is - * at a reasonably up-to-date patch level. - * - * Older HP-UX 10.x systems might not have those fields - * at all. - * - * Therefore, we'll search for the entry with the major - * device number of a device with the name "/dev/", - * if such a device exists, as the old code did. - */ - snprintf(dname, sizeof(dname), "/dev/%s%d", device, unit); - if (stat(dname, &statbuf) < 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "stat: %s: %s", - dname, pcap_strerror(errno)); - return (-1); - } - majdev = major(statbuf.st_rdev); - - ip = ipstart; - - for (i = 0; i < ap->dl_count; i++) { - if (ip->dl_mjr_num == majdev && - ip->dl_instance_num == unit) - break; - - ip = (dl_hp_ppa_info_t *)((u_char *)ipstart + ip->dl_next_offset); - } - } - if (i == ap->dl_count) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, - "can't find /dev/dlpi PPA for %s%d", device, unit); - return (-1); - } - if (ip->dl_hdw_state == HDW_DEAD) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, - "%s%d: hardware state: DOWN\n", device, unit); - free(ppa_data_buf); - return (-1); - } - ppa = ip->dl_ppa; - free(ppa_data_buf); - return (ppa); -} -#endif - -#ifdef HAVE_HPUX9 -/* - * Under HP-UX 9, there is no good way to determine the ppa. - * So punt and read it from /dev/kmem. - */ -static struct nlist nl[] = { -#define NL_IFNET 0 - { "ifnet" }, - { "" } -}; - -static char path_vmunix[] = "/hp-ux"; - -/* Determine ppa number that specifies ifname */ -static int -get_dlpi_ppa(register int fd, register const char *ifname, register int unit, - register char *ebuf) -{ - register const char *cp; - register int kd; - void *addr; - struct ifnet ifnet; - char if_name[sizeof(ifnet.if_name) + 1]; - - cp = strrchr(ifname, '/'); - if (cp != NULL) - ifname = cp + 1; - if (nlist(path_vmunix, &nl) < 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "nlist %s failed", - path_vmunix); - return (-1); - } - if (nl[NL_IFNET].n_value == 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, - "could't find %s kernel symbol", - nl[NL_IFNET].n_name); - return (-1); - } - kd = open("/dev/kmem", O_RDONLY); - if (kd < 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "kmem open: %s", - pcap_strerror(errno)); - return (-1); - } - if (dlpi_kread(kd, nl[NL_IFNET].n_value, - &addr, sizeof(addr), ebuf) < 0) { - close(kd); - return (-1); - } - for (; addr != NULL; addr = ifnet.if_next) { - if (dlpi_kread(kd, (off_t)addr, - &ifnet, sizeof(ifnet), ebuf) < 0 || - dlpi_kread(kd, (off_t)ifnet.if_name, - if_name, sizeof(ifnet.if_name), ebuf) < 0) { - (void)close(kd); - return (-1); - } - if_name[sizeof(ifnet.if_name)] = '\0'; - if (strcmp(if_name, ifname) == 0 && ifnet.if_unit == unit) - return (ifnet.if_index); - } - - snprintf(ebuf, PCAP_ERRBUF_SIZE, "Can't find %s", ifname); - return (-1); -} - -static int -dlpi_kread(register int fd, register off_t addr, - register void *buf, register u_int len, register char *ebuf) -{ - register int cc; - - if (lseek(fd, addr, SEEK_SET) < 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "lseek: %s", - pcap_strerror(errno)); - return (-1); - } - cc = read(fd, buf, len); - if (cc < 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "read: %s", - pcap_strerror(errno)); - return (-1); - } else if (cc != len) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "short read (%d != %d)", cc, - len); - return (-1); - } - return (cc); -} -#endif diff --git a/contrib/libpcap-0.8.3/pcap-enet.c b/contrib/libpcap-0.8.3/pcap-enet.c deleted file mode 100644 index bbfe3e5557..0000000000 --- a/contrib/libpcap-0.8.3/pcap-enet.c +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Stanford Enetfilter subroutines for tcpdump - * - * Based on the MERIT NNstat etherifrt.c and the Ultrix pcap-pf.c - * subroutines. - * - * Rayan Zachariassen, CA*Net - */ -#ifndef lint -static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/libpcap/pcap-enet.c,v 1.7.2.1 2003/11/15 23:26:44 guy Exp $"; -#endif - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -#include -#include - -#include "interface.h" - -struct packet_header { -#ifdef IBMRTPC - struct LengthWords length; - struct tap_header tap; -#endif /* IBMRTPC */ - u_char packet[8] -}; - -extern int errno; - -#define BUFSPACE (4*1024) - -/* Forwards */ -static void efReadError(int, char *); - -void -readloop(int cnt, int if_fd, struct bpf_program *fp, printfunc printit) -{ -#ifdef IBMRTPC - register struct packet_header *ph; - register u_char *bp; - register int inc; -#else /* !IBMRTPC */ - static struct timeval tv = { 0 }; -#endif /* IBMRTPC */ - register int cc, caplen; - register struct bpf_insn *fcode = fp->bf_insns; - union { - struct packet_header hdr; - u_char p[BUFSPACE]; - u_short s; - } buf; - - while (1) { - if ((cc = read(if_fd, (char *)buf.p, sizeof(buf))) < 0) - efReadError(if_fd, "reader"); - -#ifdef IBMRTPC - /* - * Loop through each packet. - */ - bp = buf.p; - while (cc > 0) { - ph = (struct packet_header *)bp; - caplen = ph->tap.th_wirelen > snaplen ? snaplen : ph->tap -.th_wirelen ; - if (bpf_filter(fcode, (char *)ph->packet, - ph->tap.th_wirelen, caplen)) { - if (cnt >= 0 && --cnt < 0) - goto out; - (*printit)((char *)ph->packet, - (struct timeval *)ph->tap.th_timestamp, - ph->tap.th_wirelen, caplen); - } - inc = ph->length.PacketOffset; - cc -= inc; - bp += inc; - } -#else /* !IBMRTPC */ - caplen = cc > snaplen ? snaplen : cc ; - if (bpf_filter(fcode, buf.hdr.packet, cc, caplen)) { - if (cnt >= 0 && --cnt < 0) - goto out; - (*printit)(buf.hdr.packet, &tv, cc, caplen); - } -#endif /* IBMRTPC */ - } - out: - wrapup(if_fd); -} - -/* Call ONLY if read() has returned an error on packet filter */ -static void -efReadError(int fid, char *msg) -{ - if (errno == EINVAL) { /* read MAXINT bytes already! */ - if (lseek(fid, 0, 0) < 0) { - perror("tcpdump: efReadError/lseek"); - exit(-1); - } - else - return; - } - else { - (void) fprintf(stderr, "tcpdump: "); - perror(msg); - exit(-1); - } -} - -void -wrapup(int fd) -{ -#ifdef IBMRTPC - struct enstats es; - - if (ioctl(fd, EIOSTATS, &es) == -1) { - perror("tcpdump: enet ioctl EIOSTATS error"); - exit(-1); - } - - fprintf(stderr, "%d packets queued", es.enStat_Rcnt); - if (es.enStat_Rdrops > 0) - fprintf(stderr, ", %d dropped", es.enStat_Rdrops); - if (es.enStat_Reads > 0) - fprintf(stderr, ", %d tcpdump %s", es.enStat_Reads, - es.enStat_Reads > 1 ? "reads" : "read"); - if (es.enStat_MaxRead > 1) - fprintf(stderr, ", %d packets in largest read", - es.enStat_MaxRead); - putc('\n', stderr); -#endif /* IBMRTPC */ - close(fd); -} - -int -initdevice(char *device, int pflag, int *linktype) -{ - struct eniocb ctl; - struct enfilter filter; - u_int maxwaiting; - int if_fd; - -#ifdef IBMRTPC - GETENETDEVICE(0, O_RDONLY, &if_fd); -#else /* !IBMRTPC */ - if_fd = open("/dev/enet", O_RDONLY, 0); -#endif /* IBMRTPC */ - - if (if_fd == -1) { - perror("tcpdump: enet open error"); - error( -"your system may not be properly configured; see \"man enet(4)\""); - exit(-1); - } - - /* Get operating parameters. */ - - if (ioctl(if_fd, EIOCGETP, (char *)&ctl) == -1) { - perror("tcpdump: enet ioctl EIOCGETP error"); - exit(-1); - } - - /* Set operating parameters. */ - -#ifdef IBMRTPC - ctl.en_rtout = 1 * ctl.en_hz; - ctl.en_tr_etherhead = 1; - ctl.en_tap_network = 1; - ctl.en_multi_packet = 1; - ctl.en_maxlen = BUFSPACE; -#else /* !IBMRTPC */ - ctl.en_rtout = 64; /* randomly picked value for HZ */ -#endif /* IBMRTPC */ - if (ioctl(if_fd, EIOCSETP, &ctl) == -1) { - perror("tcpdump: enet ioctl EIOCSETP error"); - exit(-1); - } - - /* Flush the receive queue, since we've changed - the operating parameters and we otherwise might - receive data without headers. */ - - if (ioctl(if_fd, EIOCFLUSH) == -1) { - perror("tcpdump: enet ioctl EIOCFLUSH error"); - exit(-1); - } - - /* Set the receive queue depth to its maximum. */ - - maxwaiting = ctl.en_maxwaiting; - if (ioctl(if_fd, EIOCSETW, &maxwaiting) == -1) { - perror("tcpdump: enet ioctl EIOCSETW error"); - exit(-1); - } - -#ifdef IBMRTPC - /* Clear statistics. */ - - if (ioctl(if_fd, EIOCLRSTAT, 0) == -1) { - perror("tcpdump: enet ioctl EIOCLRSTAT error"); - exit(-1); - } -#endif /* IBMRTPC */ - - /* Set the filter (accept all packets). */ - - filter.enf_Priority = 3; - filter.enf_FilterLen = 0; - if (ioctl(if_fd, EIOCSETF, &filter) == -1) { - perror("tcpdump: enet ioctl EIOCSETF error"); - exit(-1); - } - /* - * "enetfilter" supports only ethernets. - */ - *linktype = DLT_EN10MB; - - return(if_fd); -} diff --git a/contrib/libpcap-0.8.3/pcap-int.h b/contrib/libpcap-0.8.3/pcap-int.h deleted file mode 100644 index c56553c3f6..0000000000 --- a/contrib/libpcap-0.8.3/pcap-int.h +++ /dev/null @@ -1,293 +0,0 @@ -/* - * Copyright (c) 1994, 1995, 1996 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the Computer Systems - * Engineering Group at Lawrence Berkeley Laboratory. - * 4. Neither the name of the University nor of the Laboratory may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#) $Header: /tcpdump/master/libpcap/pcap-int.h,v 1.55.2.4 2003/12/15 01:42:24 guy Exp $ (LBL) - */ - -#ifndef pcap_int_h -#define pcap_int_h - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#ifdef WIN32 -#include -#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; -}; - -struct pcap_md { - struct pcap_stat stat; - /*XXX*/ - int use_bpf; /* using kernel filter */ - u_long TotPkts; /* can't oflow for 79 hrs on ether */ - u_long TotAccepted; /* count accepted by filter */ - u_long TotDrops; /* count of dropped packets */ - long TotMissed; /* missed by i/f during this run */ - long OrigMissed; /* missed by i/f before this run */ -#ifdef linux - int sock_packet; /* using Linux 2.0 compatible interface */ - int timeout; /* timeout specified to pcap_open_live */ - 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 */ - 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; - - /* - * Read buffer. - */ - int bufsize; - u_char *buffer; - u_char *bp; - int cc; - - /* - * Place holder for pcap_next(). - */ - 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 + 1]; - int dlt_count; - int *dlt_list; - - struct pcap_pkthdr pcap_header; /* This is needed for the pcap_next_ex() to work */ -}; - -/* - * This is a timeval as stored in disk in a dumpfile. - * It has to use the same types everywhere, independent of the actual - * `struct timeval' - */ - -struct pcap_timeval { - bpf_int32 tv_sec; /* seconds */ - bpf_int32 tv_usec; /* microseconds */ -}; - -/* - * How a `pcap_pkthdr' is actually stored in the dumpfile. - * - * Do not change the format of this structure, in any way (this includes - * changes that only affect the length of fields in this structure), - * and do not make the time stamp anything other than seconds and - * microseconds (e.g., seconds and nanoseconds). Instead: - * - * introduce a new structure for the new format; - * - * send mail to "tcpdump-workers@tcpdump.org", requesting a new - * magic number for your new capture file format, and, when - * you get the new magic number, put it in "savefile.c"; - * - * use that magic number for save files with the changed record - * header; - * - * make the code in "savefile.c" capable of reading files with - * the old record header as well as files with the new record header - * (using the magic number to determine the header format). - * - * Then supply the changes to "patches@tcpdump.org", so that future - * versions of libpcap and programs that use it (such as tcpdump) will - * be able to read your new capture file format. - */ - -struct pcap_sf_pkthdr { - struct pcap_timeval ts; /* time stamp */ - bpf_u_int32 caplen; /* length of portion present */ - bpf_u_int32 len; /* length this packet (off wire) */ -}; - -/* - * How a `pcap_pkthdr' is actually stored in dumpfiles written - * by some patched versions of libpcap (e.g. the ones in Red - * Hat Linux 6.1 and 6.2). - * - * Do not change the format of this structure, in any way (this includes - * changes that only affect the length of fields in this structure). - * Instead, introduce a new structure, as per the above. - */ - -struct pcap_sf_patched_pkthdr { - struct pcap_timeval ts; /* time stamp */ - bpf_u_int32 caplen; /* length of portion present */ - bpf_u_int32 len; /* length this packet (off wire) */ - int index; - unsigned short protocol; - unsigned char pkt_type; -}; - -int yylex(void); - -#ifndef min -#define min(a, b) ((a) > (b) ? (b) : (a)) -#endif - -/* XXX should these be in pcap.h? */ -int pcap_offline_read(pcap_t *, int, pcap_handler, u_char *); -int pcap_read(pcap_t *, int cnt, pcap_handler, u_char *); - - -/* - * 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. - */ -#if defined(ultrix) || defined(__osf__) || defined(__NetBSD__) -#define PCAP_FDDIPAD 3 -#endif - -#ifndef HAVE_STRLCPY -#define strlcpy(x, y, z) \ - (strncpy((x), (y), (z)), \ - ((z) <= 0 ? 0 : ((x)[(z) - 1] = '\0')), \ - strlen((y))) -#endif - -#include - -#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 */ -extern int pcap_fddipad; - -int install_bpf_program(pcap_t *, struct bpf_program *); - -int pcap_strcasecmp(const char *, const char *); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/contrib/libpcap-0.8.3/pcap-linux.c b/contrib/libpcap-0.8.3/pcap-linux.c deleted file mode 100644 index df1b64686a..0000000000 --- a/contrib/libpcap-0.8.3/pcap-linux.c +++ /dev/null @@ -1,1999 +0,0 @@ -/* - * pcap-linux.c: Packet capture interface to the Linux kernel - * - * Copyright (c) 2000 Torsten Landschoff - * Sebastian Krahmer - * - * License: BSD - * - * 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. The names of the authors may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#ifndef lint -static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/libpcap/pcap-linux.c,v 1.98.2.4 2003/11/21 10:20:46 guy Exp $ (LBL)"; -#endif - -/* - * Known problems with 2.0[.x] kernels: - * - * - The loopback device gives every packet twice; on 2.2[.x] kernels, - * if we use PF_PACKET, we can filter out the transmitted version - * of the packet by using data in the "sockaddr_ll" returned by - * "recvfrom()", but, on 2.0[.x] kernels, we have to use - * PF_INET/SOCK_PACKET, which means "recvfrom()" supplies a - * "sockaddr_pkt" which doesn't give us enough information to let - * us do that. - * - * - We have to set the interface's IFF_PROMISC flag ourselves, if - * we're to run in promiscuous mode, which means we have to turn - * it off ourselves when we're done; the kernel doesn't keep track - * of how many sockets are listening promiscuously, which means - * it won't get turned off automatically when no sockets are - * listening promiscuously. We catch "pcap_close()" and, for - * interfaces we put into promiscuous mode, take them out of - * promiscuous mode - which isn't necessarily the right thing to - * do, if another socket also requested promiscuous mode between - * the time when we opened the socket and the time when we close - * the socket. - * - * - MSG_TRUNC isn't supported, so you can't specify that "recvfrom()" - * return the amount of data that you could have read, rather than - * the amount that was returned, so we can't just allocate a buffer - * whose size is the snapshot length and pass the snapshot length - * as the byte count, and also pass MSG_TRUNC, so that the return - * value tells us how long the packet was on the wire. - * - * This means that, if we want to get the actual size of the packet, - * so we can return it in the "len" field of the packet header, - * we have to read the entire packet, not just the part that fits - * within the snapshot length, and thus waste CPU time copying data - * from the kernel that our caller won't see. - * - * We have to get the actual size, and supply it in "len", because - * otherwise, the IP dissector in tcpdump, for example, will complain - * about "truncated-ip", as the packet will appear to have been - * shorter, on the wire, than the IP header said it should have been. - */ - - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "pcap-int.h" -#include "sll.h" - -#ifdef HAVE_DAG_API -#include "pcap-dag.h" -#endif /* HAVE_DAG_API */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * If PF_PACKET is defined, we can use {SOCK_RAW,SOCK_DGRAM}/PF_PACKET - * sockets rather than SOCK_PACKET sockets. - * - * To use them, we include rather than - * ; we do so because - * - * some Linux distributions (e.g., Slackware 4.0) have 2.2 or - * later kernels and libc5, and don't provide a - * file; - * - * not all versions of glibc2 have a file - * that defines stuff needed for some of the 2.4-or-later-kernel - * features, so if the system has a 2.4 or later kernel, we - * still can't use those features. - * - * We're already including a number of other headers, and - * this code is Linux-specific (no other OS has PF_PACKET sockets as - * a raw packet capture mechanism), so it's not as if you gain any - * useful portability by using - * - * XXX - should we just include even if PF_PACKET - * isn't defined? It only defines one data structure in 2.0.x, so - * it shouldn't cause any problems. - */ -#ifdef PF_PACKET -# include - - /* - * On at least some Linux distributions (for example, Red Hat 5.2), - * there's no file, but PF_PACKET is defined if - * you include , but doesn't define - * any of the PF_PACKET stuff such as "struct sockaddr_ll" or any of - * the PACKET_xxx stuff. - * - * So we check whether PACKET_HOST is defined, and assume that we have - * PF_PACKET sockets only if it is defined. - */ -# ifdef PACKET_HOST -# define HAVE_PF_PACKET_SOCKETS -# endif /* PACKET_HOST */ -#endif /* PF_PACKET */ - -#ifdef SO_ATTACH_FILTER -#include -#include -#endif - -#ifndef __GLIBC__ -typedef int socklen_t; -#endif - -#ifndef MSG_TRUNC -/* - * This is being compiled on a system that lacks MSG_TRUNC; define it - * with the value it has in the 2.2 and later kernels, so that, on - * those kernels, when we pass it in the flags argument to "recvfrom()" - * we're passing the right value and thus get the MSG_TRUNC behavior - * we want. (We don't get that behavior on 2.0[.x] kernels, because - * they didn't support MSG_TRUNC.) - */ -#define MSG_TRUNC 0x20 -#endif - -#ifndef SOL_PACKET -/* - * This is being compiled on a system that lacks SOL_PACKET; define it - * with the value it has in the 2.2 and later kernels, so that we can - * set promiscuous mode in the good modern way rather than the old - * 2.0-kernel crappy way. - */ -#define SOL_PACKET 263 -#endif - -#define MAX_LINKHEADER_SIZE 256 - -/* - * When capturing on all interfaces we use this as the buffer size. - * Should be bigger then all MTUs that occur in real life. - * 64kB should be enough for now. - */ -#define BIGGER_THAN_ALL_MTUS (64*1024) - -/* - * Prototypes for internal functions - */ -static void map_arphrd_to_dlt(pcap_t *, int, int); -static int live_open_old(pcap_t *, const char *, int, int, char *); -static int live_open_new(pcap_t *, const char *, int, int, char *); -static int pcap_read_linux(pcap_t *, int, pcap_handler, u_char *); -static int pcap_read_packet(pcap_t *, pcap_handler, u_char *); -static int pcap_stats_linux(pcap_t *, struct pcap_stat *); -static int pcap_setfilter_linux(pcap_t *, struct bpf_program *); -static void pcap_close_linux(pcap_t *); - -/* - * Wrap some ioctl calls - */ -#ifdef HAVE_PF_PACKET_SOCKETS -static int iface_get_id(int fd, const char *device, char *ebuf); -#endif -static int iface_get_mtu(int fd, const char *device, char *ebuf); -static int iface_get_arptype(int fd, const char *device, char *ebuf); -#ifdef HAVE_PF_PACKET_SOCKETS -static int iface_bind(int fd, int ifindex, char *ebuf); -#endif -static int iface_bind_old(int fd, const char *device, char *ebuf); - -#ifdef SO_ATTACH_FILTER -static int fix_program(pcap_t *handle, struct sock_fprog *fcode); -static int fix_offset(struct bpf_insn *p); -static int set_kernel_filter(pcap_t *handle, struct sock_fprog *fcode); -static int reset_kernel_filter(pcap_t *handle); - -static struct sock_filter total_insn - = BPF_STMT(BPF_RET | BPF_K, 0); -static struct sock_fprog total_fcode - = { 1, &total_insn }; -#endif - -/* - * Get a handle for a live capture from the given device. You can - * pass NULL as device to get all packages (without link level - * information of course). If you pass 1 as promisc the interface - * will be set to promiscous mode (XXX: I think this usage should - * be deprecated and functions be added to select that later allow - * modification of that values -- Torsten). - * - * See also pcap(3). - */ -pcap_t * -pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, - char *ebuf) -{ - pcap_t *handle; - int mtu; - int err; - int live_open_ok = 0; - struct utsname utsname; - -#ifdef HAVE_DAG_API - if (strstr(device, "dag")) { - return dag_open_live(device, snaplen, promisc, to_ms, ebuf); - } -#endif /* HAVE_DAG_API */ - - /* Allocate a handle for this session. */ - - handle = malloc(sizeof(*handle)); - if (handle == NULL) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", - pcap_strerror(errno)); - return NULL; - } - - /* Initialize some components of the pcap structure. */ - - memset(handle, 0, sizeof(*handle)); - handle->snapshot = snaplen; - handle->md.timeout = to_ms; - - /* - * NULL and "any" are special devices which give us the hint to - * monitor all devices. - */ - if (!device || strcmp(device, "any") == 0) { - device = NULL; - handle->md.device = strdup("any"); - if (promisc) { - promisc = 0; - /* Just a warning. */ - snprintf(ebuf, PCAP_ERRBUF_SIZE, - "Promiscuous mode not supported on the \"any\" device"); - } - - } else - handle->md.device = strdup(device); - - if (handle->md.device == NULL) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "strdup: %s", - pcap_strerror(errno) ); - free(handle); - return NULL; - } - - /* - * Current Linux kernels use the protocol family PF_PACKET to - * allow direct access to all packets on the network while - * older kernels had a special socket type SOCK_PACKET to - * implement this feature. - * While this old implementation is kind of obsolete we need - * to be compatible with older kernels for a while so we are - * trying both methods with the newer method preferred. - */ - - if ((err = live_open_new(handle, device, promisc, to_ms, ebuf)) == 1) - live_open_ok = 1; - else if (err == 0) { - /* Non-fatal error; try old way */ - if (live_open_old(handle, device, promisc, to_ms, ebuf)) - live_open_ok = 1; - } - if (!live_open_ok) { - /* - * Both methods to open the packet socket failed. Tidy - * up and report our failure (ebuf is expected to be - * set by the functions above). - */ - - if (handle->md.device != NULL) - free(handle->md.device); - free(handle); - return NULL; - } - - /* - * Compute the buffer size. - * - * If we're using SOCK_PACKET, this might be a 2.0[.x] kernel, - * and might require special handling - check. - */ - if (handle->md.sock_packet && (uname(&utsname) < 0 || - strncmp(utsname.release, "2.0", 3) == 0)) { - /* - * We're using a SOCK_PACKET structure, and either - * we couldn't find out what kernel release this is, - * or it's a 2.0[.x] kernel. - * - * In the 2.0[.x] kernel, a "recvfrom()" on - * a SOCK_PACKET socket, with MSG_TRUNC set, will - * return the number of bytes read, so if we pass - * a length based on the snapshot length, it'll - * return the number of bytes from the packet - * copied to userland, not the actual length - * of the packet. - * - * This means that, for example, the IP dissector - * in tcpdump will get handed a packet length less - * than the length in the IP header, and will - * complain about "truncated-ip". - * - * So we don't bother trying to copy from the - * kernel only the bytes in which we're interested, - * but instead copy them all, just as the older - * versions of libpcap for Linux did. - * - * The buffer therefore needs to be big enough to - * hold the largest packet we can get from this - * device. Unfortunately, we can't get the MRU - * of the network; we can only get the MTU. The - * MTU may be too small, in which case a packet larger - * than the buffer size will be truncated *and* we - * won't get the actual packet size. - * - * However, if the snapshot length is larger than - * the buffer size based on the MTU, we use the - * snapshot length as the buffer size, instead; - * this means that with a sufficiently large snapshot - * length we won't artificially truncate packets - * to the MTU-based size. - * - * This mess just one of many problems with packet - * capture on 2.0[.x] kernels; you really want a - * 2.2[.x] or later kernel if you want packet capture - * to work well. - */ - mtu = iface_get_mtu(handle->fd, device, ebuf); - if (mtu == -1) { - pcap_close_linux(handle); - free(handle); - return NULL; - } - handle->bufsize = MAX_LINKHEADER_SIZE + mtu; - if (handle->bufsize < handle->snapshot) - handle->bufsize = handle->snapshot; - } else { - /* - * This is a 2.2[.x] or later kernel (we know that - * either because we're not using a SOCK_PACKET - * socket - PF_PACKET is supported only in 2.2 - * and later kernels - or because we checked the - * kernel version). - * - * We can safely pass "recvfrom()" a byte count - * based on the snapshot length. - */ - handle->bufsize = handle->snapshot; - } - - /* Allocate the buffer */ - - handle->buffer = malloc(handle->bufsize + handle->offset); - if (!handle->buffer) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, - "malloc: %s", pcap_strerror(errno)); - pcap_close_linux(handle); - free(handle); - return NULL; - } - - /* - * "handle->fd" is a socket, so "select()" and "poll()" - * should work on it. - */ - handle->selectable_fd = handle->fd; - - handle->read_op = pcap_read_linux; - handle->setfilter_op = pcap_setfilter_linux; - handle->set_datalink_op = NULL; /* can't change data link type */ - handle->getnonblock_op = pcap_getnonblock_fd; - handle->setnonblock_op = pcap_setnonblock_fd; - handle->stats_op = pcap_stats_linux; - handle->close_op = pcap_close_linux; - - return handle; -} - -/* - * Read at most max_packets from the capture stream and call the callback - * for each of them. Returns the number of packets handled or -1 if an - * error occured. - */ -static int -pcap_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user) -{ - /* - * Currently, on Linux only one packet is delivered per read, - * so we don't loop. - */ - return pcap_read_packet(handle, callback, user); -} - -/* - * Read a packet from the socket calling the handler provided by - * the user. Returns the number of packets received or -1 if an - * error occured. - */ -static int -pcap_read_packet(pcap_t *handle, pcap_handler callback, u_char *userdata) -{ - u_char *bp; - int offset; -#ifdef HAVE_PF_PACKET_SOCKETS - struct sockaddr_ll from; - struct sll_header *hdrp; -#else - struct sockaddr from; -#endif - socklen_t fromlen; - int packet_len, caplen; - struct pcap_pkthdr pcap_header; - -#ifdef HAVE_PF_PACKET_SOCKETS - /* - * If this is a cooked device, leave extra room for a - * fake packet header. - */ - if (handle->md.cooked) - offset = SLL_HDR_LEN; - else - offset = 0; -#else - /* - * This system doesn't have PF_PACKET sockets, so it doesn't - * support cooked devices. - */ - offset = 0; -#endif - - /* Receive a single packet from the kernel */ - - bp = handle->buffer + handle->offset; - do { - /* - * Has "pcap_breakloop()" been called? - */ - if (handle->break_loop) { - /* - * Yes - clear the flag that indicates that it - * has, and return -2 as an indication that we - * were told to break out of the loop. - */ - handle->break_loop = 0; - return -2; - } - fromlen = sizeof(from); - packet_len = recvfrom( - handle->fd, bp + offset, - handle->bufsize - offset, MSG_TRUNC, - (struct sockaddr *) &from, &fromlen); - } while (packet_len == -1 && errno == EINTR); - - /* Check if an error occured */ - - if (packet_len == -1) { - if (errno == EAGAIN) - return 0; /* no packet there */ - else { - snprintf(handle->errbuf, sizeof(handle->errbuf), - "recvfrom: %s", pcap_strerror(errno)); - return -1; - } - } - -#ifdef HAVE_PF_PACKET_SOCKETS - /* - * If this is from the loopback device, reject outgoing packets; - * we'll see the packet as an incoming packet as well, and - * we don't want to see it twice. - * - * We can only do this if we're using PF_PACKET; the address - * returned for SOCK_PACKET is a "sockaddr_pkt" which lacks - * the relevant packet type information. - */ - if (!handle->md.sock_packet && - from.sll_ifindex == handle->md.lo_ifindex && - from.sll_pkttype == PACKET_OUTGOING) - return 0; -#endif - -#ifdef HAVE_PF_PACKET_SOCKETS - /* - * If this is a cooked device, fill in the fake packet header. - */ - if (handle->md.cooked) { - /* - * Add the length of the fake header to the length - * of packet data we read. - */ - packet_len += SLL_HDR_LEN; - - hdrp = (struct sll_header *)bp; - - /* - * Map the PACKET_ value to a LINUX_SLL_ value; we - * want the same numerical value to be used in - * the link-layer header even if the numerical values - * for the PACKET_ #defines change, so that programs - * that look at the packet type field will always be - * able to handle DLT_LINUX_SLL captures. - */ - switch (from.sll_pkttype) { - - case PACKET_HOST: - hdrp->sll_pkttype = htons(LINUX_SLL_HOST); - break; - - case PACKET_BROADCAST: - hdrp->sll_pkttype = htons(LINUX_SLL_BROADCAST); - break; - - case PACKET_MULTICAST: - hdrp->sll_pkttype = htons(LINUX_SLL_MULTICAST); - break; - - case PACKET_OTHERHOST: - hdrp->sll_pkttype = htons(LINUX_SLL_OTHERHOST); - break; - - case PACKET_OUTGOING: - hdrp->sll_pkttype = htons(LINUX_SLL_OUTGOING); - break; - - default: - hdrp->sll_pkttype = -1; - break; - } - - hdrp->sll_hatype = htons(from.sll_hatype); - hdrp->sll_halen = htons(from.sll_halen); - memcpy(hdrp->sll_addr, from.sll_addr, - (from.sll_halen > SLL_ADDRLEN) ? - SLL_ADDRLEN : - from.sll_halen); - hdrp->sll_protocol = from.sll_protocol; - } -#endif - - /* - * XXX: According to the kernel source we should get the real - * packet len if calling recvfrom with MSG_TRUNC set. It does - * not seem to work here :(, but it is supported by this code - * anyway. - * To be honest the code RELIES on that feature so this is really - * broken with 2.2.x kernels. - * I spend a day to figure out what's going on and I found out - * that the following is happening: - * - * The packet comes from a random interface and the packet_rcv - * hook is called with a clone of the packet. That code inserts - * the packet into the receive queue of the packet socket. - * If a filter is attached to that socket that filter is run - * first - and there lies the problem. The default filter always - * cuts the packet at the snaplen: - * - * # tcpdump -d - * (000) ret #68 - * - * So the packet filter cuts down the packet. The recvfrom call - * says "hey, it's only 68 bytes, it fits into the buffer" with - * the result that we don't get the real packet length. This - * is valid at least until kernel 2.2.17pre6. - * - * We currently handle this by making a copy of the filter - * program, fixing all "ret" instructions with non-zero - * operands to have an operand of 65535 so that the filter - * doesn't truncate the packet, and supplying that modified - * filter to the kernel. - */ - - caplen = packet_len; - if (caplen > handle->snapshot) - caplen = handle->snapshot; - - /* Run the packet filter if not using kernel filter */ - if (!handle->md.use_bpf && handle->fcode.bf_insns) { - if (bpf_filter(handle->fcode.bf_insns, bp, - packet_len, caplen) == 0) - { - /* rejected by filter */ - return 0; - } - } - - /* Fill in our own header data */ - - if (ioctl(handle->fd, SIOCGSTAMP, &pcap_header.ts) == -1) { - snprintf(handle->errbuf, sizeof(handle->errbuf), - "ioctl: %s", pcap_strerror(errno)); - return -1; - } - pcap_header.caplen = caplen; - pcap_header.len = packet_len; - - /* - * Count the packet. - * - * Arguably, we should count them before we check the filter, - * as on many other platforms "ps_recv" counts packets - * handed to the filter rather than packets that passed - * the filter, but if filtering is done in the kernel, we - * can't get a count of packets that passed the filter, - * and that would mean the meaning of "ps_recv" wouldn't - * be the same on all Linux systems. - * - * XXX - it's not the same on all systems in any case; - * ideally, we should have a "get the statistics" call - * that supplies more counts and indicates which of them - * it supplies, so that we supply a count of packets - * handed to the filter only on platforms where that - * information is available. - * - * We count them here even if we can get the packet count - * from the kernel, as we can only determine at run time - * whether we'll be able to get it from the kernel (if - * HAVE_TPACKET_STATS isn't defined, we can't get it from - * the kernel, but if it is defined, the library might - * have been built with a 2.4 or later kernel, but we - * might be running on a 2.2[.x] kernel without Alexey - * Kuznetzov's turbopacket patches, and thus the kernel - * might not be able to supply those statistics). We - * could, I guess, try, when opening the socket, to get - * the statistics, and if we can not increment the count - * here, but it's not clear that always incrementing - * the count is more expensive than always testing a flag - * in memory. - */ - handle->md.stat.ps_recv++; - - /* Call the user supplied callback function */ - callback(userdata, &pcap_header, bp); - - return 1; -} - -/* - * Get the statistics for the given packet capture handle. - * Reports the number of dropped packets iff the kernel supports - * the PACKET_STATISTICS "getsockopt()" argument (2.4 and later - * kernels, and 2.2[.x] kernels with Alexey Kuznetzov's turbopacket - * patches); otherwise, that information isn't available, and we lie - * and report 0 as the count of dropped packets. - */ -static int -pcap_stats_linux(pcap_t *handle, struct pcap_stat *stats) -{ -#ifdef HAVE_TPACKET_STATS - struct tpacket_stats kstats; - socklen_t len = sizeof (struct tpacket_stats); -#endif - -#ifdef HAVE_TPACKET_STATS - /* - * Try to get the packet counts from the kernel. - */ - if (getsockopt(handle->fd, SOL_PACKET, PACKET_STATISTICS, - &kstats, &len) > -1) { - /* - * In "linux/net/packet/af_packet.c", at least in the - * 2.4.9 kernel, "tp_packets" is incremented for every - * packet that passes the packet filter *and* is - * successfully queued on the socket; "tp_drops" is - * incremented for every packet dropped because there's - * not enough free space in the socket buffer. - * - * When the statistics are returned for a PACKET_STATISTICS - * "getsockopt()" call, "tp_drops" is added to "tp_packets", - * so that "tp_packets" counts all packets handed to - * the PF_PACKET socket, including packets dropped because - * there wasn't room on the socket buffer - but not - * including packets that didn't pass the filter. - * - * In the BSD BPF, the count of received packets is - * incremented for every packet handed to BPF, regardless - * of whether it passed the filter. - * - * We can't make "pcap_stats()" work the same on both - * platforms, but the best approximation is to return - * "tp_packets" as the count of packets and "tp_drops" - * as the count of drops. - */ - handle->md.stat.ps_recv = kstats.tp_packets; - handle->md.stat.ps_drop = kstats.tp_drops; - } - else - { - /* - * If the error was EOPNOTSUPP, fall through, so that - * if you build the library on a system with - * "struct tpacket_stats" and run it on a system - * that doesn't, it works as it does if the library - * is built on a system without "struct tpacket_stats". - */ - if (errno != EOPNOTSUPP) { - snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, - "pcap_stats: %s", pcap_strerror(errno)); - return -1; - } - } -#endif - /* - * On systems where the PACKET_STATISTICS "getsockopt()" argument - * is supported on PF_PACKET sockets: - * - * "ps_recv" counts only packets that *passed* the filter, - * not packets that didn't pass the filter. This includes - * packets later dropped because we ran out of buffer space. - * - * "ps_drop" counts packets dropped because we ran out of - * buffer space. It doesn't count packets dropped by the - * interface driver. It counts only packets that passed - * the filter. - * - * Both statistics include packets not yet read from the - * kernel by libpcap, and thus not yet seen by the application. - * - * On systems where the PACKET_STATISTICS "getsockopt()" argument - * is not supported on PF_PACKET sockets: - * - * "ps_recv" counts only packets that *passed* the filter, - * not packets that didn't pass the filter. It does not - * count packets dropped because we ran out of buffer - * space. - * - * "ps_drop" is not supported. - * - * "ps_recv" doesn't include packets not yet read from - * the kernel by libpcap. - */ - *stats = handle->md.stat; - return 0; -} - -/* - * Description string for the "any" device. - */ -static const char any_descr[] = "Pseudo-device that captures on all interfaces"; - -int -pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf) -{ - if (pcap_add_if(alldevsp, "any", 0, any_descr, errbuf) < 0) - return (-1); - -#ifdef HAVE_DAG_API - if (dag_platform_finddevs(alldevsp, errbuf) < 0) - return (-1); -#endif /* HAVE_DAG_API */ - - return (0); -} - -/* - * Attach the given BPF code to the packet capture device. - */ -static int -pcap_setfilter_linux(pcap_t *handle, struct bpf_program *filter) -{ -#ifdef SO_ATTACH_FILTER - struct sock_fprog fcode; - int can_filter_in_kernel; - int err = 0; -#endif - - if (!handle) - return -1; - if (!filter) { - strncpy(handle->errbuf, "setfilter: No filter specified", - sizeof(handle->errbuf)); - return -1; - } - - /* Make our private copy of the filter */ - - if (install_bpf_program(handle, filter) < 0) - /* install_bpf_program() filled in errbuf */ - return -1; - - /* - * Run user level packet filter by default. Will be overriden if - * installing a kernel filter succeeds. - */ - handle->md.use_bpf = 0; - - /* Install kernel level filter if possible */ - -#ifdef SO_ATTACH_FILTER -#ifdef USHRT_MAX - if (handle->fcode.bf_len > USHRT_MAX) { - /* - * fcode.len is an unsigned short for current kernel. - * I have yet to see BPF-Code with that much - * instructions but still it is possible. So for the - * sake of correctness I added this check. - */ - fprintf(stderr, "Warning: Filter too complex for kernel\n"); - fcode.filter = NULL; - can_filter_in_kernel = 0; - } else -#endif /* USHRT_MAX */ - { - /* - * Oh joy, the Linux kernel uses struct sock_fprog instead - * of struct bpf_program and of course the length field is - * of different size. Pointed out by Sebastian - * - * Oh, and we also need to fix it up so that all "ret" - * instructions with non-zero operands have 65535 as the - * operand, and so that, if we're in cooked mode, all - * memory-reference instructions use special magic offsets - * in references to the link-layer header and assume that - * the link-layer payload begins at 0; "fix_program()" - * will do that. - */ - switch (fix_program(handle, &fcode)) { - - case -1: - default: - /* - * Fatal error; just quit. - * (The "default" case shouldn't happen; we - * return -1 for that reason.) - */ - return -1; - - case 0: - /* - * The program performed checks that we can't make - * work in the kernel. - */ - can_filter_in_kernel = 0; - break; - - case 1: - /* - * We have a filter that'll work in the kernel. - */ - can_filter_in_kernel = 1; - break; - } - } - - if (can_filter_in_kernel) { - if ((err = set_kernel_filter(handle, &fcode)) == 0) - { - /* Installation succeded - using kernel filter. */ - handle->md.use_bpf = 1; - } - else if (err == -1) /* Non-fatal error */ - { - /* - * Print a warning if we weren't able to install - * the filter for a reason other than "this kernel - * isn't configured to support socket filters. - */ - if (errno != ENOPROTOOPT && errno != EOPNOTSUPP) { - fprintf(stderr, - "Warning: Kernel filter failed: %s\n", - pcap_strerror(errno)); - } - } - } - - /* - * If we're not using the kernel filter, get rid of any kernel - * filter that might've been there before, e.g. because the - * previous filter could work in the kernel, or because some other - * code attached a filter to the socket by some means other than - * calling "pcap_setfilter()". Otherwise, the kernel filter may - * filter out packets that would pass the new userland filter. - */ - if (!handle->md.use_bpf) - reset_kernel_filter(handle); - - /* - * Free up the copy of the filter that was made by "fix_program()". - */ - if (fcode.filter != NULL) - free(fcode.filter); - - if (err == -2) - /* Fatal error */ - return -1; -#endif /* SO_ATTACH_FILTER */ - - return 0; -} - -/* - * Linux uses the ARP hardware type to identify the type of an - * interface. pcap uses the DLT_xxx constants for this. This - * function takes a pointer to a "pcap_t", and an ARPHRD_xxx - * constant, as arguments, and sets "handle->linktype" to the - * appropriate DLT_XXX constant and sets "handle->offset" to - * the appropriate value (to make "handle->offset" plus link-layer - * header length be a multiple of 4, so that the link-layer payload - * will be aligned on a 4-byte boundary when capturing packets). - * (If the offset isn't set here, it'll be 0; add code as appropriate - * for cases where it shouldn't be 0.) - * - * If "cooked_ok" is non-zero, we can use DLT_LINUX_SLL and capture - * in cooked mode; otherwise, we can't use cooked mode, so we have - * to pick some type that works in raw mode, or fail. - * - * Sets the link type to -1 if unable to map the type. - */ -static void map_arphrd_to_dlt(pcap_t *handle, int arptype, int cooked_ok) -{ - switch (arptype) { - - case ARPHRD_ETHER: - case ARPHRD_METRICOM: - case ARPHRD_LOOPBACK: - handle->linktype = DLT_EN10MB; - handle->offset = 2; - break; - - case ARPHRD_EETHER: - handle->linktype = DLT_EN3MB; - break; - - case ARPHRD_AX25: - handle->linktype = DLT_AX25; - break; - - case ARPHRD_PRONET: - handle->linktype = DLT_PRONET; - break; - - case ARPHRD_CHAOS: - handle->linktype = DLT_CHAOS; - break; - -#ifndef ARPHRD_IEEE802_TR -#define ARPHRD_IEEE802_TR 800 /* From Linux 2.4 */ -#endif - case ARPHRD_IEEE802_TR: - case ARPHRD_IEEE802: - handle->linktype = DLT_IEEE802; - handle->offset = 2; - break; - - case ARPHRD_ARCNET: - handle->linktype = DLT_ARCNET_LINUX; - break; - -#ifndef ARPHRD_FDDI /* From Linux 2.2.13 */ -#define ARPHRD_FDDI 774 -#endif - case ARPHRD_FDDI: - handle->linktype = DLT_FDDI; - handle->offset = 3; - break; - -#ifndef ARPHRD_ATM /* FIXME: How to #include this? */ -#define ARPHRD_ATM 19 -#endif - case ARPHRD_ATM: - /* - * The Classical IP implementation in ATM for Linux - * supports both what RFC 1483 calls "LLC Encapsulation", - * in which each packet has an LLC header, possibly - * with a SNAP header as well, prepended to it, and - * what RFC 1483 calls "VC Based Multiplexing", in which - * different virtual circuits carry different network - * layer protocols, and no header is prepended to packets. - * - * They both have an ARPHRD_ type of ARPHRD_ATM, so - * you can't use the ARPHRD_ type to find out whether - * captured packets will have an LLC header, and, - * while there's a socket ioctl to *set* the encapsulation - * type, there's no ioctl to *get* the encapsulation type. - * - * This means that - * - * programs that dissect Linux Classical IP frames - * would have to check for an LLC header and, - * depending on whether they see one or not, dissect - * the frame as LLC-encapsulated or as raw IP (I - * don't know whether there's any traffic other than - * IP that would show up on the socket, or whether - * there's any support for IPv6 in the Linux - * Classical IP code); - * - * filter expressions would have to compile into - * code that checks for an LLC header and does - * the right thing. - * - * Both of those are a nuisance - and, at least on systems - * that support PF_PACKET sockets, we don't have to put - * up with those nuisances; instead, we can just capture - * in cooked mode. That's what we'll do, if we can. - * Otherwise, we'll just fail. - */ - if (cooked_ok) - handle->linktype = DLT_LINUX_SLL; - else - handle->linktype = -1; - break; - -#ifndef ARPHRD_IEEE80211 /* From Linux 2.4.6 */ -#define ARPHRD_IEEE80211 801 -#endif - case ARPHRD_IEEE80211: - handle->linktype = DLT_IEEE802_11; - break; - -#ifndef ARPHRD_IEEE80211_PRISM /* From Linux 2.4.18 */ -#define ARPHRD_IEEE80211_PRISM 802 -#endif - case ARPHRD_IEEE80211_PRISM: - handle->linktype = DLT_PRISM_HEADER; - break; - - case ARPHRD_PPP: - /* - * Some PPP code in the kernel supplies no link-layer - * header whatsoever to PF_PACKET sockets; other PPP - * code supplies PPP link-layer headers ("syncppp.c"); - * some PPP code might supply random link-layer - * headers (PPP over ISDN - there's code in Ethereal, - * for example, to cope with PPP-over-ISDN captures - * with which the Ethereal developers have had to cope, - * heuristically trying to determine which of the - * oddball link-layer headers particular packets have). - * - * As such, we just punt, and run all PPP interfaces - * in cooked mode, if we can; otherwise, we just treat - * it as DLT_RAW, for now - if somebody needs to capture, - * on a 2.0[.x] kernel, on PPP devices that supply a - * link-layer header, they'll have to add code here to - * map to the appropriate DLT_ type (possibly adding a - * new DLT_ type, if necessary). - */ - if (cooked_ok) - handle->linktype = DLT_LINUX_SLL; - else { - /* - * XXX - handle ISDN types here? We can't fall - * back on cooked sockets, so we'd have to - * figure out from the device name what type of - * link-layer encapsulation it's using, and map - * that to an appropriate DLT_ value, meaning - * we'd map "isdnN" devices to DLT_RAW (they - * supply raw IP packets with no link-layer - * header) and "isdY" devices to a new DLT_I4L_IP - * type that has only an Ethernet packet type as - * a link-layer header. - * - * But sometimes we seem to get random crap - * in the link-layer header when capturing on - * ISDN devices.... - */ - handle->linktype = DLT_RAW; - } - break; - -#ifndef ARPHRD_CISCO -#define ARPHRD_CISCO 513 /* previously ARPHRD_HDLC */ -#endif - case ARPHRD_CISCO: - handle->linktype = DLT_C_HDLC; - break; - - /* Not sure if this is correct for all tunnels, but it - * works for CIPE */ - case ARPHRD_TUNNEL: -#ifndef ARPHRD_SIT -#define ARPHRD_SIT 776 /* From Linux 2.2.13 */ -#endif - case ARPHRD_SIT: - case ARPHRD_CSLIP: - case ARPHRD_SLIP6: - case ARPHRD_CSLIP6: - case ARPHRD_ADAPT: - case ARPHRD_SLIP: -#ifndef ARPHRD_RAWHDLC -#define ARPHRD_RAWHDLC 518 -#endif - case ARPHRD_RAWHDLC: -#ifndef ARPHRD_DLCI -#define ARPHRD_DLCI 15 -#endif - case ARPHRD_DLCI: - /* - * XXX - should some of those be mapped to DLT_LINUX_SLL - * instead? Should we just map all of them to DLT_LINUX_SLL? - */ - handle->linktype = DLT_RAW; - break; - -#ifndef ARPHRD_FRAD -#define ARPHRD_FRAD 770 -#endif - case ARPHRD_FRAD: - handle->linktype = DLT_FRELAY; - break; - - case ARPHRD_LOCALTLK: - handle->linktype = DLT_LTALK; - break; - -#ifndef ARPHRD_FCPP -#define ARPHRD_FCPP 784 -#endif - case ARPHRD_FCPP: -#ifndef ARPHRD_FCAL -#define ARPHRD_FCAL 785 -#endif - case ARPHRD_FCAL: -#ifndef ARPHRD_FCPL -#define ARPHRD_FCPL 786 -#endif - case ARPHRD_FCPL: -#ifndef ARPHRD_FCFABRIC -#define ARPHRD_FCFABRIC 787 -#endif - case ARPHRD_FCFABRIC: - /* - * We assume that those all mean RFC 2625 IP-over- - * Fibre Channel, with the RFC 2625 header at - * the beginning of the packet. - */ - handle->linktype = DLT_IP_OVER_FC; - break; - - case ARPHRD_IRDA: - /* Don't expect IP packet out of this interfaces... */ - handle->linktype = DLT_LINUX_IRDA; - /* We need to save packet direction for IrDA decoding, - * so let's use "Linux-cooked" mode. Jean II */ - //handle->md.cooked = 1; - break; - - default: - handle->linktype = -1; - break; - } -} - -/* ===== Functions to interface to the newer kernels ================== */ - -/* - * Try to open a packet socket using the new kernel interface. - * Returns 0 on failure. - * FIXME: 0 uses to mean success (Sebastian) - */ -static int -live_open_new(pcap_t *handle, const char *device, int promisc, - int to_ms, char *ebuf) -{ -#ifdef HAVE_PF_PACKET_SOCKETS - int sock_fd = -1, device_id, arptype; - int err; - int fatal_err = 0; - struct packet_mreq mr; - - /* One shot loop used for error handling - bail out with break */ - - do { - /* - * Open a socket with protocol family packet. If a device is - * given we try to open it in raw mode otherwise we use - * the cooked interface. - */ - sock_fd = device ? - socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)) - : socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_ALL)); - - if (sock_fd == -1) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "socket: %s", - pcap_strerror(errno) ); - break; - } - - /* It seems the kernel supports the new interface. */ - handle->md.sock_packet = 0; - - /* - * Get the interface index of the loopback device. - * If the attempt fails, don't fail, just set the - * "md.lo_ifindex" to -1. - * - * XXX - can there be more than one device that loops - * packets back, i.e. devices other than "lo"? If so, - * we'd need to find them all, and have an array of - * indices for them, and check all of them in - * "pcap_read_packet()". - */ - handle->md.lo_ifindex = iface_get_id(sock_fd, "lo", ebuf); - - /* - * Default value for offset to align link-layer payload - * on a 4-byte boundary. - */ - handle->offset = 0; - - /* - * What kind of frames do we have to deal with? Fall back - * to cooked mode if we have an unknown interface type. - */ - - if (device) { - /* Assume for now we don't need cooked mode. */ - handle->md.cooked = 0; - - arptype = iface_get_arptype(sock_fd, device, ebuf); - if (arptype == -1) { - fatal_err = 1; - break; - } - map_arphrd_to_dlt(handle, arptype, 1); - if (handle->linktype == -1 || - handle->linktype == DLT_LINUX_SLL || - handle->linktype == DLT_LINUX_IRDA || - (handle->linktype == DLT_EN10MB && - (strncmp("isdn", device, 4) == 0 || - strncmp("isdY", device, 4) == 0))) { - /* - * Unknown interface type (-1), or a - * device we explicitly chose to run - * in cooked mode (e.g., PPP devices), - * or an ISDN device (whose link-layer - * type we can only determine by using - * APIs that may be different on different - * kernels) - reopen in cooked mode. - */ - if (close(sock_fd) == -1) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, - "close: %s", pcap_strerror(errno)); - break; - } - sock_fd = socket(PF_PACKET, SOCK_DGRAM, - htons(ETH_P_ALL)); - if (sock_fd == -1) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, - "socket: %s", pcap_strerror(errno)); - break; - } - handle->md.cooked = 1; - - if (handle->linktype == -1) { - /* - * Warn that we're falling back on - * cooked mode; we may want to - * update "map_arphrd_to_dlt()" - * to handle the new type. - */ - snprintf(ebuf, PCAP_ERRBUF_SIZE, - "arptype %d not " - "supported by libpcap - " - "falling back to cooked " - "socket", - arptype); - } - /* IrDA capture is not a real "cooked" capture, - * it's IrLAP frames, not IP packets. */ - if(handle->linktype != DLT_LINUX_IRDA) - handle->linktype = DLT_LINUX_SLL; - } - - device_id = iface_get_id(sock_fd, device, ebuf); - if (device_id == -1) - break; - - if ((err = iface_bind(sock_fd, device_id, ebuf)) < 0) { - if (err == -2) - fatal_err = 1; - break; - } - } else { - /* - * This is cooked mode. - */ - handle->md.cooked = 1; - handle->linktype = DLT_LINUX_SLL; - - /* - * XXX - squelch GCC complaints about - * uninitialized variables; if we can't - * select promiscuous mode on all interfaces, - * we should move the code below into the - * "if (device)" branch of the "if" and - * get rid of the next statement. - */ - device_id = -1; - } - - /* - * Select promiscuous mode on if "promisc" is set. - * - * Do not turn allmulti mode on if we don't select - * promiscuous mode - on some devices (e.g., Orinoco - * wireless interfaces), allmulti mode isn't supported - * and the driver implements it by turning promiscuous - * mode on, and that screws up the operation of the - * card as a normal networking interface, and on no - * other platform I know of does starting a non- - * promiscuous capture affect which multicast packets - * are received by the interface. - */ - - /* - * Hmm, how can we set promiscuous mode on all interfaces? - * I am not sure if that is possible at all. - */ - - if (device && promisc) { - memset(&mr, 0, sizeof(mr)); - mr.mr_ifindex = device_id; - mr.mr_type = PACKET_MR_PROMISC; - if (setsockopt(sock_fd, SOL_PACKET, - PACKET_ADD_MEMBERSHIP, &mr, sizeof(mr)) == -1) - { - snprintf(ebuf, PCAP_ERRBUF_SIZE, - "setsockopt: %s", pcap_strerror(errno)); - break; - } - } - - /* Save the socket FD in the pcap structure */ - - handle->fd = sock_fd; - - return 1; - - } while(0); - - if (sock_fd != -1) - close(sock_fd); - - if (fatal_err) - return -2; - else - return 0; -#else - strncpy(ebuf, - "New packet capturing interface not supported by build " - "environment", PCAP_ERRBUF_SIZE); - return 0; -#endif -} - -#ifdef HAVE_PF_PACKET_SOCKETS -/* - * Return the index of the given device name. Fill ebuf and return - * -1 on failure. - */ -static int -iface_get_id(int fd, const char *device, char *ebuf) -{ - struct ifreq ifr; - - memset(&ifr, 0, sizeof(ifr)); - strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); - - if (ioctl(fd, SIOCGIFINDEX, &ifr) == -1) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, - "ioctl: %s", pcap_strerror(errno)); - return -1; - } - - return ifr.ifr_ifindex; -} - -/* - * Bind the socket associated with FD to the given device. - */ -static int -iface_bind(int fd, int ifindex, char *ebuf) -{ - struct sockaddr_ll sll; - int err; - socklen_t errlen = sizeof(err); - - memset(&sll, 0, sizeof(sll)); - sll.sll_family = AF_PACKET; - sll.sll_ifindex = ifindex; - sll.sll_protocol = htons(ETH_P_ALL); - - if (bind(fd, (struct sockaddr *) &sll, sizeof(sll)) == -1) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, - "bind: %s", pcap_strerror(errno)); - return -1; - } - - /* Any pending errors, e.g., network is down? */ - - if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &errlen) == -1) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, - "getsockopt: %s", pcap_strerror(errno)); - return -2; - } - - if (err > 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, - "bind: %s", pcap_strerror(err)); - return -2; - } - - return 0; -} - -#endif - - -/* ===== Functions to interface to the older kernels ================== */ - -/* - * With older kernels promiscuous mode is kind of interesting because we - * have to reset the interface before exiting. The problem can't really - * be solved without some daemon taking care of managing usage counts. - * If we put the interface into promiscuous mode, we set a flag indicating - * that we must take it out of that mode when the interface is closed, - * and, when closing the interface, if that flag is set we take it out - * of promiscuous mode. - */ - -/* - * List of pcaps for which we turned promiscuous mode on by hand. - * If there are any such pcaps, we arrange to call "pcap_close_all()" - * when we exit, and have it close all of them to turn promiscuous mode - * off. - */ -static struct pcap *pcaps_to_close; - -/* - * TRUE if we've already called "atexit()" to cause "pcap_close_all()" to - * be called on exit. - */ -static int did_atexit; - -static void pcap_close_all(void) -{ - struct pcap *handle; - - while ((handle = pcaps_to_close) != NULL) - pcap_close(handle); -} - -static void pcap_close_linux( pcap_t *handle ) -{ - struct pcap *p, *prevp; - struct ifreq ifr; - - if (handle->md.clear_promisc) { - /* - * We put the interface into promiscuous mode; take - * it out of promiscuous mode. - * - * XXX - if somebody else wants it in promiscuous mode, - * this code cannot know that, so it'll take it out - * of promiscuous mode. That's not fixable in 2.0[.x] - * kernels. - */ - memset(&ifr, 0, sizeof(ifr)); - strncpy(ifr.ifr_name, handle->md.device, sizeof(ifr.ifr_name)); - if (ioctl(handle->fd, SIOCGIFFLAGS, &ifr) == -1) { - fprintf(stderr, - "Can't restore interface flags (SIOCGIFFLAGS failed: %s).\n" - "Please adjust manually.\n" - "Hint: This can't happen with Linux >= 2.2.0.\n", - strerror(errno)); - } else { - if (ifr.ifr_flags & IFF_PROMISC) { - /* - * Promiscuous mode is currently on; turn it - * off. - */ - ifr.ifr_flags &= ~IFF_PROMISC; - if (ioctl(handle->fd, SIOCSIFFLAGS, &ifr) == -1) { - fprintf(stderr, - "Can't restore interface flags (SIOCSIFFLAGS failed: %s).\n" - "Please adjust manually.\n" - "Hint: This can't happen with Linux >= 2.2.0.\n", - strerror(errno)); - } - } - } - - /* - * Take this pcap out of the list of pcaps for which we - * have to take the interface out of promiscuous mode. - */ - for (p = pcaps_to_close, prevp = NULL; p != NULL; - prevp = p, p = p->md.next) { - if (p == handle) { - /* - * Found it. Remove it from the list. - */ - if (prevp == NULL) { - /* - * It was at the head of the list. - */ - pcaps_to_close = p->md.next; - } else { - /* - * It was in the middle of the list. - */ - prevp->md.next = p->md.next; - } - break; - } - } - } - - if (handle->md.device != NULL) - free(handle->md.device); - handle->md.device = NULL; - if (handle->buffer != NULL) - free(handle->buffer); - if (handle->fd >= 0) - close(handle->fd); -} - -/* - * Try to open a packet socket using the old kernel interface. - * Returns 0 on failure. - * FIXME: 0 uses to mean success (Sebastian) - */ -static int -live_open_old(pcap_t *handle, const char *device, int promisc, - int to_ms, char *ebuf) -{ - int arptype; - struct ifreq ifr; - - do { - /* Open the socket */ - - handle->fd = socket(PF_INET, SOCK_PACKET, htons(ETH_P_ALL)); - if (handle->fd == -1) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, - "socket: %s", pcap_strerror(errno)); - break; - } - - /* It worked - we are using the old interface */ - handle->md.sock_packet = 1; - - /* ...which means we get the link-layer header. */ - handle->md.cooked = 0; - - /* Bind to the given device */ - - if (!device) { - strncpy(ebuf, "pcap_open_live: The \"any\" device isn't supported on 2.0[.x]-kernel systems", - PCAP_ERRBUF_SIZE); - break; - } - if (iface_bind_old(handle->fd, device, ebuf) == -1) - break; - - /* - * Try to get the link-layer type. - */ - arptype = iface_get_arptype(handle->fd, device, ebuf); - if (arptype == -1) - break; - - /* - * Try to find the DLT_ type corresponding to that - * link-layer type. - */ - map_arphrd_to_dlt(handle, arptype, 0); - if (handle->linktype == -1) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, - "unknown arptype %d", arptype); - break; - } - - /* Go to promisc mode if requested */ - - if (promisc) { - memset(&ifr, 0, sizeof(ifr)); - strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); - if (ioctl(handle->fd, SIOCGIFFLAGS, &ifr) == -1) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, - "ioctl: %s", pcap_strerror(errno)); - break; - } - if ((ifr.ifr_flags & IFF_PROMISC) == 0) { - /* - * Promiscuous mode isn't currently on, - * so turn it on, and remember that - * we should turn it off when the - * pcap_t is closed. - */ - - /* - * If we haven't already done so, arrange - * to have "pcap_close_all()" called when - * we exit. - */ - if (!did_atexit) { - if (atexit(pcap_close_all) == -1) { - /* - * "atexit()" failed; don't - * put the interface in - * promiscuous mode, just - * give up. - */ - strncpy(ebuf, "atexit failed", - PCAP_ERRBUF_SIZE); - break; - } - did_atexit = 1; - } - - ifr.ifr_flags |= IFF_PROMISC; - if (ioctl(handle->fd, SIOCSIFFLAGS, &ifr) == -1) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, - "ioctl: %s", - pcap_strerror(errno)); - break; - } - handle->md.clear_promisc = 1; - - /* - * Add this to the list of pcaps - * to close when we exit. - */ - handle->md.next = pcaps_to_close; - pcaps_to_close = handle; - } - } - - /* - * Default value for offset to align link-layer payload - * on a 4-byte boundary. - */ - handle->offset = 0; - - return 1; - - } while (0); - - pcap_close_linux(handle); - return 0; -} - -/* - * Bind the socket associated with FD to the given device using the - * interface of the old kernels. - */ -static int -iface_bind_old(int fd, const char *device, char *ebuf) -{ - struct sockaddr saddr; - int err; - socklen_t errlen = sizeof(err); - - memset(&saddr, 0, sizeof(saddr)); - strncpy(saddr.sa_data, device, sizeof(saddr.sa_data)); - if (bind(fd, &saddr, sizeof(saddr)) == -1) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, - "bind: %s", pcap_strerror(errno)); - return -1; - } - - /* Any pending errors, e.g., network is down? */ - - if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &errlen) == -1) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, - "getsockopt: %s", pcap_strerror(errno)); - return -1; - } - - if (err > 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, - "bind: %s", pcap_strerror(err)); - return -1; - } - - return 0; -} - - -/* ===== System calls available on all supported kernels ============== */ - -/* - * Query the kernel for the MTU of the given interface. - */ -static int -iface_get_mtu(int fd, const char *device, char *ebuf) -{ - struct ifreq ifr; - - if (!device) - return BIGGER_THAN_ALL_MTUS; - - memset(&ifr, 0, sizeof(ifr)); - strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); - - if (ioctl(fd, SIOCGIFMTU, &ifr) == -1) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, - "ioctl: %s", pcap_strerror(errno)); - return -1; - } - - return ifr.ifr_mtu; -} - -/* - * Get the hardware type of the given interface as ARPHRD_xxx constant. - */ -static int -iface_get_arptype(int fd, const char *device, char *ebuf) -{ - struct ifreq ifr; - - memset(&ifr, 0, sizeof(ifr)); - strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); - - if (ioctl(fd, SIOCGIFHWADDR, &ifr) == -1) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, - "ioctl: %s", pcap_strerror(errno)); - return -1; - } - - return ifr.ifr_hwaddr.sa_family; -} - -#ifdef SO_ATTACH_FILTER -static int -fix_program(pcap_t *handle, struct sock_fprog *fcode) -{ - size_t prog_size; - register int i; - register struct bpf_insn *p; - struct bpf_insn *f; - int len; - - /* - * Make a copy of the filter, and modify that copy if - * necessary. - */ - prog_size = sizeof(*handle->fcode.bf_insns) * handle->fcode.bf_len; - len = handle->fcode.bf_len; - f = (struct bpf_insn *)malloc(prog_size); - if (f == NULL) { - snprintf(handle->errbuf, sizeof(handle->errbuf), - "malloc: %s", pcap_strerror(errno)); - return -1; - } - memcpy(f, handle->fcode.bf_insns, prog_size); - fcode->len = len; - fcode->filter = (struct sock_filter *) f; - - for (i = 0; i < len; ++i) { - p = &f[i]; - /* - * What type of instruction is this? - */ - switch (BPF_CLASS(p->code)) { - - case BPF_RET: - /* - * It's a return instruction; is the snapshot - * length a constant, rather than the contents - * of the accumulator? - */ - if (BPF_MODE(p->code) == BPF_K) { - /* - * Yes - if the value to be returned, - * i.e. the snapshot length, is anything - * other than 0, make it 65535, so that - * the packet is truncated by "recvfrom()", - * not by the filter. - * - * XXX - there's nothing we can easily do - * if it's getting the value from the - * accumulator; we'd have to insert - * code to force non-zero values to be - * 65535. - */ - if (p->k != 0) - p->k = 65535; - } - break; - - case BPF_LD: - case BPF_LDX: - /* - * It's a load instruction; is it loading - * from the packet? - */ - switch (BPF_MODE(p->code)) { - - case BPF_ABS: - case BPF_IND: - case BPF_MSH: - /* - * Yes; are we in cooked mode? - */ - if (handle->md.cooked) { - /* - * Yes, so we need to fix this - * instruction. - */ - if (fix_offset(p) < 0) { - /* - * We failed to do so. - * Return 0, so our caller - * knows to punt to userland. - */ - return 0; - } - } - break; - } - break; - } - } - return 1; /* we succeeded */ -} - -static int -fix_offset(struct bpf_insn *p) -{ - /* - * What's the offset? - */ - if (p->k >= SLL_HDR_LEN) { - /* - * It's within the link-layer payload; that starts at an - * offset of 0, as far as the kernel packet filter is - * concerned, so subtract the length of the link-layer - * header. - */ - p->k -= SLL_HDR_LEN; - } else if (p->k == 14) { - /* - * It's the protocol field; map it to the special magic - * kernel offset for that field. - */ - p->k = SKF_AD_OFF + SKF_AD_PROTOCOL; - } else { - /* - * It's within the header, but it's not one of those - * fields; we can't do that in the kernel, so punt - * to userland. - */ - return -1; - } - return 0; -} - -static int -set_kernel_filter(pcap_t *handle, struct sock_fprog *fcode) -{ - int total_filter_on = 0; - int save_mode; - int ret; - int save_errno; - - /* - * The socket filter code doesn't discard all packets queued - * up on the socket when the filter is changed; this means - * that packets that don't match the new filter may show up - * after the new filter is put onto the socket, if those - * packets haven't yet been read. - * - * This means, for example, that if you do a tcpdump capture - * with a filter, the first few packets in the capture might - * be packets that wouldn't have passed the filter. - * - * We therefore discard all packets queued up on the socket - * when setting a kernel filter. (This isn't an issue for - * userland filters, as the userland filtering is done after - * packets are queued up.) - * - * To flush those packets, we put the socket in read-only mode, - * and read packets from the socket until there are no more to - * read. - * - * In order to keep that from being an infinite loop - i.e., - * to keep more packets from arriving while we're draining - * the queue - we put the "total filter", which is a filter - * that rejects all packets, onto the socket before draining - * the queue. - * - * This code deliberately ignores any errors, so that you may - * get bogus packets if an error occurs, rather than having - * the filtering done in userland even if it could have been - * done in the kernel. - */ - if (setsockopt(handle->fd, SOL_SOCKET, SO_ATTACH_FILTER, - &total_fcode, sizeof(total_fcode)) == 0) { - char drain[1]; - - /* - * Note that we've put the total filter onto the socket. - */ - total_filter_on = 1; - - /* - * Save the socket's current mode, and put it in - * non-blocking mode; we drain it by reading packets - * until we get an error (which is normally a - * "nothing more to be read" error). - */ - save_mode = fcntl(handle->fd, F_GETFL, 0); - if (save_mode != -1 && - fcntl(handle->fd, F_SETFL, save_mode | O_NONBLOCK) >= 0) { - while (recv(handle->fd, &drain, sizeof drain, - MSG_TRUNC) >= 0) - ; - save_errno = errno; - fcntl(handle->fd, F_SETFL, save_mode); - if (save_errno != EAGAIN) { - /* Fatal error */ - reset_kernel_filter(handle); - snprintf(handle->errbuf, sizeof(handle->errbuf), - "recv: %s", pcap_strerror(save_errno)); - return -2; - } - } - } - - /* - * Now attach the new filter. - */ - ret = setsockopt(handle->fd, SOL_SOCKET, SO_ATTACH_FILTER, - fcode, sizeof(*fcode)); - if (ret == -1 && total_filter_on) { - /* - * Well, we couldn't set that filter on the socket, - * but we could set the total filter on the socket. - * - * This could, for example, mean that the filter was - * too big to put into the kernel, so we'll have to - * filter in userland; in any case, we'll be doing - * filtering in userland, so we need to remove the - * total filter so we see packets. - */ - save_errno = errno; - - /* - * XXX - if this fails, we're really screwed; - * we have the total filter on the socket, - * and it won't come off. What do we do then? - */ - reset_kernel_filter(handle); - - errno = save_errno; - } - return ret; -} - -static int -reset_kernel_filter(pcap_t *handle) -{ - /* setsockopt() barfs unless it get a dummy parameter */ - int dummy; - - return setsockopt(handle->fd, SOL_SOCKET, SO_DETACH_FILTER, - &dummy, sizeof(dummy)); -} -#endif diff --git a/contrib/libpcap-0.8.3/pcap-namedb.h b/contrib/libpcap-0.8.3/pcap-namedb.h deleted file mode 100644 index 4833c4da00..0000000000 --- a/contrib/libpcap-0.8.3/pcap-namedb.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 1994, 1996 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the Computer Systems - * Engineering Group at Lawrence Berkeley Laboratory. - * 4. Neither the name of the University nor of the Laboratory may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#) $Header: /tcpdump/master/libpcap/pcap-namedb.h,v 1.8 2000/07/29 07:36:43 guy Exp $ (LBL) - */ - -#ifndef lib_pcap_ethers_h -#define lib_pcap_ethers_h - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * As returned by the pcap_next_etherent() - * XXX this stuff doesn't belong in this interface, but this - * library already must do name to address translation, so - * on systems that don't have support for /etc/ethers, we - * export these hooks since they'll - */ -struct pcap_etherent { - u_char addr[6]; - char name[122]; -}; -#ifndef PCAP_ETHERS_FILE -#define PCAP_ETHERS_FILE "/etc/ethers" -#endif -struct pcap_etherent *pcap_next_etherent(FILE *); -u_char *pcap_ether_hostton(const char*); -u_char *pcap_ether_aton(const char *); - -bpf_u_int32 **pcap_nametoaddr(const char *); -#ifdef INET6 -struct addrinfo *pcap_nametoaddrinfo(const char *); -#endif -bpf_u_int32 pcap_nametonetaddr(const char *); - -int pcap_nametoport(const char *, int *, int *); -int pcap_nametoproto(const char *); -int pcap_nametoeproto(const char *); -/* - * If a protocol is unknown, PROTO_UNDEF is returned. - * Also, pcap_nametoport() returns the protocol along with the port number. - * If there are ambiguous entried in /etc/services (i.e. domain - * can be either tcp or udp) PROTO_UNDEF is returned. - */ -#define PROTO_UNDEF -1 - -/* XXX move these to pcap-int.h? */ -int __pcap_atodn(const char *, bpf_u_int32 *); -int __pcap_atoin(const char *, bpf_u_int32 *); -u_short __pcap_nametodnaddr(const char *); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/contrib/libpcap-0.8.3/pcap-nit.c b/contrib/libpcap-0.8.3/pcap-nit.c deleted file mode 100644 index 86aad0ffe8..0000000000 --- a/contrib/libpcap-0.8.3/pcap-nit.c +++ /dev/null @@ -1,308 +0,0 @@ -/* - * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that: (1) source code distributions - * retain the above copyright notice and this paragraph in its entirety, (2) - * distributions including binary code include the above copyright notice and - * this paragraph in its entirety in the documentation or other materials - * provided with the distribution, and (3) all advertising materials mentioning - * features or use of this software display the following acknowledgement: - * ``This product includes software developed by the University of California, - * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of - * the University nor the names of its contributors may be used to endorse - * or promote products derived from this software without specific prior - * written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ -#ifndef lint -static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/libpcap/pcap-nit.c,v 1.50.2.4 2004/03/21 08:33:23 guy Exp $ (LBL)"; -#endif - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "pcap-int.h" - -#ifdef HAVE_OS_PROTO_H -#include "os-proto.h" -#endif - -/* - * The chunk size for NIT. This is the amount of buffering - * done for read calls. - */ -#define CHUNKSIZE (2*1024) - -/* - * The total buffer space used by NIT. - */ -#define BUFSPACE (4*CHUNKSIZE) - -/* Forwards */ -static int nit_setflags(int, int, int, char *); - -static int -pcap_stats_nit(pcap_t *p, struct pcap_stat *ps) -{ - - /* - * "ps_recv" counts packets handed to the filter, not packets - * that passed the filter. As filtering is done in userland, - * this does not include packets dropped because we ran out - * of buffer space. - * - * "ps_drop" presumably counts packets dropped by the socket - * because of flow control requirements or resource exhaustion; - * it doesn't count packets dropped by the interface driver. - * As filtering is done in userland, it counts packets regardless - * of whether they would've passed the filter. - * - * These statistics don't include packets not yet read from the - * kernel by libpcap or packets not yet read from libpcap by the - * application. - */ - *ps = p->md.stat; - return (0); -} - -static int -pcap_read_nit(pcap_t *p, int cnt, pcap_handler callback, u_char *user) -{ - register int cc, n; - register struct bpf_insn *fcode = p->fcode.bf_insns; - register u_char *bp, *cp, *ep; - register struct nit_hdr *nh; - register int caplen; - - cc = p->cc; - if (cc == 0) { - cc = read(p->fd, (char *)p->buffer, p->bufsize); - if (cc < 0) { - if (errno == EWOULDBLOCK) - return (0); - snprintf(p->errbuf, sizeof(p->errbuf), "pcap_read: %s", - pcap_strerror(errno)); - return (-1); - } - bp = p->buffer; - } else - bp = p->bp; - - /* - * Loop through each packet. The increment expression - * rounds up to the next int boundary past the end of - * the previous packet. - */ - n = 0; - ep = bp + cc; - while (bp < ep) { - /* - * Has "pcap_breakloop()" been called? - * If so, return immediately - if we haven't read any - * packets, clear the flag and return -2 to indicate - * that we were told to break out of the loop, otherwise - * leave the flag set, so that the *next* call will break - * out of the loop without having read any packets, and - * return the number of packets we've processed so far. - */ - if (p->break_loop) { - if (n == 0) { - p->break_loop = 0; - return (-2); - } else { - p->cc = ep - bp; - p->bp = bp; - return (n); - } - } - - nh = (struct nit_hdr *)bp; - cp = bp + sizeof(*nh); - - switch (nh->nh_state) { - - case NIT_CATCH: - break; - - case NIT_NOMBUF: - case NIT_NOCLUSTER: - case NIT_NOSPACE: - p->md.stat.ps_drop = nh->nh_dropped; - continue; - - case NIT_SEQNO: - continue; - - default: - snprintf(p->errbuf, sizeof(p->errbuf), - "bad nit state %d", nh->nh_state); - return (-1); - } - ++p->md.stat.ps_recv; - bp += ((sizeof(struct nit_hdr) + nh->nh_datalen + - sizeof(int) - 1) & ~(sizeof(int) - 1)); - - caplen = nh->nh_wirelen; - if (caplen > p->snapshot) - caplen = p->snapshot; - if (bpf_filter(fcode, cp, nh->nh_wirelen, caplen)) { - struct pcap_pkthdr h; - h.ts = nh->nh_timestamp; - h.len = nh->nh_wirelen; - h.caplen = caplen; - (*callback)(user, &h, cp); - if (++n >= cnt && cnt >= 0) { - p->cc = ep - bp; - p->bp = bp; - return (n); - } - } - } - p->cc = 0; - return (n); -} - -static int -nit_setflags(int fd, int promisc, int to_ms, char *ebuf) -{ - struct nit_ioc nioc; - - memset(&nioc, 0, sizeof(nioc)); - nioc.nioc_bufspace = BUFSPACE; - nioc.nioc_chunksize = CHUNKSIZE; - nioc.nioc_typetomatch = NT_ALLTYPES; - nioc.nioc_snaplen = p->snapshot; - nioc.nioc_bufalign = sizeof(int); - nioc.nioc_bufoffset = 0; - - if (to_ms != 0) { - nioc.nioc_flags |= NF_TIMEOUT; - nioc.nioc_timeout.tv_sec = to_ms / 1000; - nioc.nioc_timeout.tv_usec = (to_ms * 1000) % 1000000; - } - if (promisc) - nioc.nioc_flags |= NF_PROMISC; - - if (ioctl(fd, SIOCSNIT, &nioc) < 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "SIOCSNIT: %s", - pcap_strerror(errno)); - return (-1); - } - return (0); -} - -static void -pcap_close_nit(pcap_t *p) -{ - if (p->buffer != NULL) - free(p->buffer); - if (p->fd >= 0) - close(p->fd); -} - -pcap_t * -pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, - char *ebuf) -{ - int fd; - struct sockaddr_nit snit; - register pcap_t *p; - - p = (pcap_t *)malloc(sizeof(*p)); - if (p == NULL) { - strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE); - return (NULL); - } - - if (snaplen < 96) - /* - * NIT requires a snapshot length of at least 96. - */ - snaplen = 96; - - memset(p, 0, sizeof(*p)); - p->fd = fd = socket(AF_NIT, SOCK_RAW, NITPROTO_RAW); - if (fd < 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, - "socket: %s", pcap_strerror(errno)); - goto bad; - } - snit.snit_family = AF_NIT; - (void)strncpy(snit.snit_ifname, device, NITIFSIZ); - - if (bind(fd, (struct sockaddr *)&snit, sizeof(snit))) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, - "bind: %s: %s", snit.snit_ifname, pcap_strerror(errno)); - goto bad; - } - p->snapshot = snaplen; - nit_setflags(p->fd, promisc, to_ms, ebuf); - - /* - * NIT supports only ethernets. - */ - p->linktype = DLT_EN10MB; - - p->bufsize = BUFSPACE; - p->buffer = (u_char *)malloc(p->bufsize); - if (p->buffer == NULL) { - strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE); - goto bad; - } - - /* - * "p->fd" is a socket, so "select()" should work on it. - */ - p->selectable_fd = p->fd; - - p->read_op = pcap_read_nit; - p->setfilter_op = install_bpf_program; /* no kernel filtering */ - p->set_datalink_op = NULL; /* can't change data link type */ - p->getnonblock_op = pcap_getnonblock_fd; - p->setnonblock_op = pcap_setnonblock_fd; - p->stats_op = pcap_stats_nit; - p->close_op = pcap_close_nit; - - return (p); - bad: - if (fd >= 0) - close(fd); - free(p); - return (NULL); -} - -int -pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf) -{ - return (0); -} diff --git a/contrib/libpcap-0.8.3/pcap-nit.h b/contrib/libpcap-0.8.3/pcap-nit.h deleted file mode 100644 index 52f5fc4bd2..0000000000 --- a/contrib/libpcap-0.8.3/pcap-nit.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (c) 1990, 1994 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by the University of California, Lawrence Berkeley Laboratory, - * Berkeley, CA. The name of the University may not be used to - * endorse or promote products derived from this software without - * specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * @(#) $Header: /tcpdump/master/libpcap/pcap-nit.h,v 1.2.1.1 1999/10/07 23:46:40 mcr Exp $ (LBL) - */ diff --git a/contrib/libpcap-0.8.3/pcap-null.c b/contrib/libpcap-0.8.3/pcap-null.c deleted file mode 100644 index a4dd72f3f2..0000000000 --- a/contrib/libpcap-0.8.3/pcap-null.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 1994, 1995, 1996 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that: (1) source code distributions - * retain the above copyright notice and this paragraph in its entirety, (2) - * distributions including binary code include the above copyright notice and - * this paragraph in its entirety in the documentation or other materials - * provided with the distribution, and (3) all advertising materials mentioning - * features or use of this software display the following acknowledgement: - * ``This product includes software developed by the University of California, - * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of - * the University nor the names of its contributors may be used to endorse - * or promote products derived from this software without specific prior - * written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ -#ifndef lint -static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/libpcap/pcap-null.c,v 1.20.2.1 2003/11/15 23:26:45 guy Exp $ (LBL)"; -#endif - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include /* optionally get BSD define */ - -#include - -#ifdef HAVE_OS_PROTO_H -#include "os-proto.h" -#endif - -#include "pcap-int.h" - -static char nosup[] = "live packet capture not supported on this system"; - -pcap_t * -pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, - char *ebuf) -{ - (void)strlcpy(ebuf, nosup, PCAP_ERRBUF_SIZE); - return (NULL); -} - -int -pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf) -{ - return (0); -} diff --git a/contrib/libpcap-0.8.3/pcap-pf.c b/contrib/libpcap-0.8.3/pcap-pf.c deleted file mode 100644 index e84d1c7db1..0000000000 --- a/contrib/libpcap-0.8.3/pcap-pf.c +++ /dev/null @@ -1,538 +0,0 @@ -/* - * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that: (1) source code distributions - * retain the above copyright notice and this paragraph in its entirety, (2) - * distributions including binary code include the above copyright notice and - * this paragraph in its entirety in the documentation or other materials - * provided with the distribution, and (3) all advertising materials mentioning - * features or use of this software display the following acknowledgement: - * ``This product includes software developed by the University of California, - * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of - * the University nor the names of its contributors may be used to endorse - * or promote products derived from this software without specific prior - * written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * packet filter subroutines for tcpdump - * Extraction/creation by Jeffrey Mogul, DECWRL - */ - -#ifndef lint -static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/libpcap/pcap-pf.c,v 1.79.2.5 2003/11/22 00:32:55 guy Exp $ (LBL)"; -#endif - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#include -#include -#include -#include - -struct mbuf; -struct rtentry; -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -/* - * Make "pcap.h" not include "pcap-bpf.h"; we are going to include the - * native OS version, as we need various BPF ioctls from it. - */ -#define PCAP_DONT_INCLUDE_PCAP_BPF_H -#include - -#include "pcap-int.h" - -#ifdef HAVE_OS_PROTO_H -#include "os-proto.h" -#endif - -static int pcap_setfilter_pf(pcap_t *, struct bpf_program *); - -/* - * BUFSPACE is the size in bytes of the packet read buffer. Most tcpdump - * applications aren't going to need more than 200 bytes of packet header - * and the read shouldn't return more packets than packetfilter's internal - * queue limit (bounded at 256). - */ -#define BUFSPACE (200 * 256) - -static int -pcap_read_pf(pcap_t *pc, int cnt, pcap_handler callback, u_char *user) -{ - register u_char *p, *bp; - struct bpf_insn *fcode; - register int cc, n, buflen, inc; - register struct enstamp *sp; -#ifdef LBL_ALIGN - struct enstamp stamp; -#endif -#ifdef PCAP_FDDIPAD - register int pad; -#endif - - fcode = pc->md.use_bpf ? NULL : pc->fcode.bf_insns; - again: - cc = pc->cc; - if (cc == 0) { - cc = read(pc->fd, (char *)pc->buffer + pc->offset, pc->bufsize); - if (cc < 0) { - if (errno == EWOULDBLOCK) - return (0); - if (errno == EINVAL && - lseek(pc->fd, 0L, SEEK_CUR) + pc->bufsize < 0) { - /* - * Due to a kernel bug, after 2^31 bytes, - * the kernel file offset overflows and - * read fails with EINVAL. The lseek() - * to 0 will fix things. - */ - (void)lseek(pc->fd, 0L, SEEK_SET); - goto again; - } - snprintf(pc->errbuf, sizeof(pc->errbuf), "pf read: %s", - pcap_strerror(errno)); - return (-1); - } - bp = pc->buffer + pc->offset; - } else - bp = pc->bp; - /* - * Loop through each packet. - */ - n = 0; -#ifdef PCAP_FDDIPAD - if (pc->linktype == DLT_FDDI) - pad = pcap_fddipad; - else - pad = 0; -#endif - while (cc > 0) { - /* - * Has "pcap_breakloop()" been called? - * If so, return immediately - if we haven't read any - * packets, clear the flag and return -2 to indicate - * that we were told to break out of the loop, otherwise - * leave the flag set, so that the *next* call will break - * out of the loop without having read any packets, and - * return the number of packets we've processed so far. - */ - if (pc->break_loop) { - if (n == 0) { - pc->break_loop = 0; - return (-2); - } else { - pc->cc = cc; - pc->bp = bp; - return (n); - } - } - if (cc < sizeof(*sp)) { - snprintf(pc->errbuf, sizeof(pc->errbuf), - "pf short read (%d)", cc); - return (-1); - } -#ifdef LBL_ALIGN - if ((long)bp & 3) { - sp = &stamp; - memcpy((char *)sp, (char *)bp, sizeof(*sp)); - } else -#endif - sp = (struct enstamp *)bp; - if (sp->ens_stamplen != sizeof(*sp)) { - snprintf(pc->errbuf, sizeof(pc->errbuf), - "pf short stamplen (%d)", - sp->ens_stamplen); - return (-1); - } - - p = bp + sp->ens_stamplen; - buflen = sp->ens_count; - if (buflen > pc->snapshot) - buflen = pc->snapshot; - - /* Calculate inc before possible pad update */ - inc = ENALIGN(buflen + sp->ens_stamplen); - cc -= inc; - bp += inc; -#ifdef PCAP_FDDIPAD - p += pad; - buflen -= pad; -#endif - pc->md.TotPkts++; - pc->md.TotDrops += sp->ens_dropped; - pc->md.TotMissed = sp->ens_ifoverflows; - if (pc->md.OrigMissed < 0) - pc->md.OrigMissed = pc->md.TotMissed; - - /* - * Short-circuit evaluation: if using BPF filter - * in kernel, no need to do it now. - */ - if (fcode == NULL || - bpf_filter(fcode, p, sp->ens_count, buflen)) { - struct pcap_pkthdr h; - pc->md.TotAccepted++; - h.ts = sp->ens_tstamp; -#ifdef PCAP_FDDIPAD - h.len = sp->ens_count - pad; -#else - h.len = sp->ens_count; -#endif - h.caplen = buflen; - (*callback)(user, &h, p); - if (++n >= cnt && cnt > 0) { - pc->cc = cc; - pc->bp = bp; - return (n); - } - } - } - pc->cc = 0; - return (n); -} - -static int -pcap_stats_pf(pcap_t *p, struct pcap_stat *ps) -{ - - /* - * If packet filtering is being done in the kernel: - * - * "ps_recv" counts only packets that passed the filter. - * This does not include packets dropped because we - * ran out of buffer space. (XXX - perhaps it should, - * by adding "ps_drop" to "ps_recv", for compatibility - * with some other platforms. On the other hand, on - * some platforms "ps_recv" counts only packets that - * passed the filter, and on others it counts packets - * that didn't pass the filter....) - * - * "ps_drop" counts packets that passed the kernel filter - * (if any) but were dropped because the input queue was - * full. - * - * "ps_ifdrop" counts packets dropped by the network - * inteface (regardless of whether they would have passed - * the input filter, of course). - * - * If packet filtering is not being done in the kernel: - * - * "ps_recv" counts only packets that passed the filter. - * - * "ps_drop" counts packets that were dropped because the - * input queue was full, regardless of whether they passed - * the userland filter. - * - * "ps_ifdrop" counts packets dropped by the network - * inteface (regardless of whether they would have passed - * the input filter, of course). - * - * These statistics don't include packets not yet read from - * the kernel by libpcap, but they may include packets not - * yet read from libpcap by the application. - */ - ps->ps_recv = p->md.TotAccepted; - ps->ps_drop = p->md.TotDrops; - ps->ps_ifdrop = p->md.TotMissed - p->md.OrigMissed; - return (0); -} - -static void -pcap_close_pf(pcap_t *p) -{ - if (p->buffer != NULL) - free(p->buffer); - if (p->fd >= 0) - close(p->fd); -} - -pcap_t * -pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, - char *ebuf) -{ - pcap_t *p; - short enmode; - int backlog = -1; /* request the most */ - struct enfilter Filter; - struct endevp devparams; - - p = (pcap_t *)malloc(sizeof(*p)); - if (p == NULL) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, - "pcap_open_live: %s", pcap_strerror(errno)); - return (0); - } - memset(p, 0, sizeof(*p)); - - /* - * XXX - we assume here that "pfopen()" does not, in fact, modify - * its argument, even though it takes a "char *" rather than a - * "const char *" as its first argument. That appears to be - * the case, at least on Digital UNIX 4.0. - */ - p->fd = pfopen(device, O_RDONLY); - if (p->fd < 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "pf open: %s: %s\n\ -your system may not be properly configured; see the packetfilter(4) man page\n", - device, pcap_strerror(errno)); - goto bad; - } - p->md.OrigMissed = -1; - enmode = ENTSTAMP|ENBATCH|ENNONEXCL; - if (promisc) - enmode |= ENPROMISC; - if (ioctl(p->fd, EIOCMBIS, (caddr_t)&enmode) < 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "EIOCMBIS: %s", - pcap_strerror(errno)); - goto bad; - } -#ifdef ENCOPYALL - /* Try to set COPYALL mode so that we see packets to ourself */ - enmode = ENCOPYALL; - (void)ioctl(p->fd, EIOCMBIS, (caddr_t)&enmode);/* OK if this fails */ -#endif - /* set the backlog */ - if (ioctl(p->fd, EIOCSETW, (caddr_t)&backlog) < 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "EIOCSETW: %s", - pcap_strerror(errno)); - goto bad; - } - /* discover interface type */ - if (ioctl(p->fd, EIOCDEVP, (caddr_t)&devparams) < 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "EIOCDEVP: %s", - pcap_strerror(errno)); - goto bad; - } - /* HACK: to compile prior to Ultrix 4.2 */ -#ifndef ENDT_FDDI -#define ENDT_FDDI 4 -#endif - switch (devparams.end_dev_type) { - - case ENDT_10MB: - p->linktype = DLT_EN10MB; - p->offset = 2; - break; - - case ENDT_FDDI: - p->linktype = DLT_FDDI; - break; - -#ifdef ENDT_SLIP - case ENDT_SLIP: - p->linktype = DLT_SLIP; - break; -#endif - -#ifdef ENDT_PPP - case ENDT_PPP: - p->linktype = DLT_PPP; - break; -#endif - -#ifdef ENDT_LOOPBACK - case ENDT_LOOPBACK: - /* - * It appears to use Ethernet framing, at least on - * Digital UNIX 4.0. - */ - p->linktype = DLT_EN10MB; - p->offset = 2; - break; -#endif - -#ifdef ENDT_TRN - case ENDT_TRN: - p->linktype = DLT_IEEE802; - break; -#endif - - default: - /* - * XXX - what about ENDT_IEEE802? The pfilt.h header - * file calls this "IEEE 802 networks (non-Ethernet)", - * but that doesn't specify a specific link layer type; - * it could be 802.4, or 802.5 (except that 802.5 is - * ENDT_TRN), or 802.6, or 802.11, or.... That's why - * DLT_IEEE802 was hijacked to mean Token Ring in various - * BSDs, and why we went along with that hijacking. - * - * XXX - what about ENDT_HDLC and ENDT_NULL? - * Presumably, as ENDT_OTHER is just "Miscellaneous - * framing", there's not much we can do, as that - * doesn't specify a particular type of header. - */ - snprintf(ebuf, PCAP_ERRBUF_SIZE, "unknown data-link type %u", - devparams.end_dev_type); - goto bad; - } - /* set truncation */ -#ifdef PCAP_FDDIPAD - if (p->linktype == DLT_FDDI) - /* packetfilter includes the padding in the snapshot */ - snaplen += pcap_fddipad; -#endif - if (ioctl(p->fd, EIOCTRUNCATE, (caddr_t)&snaplen) < 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "EIOCTRUNCATE: %s", - pcap_strerror(errno)); - goto bad; - } - p->snapshot = snaplen; - /* accept all packets */ - memset(&Filter, 0, sizeof(Filter)); - Filter.enf_Priority = 37; /* anything > 2 */ - Filter.enf_FilterLen = 0; /* means "always true" */ - if (ioctl(p->fd, EIOCSETF, (caddr_t)&Filter) < 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "EIOCSETF: %s", - pcap_strerror(errno)); - goto bad; - } - - if (to_ms != 0) { - struct timeval timeout; - timeout.tv_sec = to_ms / 1000; - timeout.tv_usec = (to_ms * 1000) % 1000000; - if (ioctl(p->fd, EIOCSRTIMEOUT, (caddr_t)&timeout) < 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "EIOCSRTIMEOUT: %s", - pcap_strerror(errno)); - goto bad; - } - } - - p->bufsize = BUFSPACE; - p->buffer = (u_char*)malloc(p->bufsize + p->offset); - if (p->buffer == NULL) { - strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE); - goto bad; - } - - /* - * "select()" and "poll()" work on packetfilter devices. - */ - p->selectable_fd = p->fd; - - p->read_op = pcap_read_pf; - p->setfilter_op = pcap_setfilter_pf; - p->set_datalink_op = NULL; /* can't change data link type */ - p->getnonblock_op = pcap_getnonblock_fd; - p->setnonblock_op = pcap_setnonblock_fd; - p->stats_op = pcap_stats_pf; - p->close_op = pcap_close_pf; - - return (p); - bad: - if (p->fd >= 0) - close(p->fd); - free(p); - return (NULL); -} - -int -pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf) -{ - return (0); -} - -static int -pcap_setfilter_pf(pcap_t *p, struct bpf_program *fp) -{ - struct bpf_version bv; - - /* - * See if BIOCVERSION works. If not, we assume the kernel doesn't - * support BPF-style filters (it's not documented in the bpf(7) - * or packetfiler(7) man pages, but the code used to fail if - * BIOCSETF worked but BIOCVERSION didn't, and I've seen it do - * kernel filtering in DU 4.0, so presumably BIOCVERSION works - * there, at least). - */ - if (ioctl(p->fd, BIOCVERSION, (caddr_t)&bv) >= 0) { - /* - * OK, we have the version of the BPF interpreter; - * is it the same major version as us, and the same - * or better minor version? - */ - if (bv.bv_major == BPF_MAJOR_VERSION && - bv.bv_minor >= BPF_MINOR_VERSION) { - /* - * Yes. Try to install the filter. - */ - if (ioctl(p->fd, BIOCSETF, (caddr_t)fp) < 0) { - snprintf(p->errbuf, sizeof(p->errbuf), - "BIOCSETF: %s", pcap_strerror(errno)); - return (-1); - } - - /* - * OK, that succeeded. We're doing filtering in - * the kernel. (We assume we don't have a - * userland filter installed - that'd require - * a previous version check to have failed but - * this one to succeed.) - * - * XXX - this message should be supplied to the - * application as a warning of some sort, - * except that if it's a GUI application, it's - * not clear that it should be displayed in - * a window to annoy the user. - */ - fprintf(stderr, "tcpdump: Using kernel BPF filter\n"); - p->md.use_bpf = 1; - return (0); - } - - /* - * We can't use the kernel's BPF interpreter; don't give - * up, just log a message and be inefficient. - * - * XXX - this should really be supplied to the application - * as a warning of some sort. - */ - fprintf(stderr, - "tcpdump: Requires BPF language %d.%d or higher; kernel is %d.%d\n", - BPF_MAJOR_VERSION, BPF_MINOR_VERSION, - bv.bv_major, bv.bv_minor); - } - - /* - * We couldn't do filtering in the kernel; do it in userland. - */ - if (install_bpf_program(p, fp) < 0) - return (-1); - - /* - * XXX - this message should be supplied by the application as - * a warning of some sort. - */ - fprintf(stderr, "tcpdump: Filtering in user process\n"); - p->md.use_bpf = 0; - return (0); -} diff --git a/contrib/libpcap-0.8.3/pcap-pf.h b/contrib/libpcap-0.8.3/pcap-pf.h deleted file mode 100644 index 60bea83a72..0000000000 --- a/contrib/libpcap-0.8.3/pcap-pf.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (c) 1990, 1994 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by the University of California, Lawrence Berkeley Laboratory, - * Berkeley, CA. The name of the University may not be used to - * endorse or promote products derived from this software without - * specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * @(#) $Header: /tcpdump/master/libpcap/pcap-pf.h,v 1.2.1.1 1999/10/07 23:46:40 mcr Exp $ (LBL) - */ diff --git a/contrib/libpcap-0.8.3/pcap-snit.c b/contrib/libpcap-0.8.3/pcap-snit.c deleted file mode 100644 index d022dd3e79..0000000000 --- a/contrib/libpcap-0.8.3/pcap-snit.c +++ /dev/null @@ -1,367 +0,0 @@ -/* - * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that: (1) source code distributions - * retain the above copyright notice and this paragraph in its entirety, (2) - * distributions including binary code include the above copyright notice and - * this paragraph in its entirety in the documentation or other materials - * provided with the distribution, and (3) all advertising materials mentioning - * features or use of this software display the following acknowledgement: - * ``This product includes software developed by the University of California, - * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of - * the University nor the names of its contributors may be used to endorse - * or promote products derived from this software without specific prior - * written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * Modifications made to accommodate the new SunOS4.0 NIT facility by - * Micky Liu, micky@cunixc.cc.columbia.edu, Columbia University in May, 1989. - * This module now handles the STREAMS based NIT. - */ - -#ifndef lint -static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/libpcap/pcap-snit.c,v 1.66.2.3 2003/11/21 10:20:48 guy Exp $ (LBL)"; -#endif - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "pcap-int.h" - -#ifdef HAVE_OS_PROTO_H -#include "os-proto.h" -#endif - -/* - * The chunk size for NIT. This is the amount of buffering - * done for read calls. - */ -#define CHUNKSIZE (2*1024) - -/* - * The total buffer space used by NIT. - */ -#define BUFSPACE (4*CHUNKSIZE) - -/* Forwards */ -static int nit_setflags(int, int, int, char *); - -static int -pcap_stats_snit(pcap_t *p, struct pcap_stat *ps) -{ - - /* - * "ps_recv" counts packets handed to the filter, not packets - * that passed the filter. As filtering is done in userland, - * this does not include packets dropped because we ran out - * of buffer space. - * - * "ps_drop" counts packets dropped inside the "/dev/nit" - * device because of flow control requirements or resource - * exhaustion; it doesn't count packets dropped by the - * interface driver, or packets dropped upstream. As filtering - * is done in userland, it counts packets regardless of whether - * they would've passed the filter. - * - * These statistics don't include packets not yet read from the - * kernel by libpcap or packets not yet read from libpcap by the - * application. - */ - *ps = p->md.stat; - return (0); -} - -static int -pcap_read_snit(pcap_t *p, int cnt, pcap_handler callback, u_char *user) -{ - register int cc, n; - register struct bpf_insn *fcode = p->fcode.bf_insns; - register u_char *bp, *cp, *ep; - register struct nit_bufhdr *hdrp; - register struct nit_iftime *ntp; - register struct nit_iflen *nlp; - register struct nit_ifdrops *ndp; - register int caplen; - - cc = p->cc; - if (cc == 0) { - cc = read(p->fd, (char *)p->buffer, p->bufsize); - if (cc < 0) { - if (errno == EWOULDBLOCK) - return (0); - snprintf(p->errbuf, sizeof(p->errbuf), "pcap_read: %s", - pcap_strerror(errno)); - return (-1); - } - bp = p->buffer; - } else - bp = p->bp; - - /* - * loop through each snapshot in the chunk - */ - n = 0; - ep = bp + cc; - while (bp < ep) { - /* - * Has "pcap_breakloop()" been called? - * If so, return immediately - if we haven't read any - * packets, clear the flag and return -2 to indicate - * that we were told to break out of the loop, otherwise - * leave the flag set, so that the *next* call will break - * out of the loop without having read any packets, and - * return the number of packets we've processed so far. - */ - if (p->break_loop) { - if (n == 0) { - p->break_loop = 0; - return (-2); - } else { - p->bp = bp; - p->cc = ep - bp; - return (n); - } - } - - ++p->md.stat.ps_recv; - cp = bp; - - /* get past NIT buffer */ - hdrp = (struct nit_bufhdr *)cp; - cp += sizeof(*hdrp); - - /* get past NIT timer */ - ntp = (struct nit_iftime *)cp; - cp += sizeof(*ntp); - - ndp = (struct nit_ifdrops *)cp; - p->md.stat.ps_drop = ndp->nh_drops; - cp += sizeof *ndp; - - /* get past packet len */ - nlp = (struct nit_iflen *)cp; - cp += sizeof(*nlp); - - /* next snapshot */ - bp += hdrp->nhb_totlen; - - caplen = nlp->nh_pktlen; - if (caplen > p->snapshot) - caplen = p->snapshot; - - if (bpf_filter(fcode, cp, nlp->nh_pktlen, caplen)) { - struct pcap_pkthdr h; - h.ts = ntp->nh_timestamp; - h.len = nlp->nh_pktlen; - h.caplen = caplen; - (*callback)(user, &h, cp); - if (++n >= cnt && cnt >= 0) { - p->cc = ep - bp; - p->bp = bp; - return (n); - } - } - } - p->cc = 0; - return (n); -} - -static int -nit_setflags(int fd, int promisc, int to_ms, char *ebuf) -{ - bpf_u_int32 flags; - struct strioctl si; - struct timeval timeout; - - si.ic_timout = INFTIM; - if (to_ms != 0) { - timeout.tv_sec = to_ms / 1000; - timeout.tv_usec = (to_ms * 1000) % 1000000; - si.ic_cmd = NIOCSTIME; - si.ic_len = sizeof(timeout); - si.ic_dp = (char *)&timeout; - if (ioctl(fd, I_STR, (char *)&si) < 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "NIOCSTIME: %s", - pcap_strerror(errno)); - return (-1); - } - } - flags = NI_TIMESTAMP | NI_LEN | NI_DROPS; - if (promisc) - flags |= NI_PROMISC; - si.ic_cmd = NIOCSFLAGS; - si.ic_len = sizeof(flags); - si.ic_dp = (char *)&flags; - if (ioctl(fd, I_STR, (char *)&si) < 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "NIOCSFLAGS: %s", - pcap_strerror(errno)); - return (-1); - } - return (0); -} - -static void -pcap_close_snit(pcap_t *p) -{ - if (p->buffer != NULL) - free(p->buffer); - if (p->fd >= 0) - close(p->fd); -} - -pcap_t * -pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, - char *ebuf) -{ - struct strioctl si; /* struct for ioctl() */ - struct ifreq ifr; /* interface request struct */ - int chunksize = CHUNKSIZE; - int fd; - static char dev[] = "/dev/nit"; - register pcap_t *p; - - p = (pcap_t *)malloc(sizeof(*p)); - if (p == NULL) { - strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE); - return (NULL); - } - - if (snaplen < 96) - /* - * NIT requires a snapshot length of at least 96. - */ - snaplen = 96; - - memset(p, 0, sizeof(*p)); - p->fd = fd = open(dev, O_RDONLY); - if (fd < 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s: %s", dev, - pcap_strerror(errno)); - goto bad; - } - - /* arrange to get discrete messages from the STREAM and use NIT_BUF */ - if (ioctl(fd, I_SRDOPT, (char *)RMSGD) < 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "I_SRDOPT: %s", - pcap_strerror(errno)); - goto bad; - } - if (ioctl(fd, I_PUSH, "nbuf") < 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "push nbuf: %s", - pcap_strerror(errno)); - goto bad; - } - /* set the chunksize */ - si.ic_cmd = NIOCSCHUNK; - si.ic_timout = INFTIM; - si.ic_len = sizeof(chunksize); - si.ic_dp = (char *)&chunksize; - if (ioctl(fd, I_STR, (char *)&si) < 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "NIOCSCHUNK: %s", - pcap_strerror(errno)); - goto bad; - } - - /* request the interface */ - strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); - ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0'; - si.ic_cmd = NIOCBIND; - si.ic_len = sizeof(ifr); - si.ic_dp = (char *)𝔦 - if (ioctl(fd, I_STR, (char *)&si) < 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "NIOCBIND: %s: %s", - ifr.ifr_name, pcap_strerror(errno)); - goto bad; - } - - /* set the snapshot length */ - si.ic_cmd = NIOCSSNAP; - si.ic_len = sizeof(snaplen); - si.ic_dp = (char *)&snaplen; - if (ioctl(fd, I_STR, (char *)&si) < 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "NIOCSSNAP: %s", - pcap_strerror(errno)); - goto bad; - } - p->snapshot = snaplen; - if (nit_setflags(p->fd, promisc, to_ms, ebuf) < 0) - goto bad; - - (void)ioctl(fd, I_FLUSH, (char *)FLUSHR); - /* - * NIT supports only ethernets. - */ - p->linktype = DLT_EN10MB; - - p->bufsize = BUFSPACE; - p->buffer = (u_char *)malloc(p->bufsize); - if (p->buffer == NULL) { - strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE); - goto bad; - } - - /* - * "p->fd" is an FD for a STREAMS device, so "select()" and - * "poll()" should work on it. - */ - p->selectable_fd = p->fd; - - p->read_op = pcap_read_snit; - p->setfilter_op = install_bpf_program; /* no kernel filtering */ - p->set_datalink_op = NULL; /* can't change data link type */ - p->getnonblock_op = pcap_getnonblock_fd; - p->setnonblock_op = pcap_setnonblock_fd; - p->stats_op = pcap_stats_snit; - p->close_op = pcap_close_snit; - - return (p); - bad: - if (fd >= 0) - close(fd); - free(p); - return (NULL); -} - -int -pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf) -{ - return (0); -} diff --git a/contrib/libpcap-0.8.3/pcap-snoop.c b/contrib/libpcap-0.8.3/pcap-snoop.c deleted file mode 100644 index 1260bd7419..0000000000 --- a/contrib/libpcap-0.8.3/pcap-snoop.c +++ /dev/null @@ -1,350 +0,0 @@ -/* - * Copyright (c) 1993, 1994, 1995, 1996, 1997 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that: (1) source code distributions - * retain the above copyright notice and this paragraph in its entirety, (2) - * distributions including binary code include the above copyright notice and - * this paragraph in its entirety in the documentation or other materials - * provided with the distribution, and (3) all advertising materials mentioning - * features or use of this software display the following acknowledgement: - * ``This product includes software developed by the University of California, - * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of - * the University nor the names of its contributors may be used to endorse - * or promote products derived from this software without specific prior - * written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ -#ifndef lint -static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/libpcap/pcap-snoop.c,v 1.45.2.5 2004/03/21 08:33:24 guy Exp $ (LBL)"; -#endif - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "pcap-int.h" - -#ifdef HAVE_OS_PROTO_H -#include "os-proto.h" -#endif - -static int -pcap_read_snoop(pcap_t *p, int cnt, pcap_handler callback, u_char *user) -{ - int cc; - register struct snoopheader *sh; - register int datalen; - register int caplen; - register u_char *cp; - -again: - /* - * Has "pcap_breakloop()" been called? - */ - if (p->break_loop) { - /* - * Yes - clear the flag that indicates that it - * has, and return -2 to indicate that we were - * told to break out of the loop. - */ - p->break_loop = 0; - return (-2); - } - cc = read(p->fd, (char *)p->buffer, p->bufsize); - if (cc < 0) { - /* Don't choke when we get ptraced */ - switch (errno) { - - case EINTR: - goto again; - - case EWOULDBLOCK: - return (0); /* XXX */ - } - snprintf(p->errbuf, sizeof(p->errbuf), - "read: %s", pcap_strerror(errno)); - return (-1); - } - sh = (struct snoopheader *)p->buffer; - datalen = sh->snoop_packetlen; - caplen = (datalen < p->snapshot) ? datalen : p->snapshot; - cp = (u_char *)(sh + 1) + p->offset; /* XXX */ - - /* - * XXX unfortunately snoop loopback isn't exactly like - * BSD's. The address family is encoded in the first 2 - * bytes rather than the first 4 bytes! Luckily the last - * two snoop loopback bytes are zeroed. - */ - if (p->linktype == DLT_NULL && *((short *)(cp + 2)) == 0) { - u_int *uip = (u_int *)cp; - *uip >>= 16; - } - - if (p->fcode.bf_insns == NULL || - bpf_filter(p->fcode.bf_insns, cp, datalen, caplen)) { - struct pcap_pkthdr h; - ++p->md.stat.ps_recv; - h.ts.tv_sec = sh->snoop_timestamp.tv_sec; - h.ts.tv_usec = sh->snoop_timestamp.tv_usec; - h.len = datalen; - h.caplen = caplen; - (*callback)(user, &h, cp); - return (1); - } - return (0); -} - -static int -pcap_stats_snoop(pcap_t *p, struct pcap_stat *ps) -{ - register struct rawstats *rs; - struct rawstats rawstats; - - rs = &rawstats; - memset(rs, 0, sizeof(*rs)); - if (ioctl(p->fd, SIOCRAWSTATS, (char *)rs) < 0) { - snprintf(p->errbuf, sizeof(p->errbuf), - "SIOCRAWSTATS: %s", pcap_strerror(errno)); - return (-1); - } - - /* - * "ifdrops" are those dropped by the network interface - * due to resource shortages or hardware errors. - * - * "sbdrops" are those dropped due to socket buffer limits. - * - * As filter is done in userland, "sbdrops" counts packets - * regardless of whether they would've passed the filter. - * - * XXX - does this count *all* Snoop or Drain sockets, - * rather than just this socket? If not, why does it have - * both Snoop and Drain statistics? - */ - p->md.stat.ps_drop = - rs->rs_snoop.ss_ifdrops + rs->rs_snoop.ss_sbdrops + - rs->rs_drain.ds_ifdrops + rs->rs_drain.ds_sbdrops; - - /* - * "ps_recv" counts only packets that passed the filter. - * As filtering is done in userland, this does not include - * packets dropped because we ran out of buffer space. - */ - *ps = p->md.stat; - return (0); -} - -static void -pcap_close_snoop(pcap_t *p) -{ - if (p->buffer != NULL) - free(p->buffer); - if (p->fd >= 0) - close(p->fd); -} - -/* XXX can't disable promiscuous */ -pcap_t * -pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, - char *ebuf) -{ - int fd; - struct sockaddr_raw sr; - struct snoopfilter sf; - u_int v; - int ll_hdrlen; - int snooplen; - pcap_t *p; - struct ifreq ifr; - - p = (pcap_t *)malloc(sizeof(*p)); - if (p == NULL) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", - pcap_strerror(errno)); - return (NULL); - } - memset(p, 0, sizeof(*p)); - fd = socket(PF_RAW, SOCK_RAW, RAWPROTO_SNOOP); - if (fd < 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "snoop socket: %s", - pcap_strerror(errno)); - goto bad; - } - p->fd = fd; - memset(&sr, 0, sizeof(sr)); - sr.sr_family = AF_RAW; - (void)strncpy(sr.sr_ifname, device, sizeof(sr.sr_ifname)); - if (bind(fd, (struct sockaddr *)&sr, sizeof(sr))) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "snoop bind: %s", - pcap_strerror(errno)); - goto bad; - } - memset(&sf, 0, sizeof(sf)); - if (ioctl(fd, SIOCADDSNOOP, &sf) < 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "SIOCADDSNOOP: %s", - pcap_strerror(errno)); - goto bad; - } - v = 64 * 1024; - (void)setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (char *)&v, sizeof(v)); - /* - * XXX hack - map device name to link layer type - */ - if (strncmp("et", device, 2) == 0 || /* Challenge 10 Mbit */ - strncmp("ec", device, 2) == 0 || /* Indigo/Indy 10 Mbit, - O2 10/100 */ - strncmp("ef", device, 2) == 0 || /* O200/2000 10/100 Mbit */ - strncmp("eg", device, 2) == 0 || /* Octane/O2xxx/O3xxx Gigabit */ - strncmp("gfe", device, 3) == 0 || /* GIO 100 Mbit */ - strncmp("fxp", device, 3) == 0 || /* Challenge VME Enet */ - strncmp("ep", device, 2) == 0 || /* Challenge 8x10 Mbit EPLEX */ - strncmp("vfe", device, 3) == 0 || /* Challenge VME 100Mbit */ - strncmp("fa", device, 2) == 0 || - strncmp("qaa", device, 3) == 0 || - strncmp("cip", device, 3) == 0 || - strncmp("el", device, 2) == 0) { - p->linktype = DLT_EN10MB; - p->offset = RAW_HDRPAD(sizeof(struct ether_header)); - ll_hdrlen = sizeof(struct ether_header); - } else if (strncmp("ipg", device, 3) == 0 || - strncmp("rns", device, 3) == 0 || /* O2/200/2000 FDDI */ - strncmp("xpi", device, 3) == 0) { - p->linktype = DLT_FDDI; - p->offset = 3; /* XXX yeah? */ - ll_hdrlen = 13; - } else if (strncmp("ppp", device, 3) == 0) { - p->linktype = DLT_RAW; - ll_hdrlen = 0; /* DLT_RAW meaning "no PPP header, just the IP packet"? */ - } else if (strncmp("qfa", device, 3) == 0) { - p->linktype = DLT_IP_OVER_FC; - ll_hdrlen = 24; - } else if (strncmp("pl", device, 2) == 0) { - p->linktype = DLT_RAW; - ll_hdrlen = 0; /* Cray UNICOS/mp pseudo link */ - } else if (strncmp("lo", device, 2) == 0) { - p->linktype = DLT_NULL; - ll_hdrlen = 4; - } else { - snprintf(ebuf, PCAP_ERRBUF_SIZE, - "snoop: unknown physical layer type"); - goto bad; - } -#ifdef SIOCGIFMTU - /* - * XXX - IRIX appears to give you an error if you try to set the - * capture length to be greater than the MTU, so let's try to get - * the MTU first and, if that succeeds, trim the snap length - * to be no greater than the MTU. - */ - (void)strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); - if (ioctl(fd, SIOCGIFMTU, (char *)&ifr) < 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "SIOCGIFMTU: %s", - pcap_strerror(errno)); - goto bad; - } - /* - * OK, we got it. - * - * XXX - some versions of IRIX 6.5 define "ifr_mtu" and have an - * "ifru_metric" member of the "ifr_ifru" union in an "ifreq" - * structure, others don't. - * - * I've no idea what's going on, so, if "ifr_mtu" isn't defined, - * we define it as "ifr_metric", as using that field appears to - * work on the versions that lack "ifr_mtu" (and, on those that - * don't lack it, "ifru_metric" and "ifru_mtu" are both "int" - * members of the "ifr_ifru" union, which suggests that they - * may be interchangeable in this case). - */ -#ifndef ifr_mtu -#define ifr_mtu ifr_metric -#endif - if (snaplen > ifr.ifr_mtu + ll_hdrlen) - snaplen = ifr.ifr_mtu + ll_hdrlen; -#endif - - /* - * The argument to SIOCSNOOPLEN is the number of link-layer - * payload bytes to capture - it doesn't count link-layer - * header bytes. - */ - snooplen = snaplen - ll_hdrlen; - if (snooplen < 0) - snooplen = 0; - if (ioctl(fd, SIOCSNOOPLEN, &snooplen) < 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "SIOCSNOOPLEN: %s", - pcap_strerror(errno)); - goto bad; - } - p->snapshot = snaplen; - v = 1; - if (ioctl(fd, SIOCSNOOPING, &v) < 0) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "SIOCSNOOPING: %s", - pcap_strerror(errno)); - goto bad; - } - - p->bufsize = 4096; /* XXX */ - p->buffer = (u_char *)malloc(p->bufsize); - if (p->buffer == NULL) { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", - pcap_strerror(errno)); - goto bad; - } - - /* - * "p->fd" is a socket, so "select()" should work on it. - */ - p->selectable_fd = p->fd; - - p->read_op = pcap_read_snoop; - p->setfilter_op = install_bpf_program; /* no kernel filtering */ - p->set_datalink_op = NULL; /* can't change data link type */ - p->getnonblock_op = pcap_getnonblock_fd; - p->setnonblock_op = pcap_setnonblock_fd; - p->stats_op = pcap_stats_snoop; - p->close_op = pcap_close_snoop; - - return (p); - bad: - (void)close(fd); - free(p); - return (NULL); -} - -int -pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf) -{ - return (0); -} diff --git a/contrib/libpcap-0.8.3/pcap-stdinc.h b/contrib/libpcap-0.8.3/pcap-stdinc.h deleted file mode 100644 index fa5ea26bb3..0000000000 --- a/contrib/libpcap-0.8.3/pcap-stdinc.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2002 - 2003 - * NetGroup, Politecnico di Torino (Italy) - * 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. Neither the name of the Politecnico di Torino 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 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 - * OWNER 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. - * - */ - -#define SIZEOF_CHAR 1 -#define SIZEOF_SHORT 2 -#define SIZEOF_INT 4 - -/* - * Avoids a compiler warning in case this was already defined - * (someone defined _WINSOCKAPI_ when including 'windows.h', in order - * to prevent it from including 'winsock.h') - */ -#ifdef _WINSOCKAPI_ -#undef _WINSOCKAPI_ -#endif -#include - -#include - -#include "bittypes.h" -#include -#include - -#ifndef __MINGW32__ -#include "IP6_misc.h" -#endif - -#define caddr_t char* - -#define snprintf _snprintf -#define vsnprintf _vsnprintf -#define inline __inline diff --git a/contrib/libpcap-0.8.3/pcap-win32.c b/contrib/libpcap-0.8.3/pcap-win32.c deleted file mode 100644 index ef1b0f3569..0000000000 --- a/contrib/libpcap-0.8.3/pcap-win32.c +++ /dev/null @@ -1,446 +0,0 @@ -/* - * Copyright (c) 1999 - 2003 - * NetGroup, Politecnico di Torino (Italy) - * 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. Neither the name of the Politecnico di Torino 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 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 - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#ifndef lint -static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/libpcap/pcap-win32.c,v 1.15.2.3 2003/11/30 02:32:02 guy Exp $ (LBL)"; -#endif - -#include -#include -#include -#ifdef __MINGW32__ -int* _errno(); -#define errno (*_errno()) -#endif /* __MINGW32__ */ - -static int pcap_setfilter_win32(pcap_t *, struct bpf_program *); -static int pcap_getnonblock_win32(pcap_t *, char *); -static int pcap_setnonblock_win32(pcap_t *, int, char *); - -#define PcapBufSize 256000 /*dimension of the buffer in the pcap_t structure*/ -#define SIZE_BUF 1000000 - -/* - * Header that the WinPcap driver associates to the packets. - * Once was in bpf.h - */ -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) */ -}; - -/* Start winsock */ -int -wsockinit() -{ - WORD wVersionRequested; - WSADATA wsaData; - int err; - wVersionRequested = MAKEWORD( 1, 1); - err = WSAStartup( wVersionRequested, &wsaData ); - if ( err != 0 ) - { - return -1; - } - return 0; -} - - -static int -pcap_stats_win32(pcap_t *p, struct pcap_stat *ps) -{ - - if(PacketGetStats(p->adapter, (struct bpf_stat*)ps) != TRUE){ - snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "PacketGetStats error: %s", pcap_win32strerror()); - return -1; - } - - return 0; -} - -static int -pcap_read_win32(pcap_t *p, int cnt, pcap_handler callback, u_char *user) -{ - int cc; - int n = 0; - register u_char *bp, *ep; - - cc = p->cc; - if (p->cc == 0) { - /* - * Has "pcap_breakloop()" been called? - */ - if (p->break_loop) { - /* - * Yes - clear the flag that indicates that it - * has, and return -2 to indicate that we were - * told to break out of the loop. - */ - p->break_loop = 0; - return (-2); - } - - /* capture the packets */ - if(PacketReceivePacket(p->adapter,p->Packet,TRUE)==FALSE){ - snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read error: PacketReceivePacket failed"); - return (-1); - } - - cc = p->Packet->ulBytesReceived; - - bp = p->Packet->Buffer; - } - else - bp = p->bp; - - /* - * Loop through each packet. - */ -#define bhp ((struct bpf_hdr *)bp) - ep = bp + cc; - while (1) { - register int caplen, hdrlen; - - /* - * Has "pcap_breakloop()" been called? - * If so, return immediately - if we haven't read any - * packets, clear the flag and return -2 to indicate - * that we were told to break out of the loop, otherwise - * leave the flag set, so that the *next* call will break - * out of the loop without having read any packets, and - * return the number of packets we've processed so far. - */ - if (p->break_loop) { - if (n == 0) { - p->break_loop = 0; - return (-2); - } else { - p->bp = bp; - p->cc = ep - bp; - return (n); - } - } - if (bp >= ep) - break; - - caplen = bhp->bh_caplen; - hdrlen = bhp->bh_hdrlen; - - /* - * XXX A bpf_hdr matches a pcap_pkthdr. - */ - (*callback)(user, (struct pcap_pkthdr*)bp, bp + hdrlen); - bp += BPF_WORDALIGN(caplen + hdrlen); - if (++n >= cnt && cnt > 0) { - p->bp = bp; - p->cc = ep - bp; - return (n); - } - } -#undef bhp - p->cc = 0; - return (n); -} - - -static void -pcap_close_win32(pcap_t *p) -{ - if (p->buffer != NULL) - free(p->buffer); - if (p->adapter != NULL) { - PacketCloseAdapter(p->adapter); - p->adapter = NULL; - } -} - -pcap_t * -pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, - char *ebuf) -{ - register pcap_t *p; - NetType type; - - /* Init WinSock */ - wsockinit(); - - p = (pcap_t *)malloc(sizeof(*p)); - if (p == NULL) - { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno)); - return (NULL); - } - memset(p, 0, sizeof(*p)); - p->adapter=NULL; - - p->adapter = PacketOpenAdapter((char*)device); - - if (p->adapter == NULL) - { - /* Adapter detected but we are not able to open it. Return failure. */ - snprintf(ebuf, PCAP_ERRBUF_SIZE, "Error opening adapter: %s", pcap_win32strerror()); - return NULL; - } - - /*get network type*/ - if(PacketGetNetType (p->adapter,&type) == FALSE) - { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "Cannot determine the network type: %s", pcap_win32strerror()); - goto bad; - } - - /*Set the linktype*/ - switch (type.LinkType) - { - case NdisMediumWan: - p->linktype = DLT_EN10MB; - break; - - case NdisMedium802_3: - p->linktype = DLT_EN10MB; - break; - - case NdisMediumFddi: - p->linktype = DLT_FDDI; - break; - - case NdisMedium802_5: - p->linktype = DLT_IEEE802; - break; - - case NdisMediumArcnetRaw: - p->linktype = DLT_ARCNET; - break; - - case NdisMediumArcnet878_2: - p->linktype = DLT_ARCNET; - break; - - case NdisMediumAtm: - p->linktype = DLT_ATM_RFC1483; - break; - - default: - p->linktype = DLT_EN10MB; /*an unknown adapter is assumed to be ethernet*/ - break; - } - - /* Set promisquous mode */ - if (promisc) PacketSetHwFilter(p->adapter,NDIS_PACKET_TYPE_PROMISCUOUS); - else PacketSetHwFilter(p->adapter,NDIS_PACKET_TYPE_ALL_LOCAL); - - /* Set the buffer size */ - p->bufsize = PcapBufSize; - - p->buffer = (u_char *)malloc(PcapBufSize); - if (p->buffer == NULL) - { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno)); - goto bad; - } - - p->snapshot = snaplen; - - /* allocate Packet structure used during the capture */ - if((p->Packet = PacketAllocatePacket())==NULL) - { - snprintf(ebuf, PCAP_ERRBUF_SIZE, "failed to allocate the PACKET structure"); - goto bad; - } - - PacketInitPacket(p->Packet,(BYTE*)p->buffer,p->bufsize); - - /* allocate the standard buffer in the driver */ - if(PacketSetBuff( p->adapter, SIZE_BUF)==FALSE) - { - snprintf(ebuf, PCAP_ERRBUF_SIZE,"driver error: not enough memory to allocate the kernel buffer\n"); - goto bad; - } - - /* tell the driver to copy the buffer only if it contains at least 16K */ - if(PacketSetMinToCopy(p->adapter,16000)==FALSE) - { - snprintf(ebuf, PCAP_ERRBUF_SIZE,"Error calling PacketSetMinToCopy: %s\n", pcap_win32strerror()); - goto bad; - } - - PacketSetReadTimeout(p->adapter, to_ms); - - p->read_op = pcap_read_win32; - p->setfilter_op = pcap_setfilter_win32; - p->set_datalink_op = NULL; /* can't change data link type */ - p->getnonblock_op = pcap_getnonblock_win32; - p->setnonblock_op = pcap_setnonblock_win32; - p->stats_op = pcap_stats_win32; - p->close_op = pcap_close_win32; - - return (p); -bad: - if (p->adapter) - PacketCloseAdapter(p->adapter); - if (p->buffer != NULL) - free(p->buffer); - free(p); - return (NULL); -} - - -static int -pcap_setfilter_win32(pcap_t *p, struct bpf_program *fp) -{ - if(PacketSetBpf(p->adapter,fp)==FALSE){ - /* kernel filter not installed. */ - snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Driver error: cannot set bpf filter: %s", pcap_win32strerror()); - return (-1); - } - return (0); -} - - -static int -pcap_getnonblock_win32(pcap_t *p, char *errbuf) -{ - /* - * XXX - if there were a PacketGetReadTimeout() call, we - * would use it, and return 1 if the timeout is -1 - * and 0 otherwise. - */ - return (p->nonblock); -} - -static int -pcap_setnonblock_win32(pcap_t *p, int nonblock, char *errbuf) -{ - int newtimeout; - - if (nonblock) { - /* - * Set the read timeout to -1 for non-blocking mode. - */ - newtimeout = -1; - } else { - /* - * Restore the timeout set when the device was opened. - * (Note that this may be -1, in which case we're not - * really leaving non-blocking mode.) - */ - newtimeout = p->timeout; - } - if (!PacketSetReadTimeout(p->adapter, newtimeout)) { - snprintf(p->errbuf, PCAP_ERRBUF_SIZE, - "PacketSetReadTimeout: %s", pcap_win32strerror()); - return (-1); - } - p->nonblock = (newtimeout == -1); - return (0); -} - -/* Set the driver working mode */ -int -pcap_setmode(pcap_t *p, int mode){ - - if (p->adapter==NULL) - { - snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "impossible to set mode while reading from a file"); - return -1; - } - - if(PacketSetMode(p->adapter,mode)==FALSE) - { - snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: working mode not recognized"); - return -1; - } - - return 0; -} - -/* Send a packet to the network */ -int -pcap_sendpacket(pcap_t *p, u_char *buf, int size){ - LPPACKET PacketToSend; - - if (p->adapter==NULL) - { - snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Writing a packet is allowed only on a physical adapter"); - return -1; - } - - PacketToSend=PacketAllocatePacket(); - PacketInitPacket(PacketToSend,buf,size); - if(PacketSendPacket(p->adapter,PacketToSend,TRUE) == FALSE){ - PacketFreePacket(PacketToSend); - return -1; - } - - PacketFreePacket(PacketToSend); - return 0; -} - -/* Set the dimension of the kernel-level capture buffer */ -int -pcap_setbuff(pcap_t *p, int dim) -{ - if (p->adapter==NULL) - { - snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "The kernel buffer size cannot be set while reading from a file"); - return -1; - } - - if(PacketSetBuff(p->adapter,dim)==FALSE) - { - snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: not enough memory to allocate the kernel buffer"); - return -1; - } - return 0; -} - -/*set the minimum amount of data that will release a read call*/ -int -pcap_setmintocopy(pcap_t *p, int size) -{ - if (p->adapter==NULL) - { - snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Impossible to set the mintocopy parameter on an offline capture"); - return -1; - } - - if(PacketSetMinToCopy(p->adapter, size)==FALSE) - { - snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: unable to set the requested mintocopy size"); - return -1; - } - return 0; -} diff --git a/contrib/libpcap-0.8.3/pcap.3 b/contrib/libpcap-0.8.3/pcap.3 deleted file mode 100644 index 7aad4a181d..0000000000 --- a/contrib/libpcap-0.8.3/pcap.3 +++ /dev/null @@ -1,1196 +0,0 @@ -.\" @(#) $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. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that: (1) source code distributions -.\" retain the above copyright notice and this paragraph in its entirety, (2) -.\" distributions including binary code include the above copyright notice and -.\" this paragraph in its entirety in the documentation or other materials -.\" provided with the distribution, and (3) all advertising materials mentioning -.\" features or use of this software display the following acknowledgement: -.\" ``This product includes software developed by the University of California, -.\" Lawrence Berkeley Laboratory and its contributors.'' Neither the name of -.\" the University nor the names of its contributors may be used to endorse -.\" or promote products derived from this software without specific prior -.\" written permission. -.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED -.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF -.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -.\" -.TH PCAP 3 "27 February 2004" -.SH NAME -pcap \- Packet Capture library -.SH SYNOPSIS -.nf -.ft B -#include -.ft -.LP -.nf -.ft B -char errbuf[PCAP_ERRBUF_SIZE]; -.ft -.LP -.ft B -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(const char *fname, char *errbuf) -pcap_dumper_t *pcap_dump_open(pcap_t *p, const char *fname) -.ft -.LP -.ft B -int pcap_setnonblock(pcap_t *p, int nonblock, char *errbuf); -int pcap_getnonblock(pcap_t *p, char *errbuf); -.ft -.LP -.ft B -int pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) -void pcap_freealldevs(pcap_if_t *alldevs) -char *pcap_lookupdev(char *errbuf) -int pcap_lookupnet(const char *device, bpf_u_int32 *netp, -.ti +8 -bpf_u_int32 *maskp, char *errbuf) -.ft -.LP -.ft B -int pcap_dispatch(pcap_t *p, int cnt, -.ti +8 -pcap_handler callback, u_char *user) -int pcap_loop(pcap_t *p, int cnt, -.ti +8 -pcap_handler callback, u_char *user) -void pcap_dump(u_char *user, struct pcap_pkthdr *h, -.ti +8 -u_char *sp) -.ft -.LP -.ft B -int pcap_compile(pcap_t *p, struct bpf_program *fp, -.ti +8 -char *str, int optimize, bpf_u_int32 netmask) -int pcap_setfilter(pcap_t *p, struct bpf_program *fp) -void pcap_freecode(struct bpf_program *); -.ft -.LP -.ft B -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) -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 -.SH DESCRIPTION -The Packet Capture library -provides a high level interface to packet capture systems. All packets -on the network, even those destined for other hosts, are accessible -through this mechanism. -.PP -.SH ROUTINES -NOTE: -.I errbuf -in -.BR pcap_open_live() , -.BR pcap_open_dead() , -.BR pcap_open_offline() , -.BR pcap_setnonblock() , -.BR pcap_getnonblock() , -.BR pcap_findalldevs() , -.BR pcap_lookupdev() , -and -.B pcap_lookupnet() -is assumed to be able to hold at least -.B PCAP_ERRBUF_SIZE -chars. -.PP -.B pcap_open_live() -is used to obtain a packet capture descriptor to look -at packets on the network. -.I device -is a string that specifies the network device to open; on Linux systems -with 2.2 or later kernels, a -.I device -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. 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 -could well be in promiscuous mode for some other reason.) For now, this -doesn't work on the "any" device; if an argument of "any" or NULL is -supplied, the -.I promisc -flag is ignored. -.I to_ms -specifies the read timeout in milliseconds. The read timeout is used to -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. 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() -fails and returns -.BR NULL . -.I errbuf -may also be set to warning text when -.B pcap_open_live() -succeds; to detect this case the caller should store a zero-length string in -.I errbuf -before calling -.B pcap_open_live() -and display the warning to the user if -.I errbuf -is no longer a zero-length string. -.PP -.B pcap_open_dead() -is used for creating a -.B pcap_t -structure to use when calling the other functions in libpcap. It is -typically used when just using libpcap for compiling BPF code. -.PP -.B pcap_open_offline() -is called to open a ``savefile'' for reading. -.I fname -specifies the name of the file to open. The file has -the same format as those used by -.B tcpdump(1) -and -.BR tcpslice(1) . -The name "-" in a synonym for -.BR stdin . -.I errbuf -is used to return error text and is only set when -.B pcap_open_offline() -fails and returns -.BR NULL . -.PP -.B pcap_dump_open() -is called to open a ``savefile'' for writing. The name "-" in a synonym -for -.BR stdout . -.B NULL -is returned on failure. -.I p -is a -.I pcap -struct as returned by -.B pcap_open_offline() -or -.BR pcap_open_live() . -.I fname -specifies the name of the file to open. -If -.B NULL -is returned, -.B pcap_geterr() -can be used to get the error text. -.PP -.B pcap_setnonblock() -puts a capture descriptor, opened with -.BR pcap_open_live() , -into ``non-blocking'' mode, or takes it out of ``non-blocking'' mode, -depending on whether the -.I nonblock -argument is non-zero or zero. It has no effect on ``savefiles''. -If there is an error, \-1 is returned and -.I errbuf -is filled in with an appropriate error message; otherwise, 0 is -returned. -In -``non-blocking'' mode, an attempt to read from the capture descriptor -with -.B pcap_dispatch() -will, if no packets are currently available to be read, return 0 -immediately rather than blocking waiting for packets to arrive. -.B pcap_loop() -and -.B pcap_next() -will not work in ``non-blocking'' mode. -.PP -.B pcap_getnonblock() -returns the current ``non-blocking'' state of the capture descriptor; it -always returns 0 on ``savefiles''. -If there is an error, \-1 is returned and -.I errbuf -is filled in with an appropriate error message. -.PP -.B pcap_findalldevs() -constructs a list of network devices that can be opened with -.BR pcap_open_live() . -(Note that there may be network devices that cannot be opened with -.BR pcap_open_live() -by the -process calling -.BR pcap_findalldevs() , -because, for example, that process might not have sufficient privileges -to open them for capturing; if so, those devices will not appear on the -list.) -.I alldevsp -is set to point to the first element of the list; each element of the -list is of type -.BR pcap_if_t , -and has the following members: -.RS -.TP -.B next -if not -.BR NULL , -a pointer to the next element in the list; -.B NULL -for the last element of the list -.TP -.B name -a pointer to a string giving a name for the device to pass to -.B pcap_open_live() -.TP -.B description -if not -.BR NULL , -a pointer to a string giving a human-readable description of the device -.TP -.B addresses -a pointer to the first element of a list of addresses for the interface -.TP -.B flags -interface flags: -.RS -.TP -.B PCAP_IF_LOOPBACK -set if the interface is a loopback interface -.RE -.RE -.PP -Each element of the list of addresses is of type -.BR pcap_addr_t , -and has the following members: -.RS -.TP -.B next -if not -.BR NULL , -a pointer to the next element in the list; -.B NULL -for the last element of the list -.TP -.B addr -a pointer to a -.B "struct sockaddr" -containing an address -.TP -.B netmask -if not -.BR NULL , -a pointer to a -.B "struct sockaddr" -that contains the netmask corresponding to the address pointed to by -.B addr -.TP -.B broadaddr -if not -.BR NULL , -a pointer to a -.B "struct sockaddr" -that contains the broadcast address corresponding to the address pointed -to by -.BR addr ; -may be null if the interface doesn't support broadcasts -.TP -.B dstaddr -if not -.BR NULL , -a pointer to a -.B "struct sockaddr" -that contains the destination address corresponding to the address pointed -to by -.BR addr ; -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() . -.PP -.B pcap_lookupdev() -returns a pointer to a network device suitable for use with -.B pcap_open_live() -and -.BR pcap_lookupnet() . -If there is an error, -.B NULL -is returned and -.I errbuf -is filled in with an appropriate error message. -.PP -.B pcap_lookupnet() -is used to determine the network number and mask -associated with the network device -.BR device . -Both -.I netp -and -.I maskp -are -.I bpf_u_int32 -pointers. -A return of \-1 indicates an error in which case -.I errbuf -is filled in with an appropriate error message. -.PP -.B pcap_dispatch() -is used to collect and process packets. -.I cnt -specifies the maximum number of packets to process before returning. -This is not a minimum number; when reading a live capture, only one -bufferful of packets is read at a time, so fewer than -.I cnt -packets may be processed. A -.I cnt -of \-1 processes all the packets received in one buffer when reading a -live capture, or all the packets in the file when reading a -``savefile''. -.I callback -specifies a routine to be called with three arguments: -a -.I u_char -pointer which is passed in from -.BR pcap_dispatch() , -a -.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 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 -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.'' A return of \-1 indicates -an error in which case -.B pcap_perror() -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, -.B pcap_dispatch() -will not necessarily return when the read times out; on some platforms, -the read timeout isn't supported, and, on other platforms, the timer -doesn't start until at least one packet arrives. This means that the -read timeout should -.B NOT -be used in, for example, an interactive application, to allow the packet -capture loop to ``poll'' for user input periodically, as there's no -guarantee that -.B pcap_dispatch() -will return after the timeout expires. -.PP -.B pcap_loop() -is similar to -.B pcap_dispatch() -except it keeps reading packets until -.I cnt -packets are processed or an error occurs. -It does -.B not -return when live read timeouts occur. -Rather, specifying a non-zero read timeout to -.B pcap_open_live() -and then calling -.B pcap_dispatch() -allows the reception and processing of any packets that arrive when the -timeout occurs. -A negative -.I cnt -causes -.B pcap_loop() -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 -.B pcap_dispatch() -with a -.I cnt -of 1) and returns a -.I u_char -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 -.BR pcap_dump_open() . -Note that its calling arguments are suitable for use with -.B pcap_dispatch() -or -.BR pcap_loop() . -If called directly, the -.I user -parameter is of type -.I pcap_dumper_t -as returned by -.BR pcap_dump_open() . -.PP -.B pcap_compile() -is used to compile the string -.I str -into a filter program. -.I program -is a pointer to a -.I bpf_program -struct and is filled in by -.BR pcap_compile() . -.I optimize -controls whether optimization on the resulting code is performed. -.I netmask -specifies the 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 -.B pcap_compile_nopcap() -is similar to -.B pcap_compile() -except that instead of passing a pcap structure, one passes the -snaplen and linktype explicitly. It is intended to be used for -compiling filters for direct BPF usage, without necessarily having -called -.BR pcap_open() . -A return of \-1 indicates an error; the error text is unavailable. -.RB ( pcap_compile_nopcap() -is a wrapper around -.BR pcap_open_dead() , -.BR pcap_compile() , -and -.BR pcap_close() ; -the latter three routines can be used directly in order to get the error -text for a compilation error.) -.B -.PP -.B pcap_setfilter() -is used to specify a filter program. -.I fp -is a pointer to a -.I bpf_program -struct, usually the result of a call to -.BR pcap_compile() . -.B \-1 -is returned on failure, in which case -.BR pcap_geterr() -may be used to display the error text; -.B 0 -is returned on success. -.PP -.B pcap_freecode() -is used to free up allocated memory pointed to by a -.I bpf_program -struct generated by -.B pcap_compile() -when that BPF program is no longer needed, for example after it -has been made the filter program for a pcap structure by a call to -.BR pcap_setfilter() . -.PP -.B pcap_datalink() -returns the link layer type; link layer types it can return include: -.PP -.RS 5 -.TP 5 -.B DLT_NULL -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. -.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 -machine on which the packets are captured; if a live capture is being -done, ``host byte order'' is the byte order of the machine capturing the -packets, and the PF_ values are those of the OS of the machine capturing -the packets, but if a ``savefile'' is being read, the byte order and PF_ -values are -.I not -necessarily those of the machine reading the capture file. -.TP 5 -.B DLT_EN10MB -Ethernet (10Mb, 100Mb, 1000Mb, and up) -.TP 5 -.B DLT_IEEE802 -IEEE 802.5 Token Ring -.TP 5 -.B DLT_ARCNET -ARCNET -.TP 5 -.B DLT_SLIP -SLIP; the link layer header contains, in order: -.RS 10 -.LP -a 1-byte flag, which is 0 for packets received by the machine and 1 for -packets sent by the machine; -.LP -a 1-byte field, the upper 4 bits of which indicate the type of packet, -as per RFC 1144: -.RS 5 -.TP 5 -0x40 -an unmodified IP datagram (TYPE_IP); -.TP 5 -0x70 -an uncompressed-TCP IP datagram (UNCOMPRESSED_TCP), with that byte being -the first byte of the raw IP header on the wire, containing the -connection number in the protocol field; -.TP 5 -0x80 -a compressed-TCP IP datagram (COMPRESSED_TCP), with that byte being the -first byte of the compressed TCP/IP datagram header; -.RE -.LP -for UNCOMPRESSED_TCP, the rest of the modified IP header, and for -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. -.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. -.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. -.TP 5 -.B DLT_RAW -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. -.TP 5 -.B DLT_PPP_ETHER -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. -.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. -.IP -Note that, if a ``savefile'' is being read, those PF_ values are -.I not -necessarily those of the machine reading the capture file. -.TP 5 -.B DLT_LINUX_SLL -Linux "cooked" capture encapsulation; the link layer header contains, in -order: -.RS 10 -.LP -a 2-byte "packet type", in network byte order, which is one of: -.RS 5 -.TP 5 -0 -packet was sent to us by somebody else -.TP 5 -1 -packet was broadcast by somebody else -.TP 5 -2 -packet was multicast, but not broadcast, by somebody else -.TP 5 -3 -packet was sent by somebody else to somebody else -.TP 5 -4 -packet was sent by us -.RE -.LP -a 2-byte field, in network byte order, containing a Linux ARPHRD_ value -for the link layer device type; -.LP -a 2-byte field, in network byte order, containing the length of the -link layer address of the sender of the packet (which could be 0); -.LP -an 8-byte field containing that number of bytes of the link layer header -(if there are more than 8 bytes, only the first 8 are present); -.LP -a 2-byte field containing an Ethernet protocol type, in network byte -order, or containing 1 for Novell 802.3 frames without an 802.2 LLC -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. -.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_snapshot() -returns the snapshot length specified when -.B pcap_open_live() -was called. -.PP -.B pcap_is_swapped() -returns true if the current ``savefile'' uses a different byte order -than the current system. -.PP -.B pcap_major_version() -returns the major number of the file format of the savefile; -.B pcap_minor_version() -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'' -was opened with -.BR pcap_open_offline() , -or NULL, if a network device was opened with -.BR pcap_open_live() . -.PP -.B pcap_stats() -returns 0 and fills in a -.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 -.B pcap_perror() -or -.BR pcap_geterr() . -.B pcap_stats() -is supported only on live captures, not on ``savefiles''; no statistics -are stored in ``savefiles'', so no statistics are available when reading -from a ``savefile''. -.PP -.B pcap_fileno() -returns the file descriptor number from which captured packets are read, -if a network device was opened with -.BR pcap_open_live() , -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 , -prefixed by -.IR prefix . -.PP -.B pcap_geterr() -returns the error text pertaining to the last pcap library error. -.BR NOTE : -the pointer it returns will no longer point to a valid error message -string after the -.B pcap_t -passed to it is closed; you must use or copy the string before closing -the -.BR pcap_t . -.PP -.B pcap_strerror() -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 -.SH SEE ALSO -tcpdump(1), tcpslice(1) -.SH AUTHORS -The original authors are: -.LP -Van Jacobson, -Craig Leres and -Steven McCanne, all of the -Lawrence Berkeley National Laboratory, University of California, Berkeley, CA. -.LP -The current version is available from "The Tcpdump Group"'s Web site at -.LP -.RS -.I http://www.tcpdump.org/ -.RE -.SH BUGS -Please send problems, bugs, questions, desirable enhancements, etc. to: -.LP -.RS -tcpdump-workers@tcpdump.org -.RE -.LP -Please send source code contributions, etc. to: -.LP -.RS -patches@tcpdump.org -.RE diff --git a/contrib/libpcap-0.8.3/pcap.c b/contrib/libpcap-0.8.3/pcap.c deleted file mode 100644 index fbaceb5a06..0000000000 --- a/contrib/libpcap-0.8.3/pcap.c +++ /dev/null @@ -1,772 +0,0 @@ -/* - * Copyright (c) 1993, 1994, 1995, 1996, 1997, 1998 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the Computer Systems - * Engineering Group at Lawrence Berkeley Laboratory. - * 4. Neither the name of the University nor of the Laboratory may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef lint -static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/libpcap/pcap.c,v 1.63.2.9 2004/03/25 22:40:52 guy Exp $ (LBL)"; -#endif - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifdef WIN32 -#include -#else /* WIN32 */ -#include -#endif /* WIN32 */ - -#include -#include -#include -#ifndef _MSC_VER -#include -#endif -#include -#include - -#ifdef HAVE_OS_PROTO_H -#include "os-proto.h" -#endif - -#include "pcap-int.h" - -#ifdef HAVE_DAG_API -#include -#include -#endif - -int -pcap_dispatch(pcap_t *p, int cnt, pcap_handler callback, u_char *user) -{ - - return p->read_op(p, cnt, callback, user); -} - -/* - * XXX - is this necessary? - */ -int -pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) -{ - - return p->read_op(p, cnt, callback, user); -} - -int -pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user) -{ - register int n; - - for (;;) { - if (p->sf.rfile != NULL) { - /* - * 0 means EOF, so don't loop if we get 0. - */ - n = pcap_offline_read(p, cnt, callback, user); - } else { - /* - * XXX keep reading until we get something - * (or an error occurs) - */ - do { - n = p->read_op(p, cnt, callback, user); - } while (n == 0); - } - if (n <= 0) - return (n); - if (cnt > 0) { - cnt -= n; - if (cnt <= 0) - return (0); - } - } -} - -struct singleton { - struct pcap_pkthdr *hdr; - const u_char *pkt; -}; - - -static void -pcap_oneshot(u_char *userData, const struct pcap_pkthdr *h, const u_char *pkt) -{ - struct singleton *sp = (struct singleton *)userData; - *sp->hdr = *h; - sp->pkt = pkt; -} - -const u_char * -pcap_next(pcap_t *p, struct pcap_pkthdr *h) -{ - struct singleton s; - - s.hdr = h; - if (pcap_dispatch(p, 1, pcap_oneshot, (u_char*)&s) <= 0) - return (0); - return (s.pkt); -} - -struct pkt_for_fakecallback { - struct pcap_pkthdr *hdr; - const u_char **pkt; -}; - -static void -pcap_fakecallback(u_char *userData, const struct pcap_pkthdr *h, - const u_char *pkt) -{ - struct pkt_for_fakecallback *sp = (struct pkt_for_fakecallback *)userData; - - *sp->hdr = *h; - *sp->pkt = pkt; -} - -int -pcap_next_ex(pcap_t *p, struct pcap_pkthdr **pkt_header, - const u_char **pkt_data) -{ - struct pkt_for_fakecallback s; - - s.hdr = &p->pcap_header; - s.pkt = pkt_data; - - /* Saves a pointer to the packet headers */ - *pkt_header= &p->pcap_header; - - if (p->sf.rfile != NULL) { - int status; - - /* We are on an offline capture */ - status = pcap_offline_read(p, 1, pcap_fakecallback, - (u_char *)&s); - - /* - * Return codes for pcap_offline_read() are: - * - 0: EOF - * - -1: error - * - >1: OK - * The first one ('0') conflicts with the return code of - * 0 from pcap_read() meaning "no packets arrived before - * the timeout expired", so we map it to -2 so you can - * distinguish between an EOF from a savefile and a - * "no packets arrived before the timeout expired, try - * again" from a live capture. - */ - if (status == 0) - return (-2); - else - return (status); - } - - /* - * Return codes for pcap_read() are: - * - 0: timeout - * - -1: error - * - -2: loop was broken out of with pcap_breakloop() - * - >1: OK - * The first one ('0') conflicts with the return code of 0 from - * pcap_offline_read() meaning "end of file". - */ - return (p->read_op(p, 1, pcap_fakecallback, (u_char *)&s)); -} - -/* - * Force the loop in "pcap_read()" or "pcap_read_offline()" to terminate. - */ -void -pcap_breakloop(pcap_t *p) -{ - p->break_loop = 1; -} - -int -pcap_datalink(pcap_t *p) -{ - return (p->linktype); -} - -int -pcap_list_datalinks(pcap_t *p, int **dlt_buffer) -{ - if (p->dlt_count == 0) { - /* - * We couldn't fetch the list of DLTs, which means - * this platform doesn't support changing the - * DLT for an interface. Return a list of DLTs - * containing only the DLT this device supports. - */ - *dlt_buffer = (int*)malloc(sizeof(**dlt_buffer)); - if (*dlt_buffer == NULL) { - (void)snprintf(p->errbuf, sizeof(p->errbuf), - "malloc: %s", pcap_strerror(errno)); - return (-1); - } - **dlt_buffer = p->linktype; - return (1); - } else { - *dlt_buffer = (int*)malloc(sizeof(**dlt_buffer) * p->dlt_count); - if (*dlt_buffer == NULL) { - (void)snprintf(p->errbuf, sizeof(p->errbuf), - "malloc: %s", pcap_strerror(errno)); - return (-1); - } - (void)memcpy(*dlt_buffer, p->dlt_list, - sizeof(**dlt_buffer) * p->dlt_count); - return (p->dlt_count); - } -} - -int -pcap_set_datalink(pcap_t *p, int dlt) -{ - int i; - const char *dlt_name; - - if (p->dlt_count == 0 || p->set_datalink_op == NULL) { - /* - * We couldn't fetch the list of DLTs, or we don't - * have a "set datalink" operation, which means - * this platform doesn't support changing the - * DLT for an interface. Check whether the new - * DLT is the one this interface supports. - */ - if (p->linktype != dlt) - goto unsupported; - - /* - * It is, so there's nothing we need to do here. - */ - return (0); - } - for (i = 0; i < p->dlt_count; i++) - if (p->dlt_list[i] == dlt) - break; - if (i >= p->dlt_count) - goto unsupported; - if (p->set_datalink_op(p, dlt) == -1) - return (-1); - p->linktype = dlt; - return (0); - -unsupported: - dlt_name = pcap_datalink_val_to_name(dlt); - if (dlt_name != NULL) { - (void) snprintf(p->errbuf, sizeof(p->errbuf), - "%s is not one of the DLTs supported by this device", - dlt_name); - } else { - (void) snprintf(p->errbuf, sizeof(p->errbuf), - "DLT %d is not one of the DLTs supported by this device", - dlt); - } - return (-1); -} - -struct dlt_choice { - const char *name; - const char *description; - int dlt; -}; - -#define DLT_CHOICE(code, description) { #code, description, code } -#define DLT_CHOICE_SENTINEL { NULL, NULL, 0 } - -static struct dlt_choice dlt_choices[] = { - DLT_CHOICE(DLT_NULL, "BSD loopback"), - DLT_CHOICE(DLT_EN10MB, "Ethernet"), - DLT_CHOICE(DLT_IEEE802, "Token ring"), - DLT_CHOICE(DLT_ARCNET, "ARCNET"), - DLT_CHOICE(DLT_SLIP, "SLIP"), - DLT_CHOICE(DLT_PPP, "PPP"), - DLT_CHOICE(DLT_FDDI, "FDDI"), - DLT_CHOICE(DLT_ATM_RFC1483, "RFC 1483 IP-over-ATM"), - DLT_CHOICE(DLT_RAW, "Raw IP"), - DLT_CHOICE(DLT_SLIP_BSDOS, "BSD/OS SLIP"), - DLT_CHOICE(DLT_PPP_BSDOS, "BSD/OS PPP"), - DLT_CHOICE(DLT_ATM_CLIP, "Linux Classical IP-over-ATM"), - DLT_CHOICE(DLT_PPP_SERIAL, "PPP over serial"), - DLT_CHOICE(DLT_PPP_ETHER, "PPPoE"), - DLT_CHOICE(DLT_C_HDLC, "Cisco HDLC"), - DLT_CHOICE(DLT_IEEE802_11, "802.11"), - DLT_CHOICE(DLT_FRELAY, "Frame Relay"), - DLT_CHOICE(DLT_LOOP, "OpenBSD loopback"), - DLT_CHOICE(DLT_ENC, "OpenBSD encapsulated IP"), - DLT_CHOICE(DLT_LINUX_SLL, "Linux cooked"), - DLT_CHOICE(DLT_LTALK, "Localtalk"), - DLT_CHOICE(DLT_PFLOG, "OpenBSD pflog file"), - DLT_CHOICE(DLT_PRISM_HEADER, "802.11 plus Prism header"), - DLT_CHOICE(DLT_IP_OVER_FC, "RFC 2625 IP-over-Fibre Channel"), - DLT_CHOICE(DLT_SUNATM, "Sun raw ATM"), - DLT_CHOICE(DLT_IEEE802_11_RADIO, "802.11 plus BSD radio information header"), - DLT_CHOICE(DLT_APPLE_IP_OVER_IEEE1394, "Apple IP-over-IEEE 1394"), - DLT_CHOICE(DLT_ARCNET_LINUX, "Linux ARCNET"), - DLT_CHOICE(DLT_LINUX_IRDA, "Linux IrDA"), - DLT_CHOICE(DLT_IEEE802_11_RADIO_AVS, "802.11 plus AVS radio information header"), - DLT_CHOICE_SENTINEL -}; - -/* - * This array is designed for mapping upper and lower case letter - * together for a case independent comparison. The mappings are - * based upon ascii character sequences. - */ -static const u_char charmap[] = { - (u_char)'\000', (u_char)'\001', (u_char)'\002', (u_char)'\003', - (u_char)'\004', (u_char)'\005', (u_char)'\006', (u_char)'\007', - (u_char)'\010', (u_char)'\011', (u_char)'\012', (u_char)'\013', - (u_char)'\014', (u_char)'\015', (u_char)'\016', (u_char)'\017', - (u_char)'\020', (u_char)'\021', (u_char)'\022', (u_char)'\023', - (u_char)'\024', (u_char)'\025', (u_char)'\026', (u_char)'\027', - (u_char)'\030', (u_char)'\031', (u_char)'\032', (u_char)'\033', - (u_char)'\034', (u_char)'\035', (u_char)'\036', (u_char)'\037', - (u_char)'\040', (u_char)'\041', (u_char)'\042', (u_char)'\043', - (u_char)'\044', (u_char)'\045', (u_char)'\046', (u_char)'\047', - (u_char)'\050', (u_char)'\051', (u_char)'\052', (u_char)'\053', - (u_char)'\054', (u_char)'\055', (u_char)'\056', (u_char)'\057', - (u_char)'\060', (u_char)'\061', (u_char)'\062', (u_char)'\063', - (u_char)'\064', (u_char)'\065', (u_char)'\066', (u_char)'\067', - (u_char)'\070', (u_char)'\071', (u_char)'\072', (u_char)'\073', - (u_char)'\074', (u_char)'\075', (u_char)'\076', (u_char)'\077', - (u_char)'\100', (u_char)'\141', (u_char)'\142', (u_char)'\143', - (u_char)'\144', (u_char)'\145', (u_char)'\146', (u_char)'\147', - (u_char)'\150', (u_char)'\151', (u_char)'\152', (u_char)'\153', - (u_char)'\154', (u_char)'\155', (u_char)'\156', (u_char)'\157', - (u_char)'\160', (u_char)'\161', (u_char)'\162', (u_char)'\163', - (u_char)'\164', (u_char)'\165', (u_char)'\166', (u_char)'\167', - (u_char)'\170', (u_char)'\171', (u_char)'\172', (u_char)'\133', - (u_char)'\134', (u_char)'\135', (u_char)'\136', (u_char)'\137', - (u_char)'\140', (u_char)'\141', (u_char)'\142', (u_char)'\143', - (u_char)'\144', (u_char)'\145', (u_char)'\146', (u_char)'\147', - (u_char)'\150', (u_char)'\151', (u_char)'\152', (u_char)'\153', - (u_char)'\154', (u_char)'\155', (u_char)'\156', (u_char)'\157', - (u_char)'\160', (u_char)'\161', (u_char)'\162', (u_char)'\163', - (u_char)'\164', (u_char)'\165', (u_char)'\166', (u_char)'\167', - (u_char)'\170', (u_char)'\171', (u_char)'\172', (u_char)'\173', - (u_char)'\174', (u_char)'\175', (u_char)'\176', (u_char)'\177', - (u_char)'\200', (u_char)'\201', (u_char)'\202', (u_char)'\203', - (u_char)'\204', (u_char)'\205', (u_char)'\206', (u_char)'\207', - (u_char)'\210', (u_char)'\211', (u_char)'\212', (u_char)'\213', - (u_char)'\214', (u_char)'\215', (u_char)'\216', (u_char)'\217', - (u_char)'\220', (u_char)'\221', (u_char)'\222', (u_char)'\223', - (u_char)'\224', (u_char)'\225', (u_char)'\226', (u_char)'\227', - (u_char)'\230', (u_char)'\231', (u_char)'\232', (u_char)'\233', - (u_char)'\234', (u_char)'\235', (u_char)'\236', (u_char)'\237', - (u_char)'\240', (u_char)'\241', (u_char)'\242', (u_char)'\243', - (u_char)'\244', (u_char)'\245', (u_char)'\246', (u_char)'\247', - (u_char)'\250', (u_char)'\251', (u_char)'\252', (u_char)'\253', - (u_char)'\254', (u_char)'\255', (u_char)'\256', (u_char)'\257', - (u_char)'\260', (u_char)'\261', (u_char)'\262', (u_char)'\263', - (u_char)'\264', (u_char)'\265', (u_char)'\266', (u_char)'\267', - (u_char)'\270', (u_char)'\271', (u_char)'\272', (u_char)'\273', - (u_char)'\274', (u_char)'\275', (u_char)'\276', (u_char)'\277', - (u_char)'\300', (u_char)'\341', (u_char)'\342', (u_char)'\343', - (u_char)'\344', (u_char)'\345', (u_char)'\346', (u_char)'\347', - (u_char)'\350', (u_char)'\351', (u_char)'\352', (u_char)'\353', - (u_char)'\354', (u_char)'\355', (u_char)'\356', (u_char)'\357', - (u_char)'\360', (u_char)'\361', (u_char)'\362', (u_char)'\363', - (u_char)'\364', (u_char)'\365', (u_char)'\366', (u_char)'\367', - (u_char)'\370', (u_char)'\371', (u_char)'\372', (u_char)'\333', - (u_char)'\334', (u_char)'\335', (u_char)'\336', (u_char)'\337', - (u_char)'\340', (u_char)'\341', (u_char)'\342', (u_char)'\343', - (u_char)'\344', (u_char)'\345', (u_char)'\346', (u_char)'\347', - (u_char)'\350', (u_char)'\351', (u_char)'\352', (u_char)'\353', - (u_char)'\354', (u_char)'\355', (u_char)'\356', (u_char)'\357', - (u_char)'\360', (u_char)'\361', (u_char)'\362', (u_char)'\363', - (u_char)'\364', (u_char)'\365', (u_char)'\366', (u_char)'\367', - (u_char)'\370', (u_char)'\371', (u_char)'\372', (u_char)'\373', - (u_char)'\374', (u_char)'\375', (u_char)'\376', (u_char)'\377', -}; - -int -pcap_strcasecmp(const char *s1, const char *s2) -{ - register const u_char *cm = charmap, - *us1 = (u_char *)s1, - *us2 = (u_char *)s2; - - while (cm[*us1] == cm[*us2++]) - if (*us1++ == '\0') - return(0); - return (cm[*us1] - cm[*--us2]); -} - -int -pcap_datalink_name_to_val(const char *name) -{ - int i; - - for (i = 0; dlt_choices[i].name != NULL; i++) { - if (pcap_strcasecmp(dlt_choices[i].name + sizeof("DLT_") - 1, - name) == 0) - return (dlt_choices[i].dlt); - } - return (-1); -} - -const char * -pcap_datalink_val_to_name(int dlt) -{ - int i; - - for (i = 0; dlt_choices[i].name != NULL; i++) { - if (dlt_choices[i].dlt == dlt) - return (dlt_choices[i].name + sizeof("DLT_") - 1); - } - return (NULL); -} - -const char * -pcap_datalink_val_to_description(int dlt) -{ - int i; - - for (i = 0; dlt_choices[i].name != NULL; i++) { - if (dlt_choices[i].dlt == dlt) - return (dlt_choices[i].description); - } - return (NULL); -} - -int -pcap_snapshot(pcap_t *p) -{ - return (p->snapshot); -} - -int -pcap_is_swapped(pcap_t *p) -{ - return (p->sf.swapped); -} - -int -pcap_major_version(pcap_t *p) -{ - return (p->sf.version_major); -} - -int -pcap_minor_version(pcap_t *p) -{ - return (p->sf.version_minor); -} - -FILE * -pcap_file(pcap_t *p) -{ - return (p->sf.rfile); -} - -int -pcap_fileno(pcap_t *p) -{ -#ifndef WIN32 - return (p->fd); -#else - if (p->adapter != NULL) - return ((int)(DWORD)p->adapter->hFile); - else - return (-1); -#endif -} - -#ifndef WIN32 -int -pcap_get_selectable_fd(pcap_t *p) -{ - return (p->selectable_fd); -} -#endif - -void -pcap_perror(pcap_t *p, char *prefix) -{ - fprintf(stderr, "%s: %s\n", prefix, p->errbuf); -} - -char * -pcap_geterr(pcap_t *p) -{ - return (p->errbuf); -} - -int -pcap_getnonblock(pcap_t *p, char *errbuf) -{ - return p->getnonblock_op(p, errbuf); -} - -/* - * Get the current non-blocking mode setting, under the assumption that - * it's just the standard POSIX non-blocking flag. - * - * We don't look at "p->nonblock", in case somebody tweaked the FD - * directly. - */ -#ifndef WIN32 -int -pcap_getnonblock_fd(pcap_t *p, char *errbuf) -{ - int fdflags; - - fdflags = fcntl(p->fd, F_GETFL, 0); - if (fdflags == -1) { - snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "F_GETFL: %s", - pcap_strerror(errno)); - return (-1); - } - if (fdflags & O_NONBLOCK) - return (1); - else - return (0); -} -#endif - -int -pcap_setnonblock(pcap_t *p, int nonblock, char *errbuf) -{ - return p->setnonblock_op(p, nonblock, errbuf); -} - -#ifndef WIN32 -/* - * Set non-blocking mode, under the assumption that it's just the - * standard POSIX non-blocking flag. (This can be called by the - * per-platform non-blocking-mode routine if that routine also - * needs to do some additional work.) - */ -int -pcap_setnonblock_fd(pcap_t *p, int nonblock, char *errbuf) -{ - int fdflags; - - fdflags = fcntl(p->fd, F_GETFL, 0); - if (fdflags == -1) { - snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "F_GETFL: %s", - pcap_strerror(errno)); - return (-1); - } - if (nonblock) - fdflags |= O_NONBLOCK; - else - fdflags &= ~O_NONBLOCK; - if (fcntl(p->fd, F_SETFL, fdflags) == -1) { - snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "F_SETFL: %s", - pcap_strerror(errno)); - return (-1); - } - return (0); -} -#endif - -#ifdef WIN32 -/* - * Generate a string for the last Win32-specific error (i.e. an error generated when - * calling a Win32 API). - * For errors occurred during standard C calls, we still use pcap_strerror() - */ -char * -pcap_win32strerror(void) -{ - DWORD error; - static char errbuf[PCAP_ERRBUF_SIZE+1]; - int errlen; - - error = GetLastError(); - FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, errbuf, - PCAP_ERRBUF_SIZE, NULL); - - /* - * "FormatMessage()" "helpfully" sticks CR/LF at the end of the - * message. Get rid of it. - */ - errlen = strlen(errbuf); - if (errlen >= 2) { - errbuf[errlen - 1] = '\0'; - errbuf[errlen - 2] = '\0'; - } - return (errbuf); -} -#endif - -/* - * Not all systems have strerror(). - */ -char * -pcap_strerror(int errnum) -{ -#ifdef HAVE_STRERROR - return (strerror(errnum)); -#else - extern int sys_nerr; - extern const char *const sys_errlist[]; - static char ebuf[20]; - - if ((unsigned int)errnum < sys_nerr) - return ((char *)sys_errlist[errnum]); - (void)snprintf(ebuf, sizeof ebuf, "Unknown error: %d", errnum); - return(ebuf); -#endif -} - -int -pcap_setfilter(pcap_t *p, struct bpf_program *fp) -{ - return p->setfilter_op(p, fp); -} - -int -pcap_stats(pcap_t *p, struct pcap_stat *ps) -{ - return p->stats_op(p, ps); -} - -static int -pcap_stats_dead(pcap_t *p, struct pcap_stat *ps) -{ - snprintf(p->errbuf, PCAP_ERRBUF_SIZE, - "Statistics aren't available from a pcap_open_dead pcap_t"); - return (-1); -} - -static void -pcap_close_dead(pcap_t *p) -{ - /* Nothing to do. */ -} - -pcap_t * -pcap_open_dead(int linktype, int snaplen) -{ - pcap_t *p; - - p = malloc(sizeof(*p)); - if (p == NULL) - return NULL; - memset (p, 0, sizeof(*p)); - p->snapshot = snaplen; - p->linktype = linktype; - p->stats_op = pcap_stats_dead; - p->close_op = pcap_close_dead; - return p; -} - -void -pcap_close(pcap_t *p) -{ - p->close_op(p); - if (p->dlt_list != NULL) - free(p->dlt_list); - pcap_freecode(&p->fcode); - free(p); -} - -/* - * We make the version string static, and return a pointer to it, rather - * than exporting the version string directly. On at least some UNIXes, - * if you import data from a shared library into an program, the data is - * bound into the program binary, so if the string in the version of the - * library with which the program was linked isn't the same as the - * string in the version of the library with which the program is being - * run, various undesirable things may happen (warnings, the string - * being the one from the version of the library with which the program - * was linked, or even weirder things, such as the string being the one - * from the library but being truncated). - */ -#ifdef WIN32 -/* - * XXX - it'd be nice if we could somehow generate the WinPcap and libpcap - * version numbers when building WinPcap. (It'd be nice to do so for - * the packet.dll version number as well.) - */ -static const char wpcap_version_string[] = "3.0"; -static const char pcap_version_string_fmt[] = - "WinPcap version %s, based on libpcap version 0.8"; -static const char pcap_version_string_packet_dll_fmt[] = - "WinPcap version %s (packet.dll version %s), based on libpcap version 0.8"; -static char *pcap_version_string; - -const char * -pcap_lib_version(void) -{ - char *packet_version_string; - size_t pcap_version_string_len; - - if (pcap_version_string == NULL) { - /* - * Generate the version string. - */ - packet_version_string = PacketGetVersion(); - if (strcmp(wpcap_version_string, packet_version_string) == 0) { - /* - * WinPcap version string and packet.dll version - * string are the same; just report the WinPcap - * version. - */ - pcap_version_string_len = - (sizeof pcap_version_string_fmt - 2) + - strlen(wpcap_version_string); - pcap_version_string = malloc(pcap_version_string_len); - sprintf(pcap_version_string, pcap_version_string_fmt, - wpcap_version_string); - } else { - /* - * WinPcap version string and packet.dll version - * string are different; that shouldn't be the - * case (the two libraries should come from the - * same version of WinPcap), so we report both - * versions. - */ - pcap_version_string_len = - (sizeof pcap_version_string_packet_dll_fmt - 4) + - strlen(wpcap_version_string) + - strlen(packet_version_string); - pcap_version_string = malloc(pcap_version_string_len); - sprintf(pcap_version_string, - pcap_version_string_packet_dll_fmt, - wpcap_version_string, packet_version_string); - } - } - return (pcap_version_string); -} -#else -#include "version.h" - -const char * -pcap_lib_version(void) -{ - return (pcap_version_string); -} -#endif diff --git a/contrib/libpcap-0.8.3/pcap.h b/contrib/libpcap-0.8.3/pcap.h deleted file mode 100644 index 450ac00dee..0000000000 --- a/contrib/libpcap-0.8.3/pcap.h +++ /dev/null @@ -1,258 +0,0 @@ -/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */ -/* - * Copyright (c) 1993, 1994, 1995, 1996, 1997 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the Computer Systems - * Engineering Group at Lawrence Berkeley Laboratory. - * 4. Neither the name of the University nor of the Laboratory may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#) $Header: /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 -#else /* WIN32 */ -#include -#include -#endif /* WIN32 */ - -#ifndef PCAP_DONT_INCLUDE_PCAP_BPF_H -#include -#endif - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define PCAP_VERSION_MAJOR 2 -#define PCAP_VERSION_MINOR 4 - -#define PCAP_ERRBUF_SIZE 256 - -/* - * Compatibility for systems that have a bpf.h that - * predates the bpf typedefs for 64-bit support. - */ -#if BPF_RELEASE - 0 < 199406 -typedef int bpf_int32; -typedef u_int bpf_u_int32; -#endif - -typedef struct pcap pcap_t; -typedef struct pcap_dumper pcap_dumper_t; -typedef struct pcap_if pcap_if_t; -typedef struct pcap_addr pcap_addr_t; - -/* - * The first record in the file contains saved values for some - * of the flags used in the printout phases of tcpdump. - * Many fields here are 32 bit ints so compilers won't insert unwanted - * padding; these files need to be interchangeable across architectures. - * - * Do not change the layout of this structure, in any way (this includes - * changes that only affect the length of fields in this structure). - * - * Also, do not change the interpretation of any of the members of this - * structure, in any way (this includes using values other than - * LINKTYPE_ values, as defined in "savefile.c", in the "linktype" - * field). - * - * Instead: - * - * introduce a new structure for the new format, if the layout - * of the structure changed; - * - * send mail to "tcpdump-workers@tcpdump.org", requesting a new - * magic number for your new capture file format, and, when - * you get the new magic number, put it in "savefile.c"; - * - * use that magic number for save files with the changed file - * header; - * - * make the code in "savefile.c" capable of reading files with - * the old file header as well as files with the new file header - * (using the magic number to determine the header format). - * - * Then supply the changes to "patches@tcpdump.org", so that future - * versions of libpcap and programs that use it (such as tcpdump) will - * be able to read your new capture file format. - */ -struct pcap_file_header { - bpf_u_int32 magic; - u_short version_major; - u_short version_minor; - bpf_int32 thiszone; /* gmt to local correction */ - bpf_u_int32 sigfigs; /* accuracy of timestamps */ - bpf_u_int32 snaplen; /* max length saved portion of each pkt */ - bpf_u_int32 linktype; /* data link type (LINKTYPE_*) */ -}; - -/* - * Each packet in the dump file is prepended with this generic header. - * This gets around the problem of different headers for different - * packet interfaces. - */ -struct pcap_pkthdr { - struct timeval ts; /* time stamp */ - bpf_u_int32 caplen; /* length of portion present */ - bpf_u_int32 len; /* length this packet (off wire) */ -}; - -/* - * As returned by the pcap_stats() - */ -struct pcap_stat { - u_int ps_recv; /* number of packets received */ - u_int ps_drop; /* number of packets dropped */ - u_int ps_ifdrop; /* drops by interface XXX not yet supported */ -#ifdef WIN32 - u_int bs_capt; /* number of packets that reach the application */ -#endif /* WIN32 */ -}; - -/* - * Item in a list of interfaces. - */ -struct pcap_if { - struct pcap_if *next; - char *name; /* name to hand to "pcap_open_live()" */ - char *description; /* textual description of interface, or NULL */ - struct pcap_addr *addresses; - bpf_u_int32 flags; /* PCAP_IF_ interface flags */ -}; - -#define PCAP_IF_LOOPBACK 0x00000001 /* interface is loopback */ - -/* - * Representation of an interface address. - */ -struct pcap_addr { - struct pcap_addr *next; - struct sockaddr *addr; /* address */ - struct sockaddr *netmask; /* netmask for that address */ - struct sockaddr *broadaddr; /* broadcast address for that address */ - struct sockaddr *dstaddr; /* P2P destination address for that address */ -}; - -typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *, - const u_char *); - -char *pcap_lookupdev(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 *); -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 *); -int pcap_setnonblock(pcap_t *, int, char *); -void pcap_perror(pcap_t *, char *); -char *pcap_strerror(int); -char *pcap_geterr(pcap_t *); -int pcap_compile(pcap_t *, struct bpf_program *, char *, int, - bpf_u_int32); -int pcap_compile_nopcap(int, int, struct bpf_program *, - char *, int, bpf_u_int32); -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 *); -int pcap_minor_version(pcap_t *); - -/* XXX */ -FILE *pcap_file(pcap_t *); -int pcap_fileno(pcap_t *); - -pcap_dumper_t *pcap_dump_open(pcap_t *, 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 -#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 - -#endif diff --git a/contrib/libpcap-0.8.3/pf.h b/contrib/libpcap-0.8.3/pf.h deleted file mode 100644 index ad6649cf4e..0000000000 --- a/contrib/libpcap-0.8.3/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.1.2.1 2004/03/28 21:45:33 fenner 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; - sa_family_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-0.8.3/ppp.h b/contrib/libpcap-0.8.3/ppp.h deleted file mode 100644 index b7b987d3a5..0000000000 --- a/contrib/libpcap-0.8.3/ppp.h +++ /dev/null @@ -1,52 +0,0 @@ -/* @(#) $Header: /tcpdump/master/libpcap/ppp.h,v 1.8 1999/10/19 15:18:31 itojun Exp $ (LBL) */ -/* - * Point to Point Protocol (PPP) RFC1331 - * - * Copyright 1989 by Carnegie Mellon. - * - * Permission to use, copy, modify, and distribute this program for any - * purpose and without fee is hereby granted, provided that this copyright - * and permission notice appear on all copies and supporting documentation, - * the name of Carnegie Mellon not be used in advertising or publicity - * pertaining to distribution of the program without specific prior - * permission, and notice be given in supporting documentation that copying - * and distribution is by permission of Carnegie Mellon and Stanford - * University. Carnegie Mellon makes no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. - */ -#define PPP_ADDRESS 0xff /* The address byte value */ -#define PPP_CONTROL 0x03 /* The control byte value */ - -/* Protocol numbers */ -#define PPP_IP 0x0021 /* Raw IP */ -#define PPP_OSI 0x0023 /* OSI Network Layer */ -#define PPP_NS 0x0025 /* Xerox NS IDP */ -#define PPP_DECNET 0x0027 /* DECnet Phase IV */ -#define PPP_APPLE 0x0029 /* Appletalk */ -#define PPP_IPX 0x002b /* Novell IPX */ -#define PPP_VJC 0x002d /* Van Jacobson Compressed TCP/IP */ -#define PPP_VJNC 0x002f /* Van Jacobson Uncompressed TCP/IP */ -#define PPP_BRPDU 0x0031 /* Bridging PDU */ -#define PPP_STII 0x0033 /* Stream Protocol (ST-II) */ -#define PPP_VINES 0x0035 /* Banyan Vines */ -#define PPP_IPV6 0x0057 /* Internet Protocol version 6 */ - -#define PPP_HELLO 0x0201 /* 802.1d Hello Packets */ -#define PPP_LUXCOM 0x0231 /* Luxcom */ -#define PPP_SNS 0x0233 /* Sigma Network Systems */ - -#define PPP_IPCP 0x8021 /* IP Control Protocol */ -#define PPP_OSICP 0x8023 /* OSI Network Layer Control Protocol */ -#define PPP_NSCP 0x8025 /* Xerox NS IDP Control Protocol */ -#define PPP_DECNETCP 0x8027 /* DECnet Control Protocol */ -#define PPP_APPLECP 0x8029 /* Appletalk Control Protocol */ -#define PPP_IPXCP 0x802b /* Novell IPX Control Protocol */ -#define PPP_STIICP 0x8033 /* Strean Protocol Control Protocol */ -#define PPP_VINESCP 0x8035 /* Banyan Vines Control Protocol */ -#define PPP_IPV6CP 0x8057 /* IPv6 Control Protocol */ - -#define PPP_LCP 0xc021 /* Link Control Protocol */ -#define PPP_PAP 0xc023 /* Password Authentication Protocol */ -#define PPP_LQM 0xc025 /* Link Quality Monitoring */ -#define PPP_CHAP 0xc223 /* Challenge Handshake Authentication Protocol */ diff --git a/contrib/libpcap-0.8.3/rawss7.h b/contrib/libpcap-0.8.3/rawss7.h deleted file mode 100644 index 8f8d058456..0000000000 --- a/contrib/libpcap-0.8.3/rawss7.h +++ /dev/null @@ -1,105 +0,0 @@ -/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */ -/* - * Copyright (c) 2003 - The tcpdump group. - * - * 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. Neither the name of the University nor of the Laboratory may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#) $Header: /tcpdump/master/libpcap/rawss7.h,v 1.1 2003/09/10 19:55:36 mcr Exp $ (LBL) - */ - -/* - * This file is never used in libpcap or tcpdump. It is provided as - * documentation linktypes 139 through 142 only. - */ - -/* - * Date: Tue, 09 Sep 2003 09:41:04 -0400 - * From: Jeff Morriss - * To: tcpdump-workers@tcpdump.org - * Subject: [tcpdump-workers] request for LINKTYPE_ - * - * We've had some discussion over on ethereal-dev about a "fake link" or - * "raw SS7" dissector that allows dumping an arbitrary protocol into a - * file without any (otherwise necessary) lower level protocols. The - * common example has been dumping MTP3 into a file without, well, MTP2 or - * M2PA. - * - * We want to store these protocols directly in PCAP file format because - * it's well defined and there isn't another (popular) file format for - * capturing SS7 messages that we can reverse engineer (and we want to read - * these files into Ethereal). Rather than creating a new file format, it's - * a lot easier to just allocate a LINKTYPE_. - * - * Here is the original post thread: - * - * http://ethereal.com/lists/ethereal-dev/200306/threads.html#00200 - * - * July's thread on the subject: - * - * http://ethereal.com/lists/ethereal-dev/200307/threads.html#00124 - * - * August's thread: - * - * http://ethereal.com/lists/ethereal-dev/200308/threads.html#00193 - * - * - * and one of the last messages--which is why I'm mailing you today: - * - * http://ethereal.com/lists/ethereal-dev/200308/msg00193.html - * - * - * Based on the message in the last URL, I'd like to request a new - * LINKTYPE_: LINKTYPE_RAWSS7. - * - * This packets in this file type will contain a header: - */ - -typedef struct _rawss7_hdr { - /* NOTE: These are in network-byte order. */ - guint32 type; - guint16 length; - guint16 spare; -} rawss7_hdr; - -/* - * - * followed by protocol data for whatever protocol 'type' indicates. - * - * There was some discussion about these protocol 'type's being allocated by - * tcpdump-workers as well. In fact it would be handy to have one place to - * allocate such numbers, so what do you think about allocating 3 more (for - * now) LINKTYPE_'s: - */ - -#define LINKTYPE_RAWSS7_MTP2 140 -#define LINKTYPE_RAWSS7_MTP3 141 -#define LINKTYPE_RAWSS7_SCCP 142 - -/* - * - * There is no reason this can't be used to store non-SS7 protocols, but - * it's what we need to use it for now... - * - */ diff --git a/contrib/libpcap-0.8.3/savefile.c b/contrib/libpcap-0.8.3/savefile.c deleted file mode 100644 index cc307bdff1..0000000000 --- a/contrib/libpcap-0.8.3/savefile.c +++ /dev/null @@ -1,1035 +0,0 @@ -/* - * Copyright (c) 1993, 1994, 1995, 1996, 1997 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that: (1) source code distributions - * retain the above copyright notice and this paragraph in its entirety, (2) - * distributions including binary code include the above copyright notice and - * this paragraph in its entirety in the documentation or other materials - * provided with the distribution, and (3) all advertising materials mentioning - * features or use of this software display the following acknowledgement: - * ``This product includes software developed by the University of California, - * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of - * the University nor the names of its contributors may be used to endorse - * or promote products derived from this software without specific prior - * written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * savefile.c - supports offline use of tcpdump - * Extraction/creation by Jeffrey Mogul, DECWRL - * Modified by Steve McCanne, LBL. - * - * Used to save the received packet headers, after filtering, to - * a file, and then read them later. - * The first record in the file contains saved values for the machine - * dependent values so we can print the dump file on any architecture. - */ - -#ifndef lint -static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/libpcap/savefile.c,v 1.92.2.11 2004/03/11 23:46:14 guy Exp $ (LBL)"; -#endif - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#include -#include - -#include "pcap-int.h" - -#ifdef HAVE_OS_PROTO_H -#include "os-proto.h" -#endif - -#define TCPDUMP_MAGIC 0xa1b2c3d4 -#define PATCHED_TCPDUMP_MAGIC 0xa1b2cd34 - -/* - * We use the "receiver-makes-right" approach to byte order, - * because time is at a premium when we are writing the file. - * In other words, the pcap_file_header and pcap_pkthdr, - * records are written in host byte order. - * Note that the bytes of packet data are written out in the order in - * which they were received, so multi-byte fields in packets are not - * written in host byte order, they're written in whatever order the - * sending machine put them in. - * - * ntoh[ls] aren't sufficient because we might need to swap on a big-endian - * machine (if the file was written in little-end order). - */ -#define SWAPLONG(y) \ -((((y)&0xff)<<24) | (((y)&0xff00)<<8) | (((y)&0xff0000)>>8) | (((y)>>24)&0xff)) -#define SWAPSHORT(y) \ - ( (((y)&0xff)<<8) | ((u_short)((y)&0xff00)>>8) ) - -#define SFERR_TRUNC 1 -#define SFERR_BADVERSION 2 -#define SFERR_BADF 3 -#define SFERR_EOF 4 /* not really an error, just a status */ - -/* - * We don't write DLT_* values to the capture file header, because - * they're not the same on all platforms. - * - * Unfortunately, the various flavors of BSD have not always used the same - * numerical values for the same data types, and various patches to - * libpcap for non-BSD OSes have added their own DLT_* codes for link - * layer encapsulation types seen on those OSes, and those codes have had, - * in some cases, values that were also used, on other platforms, for other - * link layer encapsulation types. - * - * This means that capture files of a type whose numerical DLT_* code - * means different things on different BSDs, or with different versions - * of libpcap, can't always be read on systems other than those like - * the one running on the machine on which the capture was made. - * - * Instead, we define here a set of LINKTYPE_* codes, and map DLT_* codes - * to LINKTYPE_* codes when writing a savefile header, and map LINKTYPE_* - * codes to DLT_* codes when reading a savefile header. - * - * For those DLT_* codes that have, as far as we know, the same values on - * all platforms (DLT_NULL through DLT_FDDI), we define LINKTYPE_xxx as - * DLT_xxx; that way, captures of those types can still be read by - * versions of libpcap that map LINKTYPE_* values to DLT_* values, and - * captures of those types written by versions of libpcap that map DLT_ - * values to LINKTYPE_ values can still be read by older versions - * of libpcap. - * - * The other LINKTYPE_* codes are given values starting at 100, in the - * hopes that no DLT_* code will be given one of those values. - * - * In order to ensure that a given LINKTYPE_* code's value will refer to - * the same encapsulation type on all platforms, you should not allocate - * a new LINKTYPE_* value without consulting "tcpdump-workers@tcpdump.org". - * The tcpdump developers will allocate a value for you, and will not - * subsequently allocate it to anybody else; that value will be added to - * the "pcap.h" in the tcpdump.org CVS repository, so that a future - * libpcap release will include it. - * - * You should, if possible, also contribute patches to libpcap and tcpdump - * to handle the new encapsulation type, so that they can also be checked - * into the tcpdump.org CVS repository and so that they will appear in - * future libpcap and tcpdump releases. - * - * Do *NOT* assume that any values after the largest value in this file - * are available; you might not have the most up-to-date version of this - * file, and new values after that one might have been assigned. Also, - * do *NOT* use any values below 100 - those might already have been - * taken by one (or more!) organizations. - */ -#define LINKTYPE_NULL DLT_NULL -#define LINKTYPE_ETHERNET DLT_EN10MB /* also for 100Mb and up */ -#define LINKTYPE_EXP_ETHERNET DLT_EN3MB /* 3Mb experimental Ethernet */ -#define LINKTYPE_AX25 DLT_AX25 -#define LINKTYPE_PRONET DLT_PRONET -#define LINKTYPE_CHAOS DLT_CHAOS -#define LINKTYPE_TOKEN_RING DLT_IEEE802 /* DLT_IEEE802 is used for Token Ring */ -#define LINKTYPE_ARCNET DLT_ARCNET /* BSD-style headers */ -#define LINKTYPE_SLIP DLT_SLIP -#define LINKTYPE_PPP DLT_PPP -#define LINKTYPE_FDDI DLT_FDDI - -/* - * LINKTYPE_PPP is for use when there might, or might not, be an RFC 1662 - * PPP in HDLC-like framing header (with 0xff 0x03 before the PPP protocol - * field) at the beginning of the packet. - * - * This is for use when there is always such a header; the address field - * might be 0xff, for regular PPP, or it might be an address field for Cisco - * point-to-point with HDLC framing as per section 4.3.1 of RFC 1547 ("Cisco - * HDLC"). This is, for example, what you get with NetBSD's DLT_PPP_SERIAL. - * - * We give it the same value as NetBSD's DLT_PPP_SERIAL, in the hopes that - * nobody else will choose a DLT_ value of 50, and so that DLT_PPP_SERIAL - * captures will be written out with a link type that NetBSD's tcpdump - * can read. - */ -#define LINKTYPE_PPP_HDLC 50 /* PPP in HDLC-like framing */ - -#define LINKTYPE_PPP_ETHER 51 /* NetBSD PPP-over-Ethernet */ - -/* - * This isn't supported in libpcap 0.8[.x], but is supported in the - * current CVS version; we include it here to note that it's not available - * for anybody else to use. - */ -#define LINKTYPE_SYMANTEC_FIREWALL 99 /* Symantec Enterprise Firewall */ - -#define LINKTYPE_ATM_RFC1483 100 /* LLC/SNAP-encapsulated ATM */ -#define LINKTYPE_RAW 101 /* raw IP */ -#define LINKTYPE_SLIP_BSDOS 102 /* BSD/OS SLIP BPF header */ -#define LINKTYPE_PPP_BSDOS 103 /* BSD/OS PPP BPF header */ -#define LINKTYPE_C_HDLC 104 /* Cisco HDLC */ -#define LINKTYPE_IEEE802_11 105 /* IEEE 802.11 (wireless) */ -#define LINKTYPE_ATM_CLIP 106 /* Linux Classical IP over ATM */ -#define LINKTYPE_FRELAY 107 /* Frame Relay */ -#define LINKTYPE_LOOP 108 /* OpenBSD loopback */ -#define LINKTYPE_ENC 109 /* OpenBSD IPSEC enc */ - -/* - * These three types are reserved for future use. - */ -#define LINKTYPE_LANE8023 110 /* ATM LANE + 802.3 */ -#define LINKTYPE_HIPPI 111 /* NetBSD HIPPI */ -#define LINKTYPE_HDLC 112 /* NetBSD HDLC framing */ - -#define LINKTYPE_LINUX_SLL 113 /* Linux cooked socket capture */ -#define LINKTYPE_LTALK 114 /* Apple LocalTalk hardware */ -#define LINKTYPE_ECONET 115 /* Acorn Econet */ - -/* - * Reserved for use with OpenBSD ipfilter. - */ -#define LINKTYPE_IPFILTER 116 - -#define LINKTYPE_PFLOG 117 /* OpenBSD DLT_PFLOG */ -#define LINKTYPE_CISCO_IOS 118 /* For Cisco-internal use */ -#define LINKTYPE_PRISM_HEADER 119 /* 802.11+Prism II monitor mode */ -#define LINKTYPE_AIRONET_HEADER 120 /* FreeBSD Aironet driver stuff */ - -/* - * Reserved for Siemens HiPath HDLC. - */ -#define LINKTYPE_HHDLC 121 - -#define LINKTYPE_IP_OVER_FC 122 /* RFC 2625 IP-over-Fibre Channel */ -#define LINKTYPE_SUNATM 123 /* Solaris+SunATM */ - -/* - * Reserved as per request from Kent Dahlgren - * for private use. - */ -#define LINKTYPE_RIO 124 /* RapidIO */ -#define LINKTYPE_PCI_EXP 125 /* PCI Express */ -#define LINKTYPE_AURORA 126 /* Xilinx Aurora link layer */ - -#define LINKTYPE_IEEE802_11_RADIO 127 /* 802.11 plus BSD radio header */ - -/* - * Reserved for the TZSP encapsulation, as per request from - * Chris Waters - * TZSP is a generic encapsulation for any other link type, - * which includes a means to include meta-information - * with the packet, e.g. signal strength and channel - * for 802.11 packets. - */ -#define LINKTYPE_TZSP 128 /* Tazmen Sniffer Protocol */ - -#define LINKTYPE_ARCNET_LINUX 129 /* Linux-style headers */ - -/* - * Juniper-private data link types, as per request from - * Hannes Gredler . The corresponding - * DLT_s are used for passing on chassis-internal - * metainformation such as QOS profiles, etc.. - */ -#define LINKTYPE_JUNIPER_MLPPP 130 -#define LINKTYPE_JUNIPER_MLFR 131 -#define LINKTYPE_JUNIPER_ES 132 -#define LINKTYPE_JUNIPER_GGSN 133 -#define LINKTYPE_JUNIPER_MFR 134 -#define LINKTYPE_JUNIPER_ATM2 135 -#define LINKTYPE_JUNIPER_SERVICES 136 -#define LINKTYPE_JUNIPER_ATM1 137 - -#define LINKTYPE_APPLE_IP_OVER_IEEE1394 138 /* Apple IP-over-IEEE 1394 cooked header */ - -#define LINKTYPE_RAWSS7 139 /* see rawss7.h for */ -#define LINKTYPE_RAWSS7_MTP2 140 /* information on these */ -#define LINKTYPE_RAWSS7_MTP3 141 /* definitions */ -#define LINKTYPE_RAWSS7_SCCP 142 - -/* - * This isn't supported in libpcap 0.8[.x], but is supported in the - * current CVS version; we include it here to note that it's not available - * for anybody else to use. - */ -#define LINKTYPE_DOCSIS 143 /* DOCSIS MAC frames */ - -#define LINKTYPE_LINUX_IRDA 144 /* Linux-IrDA */ - -/* - * Reserved for IBM SP switch and IBM Next Federation switch. - */ -#define LINKTYPE_IBM_SP 145 -#define LINKTYPE_IBM_SN 146 - -/* - * Reserved for private use. If you have some link-layer header type - * that you want to use within your organization, with the capture files - * using that link-layer header type not ever be sent outside your - * organization, you can use these values. - * - * No libpcap release will use these for any purpose, nor will any - * tcpdump release use them, either. - * - * Do *NOT* use these in capture files that you expect anybody not using - * your private versions of capture-file-reading tools to read; in - * particular, do *NOT* use them in products, otherwise you may find that - * people won't be able to use tcpdump, or snort, or Ethereal, or... to - * read capture files from your firewall/intrusion detection/traffic - * monitoring/etc. appliance, or whatever product uses that LINKTYPE_ value, - * and you may also find that the developers of those applications will - * not accept patches to let them read those files. - * - * Also, do not use them if somebody might send you a capture using them - * for *their* private type and tools using them for *your* private type - * would have to read them. - * - * Instead, in those cases, ask "tcpdump-workers@tcpdump.org" for a new DLT_ - * and LINKTYPE_ value, as per the comment in pcap-bpf.h, and use the type - * you're given. - */ -#define LINKTYPE_USER0 147 -#define LINKTYPE_USER1 148 -#define LINKTYPE_USER2 149 -#define LINKTYPE_USER3 150 -#define LINKTYPE_USER4 151 -#define LINKTYPE_USER5 152 -#define LINKTYPE_USER6 153 -#define LINKTYPE_USER7 154 -#define LINKTYPE_USER8 155 -#define LINKTYPE_USER9 156 -#define LINKTYPE_USER10 157 -#define LINKTYPE_USER11 158 -#define LINKTYPE_USER12 159 -#define LINKTYPE_USER13 160 -#define LINKTYPE_USER14 161 -#define LINKTYPE_USER15 162 - -/* - * For future use with 802.11 captures - defined by AbsoluteValue - * Systems to store a number of bits of link-layer information - * including radio information: - * - * http://www.shaftnet.org/~pizza/software/capturefrm.txt - * - * but could and arguably should also be used by non-AVS Linux - * 802.11 drivers; that may happen in the future. - */ -#define LINKTYPE_IEEE802_11_RADIO_AVS 163 /* 802.11 plus AVS radio header */ - -/* - * Juniper-private data link type, as per request from - * Hannes Gredler . The corresponding - * DLT_s are used for passing on chassis-internal - * metainformation such as QOS profiles, etc.. - */ -#define LINKTYPE_JUNIPER_MONITOR 164 - -static struct linktype_map { - int dlt; - int linktype; -} map[] = { - /* - * These DLT_* codes have LINKTYPE_* codes with values identical - * to the values of the corresponding DLT_* code. - */ - { DLT_NULL, LINKTYPE_NULL }, - { DLT_EN10MB, LINKTYPE_ETHERNET }, - { DLT_EN3MB, LINKTYPE_EXP_ETHERNET }, - { DLT_AX25, LINKTYPE_AX25 }, - { DLT_PRONET, LINKTYPE_PRONET }, - { DLT_CHAOS, LINKTYPE_CHAOS }, - { DLT_IEEE802, LINKTYPE_TOKEN_RING }, - { DLT_ARCNET, LINKTYPE_ARCNET }, - { DLT_SLIP, LINKTYPE_SLIP }, - { DLT_PPP, LINKTYPE_PPP }, - { DLT_FDDI, LINKTYPE_FDDI }, - - /* - * These DLT_* codes have different values on different - * platforms; we map them to LINKTYPE_* codes that - * have values that should never be equal to any DLT_* - * code. - */ -#ifdef DLT_FR - /* BSD/OS Frame Relay */ - { DLT_FR, LINKTYPE_FRELAY }, -#endif - - { DLT_SYMANTEC_FIREWALL, LINKTYPE_SYMANTEC_FIREWALL }, - { DLT_ATM_RFC1483, LINKTYPE_ATM_RFC1483 }, - { DLT_RAW, LINKTYPE_RAW }, - { DLT_SLIP_BSDOS, LINKTYPE_SLIP_BSDOS }, - { DLT_PPP_BSDOS, LINKTYPE_PPP_BSDOS }, - - /* BSD/OS Cisco HDLC */ - { DLT_C_HDLC, LINKTYPE_C_HDLC }, - - /* - * These DLT_* codes are not on all platforms, but, so far, - * there don't appear to be any platforms that define - * other codes with those values; we map them to - * different LINKTYPE_* values anyway, just in case. - */ - - /* Linux ATM Classical IP */ - { DLT_ATM_CLIP, LINKTYPE_ATM_CLIP }, - - /* NetBSD sync/async serial PPP (or Cisco HDLC) */ - { DLT_PPP_SERIAL, LINKTYPE_PPP_HDLC }, - - /* NetBSD PPP over Ethernet */ - { DLT_PPP_ETHER, LINKTYPE_PPP_ETHER }, - - /* IEEE 802.11 wireless */ - { DLT_IEEE802_11, LINKTYPE_IEEE802_11 }, - - /* Frame Relay */ - { DLT_FRELAY, LINKTYPE_FRELAY }, - - /* OpenBSD loopback */ - { DLT_LOOP, LINKTYPE_LOOP }, - - /* Linux cooked socket capture */ - { DLT_LINUX_SLL, LINKTYPE_LINUX_SLL }, - - /* Apple LocalTalk hardware */ - { DLT_LTALK, LINKTYPE_LTALK }, - - /* Acorn Econet */ - { DLT_ECONET, LINKTYPE_ECONET }, - - /* OpenBSD DLT_PFLOG */ - { DLT_PFLOG, LINKTYPE_PFLOG }, - - /* For Cisco-internal use */ - { DLT_CISCO_IOS, LINKTYPE_CISCO_IOS }, - - /* Prism II monitor-mode header plus 802.11 header */ - { DLT_PRISM_HEADER, LINKTYPE_PRISM_HEADER }, - - /* FreeBSD Aironet driver stuff */ - { DLT_AIRONET_HEADER, LINKTYPE_AIRONET_HEADER }, - - /* Siemens HiPath HDLC */ - { DLT_HHDLC, LINKTYPE_HHDLC }, - - /* RFC 2625 IP-over-Fibre Channel */ - { DLT_IP_OVER_FC, LINKTYPE_IP_OVER_FC }, - - /* Solaris+SunATM */ - { DLT_SUNATM, LINKTYPE_SUNATM }, - - /* RapidIO */ - { DLT_RIO, LINKTYPE_RIO }, - - /* PCI Express */ - { DLT_PCI_EXP, LINKTYPE_PCI_EXP }, - - /* Xilinx Aurora link layer */ - { DLT_AURORA, LINKTYPE_AURORA }, - - /* 802.11 plus BSD radio header */ - { DLT_IEEE802_11_RADIO, LINKTYPE_IEEE802_11_RADIO }, - - /* Tazmen Sniffer Protocol */ - { DLT_TZSP, LINKTYPE_TZSP }, - - /* Arcnet with Linux-style link-layer headers */ - { DLT_ARCNET_LINUX, LINKTYPE_ARCNET_LINUX }, - - /* Juniper-internal chassis encapsulation */ - { DLT_JUNIPER_MLPPP, LINKTYPE_JUNIPER_MLPPP }, - { DLT_JUNIPER_MLFR, LINKTYPE_JUNIPER_MLFR }, - { DLT_JUNIPER_ES, LINKTYPE_JUNIPER_ES }, - { DLT_JUNIPER_GGSN, LINKTYPE_JUNIPER_GGSN }, - { DLT_JUNIPER_MFR, LINKTYPE_JUNIPER_MFR }, - { DLT_JUNIPER_ATM2, LINKTYPE_JUNIPER_ATM2 }, - { DLT_JUNIPER_SERVICES, LINKTYPE_JUNIPER_SERVICES }, - { DLT_JUNIPER_ATM1, LINKTYPE_JUNIPER_ATM1 }, - - /* Apple IP-over-IEEE 1394 cooked header */ - { DLT_APPLE_IP_OVER_IEEE1394, LINKTYPE_APPLE_IP_OVER_IEEE1394 }, - - /* DOCSIS MAC frames */ - { DLT_DOCSIS, LINKTYPE_DOCSIS }, - - /* IrDA IrLAP packets + Linux-cooked header */ - { DLT_LINUX_IRDA, LINKTYPE_LINUX_IRDA }, - - /* IBM SP and Next Federation switches */ - { DLT_IBM_SP, LINKTYPE_IBM_SP }, - { DLT_IBM_SN, LINKTYPE_IBM_SN }, - - /* 802.11 plus AVS radio header */ - { DLT_IEEE802_11_RADIO_AVS, LINKTYPE_IEEE802_11_RADIO_AVS }, - - /* - * Any platform that defines additional DLT_* codes should: - * - * request a LINKTYPE_* code and value from tcpdump.org, - * as per the above; - * - * add, in their version of libpcap, an entry to map - * those DLT_* codes to the corresponding LINKTYPE_* - * code; - * - * redefine, in their "net/bpf.h", any DLT_* values - * that collide with the values used by their additional - * DLT_* codes, to remove those collisions (but without - * making them collide with any of the LINKTYPE_* - * values equal to 50 or above; they should also avoid - * defining DLT_* values that collide with those - * LINKTYPE_* values, either). - */ - - /* Juniper-internal chassis encapsulation */ - { DLT_JUNIPER_MONITOR, LINKTYPE_JUNIPER_MONITOR }, - - { -1, -1 } -}; - -static int -dlt_to_linktype(int dlt) -{ - int i; - - for (i = 0; map[i].dlt != -1; i++) { - if (map[i].dlt == dlt) - return (map[i].linktype); - } - - /* - * If we don't have a mapping for this DLT_ code, return an - * error; that means that the table above needs to have an - * entry added. - */ - return (-1); -} - -static int -linktype_to_dlt(int linktype) -{ - int i; - - for (i = 0; map[i].linktype != -1; i++) { - if (map[i].linktype == linktype) - return (map[i].dlt); - } - - /* - * If we don't have an entry for this link type, return - * the link type value; it may be a DLT_ value from an - * older version of libpcap. - */ - return linktype; -} - -static int -sf_write_header(FILE *fp, int linktype, int thiszone, int snaplen) -{ - struct pcap_file_header hdr; - - hdr.magic = TCPDUMP_MAGIC; - hdr.version_major = PCAP_VERSION_MAJOR; - hdr.version_minor = PCAP_VERSION_MINOR; - - hdr.thiszone = thiszone; - hdr.snaplen = snaplen; - hdr.sigfigs = 0; - hdr.linktype = linktype; - - if (fwrite((char *)&hdr, sizeof(hdr), 1, fp) != 1) - return (-1); - - return (0); -} - -static void -swap_hdr(struct pcap_file_header *hp) -{ - hp->version_major = SWAPSHORT(hp->version_major); - hp->version_minor = SWAPSHORT(hp->version_minor); - hp->thiszone = SWAPLONG(hp->thiszone); - hp->sigfigs = SWAPLONG(hp->sigfigs); - hp->snaplen = SWAPLONG(hp->snaplen); - hp->linktype = SWAPLONG(hp->linktype); -} - -static int -sf_getnonblock(pcap_t *p, char *errbuf) -{ - /* - * This is a savefile, not a live capture file, so never say - * it's in non-blocking mode. - */ - return (0); -} - -static int -sf_setnonblock(pcap_t *p, int nonblock, char *errbuf) -{ - /* - * This is a savefile, not a live capture file, so ignore - * requests to put it in non-blocking mode. - */ - return (0); -} - -static int -sf_stats(pcap_t *p, struct pcap_stat *ps) -{ - snprintf(p->errbuf, PCAP_ERRBUF_SIZE, - "Statistics aren't available from savefiles"); - return (-1); -} - -static void -sf_close(pcap_t *p) -{ - if (p->sf.rfile != stdin) - (void)fclose(p->sf.rfile); - if (p->sf.base != NULL) - free(p->sf.base); -} - -pcap_t * -pcap_open_offline(const char *fname, char *errbuf) -{ - register pcap_t *p; - register FILE *fp; - struct pcap_file_header hdr; - bpf_u_int32 magic; - int linklen; - - p = (pcap_t *)malloc(sizeof(*p)); - if (p == NULL) { - strlcpy(errbuf, "out of swap", PCAP_ERRBUF_SIZE); - return (NULL); - } - - memset((char *)p, 0, sizeof(*p)); - - if (fname[0] == '-' && fname[1] == '\0') - fp = stdin; - else { -#ifndef WIN32 - fp = fopen(fname, "r"); -#else - fp = fopen(fname, "rb"); -#endif - if (fp == NULL) { - snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", fname, - pcap_strerror(errno)); - goto bad; - } - } - if (fread((char *)&hdr, sizeof(hdr), 1, fp) != 1) { - snprintf(errbuf, PCAP_ERRBUF_SIZE, "fread: %s", - pcap_strerror(errno)); - goto bad; - } - magic = hdr.magic; - if (magic != TCPDUMP_MAGIC && magic != PATCHED_TCPDUMP_MAGIC) { - magic = SWAPLONG(magic); - if (magic != TCPDUMP_MAGIC && magic != PATCHED_TCPDUMP_MAGIC) { - snprintf(errbuf, PCAP_ERRBUF_SIZE, - "bad dump file format"); - goto bad; - } - p->sf.swapped = 1; - swap_hdr(&hdr); - } - if (magic == PATCHED_TCPDUMP_MAGIC) { - /* - * XXX - the patch that's in some versions of libpcap - * changes the packet header but not the magic number; - * we'd have to use some hacks^H^H^H^H^Hheuristics to - * detect that. - */ - p->sf.hdrsize = sizeof(struct pcap_sf_patched_pkthdr); - } else - p->sf.hdrsize = sizeof(struct pcap_sf_pkthdr); - if (hdr.version_major < PCAP_VERSION_MAJOR) { - snprintf(errbuf, PCAP_ERRBUF_SIZE, "archaic file format"); - goto bad; - } - p->tzoff = hdr.thiszone; - p->snapshot = hdr.snaplen; - p->linktype = linktype_to_dlt(hdr.linktype); - p->sf.rfile = fp; -#ifndef WIN32 - p->bufsize = hdr.snaplen; -#else - /* Allocate the space for pcap_pkthdr as well. It will be used by pcap_read_ex */ - p->bufsize = hdr.snaplen+sizeof(struct pcap_pkthdr); -#endif - - /* Align link header as required for proper data alignment */ - /* XXX should handle all types */ - switch (p->linktype) { - - case DLT_EN10MB: - linklen = 14; - break; - - case DLT_FDDI: - linklen = 13 + 8; /* fddi_header + llc */ - break; - - case DLT_NULL: - default: - linklen = 0; - break; - } - - if (p->bufsize < 0) - p->bufsize = BPF_MAXBUFSIZE; - p->sf.base = (u_char *)malloc(p->bufsize + BPF_ALIGNMENT); - if (p->sf.base == NULL) { - strlcpy(errbuf, "out of swap", PCAP_ERRBUF_SIZE); - goto bad; - } - p->buffer = p->sf.base + BPF_ALIGNMENT - (linklen % BPF_ALIGNMENT); - p->sf.version_major = hdr.version_major; - p->sf.version_minor = hdr.version_minor; -#ifdef PCAP_FDDIPAD - /* XXX padding only needed for kernel fcode */ - pcap_fddipad = 0; -#endif - - /* - * We interchanged the caplen and len fields at version 2.3, - * in order to match the bpf header layout. But unfortunately - * some files were written with version 2.3 in their headers - * but without the interchanged fields. - * - * In addition, DG/UX tcpdump writes out files with a version - * number of 543.0, and with the caplen and len fields in the - * pre-2.3 order. - */ - switch (hdr.version_major) { - - case 2: - if (hdr.version_minor < 3) - p->sf.lengths_swapped = SWAPPED; - else if (hdr.version_minor == 3) - p->sf.lengths_swapped = MAYBE_SWAPPED; - else - p->sf.lengths_swapped = NOT_SWAPPED; - break; - - case 543: - p->sf.lengths_swapped = SWAPPED; - break; - - default: - p->sf.lengths_swapped = NOT_SWAPPED; - break; - } - -#ifndef WIN32 - /* - * You can do "select()" and "poll()" on plain files on most - * platforms, and should be able to do so on pipes. - * - * You can't do "select()" on anything other than sockets in - * Windows, so, on Win32 systems, we don't have "selectable_fd". - */ - p->selectable_fd = fileno(fp); -#endif - - p->read_op = pcap_offline_read; - p->setfilter_op = install_bpf_program; - p->set_datalink_op = NULL; /* we don't support munging link-layer headers */ - p->getnonblock_op = sf_getnonblock; - p->setnonblock_op = sf_setnonblock; - p->stats_op = sf_stats; - p->close_op = sf_close; - - return (p); - bad: - if(fp) - fclose(fp); - free(p); - return (NULL); -} - -/* - * Read sf_readfile and return the next packet. Return the header in hdr - * and the contents in buf. Return 0 on success, SFERR_EOF if there were - * no more packets, and SFERR_TRUNC if a partial packet was encountered. - */ -static int -sf_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char *buf, u_int buflen) -{ - struct pcap_sf_patched_pkthdr sf_hdr; - FILE *fp = p->sf.rfile; - size_t amt_read; - bpf_u_int32 t; - - /* - * Read the packet header; the structure we use as a buffer - * is the longer structure for files generated by the patched - * libpcap, but if the file has the magic number for an - * unpatched libpcap we only read as many bytes as the regular - * header has. - */ - amt_read = fread(&sf_hdr, 1, p->sf.hdrsize, fp); - if (amt_read != p->sf.hdrsize) { - if (ferror(fp)) { - snprintf(p->errbuf, PCAP_ERRBUF_SIZE, - "error reading dump file: %s", - pcap_strerror(errno)); - return (-1); - } else { - if (amt_read != 0) { - snprintf(p->errbuf, PCAP_ERRBUF_SIZE, - "truncated dump file; tried to read %d header bytes, only got %lu", - p->sf.hdrsize, (unsigned long)amt_read); - return (-1); - } - /* EOF */ - return (1); - } - } - - if (p->sf.swapped) { - /* these were written in opposite byte order */ - hdr->caplen = SWAPLONG(sf_hdr.caplen); - hdr->len = SWAPLONG(sf_hdr.len); - hdr->ts.tv_sec = SWAPLONG(sf_hdr.ts.tv_sec); - hdr->ts.tv_usec = SWAPLONG(sf_hdr.ts.tv_usec); - } else { - hdr->caplen = sf_hdr.caplen; - hdr->len = sf_hdr.len; - hdr->ts.tv_sec = sf_hdr.ts.tv_sec; - hdr->ts.tv_usec = sf_hdr.ts.tv_usec; - } - /* Swap the caplen and len fields, if necessary. */ - switch (p->sf.lengths_swapped) { - - case NOT_SWAPPED: - break; - - case MAYBE_SWAPPED: - if (hdr->caplen <= hdr->len) { - /* - * The captured length is <= the actual length, - * so presumably they weren't swapped. - */ - break; - } - /* FALLTHROUGH */ - - case SWAPPED: - t = hdr->caplen; - hdr->caplen = hdr->len; - hdr->len = t; - break; - } - - if (hdr->caplen > buflen) { - /* - * This can happen due to Solaris 2.3 systems tripping - * over the BUFMOD problem and not setting the snapshot - * correctly in the savefile header. If the caplen isn't - * grossly wrong, try to salvage. - */ - static u_char *tp = NULL; - static size_t tsize = 0; - - if (hdr->caplen > 65535) { - snprintf(p->errbuf, PCAP_ERRBUF_SIZE, - "bogus savefile header"); - return (-1); - } - - if (tsize < hdr->caplen) { - tsize = ((hdr->caplen + 1023) / 1024) * 1024; - if (tp != NULL) - free((u_char *)tp); - tp = (u_char *)malloc(tsize); - if (tp == NULL) { - tsize = 0; - snprintf(p->errbuf, PCAP_ERRBUF_SIZE, - "BUFMOD hack malloc"); - return (-1); - } - } - amt_read = fread((char *)tp, 1, hdr->caplen, fp); - if (amt_read != hdr->caplen) { - if (ferror(fp)) { - snprintf(p->errbuf, PCAP_ERRBUF_SIZE, - "error reading dump file: %s", - pcap_strerror(errno)); - } else { - snprintf(p->errbuf, PCAP_ERRBUF_SIZE, - "truncated dump file; tried to read %u captured bytes, only got %lu", - hdr->caplen, (unsigned long)amt_read); - } - return (-1); - } - /* - * We can only keep up to buflen bytes. Since caplen > buflen - * is exactly how we got here, we know we can only keep the - * first buflen bytes and must drop the remainder. Adjust - * caplen accordingly, so we don't get confused later as - * to how many bytes we have to play with. - */ - hdr->caplen = buflen; - memcpy((char *)buf, (char *)tp, buflen); - - } else { - /* read the packet itself */ - amt_read = fread((char *)buf, 1, hdr->caplen, fp); - if (amt_read != hdr->caplen) { - if (ferror(fp)) { - snprintf(p->errbuf, PCAP_ERRBUF_SIZE, - "error reading dump file: %s", - pcap_strerror(errno)); - } else { - snprintf(p->errbuf, PCAP_ERRBUF_SIZE, - "truncated dump file; tried to read %u captured bytes, only got %lu", - hdr->caplen, (unsigned long)amt_read); - } - return (-1); - } - } - return (0); -} - -/* - * Print out packets stored in the file initialized by sf_read_init(). - * If cnt > 0, return after 'cnt' packets, otherwise continue until eof. - */ -int -pcap_offline_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) -{ - struct bpf_insn *fcode = p->fcode.bf_insns; - int status = 0; - int n = 0; - - while (status == 0) { - struct pcap_pkthdr h; - - /* - * Has "pcap_breakloop()" been called? - * If so, return immediately - if we haven't read any - * packets, clear the flag and return -2 to indicate - * that we were told to break out of the loop, otherwise - * leave the flag set, so that the *next* call will break - * out of the loop without having read any packets, and - * return the number of packets we've processed so far. - */ - if (p->break_loop) { - if (n == 0) { - p->break_loop = 0; - return (-2); - } else - return (n); - } - - status = sf_next_packet(p, &h, p->buffer, p->bufsize); - if (status) { - if (status == 1) - return (0); - return (status); - } - - if (fcode == NULL || - bpf_filter(fcode, p->buffer, h.len, h.caplen)) { - (*callback)(user, &h, p->buffer); - if (++n >= cnt && cnt > 0) - break; - } - } - /*XXX this breaks semantics tcpslice expects */ - return (n); -} - -/* - * Output a packet to the initialized dump file. - */ -void -pcap_dump(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) -{ - register FILE *f; - struct pcap_sf_pkthdr sf_hdr; - - f = (FILE *)user; - sf_hdr.ts.tv_sec = h->ts.tv_sec; - sf_hdr.ts.tv_usec = h->ts.tv_usec; - sf_hdr.caplen = h->caplen; - sf_hdr.len = h->len; - /* XXX we should check the return status */ - (void)fwrite(&sf_hdr, sizeof(sf_hdr), 1, f); - (void)fwrite((char *)sp, h->caplen, 1, f); -} - -/* - * Initialize so that sf_write() will output to the file named 'fname'. - */ -pcap_dumper_t * -pcap_dump_open(pcap_t *p, const char *fname) -{ - FILE *f; - int linktype; - - linktype = dlt_to_linktype(p->linktype); - if (linktype == -1) { - snprintf(p->errbuf, PCAP_ERRBUF_SIZE, - "%s: link-layer type %d isn't supported in savefiles", - fname, linktype); - return (NULL); - } - - if (fname[0] == '-' && fname[1] == '\0') { - f = stdout; -#ifdef WIN32 - _setmode(_fileno(f), _O_BINARY); -#endif - } else { -#ifndef WIN32 - f = fopen(fname, "w"); -#else - f = fopen(fname, "wb"); - setbuf(f, NULL); /* XXX - why? */ -#endif - if (f == NULL) { - snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s", - fname, pcap_strerror(errno)); - return (NULL); - } - } - (void)sf_write_header(f, linktype, p->tzoff, p->snapshot); - return ((pcap_dumper_t *)f); -} - -FILE * -pcap_dump_file(pcap_dumper_t *p) -{ - return ((FILE *)p); -} - -int -pcap_dump_flush(pcap_dumper_t *p) -{ - - if (fflush((FILE *)p) == EOF) - return (-1); - else - return (0); -} - -void -pcap_dump_close(pcap_dumper_t *p) -{ - -#ifdef notyet - if (ferror((FILE *)p)) - return-an-error; - /* XXX should check return from fclose() too */ -#endif - (void)fclose((FILE *)p); -} diff --git a/contrib/libpcap-0.8.3/scanner.l b/contrib/libpcap-0.8.3/scanner.l deleted file mode 100644 index 8acc61a772..0000000000 --- a/contrib/libpcap-0.8.3/scanner.l +++ /dev/null @@ -1,420 +0,0 @@ -%{ -/* - * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that: (1) source code distributions - * retain the above copyright notice and this paragraph in its entirety, (2) - * distributions including binary code include the above copyright notice and - * this paragraph in its entirety in the documentation or other materials - * provided with the distribution, and (3) all advertising materials mentioning - * features or use of this software display the following acknowledgement: - * ``This product includes software developed by the University of California, - * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of - * the University nor the names of its contributors may be used to endorse - * or promote products derived from this software without specific prior - * written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#ifndef lint -static 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 -#include - -#include "pcap-int.h" - -#include "gencode.h" -#ifdef INET6 -#ifdef WIN32 -#include - -#ifdef __MINGW32__ -#include "IP6_misc.h" -#endif -#else /* WIN32 */ -#include /* for "struct sockaddr" in "struct addrinfo" */ -#include /* for "struct addrinfo" */ -#endif /* WIN32 */ - -/* Workaround for AIX 4.3 */ -#if !defined(AI_NUMERICHOST) -#define AI_NUMERICHOST 0x04 -#endif -#endif /*INET6*/ -#include -#include "tokdefs.h" - -#ifdef HAVE_OS_PROTO_H -#include "os-proto.h" -#endif - -static int stoi(char *); -static inline int xdtoi(int); - -#ifdef FLEX_SCANNER -#define YY_NO_UNPUT -static YY_BUFFER_STATE in_buffer; -#else -static char *in_buffer; - -#undef getc -#define getc(fp) (*in_buffer == 0 ? EOF : *in_buffer++) -#endif - -#define yylval pcap_lval -extern YYSTYPE yylval; - -%} - -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 -%n 2000 - -V680 {W}:{W}:{W}:{W}:{W}:{W}:{W}:{W} - -V670 ::{W}:{W}:{W}:{W}:{W}:{W}:{W} -V671 {W}::{W}:{W}:{W}:{W}:{W}:{W} -V672 {W}:{W}::{W}:{W}:{W}:{W}:{W} -V673 {W}:{W}:{W}::{W}:{W}:{W}:{W} -V674 {W}:{W}:{W}:{W}::{W}:{W}:{W} -V675 {W}:{W}:{W}:{W}:{W}::{W}:{W} -V676 {W}:{W}:{W}:{W}:{W}:{W}::{W} -V677 {W}:{W}:{W}:{W}:{W}:{W}:{W}:: - -V660 ::{W}:{W}:{W}:{W}:{W}:{W} -V661 {W}::{W}:{W}:{W}:{W}:{W} -V662 {W}:{W}::{W}:{W}:{W}:{W} -V663 {W}:{W}:{W}::{W}:{W}:{W} -V664 {W}:{W}:{W}:{W}::{W}:{W} -V665 {W}:{W}:{W}:{W}:{W}::{W} -V666 {W}:{W}:{W}:{W}:{W}:{W}:: - -V650 ::{W}:{W}:{W}:{W}:{W} -V651 {W}::{W}:{W}:{W}:{W} -V652 {W}:{W}::{W}:{W}:{W} -V653 {W}:{W}:{W}::{W}:{W} -V654 {W}:{W}:{W}:{W}::{W} -V655 {W}:{W}:{W}:{W}:{W}:: - -V640 ::{W}:{W}:{W}:{W} -V641 {W}::{W}:{W}:{W} -V642 {W}:{W}::{W}:{W} -V643 {W}:{W}:{W}::{W} -V644 {W}:{W}:{W}:{W}:: - -V630 ::{W}:{W}:{W} -V631 {W}::{W}:{W} -V632 {W}:{W}::{W} -V633 {W}:{W}:{W}:: - -V620 ::{W}:{W} -V621 {W}::{W} -V622 {W}:{W}:: - -V610 ::{W} -V611 {W}:: - -V600 :: - -V6604 {W}:{W}:{W}:{W}:{W}:{W}:{N}\.{N}\.{N}\.{N} - -V6504 ::{W}:{W}:{W}:{W}:{W}:{N}\.{N}\.{N}\.{N} -V6514 {W}::{W}:{W}:{W}:{W}:{N}\.{N}\.{N}\.{N} -V6524 {W}:{W}::{W}:{W}:{W}:{N}\.{N}\.{N}\.{N} -V6534 {W}:{W}:{W}::{W}:{W}:{N}\.{N}\.{N}\.{N} -V6544 {W}:{W}:{W}:{W}::{W}:{N}\.{N}\.{N}\.{N} -V6554 {W}:{W}:{W}:{W}:{W}::{N}\.{N}\.{N}\.{N} - -V6404 ::{W}:{W}:{W}:{W}:{N}\.{N}\.{N}\.{N} -V6414 {W}::{W}:{W}:{W}:{N}\.{N}\.{N}\.{N} -V6424 {W}:{W}::{W}:{W}:{N}\.{N}\.{N}\.{N} -V6434 {W}:{W}:{W}::{W}:{N}\.{N}\.{N}\.{N} -V6444 {W}:{W}:{W}:{W}::{N}\.{N}\.{N}\.{N} - -V6304 ::{W}:{W}:{W}:{N}\.{N}\.{N}\.{N} -V6314 {W}::{W}:{W}:{N}\.{N}\.{N}\.{N} -V6324 {W}:{W}::{W}:{N}\.{N}\.{N}\.{N} -V6334 {W}:{W}:{W}::{N}\.{N}\.{N}\.{N} - -V6204 ::{W}:{W}:{N}\.{N}\.{N}\.{N} -V6214 {W}::{W}:{N}\.{N}\.{N}\.{N} -V6224 {W}:{W}::{N}\.{N}\.{N}\.{N} - -V6104 ::{W}:{N}\.{N}\.{N}\.{N} -V6114 {W}::{N}\.{N}\.{N}\.{N} - -V6004 ::{N}\.{N}\.{N}\.{N} - - -V6 ({V680}|{V670}|{V671}|{V672}|{V673}|{V674}|{V675}|{V676}|{V677}|{V660}|{V661}|{V662}|{V663}|{V664}|{V665}|{V666}|{V650}|{V651}|{V652}|{V653}|{V654}|{V655}|{V640}|{V641}|{V642}|{V643}|{V644}|{V630}|{V631}|{V632}|{V633}|{V620}|{V621}|{V622}|{V610}|{V611}|{V600}|{V6604}|{V6504}|{V6514}|{V6524}|{V6534}|{V6544}|{V6554}|{V6404}|{V6414}|{V6424}|{V6434}|{V6444}|{V6304}|{V6314}|{V6324}|{V6334}|{V6204}|{V6214}|{V6224}|{V6104}|{V6114}|{V6004}) - -%% -dst return DST; -src return SRC; - -link|ether|ppp|slip return LINK; -fddi|tr|wlan return LINK; -arp return ARP; -rarp return RARP; -ip return IP; -sctp return SCTP; -tcp return TCP; -udp return UDP; -icmp return ICMP; -igmp return IGMP; -igrp return IGRP; -pim return PIM; -vrrp return VRRP; - -ip6 { -#ifdef INET6 - return IPV6; -#else - bpf_error("%s not supported", yytext); -#endif - } -icmp6 { -#ifdef INET6 - return ICMPV6; -#else - bpf_error("%s not supported", yytext); -#endif - } -ah return AH; -esp return ESP; - -atalk return ATALK; -aarp return AARP; -decnet return DECNET; -lat return LAT; -sca return SCA; -moprc return MOPRC; -mopdl return MOPDL; - -iso return ISO; -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; - -ipx return IPX; - -netbeui return NETBEUI; - -host return HOST; -net return NET; -mask return NETMASK; -port return PORT; -proto return PROTO; -protochain { -#ifdef NO_PROTOCHAIN - bpf_error("%s not supported", yytext); -#else - return PROTOCHAIN; -#endif - } - -gateway return GATEWAY; - -less return LESS; -greater return GREATER; -byte return CBYTE; -broadcast return TK_BROADCAST; -multicast return TK_MULTICAST; - -and|"&&" return AND; -or|"||" return OR; -not return '!'; - -len|length return LEN; -inbound return INBOUND; -outbound return OUTBOUND; - -vlan return VLAN; - -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; -"!=" return NEQ; -"==" return '='; -"<<" return LSH; -">>" return RSH; -${B} { yylval.e = pcap_ether_aton(((char *)yytext)+1); - return AID; } -{N} { yylval.i = stoi((char *)yytext); return NUM; } -({N}\.{N})|({N}\.{N}\.{N})|({N}\.{N}\.{N}\.{N}) { - yylval.s = sdup((char *)yytext); return HID; } -{B}:{B}:{B}:{B}:{B}:{B} { yylval.e = pcap_ether_aton((char *)yytext); - return EID; } -{V6} { -#ifdef INET6 - struct addrinfo hints, *res; - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_INET6; - hints.ai_flags = AI_NUMERICHOST; - if (getaddrinfo(yytext, NULL, &hints, &res)) - bpf_error("bogus IPv6 address %s", yytext); - else { - yylval.s = sdup((char *)yytext); return HID6; - } -#else - bpf_error("IPv6 address %s not supported", yytext); -#endif /*INET6*/ - } -{B}:+({B}:+)+ { bpf_error("bogus ethernet address %s", yytext); } -icmptype { yylval.i = 0; return NUM; } -icmpcode { yylval.i = 1; return NUM; } -icmp-echoreply { yylval.i = 0; return NUM; } -icmp-unreach { yylval.i = 3; return NUM; } -icmp-sourcequench { yylval.i = 4; return NUM; } -icmp-redirect { yylval.i = 5; return NUM; } -icmp-echo { yylval.i = 8; return NUM; } -icmp-routeradvert { yylval.i = 9; return NUM; } -icmp-routersolicit { yylval.i = 10; return NUM; } -icmp-timxceed { yylval.i = 11; return NUM; } -icmp-paramprob { yylval.i = 12; return NUM; } -icmp-tstamp { yylval.i = 13; return NUM; } -icmp-tstampreply { yylval.i = 14; return NUM; } -icmp-ireq { yylval.i = 15; return NUM; } -icmp-ireqreply { yylval.i = 16; return NUM; } -icmp-maskreq { yylval.i = 17; return NUM; } -icmp-maskreply { yylval.i = 18; return NUM; } -tcpflags { yylval.i = 13; return NUM; } -tcp-fin { yylval.i = 0x01; return NUM; } -tcp-syn { yylval.i = 0x02; return NUM; } -tcp-rst { yylval.i = 0x04; return NUM; } -tcp-push { yylval.i = 0x08; return NUM; } -tcp-ack { yylval.i = 0x10; return NUM; } -tcp-urg { yylval.i = 0x20; return NUM; } -[A-Za-z0-9]([-_.A-Za-z0-9]*[.A-Za-z0-9])? { - yylval.s = sdup((char *)yytext); return ID; } -"\\"[^ !()\n\t]+ { yylval.s = sdup((char *)yytext + 1); return ID; } -[^ \[\]\t\n\-_.A-Za-z0-9!<>()&|=]+ { - bpf_error("illegal token: %s", yytext); } -. { bpf_error("illegal char '%c'", *yytext); } -%% -void -lex_init(buf) - char *buf; -{ -#ifdef FLEX_SCANNER - in_buffer = yy_scan_string(buf); -#else - in_buffer = buf; -#endif -} - -/* - * Do any cleanup necessary after parsing. - */ -void -lex_cleanup() -{ -#ifdef FLEX_SCANNER - if (in_buffer != NULL) - yy_delete_buffer(in_buffer); - in_buffer = NULL; -#endif -} - -/* - * Also define a yywrap. Note that if we're using flex, it will - * define a macro to map this identifier to pcap_wrap. - */ -int -yywrap() -{ - return 1; -} - -/* Hex digit to integer. */ -static inline int -xdtoi(c) - register int c; -{ - if (isdigit(c)) - return c - '0'; - else if (islower(c)) - return c - 'a' + 10; - else - return c - 'A' + 10; -} - -/* - * Convert string to integer. Just like atoi(), but checks for - * preceding 0x or 0 and uses hex or octal instead of decimal. - */ -static int -stoi(s) - char *s; -{ - int base = 10; - int n = 0; - - if (*s == '0') { - if (s[1] == 'x' || s[1] == 'X') { - s += 2; - base = 16; - } - else { - base = 8; - s += 1; - } - } - while (*s) - n = n * base + xdtoi(*s++); - - return n; -} diff --git a/contrib/libpcap-0.8.3/sll.h b/contrib/libpcap-0.8.3/sll.h deleted file mode 100644 index 85a3a9d97d..0000000000 --- a/contrib/libpcap-0.8.3/sll.h +++ /dev/null @@ -1,124 +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. - * - * @(#) $Header: /tcpdump/master/libpcap/sll.h,v 1.7 2002/06/11 17:04:48 itojun Exp $ (LBL) - */ - -/* - * For captures on Linux cooked sockets, we construct a fake header - * that includes: - * - * a 2-byte "packet type" which is one of: - * - * LINUX_SLL_HOST packet was sent to us - * LINUX_SLL_BROADCAST packet was broadcast - * LINUX_SLL_MULTICAST packet was multicast - * LINUX_SLL_OTHERHOST packet was sent to somebody else - * LINUX_SLL_OUTGOING packet was sent *by* us; - * - * a 2-byte Ethernet protocol field; - * - * a 2-byte link-layer type; - * - * a 2-byte link-layer address length; - * - * an 8-byte source link-layer address, whose actual length is - * specified by the previous value. - * - * All fields except for the link-layer address are in network byte order. - * - * DO NOT change the layout of this structure, or change any of the - * LINUX_SLL_ values below. If you must change the link-layer header - * for a "cooked" Linux capture, introduce a new DLT_ type (ask - * "tcpdump-workers@tcpdump.org" for one, so that you don't give it a - * value that collides with a value already being used), and use the - * new header in captures of that type, so that programs that can - * handle DLT_LINUX_SLL captures will continue to handle them correctly - * without any change, and so that capture files with different headers - * can be told apart and programs that read them can dissect the - * packets in them. - */ - -/* - * A DLT_LINUX_SLL fake link-layer header. - */ -#define SLL_HDR_LEN 16 /* total header length */ -#define SLL_ADDRLEN 8 /* length of address field */ - -struct sll_header { - u_int16_t sll_pkttype; /* packet type */ - u_int16_t sll_hatype; /* link-layer address type */ - u_int16_t sll_halen; /* link-layer address length */ - u_int8_t sll_addr[SLL_ADDRLEN]; /* link-layer address */ - u_int16_t sll_protocol; /* protocol */ -}; - -/* - * The LINUX_SLL_ values for "sll_pkttype"; these correspond to the - * PACKET_ values on Linux, but are defined here so that they're - * available even on systems other than Linux, and so that they - * don't change even if the PACKET_ values change. - */ -#define LINUX_SLL_HOST 0 -#define LINUX_SLL_BROADCAST 1 -#define LINUX_SLL_MULTICAST 2 -#define LINUX_SLL_OTHERHOST 3 -#define LINUX_SLL_OUTGOING 4 - -/* - * The LINUX_SLL_ values for "sll_protocol"; these correspond to the - * ETH_P_ values on Linux, but are defined here so that they're - * available even on systems other than Linux. We assume, for now, - * that the ETH_P_ values won't change in Linux; if they do, then: - * - * if we don't translate them in "pcap-linux.c", capture files - * won't necessarily be readable if captured on a system that - * defines ETH_P_ values that don't match these values; - * - * if we do translate them in "pcap-linux.c", that makes life - * unpleasant for the BPF code generator, as the values you test - * for in the kernel aren't the values that you test for when - * reading a capture file, so the fixup code run on BPF programs - * handed to the kernel ends up having to do more work. - * - * Add other values here as necessary, for handling packet types that - * might show up on non-Ethernet, non-802.x networks. (Not all the ones - * in the Linux "if_ether.h" will, I suspect, actually show up in - * captures.) - */ -#define LINUX_SLL_P_802_3 0x0001 /* Novell 802.3 frames without 802.2 LLC header */ -#define LINUX_SLL_P_802_2 0x0004 /* 802.2 frames (not D/I/X Ethernet) */ diff --git a/contrib/libpcap-0.8.3/snprintf.c b/contrib/libpcap-0.8.3/snprintf.c deleted file mode 100644 index 111e78ede9..0000000000 --- a/contrib/libpcap-0.8.3/snprintf.c +++ /dev/null @@ -1,632 +0,0 @@ -/* - * Copyright (c) 1995-1999 Kungliga Tekniska Högskolan - * (Royal Institute of Technology, Stockholm, Sweden). - * 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. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - */ - -/* $Id: snprintf.c,v 1.1 2003/12/15 01:35:05 guy Exp $ */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#ifndef lint -static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/libpcap/snprintf.c,v 1.1 2003/12/15 01:35:05 guy Exp $"; -#endif - -#include -#include -#include -#include -#include -#include - -#include - -enum format_flags { - minus_flag = 1, - plus_flag = 2, - space_flag = 4, - alternate_flag = 8, - zero_flag = 16 -}; - -/* - * Common state - */ - -struct state { - unsigned char *str; - unsigned char *s; - unsigned char *theend; - size_t sz; - size_t max_sz; - int (*append_char)(struct state *, unsigned char); - int (*reserve)(struct state *, size_t); - /* XXX - methods */ -}; - -#ifndef HAVE_VSNPRINTF -static int -sn_reserve (struct state *state, size_t n) -{ - return state->s + n > state->theend; -} - -static int -sn_append_char (struct state *state, unsigned char c) -{ - if (sn_reserve (state, 1)) { - return 1; - } else { - *state->s++ = c; - return 0; - } -} -#endif - -#if 0 -static int -as_reserve (struct state *state, size_t n) -{ - if (state->s + n > state->theend) { - int off = state->s - state->str; - unsigned char *tmp; - - if (state->max_sz && state->sz >= state->max_sz) - return 1; - - state->sz = max(state->sz * 2, state->sz + n); - if (state->max_sz) - state->sz = min(state->sz, state->max_sz); - tmp = realloc (state->str, state->sz); - if (tmp == NULL) - return 1; - state->str = tmp; - state->s = state->str + off; - state->theend = state->str + state->sz - 1; - } - return 0; -} - -static int -as_append_char (struct state *state, unsigned char c) -{ - if(as_reserve (state, 1)) - return 1; - else { - *state->s++ = c; - return 0; - } -} -#endif - -static int -append_number(struct state *state, - unsigned long num, unsigned base, char *rep, - int width, int prec, int flags, int minusp) -{ - int len = 0; - int i; - - /* given precision, ignore zero flag */ - if(prec != -1) - flags &= ~zero_flag; - else - prec = 1; - /* zero value with zero precision -> "" */ - if(prec == 0 && num == 0) - return 0; - do{ - if((*state->append_char)(state, rep[num % base])) - return 1; - len++; - num /= base; - }while(num); - prec -= len; - /* pad with prec zeros */ - while(prec-- > 0){ - if((*state->append_char)(state, '0')) - return 1; - len++; - } - /* add length of alternate prefix (added later) to len */ - if(flags & alternate_flag && (base == 16 || base == 8)) - len += base / 8; - /* pad with zeros */ - if(flags & zero_flag){ - width -= len; - if(minusp || (flags & space_flag) || (flags & plus_flag)) - width--; - while(width-- > 0){ - if((*state->append_char)(state, '0')) - return 1; - len++; - } - } - /* add alternate prefix */ - if(flags & alternate_flag && (base == 16 || base == 8)){ - if(base == 16) - if((*state->append_char)(state, rep[10] + 23)) /* XXX */ - return 1; - if((*state->append_char)(state, '0')) - return 1; - } - /* add sign */ - if(minusp){ - if((*state->append_char)(state, '-')) - return 1; - len++; - } else if(flags & plus_flag) { - if((*state->append_char)(state, '+')) - return 1; - len++; - } else if(flags & space_flag) { - if((*state->append_char)(state, ' ')) - return 1; - len++; - } - if(flags & minus_flag) - /* swap before padding with spaces */ - for(i = 0; i < len / 2; i++){ - char c = state->s[-i-1]; - state->s[-i-1] = state->s[-len+i]; - state->s[-len+i] = c; - } - width -= len; - while(width-- > 0){ - if((*state->append_char)(state, ' ')) - return 1; - len++; - } - if(!(flags & minus_flag)) - /* swap after padding with spaces */ - for(i = 0; i < len / 2; i++){ - char c = state->s[-i-1]; - state->s[-i-1] = state->s[-len+i]; - state->s[-len+i] = c; - } - - return 0; -} - -static int -append_string (struct state *state, - unsigned char *arg, - int width, - int prec, - int flags) -{ - if(prec != -1) - width -= prec; - else - width -= strlen((char *)arg); - if(!(flags & minus_flag)) - while(width-- > 0) - if((*state->append_char) (state, ' ')) - return 1; - if (prec != -1) { - while (*arg && prec--) - if ((*state->append_char) (state, *arg++)) - return 1; - } else { - while (*arg) - if ((*state->append_char) (state, *arg++)) - return 1; - } - if(flags & minus_flag) - while(width-- > 0) - if((*state->append_char) (state, ' ')) - return 1; - return 0; -} - -static int -append_char(struct state *state, - unsigned char arg, - int width, - int flags) -{ - while(!(flags & minus_flag) && --width > 0) - if((*state->append_char) (state, ' ')) - return 1; - - if((*state->append_char) (state, arg)) - return 1; - while((flags & minus_flag) && --width > 0) - if((*state->append_char) (state, ' ')) - return 1; - - return 0; -} - -/* - * This can't be made into a function... - */ - -#define PARSE_INT_FORMAT(res, arg, unsig) \ -if (long_flag) \ - res = (unsig long)va_arg(arg, unsig long); \ -else if (short_flag) \ - res = (unsig short)va_arg(arg, unsig int); \ -else \ - res = (unsig int)va_arg(arg, unsig int) - -/* - * zyxprintf - return 0 or -1 - */ - -static int -xyzprintf (struct state *state, const char *char_format, va_list ap) -{ - const unsigned char *format = (const unsigned char *)char_format; - unsigned char c; - - while((c = *format++)) { - if (c == '%') { - int flags = 0; - int width = 0; - int prec = -1; - int long_flag = 0; - int short_flag = 0; - - /* flags */ - while((c = *format++)){ - if(c == '-') - flags |= minus_flag; - else if(c == '+') - flags |= plus_flag; - else if(c == ' ') - flags |= space_flag; - else if(c == '#') - flags |= alternate_flag; - else if(c == '0') - flags |= zero_flag; - else - break; - } - - if((flags & space_flag) && (flags & plus_flag)) - flags ^= space_flag; - - if((flags & minus_flag) && (flags & zero_flag)) - flags ^= zero_flag; - - /* width */ - if (isdigit(c)) - do { - width = width * 10 + c - '0'; - c = *format++; - } while(isdigit(c)); - else if(c == '*') { - width = va_arg(ap, int); - c = *format++; - } - - /* precision */ - if (c == '.') { - prec = 0; - c = *format++; - if (isdigit(c)) - do { - prec = prec * 10 + c - '0'; - c = *format++; - } while(isdigit(c)); - else if (c == '*') { - prec = va_arg(ap, int); - c = *format++; - } - } - - /* size */ - - if (c == 'h') { - short_flag = 1; - c = *format++; - } else if (c == 'l') { - long_flag = 1; - c = *format++; - } - - switch (c) { - case 'c' : - if(append_char(state, va_arg(ap, int), width, flags)) - return -1; - break; - case 's' : - if (append_string(state, - va_arg(ap, unsigned char*), - width, - prec, - flags)) - return -1; - break; - case 'd' : - case 'i' : { - long arg; - unsigned long num; - int minusp = 0; - - PARSE_INT_FORMAT(arg, ap, signed); - - if (arg < 0) { - minusp = 1; - num = -arg; - } else - num = arg; - - if (append_number (state, num, 10, "0123456789", - width, prec, flags, minusp)) - return -1; - break; - } - case 'u' : { - unsigned long arg; - - PARSE_INT_FORMAT(arg, ap, unsigned); - - if (append_number (state, arg, 10, "0123456789", - width, prec, flags, 0)) - return -1; - break; - } - case 'o' : { - unsigned long arg; - - PARSE_INT_FORMAT(arg, ap, unsigned); - - if (append_number (state, arg, 010, "01234567", - width, prec, flags, 0)) - return -1; - break; - } - case 'x' : { - unsigned long arg; - - PARSE_INT_FORMAT(arg, ap, unsigned); - - if (append_number (state, arg, 0x10, "0123456789abcdef", - width, prec, flags, 0)) - return -1; - break; - } - case 'X' :{ - unsigned long arg; - - PARSE_INT_FORMAT(arg, ap, unsigned); - - if (append_number (state, arg, 0x10, "0123456789ABCDEF", - width, prec, flags, 0)) - return -1; - break; - } - case 'p' : { - unsigned long arg = (unsigned long)va_arg(ap, void*); - - if (append_number (state, arg, 0x10, "0123456789ABCDEF", - width, prec, flags, 0)) - return -1; - break; - } - case 'n' : { - int *arg = va_arg(ap, int*); - *arg = state->s - state->str; - break; - } - case '\0' : - --format; - /* FALLTHROUGH */ - case '%' : - if ((*state->append_char)(state, c)) - return -1; - break; - default : - if ( (*state->append_char)(state, '%') - || (*state->append_char)(state, c)) - return -1; - break; - } - } else - if ((*state->append_char) (state, c)) - return -1; - } - return 0; -} - -#ifndef HAVE_SNPRINTF -int -snprintf (char *str, size_t sz, const char *format, ...) -{ - va_list args; - int ret; - - va_start(args, format); - ret = vsnprintf (str, sz, format, args); - -#ifdef PARANOIA - { - int ret2; - char *tmp; - - tmp = malloc (sz); - if (tmp == NULL) - abort (); - - ret2 = vsprintf (tmp, format, args); - if (ret != ret2 || strcmp(str, tmp)) - abort (); - free (tmp); - } -#endif - - va_end(args); - return ret; -} -#endif - -#if 0 -#ifndef HAVE_ASPRINTF -int -asprintf (char **ret, const char *format, ...) -{ - va_list args; - int val; - - va_start(args, format); - val = vasprintf (ret, format, args); - -#ifdef PARANOIA - { - int ret2; - char *tmp; - tmp = malloc (val + 1); - if (tmp == NULL) - abort (); - - ret2 = vsprintf (tmp, format, args); - if (val != ret2 || strcmp(*ret, tmp)) - abort (); - free (tmp); - } -#endif - - va_end(args); - return val; -} -#endif - -#ifndef HAVE_ASNPRINTF -int -asnprintf (char **ret, size_t max_sz, const char *format, ...) -{ - va_list args; - int val; - - va_start(args, format); - val = vasnprintf (ret, max_sz, format, args); - -#ifdef PARANOIA - { - int ret2; - char *tmp; - tmp = malloc (val + 1); - if (tmp == NULL) - abort (); - - ret2 = vsprintf (tmp, format, args); - if (val != ret2 || strcmp(*ret, tmp)) - abort (); - free (tmp); - } -#endif - - va_end(args); - return val; -} -#endif - -#ifndef HAVE_VASPRINTF -int -vasprintf (char **ret, const char *format, va_list args) -{ - return vasnprintf (ret, 0, format, args); -} -#endif - - -#ifndef HAVE_VASNPRINTF -int -vasnprintf (char **ret, size_t max_sz, const char *format, va_list args) -{ - int st; - size_t len; - struct state state; - - state.max_sz = max_sz; - state.sz = 1; - state.str = malloc(state.sz); - if (state.str == NULL) { - *ret = NULL; - return -1; - } - state.s = state.str; - state.theend = state.s + state.sz - 1; - state.append_char = as_append_char; - state.reserve = as_reserve; - - st = xyzprintf (&state, format, args); - if (st) { - free (state.str); - *ret = NULL; - return -1; - } else { - char *tmp; - - *state.s = '\0'; - len = state.s - state.str; - tmp = realloc (state.str, len+1); - if (tmp == NULL) { - free (state.str); - *ret = NULL; - return -1; - } - *ret = tmp; - return len; - } -} -#endif -#endif - -#ifndef HAVE_VSNPRINTF -int -vsnprintf (char *str, size_t sz, const char *format, va_list args) -{ - struct state state; - int ret; - unsigned char *ustr = (unsigned char *)str; - - state.max_sz = 0; - state.sz = sz; - state.str = ustr; - state.s = ustr; - state.theend = ustr + sz - 1; - state.append_char = sn_append_char; - state.reserve = sn_reserve; - - ret = xyzprintf (&state, format, args); - *state.s = '\0'; - if (ret) - return sz; - else - return state.s - state.str; -} -#endif - diff --git a/contrib/libpcap-0.8.3/sunatmpos.h b/contrib/libpcap-0.8.3/sunatmpos.h deleted file mode 100644 index 7538b2a9b6..0000000000 --- a/contrib/libpcap-0.8.3/sunatmpos.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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. - * - * @(#) $Header: /tcpdump/master/libpcap/sunatmpos.h,v 1.1 2002/07/11 09:06:47 guy Exp $ (LBL) - */ - -/* SunATM header for ATM packet */ -#define SUNATM_DIR_POS 0 -#define SUNATM_VPI_POS 1 -#define SUNATM_VCI_POS 2 -#define SUNATM_PKT_BEGIN_POS 4 /* Start of ATM packet */ - -/* Protocol type values in the bottom for bits of the byte at SUNATM_DIR_POS. */ -#define PT_LANE 0x01 /* LANE */ -#define PT_LLC 0x02 /* LLC encapsulation */ -#define PT_ILMI 0x05 /* ILMI */ -#define PT_QSAAL 0x06 /* Q.SAAL */ -- 2.41.0