+++ /dev/null
-@(#) $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 <assar@sics.se>
-- 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 <gdt@ir.bbn.com>
-- 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.
+++ /dev/null
-This file lists people who have contributed to libpcap:
-
-The current maintainers:
- Bill Fenner <fenner@research.att.com>
- Fulvio Risso <risso@polito.it>
- Guy Harris <guy@alum.mit.edu>
- Hannes Gredler <hannes@juniper.net>
- Jun-ichiro itojun Hagino <itojun@iijlab.net>
- Michael Richardson <mcr@sandelman.ottawa.on.ca>
-
-Additional people who have contributed patches:
-
- Alan Bawden <Alan@LCS.MIT.EDU>
- Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
- Albert Chin <china@thewrittenword.com>
- Andrew Brown <atatat@atatdot.net>
- Antti Kantee <pooka@netbsd.org>
- Arkadiusz Miskiewicz <misiek@pld.org.pl>
- Armando L. Caro Jr. <acaro@mail.eecis.udel.edu>
- Assar Westerlund <assar@sics.se>
- Brian Ginsbach <ginsbach@cray.com>
- Charles M. Hannum <mycroft@netbsd.org>
- Chris G. Demetriou <cgd@netbsd.org>
- Chris Pepper <pepper@mail.reppep.com>
- Darren Reed <darrenr@reed.wattle.id.au>
- David Kaelbling <drk@sgi.com>
- David Young <dyoung@ojctech.com>
- Don Ebright <Don.Ebright@compuware.com>
- Eric Anderson <anderse@hpl.hp.com>
- Franz Schaefer <schaefer@mond.at>
- Gianluca Varenni <varenni@netgroup-serv.polito.it>
- Gisle Vanem <giva@bgnett.no>
- Graeme Hewson <ghewson@cix.compulink.co.uk>
- Greg Stark <gsstark@mit.edu>
- Greg Troxel <gdt@ir.bbn.com>
- Guillaume Pelat <endymion_@users.sourceforge.net>
- Hyung Sik Yoon <hsyn@kr.ibm.com>
- Igor Khristophorov <igor@atdot.org>
- Jan-Philip Velders <jpv@veldersjes.net>
- Jason R. Thorpe <thorpej@netbsd.org>
- Javier Achirica <achirica@ttd.net>
- Jean Tourrilhes <jt@hpl.hp.com>
- Jefferson Ogata <jogata@nodc.noaa.gov>
- Jesper Peterson <jesper@endace.com>
- John Bankier <jbankier@rainfinity.com>
- Jon Lindgren <jonl@yubyub.net>
- Juergen Schoenwaelder <schoenw@ibr.cs.tu-bs.de>
- Kazushi Sugyo <sugyo@pb.jp.nec.com>
- Klaus Klein <kleink@netbsd.org>
- Koryn Grant <koryn@endace.com>
- Krzysztof Halasa <khc@pm.waw.pl>
- Lorenzo Cavallaro <sullivan@sikurezza.org>
- Loris Degioanni <loris@netgroup-serv.polito.it>
- Love Hörnquist-Åstrand <lha@stacken.kth.se>
- Maciej W. Rozycki <macro@ds2.pg.gda.pl>
- Marcus Felipe Pereira <marcus@task.com.br>
- Martin Husemann <martin@netbsd.org>
- Mike Wiacek <mike@iroot.net>
- Monroe Williams <monroe@pobox.com>
- Octavian Cerna <tavy@ylabs.com>
- Olaf Kirch <okir@caldera.de>
- Onno van der Linden <onno@simplex.nl>
- Paul Mundt <lethal@linux-sh.org>
- Pavel Kankovsky <kan@dcit.cz>
- Peter Fales <peter@fales-lorenz.net>
- Peter Jeremy <peter.jeremy@alcatel.com.au>
- Phil Wood <cpw@lanl.gov>
- Rafal Maszkowski <rzm@icm.edu.pl>
- Rick Jones <raj@cup.hp.com>
- Scott Barron <sb125499@ohiou.edu>
- Scott Gifford <sgifford@tir.com>
- Sebastian Krahmer <krahmer@cs.uni-potsdam.de>
- Shaun Clowes <delius@progsoc.uts.edu.au>
- Solomon Peachy <pizza@shaftnet.org>
- Stefan Hudson <hudson@mbay.net>
- Takashi Yamamoto <yamt@mwd.biglobe.ne.jp>
- Tony Li <tli@procket.com>
- Torsten Landschoff <torsten@debian.org>
- Uns Lider <unslider@miranda.org>
- Uwe Girlich <Uwe.Girlich@philosys.de>
- Xianjie Zhang <xzhang@cup.hp.com>
- Yen Yen Lim
- Yoann Vandoorselaere <yoann@prelude-ids.org>
-
-The original LBL crew:
- Steve McCanne
- Craig Leres
- Van Jacobson
+++ /dev/null
-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
+++ /dev/null
-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.
+++ /dev/null
-@(#) $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 <libpcap@ee.lbl.gov>
- 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
+++ /dev/null
-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
+++ /dev/null
-
-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
+++ /dev/null
- 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...
+++ /dev/null
-/*
- * 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 */
+++ /dev/null
-/*
- * 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
+++ /dev/null
-/*-
- * 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 <pcap-stdinc.h>
-
-#else /* WIN32 */
-
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/time.h>
-
-#define SOLARIS (defined(sun) && (defined(__SVR4) || defined(__svr4__)))
-#if defined(__hpux) || SOLARIS
-# include <sys/sysmacros.h>
-# include <sys/stream.h>
-# 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 <pcap-bpf.h>
-
-#if !defined(KERNEL) && !defined(_KERNEL)
-#include <stdlib.h>
-#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 <netinet/in.h>
-#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 <sys/mbuf.h>
-# 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;
-}
+++ /dev/null
-/*
- * 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 <pcap.h>
-#include <stdio.h>
-
-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));
- }
-}
+++ /dev/null
-/*
- * 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 <stdio.h>
-#include <string.h>
-
-#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;
-}
+++ /dev/null
-/*
- * 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 <sys/types.h>
-
-#include <ctype.h>
-#include <memory.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "pcap-int.h"
-
-#include <pcap-namedb.h>
-
-#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);
-}
+++ /dev/null
-/*
- * 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
- * <netinet/if_ether.h>, 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
- * <netinet/if_ether.h> 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
+++ /dev/null
-/* -*- 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 <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-
-#include <net/if.h>
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <ifaddrs.h>
-
-#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);
-}
+++ /dev/null
-/* -*- 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 <sys/param.h>
-#include <sys/file.h>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-#ifdef HAVE_SYS_SOCKIO_H
-#include <sys/sockio.h>
-#endif
-#include <sys/time.h> /* concession to AIX */
-
-struct mbuf; /* Squelch compiler warnings on some platforms for */
-struct rtentry; /* declarations in <net/if.h> */
-#include <net/if.h>
-#include <netinet/in.h>
-
-#include <ctype.h>
-#include <errno.h>
-#include <memory.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#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);
-}
+++ /dev/null
-/* -*- 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 <sys/param.h>
-#include <sys/file.h>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-#ifdef HAVE_SYS_SOCKIO_H
-#include <sys/sockio.h>
-#endif
-#include <sys/time.h> /* concession to AIX */
-
-struct mbuf; /* Squelch compiler warnings on some platforms for */
-struct rtentry; /* declarations in <net/if.h> */
-#include <net/if.h>
-#include <netinet/in.h>
-
-#include <ctype.h>
-#include <errno.h>
-#include <memory.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#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);
-}
+++ /dev/null
-/* -*- 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 <pcap.h>
-
-/*
- * 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);
-}
+++ /dev/null
-/*
- * 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 <pcap.h>
-#include <pcap-int.h>
-#include <packet32.h>
-
-#include <errno.h>
-
-/*
- * 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);
-}
+++ /dev/null
-/*#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 <pcap-stdinc.h>
-#else /* WIN32 */
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-#endif /* WIN32 */
-
-/*
- * XXX - why was this included even on UNIX?
- */
-#ifdef __MINGW32__
-#include "IP6_misc.h"
-#endif
-
-#ifndef WIN32
-
-#ifdef __NetBSD__
-#include <sys/param.h>
-#endif
-
-#include <netinet/in.h>
-
-#endif /* WIN32 */
-
-#include <stdlib.h>
-#include <string.h>
-#include <memory.h>
-#include <setjmp.h>
-#include <stdarg.h>
-
-#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 <netdb.h> /* for "struct addrinfo" */
-#endif /* WIN32 */
-#endif /*INET6*/
-#include <pcap-namedb.h>
-
-#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");
- /*