Import of libpcap 1.0.0.

This commit is contained in:
Rui Paulo 2009-03-21 20:43:56 +00:00
parent 3430dc7c1f
commit c6a6c5e28b
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/vendor/libpcap/dist/; revision=190214
svn path=/vendor/libpcap/1.0.0/; revision=190215; tag=vendor/libpcap/1.0.0
153 changed files with 22479 additions and 11765 deletions

57
CHANGES
View File

@ -1,28 +1,41 @@
@(#) $Header: /tcpdump/master/libpcap/CHANGES,v 1.59.2.13 2007/09/12 22:40:04 ken Exp $ (LBL)
@(#) $Header: /tcpdump/master/libpcap/CHANGES,v 1.67.2.4 2008-10-28 00:27:42 ken Exp $ (LBL)
Mon. September 10, 2007. ken@xelerance.com. Summary for 0.9.8 libpcap release
Change build process to put public libpcap headers into pcap subir
DLT: Add value for IPMI IPMB packets
DLT: Add value for u10 Networks boards
Require <net/pfvar.h> for pf definitions - allows reading of pflog formatted
libpcap files on an OS other than where the file was generated
Mon. October 27, 2008. ken@netfunctional.ca. Summary for 1.0.0 libpcap release
Compile with IPv6 support by default
Compile with large file support on by default
Add pcap-config script, which deals with -I/-L flags for compiling
DLT: Add IPMB
DLT: Add LAPD
DLT: Add AX25 (AX.25 w/KISS header)
DLT: Add JUNIPER_ST
802.15.4 support
Variable length 802.11 header support
X2E data type support
SITA ACN Interface support - see README.sita
Support for zerocopy BPF on platforms that support it
Better support for dealing with VLAN tagging/stripping on Linux
Fix dynamic library support on OSX
Return PCAP_ERROR_IFACE_NOT_UP if the interface isn't 'UP', so applications
can print better diagnostic information
Return PCAP_ERROR_PERM_DENIED if we don't have permission to open a device, so
applications can tell the user they need to go play with permissions
On Linux, ignore ENETDOWN so we can continue to capture packets if the
interface goes down and comes back up again.
On Linux, support new tpacket frame headers (2.6.27+)
On Mac OS X, add scripts for changing permissions on /dev/pbf* and launchd plist
On Solaris, support 'passive mode' on systems that support it
Fixes to autoconf and general build environment
Man page reorganization + cleanup
Autogenerate VERSION numbers better
Wed. July 23, 2007. mcr@xelerance.com. Summary for 0.9.7 libpcap release
Mon. September 10, 2007. ken@xelerance.com. Summary for 0.9.8 libpcap release
Change build process to put public libpcap headers into pcap subir
DLT: Add value for IPMI IPMB packets
DLT: Add value for u10 Networks boards
Require <net/pfvar.h> for pf definitions - allows reading of pflog formatted
libpcap files on an OS other than where the file was generated
FIXED version file to be 0.9.7 instead of 0.9.5.
added flags/configuration for cloning bpf device.
added DLT_MTP2_WITH_PHDR support (PPI)
"fix" the "memory leak" in icode_to_fcode() -- documentation bug
Various link-layer types, with a pseudo-header, for SITA http://www.sita.aero/
introduces support for the DAG ERF type TYPE_COLOR_MC_HDLC_POS.
Basic BPF filtering support for DLT_MTP2_WITH_PHDR is also added.
check for IPv4 and IPv6, even for DLT_RAW
add support for DLT_JUNIPER_ISM
Pick up changes from NetBSD: many from tron, christos, drochner
Allocate DLT_ for 802.15.4 without any header munging, for Mikko Saarnivala.
Header for 802.16 MAC Common Part Sublayer plus a radiotap radio header
Wed. April 25, 2007. ken@xelerance.com. Summary for 0.9.6 libpcap release
Wed. April 25, 2007. ken@xelerance.com. Summary for 0.9.6 libpcap release
Put the public libpcap headers into a pcap subdirectory in both the
source directory and the target include directory, and have include

210
CREDITS
View File

@ -1,108 +1,126 @@
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>
Bill Fenner <fenner at research dot att dot com>
Fulvio Risso <risso at polito dot it>
Guy Harris <guy at alum dot mit dot edu>
Hannes Gredler <hannes at juniper dot net>
Michael Richardson <mcr at sandelman dot ottawa dot on dot 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 Lightfoot <cwrl@users.sourceforge.net>
Chris Pepper <pepper@mail.reppep.com>
Daniele Orlandi <daniele@orlandi.com>
Darren Reed <darrenr@reed.wattle.id.au>
David Kaelbling <drk@sgi.com>
David Young <dyoung@ojctech.com>
Dean Gaudet <dean@arctic.org>
Don Ebright <Don.Ebright@compuware.com>
Dug Song <dugsong@monkey.org>
Eric Anderson <anderse@hpl.hp.com>
Erik de Castro Lopo <erik.de.castro.lopo@sensorynetworks.com>
Florent Drouin <Florent.Drouin@alcatel-lucent.fr>
Franz Schaefer <schaefer@mond.at>
Gianluca Varenni <varenni@netgroup-serv.polito.it>
Gilbert Hoyek <gil_hoyek@hotmail.com>
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>
Jung-uk Kim <jkim@FreeBSD.org>
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>
Mark C. Brown <mbrown@hp.com>
Mark Pizzolato <List-tcpdump-workers@subscriptions.pizzolato.net>
Martin Husemann <martin@netbsd.org>
Matthew Luckie <mjl@luckie.org.nz>
Max Laier <max@love2party.net>
Mike Kershaw <dragorn@kismetwireless.net>
Mike Wiacek <mike@iroot.net>
Monroe Williams <monroe@pobox.com>
Nicolas Dade <ndade@nsd.dyndns.org>
Octavian Cerna <tavy@ylabs.com>
Olaf Kirch <okir@caldera.de>
Ollie Wild <aaw@users.sourceforge.net>
Onno van der Linden <onno@simplex.nl>
Patrick Marie <mycroft@virgaria.org>
Paul Mundt <lethal@linux-sh.org>
Pavel Kankovsky <kan@dcit.cz>
Pawel Pokrywka <publicpp@gmail.com>
Peter Fales <peter@fales-lorenz.net>
Peter Jeremy <peter.jeremy@alcatel.com.au>
Phil Wood <cpw@lanl.gov>
Rafal Maszkowski <rzm@icm.edu.pl>
<rcb-isis@users.sourceforge.net>
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>
Stephen Donnelly <stephen@endace.com>
Takashi Yamamoto <yamt@mwd.biglobe.ne.jp>
Tanaka Shin-ya <zstanaka@archer.livedoor.com>
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>
Alan Bawden <Alan at LCS dot MIT dot EDU>
Alexander 'Leo' Bergolth <Leo dot Bergolth at wu-wien dot ac dot at>
Alexey Kuznetsov <kuznet at ms2 dot inr dot ac dot ru>
Albert Chin <china at thewrittenword dot com>
Andrew Brown <atatat at atatdot dot net>
Antti Kantee <pooka at netbsd dot org>
Arien Vijn <arienvijn at sourceforge dot net>
Arkadiusz Miskiewicz <misiek at pld dot org dot pl>
Armando L. Caro Jr. <acaro at mail dot eecis dot udel dot edu>
Assar Westerlund <assar at sics dot se>
Brian Ginsbach <ginsbach at cray dot com>
Charles M. Hannum <mycroft at netbsd dot org>
Chris G. Demetriou <cgd at netbsd dot org>
Chris Lightfoot <cwrl at users dot sourceforge dot net>
Chris Pepper <pepper at mail dot reppep dot com>
Christian Peron <csjp at freebsd dot org>
Daniele Orlandi <daniele at orlandi dot com>
Darren Reed <darrenr at reed dot wattle dot id dot au>
David Kaelbling <drk at sgi dot com>
David Young <dyoung at ojctech dot com>
Dean Gaudet <dean at arctic dot org>
Don Ebright <Don dot Ebright at compuware dot com>
Dug Song <dugsong at monkey dot org>
Eric Anderson <anderse at hpl dot hp dot com>
Erik de Castro Lopo <erik dot de dot castro dot lopo at sensorynetworks dot com>
Florent Drouin <Florent dot Drouin at alcatel-lucent dot fr>
Franz Schaefer <schaefer at mond dot at>
Fulko Hew <fulko dot hew at gmail dot com>
Gianluca Varenni <varenni at netgroup-serv dot polito dot it>
Gilbert Hoyek <gil_hoyek at hotmail dot com>
Gisle Vanem <gvanem at broadpark dot no>
Gisle Vanem <giva at bgnett dot no>
Graeme Hewson <ghewson at cix dot compulink dot co dot uk>
Greg Stark <gsstark at mit dot edu>
Greg Troxel <gdt at ir dot bbn dot com>
Gregor Maier <gregor at net dot in dot tum dot de>
Guillaume Pelat <endymion_ at users dot sourceforge dot net>
Hagen Paul Pfeifer <hagen at jauu dot net>
Hyung Sik Yoon <hsyn at kr dot ibm dot com>
Igor Khristophorov <igor at atdot dot org>
Jan-Philip Velders <jpv at veldersjes dot net>
Jason R. Thorpe <thorpej at netbsd dot org>
Javier Achirica <achirica at ttd dot net>
Jean Tourrilhes <jt at hpl dot hp dot com>
Jefferson Ogata <jogata at nodc dot noaa dot gov>
Jesper Peterson <jesper at endace dot com>
Joerg Mayer <jmayer at loplof dot de>
John Bankier <jbankier at rainfinity dot com>
Jon Lindgren <jonl at yubyub dot net>
Juergen Schoenwaelder <schoenw at ibr dot cs dot tu-bs dot de>
Jung-uk Kim <jkim at FreeBSD dot org>
Kazushi Sugyo <sugyo at pb dot jp dot nec dot com>
Klaus Klein <kleink at netbsd dot org>
Koryn Grant <koryn at endace dot com>
Kris Katterjohn <katterjohn at gmail dot com>
Krzysztof Halasa <khc at pm dot waw dot pl>
Lorenzo Cavallaro <sullivan at sikurezza dot org>
Loris Degioanni <loris at netgroup-serv dot polito dot it>
Love Hörnquist-Åstrand <lha at stacken dot kth dot se>
Luis Martin Garcia <luis dot mgarc at gmail dot com>
Maciej W. Rozycki <macro at ds2 dot pg dot gda dot pl>
Marcus Felipe Pereira <marcus at task dot com dot br>
Mark C. Brown <mbrown at hp dot com>
Mark Pizzolato <List-tcpdump-workers at subscriptions dot pizzolato dot net>
Martin Husemann <martin at netbsd dot org>
Matthew Luckie <mjl at luckie dot org dot nz>
Max Laier <max at love2party dot net>
Mike Frysinger <vapier at gmail dot com>
Mike Kershaw <dragorn at kismetwireless dot net>
Mike Wiacek <mike at iroot dot net>
Monroe Williams <monroe at pobox dot com>
Nicolas Dade <ndade at nsd dot dyndns dot org>
Octavian Cerna <tavy at ylabs dot com>
Olaf Kirch <okir at caldera dot de>
Ollie Wild <aaw at users dot sourceforge dot net>
Onno van der Linden <onno at simplex dot nl>
Paolo Abeni <paolo dot abeni at email dot it>
Patrick Marie <mycroft at virgaria dot org>
Patrick McHardy <kaber at trash not net>
Paul Mundt <lethal at linux-sh dot org>
Pavel Kankovsky <kan at dcit dot cz>
Pawel Pokrywka <publicpp at gmail dot com>
Peter Fales <peter at fales-lorenz dot net>
Peter Jeremy <peter dot jeremy at alcatel dot com dot au>
Phil Wood <cpw at lanl dot gov>
Rafal Maszkowski <rzm at icm dot edu dot pl>
<rcb-isis at users dot sourceforge dot net>
Richard Stearn <richard at rns-stearn dot demon dot co dot uk>
Rick Jones <raj at cup dot hp dot com>
Sagun Shakya <sagun dot shakya at sun dot com>
Scott Barron <sb125499 at ohiou dot edu>
Scott Gifford <sgifford at tir dot com>
Sebastian Krahmer <krahmer at cs dot uni-potsdam dot de>
Sepherosa Ziehau <sepherosa at gmail dot com>
Shaun Clowes <delius at progsoc dot uts dot edu dot au>
Solomon Peachy <pizza at shaftnet dot org>
Stefan Hudson <hudson at mbay dot net>
Stephen Donnelly <stephen at endace dot com>
Takashi Yamamoto <yamt at mwd dot biglobe dot ne dot jp>
Tanaka Shin-ya <zstanaka at archer dot livedoor dot com>
Tony Li <tli at procket dot com>
Torsten Landschoff <torsten at debian dot org>
Uns Lider <unslider at miranda dot org>
Uwe Girlich <Uwe dot Girlich at philosys dot de>
Xianjie Zhang <xzhang at cup dot hp dot com>
Yen Yen Lim
Yoann Vandoorselaere <yoann@prelude-ids.org>
Yoann Vandoorselaere <yoann at prelude-ids dot org>
The original LBL crew:
Steve McCanne
Craig Leres
Van Jacobson
Past maintainers:
Jun-ichiro itojun Hagino <itojun at iijlab dot net>

124
FILES
View File

@ -1,124 +0,0 @@
CHANGES
ChmodBPF/ChmodBPF
ChmodBPF/StartupParameters.plist
CREDITS
FILES
INSTALL.txt
LICENSE
Makefile.in
README
README.aix
README.dag
README.hpux
README.linux
README.macosx
README.septel
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
missing/snprintf.c
mkdep
msdos/bin2c.c
msdos/common.dj
msdos/makefile
msdos/makefile.dj
msdos/makefile.wc
msdos/ndis2.c
msdos/ndis2.h
msdos/ndis_0.asm
msdos/pkt_rx0.asm
msdos/pkt_rx1.s
msdos/pktdrvr.c
msdos/pktdrvr.h
msdos/readme.dos
nametoaddr.c
nlpid.h
optimize.c
packaging/pcap.spec
packaging/pcap.spec.in
pcap-bpf.c
pcap-bpf.h
pcap-dag.c
pcap-dag.h
pcap-dlpi.c
pcap-dos.c
pcap-dos.h
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-septel.c
pcap-septel.h
pcap-stdinc.h
pcap-snit.c
pcap-snoop.c
pcap-win32.c
pcap.3
pcap.c
pcap.h
ppp.h
savefile.c
scanner.l
sll.h
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

342
INSTALL
View File

@ -1,342 +0,0 @@
@(#) $Header: /tcpdump/master/libpcap/INSTALL,v 1.46 2000/12/16 09:05:11 guy Exp $ (LBL)
To build libpcap, run "./configure" (a shell script). The configure
script will determine your system attributes and generate an
appropriate Makefile from Makefile.in. Next run "make". If everything
goes well you can su to root and run "make install". However, you need
not install libpcap if you just want to build tcpdump; just make sure
the tcpdump and libpcap directory trees have the same parent
directory.
If configure says:
configure: warning: cannot determine packet capture interface
configure: warning: (see INSTALL for more info)
then your system either does not support packet capture or your system
does support packet capture but libpcap does not support that
particular type. (If you have HP-UX, see below.) If your system uses a
packet capture not supported by libpcap, please send us patches; don't
forget to include an autoconf fragment suitable for use in
configure.in.
It is possible to override the default packet capture type, although
the circumstance where this works are limited. For example if you have
installed bpf under SunOS 4 and wish to build a snit libpcap:
./configure --with-pcap=snit
Another example is to force a supported packet capture type in the case
where the configure scripts fails to detect it.
You will need an ANSI C compiler to build libpcap. The configure script
will abort if your compiler is not ANSI compliant. If this happens, use
the GNU C compiler, available via anonymous ftp:
ftp://ftp.gnu.org/pub/gnu/gcc/
If you use flex, you must use version 2.4.6 or higher. The configure
script automatically detects the version of flex and will not use it
unless it is new enough. You can use "flex -V" to see what version you
have (unless it's really old). The current version of flex is available
via anonymous ftp:
ftp://ftp.ee.lbl.gov/flex-*.tar.Z
As of this writing, the current version is 2.5.4.
If you use bison, you must use flex (and visa versa). The configure
script automatically falls back to lex and yacc if both flex and bison
are not found.
Sometimes the stock C compiler does not interact well with flex and
bison. The list of problems includes undefined references for alloca.
You can get around this by installing gcc or manually disabling flex
and bison with:
./configure --without-flex --without-bison
If your system only has AT&T lex, this is okay unless your libpcap
program uses other lex/yacc generated code. (Although it's possible to
map the yy* identifiers with a script, we use flex and bison so we
don't feel this is necessary.)
Some systems support the Berkeley Packet Filter natively; for example
out of the box OSF and BSD/OS have bpf. If your system does not support
bpf, you will need to pick up:
ftp://ftp.ee.lbl.gov/bpf-*.tar.Z
Note well: you MUST have kernel source for your operating system in
order to install bpf. An exception is SunOS 4; the bpf distribution
includes replacement kernel objects for some of the standard SunOS 4
network device drivers. See the bpf INSTALL document for more
information.
If you use Solaris, there is a bug with bufmod(7) that is fixed in
Solaris 2.3.2 (aka SunOS 5.3.2). Setting a snapshot length with the
broken bufmod(7) results in data be truncated from the FRONT of the
packet instead of the end. The work around is to not set a snapshot
length but this results in performance problems since the entire packet
is copied to user space. If you must run an older version of Solaris,
there is a patch available from Sun; ask for bugid 1149065. After
installing the patch, use "setenv BUFMOD_FIXED" to enable use of
bufmod(7). However, we recommend you run a more current release of
Solaris.
If you use the SPARCompiler, you must be careful to not use the
/usr/ucb/cc interface. If you do, you will get bogus warnings and
perhaps errors. Either make sure your path has /opt/SUNWspro/bin
before /usr/ucb or else:
setenv CC /opt/SUNWspro/bin/cc
before running configure. (You might have to do a "make distclean"
if you already ran configure once).
Also note that "make depend" won't work; while all of the known
universe uses -M, the SPARCompiler uses -xM to generate makefile
dependencies.
If you are trying to do packet capture with a FORE ATM card, you may or
may not be able to. They usually only release their driver in object
code so unless their driver supports packet capture, there's not much
libpcap can do.
If you get an error like:
tcpdump: recv_ack: bind error 0x???
when using DLPI, look for the DL_ERROR_ACK error return values, usually
in /usr/include/sys/dlpi.h, and find the corresponding value.
Under {DEC OSF/1, Digital UNIX, Tru64 UNIX}, packet capture must be
enabled before it can be used. For instructions on how to enable packet
filter support, see:
ftp://ftp.digital.com/pub/Digital/dec-faq/Digital-UNIX
Look for the "How do I configure the Berkeley Packet Filter and capture
tcpdump traces?" item.
Once you enable packet filter support, your OSF system will support bpf
natively.
Under Ultrix, packet capture must be enabled before it can be used. For
instructions on how to enable packet filter support, see:
ftp://ftp.digital.com/pub/Digital/dec-faq/ultrix
If you use HP-UX, you must have at least version 9 and either the
version of cc that supports ANSI C (cc -Aa) or else use the GNU C
compiler. You must also buy the optional streams package. If you don't
have:
/usr/include/sys/dlpi.h
/usr/include/sys/dlpi_ext.h
then you don't have the streams package. In addition, we believe you
need to install the "9.X LAN and DLPI drivers cumulative" patch
(PHNE_6855) to make the version 9 DLPI work with libpcap.
The DLPI streams package is standard starting with HP-UX 10.
The HP implementation of DLPI is a little bit eccentric. Unlike
Solaris, you must attach /dev/dlpi instead of the specific /dev/*
network pseudo device entry in order to capture packets. The PPA is
based on the ifnet "index" number. Under HP-UX 9, it is necessary to
read /dev/kmem and the kernel symbol file (/hp-ux). Under HP-UX 10,
DLPI can provide information for determining the PPA. It does not seem
to be possible to trace the loopback interface. Unlike other DLPI
implementations, PHYS implies MULTI and SAP and you get an error if you
try to enable more than one promiscuous mode at a time.
It is impossible to capture outbound packets on HP-UX 9. To do so on
HP-UX 10, you will, apparently, need a late "LAN products cumulative
patch" (at one point, it was claimed that this would be PHNE_18173 for
s700/10.20; at another point, it was claimed that the required patches
were PHNE_20892, PHNE_20725 and PHCO_10947, or newer patches), and to do
so on HP-UX 11 you will, apparently, need the latest lancommon/DLPI
patches and the latest driver patch for the interface(s) in use on HP-UX
11 (at one point, it was claimed that patches PHNE_19766, PHNE_19826,
PHNE_20008, and PHNE_20735 did the trick).
Furthermore, on HP-UX 10, you will need to turn on a kernel switch by
doing
echo 'lanc_outbound_promisc_flag/W 1' | adb -w /stand/vmunix /dev/mem
You would have to arrange that this happen on reboots; the right way to
do that would probably be to put it into an executable script file
"/sbin/init.d/outbound_promisc" and making
"/sbin/rc2.d/S350outbound_promisc" a symbolic link to that script.
Finally, testing shows that there can't be more than one simultaneous
DLPI user per network interface.
If you use Linux, this version of libpcap is known to compile and run
under Red Hat 4.0 with the 2.0.25 kernel. It may work with earlier 2.X
versions but is guaranteed not to work with 1.X kernels. Running more
than one libpcap program at a time, on a system with a 2.0.X kernel, can
cause problems since promiscuous mode is implemented by twiddling the
interface flags from the libpcap application; the packet capture
mechanism in the 2.2 and later kernels doesn't have this problem. Also,
packet timestamps aren't very good. This appears to be due to haphazard
handling of the timestamp in the kernel.
Note well: there is rumoured to be a version of tcpdump floating around
called 3.0.3 that includes libpcap and is supposed to support Linux.
You should be advised that neither the Network Research Group at LBNL
nor the Tcpdump Group ever generated a release with this version number.
The LBNL Network Research Group notes with interest that a standard
cracker trick to get people to install trojans is to distribute bogus
packages that have a version number higher than the current release.
They also noted with annoyance that 90% of the Linux related bug reports
they got are due to changes made to unofficial versions of their page.
If you are having trouble but aren't using a version that came from
tcpdump.org, please try that before submitting a bug report!
On Linux, libpcap will not work if the kernel does not have the packet
socket option enabled; see the README.linux file for information about
this.
If you use AIX, you may not be able to build libpcap from this release.
libpcap. We do not have an AIX system in house so it's impossible for
us to test AIX patches submitted to us. We are told that you must link
against /lib/pse.exp, that you must use AIX cc or a GNU C compiler
newer than 2.7.2 and that you may need to run strload before running a
libpcap application.
Read the README.aix file for information on installing libpcap and
configuring your system to be able to support libpcap.
If you use NeXTSTEP, you will not be able to build libpcap from this
release. We hope to support this operating system in some future
release of libpcap.
If you use SINIX, you should be able to build libpcap from this
release. It is known to compile and run on SINIX-Y/N 5.42 with the C-DS
V1.0 or V1.1 compiler. But note that in some releases of SINIX, yacc
emits incorrect code; if grammar.y fails to compile, change every
occurence of:
#ifdef YYDEBUG
to:
#if YYDEBUG
Another workaround is to use flex and bison.
If you use SCO, you might have trouble building libpcap from this
release. We do not have a machine running SCO and have not had reports
of anyone successfully building on it. Since SCO apparently supports
DLPI, it's possible the current version works. Meanwhile, SCO provides
a tcpdump binary as part of their "Network/Security Tools" package:
http://www.sco.com/technology/internet/goodies/#SECURITY
There is also a README that explains how to enable packet capture.
If you use UnixWare, you will not be able to build libpcap from this
release. We hope to support this operating system in some future
release of libpcap. Meanwhile, there appears to be an UnixWare port of
libpcap 0.0 (and tcpdump 3.0) in:
ftp://ftp1.freebird.org/pub/mirror/freebird/internet/systools/
UnixWare appears to use a hacked version of DLPI.
If linking tcpdump fails with "Undefined: _alloca" when using bison on
a Sun4, your version of bison is broken. In any case version 1.16 or
higher is recommended (1.14 is known to cause problems 1.16 is known to
work). Either pick up a current version from:
ftp://ftp.gnu.org/pub/gnu/bison
or hack around it by inserting the lines:
#ifdef __GNUC__
#define alloca __builtin_alloca
#else
#ifdef sparc
#include <alloca.h>
#else
char *alloca ();
#endif
#endif
right after the (100 line!) GNU license comment in bison.simple, remove
grammar.[co] and fire up make again.
If you use SunOS 4, your kernel must support streams NIT. If you run a
libpcap program and it dies with:
/dev/nit: No such device
You must add streams NIT support to your kernel configuration, run
config and boot the new kernel.
If you are running a version of SunOS earlier than 4.1, you will need
to replace the Sun supplied /sys/sun{3,4,4c}/OBJ/nit_if.o with the
appropriate version from this distribution's SUNOS4 subdirectory and
build a new kernel:
nit_if.o.sun3-sunos4 (any flavor of sun3)
nit_if.o.sun4c-sunos4.0.3c (SS1, SS1+, IPC, SLC, etc.)
nit_if.o.sun4-sunos4 (Sun4's not covered by
nit_if.o.sun4c-sunos4.0.3c)
These nit replacements fix a bug that makes nit essentially unusable in
pre-SunOS 4.1. In addition, our sun4c-sunos4.0.3c nit gives you
timestamps to the resolution of the SS-1 clock (1 us) rather than the
lousy 20ms timestamps Sun gives you (tcpdump will print out the full
timestamp resolution if it finds it's running on a SS-1).
FILES
-----
CHANGES - description of differences between releases
FILES - list of files exported as part of the distribution
INSTALL - this file
Makefile.in - compilation rules (input to the configure script)
README - description of distribution
SUNOS4 - pre-SunOS 4.1 replacement kernel nit modules
VERSION - version of this release
aclocal.m4 - autoconf macros
bpf/net - copies of bpf_filter.c and bpf.h
bpf_filter.c - symlink to bpf/net/bpf_filter.c
bpf_image.c - bpf disassembly routine
config.guess - autoconf support
config.sub - autoconf support
configure - configure script (run this first)
configure.in - configure script source
etherent.c - /etc/ethers support routines
ethertype.h - ethernet protocol types and names definitions
gencode.c - bpf code generation routines
gencode.h - bpf code generation definitions
grammar.y - filter string grammar
inet.c - network routines
install-sh - BSD style install script
lbl/gnuc.h - gcc macros and defines
lbl/os-*.h - os dependent defines and prototypes
mkdep - construct Makefile dependency list
nametoaddr.c - hostname to address routines
net - symlink to bpf/net
optimize.c - bpf optimization routines
pcap-bpf.c - BSD Packet Filter support
pcap-dlpi.c - Data Link Provider Interface support
pcap-enet.c - enet support
pcap-int.h - internal libpcap definitions
pcap-namedb.h - public libpcap name database definitions
pcap-nit.c - Network Interface Tap support
pcap-nit.h - Network Interface Tap definitions
pcap-null.c - dummy monitor support (allows offline use of libpcap)
pcap-pf.c - Packet Filter support
pcap-pf.h - Packet Filter definitions
pcap-snit.c - Streams based Network Interface Tap support
pcap-snoop.c - Snoop network monitoring support
pcap.3 - manual entry
pcap.c - pcap utility routines
pcap.h - public libpcap definitions
ppp.h - Point to Point Protocol definitions
savefile.c - offline support
scanner.l - filter string scanner

View File

@ -1,4 +1,4 @@
@(#) $Header: /tcpdump/master/libpcap/INSTALL.txt,v 1.12.2.2 2007/09/12 19:17:24 guy Exp $ (LBL)
@(#) $Header: /tcpdump/master/libpcap/INSTALL.txt,v 1.21.2.8 2008-06-12 20:25:38 guy Exp $ (LBL)
To build libpcap, run "./configure" (a shell script). The configure
script will determine your system attributes and generate an
@ -211,8 +211,7 @@ Read the README.aix file for information on installing libpcap and
configuring your system to be able to support libpcap.
If you use NeXTSTEP, you will not be able to build libpcap from this
release. We hope to support this operating system in some future
release of libpcap.
release.
If you use SINIX, you should be able to build libpcap from this
release. It is known to compile and run on SINIX-Y/N 5.42 with the C-DS
@ -229,22 +228,22 @@ Another workaround is to use flex and bison.
If you use SCO, you might have trouble building libpcap from this
release. We do not have a machine running SCO and have not had reports
of anyone successfully building on it. Since SCO apparently supports
DLPI, it's possible the current version works. Meanwhile, SCO provides
a tcpdump binary as part of their "Network/Security Tools" package:
of anyone successfully building on it; the current release of libpcap
does not compile on SCO OpenServer 5. Although SCO apparently supports
DLPI to some extent, the DLPI in OpenServer 5 is very non-standard, and
it appears that completely new code would need to be written to capture
network traffic. SCO do not appear to provide tcpdump binaries for
OpenServer 5 or OpenServer 6 as part of SCO Skunkware:
http://www.sco.com/technology/internet/goodies/#SECURITY
http://www.sco.com/skunkware/
There is also a README that explains how to enable packet capture.
If you use UnixWare, you will not be able to build libpcap from this
release. We hope to support this operating system in some future
release of libpcap. Meanwhile, there appears to be an UnixWare port of
libpcap 0.0 (and tcpdump 3.0) in:
ftp://ftp1.freebird.org/pub/mirror/freebird/internet/systools/
UnixWare appears to use a hacked version of DLPI.
If you use UnixWare, you might be able to build libpcap from this
release, or you might not. We do not have a machine running UnixWare,
so we have not tested it; however, SCO provide packages for libpcap
0.6.2 and tcpdump 3.7.1 in the UnixWare 7/Open UNIX 8 part of SCO
Skunkware, and the source package for libpcap 0.6.2 is not changed from
the libpcap 0.6.2 source release, so this release of libpcap might also
build without changes on UnixWare 7.
If linking tcpdump fails with "Undefined: _alloca" when using bison on
a Sun4, your version of bison is broken. In any case version 1.16 or
@ -298,7 +297,6 @@ CHANGES - description of differences between releases
ChmodBPF/* - Mac OS X startup item to set ownership and permissions
on /dev/bpf*
CREDITS - people that have helped libpcap along
FILES - list of files exported as part of the distribution
INSTALL.txt - this file
LICENSE - the license under which tcpdump is distributed
Makefile.in - compilation rules (input to the configure script)
@ -309,6 +307,7 @@ README.hpux - notes on using libpcap on HP-UX
README.linux - notes on using libpcap on Linux
README.macosx - notes on using libpcap on Mac OS X
README.septel - notes on using libpcap to capture on Intel/Septel devices
README.sita - notes on using libpcap to capture on SITA devices
README.tru64 - notes on using libpcap on Digital/Tru64 UNIX
README.Win32 - notes on using libpcap on Win32 systems (with WinPcap)
SUNOS4 - pre-SunOS 4.1 replacement kernel nit modules
@ -326,16 +325,22 @@ config.h.in - autoconf input
config.sub - autoconf support
configure - configure script (run this first)
configure.in - configure script source
dlpisubs.c - DLPI-related functions for pcap-dlpi.c and pcap-libdlpi.c
dlpisubs.h - DLPI-related function declarations
etherent.c - /etc/ethers support routines
ethertype.h - Ethernet protocol types and names definitions
fad-getad.c - pcap_findalldevs() for systems with getifaddrs()
fad-gifc.c - pcap_findalldevs() for systems with only SIOCGIFLIST
fad-glifc.c - pcap_findalldevs() for systems with SIOCGLIFCONF
fad-null.c - pcap_findalldevs() for systems without capture support
fad-sita.c - pcap_findalldevs() for systems with SITA support
fad-win32.c - pcap_findalldevs() for WinPcap
filtertest.c - test program for BPF compiler
findalldevstest.c - test program for pcap_findalldevs()
gencode.c - BPF code generation routines
gencode.h - BPF code generation definitions
grammar.y - filter string grammar
ieee80211.h - 802.11 definitions
inet.c - network routines
install-sh - BSD style install script
lbl/os-*.h - OS-dependent defines and prototypes
@ -348,8 +353,16 @@ nlpid.h - OSI network layer protocol identifier definitions
net - symlink to bpf/net
optimize.c - BPF optimization routines
packaging - packaging information for building libpcap RPMs
pcap/bluetooth.h - public definition of DLT_BLUETOOTH_HCI_H4_WITH_PHDR header
pcap/bpf.h - BPF definitions
pcap/namedb.h - public libpcap name database definitions
pcap/pcap.h - public libpcap definitions
pcap/sll.h - public definition of DLT_LINUX_SLL header
pcap/usb.h - public definition of DLT_USB header
pcap-bpf.c - BSD Packet Filter support
pcap-bpf.h - BPF definitions
pcap-bpf.h - header for backwards compatibility
pcap-bt-linux.c - Bluetooth capture support for Linux
pcap-bt-linux.h - Bluetooth capture support for Linux
pcap-dag.c - Endace DAG device capture support
pcap-dag.h - Endace DAG device capture support
pcap-dlpi.c - Data Link Provider Interface support
@ -357,26 +370,34 @@ pcap-dos.c - MS-DOS capture support
pcap-dos.h - headers for MS-DOS capture support
pcap-enet.c - enet support
pcap-int.h - internal libpcap definitions
pcap-libdlpi.c - Data Link Provider Interface support for systems with libdlpi
pcap-linux.c - Linux packet socket support
pcap-namedb.h - public libpcap name database definitions
pcap-namedb.h - header for backwards compatibility
pcap-nit.c - SunOS Network Interface Tap support
pcap-nit.h - SunOS Network Interface Tap definitions
pcap-null.c - dummy monitor support (allows offline use of libpcap)
pcap-pf.c - Ultrix and Digital/Tru64 UNIX Packet Filter support
pcap-pf.h - Ultrix and Digital/Tru64 UNIX Packet Filter definitions
pcap-septel.c - INTEL/Septel device capture support
pcap-septel.h - INTEL/Septel device capture support
pcap-septel.c - Intel/Septel device capture support
pcap-septel.h - Intel/Septel device capture support
pcap-sita.c - SITA device capture support
pcap-sita.h - SITA device capture support
pcap-sita.html - SITA device capture documentation
pcap-stdinc.h - includes and #defines for compiling on Win32 systems
pcap-snit.c - SunOS 4.x STREAMS-based Network Interface Tap support
pcap-snoop.c - IRIX Snoop network monitoring support
pcap-usb-linux.c - USB capture support for Linux
pcap-usb-linux.h - USB capture support for Linux
pcap-win32.c - WinPcap capture support
pcap.3 - manual entry
pcap.3pcap - manual entry for the library
pcap.c - pcap utility routines
pcap.h - public libpcap definitions
pcap.h - header for backwards compatibility
pcap_*.3pcap - manual entries for library functions
pcap-filter.4 - manual entry for filter syntax
pcap-linktype.4 - manual entry for link-layer header types
ppp.h - Point to Point Protocol definitions
rawss7.h - information on DLT_ types for SS7
runlex.sh - wrapper for Lex/Flex
savefile.c - offline support
scanner.l - filter string scanner
sll.h - definitions for Linux cooked mode fake link-layer header
sunatmpos.h - definitions for SunATM capturing
Win32 - headers and routines for building on Win32 systems

View File

@ -17,7 +17,7 @@
# WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
#
# @(#) $Header: /tcpdump/master/libpcap/Makefile.in,v 1.99.2.2 2007/07/24 02:35:15 mcr Exp $ (LBL)
# @(#) $Header: /tcpdump/master/libpcap/Makefile.in,v 1.108.2.28 2008-10-23 22:13:21 guy Exp $ (LBL)
#
# Various configurable paths (remember to edit Makefile.in, not Makefile)
@ -26,11 +26,14 @@
# Top level hierarchy
prefix = @prefix@
exec_prefix = @exec_prefix@
datarootdir = @datarootdir@
# Pathname of directory to install the configure program
bindir = @bindir@
# Pathname of directory to install the include files
includedir = @includedir@
# Pathname of directory to install the library
libdir = @libdir@
# Pathname of directory to install the man page
# Pathname of directory to install the man pages
mandir = @mandir@
# VPATH
@ -47,6 +50,7 @@ INCLS = -I. @V_INCLS@
DEFS = @DEFS@ @V_DEFS@
LIBS = @V_LIBS@
DAGLIBS = @DAGLIBS@
DEPLIBS = @DEPLIBS@
DYEXT = @DYEXT@
PROG=libpcap
@ -73,7 +77,7 @@ YACC = @V_YACC@
@rm -f $@
$(CC) $(CFLAGS) -c $(srcdir)/$*.c
PSRC = pcap-@V_PCAP@.c
PSRC = pcap-@V_PCAP@.c @USB_SRC@ @BT_SRC@
FSRC = fad-@V_FINDALLDEVS@.c
SSRC = @SSRC@
CSRC = pcap.c inet.c gencode.c optimize.c nametoaddr.c \
@ -86,10 +90,31 @@ SRC = $(PSRC) $(FSRC) $(CSRC) $(SSRC) $(GENSRC)
# We would like to say "OBJ = $(SRC:.c=.o)" but Ultrix's make cannot
# hack the extra indirection
OBJ = $(PSRC:.c=.o) $(FSRC:.c=.o) $(CSRC:.c=.o) $(SSRC:.c=.o) $(GENSRC:.c=.o) $(LIBOBJS)
HDR = pcap.h pcap-int.h pcap-namedb.h pcap-nit.h pcap-pf.h \
ethertype.h gencode.h gnuc.h
HDR = \
acconfig.h \
arcnet.h \
atmuni31.h \
ethertype.h \
gencode.h \
ieee80211.h \
llc.h \
nlpid.h \
pcap/bluetooth.h \
pcap/bpf.h \
pcap/namedb.h \
pcap/pcap.h \
pcap/sll.h \
pcap/usb.h \
pcap/vlan.h \
pcap.h \
pcap-int.h \
pcap-namedb.h \
pcap-stdinc.h \
ppp.h \
sunatmpos.h
GENHDR = \
tokdefs.h version.h
scanner.h tokdefs.h version.h
TAGHDR = \
pcap-bpf.h
@ -99,11 +124,198 @@ TAGFILES = \
CLEANFILES = $(OBJ) libpcap.a $(GENSRC) $(GENHDR) lex.yy.c
all: libpcap.a
MAN1 = pcap-config.1
MAN3PCAP_EXPAND = \
pcap.3pcap.in \
pcap_compile.3pcap.in \
pcap_datalink.3pcap.in \
pcap_dump_open.3pcap.in \
pcap_list_datalinks.3pcap.in \
pcap_open_dead.3pcap.in \
pcap_open_offline.3pcap.in
MAN3PCAP_NOEXPAND = \
pcap_activate.3pcap \
pcap_breakloop.3pcap \
pcap_can_set_rfmon.3pcap \
pcap_close.3pcap \
pcap_create.3pcap \
pcap_datalink_name_to_val.3pcap \
pcap_datalink_val_to_name.3pcap \
pcap_dump.3pcap \
pcap_dump_close.3pcap \
pcap_dump_file.3pcap \
pcap_dump_flush.3pcap \
pcap_dump_ftell.3pcap \
pcap_file.3pcap \
pcap_fileno.3pcap \
pcap_findalldevs.3pcap \
pcap_freealldevs.3pcap \
pcap_freecode.3pcap \
pcap_free_datalinks.3pcap \
pcap_get_selectable_fd.3pcap \
pcap_geterr.3pcap \
pcap_inject.3pcap \
pcap_is_swapped.3pcap \
pcap_lib_version.3pcap \
pcap_lookupdev.3pcap \
pcap_lookupnet.3pcap \
pcap_loop.3pcap \
pcap_major_version.3pcap \
pcap_next_ex.3pcap \
pcap_offline_filter.3pcap \
pcap_open_live.3pcap \
pcap_set_buffer_size.3pcap \
pcap_set_datalink.3pcap \
pcap_set_promisc.3pcap \
pcap_set_rfmon.3pcap \
pcap_set_snaplen.3pcap \
pcap_set_timeout.3pcap \
pcap_setdirection.3pcap \
pcap_setfilter.3pcap \
pcap_setnonblock.3pcap \
pcap_snapshot.3pcap \
pcap_stats.3pcap \
pcap_statustostr.3pcap \
pcap_strerror.3pcap
MAN3PCAP = $(MAN3PCAP_NOEXPAND) $(MAN3PCAP_EXPAND:.in=)
MANFILE = \
pcap-savefile.manfile.in
MANMISC = \
pcap-filter.manmisc.in \
pcap-linktype.manmisc.in
EXTRA_DIST = \
CHANGES \
ChmodBPF/ChmodBPF \
ChmodBPF/StartupParameters.plist \
CREDITS \
INSTALL.txt \
LICENSE \
Makefile.in \
README \
README.aix \
README.dag \
README.hpux \
README.linux \
README.macosx \
README.septel \
README.sita \
README.tru64 \
README.Win32 \
SUNOS4/nit_if.o.sparc \
SUNOS4/nit_if.o.sun3 \
SUNOS4/nit_if.o.sun4c.4.0.3c \
TODO \
VERSION \
aclocal.m4 \
bpf/net/bpf_filter.c \
chmod_bpf \
config.guess \
config.h.in \
config.sub \
configure \
configure.in \
dlpisubs.c \
dlpisubs.h \
fad-getad.c \
fad-gifc.c \
fad-glifc.c \
fad-null.c \
fad-sita.c \
fad-win32.c \
filtertest.c \
findalldevstest.c \
grammar.y \
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 \
missing/snprintf.c \
mkdep \
msdos/bin2c.c \
msdos/common.dj \
msdos/makefile \
msdos/makefile.dj \
msdos/makefile.wc \
msdos/ndis2.c \
msdos/ndis2.h \
msdos/ndis_0.asm \
msdos/pkt_rx0.asm \
msdos/pkt_rx1.s \
msdos/pktdrvr.c \
msdos/pktdrvr.h \
msdos/readme.dos \
net/bpf_filter.c \
org.tcpdump.chmod_bpf.plist \
packaging/pcap.spec.in \
pcap-bpf.c \
pcap-bpf.h \
pcap-bt-linux.c \
pcap-bt-linux.h \
pcap-config.in \
pcap-dag.c \
pcap-dag.h \
pcap-dlpi.c \
pcap-dos.c \
pcap-dos.h \
pcap-enet.c \
pcap-int.h \
pcap-libdlpi.c \
pcap-linux.c \
pcap-namedb.h \
pcap-nit.c \
pcap-null.c \
pcap-pf.c \
pcap-septel.c \
pcap-septel.h \
pcap-sita.h \
pcap-sita.c \
pcap-sita.html \
pcap-snit.c \
pcap-snoop.c \
pcap-usb-linux.c \
pcap-usb-linux.h \
pcap-win32.c \
runlex.sh \
scanner.l \
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/Prj/libpcap.dsp \
Win32/Prj/libpcap.dsw \
Win32/Src/ffs.c \
Win32/Src/gai_strerror.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
all: libpcap.a pcap-config
libpcap.a: $(OBJ)
@rm -f $@
ar rc $@ $(OBJ) $(LIBS)
$(AR) rc $@ $(OBJ) $(LIBS)
$(RANLIB) $@
shared: libpcap.$(DYEXT)
@ -114,19 +326,27 @@ shared: libpcap.$(DYEXT)
#
libpcap.so: $(OBJ)
@rm -f $@
$(CC) -shared -o $@.`cat VERSION` $(OBJ) $(DAGLIBS)
$(CC) -shared -Wl,-soname,$@.1 -o $@.`cat $(srcdir)/VERSION` $(OBJ) $(DAGLIBS)
# the following rule succeeds, but the result is untested.
#
# The following rule succeeds, but the result is untested.
#
# XXX - OS X installs the library as "libpcap.A.dylib", with that as the
# install_name, and sets the current version to 1 as well. VERSION
# might contain a not-purely-numeric version number, but
# -current_version requires a purely numeric version, so this won't
# work with top-of-tree builds.
#
libpcap.dylib: $(OBJ)
rm -f libpcap*.dylib
$(CC) -dynamiclib -undefined error -o libpcap.`cat VERSION`.dylib $(OBJ) \
-install_name $(libdir)/libpcap.0.dylib -compatibility_version `cat VERSION` \
-current_version `cat VERSION`
$(CC) -dynamiclib -undefined error -o libpcap.`cat $(srcdir)/VERSION`.dylib $(OBJ) \
-install_name $(libdir)/libpcap.A.dylib \
-compatibility_version 1 \
-current_version `sed 's/[^0-9.].*$$//' $(srcdir)/VERSION`
scanner.c: $(srcdir)/scanner.l
@rm -f $@
$(LEX) -t $< > $$$$.$@; mv $$$$.$@ $@
./runlex.sh $(LEX) -o$@ $<
scanner.o: scanner.c tokdefs.h
$(CC) $(CFLAGS) -c scanner.c
@ -172,43 +392,135 @@ bpf_filter.c: $(srcdir)/bpf/net/bpf_filter.c
bpf_filter.o: bpf_filter.c
$(CC) $(CFLAGS) -c bpf_filter.c
install: libpcap.a
#
# Generate the pcap-config script.
#
pcap-config: pcap-config.in Makefile
@rm -f $@ $@.tmp
sed -e 's|@includedir[@]|$(includedir)|g' \
-e 's|@libdir[@]|$(libdir)|g' \
-e 's|@DEPLIBS[@]|$(DEPLIBS)|g' \
pcap-config.in >$@.tmp
mv $@.tmp $@
chmod a+x $@
#
# Test programs - not built by default, and not installed.
#
filtertest: filtertest.c libpcap.a
$(CC) $(CFLAGS) -I. -L. -o filtertest filtertest.c libpcap.a
findalldevstest: findalldevstest.c libpcap.a
$(CC) $(CFLAGS) -I. -L. -o findalldevstest findalldevstest.c libpcap.a
install: libpcap.a pcap-config
[ -d $(DESTDIR)$(libdir) ] || \
(mkdir -p $(DESTDIR)$(libdir); chmod 755 $(DESTDIR)$(libdir))
$(INSTALL_DATA) libpcap.a $(DESTDIR)$(libdir)/libpcap.a
$(RANLIB) $(DESTDIR)$(libdir)/libpcap.a
[ -d $(DESTDIR)$(includedir) ] || \
(mkdir -p $(DESTDIR)$(includedir); chmod 755 $(DESTDIR)$(includedir))
[ -d $(DESTDIR)$(includedir)/pcap ] || \
(mkdir -p $(DESTDIR)$(includedir)/pcap; chmod 755 $(DESTDIR)$(includedir)/pcap)
[ -d $(DESTDIR)$(mandir)/man1 ] || \
(mkdir -p $(DESTDIR)$(mandir)/man1; chmod 755 $(DESTDIR)$(mandir)/man1)
[ -d $(DESTDIR)$(mandir)/man3 ] || \
(mkdir -p $(DESTDIR)$(mandir)/man3; chmod 755 $(DESTDIR)$(mandir)/man3)
[ -d $(DESTDIR)$(mandir)/man@MAN_FILE_FORMATS@ ] || \
(mkdir -p $(DESTDIR)$(mandir)/man@MAN_FILE_FORMATS@; chmod 755 $(DESTDIR)$(mandir)/man@MAN_FILE_FORMATS@)
[ -d $(DESTDIR)$(mandir)/man@MAN_MISC_INFO@ ] || \
(mkdir -p $(DESTDIR)$(mandir)/man@MAN_MISC_INFO@; chmod 755 $(DESTDIR)$(mandir)/man@MAN_MISC_INFO@)
$(INSTALL_DATA) $(srcdir)/pcap/pcap.h \
$(DESTDIR)$(includedir)/pcap/pcap.h
$(INSTALL_DATA) $(srcdir)/pcap/bpf.h \
$(DESTDIR)$(includedir)/pcap/bpf.h
$(INSTALL_DATA) $(srcdir)/pcap/namedb.h \
$(DESTDIR)$(includedir)/pcap/namedb.h
$(INSTALL_DATA) $(srcdir)/pcap/sll.h \
$(DESTDIR)$(includedir)/pcap/sll.h
$(INSTALL_DATA) $(srcdir)/pcap/usb.h \
$(DESTDIR)$(includedir)/pcap/usb.h
$(INSTALL_DATA) $(srcdir)/pcap.h $(DESTDIR)$(includedir)/pcap.h
$(INSTALL_DATA) $(srcdir)/pcap-bpf.h \
$(DESTDIR)$(includedir)/pcap-bpf.h
$(INSTALL_DATA) $(srcdir)/pcap-namedb.h \
$(DESTDIR)$(includedir)/pcap-namedb.h
[ -d $(DESTDIR)$(mandir)/man3 ] || \
(mkdir -p $(DESTDIR)$(mandir)/man3; chmod 755 $(DESTDIR)$(mandir)/man3)
$(INSTALL_DATA) $(srcdir)/pcap.3 \
$(DESTDIR)$(mandir)/man3/pcap.3
$(INSTALL_PROGRAM) pcap-config $(DESTDIR)$(bindir)/pcap-config
for i in $(MAN1); do \
$(INSTALL_DATA) $(srcdir)/$$i \
$(DESTDIR)$(mandir)/man1/$$i; done
for i in $(MAN3PCAP); do \
$(INSTALL_DATA) $(srcdir)/$$i \
$(DESTDIR)$(mandir)/man3/$$i; done
ln $(DESTDIR)$(mandir)/man3/pcap_datalink_val_to_name.3pcap \
$(DESTDIR)$(mandir)/man3/pcap_datalink_val_to_description.3pcap
ln $(DESTDIR)$(mandir)/man3/pcap_dump_open.3pcap \
$(DESTDIR)$(mandir)/man3/pcap_dump_fopen.3pcap
ln $(DESTDIR)$(mandir)/man3/pcap_geterr.3pcap \
$(DESTDIR)$(mandir)/man3/pcap_perror.3pcap
ln $(DESTDIR)$(mandir)/man3/pcap_inject.3pcap \
$(DESTDIR)$(mandir)/man3/pcap_sendpacket.3pcap
ln $(DESTDIR)$(mandir)/man3/pcap_loop.3pcap \
$(DESTDIR)$(mandir)/man3/pcap_dispatch.3pcap
ln $(DESTDIR)$(mandir)/man3/pcap_major_version.3pcap \
$(DESTDIR)$(mandir)/man3/pcap_minor_version.3pcap
ln $(DESTDIR)$(mandir)/man3/pcap_next_ex.3pcap \
$(DESTDIR)$(mandir)/man3/pcap_next.3pcap
ln $(DESTDIR)$(mandir)/man3/pcap_open_offline.3pcap \
$(DESTDIR)$(mandir)/man3/pcap_fopen_offline.3pcap
ln $(DESTDIR)$(mandir)/man3/pcap_setnonblock.3pcap \
$(DESTDIR)$(mandir)/man3/pcap_getnonblock.3pcap
for i in $(MANFILE); do \
$(INSTALL_DATA) $(srcdir)/`echo $$i | sed 's/.manfile.in/.manfile/'` \
$(DESTDIR)$(mandir)/man@MAN_FILE_FORMATS@/`echo $$i | sed 's/.manfile.in/.@MAN_FILE_FORMATS@/'`; done
for i in $(MANMISC); do \
$(INSTALL_DATA) $(srcdir)/`echo $$i | sed 's/.manmisc.in/.manmisc/'` \
$(DESTDIR)$(mandir)/man@MAN_MISC_INFO@/`echo $$i | sed 's/.manmisc.in/.@MAN_MISC_INFO@/'`; done
install-shared: install-shared-$(DYEXT)
install-shared-so: libpcap.so
$(INSTALL_PROGRAM) libpcap.so.`cat VERSION` $(DESTDIR)$(libdir)/libpcap.so.`cat VERSION`
install-shared-dylib: libpcap.dylib
$(INSTALL_PROGRAM) libpcap.`cat VERSION`.dylib $(DESTDIR)$(libdir)/libpcap.`cat VERSION`.dylib
VER=`cat VERSION`; cd $(DESTDIR)$(libdir) && ln -sf libpcap.$$VER.dylib libpcap.0.dylib; ln -sf libpcap.0.dylib libpcap.dylib
VER=`cat VERSION`; cd $(DESTDIR)$(libdir) && ln -sf libpcap.$$VER.dylib libpcap.A.dylib; ln -sf libpcap.A.dylib libpcap.dylib
uninstall:
rm -f $(DESTDIR)$(libdir)/libpcap.a
rm -f $(DESTDIR)$(includedir)/pcap/pcap.h
rm -f $(DESTDIR)$(includedir)/pcap/bpf.h
rm -f $(DESTDIR)$(includedir)/pcap/namedb.h
rm -f $(DESTDIR)$(includedir)/pcap/sll.h
rm -f $(DESTDIR)$(includedir)/pcap/usb.h
-rmdir $(DESTDIR)$(includedir)/pcap
rm -f $(DESTDIR)$(includedir)/pcap.h
rm -f $(DESTDIR)$(includedir)/pcap-bpf.h
rm -f $(DESTDIR)$(includedir)/pcap-namedb.h
rm -f $(DESTDIR)$(mandir)/man3/pcap.3
for i in $(MAN1); do \
rm -f $(DESTDIR)$(mandir)/man1/$$i; done
for i in $(MAN3PCAP); do \
rm -f $(DESTDIR)$(mandir)/man3/$$i; done
rm -f $(DESTDIR)$(mandir)/man3/pcap_datalink_val_to_description.3pcap
rm -f $(DESTDIR)$(mandir)/man3/pcap_dump_fopen.3pcap
rm -f $(DESTDIR)$(mandir)/man3/pcap_perror.3pcap
rm -f $(DESTDIR)$(mandir)/man3/pcap_sendpacket.3pcap
rm -f $(DESTDIR)$(mandir)/man3/pcap_dispatch.3pcap
rm -f $(DESTDIR)$(mandir)/man3/pcap_minor_version.3pcap
rm -f $(DESTDIR)$(mandir)/man3/pcap_next.3pcap
rm -f $(DESTDIR)$(mandir)/man3/pcap_fopen_offline.3pcap
rm -f $(DESTDIR)$(mandir)/man3/pcap_getnonblock.3pcap
for i in $(MANFILE); do \
rm -f $(DESTDIR)$(mandir)/man@MAN_FILE_FORMATS@/`echo $$i | sed 's/.manfile.in/.@MAN_FILE_FORMATS@/'`; done
for i in $(MANMISC); do \
rm -f $(DESTDIR)$(mandir)/man@MAN_MISC_INFO@/`echo $$i | sed 's/.manmisc.in/.@MAN_MISC_INFO@/'`; done
clean:
rm -f $(CLEANFILES) libpcap*.dylib libpcap.so*
distclean: clean
rm -f Makefile config.cache config.log config.status \
config.h gnuc.h os-proto.h bpf_filter.c stamp-h stamp-h.in
config.h gnuc.h os-proto.h bpf_filter.c pcap-config \
stamp-h stamp-h.in
rm -f $(MAN3PCAP_EXPAND:.in=) $(MANFILE:.in=) $(MANMISC:.in=)
rm -rf autom4te.cache
tags: $(TAGFILES)
@ -220,8 +532,12 @@ packaging/pcap.spec: packaging/pcap.spec.in VERSION
releasetar:
@cwd=`pwd` ; dir=`basename $$cwd` ; name=$(PROG)-`cat VERSION` ; \
list="" ; make distclean; cd ..; mkdir -p n; cd n; ln -s ../$$dir $$name; \
tar -c -z -f $$name.tar.gz $$name/. ;
mkdir $$name; \
tar cf - $(CSRC) $(HDR) $(MAN1) $(MAN3PCAP_EXPAND) \
$(MAN3PCAP_NOEXPAND) $(MANFILE) $(MANMISC) $(EXTRA_DIST) | \
(cd $$name; tar xf -); \
tar -c -z -f $$name.tar.gz $$name; \
rm -rf $$name
depend: $(GENSRC) $(GENHDR) bpf_filter.c
./mkdep -c $(CC) $(DEFS) $(INCLS) $(SRC)

42
README
View File

@ -1,20 +1,22 @@
@(#) $Header: /tcpdump/master/libpcap/README,v 1.30 2004/10/12 02:02:28 guy Exp $ (LBL)
@(#) $Header: /tcpdump/master/libpcap/README,v 1.30.4.3 2008-10-17 10:39:20 ken Exp $ (LBL)
LIBPCAP 0.9
Now maintained by "The Tcpdump Group"
See www.tcpdump.org
LIBPCAP 1.0.0
Please send inquiries/comments/reports to tcpdump-workers@tcpdump.org
www.tcpdump.org
Please send inquiries/comments/reports to:
tcpdump-workers@lists.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.9 of LIBPCAP can be retrieved with the CVS tag "libpcap_0_9rel1":
cvs -d :pserver:tcpdump@cvs.tcpdump.org:/tcpdump/master checkout -r libpcap_0_9rel1 libpcap
Version 1.0.0 of LIBPCAP can be retrieved with the CVS tag "libpcap_1_0":
cvs -d :pserver:tcpdump@cvs.tcpdump.org:/tcpdump/master checkout -r libpcap_1_0 libpcap
Please send patches against the master copy to patches@tcpdump.org.
Please submit patches against the master copy to the libpcap project on
sourceforge.net.
formerly from Lawrence Berkeley National Laboratory
Network Research Group <libpcap@ee.lbl.gov>
@ -30,8 +32,6 @@ 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
@ -77,16 +77,28 @@ 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.
Note to Linux distributions and *BSD systems that include libpcap:
There's now a rule to make a shared library, which should work on Linux
and *BSD (and OS X).
It sets the soname of the library to "libpcap.so.1"; this is what it
should be, *NOT* libpcap.so.1.0 or libpcap.so.1.0.0 or something such as
that.
We've been maintaining binary compatibility between libpcap releases for
quite a while; there's no reason to tie a binary linked with libpcap to
a particular release of libpcap.
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
to the address "tcpdump-workers@lists.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.
submitted as patches on the SourceForge site for libpcap.
Current versions can be found at www.tcpdump.org, or the SourceForge
site for libpcap.

View File

@ -1,46 +0,0 @@
Under Win32, libpcap is integrated in the WinPcap packet capture system.
WinPcap provides a framework that allows libpcap to capture the packets
under Windows 95, Windows 98, Windows ME, Windows NT 4, Windows 2000
and Windows XP.
WinPcap binaries and source code can be found at http://winpcap.polito.it:
they include also a developer's pack with all the necessary to compile
libpcap-based applications under Windows.
How to compile libpcap with Visual Studio
-----------------------------------------
In order to compile libpcap you will need:
- version 6 (or higher) of Microsoft Visual Studio
- The November 2001 (or later) edition of Microsoft Platform
Software Development Kit (SDK), that contains some necessary includes
for IPv6 support. You can download it from http://www.microsoft.com/sdk
- the latest WinPcap sources from http://winpcap.polito.it/install
The WinPcap source code already contains a recent (usually the latest
stable) version of libpcap. If you need to compile a different one,
simply download it from www.tcpdump.org and copy the sources in the
winpcap\wpcap\libpcap folder of the WinPcap distribution. If you want to
compile a libpcap source retrieved from the tcpdump.org CVS, you will
have to create the scanner and the grammar by hand (with lex and yacc)
or with the cygnus makefile, since The Visual Studio project is not able
to build them.
Open the project file winpcap\wpcap\prj\wpcap.dsw with Visual Studio and
build wpcap.dll. wpcap.lib, the library file to link with the applications,
will be generated in winpcap\wpcap\lib\. wpcap.dll will be generated in
winpcap\wpcap\prj\release or winpcap\wpcap\prj\debug depending on the type
of binary that is being created.
How to compile libpcap with Cygnus
----------------------------------
To build wpcap.dll, cd to the directory WPCAP/PRJ of the WinPcap source code
distribution and type "make". libwpcap.a, the library file to link with the
applications, will be generated in winpcap\wpcap\lib\. wpcap.dll will be
generated in winpcap\wpcap\prj.
Remember, you CANNOT use the MSVC-generated .lib files with gcc, use
libwpcap.a instead.
"make install" installs wpcap.dll in the Windows system folder.

View File

@ -1,78 +0,0 @@
Using BPF:
(1) AIX 4.x's version of BPF is undocumented and somewhat unstandard; the
current BPF support code includes changes that should work around
that; it appears to compile and work on at least one AIX 4.3.3
machine.
Note that the BPF driver and the "/dev/bpf" devices might not exist
on your machine; AIX's tcpdump loads the driver and creates the
devices if they don't already exist. Our libpcap should do the
same, and the configure script should detect that it's on an AIX
system and choose BPF even if the devices aren't there.
(2) If libpcap doesn't compile on your machine when configured to use
BPF, or if the workarounds fail to make it work correctly, you
should send to tcpdump-workers@tcpdump.org a detailed bug report (if
the compile fails, send us the compile error messages; if it
compiles but fails to work correctly, send us as detailed as
possible a description of the symptoms, including indications of the
network link-layer type being wrong or time stamps being wrong).
If you fix the problems yourself, please send to patches@tcpdump.org
a patch, so we can incorporate them into the next release.
If you don't fix the problems yourself, you can, as a workaround,
make libpcap use DLPI instead of BPF.
This can be done by specifying the flag:
--with-pcap=dlpi
to the "configure" script for libpcap.
If you use DLPI:
(1) It is a good idea to have the latest version of the DLPI driver on
your system, since certain versions may be buggy and cause your AIX
system to crash. DLPI is included in the fileset bos.rte.tty. I
found that the DLPI driver that came with AIX 4.3.2 was buggy, and
had to upgrade to bos.rte.tty 4.3.2.4:
lslpp -l bos.rte.tty
bos.rte.tty 4.3.2.4 COMMITTED Base TTY Support and Commands
Updates for AIX filesets can be obtained from:
ftp://service.software.ibm.com/aix/fixes/
These updates can be installed with the smit program.
(2) After compiling libpcap, you need to make sure that the DLPI driver
is loaded. Type:
strload -q -d dlpi
If the result is:
dlpi: yes
then the DLPI driver is loaded correctly.
If it is:
dlpi: no
Then you need to type:
strload -f /etc/dlpi.conf
Check again with strload -q -d dlpi that the dlpi driver is loaded.
Alternatively, you can uncomment the lines for DLPI in
/etc/pse.conf and reboot the machine; this way DLPI will always
be loaded when you boot your system.
(3) There appears to be a problem in the DLPI code in some versions of
AIX, causing a warning about DL_PROMISC_MULTI failing; this might
be responsible for DLPI not being able to capture outgoing packets.

View File

@ -1,114 +0,0 @@
The following instructions apply if you have a Linux or FreeBSD platform and
want libpcap to support the DAG range of passive network monitoring cards from
Endace (http://www.endace.com, see below for further contact details).
1) Install and build the DAG software distribution by following the
instructions supplied with that package. Current Endace customers can download
the DAG software distibution from https://www.endace.com
2) Configure libcap. To allow the 'configure' script to locate the DAG
software distribution use the '--with-dag' option:
./configure --with-dag=DIR
Where DIR is the root of the DAG software distribution, for example
/var/src/dag. If the DAG software is correctly detected 'configure' will
report:
checking whether we have DAG API... yes
If 'configure' reports that there is no DAG API, the directory may have been
incorrectly specified or the DAG software was not built before configuring
libpcap.
See also the libpcap INSTALL.txt file for further libpcap configuration
options.
Building libpcap at this stage will include support for both the native packet
capture stream (linux or bpf) and for capturing from DAG cards. To build
libpcap with only DAG support specify the capture type as 'dag' when
configuring libpcap:
./configure --with-dag=DIR --with-pcap=dag
Applications built with libpcap configured in this way will only detect DAG
cards and will not capture from the native OS packet stream.
----------------------------------------------------------------------
Libpcap when built for DAG cards against dag-2.5.1 or later releases:
Timeouts are supported. pcap_dispatch() will return after to_ms milliseconds
regardless of how many packets are received. If to_ms is zero pcap_dispatch()
will block waiting for data indefinitely.
pcap_dispatch() will block on and process a minimum of 64kB of data (before
filtering) for efficiency. This can introduce high latencies on quiet
interfaces unless a timeout value is set. The timeout expiring will override
the 64kB minimum causing pcap_dispatch() to process any available data and
return.
pcap_setnonblock is supported. When nonblock is set, pcap_dispatch() will
check once for available data, process any data available up to count, then
return immediately.
pcap_findalldevs() is supported, e.g. dag0, dag1...
Some DAG cards can provide more than one 'stream' of received data.
This can be data from different physical ports, or separated by filtering
or load balancing mechanisms. Receive streams have even numbers, e.g.
dag0:0, dag0:2 etc. Specifying transmit streams for capture is not supported.
pcap_setfilter() is supported, BPF programs run in userspace.
pcap_setdirection() is not supported. Only received traffic is captured.
DAG cards normally do not have IP or link layer addresses assigned as
they are used to passively monitor links.
pcap_breakloop() is supported.
pcap_datalink() and pcap_list_datalinks() are supported. The DAG card does
not attempt to set the correct datalink type automatically where more than
one type is possible.
pcap_stats() is supported. ps_drop is the number of packets dropped due to
RX stream buffer overflow, this count is before filters are applied (it will
include packets that would have been dropped by the filter). The RX stream
buffer size is user configurable outside libpcap, typically 16-512MB.
pcap_get_selectable_fd() is not supported, as DAG cards do not support
poll/select methods.
pcap_inject() and pcap_sendpacket() are not supported.
Some DAG cards now support capturing to multiple virtual interfaces, called
streams. Capture streams have even numbers. These are available via libpcap
as separate interfaces, e.g. dag0:0, dag0:2, dag0:4 etc. dag0:0 is the same
as dag0. These are visible via pcap_findalldevs().
libpcap now does NOT set the card's hardware snaplen (slen). This must now be
set using the appropriate DAG coniguration program, e.g. dagthree, dagfour,
dagsix, dagconfig. This is because the snaplen is currently shared between
all of the streams. In future this may change if per-stream slen is
implemented.
DAG cards by default capture entire packets including the L2
CRC/FCS. If the card is not configured to discard the CRC/FCS, this
can confuse applications that use libpcap if they're not prepared for
packets to have an FCS. Libpcap now reads the environment variable
ERF_FCS_BITS to determine how many bits of CRC/FCS to strip from the
end of the captured frame. This defaults to 32 for use with
Ethernet. If the card is configured to strip the CRC/FCS, then set
ERF_FCS_BITS=0. If used with a HDLC/PoS/PPP/Frame Relay link with 16
bit CRC/FCS, then set ERF_FCS_BITS=16.
----------------------------------------------------------------------
Please submit bug reports via <support@endace.com>.
Please also visit our Web site at:
http://www.endace.com/
For more information about Endace DAG cards contact <sales@endace.com>.

View File

@ -1,254 +0,0 @@
For HP-UX 11i (11.11) and later, there are no known issues with
promiscuous mode under HP-UX. If you are using a earlier version of
HP-UX and cannot upgrade, please continue reading.
HP-UX patches to fix packet capture problems
Note that packet-capture programs such as tcpdump may, on HP-UX, not be
able to see packets sent from the machine on which they're running.
Some articles on groups.google.com discussing this are:
http://groups.google.com/groups?selm=82ld3v%2480i%241%40mamenchi.zrz.TU-Berlin.DE
which says:
Newsgroups: comp.sys.hp.hpux
Subject: Re: Did someone made tcpdump working on 10.20 ?
Date: 12/08/1999
From: Lutz Jaenicke <jaenicke@emserv1.ee.TU-Berlin.DE>
In article <82ks5i$5vc$1@news1.dti.ne.jp>, mtsat <mtsat@iris.dti.ne.jp>
wrote:
>Hello,
>
>I downloaded and compiled tcpdump3.4 a couple of week ago. I tried to use
>it, but I can only see incoming data, never outgoing.
>Someone (raj) explained me that a patch was missing, and that this patch
>must me "patched" (poked) in order to see outbound data in promiscuous mode.
>Many things to do .... So the question is : did someone has already this
>"ready to use" PHNE_**** patch ?
Two things:
1. You do need a late "LAN products cumulative patch" (e.g. PHNE_18173
for s700/10.20).
2. You must use
echo 'lanc_outbound_promisc_flag/W1' | /usr/bin/adb -w /stand/vmunix /dev/kmem
You can insert this e.g. into /sbin/init.d/lan
Best regards,
Lutz
and
http://groups.google.com/groups?selm=88cf4t%24p03%241%40web1.cup.hp.com
which says:
Newsgroups: comp.sys.hp.hpux
Subject: Re: tcpdump only shows incoming packets
Date: 02/15/2000
From: Rick Jones <foo@bar.baz.invalid>
Harald Skotnes <harald@cc.uit.no> wrote:
> I am running HPUX 11.0 on a C200 hanging on a 100Mb switch. I have
> compiled libpcap-0.4 an tcpdump-3.4 and it seems to work. But at a
> closer look I only get to see the incoming packets not the
> outgoing. I have tried tcpflow-0.12 which also uses libpcap and the
> same thing happens. Could someone please give me a hint on how to
> get this right?
Search/Read the archives ?-)
What you are seeing is expected, un-patched, behaviour for an HP-UX
system. On 11.00, you need to install the latest lancommon/DLPI
patches, and then the latest driver patch for the interface(s) in use.
At that point, a miracle happens and you should start seeing outbound
traffic.
[That article also mentions the patch that appears below.]
and
http://groups.google.com/groups?selm=38AA973E.96BE7DF7%40cc.uit.no
which says:
Newsgroups: comp.sys.hp.hpux
Subject: Re: tcpdump only shows incoming packets
Date: 02/16/2000
From: Harald Skotnes <harald@cc.uit.no>
Rick Jones wrote:
...
> What you are seeing is expected, un-patched, behaviour for an HP-UX
> system. On 11.00, you need to install the latest lancommon/DLPI
> patches, and then the latest driver patch for the interface(s) in
> use. At that point, a miracle happens and you should start seeing
> outbound traffic.
Thanks a lot. I have this problem on several machines running HPUX
10.20 and 11.00. The machines where patched up before y2k so did not
know what to think. Anyway I have now installed PHNE_19766,
PHNE_19826, PHNE_20008, PHNE_20735 on the C200 and now I can see the
outbound traffic too. Thanks again.
(although those patches may not be the ones to install - there may be
later patches).
And another message to tcpdump-workers@tcpdump.org, from Rick Jones:
Date: Mon, 29 Apr 2002 15:59:55 -0700
From: Rick Jones
To: tcpdump-workers@tcpdump.org
Subject: Re: [tcpdump-workers] I Can't Capture the Outbound Traffic
...
http://itrc.hp.com/ would be one place to start in a search for the most
up-to-date patches for DLPI and the lan driver(s) used on your system (I
cannot guess because 9000/800 is too generic - one hs to use the "model"
command these days and/or an ioscan command (see manpage) to guess what
the drivers (btlan[3456], gelan, etc) might be involved in addition to
DLPI.
Another option is to upgrade to 11i as outbound promiscuous mode support
is there in the base OS, no patches required.
Another posting:
http://groups.google.com/groups?selm=7d6gvn%24b3%241%40ocean.cup.hp.com
indicates that you need to install the optional STREAMS product to do
captures on HP-UX 9.x:
Newsgroups: comp.sys.hp.hpux
Subject: Re: tcpdump HP/UX 9.x
Date: 03/22/1999
From: Rick Jones <foo@bar.baz>
Dave Barr (barr@cis.ohio-state.edu) wrote:
: Has anyone ported tcpdump (or something similar) to HP/UX 9.x?
I'm reasonably confident that any port of tcpdump to 9.X would require
the (then optional) STREAMS product. This would bring DLPI, which is
what one uses to access interfaces in promiscuous mode.
I'm not sure that HP even sells the 9.X STREAMS product any longer,
since HP-UX 9.X is off the pricelist (well, maybe 9.10 for the old 68K
devices).
Your best bet is to be up on 10.20 or better if that is at all
possible. If your hardware is supported by it, I'd go with HP-UX 11.
If you want to see the system's own outbound traffic, you'll never get
that functionality on 9.X, but it might happen at some point for 10.20
and 11.X.
rick jones
(as per other messages cited here, the ability to see the system's own
outbound traffic did happen).
Rick Jones reports that HP-UX 11i needs no patches for outbound
promiscuous mode support.
An additional note, from Jost Martin, for HP-UX 10.20:
Q: How do I get ethereral on HPUX to capture the _outgoing_ packets
of an interface
A: You need to get PHNE_20892,PHNE_20725 and PHCO_10947 (or
newer, this is as of 4.4.00) and its dependencies. Then you can
enable the feature as descibed below:
Patch Name: PHNE_20892
Patch Description: s700 10.20 PCI 100Base-T cumulative patch
To trace the outbound packets, please do the following
to turn on a global promiscuous switch before running
the promiscuous applications like snoop or tcpdump:
adb -w /stand/vmunix /dev/mem
lanc_outbound_promisc_flag/W 1
(adb will echo the result showing that the flag has
been changed)
$quit
(Thanks for this part to HP-support, Ratingen)
The attached hack does this and some security-related stuff
(thanks to hildeb@www.stahl.bau.tu-bs.de (Ralf Hildebrandt) who
posted the security-part some time ago)
<<hack_ip_stack>>
(Don't switch IP-forwarding off, if you need it !)
Install the hack as /sbin/init.d/hacl_ip_stack (adjust
permissions !) and make a sequencing-symlink
/sbin/rc2.d/S350hack_ip_stack pointing to this script.
Now all this is done on every reboot.
According to Rick Jones, the global promiscuous switch also has to be
turned on for HP-UX 11.00, but not for 11i - and, in fact, the switch
doesn't even exist on 11i.
Here's the "hack_ip_stack" script:
-----------------------------------Cut Here-------------------------------------
#!/sbin/sh
#
# nettune: hack kernel parms for safety
OKAY=0
ERROR=-1
# /usr/contrib/bin fuer nettune auf Pfad
PATH=/sbin:/usr/sbin:/usr/bin:/usr/contrib/bin
export PATH
##########
# main #
##########
case $1 in
start_msg)
print "Tune IP-Stack for security"
exit $OKAY
;;
stop_msg)
print "This action is not applicable"
exit $OKAY
;;
stop)
exit $OKAY
;;
start)
;; # fall through
*)
print "USAGE: $0 {start_msg | stop_msg | start | stop}" >&2
exit $ERROR
;;
esac
###########
# start #
###########
#
# tcp-Sequence-Numbers nicht mehr inkrementieren sondern random
# Syn-Flood-Protection an
# ip_forwarding aus
# Source-Routing aus
# Ausgehende Packets an ethereal/tcpdump etc.
/usr/contrib/bin/nettune -s tcp_random_seq 2 || exit $ERROR
/usr/contrib/bin/nettune -s hp_syn_protect 1 || exit $ERROR
/usr/contrib/bin/nettune -s ip_forwarding 0 || exit $ERROR
echo 'ip_block_source_routed/W1' | /usr/bin/adb -w /stand/vmunix /dev/kmem || exit $ERROR
echo 'lanc_outbound_promisc_flag/W 1' | adb -w /stand/vmunix /dev/mem || exit $ERROR
exit $OKAY
-----------------------------------Cut Here-------------------------------------

View File

@ -1,88 +0,0 @@
In order for libpcap to be able to capture packets on a Linux system,
the "packet" protocol must be supported by your kernel. If it is not,
you may get error messages such as
modprobe: can't locate module net-pf-17
in "/var/adm/messages", or may get messages such as
socket: Address family not supported by protocol
from applications using libpcap.
You must configure the kernel with the CONFIG_PACKET option for this
protocol; the following note is from the Linux "Configure.help" file for
the 2.0[.x] kernel:
Packet socket
CONFIG_PACKET
The Packet protocol is used by applications which communicate
directly with network devices without an intermediate network
protocol implemented in the kernel, e.g. tcpdump. If you want them
to work, choose Y.
This driver is also available as a module called af_packet.o ( =
code which can be inserted in and removed from the running kernel
whenever you want). If you want to compile it as a module, say M
here and read Documentation/modules.txt; if you use modprobe or
kmod, you may also want to add "alias net-pf-17 af_packet" to
/etc/modules.conf.
and the note for the 2.2[.x] kernel says:
Packet socket
CONFIG_PACKET
The Packet protocol is used by applications which communicate
directly with network devices without an intermediate network
protocol implemented in the kernel, e.g. tcpdump. If you want them
to work, choose Y. This driver is also available as a module called
af_packet.o ( = code which can be inserted in and removed from the
running kernel whenever you want). If you want to compile it as a
module, say M here and read Documentation/modules.txt. You will
need to add 'alias net-pf-17 af_packet' to your /etc/conf.modules
file for the module version to function automatically. If unsure,
say Y.
In addition, there is an option that, in 2.2 and later kernels, will
allow packet capture filters specified to programs such as tcpdump to be
executed in the kernel, so that packets that don't pass the filter won't
be copied from the kernel to the program, rather than having all packets
copied to the program and libpcap doing the filtering in user mode.
Copying packets from the kernel to the program consumes a significant
amount of CPU, so filtering in the kernel can reduce the overhead of
capturing packets if a filter has been specified that discards a
significant number of packets. (If no filter is specified, it makes no
difference whether the filtering isn't performed in the kernel or isn't
performed in user mode. :-))
The option for this is the CONFIG_FILTER option; the "Configure.help"
file says:
Socket filtering
CONFIG_FILTER
The Linux Socket Filter is derived from the Berkeley Packet Filter.
If you say Y here, user-space programs can attach a filter to any
socket and thereby tell the kernel that it should allow or disallow
certain types of data to get through the socket. Linux Socket
Filtering works on all socket types except TCP for now. See the text
file linux/Documentation/networking/filter.txt for more information.
If unsure, say N.
Statistics:
Statistics reported by pcap are platform specific. The statistics
reported by pcap_stats on Linux are as follows:
2.2.x
=====
ps_recv Number of packets that were accepted by the pcap filter
ps_drops Always 0, this statistic is not gatherd on this platform
2.4.x
=====
ps_rec Number of packets that were accepted by the pcap filter
ps_drops Number of packets that had passed filtering but were not
passed on to pcap due to things like buffer shortage, etc.
This is useful because these are packets you are interested in
but won't be reported by, for example, tcpdump output.

View File

@ -1,43 +0,0 @@
As with other systems using BPF, Mac OS X allows users with read access
to the BPF devices to capture packets with libpcap and allows users with
write access to the BPF devices to send packets with libpcap.
On some systems that use BPF, the BPF devices live on the root file
system, and the permissions and/or ownership on those devices can be
changed to give users other than root permission to read or write those
devices.
On newer versions of FreeBSD, the BPF devices live on devfs, and devfs
can be configured to set the permissions and/or ownership of those
devices to give users other than root permission to read or write those
devices.
On Mac OS X, the BPF devices live on devfs, but the OS X version of
devfs is based on an older (non-default) FreeBSD devfs, and that version
of devfs cannot be configured to set the permissions and/or ownership of
those devices.
Therefore, we supply a "startup item" for OS X that will change the
ownership of the BPF devices so that the "admin" group owns them, and
will change the permission of the BPF devices to rw-rw----, so that all
users in the "admin" group - i.e., all users with "Allow user to
administer this computer" turned on - have both read and write access to
them.
The startup item is in the ChmodBPF directory in the source tree. A
/Library/StartupItems directory should be created if it doesn't already
exist, and the ChmodBPF directory should be copied to the
/Library/StartupItems directory (copy the entire directory, so that
there's a /Library/StartupItems/ChmodBPF directory, containing all the
files in the source tree's ChmodBPF directory; don't copy the individual
items in that directory to /Library/StartupItems).
If you want to give a particular user permission to access the BPF
devices, rather than giving all administrative users permission to
access them, you can have the ChmodBPF/ChmodBPF script change the
ownership of /dev/bpf* without changing the permissions. If you want to
give a particular user permission to read and write the BPF devices and
give the administrative users permission to read but not write the BPF
devices, you can have the script change the owner to that user, the
group to "admin", and the permissions to rw-r-----. Other possibilities
are left as an exercise for the reader.

View File

@ -1,50 +0,0 @@
The following instructions apply if you have a Linux platform and want
libpcap to support the Septel range of passive network monitoring cards
from Intel (http://www.intel.com)
1) Install and build the Septel software distribution by following the
instructions supplied with that package.
2) Configure libcap. To allow the 'configure' script to locate the Septel
software distribution use the '--with-septel' option:
./configure --with-septel=DIR
where DIR is the root of the Septel software distribution, for example
/var/src/septel.
By default (if you write only ./configure --with-septel) it takes
./../septel as argument for DIR.
If the Septel software is correctly detected 'configure' will
report:
checking whether we have Septel API... yes
If 'configure' reports that there is no Septel API, the directory may have been
incorrectly specified or the Septel software was not built before configuring
libpcap.
See also the libpcap INSTALL.txt file for further libpcap configuration
options.
Building libpcap at this stage will include support for both the native
packet capture stream and for capturing from Septel cards. To build
libpcap with only Septel support specify the capture type as 'septel'
when configuring libpcap:
./configure --with-septel=DIR --with-pcap=septel
Applications built with libpcap configured in this way will only detect Septel
cards and will not capture from the native OS packet stream.
Note: As mentioned in pcap-septel.c we should first edit the system.txt
file to change the user part example (UPE) module id to 0xdd instead of
0x2d for technical reason. So this change in system.txt is crutial and
things will go wrong if it's not done. System.txt along with config.txt
are configuration files that are edited by the user before running the
gctload program that uses these files for initialising modules and
configuring parameters.
----------------------------------------------------------------------
for more information please contact me : gil_hoyek@hotmail.com

View File

@ -1,49 +0,0 @@
The following instructions are applicable to Tru64 UNIX
(formerly Digital UNIX (formerly DEC OSF/1)) version 4.0, and
probably to later versions as well; at least some options apply to
Digital UNIX 3.2 - perhaps all do.
In order to use kernel packet filtering on this system, you have
to configure it in such a way:
Kernel configuration
--------------------
The packet filtering kernel option must be enabled at kernel
installation. If it was not the case, you can rebuild the kernel with
"doconfig -c" after adding the following line in the kernel
configuration file (/sys/conf/<HOSTNAME>):
option PACKETFILTER
or use "doconfig" without any arguments to add the packet filter driver
option via the kernel option menu (see the system administration
documentation for information on how to do this).
Device configuration
--------------------
Devices used for packet filtering must be created thanks to
the following command (executed in the /dev directory):
./MAKEDEV pfilt
Interface configuration
-----------------------
In order to capture all packets on a network, you may want to allow
applications to put the interface on that network into "local copy"
mode, so that tcpdump can see packets sent by the host on which it's
running as well as packets received by that host, and to put the
interface into "promiscuous" mode, so that tcpdump can see packets on
the network segment not sent to the host on which it's running, by using
the pfconfig(1) command:
pfconfig +c +p <network_device>
or allow application to put any interface into "local copy" or
"promiscuous" mode by using the command:
pfconfig +c +p -a
Note: all instructions given require root privileges.

View File

@ -1 +1 @@
0.9.8
1.0.0

81
aclocal.m4 vendored
View File

@ -1,4 +1,4 @@
dnl @(#) $Header: /tcpdump/master/libpcap/aclocal.m4,v 1.85.2.1 2005/04/21 03:42:09 guy Exp $ (LBL)
dnl @(#) $Header: /tcpdump/master/libpcap/aclocal.m4,v 1.86.2.6 2008-09-28 17:13:37 guy Exp $ (LBL)
dnl
dnl Copyright (c) 1995, 1996, 1997, 1998
dnl The Regents of the University of California. All rights reserved.
@ -57,7 +57,7 @@ AC_DEFUN(AC_LBL_C_INIT,
LBL_CFLAGS="$CFLAGS"
fi
if test -z "$CC" ; then
case "$target_os" in
case "$host_os" in
bsdi*)
AC_CHECK_PROG(SHLICC2, shlicc2, yes, no)
@ -100,7 +100,7 @@ AC_DEFUN(AC_LBL_C_INIT,
ac_cv_lbl_cc_ansi_prototypes=no))
AC_MSG_RESULT($ac_cv_lbl_cc_ansi_prototypes)
if test $ac_cv_lbl_cc_ansi_prototypes = no ; then
case "$target_os" in
case "$host_os" in
hpux*)
AC_MSG_CHECKING(for HP-UX ansi compiler ($CC -Aa -D_HPUX_SOURCE))
@ -129,7 +129,7 @@ AC_DEFUN(AC_LBL_C_INIT,
$2="$$2 -I/usr/local/include"
LDFLAGS="$LDFLAGS -L/usr/local/lib"
case "$target_os" in
case "$host_os" in
irix*)
V_CCOPT="$V_CCOPT -xansi -signed -g3"
@ -269,7 +269,7 @@ AC_DEFUN(AC_LBL_LIBPCAP,
AC_MSG_RESULT($libpcap)
fi
LIBS="$libpcap $LIBS"
case "$target_os" in
case "$host_os" in
aix*)
pseexe="/lib/pse.exp"
@ -301,7 +301,7 @@ AC_DEFUN(AC_LBL_TYPE_SIGNAL,
else
AC_DEFINE(RETSIGVAL,(0),[return value of signal handlers])
fi
case "$target_os" in
case "$host_os" in
irix*)
AC_DEFINE(_BSD_SIGNALS,1,[get BSD semantics on Irix])
@ -627,7 +627,7 @@ AC_DEFUN(AC_LBL_UNALIGNED_ACCESS,
# know it does work, and have the script just fail on other
# cpu types and update it when such a failure occurs.
#
alpha*|arm*|hp*|mips*|sh*|sparc*|ia64|nv1)
alpha*|arm*|bfin*|hp*|mips*|sh*|sparc*|ia64|nv1)
ac_cv_lbl_unaligned_fail=yes
;;
@ -682,7 +682,7 @@ EOF
dnl
dnl If using gcc and the file .devel exists:
dnl Compile with -g (if supported) and -Wall
dnl If using gcc 2, do extra prototype checking
dnl If using gcc 2 or later, do extra prototype checking
dnl If an os prototype include exists, symlink os-proto.h to it
dnl
dnl usage:
@ -712,7 +712,7 @@ AC_DEFUN(AC_LBL_DEVEL,
fi
fi
else
case "$target_os" in
case "$host_os" in
irix6*)
V_CCOPT="$V_CCOPT -n32"
@ -722,7 +722,7 @@ AC_DEFUN(AC_LBL_DEVEL,
;;
esac
fi
os=`echo $target_os | sed -e 's/\([[0-9]][[0-9]]*\)[[^0-9]].*$/\1/'`
os=`echo $host_os | sed -e 's/\([[0-9]][[0-9]]*\)[[^0-9]].*$/\1/'`
name="lbl/os-$os.h"
if test -f $name ; then
ln -s $name os-proto.h
@ -746,6 +746,11 @@ dnl results:
dnl
dnl LIBS
dnl
dnl XXX - "AC_LBL_LIBRARY_NET" was redone to use "AC_SEARCH_LIBS"
dnl rather than "AC_LBL_CHECK_LIB", so this isn't used any more.
dnl We keep it around for reference purposes in case it's ever
dnl useful in the future.
dnl
define(AC_LBL_CHECK_LIB,
[AC_MSG_CHECKING([for $2 in -l$1])
@ -898,3 +903,59 @@ AC_DEFUN(AC_LBL_TPACKET_STATS,
if test $ac_cv_lbl_tpacket_stats = yes; then
AC_DEFINE(HAVE_TPACKET_STATS,1,[if if_packet.h has tpacket_stats defined])
fi])
dnl
dnl Checks to see if the tpacket_auxdata struct has a tp_vlan_tci member.
dnl
dnl usage:
dnl
dnl AC_LBL_LINUX_TPACKET_AUXDATA_TP_VLAN_TCI
dnl
dnl results:
dnl
dnl HAVE_LINUX_TPACKET_AUXDATA_TP_VLAN_TCI (defined)
dnl
dnl NOTE: any compile failure means we conclude that it doesn't have
dnl that member, so if we don't have tpacket_auxdata, we conclude it
dnl doesn't have that member (which is OK, as either we won't be using
dnl code that would use that member, or we wouldn't compile in any case).
dnl
AC_DEFUN(AC_LBL_LINUX_TPACKET_AUXDATA_TP_VLAN_TCI,
[AC_MSG_CHECKING(if tpacket_auxdata struct has tp_vlan_tci member)
AC_CACHE_VAL(ac_cv_lbl_dl_hp_ppa_info_t_has_dl_module_id_1,
AC_TRY_COMPILE([
# include <linux/if_packet.h>],
[u_int i = sizeof(((struct tpacket_auxdata *)0)->tp_vlan_tci)],
ac_cv_lbl_linux_tpacket_auxdata_tp_vlan_tci=yes,
ac_cv_lbl_linux_tpacket_auxdata_tp_vlan_tci=no))
AC_MSG_RESULT($ac_cv_lbl_linux_tpacket_auxdata_tp_vlan_tci)
if test $ac_cv_lbl_linux_tpacket_auxdata_tp_vlan_tci = yes ; then
AC_DEFINE(HAVE_LINUX_TPACKET_AUXDATA_TP_VLAN_TCI,1,[if tp_vlan_tci exists])
fi])
dnl
dnl Checks to see if Solaris has the dl_passive_req_t struct defined
dnl in <sys/dlpi.h>.
dnl
dnl usage:
dnl
dnl AC_LBL_DL_PASSIVE_REQ_T
dnl
dnl results:
dnl
dnl HAVE_DLPI_PASSIVE (defined)
dnl
AC_DEFUN(AC_LBL_DL_PASSIVE_REQ_T,
[AC_MSG_CHECKING(if dl_passive_req_t struct exists)
AC_CACHE_VAL(ac_cv_lbl_has_dl_passive_req_t,
AC_TRY_COMPILE([
# include <sys/types.h>
# include <sys/dlpi.h>],
[u_int i = sizeof(dl_passive_req_t)],
ac_cv_lbl_has_dl_passive_req_t=yes,
ac_cv_lbl_has_dl_passive_req_t=no))
AC_MSG_RESULT($ac_cv_lbl_has_dl_passive_req_t)
if test $ac_cv_lbl_has_dl_passive_req_t = yes ; then
AC_DEFINE(HAVE_DLPI_PASSIVE,1,[if passive_req_t primitive
exists])
fi])

505
acsite.m4
View File

@ -1,505 +0,0 @@
dnl @(#) $Header: acsite.m4,v 1.41 96/11/29 15:30:40 leres Exp $ (LBL)
dnl
dnl Copyright (c) 1995, 1996
dnl The Regents of the University of California. All rights reserved.
dnl
dnl Redistribution and use in source and binary forms, with or without
dnl modification, are permitted provided that: (1) source code distributions
dnl retain the above copyright notice and this paragraph in its entirety, (2)
dnl distributions including binary code include the above copyright notice and
dnl this paragraph in its entirety in the documentation or other materials
dnl provided with the distribution, and (3) all advertising materials mentioning
dnl features or use of this software display the following acknowledgement:
dnl ``This product includes software developed by the University of California,
dnl Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
dnl the University nor the names of its contributors may be used to endorse
dnl or promote products derived from this software without specific prior
dnl written permission.
dnl THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
dnl WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
dnl MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
dnl
dnl LBL autoconf macros
dnl
dnl
dnl Determine which compiler we're using (cc or gcc)
dnl If using gcc, determine the version number
dnl If using cc, require that it support ansi prototypes
dnl If using gcc, use -O2 (otherwise use -O)
dnl If using cc, explicitly specify /usr/local/include
dnl
dnl usage:
dnl
dnl AC_LBL_C_INIT(copt, incls)
dnl
dnl results:
dnl
dnl $1 (copt set)
dnl $2 (incls set)
dnl CC
dnl ac_cv_gcc_vers
dnl LBL_CFLAGS
dnl
dnl XXX need to add test to make sure ac_prog_cc hasn't been called
AC_DEFUN(AC_LBL_C_INIT,
[AC_PREREQ(2.12)
$1=-O
$2=""
if test "${CFLAGS+set}" = set; then
LBL_CFLAGS="$CFLAGS"
fi
if test -z "$CC" ; then
case "$target_os" in
bsdi*)
AC_CHECK_PROG(SHLICC2, shlicc2, yes, no)
if test $SHLICC2 = yes ; then
CC=shlicc2
export CC
fi
;;
esac
fi
AC_PROG_CC
if test $ac_cv_prog_gcc = yes ; then
if test "$SHLICC2" = yes ; then
ac_cv_gcc_vers=2
$1=-O2
else
AC_MSG_CHECKING(gcc version)
AC_CACHE_VAL(ac_cv_gcc_vers,
ac_cv_gcc_vers=`$CC -v 2>&1 | \
sed -n -e '$s/.* //' -e '$s/\..*//p'`)
AC_MSG_RESULT($ac_cv_gcc_vers)
if test $ac_cv_gcc_vers -gt 1 ; then
$1=-O2
fi
fi
else
AC_MSG_CHECKING(that $CC handles ansi prototypes)
AC_CACHE_VAL(ac_cv_cc_ansi_prototypes,
AC_TRY_COMPILE(
[#include <sys/types.h>],
[int frob(int, char *)],
ac_cv_cc_ansi_prototypes=yes,
ac_cv_cc_ansi_prototypes=no))
AC_MSG_RESULT($ac_cv_cc_ansi_prototypes)
if test $ac_cv_cc_ansi_prototypes = no ; then
case "$target_os" in
hpux*)
AC_MSG_CHECKING(for HP-UX ansi compiler ($CC -Aa -D_HPUX_SOURCE))
savedcflags="$CFLAGS"
CFLAGS="-Aa -D_HPUX_SOURCE $CFLAGS"
AC_CACHE_VAL(ac_cv_cc_hpux_cc_aa,
AC_TRY_COMPILE(
[#include <sys/types.h>],
[int frob(int, char *)],
ac_cv_cc_hpux_cc_aa=yes,
ac_cv_cc_hpux_cc_aa=no))
AC_MSG_RESULT($ac_cv_cc_hpux_cc_aa)
if test $ac_cv_cc_hpux_cc_aa = no ; then
AC_MSG_ERROR(see the INSTALL for more info)
fi
CFLAGS="$savedcflags"
V_CCOPT="-Aa $V_CCOPT"
AC_DEFINE(_HPUX_SOURCE)
;;
*)
AC_MSG_ERROR(see the INSTALL for more info)
;;
esac
fi
$2=-I/usr/local/include
case "$target_os" in
irix*)
V_CCOPT="$V_CCOPT -xansi -signed -g3"
;;
osf*)
V_CCOPT="$V_CCOPT -g3"
;;
ultrix*)
AC_MSG_CHECKING(that Ultrix $CC hacks const in prototypes)
AC_CACHE_VAL(ac_cv_cc_const_proto,
AC_TRY_COMPILE(
[#include <sys/types.h>],
[struct a { int b; };
void c(const struct a *)],
ac_cv_cc_const_proto=yes,
ac_cv_cc_const_proto=no))
AC_MSG_RESULT($ac_cv_cc_const_proto)
if test $ac_cv_cc_const_proto = no ; then
AC_DEFINE(const,)
fi
;;
esac
fi
])
dnl
dnl Use pfopen.c if available and pfopen() not in standard libraries
dnl Require libpcap
dnl Look for libpcap in ..
dnl Use the installed libpcap if there is no local version
dnl
dnl usage:
dnl
dnl AC_LBL_LIBPCAP(pcapdep, incls)
dnl
dnl results:
dnl
dnl $1 (pcapdep set)
dnl $2 (incls appended)
dnl LIBS
dnl
AC_DEFUN(AC_LBL_LIBPCAP,
[pfopen=/usr/examples/packetfilter/pfopen.c
if test -f $pfopen ; then
AC_CHECK_FUNCS(pfopen)
if test $ac_cv_func_pfopen = "no" ; then
AC_MSG_RESULT(Using $pfopen)
LIBS="$LIBS $pfopen"
fi
fi
AC_MSG_CHECKING(for local pcap library)
libpcap=FAIL
lastdir=FAIL
places=`ls .. | sed -e 's,/$,,' -e 's,^,../,' | \
egrep '/libpcap-[[0-9]]*\.[[0-9]]*(\.[[0-9]]*)?([[ab]][[0-9]]*)?$'`
for dir in $places ../libpcap libpcap ; do
basedir=`echo $dir | sed -e 's/[[ab]][[0-9]]*$//'`
if test $lastdir = $basedir ; then
dnl skip alphas when an actual release is present
continue;
fi
lastdir=$dir
if test -r $dir/pcap.c ; then
libpcap=$dir/libpcap.a
d=$dir
dnl continue and select the last one that exists
fi
done
if test $libpcap = FAIL ; then
AC_MSG_RESULT(not found)
AC_CHECK_LIB(pcap, main, libpcap="-lpcap")
if test $libpcap = FAIL ; then
AC_MSG_ERROR(see the INSTALL doc for more info)
fi
else
$1=$libpcap
$2="-I$d $$2"
AC_MSG_RESULT($libpcap)
fi
LIBS="$libpcap $LIBS"])
dnl
dnl Define RETSIGTYPE and RETSIGVAL
dnl
dnl usage:
dnl
dnl AC_LBL_TYPE_SIGNAL
dnl
dnl results:
dnl
dnl RETSIGTYPE (defined)
dnl RETSIGVAL (defined)
dnl
AC_DEFUN(AC_LBL_TYPE_SIGNAL,
[AC_TYPE_SIGNAL
if test "$ac_cv_type_signal" = void ; then
AC_DEFINE(RETSIGVAL,)
else
AC_DEFINE(RETSIGVAL,(0))
fi
case "$target_os" in
irix*)
AC_DEFINE(_BSD_SIGNALS)
;;
*)
AC_CHECK_FUNCS(sigset)
if test $ac_cv_func_sigset = yes ; then
AC_DEFINE(signal, sigset)
fi
;;
esac])
dnl
dnl If using gcc, see if fixincludes should be run
dnl
dnl usage:
dnl
dnl AC_LBL_FIXINCLUDES
dnl
AC_DEFUN(AC_LBL_FIXINCLUDES,
[if test $ac_cv_prog_gcc = yes ; then
AC_MSG_CHECKING(if fixincludes is needed)
AC_CACHE_VAL(ac_cv_gcc_fixincludes,
AC_TRY_COMPILE(
[/*
* This generates a "duplicate case value" when fixincludes
* has not be run.
*/
# include <sys/types.h>
# include <sys/time.h>
# include <sys/ioctl.h>
# ifdef HAVE_SYS_IOCCOM_H
# include <sys/ioccom.h>
# endif],
[switch (0) {
case _IO('A', 1):;
case _IO('B', 1):;
}],
ac_cv_gcc_fixincludes=yes,
ac_cv_gcc_fixincludes=no))
AC_MSG_RESULT($ac_cv_gcc_fixincludes)
if test $ac_cv_gcc_fixincludes = no ; then
# Don't cache failure
unset ac_cv_gcc_fixincludes
AC_MSG_ERROR(see the INSTALL for more info)
fi
fi])
dnl
dnl Check for flex, default to lex
dnl Require flex 2.4 or higher
dnl Check for bison, default to yacc
dnl Default to lex/yacc if both flex and bison are not available
dnl Define the yy prefix string if using flex and bison
dnl
dnl usage:
dnl
dnl AC_LBL_LEX_AND_YACC(lex, yacc, yyprefix)
dnl
dnl results:
dnl
dnl $1 (lex set)
dnl $2 (yacc appended)
dnl $3 (optional flex and bison -P prefix)
dnl
AC_DEFUN(AC_LBL_LEX_AND_YACC,
[AC_CHECK_PROGS($1, flex, lex)
if test "$$1" = flex ; then
# The -V flag was added in 2.4
AC_MSG_CHECKING(for flex 2.4 or higher)
AC_CACHE_VAL(ac_cv_flex_v24,
if flex -V >/dev/null 2>&1; then
ac_cv_flex_v24=yes
else
ac_cv_flex_v24=no
fi)
AC_MSG_RESULT($ac_cv_flex_v24)
if test $ac_cv_flex_v24 = no ; then
s="2.4 or higher required"
AC_MSG_WARN(ignoring obsolete flex executable ($s))
$1=lex
fi
fi
AC_CHECK_PROGS($2, bison, yacc)
if test "$$2" = bison ; then
$2="$$2 -y"
fi
if test "$$1" != lex -a "$$2" = yacc -o "$$1" = lex -a "$$2" != yacc ; then
AC_MSG_WARN(don't have both flex and bison; reverting to lex/yacc)
$1=lex
$2=yacc
fi
if test "$$1" = flex -a -n "$3" ; then
$1="$$1 -P$3"
$2="$$2 -p $3"
fi])
dnl
dnl Checks to see if union wait is used with WEXITSTATUS()
dnl
dnl usage:
dnl
dnl AC_LBL_UNION_WAIT
dnl
dnl results:
dnl
dnl DECLWAITSTATUS (defined)
dnl
AC_DEFUN(AC_LBL_UNION_WAIT,
[AC_MSG_CHECKING(if union wait is used)
AC_CACHE_VAL(ac_cv_union_wait,
AC_TRY_COMPILE([
# include <sys/types.h>
# include <sys/wait.h>],
[int status;
u_int i = WEXITSTATUS(status);
u_int j = waitpid(0, &status, 0);],
ac_cv_union_wait=no,
ac_cv_union_wait=yes))
AC_MSG_RESULT($ac_cv_union_wait)
if test $ac_cv_union_wait = yes ; then
AC_DEFINE(DECLWAITSTATUS,union wait)
else
AC_DEFINE(DECLWAITSTATUS,int)
fi])
dnl
dnl Checks to see if the sockaddr struct has the 4.4 BSD sa_len member
dnl
dnl usage:
dnl
dnl AC_LBL_SOCKADDR_SA_LEN
dnl
dnl results:
dnl
dnl HAVE_SOCKADDR_SA_LEN (defined)
dnl
AC_DEFUN(AC_LBL_SOCKADDR_SA_LEN,
[AC_MSG_CHECKING(if sockaddr struct has sa_len member)
AC_CACHE_VAL(ac_cv_sockaddr_has_sa_len,
AC_TRY_COMPILE([
# include <sys/types.h>
# include <sys/socket.h>],
[u_int i = sizeof(((struct sockaddr *)0)->sa_len)],
ac_cv_sockaddr_has_sa_len=yes,
ac_cv_sockaddr_has_sa_len=no))
AC_MSG_RESULT($ac_cv_sockaddr_has_sa_len)
if test $ac_cv_sockaddr_has_sa_len = yes ; then
AC_DEFINE(HAVE_SOCKADDR_SA_LEN)
fi])
dnl
dnl Checks to see if -R is used
dnl
dnl usage:
dnl
dnl AC_LBL_HAVE_RUN_PATH
dnl
dnl results:
dnl
dnl ac_cv_have_run_path (yes or no)
dnl
AC_DEFUN(AC_LBL_HAVE_RUN_PATH,
[AC_MSG_CHECKING(for ${CC-cc} -R)
AC_CACHE_VAL(ac_cv_have_run_path,
[echo 'main(){}' > conftest.c
${CC-cc} -o conftest conftest.c -R/a1/b2/c3 >conftest.out 2>&1
if test ! -s conftest.out ; then
ac_cv_have_run_path=yes
else
ac_cv_have_run_path=no
fi
rm -f conftest*])
AC_MSG_RESULT($ac_cv_have_run_path)
])
dnl
dnl Checks to see if unaligned memory accesses fail
dnl
dnl usage:
dnl
dnl AC_LBL_UNALIGNED_ACCESS
dnl
dnl results:
dnl
dnl LBL_ALIGN (DEFINED)
dnl
AC_DEFUN(AC_LBL_UNALIGNED_ACCESS,
[AC_MSG_CHECKING(if unaligned accesses fail)
AC_CACHE_VAL(ac_cv_unaligned_fail,
[case "$target_cpu" in
alpha|hp*|mips|sparc)
ac_cv_unaligned_fail=yes
;;
*)
cat >conftest.c <<EOF
# include <sys/types.h>
# include <sys/wait.h>
# include <stdio.h>
unsigned char a[[5]] = { 1, 2, 3, 4, 5 };
main() {
unsigned int i;
pid_t pid;
int status;
/* avoid "core dumped" message */
pid = fork();
if (pid < 0)
exit(2);
if (pid > 0) {
/* parent */
pid = waitpid(pid, &status, 0);
if (pid < 0)
exit(3);
exit(!WIFEXITED(status));
}
/* child */
i = *(unsigned int *)&a[[1]];
printf("%d\n", i);
exit(0);
}
EOF
${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS \
conftest.c $LIBS >/dev/null 2>&1
if test ! -x conftest ; then
dnl failed to compile for some reason
ac_cv_unaligned_fail=yes
else
./conftest >conftest.out
if test ! -s conftest.out ; then
ac_cv_unaligned_fail=yes
else
ac_cv_unaligned_fail=no
fi
fi
rm -f conftest* core core.conftest
;;
esac])
AC_MSG_RESULT($ac_cv_unaligned_fail)
if test $ac_cv_unaligned_fail = yes ; then
AC_DEFINE(LBL_ALIGN)
fi])
dnl
dnl If using gcc and the file .devel exists:
dnl Compile with -g (if supported) and -Wall
dnl If using gcc 2, do extra prototype checking
dnl If an os prototype include exists, symlink os-proto.h to it
dnl
dnl usage:
dnl
dnl AC_LBL_DEVEL(copt)
dnl
dnl results:
dnl
dnl $1 (copt appended)
dnl HAVE_OS_PROTO_H (defined)
dnl os-proto.h (symlinked)
dnl
AC_DEFUN(AC_LBL_DEVEL,
[rm -f os-proto.h
if test "${LBL_CFLAGS+set}" = set; then
$1="$$1 ${LBL_CFLAGS}"
fi
if test $ac_cv_prog_gcc = yes -a -f .devel ; then
if test "${LBL_CFLAGS+set}" != set; then
if test "$ac_cv_prog_cc_g" = yes ; then
$1="-g $$1"
fi
$1="$$1 -Wall"
if test $ac_cv_gcc_vers -gt 1 ; then
$1="$$1 -Wmissing-prototypes -Wstrict-prototypes"
fi
fi
os=`echo $target_os | sed -e 's/\([[0-9]][[0-9]]*\)[[^0-9]].*$/\1/'`
name="lbl/os-$os.h"
if test -f $name ; then
ln -s $name os-proto.h
AC_DEFINE(HAVE_OS_PROTO_H)
else
AC_MSG_WARN(can't find $name)
fi
fi])

View File

@ -29,18 +29,18 @@
* 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)
* @(#) $Header: /tcpdump/master/libpcap/atmuni31.h,v 1.1.6.2 2007/10/22 19:30:14 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 */
#define VCI_PPC 0x05 /* Point-to-point signal msg */
#define VCI_BCC 0x02 /* Broadcast signal msg */
#define VCI_OAMF4SC 0x03 /* Segment OAM F4 flow cell */
#define VCI_OAMF4EC 0x04 /* End-to-end OAM F4 flow cell */
#define VCI_METAC 0x01 /* Meta signal msg */
#define VCI_ILMIC 0x10 /* ILMI msg */
/* Q.2931 signalling messages */
#define CALL_PROCEED 0x02 /* call proceeding */

View File

@ -1,419 +0,0 @@
/*-
* Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
* The Regents of the University of California. All rights reserved.
*
* This code is derived from the Stanford/CMU enet packet filter,
* (net/enet.c) distributed as part of 4.3BSD, and code contributed
* to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
* Berkeley Laboratory.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)bpf.h 7.1 (Berkeley) 5/7/91
*
* @(#) $Header: /tcpdump/master/libpcap/bpf/net/bpf.h,v 1.51 2001/11/28 05:50:05 guy Exp $ (LBL)
*/
#ifndef BPF_MAJOR_VERSION
/* BSD style release date */
#define BPF_RELEASE 199606
typedef int bpf_int32;
typedef u_int bpf_u_int32;
/*
* Alignment macros. BPF_WORDALIGN rounds up to the next
* even multiple of BPF_ALIGNMENT.
*/
#ifndef __NetBSD__
#define BPF_ALIGNMENT sizeof(bpf_int32)
#else
#define BPF_ALIGNMENT sizeof(long)
#endif
#define BPF_WORDALIGN(x) (((x)+(BPF_ALIGNMENT-1))&~(BPF_ALIGNMENT-1))
#define BPF_MAXINSNS 512
#define BPF_MAXBUFSIZE 0x8000
#define BPF_MINBUFSIZE 32
/*
* Structure for BIOCSETF.
*/
struct bpf_program {
u_int bf_len;
struct bpf_insn *bf_insns;
};
/*
* Struct returned by BIOCGSTATS.
*/
struct bpf_stat {
u_int bs_recv; /* number of packets received */
u_int bs_drop; /* number of packets dropped */
};
/*
* Struct return by BIOCVERSION. This represents the version number of
* the filter language described by the instruction encodings below.
* bpf understands a program iff kernel_major == filter_major &&
* kernel_minor >= filter_minor, that is, if the value returned by the
* running kernel has the same major number and a minor number equal
* equal to or less than the filter being downloaded. Otherwise, the
* results are undefined, meaning an error may be returned or packets
* may be accepted haphazardly.
* It has nothing to do with the source code version.
*/
struct bpf_version {
u_short bv_major;
u_short bv_minor;
};
/* Current version number of filter architecture. */
#define BPF_MAJOR_VERSION 1
#define BPF_MINOR_VERSION 1
/*
* BPF ioctls
*
* The first set is for compatibility with Sun's pcc style
* header files. If your using gcc, we assume that you
* have run fixincludes so the latter set should work.
*/
#if (defined(sun) || defined(ibm032)) && !defined(__GNUC__)
#define BIOCGBLEN _IOR(B,102, u_int)
#define BIOCSBLEN _IOWR(B,102, u_int)
#define BIOCSETF _IOW(B,103, struct bpf_program)
#define BIOCFLUSH _IO(B,104)
#define BIOCPROMISC _IO(B,105)
#define BIOCGDLT _IOR(B,106, u_int)
#define BIOCGETIF _IOR(B,107, struct ifreq)
#define BIOCSETIF _IOW(B,108, struct ifreq)
#define BIOCSRTIMEOUT _IOW(B,109, struct timeval)
#define BIOCGRTIMEOUT _IOR(B,110, struct timeval)
#define BIOCGSTATS _IOR(B,111, struct bpf_stat)
#define BIOCIMMEDIATE _IOW(B,112, u_int)
#define BIOCVERSION _IOR(B,113, struct bpf_version)
#define BIOCSTCPF _IOW(B,114, struct bpf_program)
#define BIOCSUDPF _IOW(B,115, struct bpf_program)
#else
#define BIOCGBLEN _IOR('B',102, u_int)
#define BIOCSBLEN _IOWR('B',102, u_int)
#define BIOCSETF _IOW('B',103, struct bpf_program)
#define BIOCFLUSH _IO('B',104)
#define BIOCPROMISC _IO('B',105)
#define BIOCGDLT _IOR('B',106, u_int)
#define BIOCGETIF _IOR('B',107, struct ifreq)
#define BIOCSETIF _IOW('B',108, struct ifreq)
#define BIOCSRTIMEOUT _IOW('B',109, struct timeval)
#define BIOCGRTIMEOUT _IOR('B',110, struct timeval)
#define BIOCGSTATS _IOR('B',111, struct bpf_stat)
#define BIOCIMMEDIATE _IOW('B',112, u_int)
#define BIOCVERSION _IOR('B',113, struct bpf_version)
#define BIOCSTCPF _IOW('B',114, struct bpf_program)
#define BIOCSUDPF _IOW('B',115, struct bpf_program)
#endif
/*
* Structure prepended to each packet.
*/
struct bpf_hdr {
struct timeval bh_tstamp; /* time stamp */
bpf_u_int32 bh_caplen; /* length of captured portion */
bpf_u_int32 bh_datalen; /* original length of packet */
u_short bh_hdrlen; /* length of bpf header (this struct
plus alignment padding) */
};
/*
* Because the structure above is not a multiple of 4 bytes, some compilers
* will insist on inserting padding; hence, sizeof(struct bpf_hdr) won't work.
* Only the kernel needs to know about it; applications use bh_hdrlen.
*/
#if defined(KERNEL) || defined(_KERNEL)
#define SIZEOF_BPF_HDR 18
#endif
/*
* Data-link level type codes.
*/
/*
* These are the types that are the same on all platforms; on other
* platforms, a <net/bpf.h> should be supplied that defines the additional
* DLT_* codes appropriately for that platform (the BSDs, for example,
* should not just pick up this version of "bpf.h"; they should also define
* the additional DLT_* codes used by their kernels, as well as the values
* defined here - and, if the values they use for particular DLT_ types
* differ from those here, they should use their values, not the ones
* here).
*/
#define DLT_NULL 0 /* no link-layer encapsulation */
#define DLT_EN10MB 1 /* Ethernet (10Mb) */
#define DLT_EN3MB 2 /* Experimental Ethernet (3Mb) */
#define DLT_AX25 3 /* Amateur Radio AX.25 */
#define DLT_PRONET 4 /* Proteon ProNET Token Ring */
#define DLT_CHAOS 5 /* Chaos */
#define DLT_IEEE802 6 /* IEEE 802 Networks */
#define DLT_ARCNET 7 /* ARCNET */
#define DLT_SLIP 8 /* Serial Line IP */
#define DLT_PPP 9 /* Point-to-point Protocol */
#define DLT_FDDI 10 /* FDDI */
/*
* These are values from the traditional libpcap "bpf.h".
* Ports of this to particular platforms should replace these definitions
* with the ones appropriate to that platform, if the values are
* different on that platform.
*/
#define DLT_ATM_RFC1483 11 /* LLC/SNAP encapsulated atm */
#define DLT_RAW 12 /* raw IP */
/*
* These are values from BSD/OS's "bpf.h".
* These are not the same as the values from the traditional libpcap
* "bpf.h"; however, these values shouldn't be generated by any
* OS other than BSD/OS, so the correct values to use here are the
* BSD/OS values.
*
* Platforms that have already assigned these values to other
* DLT_ codes, however, should give these codes the values
* from that platform, so that programs that use these codes will
* continue to compile - even though they won't correctly read
* files of these types.
*/
#define DLT_SLIP_BSDOS 15 /* BSD/OS Serial Line IP */
#define DLT_PPP_BSDOS 16 /* BSD/OS Point-to-point Protocol */
#define DLT_ATM_CLIP 19 /* Linux Classical-IP over ATM */
/*
* These values are defined by NetBSD; other platforms should refrain from
* using them for other purposes, so that NetBSD savefiles with link
* types of 50 or 51 can be read as this type on all platforms.
*/
#define DLT_PPP_SERIAL 50 /* PPP over serial with HDLC encapsulation */
#define DLT_PPP_ETHER 51 /* PPP over Ethernet */
/*
* Values between 100 and 103 are used in capture file headers as
* link-layer types corresponding to DLT_ types that differ
* between platforms; don't use those values for new DLT_ new types.
*/
/*
* This value was defined by libpcap 0.5; platforms that have defined
* it with a different value should define it here with that value -
* a link type of 104 in a save file will be mapped to DLT_C_HDLC,
* whatever value that happens to be, so programs will correctly
* handle files with that link type regardless of the value of
* DLT_C_HDLC.
*
* The name DLT_C_HDLC was used by BSD/OS; we use that name for source
* compatibility with programs written for BSD/OS.
*
* libpcap 0.5 defined it as DLT_CHDLC; we define DLT_CHDLC as well,
* for source compatibility with programs written for libpcap 0.5.
*/
#define DLT_C_HDLC 104 /* Cisco HDLC */
#define DLT_CHDLC DLT_C_HDLC
#define DLT_IEEE802_11 105 /* IEEE 802.11 wireless */
/*
* Values between 106 and 107 are used in capture file headers as
* link-layer types corresponding to DLT_ types that might differ
* between platforms; don't use those values for new DLT_ new types.
*/
/*
* OpenBSD DLT_LOOP, for loopback devices; it's like DLT_NULL, except
* that the AF_ type in the link-layer header is in network byte order.
*
* OpenBSD defines it as 12, but that collides with DLT_RAW, so we
* define it as 108 here. If OpenBSD picks up this file, it should
* define DLT_LOOP as 12 in its version, as per the comment above -
* and should not use 108 as a DLT_ value.
*/
#define DLT_LOOP 108
/*
* Values between 109 and 112 are used in capture file headers as
* link-layer types corresponding to DLT_ types that might differ
* between platforms; don't use those values for new DLT_ types
* other than the corresponding DLT_ types.
*/
/*
* This is for Linux cooked sockets.
*/
#define DLT_LINUX_SLL 113
/*
* Apple LocalTalk hardware.
*/
#define DLT_LTALK 114
/*
* Acorn Econet.
*/
#define DLT_ECONET 115
/*
* Reserved for use with OpenBSD ipfilter.
*/
#define DLT_IPFILTER 116
/*
* Reserved for use in capture-file headers as a link-layer type
* corresponding to OpenBSD DLT_PFLOG; DLT_PFLOG is 17 in OpenBSD,
* but that's DLT_LANE8023 in SuSE 6.3, so we can't use 17 for it
* in capture-file headers.
*/
#define DLT_PFLOG 117
/*
* Registered for Cisco-internal use.
*/
#define DLT_CISCO_IOS 118
/*
* Reserved for 802.11 cards using the Prism II chips, with a link-layer
* header including Prism monitor mode information plus an 802.11
* header.
*/
#define DLT_PRISM_HEADER 119
/*
* Reserved for Aironet 802.11 cards, with an Aironet link-layer header
* (see Doug Ambrisko's FreeBSD patches).
*/
#define DLT_AIRONET_HEADER 120
/*
* The instruction encodings.
*/
/* instruction classes */
#define BPF_CLASS(code) ((code) & 0x07)
#define BPF_LD 0x00
#define BPF_LDX 0x01
#define BPF_ST 0x02
#define BPF_STX 0x03
#define BPF_ALU 0x04
#define BPF_JMP 0x05
#define BPF_RET 0x06
#define BPF_MISC 0x07
/* ld/ldx fields */
#define BPF_SIZE(code) ((code) & 0x18)
#define BPF_W 0x00
#define BPF_H 0x08
#define BPF_B 0x10
#define BPF_MODE(code) ((code) & 0xe0)
#define BPF_IMM 0x00
#define BPF_ABS 0x20
#define BPF_IND 0x40
#define BPF_MEM 0x60
#define BPF_LEN 0x80
#define BPF_MSH 0xa0
/* alu/jmp fields */
#define BPF_OP(code) ((code) & 0xf0)
#define BPF_ADD 0x00
#define BPF_SUB 0x10
#define BPF_MUL 0x20
#define BPF_DIV 0x30
#define BPF_OR 0x40
#define BPF_AND 0x50
#define BPF_LSH 0x60
#define BPF_RSH 0x70
#define BPF_NEG 0x80
#define BPF_JA 0x00
#define BPF_JEQ 0x10
#define BPF_JGT 0x20
#define BPF_JGE 0x30
#define BPF_JSET 0x40
#define BPF_SRC(code) ((code) & 0x08)
#define BPF_K 0x00
#define BPF_X 0x08
/* ret - BPF_K and BPF_X also apply */
#define BPF_RVAL(code) ((code) & 0x18)
#define BPF_A 0x10
/* misc */
#define BPF_MISCOP(code) ((code) & 0xf8)
#define BPF_TAX 0x00
#define BPF_TXA 0x80
/*
* The instruction data structure.
*/
struct bpf_insn {
u_short code;
u_char jt;
u_char jf;
bpf_int32 k;
};
/*
* Macros for insn array initializers.
*/
#define BPF_STMT(code, k) { (u_short)(code), 0, 0, k }
#define BPF_JUMP(code, k, jt, jf) { (u_short)(code), jt, jf, k }
#if defined(BSD) && (defined(KERNEL) || defined(_KERNEL))
/*
* Systems based on non-BSD kernels don't have ifnet's (or they don't mean
* anything if it is in <net/if.h>) and won't work like this.
*/
# if __STDC__
extern void bpf_tap(struct ifnet *, u_char *, u_int);
extern void bpf_mtap(struct ifnet *, struct mbuf *);
extern void bpfattach(struct ifnet *, u_int, u_int);
extern void bpfilterattach(int);
# else
extern void bpf_tap();
extern void bpf_mtap();
extern void bpfattach();
extern void bpfilterattach();
# endif /* __STDC__ */
#endif /* BSD && (_KERNEL || KERNEL) */
#if __STDC__
extern int bpf_validate(struct bpf_insn *, int);
extern u_int bpf_filter(struct bpf_insn *, u_char *, u_int, u_int);
#else
extern int bpf_validate();
extern u_int bpf_filter();
#endif
/*
* Number of scratch memory words (for BPF_LD|BPF_MEM and BPF_ST).
*/
#define BPF_MEMWORDS 16
#endif

View File

@ -40,7 +40,7 @@
#if !(defined(lint) || defined(KERNEL) || defined(_KERNEL))
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/bpf/net/bpf_filter.c,v 1.44 2003/11/15 23:24:07 guy Exp $ (LBL)";
"@(#) $Header: /tcpdump/master/libpcap/bpf/net/bpf_filter.c,v 1.45.2.1 2008/01/02 04:22:16 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@ -71,7 +71,7 @@ static const char rcsid[] _U_ =
#endif /* WIN32 */
#include <pcap-bpf.h>
#include <pcap/bpf.h>
#if !defined(KERNEL) && !defined(_KERNEL)
#include <stdlib.h>
@ -200,8 +200,8 @@ m_xhalf(m, k, err)
*/
u_int
bpf_filter(pc, p, wirelen, buflen)
register struct bpf_insn *pc;
register u_char *p;
register const struct bpf_insn *pc;
register const u_char *p;
u_int wirelen;
register u_int buflen;
{
@ -512,54 +512,155 @@ bpf_filter(pc, p, wirelen, buflen)
}
}
/*
* 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).
* code, that memory accesses are within valid ranges (to the
* extent that this can be checked statically; loads of packet
* data have to be, and are, also checked at run time), and that
* the code terminates with either an accept or reject.
*
* 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;
const struct bpf_insn *f;
int len;
{
register int i;
register struct bpf_insn *p;
u_int i, from;
const struct bpf_insn *p;
if (len < 1)
return 0;
/*
* There's no maximum program length in userland.
*/
#if defined(KERNEL) || defined(_KERNEL)
if (len > BPF_MAXINSNS)
return 0;
#endif
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;
}
switch (BPF_CLASS(p->code)) {
/*
* 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)
case BPF_LD:
case BPF_LDX:
switch (BPF_MODE(p->code)) {
case BPF_IMM:
break;
case BPF_ABS:
case BPF_IND:
case BPF_MSH:
/*
* There's no maximum packet data size
* in userland. The runtime packet length
* check suffices.
*/
#if defined(KERNEL) || defined(_KERNEL)
/*
* More strict check with actual packet length
* is done runtime.
*/
if (p->k >= bpf_maxbufsize)
return 0;
#endif
break;
case BPF_MEM:
if (p->k >= BPF_MEMWORDS)
return 0;
break;
case BPF_LEN:
break;
default:
return 0;
}
break;
case BPF_ST:
case BPF_STX:
if (p->k >= BPF_MEMWORDS)
return 0;
break;
case BPF_ALU:
switch (BPF_OP(p->code)) {
case BPF_ADD:
case BPF_SUB:
case BPF_MUL:
case BPF_OR:
case BPF_AND:
case BPF_LSH:
case BPF_RSH:
case BPF_NEG:
break;
case BPF_DIV:
/*
* Check for constant division by 0.
*/
if (BPF_RVAL(p->code) == BPF_K && p->k == 0)
return 0;
break;
default:
return 0;
}
break;
case BPF_JMP:
/*
* Check that jumps are within the code block,
* and that unconditional branches don't go
* backwards as a result of an overflow.
* Unconditional branches have a 32-bit offset,
* so they could overflow; we check to make
* sure they don't. Conditional branches have
* an 8-bit offset, and the from address is <=
* BPF_MAXINSNS, and we assume that BPF_MAXINSNS
* is sufficiently small that adding 255 to it
* won't overflow.
*
* We know that len is <= BPF_MAXINSNS, and we
* assume that BPF_MAXINSNS is < the maximum size
* of a u_int, so that i + 1 doesn't overflow.
*
* For userland, we don't know that the from
* or len are <= BPF_MAXINSNS, but we know that
* from <= len, and, except on a 64-bit system,
* it's unlikely that len, if it truly reflects
* the size of the program we've been handed,
* will be anywhere near the maximum size of
* a u_int. We also don't check for backward
* branches, as we currently support them in
* userland for the protochain operation.
*/
from = i + 1;
switch (BPF_OP(p->code)) {
case BPF_JA:
#if defined(KERNEL) || defined(_KERNEL)
if (from + p->k < from || from + p->k >= len)
#else
if (from + p->k >= len)
#endif
return 0;
break;
case BPF_JEQ:
case BPF_JGT:
case BPF_JGE:
case BPF_JSET:
if (from + p->jt >= len || from + p->jf >= len)
return 0;
break;
default:
return 0;
}
break;
case BPF_RET:
break;
case BPF_MISC:
break;
default:
return 0;
}
}
return BPF_CLASS(f[len - 1].code) == BPF_RET;
}

View File

@ -20,7 +20,7 @@
*/
#ifndef lint
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/bpf_dump.c,v 1.14 2003/11/15 23:23:57 guy Exp $ (LBL)";
"@(#) $Header: /tcpdump/master/libpcap/bpf_dump.c,v 1.14.4.1 2008/01/02 04:22:16 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@ -31,9 +31,9 @@ static const char rcsid[] _U_ =
#include <stdio.h>
void
bpf_dump(struct bpf_program *p, int option)
bpf_dump(const struct bpf_program *p, int option)
{
struct bpf_insn *insn;
const struct bpf_insn *insn;
int i;
int n = p->bf_len;

View File

@ -21,7 +21,7 @@
#ifndef lint
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/bpf_image.c,v 1.26.2.1 2007/06/11 09:52:04 guy Exp $ (LBL)";
"@(#) $Header: /tcpdump/master/libpcap/bpf_image.c,v 1.27.2.1 2008/01/02 04:22:16 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@ -39,7 +39,7 @@ static const char rcsid[] _U_ =
char *
bpf_image(p, n)
struct bpf_insn *p;
const struct bpf_insn *p;
int n;
{
int v;

19
chmod_bpf Executable file
View File

@ -0,0 +1,19 @@
#! /bin/sh
#
# Unfortunately, Mac OS X's devfs is based on the old FreeBSD
# one, not the current one, so there's no way to configure it
# to create BPF devices with particular owners or groups.
# This startup item will make it owned by the admin group,
# with permissions rw-rw----, so that anybody in the admin
# group can use programs that capture or send raw packets.
#
# Change this as appropriate for your site, e.g. to make
# it owned by a particular user without changing the permissions,
# so only that user and the super-user can capture or send raw
# packets, or give it the permissions rw-r-----, so that
# only the super-user can send raw packets but anybody in the
# admin group can capture packets.
#
chgrp admin /dev/bpf*
chmod g+rw /dev/bpf*

View File

@ -19,6 +19,9 @@
/* define if you have dag_get_erf_types() */
#undef HAVE_DAG_GET_ERF_TYPES
/* define if you have dag_get_stream_erf_types() */
#undef HAVE_DAG_GET_STREAM_ERF_TYPES
/* define if you have streams capable DAG API */
#undef HAVE_DAG_STREAMS_API
@ -29,9 +32,15 @@
/* define if you have a /dev/dlpi */
#undef HAVE_DEV_DLPI
/* if passive_req_t primitive exists */
#undef HAVE_DLPI_PASSIVE
/* Define to 1 if you have the `ether_hostton' function. */
#undef HAVE_ETHER_HOSTTON
/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */
#undef HAVE_FSEEKO
/* on HP-UX 10.20 or later */
#undef HAVE_HPUX10_20_OR_LATER
@ -44,9 +53,18 @@
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* if libdlpi exists */
#undef HAVE_LIBDLPI
/* Define to 1 if you have the <limits.h> header file. */
#undef HAVE_LIMITS_H
/* if tp_vlan_tci exists */
#undef HAVE_LINUX_TPACKET_AUXDATA_TP_VLAN_TCI
/* Define to 1 if you have the <linux/wireless.h> header file. */
#undef HAVE_LINUX_WIRELESS_H
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
@ -56,6 +74,9 @@
/* Define to 1 if you have the <netinet/if_ether.h> header file. */
#undef HAVE_NETINET_IF_ETHER_H
/* Define to 1 if you have the <net/if_media.h> header file. */
#undef HAVE_NET_IF_MEDIA_H
/* Define to 1 if you have the <net/pfvar.h> header file. */
#undef HAVE_NET_PFVAR_H
@ -65,6 +86,9 @@
/* Define to 1 if you have the <paths.h> header file. */
#undef HAVE_PATHS_H
/* define if net/pfvar.h defines PF_NAT through PF_NORDR */
#undef HAVE_PF_NAT_THROUGH_PF_NORDR
/* define if you have a /proc/net/dev */
#undef HAVE_PROC_NET_DEV
@ -80,6 +104,9 @@
/* if struct sockaddr_storage exists */
#undef HAVE_SOCKADDR_STORAGE
/* define if socklen_t is defined */
#undef HAVE_SOCKLEN_T
/* On solaris */
#undef HAVE_SOLARIS
@ -134,6 +161,9 @@
/* Define to 1 if you have the `vsnprintf' function. */
#undef HAVE_VSNPRINTF
/* define if the system supports zerocopy BPF */
#undef HAVE_ZEROCOPY_BPF
/* define if your compiler has __attribute__ */
#undef HAVE___ATTRIBUTE__
@ -143,6 +173,9 @@
/* if unaligned access fails */
#undef LBL_ALIGN
/* path for device for USB sniffing */
#undef LINUX_USB_MON_DEV
/* Define to 1 if netinet/ether.h declares `ether_hostton' */
#undef NETINET_ETHER_H_DECLARES_ETHER_HOSTTON
@ -170,15 +203,33 @@
/* /dev/dlpi directory */
#undef PCAP_DEV_PREFIX
/* target host supports Bluetooth sniffing */
#undef PCAP_SUPPORT_BT
/* target host supports USB sniffing */
#undef PCAP_SUPPORT_USB
/* include ACN support */
#undef SITA
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Enable parser debugging */
#undef YYDEBUG
/* Number of bits in a file offset, on hosts where this is settable. */
#undef _FILE_OFFSET_BITS
/* needed on HP-UX */
#undef _HPUX_SOURCE
/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */
#undef _LARGEFILE_SOURCE
/* Define for large files, on AIX-style hosts. */
#undef _LARGE_FILES
/* define on AIX to get certain functions */
#undef _SUN
@ -194,5 +245,8 @@
/* if we have u_int32_t */
#undef u_int32_t
/* if we have u_int64_t */
#undef u_int64_t
/* if we have u_int8_t */
#undef u_int8_t

2316
configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
dnl @(#) $Header: /tcpdump/master/libpcap/configure.in,v 1.120.2.13 2007/09/12 19:17:24 guy Exp $ (LBL)
dnl @(#) $Header: /tcpdump/master/libpcap/configure.in,v 1.138.2.22 2008-10-24 07:30:18 guy Exp $ (LBL)
dnl
dnl Copyright (c) 1994, 1995, 1996, 1997
dnl The Regents of the University of California. All rights reserved.
@ -6,7 +6,7 @@ dnl
dnl Process this file with autoconf to produce a configure script.
dnl
AC_REVISION($Revision: 1.120.2.13 $)
AC_REVISION($Revision: 1.138.2.22 $)
AC_PREREQ(2.50)
AC_INIT(pcap.c)
@ -19,6 +19,13 @@ AC_C___ATTRIBUTE__
AC_LBL_CHECK_TYPE(u_int8_t, u_char)
AC_LBL_CHECK_TYPE(u_int16_t, u_short)
AC_LBL_CHECK_TYPE(u_int32_t, u_int)
AC_LBL_CHECK_TYPE(u_int64_t, unsigned long long)
#
# Try to arrange for large file support.
#
AC_SYS_LARGEFILE
AC_FUNC_FSEEKO
dnl
dnl libpcap doesn't itself use <sys/ioccom.h>; however, the test program
@ -30,6 +37,24 @@ AC_CHECK_HEADERS(sys/ioccom.h sys/sockio.h limits.h paths.h)
AC_CHECK_HEADERS(net/pfvar.h, , , [#include <sys/types.h>
#include <sys/socket.h>
#include <net/if.h>])
if test "$ac_cv_header_net_pfvar_h" = yes; then
#
# Check for various PF actions.
#
AC_MSG_CHECKING(whether net/pfvar.h defines PF_NAT through PF_NORDR)
AC_TRY_COMPILE(
[#include <sys/types.h>
#include <sys/socket.h>
#include <net/if.h>
#include <net/pfvar.h>],
[return PF_NAT+PF_NONAT+PF_BINAT+PF_NOBINAT+PF_RDR+PF_NORDR;],
[
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_PF_NAT_THROUGH_PF_NORDR, 1,
[define if net/pfvar.h defines PF_NAT through PF_NORDR])
],
AC_MSG_RESULT(no))
fi
AC_CHECK_HEADERS(netinet/if_ether.h, , , [#include <sys/types.h>
#include <sys/socket.h>])
if test "$ac_cv_header_netinet_if_ether_h" != yes; then
@ -172,6 +197,18 @@ if test "$enable_protochain" = "disabled"; then
fi
AC_MSG_RESULT(${enable_protochain})
#
# SITA support is mutually exclusive with native capture support;
# "--with-sita" selects SITA support.
#
AC_ARG_WITH(sita, [ --with-sita include SITA support],
[
AC_DEFINE(SITA,1,[include ACN support])
AC_MSG_NOTICE(Enabling SITA ACN support)
V_PCAP=sita
V_FINDALLDEVS=sita
],
[
dnl
dnl Not all versions of test support -c (character special) but it's a
dnl better way of testing since the device might be protected. So we
@ -227,6 +264,140 @@ else
fi
AC_MSG_RESULT($V_PCAP)
#
# Do capture-mechanism-dependent tests.
#
case "$V_PCAP" in
dlpi)
#
# Checks to see if Solaris has the public libdlpi(3LIB) library.
# Note: The existence of /usr/include/libdlpi.h does not mean it is the
# public libdlpi(3LIB) version. Before libdlpi was made public, a
# private version also existed, which did not have the same APIs.
# Due to a gcc bug, the default search path for 32-bit libraries does
# not include /lib, we add it explicitly here.
# [http://bugs.opensolaris.org/view_bug.do?bug_id=6619485].
# Also, due to the bug above applications that link to libpcap with
# libdlpi will have to add "-L/lib" option to "configure".
#
saved_ldflags=$LDFLAGS
LDFLAGS="$LIBS -L/lib"
AC_CHECK_LIB(dlpi, dlpi_walk,
LIBS="-ldlpi $LIBS"
V_PCAP=libdlpi
AC_DEFINE(HAVE_LIBDLPI,1,[if libdlpi exists]),
V_PCAP=dlpi)
LDFLAGS=$saved_ldflags
#
# Checks whether <sys/dlpi.h> is usable, to catch weird SCO
# versions of DLPI.
#
AC_MSG_CHECKING(whether <sys/dlpi.h> is usable)
AC_CACHE_VAL(ac_cv_sys_dlpi_usable,
AC_TRY_COMPILE(
[
#include <sys/types.h>
#include <sys/time.h>
#include <sys/dlpi.h>
],
[int i = DL_PROMISC_PHYS;],
ac_cv_sys_dlpi_usable=yes,
ac_cv_sys_dlpi_usable=no))
AC_MSG_RESULT($ac_cv_sys_dlpi_usable)
if test $ac_cv_sys_dlpi_usable = no ; then
AC_MSG_ERROR(<sys/dlpi.h> is not usable on this system; it probably has a non-standard DLPI)
fi
#
# Check whether we have a /dev/dlpi device or have multiple devices.
#
AC_MSG_CHECKING(for /dev/dlpi device)
if test -c /dev/dlpi ; then
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_DEV_DLPI, 1, [define if you have a /dev/dlpi])
else
AC_MSG_RESULT(no)
dir="/dev/dlpi"
AC_MSG_CHECKING(for $dir directory)
if test -d $dir ; then
AC_MSG_RESULT(yes)
AC_DEFINE_UNQUOTED(PCAP_DEV_PREFIX, "$dir", [/dev/dlpi directory])
else
AC_MSG_RESULT(no)
fi
fi
#
# This check is for Solaris with DLPI support for passive modes.
# See dlpi(7P) for more details.
#
AC_LBL_DL_PASSIVE_REQ_T
;;
linux)
AC_MSG_CHECKING(Linux kernel version)
if test "$cross_compiling" = yes; then
AC_CACHE_VAL(ac_cv_linux_vers,
ac_cv_linux_vers=unknown)
else
AC_CACHE_VAL(ac_cv_linux_vers,
ac_cv_linux_vers=`uname -r 2>&1 | \
sed -n -e '$s/.* //' -e '$s/\..*//p'`)
fi
AC_MSG_RESULT($ac_cv_linux_vers)
if test $ac_cv_linux_vers = unknown ; then
AC_MSG_ERROR(cannot determine linux version when cross-compiling)
fi
if test $ac_cv_linux_vers -lt 2 ; then
AC_MSG_ERROR(version 2 or higher required; see the INSTALL doc for more info)
fi
AC_CHECK_HEADERS(linux/wireless.h, [], [],
[
#include <sys/socket.h>
#include <net/if.h>
#include <linux/types.h>
])
AC_CHECK_HEADERS()
AC_LBL_TPACKET_STATS
AC_LBL_LINUX_TPACKET_AUXDATA_TP_VLAN_TCI
;;
bpf)
#
# Check whether we have the *BSD-style ioctls.
#
AC_CHECK_HEADERS(net/if_media.h)
AC_MSG_CHECKING(whether the system supports zerocopy BPF)
AC_TRY_COMPILE(
[#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <net/bpf.h>],
[return (BIOCROTZBUF + BPF_BUFMODE_ZBUF);],
[
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_ZEROCOPY_BPF, 1,
[define if the system supports zerocopy BPF])
],
AC_MSG_RESULT(no))
;;
dag)
V_DEFS="$V_DEFS -DDAG_ONLY"
;;
septel)
V_DEFS="$V_DEFS -DSEPTEL_ONLY"
;;
null)
AC_MSG_WARN(cannot determine packet capture interface)
AC_MSG_WARN((see the INSTALL doc for more info))
;;
esac
dnl
dnl Now figure out how we get a list of interfaces and addresses,
dnl if we support capturing. Don't bother if we don't support
@ -273,7 +444,8 @@ else
#
case "$V_PCAP" in
dlpi)
dlpi|libdlpi)
AC_CHECK_HEADERS(sys/bufmod.h sys/dlpi_ext.h)
#
# This might be Solaris 8 or later, with
# SIOCGLIFCONF, or it might be some other OS
@ -297,6 +469,10 @@ else
else
V_FINDALLDEVS=gifc
fi
#
# Needed for common functions used by pcap-[dlpi,libdlpi].c
#
SSRC="dlpisubs.c"
;;
*)
@ -310,13 +486,35 @@ else
;;
esac])
fi
])
AC_MSG_CHECKING(if --enable-ipv6 option is specified)
AC_ARG_ENABLE(ipv6, [ --enable-ipv6 build IPv6-capable version])
if test "$enable_ipv6" = "yes"; then
AC_DEFINE(INET6,1,[IPv6])
AC_MSG_CHECKING(for socklen_t)
AC_TRY_COMPILE([
#include <sys/types.h>
#include <sys/socket.h>
],
[ socklen_t x; ],
have_socklen_t=yes,
have_socklen_t=no)
if test "x$have_socklen_t" = "xyes"; then
AC_DEFINE(HAVE_SOCKLEN_T, 1, [define if socklen_t is defined])
fi
AC_MSG_RESULT($have_socklen_t)
AC_ARG_ENABLE(ipv6, [ --enable-ipv6 build IPv6-capable version @<:@default=yes, if getaddrinfo available@:>@],
[],
[enable_ipv6=ifavailable])
if test "$enable_ipv6" != "no"; then
AC_CHECK_FUNC(getaddrinfo,
[
AC_DEFINE(INET6,1,[IPv6])
],
[
if test "$enable_ipv6" != "ifavailable"; then
AC_MSG_FAILURE([--enable-ipv6 was given, but getaddrinfo isn't available])
fi
])
fi
AC_MSG_RESULT(${enable_ipv6-no})
AC_MSG_CHECKING(whether to build optimizer debugging code)
AC_ARG_ENABLE(optimizer-dbg, [ --enable-optimizer-dbg build optimizer debugging code])
@ -332,62 +530,6 @@ if test "$enable_yydebug" = "yes"; then
fi
AC_MSG_RESULT(${enable_yydebug-no})
case "$V_PCAP" in
dlpi)
AC_CHECK_HEADERS(sys/bufmod.h sys/dlpi_ext.h)
AC_MSG_CHECKING(for /dev/dlpi device)
if test -c /dev/dlpi ; then
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_DEV_DLPI, 1, [define if you have a /dev/dlpi])
else
AC_MSG_RESULT(no)
dir="/dev/dlpi"
AC_MSG_CHECKING(for $dir directory)
if test -d $dir ; then
AC_MSG_RESULT(yes)
AC_DEFINE_UNQUOTED(PCAP_DEV_PREFIX, "$dir", [/dev/dlpi directory])
else
AC_MSG_RESULT(no)
fi
fi
;;
linux)
AC_MSG_CHECKING(Linux kernel version)
if test "$cross_compiling" = yes; then
AC_CACHE_VAL(ac_cv_linux_vers,
ac_cv_linux_vers=unknown)
else
AC_CACHE_VAL(ac_cv_linux_vers,
ac_cv_linux_vers=`uname -r 2>&1 | \
sed -n -e '$s/.* //' -e '$s/\..*//p'`)
fi
AC_MSG_RESULT($ac_cv_linux_vers)
if test $ac_cv_linux_vers = unknown ; then
AC_MSG_ERROR(cannot determine linux version when cross-compiling)
fi
if test $ac_cv_linux_vers -lt 2 ; then
AC_MSG_ERROR(version 2 or higher required; see the INSTALL doc for more info)
fi
AC_LBL_TPACKET_STATS
;;
dag)
V_DEFS="$V_DEFS -DDAG_ONLY"
;;
septel)
V_DEFS="$V_DEFS -DSEPTEL_ONLY"
;;
null)
AC_MSG_WARN(cannot determine packet capture interface)
AC_MSG_WARN((see the INSTALL doc for more info))
;;
esac
AC_MSG_CHECKING(whether we have /proc/net/dev)
if test -r /proc/net/dev ; then
ac_cv_lbl_proc_net_dev=yes
@ -498,11 +640,11 @@ if test $ac_cv_lbl_dag_api = yes; then
dagapi_obj=$dag_lib_dir/dagapi.o
elif test -r $dag_lib_dir/libdag.a; then
# 2.5.x.
ar x $dag_lib_dir/libdag.a dagapi.o
ar x $dag_lib_dir/libdag.a dagapi.o 2>/dev/null
if test -r ./dagapi.o; then
dagapi_obj=./dagapi.o
else
ar x $dag_lib_dir/libdag.a libdag_la-dagapi.o
ar x $dag_lib_dir/libdag.a libdag_la-dagapi.o 2>/dev/null
if test -r ./libdag_la-dagapi.o; then
dagapi_obj=./libdag_la-dagapi.o
fi
@ -529,11 +671,11 @@ if test $ac_cv_lbl_dag_api = yes; then
dagopts_obj=$dag_lib_dir/dagopts.o
elif test -r $dag_lib_dir/libdag.a; then
# 2.5.x.
ar x $dag_lib_dir/libdag.a dagopts.o
ar x $dag_lib_dir/libdag.a dagopts.o 2>/dev/null
if test -r ./dagopts.o; then
dagopts_obj=./dagopts.o
else
ar x $dag_lib_dir/libdag.a libdag_la-dagopts.o
ar x $dag_lib_dir/libdag.a libdag_la-dagopts.o 2>/dev/null
if test -r ./libdag_la-dagopts.o; then
dagopts_obj=./libdag_la-dagopts.o
fi
@ -558,11 +700,11 @@ if test $ac_cv_lbl_dag_api = yes; then
dagreg_obj=$dag_lib_dir/dagreg.o
elif test -r $dag_lib_dir/libdag.a; then
# Extract from libdag.a.
ar x $dag_lib_dir/libdag.a dagreg.o
ar x $dag_lib_dir/libdag.a dagreg.o 2>/dev/null
if test -r ./dagreg.o; then
dagreg_obj=./dagreg.o
else
ar x $dag_lib_dir/libdag.a libdag_la-dagreg.o
ar x $dag_lib_dir/libdag.a libdag_la-dagreg.o 2>/dev/null
if test -r ./libdag_la-dagreg.o; then
dagreg_obj=./libdag_la-dagreg.o
fi
@ -590,27 +732,25 @@ if test $ac_cv_lbl_dag_api = yes; then
# included if there's a found-action (arg 3).
saved_ldflags=$LDFLAGS
LDFLAGS="-L$dag_lib_dir"
AC_CHECK_LIB([dag], [dag_attach_stream], [dag_version="2.5.x"], [dag_version="2.4.x"])
AC_CHECK_LIB([dag], [dag_attach_stream], [dag_streams="1"], [dag_streams="0"])
AC_CHECK_LIB([dag],[dag_get_erf_types], [
AC_DEFINE(HAVE_DAG_GET_ERF_TYPES, 1, [define if you have dag_get_erf_types()])]
)
AC_DEFINE(HAVE_DAG_GET_ERF_TYPES, 1, [define if you have dag_get_erf_types()])])
AC_CHECK_LIB([dag],[dag_get_stream_erf_types], [
AC_DEFINE(HAVE_DAG_GET_STREAM_ERF_TYPES, 1, [define if you have dag_get_stream_erf_types()])])
LDFLAGS=$saved_ldflags
if test "$dag_version" = 2.5.x; then
if test "$dag_streams" = 1; then
AC_DEFINE(HAVE_DAG_STREAMS_API, 1, [define if you have streams capable DAG API])
DAGLIBS="-ldag"
fi
# See if we can find a specific version string.
AC_MSG_CHECKING([the DAG API version])
if test -r "$dag_root/VERSION"; then
dag_version="`cat $dag_root/VERSION`"
fi
AC_MSG_RESULT([$dag_version])
AC_DEFINE(HAVE_DAG_API, 1, [define if you have the DAG API])
fi
AC_MSG_CHECKING(whether we have the DAG API)
if test $ac_cv_lbl_dag_api = no; then
AC_MSG_RESULT(no)
if test "$want_dag" = yes; then
# User wanted DAG support but we couldn't find it.
AC_MSG_ERROR([DAG API requested, but not found at $dag_root: use --without-dag])
@ -621,6 +761,8 @@ if test $ac_cv_lbl_dag_api = no; then
# found.
AC_MSG_ERROR([Specifying the capture type as "dag" requires the DAG API to be present; use the --with-dag options to specify the location. (Try "./configure --help" for more information.)])
fi
else
AC_MSG_RESULT(yes)
fi
AC_ARG_WITH(septel, [ --with-septel[[=DIR]] include Septel support (located in directory DIR, if supplied). [default=yes, on Linux, if present]],
@ -724,22 +866,56 @@ if test "$V_LEX" = lex ; then
fi
fi
#
# Assume a.out/ELF convention for shared library names (".so"), and
# V7/BSD convention for man pages (file formats in section 5,
# miscellaneous info in section 7).
#
DYEXT="so"
MAN_FILE_FORMATS=5
MAN_MISC_INFO=7
case "$host_os" in
aix*)
dnl Workaround to enable certain features
AC_DEFINE(_SUN,1,[define on AIX to get certain functions])
# We need "-lodm" and "-lcfg", as libpcap requires them on
# AIX.
DEPLIBS="-lodm -lcfg"
;;
darwin*)
DYEXT="dylib"
V_CCOPT="$V_CCOPT -fno-common"
;;
hpux9*)
AC_DEFINE(HAVE_HPUX9,1,[on HP-UX 9.x])
#
# Use System V conventions for man pages.
#
MAN_FILE_FORMATS=4
MAN_MISC_INFO=5
;;
hpux10.0*)
#
# Use System V conventions for man pages.
#
MAN_FILE_FORMATS=4
MAN_MISC_INFO=5
;;
hpux10.1*)
#
# Use System V conventions for man pages.
#
MAN_FILE_FORMATS=4
MAN_MISC_INFO=5
;;
hpux*)
@ -750,6 +926,32 @@ hpux*)
dnl for 32-bit PA-RISC, but should be left as "so" for
dnl 64-bit PA-RISC or, I suspect, IA-64.
AC_DEFINE(HAVE_HPUX10_20_OR_LATER,1,[on HP-UX 10.20 or later])
#
# Use System V conventions for man pages.
#
MAN_FILE_FORMATS=4
MAN_MISC_INFO=5
;;
irix*)
#
# Use System V conventions for man pages.
#
MAN_FILE_FORMATS=4
MAN_MISC_INFO=5
;;
linux*)
V_CCOPT="$V_CCOPT -fPIC"
;;
osf*)
#
# Use System V conventions for man pages.
#
MAN_FILE_FORMATS=4
MAN_MISC_INFO=5
;;
sinix*)
@ -768,17 +970,13 @@ sinix*)
solaris*)
AC_DEFINE(HAVE_SOLARIS,1,[On solaris])
;;
darwin*)
DYEXT="dylib"
V_CCOPT="$V_CCOPT -fno-common"
#
# Use System V conventions for man pages.
#
MAN_FILE_FORMATS=4
MAN_MISC_INFO=5
;;
linux*)
V_CCOPT="$V_CCOPT -fPIC"
;;
esac
AC_PROG_RANLIB
@ -809,17 +1007,63 @@ AC_SUBST(V_LIBS)
AC_SUBST(V_LEX)
AC_SUBST(V_PCAP)
AC_SUBST(V_FINDALLDEVS)
AC_SUBST(V_RANLIB)
AC_SUBST(V_YACC)
AC_SUBST(SSRC)
AC_SUBST(DYEXT)
AC_SUBST(DAGLIBS)
AC_SUBST(DEPLIBS)
AC_SUBST(MAN_FILE_FORMATS)
AC_SUBST(MAN_MISC_INFO)
dnl check for USB sniffing support
AC_MSG_CHECKING(for USB sniffing support)
case "$host_os" in
linux*)
AC_DEFINE(PCAP_SUPPORT_USB, 1, [target host supports USB sniffing])
USB_SRC=pcap-usb-linux.c
AC_MSG_RESULT(yes)
ac_usb_dev_name=`udevinfo -q name -p /sys/class/usb_device/usbmon 2>/dev/null`
if test $? -ne 0 ; then
ac_usb_dev_name="usbmon"
fi
AC_DEFINE_UNQUOTED(LINUX_USB_MON_DEV, "/dev/$ac_usb_dev_name", [path for device for USB sniffing])
AC_MSG_NOTICE(Device for USB sniffing is /dev/$ac_usb_dev_name)
;;
*)
AC_MSG_RESULT(no)
;;
esac
AC_SUBST(PCAP_SUPPORT_USB)
AC_SUBST(USB_SRC)
dnl check for bluetooth sniffing support
case "$host_os" in
linux*)
AC_CHECK_HEADER(bluetooth/bluetooth.h,
[
AC_DEFINE(PCAP_SUPPORT_BT, 1, [target host supports Bluetooth sniffing])
BT_SRC=pcap-bt-linux.c
AC_MSG_NOTICE(Bluetooth sniffing is supported)
],
AC_MSG_NOTICE(Bluetooth sniffing is not supported; install bluez-lib devel to enable it)
)
;;
*)
AC_MSG_NOTICE(no Bluetooth sniffing support)
;;
esac
AC_SUBST(PCAP_SUPPORT_BT)
AC_SUBST(BT_SRC)
AC_PROG_INSTALL
AC_CONFIG_HEADER(config.h)
AC_OUTPUT(Makefile)
AC_OUTPUT(Makefile pcap-filter.manmisc pcap-linktype.manmisc
pcap-savefile.manfile pcap.3pcap pcap_compile.3pcap
pcap_datalink.3pcap pcap_dump_open.3pcap
pcap_list_datalinks.3pcap pcap_open_dead.3pcap
pcap_open_offline.3pcap)
if test -f .devel ; then
make depend

349
dlpisubs.c Normal file
View File

@ -0,0 +1,349 @@
/*
* This code is derived from code formerly in pcap-dlpi.c, originally
* contributed by Atanu Ghosh (atanu@cs.ucl.ac.uk), University College
* London, and subsequently modified by Guy Harris (guy@alum.mit.edu),
* Mark Pizzolato <List-tcpdump-workers@subscriptions.pizzolato.net>,
* Mark C. Brown (mbrown@hp.com), and Sagun Shakya <Sagun.Shakya@Sun.COM>.
*/
/*
* This file contains dlpi/libdlpi related common functions used
* by pcap-[dlpi,libdlpi].c.
*/
#ifndef lint
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/dlpisubs.c,v 1.1.2.2 2008-04-04 19:39:05 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef HAVE_SYS_BUFMOD_H
/*
* Size of a bufmod chunk to pass upstream; that appears to be the
* biggest value to which you can set it, and setting it to that value
* (which is bigger than what appears to be the Solaris default of 8192)
* reduces the number of packet drops.
*/
#define CHUNKSIZE 65536
/*
* Size of the buffer to allocate for packet data we read; it must be
* large enough to hold a chunk.
*/
#define PKTBUFSIZE CHUNKSIZE
#else /* HAVE_SYS_BUFMOD_H */
/*
* Size of the buffer to allocate for packet data we read; this is
* what the value used to be - there's no particular reason why it
* should be tied to MAXDLBUF, but we'll leave it as this for now.
*/
#define PKTBUFSIZE (MAXDLBUF * sizeof(bpf_u_int32))
#endif
#include <sys/types.h>
#include <sys/time.h>
#ifdef HAVE_SYS_BUFMOD_H
#include <sys/bufmod.h>
#endif
#include <sys/dlpi.h>
#include <sys/stream.h>
#include <errno.h>
#include <memory.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stropts.h>
#include <unistd.h>
#include "pcap-int.h"
#include "dlpisubs.h"
static void pcap_stream_err(const char *, int, char *);
/*
* Get the packet statistics.
*/
int
pcap_stats_dlpi(pcap_t *p, struct pcap_stat *ps)
{
/*
* "ps_recv" counts packets handed to the filter, not packets
* that passed the filter. As filtering is done in userland,
* this would not include packets dropped because we ran out
* of buffer space; in order to make this more like other
* platforms (Linux 2.4 and later, BSDs with BPF), where the
* "packets received" count includes packets received but dropped
* due to running out of buffer space, and to keep from confusing
* applications that, for example, compute packet drop percentages,
* we also make it count packets dropped by "bufmod" (otherwise we
* might run the risk of the packet drop count being bigger than
* the received-packet count).
*
* "ps_drop" counts packets dropped by "bufmod" because of
* flow control requirements or resource exhaustion; it doesn't
* count packets dropped by the interface driver, or packets
* dropped upstream. As filtering is done in userland, it counts
* packets regardless of whether they would've passed the filter.
*
* These statistics don't include packets not yet read from
* the kernel by libpcap, but they may include packets not
* yet read from libpcap by the application.
*/
*ps = p->md.stat;
/*
* Add in the drop count, as per the above comment.
*/
ps->ps_recv += ps->ps_drop;
return (0);
}
/*
* Loop through the packets and call the callback for each packet.
* Return the number of packets read.
*/
int
pcap_process_pkts(pcap_t *p, pcap_handler callback, u_char *user,
int count, u_char *bufp, int len)
{
int n, caplen, origlen;
u_char *ep, *pk;
struct pcap_pkthdr pkthdr;
#ifdef HAVE_SYS_BUFMOD_H
struct sb_hdr *sbp;
#ifdef LBL_ALIGN
struct sb_hdr sbhdr;
#endif
#endif
/* Loop through packets */
ep = bufp + len;
n = 0;
#ifdef HAVE_SYS_BUFMOD_H
while (bufp < ep) {
/*
* Has "pcap_breakloop()" been called?
* If so, return immediately - if we haven't read any
* packets, clear the flag and return -2 to indicate
* that we were told to break out of the loop, otherwise
* leave the flag set, so that the *next* call will break
* out of the loop without having read any packets, and
* return the number of packets we've processed so far.
*/
if (p->break_loop) {
if (n == 0) {
p->break_loop = 0;
return (-2);
} else {
p->bp = bufp;
p->cc = ep - bufp;
return (n);
}
}
#ifdef LBL_ALIGN
if ((long)bufp & 3) {
sbp = &sbhdr;
memcpy(sbp, bufp, sizeof(*sbp));
} else
#endif
sbp = (struct sb_hdr *)bufp;
p->md.stat.ps_drop = sbp->sbh_drops;
pk = bufp + sizeof(*sbp);
bufp += sbp->sbh_totlen;
origlen = sbp->sbh_origlen;
caplen = sbp->sbh_msglen;
#else
origlen = len;
caplen = min(p->snapshot, len);
pk = bufp;
bufp += caplen;
#endif
++p->md.stat.ps_recv;
if (bpf_filter(p->fcode.bf_insns, pk, origlen, caplen)) {
#ifdef HAVE_SYS_BUFMOD_H
pkthdr.ts.tv_sec = sbp->sbh_timestamp.tv_sec;
pkthdr.ts.tv_usec = sbp->sbh_timestamp.tv_usec;
#else
(void) gettimeofday(&pkthdr.ts, NULL);
#endif
pkthdr.len = origlen;
pkthdr.caplen = caplen;
/* Insure caplen does not exceed snapshot */
if (pkthdr.caplen > p->snapshot)
pkthdr.caplen = p->snapshot;
(*callback)(user, &pkthdr, pk);
if (++n >= count && count >= 0) {
p->cc = ep - bufp;
p->bp = bufp;
return (n);
}
}
#ifdef HAVE_SYS_BUFMOD_H
}
#endif
p->cc = 0;
return (n);
}
/*
* Process the mac type. Returns -1 if no matching mac type found, otherwise 0.
*/
int
pcap_process_mactype(pcap_t *p, u_int mactype)
{
int retv = 0;
switch (mactype) {
case DL_CSMACD:
case DL_ETHER:
p->linktype = DLT_EN10MB;
p->offset = 2;
/*
* This is (presumably) a real Ethernet capture; give it a
* link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so
* that an application can let you choose it, in case you're
* capturing DOCSIS traffic that a Cisco Cable Modem
* Termination System is putting out onto an Ethernet (it
* doesn't put an Ethernet header onto the wire, it puts raw
* DOCSIS frames out on the wire inside the low-level
* Ethernet framing).
*/
p->dlt_list = (u_int *)malloc(sizeof(u_int) * 2);
/*
* If that fails, just leave the list empty.
*/
if (p->dlt_list != NULL) {
p->dlt_list[0] = DLT_EN10MB;
p->dlt_list[1] = DLT_DOCSIS;
p->dlt_count = 2;
}
break;
case DL_FDDI:
p->linktype = DLT_FDDI;
p->offset = 3;
break;
case DL_TPR:
/* XXX - what about DL_TPB? Is that Token Bus? */
p->linktype = DLT_IEEE802;
p->offset = 2;
break;
#ifdef HAVE_SOLARIS
case DL_IPATM:
p->linktype = DLT_SUNATM;
p->offset = 0; /* works for LANE and LLC encapsulation */
break;
#endif
default:
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "unknown mactype %u",
mactype);
retv = -1;
}
return (retv);
}
#ifdef HAVE_SYS_BUFMOD_H
/*
* Push and configure the buffer module. Returns -1 for error, otherwise 0.
*/
int
pcap_conf_bufmod(pcap_t *p, int snaplen, int timeout)
{
int retv = 0;
bpf_u_int32 ss, chunksize;
/* Non-standard call to get the data nicely buffered. */
if (ioctl(p->fd, I_PUSH, "bufmod") != 0) {
pcap_stream_err("I_PUSH bufmod", errno, p->errbuf);
retv = -1;
}
ss = snaplen;
if (ss > 0 &&
strioctl(p->fd, SBIOCSSNAP, sizeof(ss), (char *)&ss) != 0) {
pcap_stream_err("SBIOCSSNAP", errno, p->errbuf);
retv = -1;
}
/* Set up the bufmod timeout. */
if (timeout != 0) {
struct timeval to;
to.tv_sec = timeout / 1000;
to.tv_usec = (timeout * 1000) % 1000000;
if (strioctl(p->fd, SBIOCSTIME, sizeof(to), (char *)&to) != 0) {
pcap_stream_err("SBIOCSTIME", errno, p->errbuf);
retv = -1;
}
}
/* Set the chunk length. */
chunksize = CHUNKSIZE;
if (strioctl(p->fd, SBIOCSCHUNK, sizeof(chunksize), (char *)&chunksize)
!= 0) {
pcap_stream_err("SBIOCSCHUNKP", errno, p->errbuf);
retv = -1;
}
return (retv);
}
#endif /* HAVE_SYS_BUFMOD_H */
/*
* Allocate data buffer. Returns -1 if memory allocation fails, else 0.
*/
int
pcap_alloc_databuf(pcap_t *p)
{
p->bufsize = PKTBUFSIZE;
p->buffer = (u_char *)malloc(p->bufsize + p->offset);
if (p->buffer == NULL) {
strlcpy(p->errbuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
return (-1);
}
return (0);
}
/*
* Issue a STREAMS I_STR ioctl. Returns -1 on error, otherwise
* length of returned data on success.
*/
int
strioctl(int fd, int cmd, int len, char *dp)
{
struct strioctl str;
int retv;
str.ic_cmd = cmd;
str.ic_timout = -1;
str.ic_len = len;
str.ic_dp = dp;
if ((retv = ioctl(fd, I_STR, &str)) < 0)
return (retv);
return (str.ic_len);
}
/*
* Write stream error message to errbuf.
*/
static void
pcap_stream_err(const char *func, int err, char *errbuf)
{
snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", func, pcap_strerror(err));
}

28
dlpisubs.h Normal file
View File

@ -0,0 +1,28 @@
/*
* @(#) $Header: /tcpdump/master/libpcap/dlpisubs.h,v 1.1.2.2 2008-04-04 19:39:05 guy Exp $
*/
#ifndef dlpisubs_h
#define dlpisubs_h
#ifdef __cplusplus
extern "C" {
#endif
/*
* Functions used by dlpisubs.c.
*/
int pcap_stats_dlpi(pcap_t *, struct pcap_stat *);
int pcap_process_pkts(pcap_t *, pcap_handler, u_char *, int, u_char *, int);
int pcap_process_mactype(pcap_t *, u_int);
#ifdef HAVE_SYS_BUFMOD_H
int pcap_conf_bufmod(pcap_t *, int, int);
#endif
int pcap_alloc_databuf(pcap_t *);
int strioctl(int, int, int, char *);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,997 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="en"><head><title>PCAP New Generation Dump File Format</title>
<meta name="description" content="PCAP New Generation Dump File Format">
<meta name="keywords" content="Internet-Draft, Libpcap, dump file format">
<meta name="generator" content="xml2rfc v1.22 (http://xml.resource.org/)">
<style type='text/css'>
<!--
body {
font-family: verdana, charcoal, helvetica, arial, sans-serif;
font-size: small ; color: #000000 ; background-color: #ffffff ; }
.title { color: #990000; font-size: x-large ;
font-weight: bold; text-align: right;
font-family: helvetica, monaco, "MS Sans Serif", arial, sans-serif;
background-color: transparent; }
.filename { color: #666666; font-size: 18px; line-height: 28px;
font-weight: bold; text-align: right;
font-family: helvetica, arial, sans-serif;
background-color: transparent; }
td.rfcbug { background-color: #000000 ; width: 30px ; height: 30px ;
text-align: justify; vertical-align: middle ; padding-top: 2px ; }
td.rfcbug span.RFC { color: #666666; font-weight: bold; text-decoration: none;
background-color: #000000 ;
font-family: monaco, charcoal, geneva, "MS Sans Serif", helvetica, verdana, sans-serif;
font-size: x-small ; }
td.rfcbug span.hotText { color: #ffffff; font-weight: normal; text-decoration: none;
text-align: center ;
font-family: charcoal, monaco, geneva, "MS Sans Serif", helvetica, verdana, sans-serif;
font-size: x-small ; background-color: #000000; }
A { font-weight: bold; }
A:link { color: #990000; background-color: transparent ; }
A:visited { color: #333333; background-color: transparent ; }
A:active { color: #333333; background-color: transparent ; }
p { margin-left: 2em; margin-right: 2em; }
p.copyright { font-size: x-small ; }
p.toc { font-size: small ; font-weight: bold ; margin-left: 3em ;}
span.emph { font-style: italic; }
span.strong { font-weight: bold; }
span.verb { font-family: "Courier New", Courier, monospace ; }
ol.text { margin-left: 2em; margin-right: 2em; }
ul.text { margin-left: 2em; margin-right: 2em; }
li { margin-left: 3em; }
pre { margin-left: 3em; color: #333333; background-color: transparent;
font-family: "Courier New", Courier, monospace ; font-size: small ;
}
h3 { color: #333333; font-size: medium ;
font-family: helvetica, arial, sans-serif ;
background-color: transparent; }
h4 { font-size: small; font-family: helvetica, arial, sans-serif ; }
table.bug { width: 30px ; height: 15px ; }
td.bug { color: #ffffff ; background-color: #990000 ;
text-align: center ; width: 30px ; height: 15px ;
}
td.bug A.link2 { color: #ffffff ; font-weight: bold;
text-decoration: none;
font-family: monaco, charcoal, geneva, "MS Sans Serif", helvetica, sans-serif;
font-size: x-small ; background-color: transparent }
td.header { color: #ffffff; font-size: x-small ;
font-family: arial, helvetica, sans-serif; vertical-align: top;
background-color: #666666 ; width: 33% ; }
td.author { font-weight: bold; margin-left: 4em; font-size: x-small ; }
td.author-text { font-size: x-small; }
table.data { vertical-align: top ; border-collapse: collapse ;
border-style: solid solid solid solid ;
border-color: black black black black ;
font-size: small ; text-align: center ; }
table.data th { font-weight: bold ;
border-style: solid solid solid solid ;
border-color: black black black black ; }
table.data td {
border-style: solid solid solid solid ;
border-color: #333333 #333333 #333333 #333333 ; }
hr { height: 1px }
-->
</style>
</head>
<body>
<table summary="layout" cellpadding="0" cellspacing="2" class="bug" align="right"><tr><td class="bug"><a href="#toc" class="link2">&nbsp;TOC&nbsp;</a></td></tr></table>
<table summary="layout" width="66%" border="0" cellpadding="0" cellspacing="0"><tr><td><table summary="layout" width="100%" border="0" cellpadding="2" cellspacing="1">
<tr><td class="header">Network Working Group</td><td class="header">L. Degioanni</td></tr>
<tr><td class="header">Internet-Draft</td><td class="header">F. Risso</td></tr>
<tr><td class="header">Expires: August 30, 2004</td><td class="header">Politecnico di Torino</td></tr>
<tr><td class="header">&nbsp;</td><td class="header">March 2004</td></tr>
</table></td></tr></table>
<div align="right"><span class="title"><br />PCAP New Generation Dump File Format</span></div>
<div align="right"><span class="title"><br />pcap</span></div>
<h3>Status of this Memo</h3>
<p>
This document is an Internet-Draft and is
in full conformance with all provisions of Section 10 of RFC2026.</p>
<p>
Internet-Drafts are working documents of the Internet Engineering
Task Force (IETF), its areas, and its working groups.
Note that other groups may also distribute working documents as
Internet-Drafts.</p>
<p>
Internet-Drafts are draft documents valid for a maximum of six months
and may be updated, replaced, or obsoleted by other documents at any time.
It is inappropriate to use Internet-Drafts as reference material or to cite
them other than as "work in progress."</p>
<p>
The list of current Internet-Drafts can be accessed at
<a href='http://www.ietf.org/ietf/1id-abstracts.txt'>http://www.ietf.org/ietf/1id-abstracts.txt</a>.</p>
<p>
The list of Internet-Draft Shadow Directories can be accessed at
<a href='http://www.ietf.org/shadow.html'>http://www.ietf.org/shadow.html</a>.</p>
<p>
This Internet-Draft will expire on August 30, 2004.</p>
<h3>Copyright Notice</h3>
<p>
Copyright (C) The Internet Society (2004). All Rights Reserved.</p>
<h3>Abstract</h3>
<p>This document describes a format to dump captured packets on a file. This format is extensible and it is currently proposed for implementation in the libpcap/WinPcap packet capture library.
</p><a name="toc"></a><br /><hr />
<h3>Table of Contents</h3>
<p class="toc">
<a href="#anchor1">1.</a>&nbsp;
Objectives<br />
<a href="#anchor2">2.</a>&nbsp;
General File Structure<br />
<a href="#sectionblock">2.1</a>&nbsp;
General Block Structure<br />
<a href="#anchor3">2.2</a>&nbsp;
Block Types<br />
<a href="#anchor4">2.3</a>&nbsp;
Block Hierarchy and Precedence<br />
<a href="#anchor5">2.4</a>&nbsp;
Data format<br />
<a href="#anchor6">3.</a>&nbsp;
Block Definition<br />
<a href="#sectionshb">3.1</a>&nbsp;
Section Header Block (mandatory)<br />
<a href="#sectionidb">3.2</a>&nbsp;
Interface Description Block (mandatory)<br />
<a href="#sectionpb">3.3</a>&nbsp;
Packet Block (optional)<br />
<a href="#anchor7">3.4</a>&nbsp;
Simple Packet Block (optional)<br />
<a href="#anchor8">3.5</a>&nbsp;
Name Resolution Block (optional)<br />
<a href="#anchor9">3.6</a>&nbsp;
Interface Statistics Block (optional)<br />
<a href="#sectionopt">4.</a>&nbsp;
Options<br />
<a href="#anchor10">5.</a>&nbsp;
Experimental Blocks (deserved to a further investigation)<br />
<a href="#anchor11">5.1</a>&nbsp;
Other Packet Blocks (experimental)<br />
<a href="#anchor12">5.2</a>&nbsp;
Compression Block (experimental)<br />
<a href="#anchor13">5.3</a>&nbsp;
Encryption Block (experimental)<br />
<a href="#anchor14">5.4</a>&nbsp;
Fixed Length Block (experimental)<br />
<a href="#anchor15">5.5</a>&nbsp;
Directory Block (experimental)<br />
<a href="#anchor16">5.6</a>&nbsp;
Traffic Statistics and Monitoring Blocks (experimental)<br />
<a href="#anchor17">5.7</a>&nbsp;
Event/Security Block (experimental)<br />
<a href="#anchor18">6.</a>&nbsp;
Conclusions<br />
<a href="#anchor19">7.</a>&nbsp;
Most important open issues<br />
<a href="#rfc.copyright">&#167;</a>&nbsp;
Intellectual Property and Copyright Statements<br />
</p>
<br clear="all" />
<a name="anchor1"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="bug" align="right"><tr><td class="bug"><a href="#toc" class="link2">&nbsp;TOC&nbsp;</a></td></tr></table>
<a name="rfc.section.1"></a><h3>1.&nbsp;Objectives</h3>
<p>The problem of exchanging packet traces becomes more and more critical every day; unfortunately, no standard solutions exist for this task right now. One of the most accepted packet interchange formats is the one defined by libpcap, which is rather old and does not fit for some of the nowadays applications especially in terms of extensibility.
</p>
<p>This document proposes a new format for dumping packet traces. The following goals are being pursued:
</p>
<ul class="text">
<li>Extensibility: aside of some common functionalities, third parties should be able to enrich the information embedded in the file with proprietary extensions, which will be ignored by tools that are not able to understand them.
</li>
<li>Portability: a capture trace must contain all the information needed to read data independently from network, hardware and operating system of the machine that made the capture.
</li>
<li>Merge/Append data: it should be possible to add data at the end of a given file, and the resulting file must still be readable.
</li>
</ul>
<a name="anchor2"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="bug" align="right"><tr><td class="bug"><a href="#toc" class="link2">&nbsp;TOC&nbsp;</a></td></tr></table>
<a name="rfc.section.2"></a><h3>2.&nbsp;General File Structure</h3>
<a name="rfc.section.2.1"></a><h4><a name="sectionblock">2.1</a>&nbsp;General Block Structure</h4>
<p>A capture file is organized in blocks, that are appended one to another to form the file. All the blocks share a common format, which is shown in <a href="#formatblock">Figure 1</a>.
</p><br /><hr />
<a name="formatblock"></a>
<pre>
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Block Type |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Block Total Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
/ Block Body /
/ /* variable length, aligned to 32 bits */ /
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Block Total Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
</pre>
<table border="0" cellpadding="0" cellspacing="2" align="center"><tr><td align="center"><font face="monaco, MS Sans Serif" size="1"><b>&nbsp;Basic block structure.&nbsp;</b></font><br /></td></tr></table><hr size="1" shade="0">
<p>The fields have the following meaning:
</p>
<ul class="text">
<li>Block Type (32 bits): unique value that identifies the block. Values whose Most Significant Bit (MSB) is equal to 1 are reserved for local use. They allow to save private data to the file and to extend the file format.
</li>
<li>Block Total Length: total size of this block, in bytes. For instance, a block that does not have a body has a length of 12 bytes.
</li>
<li>Block Body: content of the block.
</li>
<li>Block Total Length: total size of this block, in bytes. This field is duplicated for permitting backward file navigation.
</li>
</ul>
<p>This structure, shared among all blocks, makes easy to process a file and to skip unneeded or unknown blocks. Blocks can be nested one inside the others (NOTE: needed?). Some of the blocks are mandatory, i.e. a dump file is not valid if they are not present, other are optional.
</p>
<p>The structure of the blocks allows to define other blocks if needed. A parser that does non understand them can simply ignore their content.
</p>
<a name="rfc.section.2.2"></a><h4><a name="anchor3">2.2</a>&nbsp;Block Types</h4>
<p>The currently defined blocks are the following:
</p>
<ol class="text">
<li>Section Header Block: it defines the most important characteristics of the capture file.
</li>
<li>Interface Description Block: it defines the most important characteristics of the interface(s) used for capturing traffic.
</li>
<li>Packet Block: it contains a single captured packet, or a portion of it.
</li>
<li>Simple Packet Block: it contains a single captured packet, or a portion of it, with only a minimal set of information about it.
</li>
<li>Name Resolution Block: it defines the mapping from numeric addresses present in the packet dump and the canonical name counterpart.
</li>
<li>Capture Statistics Block: it defines how to store some statistical data (e.g. packet dropped, etc) which can be useful to undestand the conditions in which the capture has been made.
</li>
<li>Compression Marker Block: TODO
</li>
<li>Encryption Marker Block: TODO
</li>
<li>Fixed Length Marker Block: TODO
</li>
</ol>
<p>The following blocks instead are considered interesting but the authors believe that they deserve more in-depth discussion before being defined:
</p>
<ol class="text">
<li>Further Packet Blocks
</li>
<li>Directory Block
</li>
<li>Traffic Statistics and Monitoring Blocks
</li>
<li>Alert and Security Blocks
</li>
</ol>
<p>TODO Currently standardized Block Type codes are specified in Appendix 1.
</p>
<a name="rfc.section.2.3"></a><h4><a name="anchor4">2.3</a>&nbsp;Block Hierarchy and Precedence</h4>
<p>The file must begin with a Section Header Block. However, more than one Section Header Block can be present on the dump, each one covering the data following it till the next one (or the end of file). A Section includes the data delimited by two Section Header Blocks (or by a Section Header Block and the end of the file), including the first Section Header Block.
</p>
<p>In case an application cannot read a Section because of different version number, it must skip everything until the next Section Header Block. Note that, in order to properly skip the blocks until the next section, all blocks must have the fields Type and Length at the beginning. This is a mandatory requirement that must be maintained in future versions of the block format.
</p>
<p><a href="#fssample-SHB">Figure 2</a> shows two valid files: the first has a typical configuration, with a single Section Header that covers the whole file. The second one contains three headers, and is normally the result of file concatenation. An application that understands only version 1.0 of the file format skips the intermediate section and restart processing the packets after the third Section Header.
</p><br /><hr />
<a name="fssample-SHB"></a>
<pre>
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| SHB v1.0 | Data |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Typical configuration with a single Section Header Block
|-- 1st Section --|-- 2nd Section --|-- 3rd Section --|
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| SHB v1.0 | Data | SHB V1.1 | Data | SHB V1.0 | Data |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Configuration with three different Section Header Blocks
</pre>
<table border="0" cellpadding="0" cellspacing="2" align="center"><tr><td align="center"><font face="monaco, MS Sans Serif" size="1"><b>&nbsp;File structure example: the Section Header Block.&nbsp;</b></font><br /></td></tr></table><hr size="1" shade="0">
<p>NOTE: TO BE COMPLETED with some examples of other blocks
</p>
<a name="rfc.section.2.4"></a><h4><a name="anchor5">2.4</a>&nbsp;Data format</h4>
<p>Data contained in each section will always be saved according to the characteristics (little endian / big endian) of the dumping machine. This refers to all fields that are saved as numbers and that span over two or more bytes.
</p>
<p>The approach of having each section saved in the native format of the generating host is more efficient because it avoids translation of data when reading / writing on the host itself, which is the most common case when generating/processing capture dumps.
</p>
<p>TODO Probably we have to specify something more here. Is what we're saying enough to avoid any kind of ambiguity?.
</p>
<a name="anchor6"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="bug" align="right"><tr><td class="bug"><a href="#toc" class="link2">&nbsp;TOC&nbsp;</a></td></tr></table>
<a name="rfc.section.3"></a><h3>3.&nbsp;Block Definition</h3>
<p>This section details the format of the body of the blocks currently defined.
</p>
<a name="rfc.section.3.1"></a><h4><a name="sectionshb">3.1</a>&nbsp;Section Header Block (mandatory)</h4>
<p>The Section Header Block is mandatory. It identifies the beginning of a section of the capture dump file. Its format is shown in <a href="#formatSHB">Figure 3</a>.
</p><br /><hr />
<a name="formatSHB"></a>
<pre>
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Magic |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Major | Minor |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
/ /
/ Options (variable) /
/ /
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
</pre>
<table border="0" cellpadding="0" cellspacing="2" align="center"><tr><td align="center"><font face="monaco, MS Sans Serif" size="1"><b>&nbsp;Section Header Block format.&nbsp;</b></font><br /></td></tr></table><hr size="1" shade="0">
<p>The meaning of the fields is:
</p>
<ul class="text">
<li>Magic: magic number, whose value is the hexadecimal number 0x1A2B3C4D. This number can be used to distinguish section that have been saved on little-endian machines from the one saved on big-endian machines.
</li>
<li>Major: number of the current mayor version of the format. Current value is 1.
</li>
<li>Minor: number of the current minor version of the format. Current value is 0.
</li>
<li>Options: optionally, a list of options (formatted according to the rules defined in <a href="#sectionopt">Section 4</a>) can be present.
</li>
</ul>
<p>Aside form the options defined in <a href="#sectionopt">Section 4</a>, the following options are valid within this block:
</p><a name="InterfaceOptions1"></a>
<table class="data" align="center" border="1" cellpadding="2" cellspacing="2">
<tr>
<th align="left" width="25%">Name</th>
<th align="left" width="25%">Code</th>
<th align="left" width="25%">Length</th>
<th align="left" width="25%">Description</th>
</tr>
<tr>
<td align="left">Hardware</td>
<td align="left">2</td>
<td align="left">variable</td>
<td align="left">An ascii string containing the description of the hardware used to create this section.</td>
</tr>
<tr>
<td align="left">Operating System</td>
<td align="left">3</td>
<td align="left">variable</td>
<td align="left">An ascii string containing the name of the operating system used to create this section.</td>
</tr>
<tr>
<td align="left">User Application</td>
<td align="left">3</td>
<td align="left">variable</td>
<td align="left">An ascii string containing the name of the application used to create this section.</td>
</tr>
</table>
<p>The Section Header Block does not contain data but it rather identifies a list of blocks (interfaces, packets) that are logically correlated. This block does not contain any reference to the size of the section it is currently delimiting, therefore the reader cannot skip a whole section at once. In case a section must be skipped, the user has to repeatedly skip all the blocks contained within it; this makes the parsing of the file slower but it permits to append several capture dumps at the same file.
</p>
<a name="rfc.section.3.2"></a><h4><a name="sectionidb">3.2</a>&nbsp;Interface Description Block (mandatory)</h4>
<p>The Interface Description Block is mandatory. This block is needed to specify the characteristics of the network interface on which the capture has been made. In order to properly associate the captured data to the corresponding interface, the Interface Description Block must be defined before any other block that uses it; therefore, this block is usually placed immediately after the Section Header Block.
</p>
<p>An Interface Description Block is valid only inside the section which it belongs to. The structure of a Interface Description Block is shown in <a href="#formatidb">Figure 4</a>.
</p><br /><hr />
<a name="formatidb"></a>
<pre>
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Interface ID | LinkType |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| SnapLen |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
/ /
/ Options (variable) /
/ /
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
</pre>
<table border="0" cellpadding="0" cellspacing="2" align="center"><tr><td align="center"><font face="monaco, MS Sans Serif" size="1"><b>&nbsp;Interface Description Block format.&nbsp;</b></font><br /></td></tr></table><hr size="1" shade="0">
<p>The meaning of the fields is:
</p>
<ul class="text">
<li>Interface ID: a progressive number that identifies uniquely any interface inside current section. Two Interface Description Blocks can have the same Interface ID only if they are in different sections of the file. The Interface ID is referenced by the packet blocks.
</li>
<li>LinkType: a value that defines the link layer type of this interface.
</li>
<li>SnapLen: maximum number of bytes dumped from each packet. The portion of each packet that exceeds this value will not be stored in the file.
</li>
<li>Options: optionally, a list of options (formatted according to the rules defined in <a href="#sectionopt">Section 4</a>) can be present.
</li>
</ul>
<p>In addition to the options defined in <a href="#sectionopt">Section 4</a>, the following options are valid within this block:
</p><a name="InterfaceOptions2"></a>
<table class="data" align="center" border="1" cellpadding="2" cellspacing="2">
<tr>
<th align="left" width="25%">Name</th>
<th align="left" width="25%">Code</th>
<th align="left" width="25%">Length</th>
<th align="left" width="25%">Description</th>
</tr>
<tr>
<td align="left">if_name</td>
<td align="left">2</td>
<td align="left">Variable</td>
<td align="left">Name of the device used to capture data.</td>
</tr>
<tr>
<td align="left">if_IPv4addr</td>
<td align="left">3</td>
<td align="left">8</td>
<td align="left">Interface network address and netmask.</td>
</tr>
<tr>
<td align="left">if_IPv6addr</td>
<td align="left">4</td>
<td align="left">17</td>
<td align="left">Interface network address and prefix length (stored in the last byte).</td>
</tr>
<tr>
<td align="left">if_MACaddr</td>
<td align="left">5</td>
<td align="left">6</td>
<td align="left">Interface Hardware MAC address (48 bits).</td>
</tr>
<tr>
<td align="left">if_EUIaddr</td>
<td align="left">6</td>
<td align="left">8</td>
<td align="left">Interface Hardware EUI address (64 bits), if available.</td>
</tr>
<tr>
<td align="left">if_speed</td>
<td align="left">7</td>
<td align="left">8</td>
<td align="left">Interface speed (in bps).</td>
</tr>
<tr>
<td align="left">if_tsaccur</td>
<td align="left">8</td>
<td align="left">1</td>
<td align="left">Precision of timestamps. If the Most Significant Bit is equal to zero, the remaining bits indicates the accuracy as as a negative power of 10 (e.g. 6 means microsecond accuracy). If the Most Significant Bit is equal to zero, the remaining bits indicates the accuracy as as negative power of 2 (e.g. 10 means 1/1024 of second). If this option is not present, a precision of 10^-6 is assumed.</td>
</tr>
<tr>
<td align="left">if_tzone</td>
<td align="left">9</td>
<td align="left">4</td>
<td align="left">Time zone for GMT support (TODO: specify better).</td>
</tr>
<tr>
<td align="left">if_flags</td>
<td align="left">10</td>
<td align="left">4</td>
<td align="left">Interface flags. (TODO: specify better. Possible flags: promiscuous, inbound/outbound, traffic filtered during capture).</td>
</tr>
<tr>
<td align="left">if_filter</td>
<td align="left">11</td>
<td align="left">variable</td>
<td align="left">The filter (e.g. "capture only TCP traffic") used to capture traffic. The first byte of the Option Data keeps a code of the filter used (e.g. if this is a libpcap string, or BPF bytecode, and more). More details about this format will be presented in Appendix XXX (TODO).</td>
</tr>
<tr>
<td align="left">if_opersystem</td>
<td align="left">12</td>
<td align="left">variable</td>
<td align="left">An ascii string containing the name of the operating system of the machine that hosts this interface. This can be different from the same information that can be contained by the Section Header Block (<a href="#sectionshb">Section 3.1</a>) because the capture can have been done on a remote machine.</td>
</tr>
</table>
<a name="rfc.section.3.3"></a><h4><a name="sectionpb">3.3</a>&nbsp;Packet Block (optional)</h4>
<p>A Packet Block is the standard container for storing the packets coming from the network. The Packet Block is optional because packets can be stored either by means of this block or the Simple Packet Block, which can be used to speed up dump generation. The format of a packet block is shown in <a href="#formatpb">Figure 5</a>.
</p><br /><hr />
<a name="formatpb"></a>
<pre>
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Interface ID | Drops Count |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Timestamp (High) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Timestamp (Low) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Captured Len |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Packet Len |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
| Packet Data |
| |
| /* variable length, byte-aligned */ |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
/ /
/ Options (variable) /
/ /
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
</pre>
<table border="0" cellpadding="0" cellspacing="2" align="center"><tr><td align="center"><font face="monaco, MS Sans Serif" size="1"><b>&nbsp;Packet Block format.&nbsp;</b></font><br /></td></tr></table><hr size="1" shade="0">
<p>The Packet Block has the following fields:
</p>
<ul class="text">
<li>Interface ID: Specifies the interface this packet comes from, and corresponds to the ID of one of the Interface Description Blocks present in this section of the file (see <a href="#formatidb">Figure 4</a>).
</li>
<li>Drops Count: a local drop counter. It specified the number of packets lost (by the interface and the operating system) between this packet and the preceding one. The value xFFFF (in hexadecimal) is reserved for those systems in which this information is not available.
</li>
<li>Timestamp (High): the most significative part of the timestamp. in standard Unix format, i.e. from 1/1/1970.
</li>
<li>Timestamp (Low): the less significative part of the timestamp. The way to interpret this field is specified by the 'ts_accur' option (see <a href="#formatidb">Figure 4</a>) of the Interface Description block referenced by this packet. If the Interface Description block does not contain a 'ts_accur' option, then this field is expressed in microseconds.
</li>
<li>Captured Len: number of bytes captured from the packet (i.e. the length of the Packet Data field). It will be the minimum value among the actual Packet Length and the snapshot length (defined in <a href="#formatidb">Figure 4</a>).
</li>
<li>Packet Len: actual length of the packet when it was transmitted on the network. Can be different from Captured Len if the user wants only a snapshot of the packet.
</li>
<li>Packet Data: the data coming from the network, including link-layer headers. The length of this field is Captured Len. The format of the link-layer headers depends on the LinkType field specified in the Interface Description Block (see <a href="#sectionidb">Section 3.2</a>) and it is specified in Appendix XXX (TODO).
</li>
<li>Options: optionally, a list of options (formatted according to the rules defined in <a href="#sectionopt">Section 4</a>) can be present.
</li>
</ul>
<p>
</p>
<a name="rfc.section.3.4"></a><h4><a name="anchor7">3.4</a>&nbsp;Simple Packet Block (optional)</h4>
<p>The Simple Packet Block is a lightweight container for storing the packets coming from the network. Its presence is optional.
</p>
<p>A Simple Packet Block is similar to a Packet Block (see <a href="#sectionpb">Section 3.3</a>), but it is smaller, simpler to process and contains only a minimal set of information. This block is preferred to the standard Packet Block when performance or space occupation are critical factors, such as in sustained traffic dump applications. A capture file can contain both Packet Blocks and Simple Packet Blocks: for example, a capture tool could switch from Packet Blocks to Simple Packet Blocks when the hardware resources become critical.
</p>
<p>The Simple Packet Block does not contain the Interface ID field. Therefore, it must be assumed that all the Simple Packet Blocks have been captured on the interface previously specified in the Interface Description Block.
</p>
<p><a href="#formatpbs">Figure 6</a> shows the format of the Simple Packet Block.
</p><br /><hr />
<a name="formatpbs"></a>
<pre>
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Packet Len |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
| Packet Data |
| |
| /* variable length, byte-aligned */ |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
</pre>
<table border="0" cellpadding="0" cellspacing="2" align="center"><tr><td align="center"><font face="monaco, MS Sans Serif" size="1"><b>&nbsp;Simple Packet Block format.&nbsp;</b></font><br /></td></tr></table><hr size="1" shade="0">
<p>The Packet Block has the following fields:
</p>
<ul class="text">
<li>Packet Len: actual length of the packet when it was transmitted on the network. Can be different from captured len if the packet has been truncated.
</li>
<li>Packet data: the data coming from the network, including link-layers headers. The length of this field can be derived from the field Block Total Length, present in the Block Header.
</li>
</ul>
<p>The Simple Packet Block does not contain the timestamp because this is one of the most costly operations on PCs. Additionally, there are applications that do not require it; e.g. an Intrusion Detection System is interested in packets, not in their timestamp.
</p>
<p>The Simple Packet Block is very efficient in term of disk space: a snapshot of length 100 bytes requires only 16 bytes of overhead, which corresponds to an efficiency of more than 86%.
</p>
<a name="rfc.section.3.5"></a><h4><a name="anchor8">3.5</a>&nbsp;Name Resolution Block (optional)</h4>
<p>The Name Resolution Block is used to support the correlation of numeric addresses (present in the captured packets) and their corresponding canonical names and it is optional. Having the literal names saved in the file, this prevents the need of a name resolution in a delayed time, when the association between names and addresses can be different from the one in use at capture time. Moreover, The Name Resolution Block avoids the need of issuing a lot of DNS requests every time the trace capture is opened, and allows to have name resolution also when reading the capture with a machine not connected to the network.
</p>
<p>The format of the Name Resolution Block is shown in <a href="#formatnrb">Figure 7</a>.
</p><br /><hr />
<a name="formatnrb"></a>
<pre>
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Record Type | Record Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Record Value |
| /* variable length, byte-aligned */ |
| + + + + + + + + + + + + + + + + + + + + + + + + +
| | | | |
+-+-+-+-+-+-+-+-+ + + + + + + + + + + + + + + + + + + + + + + + +
. . . other records . . .
| Record Type == end_of_recs | Record Length == 00 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
/ /
/ Options (variable) /
/ /
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
</pre>
<table border="0" cellpadding="0" cellspacing="2" align="center"><tr><td align="center"><font face="monaco, MS Sans Serif" size="1"><b>&nbsp;Name Resolution Block format.&nbsp;</b></font><br /></td></tr></table><hr size="1" shade="0">
<p>A Name Resolution Block is a zero-terminated list of records (in the TLV format), each of which contains an association between a network address and a name. There are three possible types of records:
</p><a name="nrrecords"></a>
<table class="data" align="center" border="1" cellpadding="2" cellspacing="2">
<tr>
<th align="left" width="25%">Name</th>
<th align="left" width="25%">Code</th>
<th align="left" width="25%">Length</th>
<th align="left" width="25%">Description</th>
</tr>
<tr>
<td align="left">end_of_recs</td>
<td align="left">0</td>
<td align="left">0</td>
<td align="left">End of records</td>
</tr>
<tr>
<td align="left">ip4_rec</td>
<td align="left">1</td>
<td align="left">Variable</td>
<td align="left">Specifies an IPv4 address (contained in the first 4 bytes), followed by one or more zero-terminated strings containing the DNS entries for that address.</td>
</tr>
<tr>
<td align="left">ip6_rec</td>
<td align="left">1</td>
<td align="left">Variable</td>
<td align="left">Specifies an IPv6 address (contained in the first 16 bytes), followed by one or more zero-terminated strings containing the DNS entries for that address.</td>
</tr>
</table>
<p>After the list or Name Resolution Records, optionally, a list of options (formatted according to the rules defined in <a href="#sectionopt">Section 4</a>) can be present.
</p>
<p>A Name Resolution Block is normally placed at the beginning of the file, but no assumptions can be taken about its position. Name Resolution Blocks can be added in a second time by tools that process the file, like network analyzers.
</p>
<p>In addiction to the options defined in <a href="#sectionopt">Section 4</a>, the following options are valid within this block:
</p><table class="data" align="center" border="1" cellpadding="2" cellspacing="2">
<tr>
<th align="left" width="25%">Name</th>
<th align="left" width="25%">Code</th>
<th align="left" width="25%">Length</th>
<th align="left" width="25%">Description</th>
</tr>
<tr>
<td align="left">ns_dnsname</td>
<td align="left">2</td>
<td align="left">Variable</td>
<td align="left">An ascii string containing the name of the machine (DNS server) used to perform the name resolution.</td>
</tr>
</table>
<a name="rfc.section.3.6"></a><h4><a name="anchor9">3.6</a>&nbsp;Interface Statistics Block (optional)</h4>
<p>The Interface Statistics Block contains the capture statistics for a given interface and it is optional. The statistics are referred to the interface defined in the current Section identified by the Interface ID field.
</p>
<p>The format of the Interface Statistics Block is shown in <a href="#formatisb">Figure 8</a>.
</p><br /><hr />
<a name="formatisb"></a>
<pre>
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| IfRecv |
| (high + low) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| IfDrop |
| (high + low) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| FilterAccept |
| (high + low) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| OSDrop |
| (high + low) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| UsrDelivered |
| (high + low) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Interface ID | Reserved |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
/ /
/ Options (variable) /
/ /
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
</pre>
<table border="0" cellpadding="0" cellspacing="2" align="center"><tr><td align="center"><font face="monaco, MS Sans Serif" size="1"><b>&nbsp;Interface Statistics Block format.&nbsp;</b></font><br /></td></tr></table><hr size="1" shade="0">
<p>The fields have the following meaning:
</p>
<ul class="text">
<li>IfRecv: number of packets received from the interface during the capture. This number is reported as a 64 bits value, in which the most significat bits are located in the first four bytes of the field.
</li>
<li>IfDrop: number of packets dropped by the interface during the capture due to lack of resources.
</li>
<li>FilterAccept: number of packets accepeted by filter during current capture.
</li>
<li>OSDrop: number of packets dropped by the operating system during the capture.
</li>
<li>UsrDelivered: number of packets delivered to the user. UsrDelivered can be different from the value 'FilterAccept - OSDropped' because some packets could still lay in the OS buffers when the capture ended.
</li>
<li>Interface ID: reference to an Interface Description Block.
</li>
<li>Reserved: Reserved to future use.
</li>
<li>Options: optionally, a list of options (formatted according to the rules defined in <a href="#sectionopt">Section 4</a>) can be present.
</li>
</ul>
<p>In addiction to the options defined in <a href="#sectionopt">Section 4</a>, the following options are valid within this block:
</p><table class="data" align="center" border="1" cellpadding="2" cellspacing="2">
<tr>
<th align="left" width="25%">Name</th>
<th align="left" width="25%">Code</th>
<th align="left" width="25%">Length</th>
<th align="left" width="25%">Description</th>
</tr>
<tr>
<td align="left">isb_starttime</td>
<td align="left">2</td>
<td align="left">8</td>
<td align="left">Time in which the capture started; time will be stored in two blocks of four bytes each, containing the timestamp in seconds and nanoseconds.</td>
</tr>
<tr>
<td align="left">isb_endtime</td>
<td align="left">3</td>
<td align="left">8</td>
<td align="left">Time in which the capture started; time will be stored in two blocks of four bytes each, containing the timestamp in seconds and nanoseconds.</td>
</tr>
</table>
<a name="sectionopt"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="bug" align="right"><tr><td class="bug"><a href="#toc" class="link2">&nbsp;TOC&nbsp;</a></td></tr></table>
<a name="rfc.section.4"></a><h3>4.&nbsp;Options</h3>
<p>Almost all blocks have the possibility to embed optional fields. Optional fields can be used to insert some information that may be useful when reading data, but that it is not really needed for packet processing. Therefore, each tool can be either read the content of the optional fields (if any), or skip them at once.
</p>
<p>Skipping all the optional fields at once is straightforward because most of the blocks have a fixed length, therefore the field Block Length (present in the General Block Structure, see <a href="#sectionblock">Section 2.1</a>) can be used to skip everything till the next block.
</p>
<p>Options are a list of Type - Length - Value fields, each one containing a single value:
</p>
<ul class="text">
<li>Option Type (2 bytes): it contains the code that specifies the type of the current TLV record. Option types whose Most Significant Bit is equal to one are reserved for local use; therefore, there is no guarantee that the code used is unique among all capture files (generated by other applications). In case of vendor-specific extensions that have to be identified uniquely, vendors must request an Option Code whose MSB is equal to zero.
</li>
<li>Option Length (2 bytes): it contains the length of the following 'Option Value' field.
</li>
<li>Option Value (variable length): it contains the value of the given option. The length of this field as been specified by the Option Length field.
</li>
</ul>
<p>Options may be repeated several times (e.g. an interface that has several IP addresses associated to it). The option list is terminated by a special code which is the 'End of Option'.
</p>
<p>The format of the optional fields is shown in <a href="#formatopt">Figure 9</a>.
</p><br /><hr />
<a name="formatopt"></a>
<pre>
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Option Code | Option Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Option Value |
| /* variable length, byte-aligned */ |
| + + + + + + + + + + + + + + + + + + + + + + + + +
| / / / |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
/ /
/ . . . other options . . . /
/ /
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Option Code == opt_endofopt | Option Length == 0 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
</pre>
<table border="0" cellpadding="0" cellspacing="2" align="center"><tr><td align="center"><font face="monaco, MS Sans Serif" size="1"><b>&nbsp;Options format.&nbsp;</b></font><br /></td></tr></table><hr size="1" shade="0">
<p>The following codes can always be present in any optional field:
</p><table class="data" align="center" border="1" cellpadding="2" cellspacing="2">
<tr>
<th align="left" width="25%">Name</th>
<th align="left" width="25%">Code</th>
<th align="left" width="25%">Length</th>
<th align="left" width="25%">Description</th>
</tr>
<tr>
<td align="left">opt_endofopt</td>
<td align="left">0</td>
<td align="left">0</td>
<td align="left">End of options: it is used to delimit the end of the optional fields. This block cannot be repeated within a given list of options.</td>
</tr>
<tr>
<td align="left">opt_comment</td>
<td align="left">1</td>
<td align="left">variable</td>
<td align="left">Comment: it is an ascii string containing a comment that is associated to the current block.</td>
</tr>
</table>
<a name="anchor10"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="bug" align="right"><tr><td class="bug"><a href="#toc" class="link2">&nbsp;TOC&nbsp;</a></td></tr></table>
<a name="rfc.section.5"></a><h3>5.&nbsp;Experimental Blocks (deserved to a further investigation)</h3>
<a name="rfc.section.5.1"></a><h4><a name="anchor11">5.1</a>&nbsp;Other Packet Blocks (experimental)</h4>
<p>Can some other packet blocks (besides the two described in the previous paragraphs) be useful?
</p>
<a name="rfc.section.5.2"></a><h4><a name="anchor12">5.2</a>&nbsp;Compression Block (experimental)</h4>
<p>The Compression Block is optional. A file can contain an arbitrary number of these blocks. A Compression Block, as the name says, is used to store compressed data. Its format is shown in <a href="#formatcb">Figure 10</a>.
</p><br /><hr />
<a name="formatcb"></a>
<pre>
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Compr. Type | |
+-+-+-+-+-+-+-+-+ |
| |
| Compressed Data |
| |
| /* variable length, byte-aligned */ |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
</pre>
<table border="0" cellpadding="0" cellspacing="2" align="center"><tr><td align="center"><font face="monaco, MS Sans Serif" size="1"><b>&nbsp;Compression Block format.&nbsp;</b></font><br /></td></tr></table><hr size="1" shade="0">
<p>The fields have the following meaning:
</p>
<ul class="text">
<li>Compression Type: specifies the compression algorithm. Possible values for this field are 0 (uncompressed), 1 (Lempel Ziv), 2 (Gzip), other?? Probably some kind of dumb and fast compression algorithm could be effective with some types of traffic (for example web), but which?
</li>
<li>Compressed Data: data of this block. Once decompressed, it is made of other blocks.
</li>
</ul>
<a name="rfc.section.5.3"></a><h4><a name="anchor13">5.3</a>&nbsp;Encryption Block (experimental)</h4>
<p>The Encryption Block is optional. A file can contain an arbitrary number of these blocks. An Encryption Block is used to sotre encrypted data. Its format is shown in <a href="#formateb">Figure 11</a>.
</p><br /><hr />
<a name="formateb"></a>
<pre>
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Encr. Type | |
+-+-+-+-+-+-+-+-+ |
| |
| Compressed Data |
| |
| /* variable length, byte-aligned */ |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
</pre>
<table border="0" cellpadding="0" cellspacing="2" align="center"><tr><td align="center"><font face="monaco, MS Sans Serif" size="1"><b>&nbsp;Encryption Block format.&nbsp;</b></font><br /></td></tr></table><hr size="1" shade="0">
<p>The fields have the following meaning:
</p>
<ul class="text">
<li>Compression Type: specifies the encryption algorithm. Possible values for this field are ??? NOTE: this block should probably contain other fields, depending on the encryption algorithm. To be define precisely.
</li>
<li>Encrypted Data: data of this block. Once decripted, it consists of other blocks.
</li>
</ul>
<a name="rfc.section.5.4"></a><h4><a name="anchor14">5.4</a>&nbsp;Fixed Length Block (experimental)</h4>
<p>The Fixed Length Block is optional. A file can contain an arbitrary number of these blocks. A Fixed Length Block can be used to optimize the access to the file. Its format is shown in <a href="#formatflm">Figure 12</a>.
A Fixed Length Block stores records with constant size. It contains a set of Blocks (normally Packet Blocks or Simple Packet Blocks), of wihich it specifies the size. Knowing this size a priori helps to scan the file and to load some portions of it without truncating a block, and is particularly useful with cell-based networks like ATM.
</p><br /><hr />
<a name="formatflm"></a>
<pre>
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Cell Size | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| |
| Fixed Size Data |
| |
| /* variable length, byte-aligned */ |
| |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
</pre>
<table border="0" cellpadding="0" cellspacing="2" align="center"><tr><td align="center"><font face="monaco, MS Sans Serif" size="1"><b>&nbsp;Fixed Length Block format.&nbsp;</b></font><br /></td></tr></table><hr size="1" shade="0">
<p>The fields have the following meaning:
</p>
<ul class="text">
<li>Cell size: the size of the blocks contained in the data field.
</li>
<li>Fixed Size Data: data of this block.
</li>
</ul>
<a name="rfc.section.5.5"></a><h4><a name="anchor15">5.5</a>&nbsp;Directory Block (experimental)</h4>
<p>If present, this block contains the following information:
</p>
<ul class="text">
<li>number of indexed packets (N)
</li>
<li>table with position and length of any indexed packet (N entries)
</li>
</ul>
<p>A directory block must be followed by at least N packets, otherwise it must be considered invalid. It can be used to efficiently load portions of the file to memory and to support operations on memory mapped files. This block can be added by tools like network analyzers as a consequence of file processing.
</p>
<a name="rfc.section.5.6"></a><h4><a name="anchor16">5.6</a>&nbsp;Traffic Statistics and Monitoring Blocks (experimental)</h4>
<p>One or more blocks could be defined to contain network statistics or traffic monitoring information. They could be use to store data collected from RMON or Netflow probes, or from other network monitoring tools.
</p>
<a name="rfc.section.5.7"></a><h4><a name="anchor17">5.7</a>&nbsp;Event/Security Block (experimental)</h4>
<p>This block could be used to store events. Events could contain generic information (for example network load over 50%, server down...) or security alerts. An event could be:
</p>
<ul class="text">
<li>skipped, if the application doesn't know how to do with it
</li>
<li>processed independently by the packets. In other words, the applications skips the packets and processes only the alerts
</li>
<li>processed in relation to packets: for example, a security tool could load only the packets of the file that are near a security alert; a monitorg tool could skip the packets captured while the server was down.
</li>
</ul>
<a name="anchor18"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="bug" align="right"><tr><td class="bug"><a href="#toc" class="link2">&nbsp;TOC&nbsp;</a></td></tr></table>
<a name="rfc.section.6"></a><h3>6.&nbsp;Conclusions</h3>
<p>The file format proposed in this document should be very versatile and satisfy a wide range of applications.
In the simplest case, it can contain a raw dump of the network data, made of a series of Simple Packet Blocks.
In the most complex case, it can be used as a repository for heterogeneous information.
In every case, the file remains easy to parse and an application can always skip the data it is not interested in; at the same time, different applications can share the file, and each of them can benfit of the information produced by the others.
Two or more files can be concatenated obtaining another valid file.
</p>
<a name="anchor19"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="bug" align="right"><tr><td class="bug"><a href="#toc" class="link2">&nbsp;TOC&nbsp;</a></td></tr></table>
<a name="rfc.section.7"></a><h3>7.&nbsp;Most important open issues</h3>
<ul class="text">
<li>Data, in the file, must be byte or word aligned? Currently, the structure of this document is not consistent with respect to this point.
</li>
</ul><a name="rfc.copyright"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="bug" align="right"><tr><td class="bug"><a href="#toc" class="link2">&nbsp;TOC&nbsp;</a></td></tr></table>
<h3>Intellectual Property Statement</h3>
<p class='copyright'>
The IETF takes no position regarding the validity or scope of
any intellectual property or other rights that might be claimed
to pertain to the implementation or use of the technology
described in this document or the extent to which any license
under such rights might or might not be available; neither does
it represent that it has made any effort to identify any such
rights. Information on the IETF's procedures with respect to
rights in standards-track and standards-related documentation
can be found in BCP-11. Copies of claims of rights made
available for publication and any assurances of licenses to
be made available, or the result of an attempt made
to obtain a general license or permission for the use of such
proprietary rights by implementors or users of this
specification can be obtained from the IETF Secretariat.</p>
<p class='copyright'>
The IETF invites any interested party to bring to its
attention any copyrights, patents or patent applications, or
other proprietary rights which may cover technology that may be
required to practice this standard. Please address the
information to the IETF Executive Director.</p>
<h3>Full Copyright Statement</h3>
<p class='copyright'>
Copyright (C) The Internet Society (2004). All Rights Reserved.</p>
<p class='copyright'>
This document and translations of it may be copied and furnished to
others, and derivative works that comment on or otherwise explain it
or assist in its implementation may be prepared, copied, published and
distributed, in whole or in part, without restriction of any kind,
provided that the above copyright notice and this paragraph are
included on all such copies and derivative works. However, this
document itself may not be modified in any way, such as by removing
the copyright notice or references to the Internet Society or other
Internet organizations, except as needed for the purpose of
developing Internet standards in which case the procedures for
copyrights defined in the Internet Standards process must be
followed, or as required to translate it into languages other than
English.</p>
<p class='copyright'>
The limited permissions granted above are perpetual and will not be
revoked by the Internet Society or its successors or assignees.</p>
<p class='copyright'>
This document and the information contained herein is provided on an
&quot;AS IS&quot; basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.</p>
<h3>Acknowledgment</h3>
<p class='copyright'>
Funding for the RFC Editor function is currently provided by the
Internet Society.</p>
</body></html>

File diff suppressed because it is too large Load Diff

View File

@ -1,746 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type='text/xsl' href='rfc2629.xslt' ?>
<!DOCTYPE rfc SYSTEM "rfc2629.dtd">
<?rfc toc="yes"?>
<rfc ipr="full2026" docname="draft-libpcap-dump-format-00.txt">
<front>
<title>PCAP New Generation Dump File Format</title>
<author initials="L." surname="Degioanni" fullname="Loris Degioanni">
<organization>Politecnico di Torino</organization>
<address>
<postal>
<street>Corso Duca degli Abruzzi, 24</street>
<city>Torino</city>
<code>10129</code>
<country>Italy</country>
</postal>
<phone>+39 011 564 7008</phone>
<email>loris.degioanni@polito.it</email>
<uri>http://netgroup.polito.it/loris/</uri>
</address>
</author>
<author initials="F." surname="Risso" fullname="Fulvio Risso">
<organization>Politecnico di Torino</organization>
<address>
<postal>
<street>Corso Duca degli Abruzzi, 24</street>
<city>Torino</city>
<code>10129</code>
<country>Italy</country>
</postal>
<phone>+39 011 564 7008</phone>
<email>fulvio.risso@polito.it</email>
<uri>http://netgroup.polito.it/fulvio.risso/</uri>
</address>
</author>
<!-- Other authors go here -->
<date month="March" year="2004"/>
<area>General</area>
<!--
<workgroup>
-->
<keyword>Internet-Draft</keyword>
<keyword>Libpcap, dump file format</keyword>
<abstract>
<t>This document describes a format to dump captured packets on a file. This format is extensible and it is currently proposed for implementation in the libpcap/WinPcap packet capture library.</t>
</abstract>
<!--
<note ...>
-->
</front>
<middle>
<section title="Objectives">
<t>The problem of exchanging packet traces becomes more and more critical every day; unfortunately, no standard solutions exist for this task right now. One of the most accepted packet interchange formats is the one defined by libpcap, which is rather old and does not fit for some of the nowadays applications especially in terms of extensibility.</t>
<t>This document proposes a new format for dumping packet traces. The following goals are being pursued:</t>
<list style="symbols">
<t>Extensibility: aside of some common functionalities, third parties should be able to enrich the information embedded in the file with proprietary extensions, which will be ignored by tools that are not able to understand them.</t>
<t>Portability: a capture trace must contain all the information needed to read data independently from network, hardware and operating system of the machine that made the capture.</t>
<t>Merge/Append data: it should be possible to add data at the end of a given file, and the resulting file must still be readable.</t>
</list>
</section>
<section title="General File Structure">
<section anchor="sectionblock" title="General Block Structure">
<t>A capture file is organized in blocks, that are appended one to another to form the file. All the blocks share a common format, which is shown in <xref target="formatblock"/>.</t>
<figure anchor="formatblock" title="Basic block structure.">
<artwork>
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Block Type |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Block Total Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
/ Block Body /
/ /* variable length, aligned to 32 bits */ /
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Block Total Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
</artwork>
</figure>
<t>The fields have the following meaning:</t>
<list style="symbols">
<t>Block Type (32 bits): unique value that identifies the block. Values whose Most Significant Bit (MSB) is equal to 1 are reserved for local use. They allow to save private data to the file and to extend the file format.</t>
<t>Block Total Length: total size of this block, in bytes. For instance, a block that does not have a body has a length of 12 bytes.</t>
<t>Block Body: content of the block.</t>
<t>Block Total Length: total size of this block, in bytes. This field is duplicated for permitting backward file navigation.</t>
</list>
<t>This structure, shared among all blocks, makes easy to process a file and to skip unneeded or unknown blocks. Blocks can be nested one inside the others (NOTE: needed?). Some of the blocks are mandatory, i.e. a dump file is not valid if they are not present, other are optional.</t>
<t>The structure of the blocks allows to define other blocks if needed. A parser that does non understand them can simply ignore their content.</t>
</section>
<section title="Block Types">
<t>The currently defined blocks are the following:</t>
<list style="numbers">
<t>Section Header Block: it defines the most important characteristics of the capture file.</t>
<t>Interface Description Block: it defines the most important characteristics of the interface(s) used for capturing traffic.</t>
<t>Packet Block: it contains a single captured packet, or a portion of it.</t>
<t>Simple Packet Block: it contains a single captured packet, or a portion of it, with only a minimal set of information about it.</t>
<t>Name Resolution Block: it defines the mapping from numeric addresses present in the packet dump and the canonical name counterpart.</t>
<t>Capture Statistics Block: it defines how to store some statistical data (e.g. packet dropped, etc) which can be useful to undestand the conditions in which the capture has been made.</t>
<t>Compression Marker Block: TODO</t>
<t>Encryption Marker Block: TODO</t>
<t>Fixed Length Marker Block: TODO</t>
</list>
<t>The following blocks instead are considered interesting but the authors believe that they deserve more in-depth discussion before being defined:</t>
<list style="numbers">
<t>Further Packet Blocks</t>
<t>Directory Block</t>
<t>Traffic Statistics and Monitoring Blocks</t>
<t>Alert and Security Blocks</t>
</list>
<t>TODO Currently standardized Block Type codes are specified in Appendix 1.</t>
</section>
<section title="Block Hierarchy and Precedence">
<t>The file must begin with a Section Header Block. However, more than one Section Header Block can be present on the dump, each one covering the data following it till the next one (or the end of file). A Section includes the data delimited by two Section Header Blocks (or by a Section Header Block and the end of the file), including the first Section Header Block.</t>
<t>In case an application cannot read a Section because of different version number, it must skip everything until the next Section Header Block. Note that, in order to properly skip the blocks until the next section, all blocks must have the fields Type and Length at the beginning. This is a mandatory requirement that must be maintained in future versions of the block format.</t>
<t><xref target="fssample-SHB"/> shows two valid files: the first has a typical configuration, with a single Section Header that covers the whole file. The second one contains three headers, and is normally the result of file concatenation. An application that understands only version 1.0 of the file format skips the intermediate section and restart processing the packets after the third Section Header.</t>
<figure anchor="fssample-SHB" title="File structure example: the Section Header Block.">
<artwork>
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| SHB v1.0 | Data |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Typical configuration with a single Section Header Block
|-- 1st Section --|-- 2nd Section --|-- 3rd Section --|
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| SHB v1.0 | Data | SHB V1.1 | Data | SHB V1.0 | Data |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Configuration with three different Section Header Blocks
</artwork>
</figure>
<t>NOTE: TO BE COMPLETED with some examples of other blocks</t>
</section>
<section title="Data format">
<t>Data contained in each section will always be saved according to the characteristics (little endian / big endian) of the dumping machine. This refers to all fields that are saved as numbers and that span over two or more bytes.</t>
<t>The approach of having each section saved in the native format of the generating host is more efficient because it avoids translation of data when reading / writing on the host itself, which is the most common case when generating/processing capture dumps.</t>
<t>TODO Probably we have to specify something more here. Is what we're saying enough to avoid any kind of ambiguity?.</t>
</section>
</section>
<section title="Block Definition">
<t>This section details the format of the body of the blocks currently defined.</t>
<section anchor="sectionshb" title="Section Header Block (mandatory)">
<t>The Section Header Block is mandatory. It identifies the beginning of a section of the capture dump file. Its format is shown in <xref target="formatSHB"/>.</t>
<figure anchor="formatSHB" title="Section Header Block format.">
<artwork>
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Magic |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Major | Minor |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
/ /
/ Options (variable) /
/ /
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
</artwork>
</figure>
<t>The meaning of the fields is:</t>
<list style="symbols">
<t>Magic: magic number, whose value is the hexadecimal number 0x1A2B3C4D. This number can be used to distinguish section that have been saved on little-endian machines from the one saved on big-endian machines.</t>
<t>Major: number of the current mayor version of the format. Current value is 1.</t>
<t>Minor: number of the current minor version of the format. Current value is 0.</t>
<t>Options: optionally, a list of options (formatted according to the rules defined in <xref target="sectionopt"/>) can be present.</t>
</list>
<t>Aside form the options defined in <xref target="sectionopt"/>, the following options are valid within this block:</t>
<texttable anchor="InterfaceOptions1">
<ttcol>Name</ttcol>
<ttcol>Code</ttcol>
<ttcol>Length</ttcol>
<ttcol>Description</ttcol>
<c>Hardware</c>
<c>2</c>
<c>variable</c>
<c>An ascii string containing the description of the hardware used to create this section.</c>
<c>Operating System</c>
<c>3</c>
<c>variable</c>
<c>An ascii string containing the name of the operating system used to create this section.</c>
<c>User Application</c>
<c>3</c>
<c>variable</c>
<c>An ascii string containing the name of the application used to create this section.</c>
</texttable>
<t>The Section Header Block does not contain data but it rather identifies a list of blocks (interfaces, packets) that are logically correlated. This block does not contain any reference to the size of the section it is currently delimiting, therefore the reader cannot skip a whole section at once. In case a section must be skipped, the user has to repeatedly skip all the blocks contained within it; this makes the parsing of the file slower but it permits to append several capture dumps at the same file.</t>
</section>
<section anchor="sectionidb" title="Interface Description Block (mandatory)">
<t>The Interface Description Block is mandatory. This block is needed to specify the characteristics of the network interface on which the capture has been made. In order to properly associate the captured data to the corresponding interface, the Interface Description Block must be defined before any other block that uses it; therefore, this block is usually placed immediately after the Section Header Block.</t>
<t>An Interface Description Block is valid only inside the section which it belongs to. The structure of a Interface Description Block is shown in <xref target="formatidb"/>.</t>
<figure anchor="formatidb" title="Interface Description Block format.">
<artwork>
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Interface ID | LinkType |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| SnapLen |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
/ /
/ Options (variable) /
/ /
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
</artwork>
</figure>
<t>The meaning of the fields is:</t>
<list style="symbols">
<t>Interface ID: a progressive number that identifies uniquely any interface inside current section. Two Interface Description Blocks can have the same Interface ID only if they are in different sections of the file. The Interface ID is referenced by the packet blocks.</t>
<t>LinkType: a value that defines the link layer type of this interface.</t>
<t>SnapLen: maximum number of bytes dumped from each packet. The portion of each packet that exceeds this value will not be stored in the file.</t>
<t>Options: optionally, a list of options (formatted according to the rules defined in <xref target="sectionopt"/>) can be present.</t>
</list>
<t>In addition to the options defined in <xref target="sectionopt"/>, the following options are valid within this block:</t>
<texttable anchor="InterfaceOptions2">
<ttcol>Name</ttcol>
<ttcol>Code</ttcol>
<ttcol>Length</ttcol>
<ttcol>Description</ttcol>
<c>if_name</c>
<c>2</c>
<c>Variable</c>
<c>Name of the device used to capture data.</c>
<c>if_IPv4addr</c>
<c>3</c>
<c>8</c>
<c>Interface network address and netmask.</c>
<c>if_IPv6addr</c>
<c>4</c>
<c>17</c>
<c>Interface network address and prefix length (stored in the last byte).</c>
<c>if_MACaddr</c>
<c>5</c>
<c>6</c>
<c>Interface Hardware MAC address (48 bits).</c>
<c>if_EUIaddr</c>
<c>6</c>
<c>8</c>
<c>Interface Hardware EUI address (64 bits), if available.</c>
<c>if_speed</c>
<c>7</c>
<c>8</c>
<c>Interface speed (in bps).</c>
<c>if_tsaccur</c>
<c>8</c>
<c>1</c>
<c>Precision of timestamps. If the Most Significant Bit is equal to zero, the remaining bits indicates the accuracy as as a negative power of 10 (e.g. 6 means microsecond accuracy). If the Most Significant Bit is equal to zero, the remaining bits indicates the accuracy as as negative power of 2 (e.g. 10 means 1/1024 of second). If this option is not present, a precision of 10^-6 is assumed.</c>
<c>if_tzone</c>
<c>9</c>
<c>4</c>
<c>Time zone for GMT support (TODO: specify better).</c>
<c>if_flags</c>
<c>10</c>
<c>4</c>
<c>Interface flags. (TODO: specify better. Possible flags: promiscuous, inbound/outbound, traffic filtered during capture).</c>
<c>if_filter</c>
<c>11</c>
<c>variable</c>
<c>The filter (e.g. "capture only TCP traffic") used to capture traffic. The first byte of the Option Data keeps a code of the filter used (e.g. if this is a libpcap string, or BPF bytecode, and more). More details about this format will be presented in Appendix XXX (TODO).</c>
<c>if_opersystem</c>
<c>12</c>
<c>variable</c>
<c>An ascii string containing the name of the operating system of the machine that hosts this interface. This can be different from the same information that can be contained by the Section Header Block (<xref target="sectionshb"/>) because the capture can have been done on a remote machine.</c>
</texttable>
</section>
<section anchor="sectionpb" title="Packet Block (optional)">
<t>A Packet Block is the standard container for storing the packets coming from the network. The Packet Block is optional because packets can be stored either by means of this block or the Simple Packet Block, which can be used to speed up dump generation. The format of a packet block is shown in <xref target="formatpb"/>.</t>
<figure anchor="formatpb" title="Packet Block format.">
<artwork>
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Interface ID | Drops Count |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Timestamp (High) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Timestamp (Low) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Captured Len |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Packet Len |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
| Packet Data |
| |
| /* variable length, byte-aligned */ |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
/ /
/ Options (variable) /
/ /
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
</artwork>
</figure>
<t>The Packet Block has the following fields:</t>
<list style="symbols">
<t>Interface ID: Specifies the interface this packet comes from, and corresponds to the ID of one of the Interface Description Blocks present in this section of the file (see <xref target="formatidb"/>).</t>
<t>Drops Count: a local drop counter. It specified the number of packets lost (by the interface and the operating system) between this packet and the preceding one. The value xFFFF (in hexadecimal) is reserved for those systems in which this information is not available.</t>
<t>Timestamp (High): the most significative part of the timestamp. in standard Unix format, i.e. from 1/1/1970.</t>
<t>Timestamp (Low): the less significative part of the timestamp. The way to interpret this field is specified by the 'ts_accur' option (see <xref target="formatidb"/>) of the Interface Description block referenced by this packet. If the Interface Description block does not contain a 'ts_accur' option, then this field is expressed in microseconds.</t>
<t>Captured Len: number of bytes captured from the packet (i.e. the length of the Packet Data field). It will be the minimum value among the actual Packet Length and the snapshot length (defined in <xref target="formatidb"/>).</t>
<t>Packet Len: actual length of the packet when it was transmitted on the network. Can be different from Captured Len if the user wants only a snapshot of the packet.</t>
<t>Packet Data: the data coming from the network, including link-layer headers. The length of this field is Captured Len. The format of the link-layer headers depends on the LinkType field specified in the Interface Description Block (see <xref target="sectionidb"/>) and it is specified in Appendix XXX (TODO).</t>
<t>Options: optionally, a list of options (formatted according to the rules defined in <xref target="sectionopt"/>) can be present.</t>
</list>
<t></t>
</section>
<section title="Simple Packet Block (optional)">
<t>The Simple Packet Block is a lightweight container for storing the packets coming from the network. Its presence is optional.</t>
<t>A Simple Packet Block is similar to a Packet Block (see <xref target="sectionpb"/>), but it is smaller, simpler to process and contains only a minimal set of information. This block is preferred to the standard Packet Block when performance or space occupation are critical factors, such as in sustained traffic dump applications. A capture file can contain both Packet Blocks and Simple Packet Blocks: for example, a capture tool could switch from Packet Blocks to Simple Packet Blocks when the hardware resources become critical.</t>
<t>The Simple Packet Block does not contain the Interface ID field. Therefore, it must be assumed that all the Simple Packet Blocks have been captured on the interface previously specified in the Interface Description Block.</t>
<t><xref target="formatpbs"/> shows the format of the Simple Packet Block.</t>
<figure anchor="formatpbs" title="Simple Packet Block format.">
<artwork>
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Packet Len |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
| Packet Data |
| |
| /* variable length, byte-aligned */ |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
</artwork>
</figure>
<t>The Packet Block has the following fields:</t>
<list style="symbols">
<t>Packet Len: actual length of the packet when it was transmitted on the network. Can be different from captured len if the packet has been truncated.</t>
<t>Packet data: the data coming from the network, including link-layers headers. The length of this field can be derived from the field Block Total Length, present in the Block Header.</t>
</list>
<t>The Simple Packet Block does not contain the timestamp because this is one of the most costly operations on PCs. Additionally, there are applications that do not require it; e.g. an Intrusion Detection System is interested in packets, not in their timestamp.</t>
<t>The Simple Packet Block is very efficient in term of disk space: a snapshot of length 100 bytes requires only 16 bytes of overhead, which corresponds to an efficiency of more than 86%.</t>
</section>
<section title="Name Resolution Block (optional)">
<t>The Name Resolution Block is used to support the correlation of numeric addresses (present in the captured packets) and their corresponding canonical names and it is optional. Having the literal names saved in the file, this prevents the need of a name resolution in a delayed time, when the association between names and addresses can be different from the one in use at capture time. Moreover, The Name Resolution Block avoids the need of issuing a lot of DNS requests every time the trace capture is opened, and allows to have name resolution also when reading the capture with a machine not connected to the network.</t>
<t>The format of the Name Resolution Block is shown in <xref target="formatnrb"/>.</t>
<figure anchor="formatnrb" title="Name Resolution Block format.">
<artwork>
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Record Type | Record Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Record Value |
| /* variable length, byte-aligned */ |
| + + + + + + + + + + + + + + + + + + + + + + + + +
| | | | |
+-+-+-+-+-+-+-+-+ + + + + + + + + + + + + + + + + + + + + + + + +
. . . other records . . .
| Record Type == end_of_recs | Record Length == 00 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
/ /
/ Options (variable) /
/ /
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
</artwork>
</figure>
<t>A Name Resolution Block is a zero-terminated list of records (in the TLV format), each of which contains an association between a network address and a name. There are three possible types of records:</t>
<texttable anchor="nrrecords">
<ttcol>Name</ttcol>
<ttcol>Code</ttcol>
<ttcol>Length</ttcol>
<ttcol>Description</ttcol>
<c>end_of_recs</c>
<c>0</c>
<c>0</c>
<c>End of records</c>
<c>ip4_rec</c>
<c>1</c>
<c>Variable</c>
<c>Specifies an IPv4 address (contained in the first 4 bytes), followed by one or more zero-terminated strings containing the DNS entries for that address.</c>
<c>ip6_rec</c>
<c>1</c>
<c>Variable</c>
<c>Specifies an IPv6 address (contained in the first 16 bytes), followed by one or more zero-terminated strings containing the DNS entries for that address.</c>
</texttable>
<t>After the list or Name Resolution Records, optionally, a list of options (formatted according to the rules defined in <xref target="sectionopt"/>) can be present.</t>
<t>A Name Resolution Block is normally placed at the beginning of the file, but no assumptions can be taken about its position. Name Resolution Blocks can be added in a second time by tools that process the file, like network analyzers.</t>
<t>In addiction to the options defined in <xref target="sectionopt"/>, the following options are valid within this block:</t>
<texttable>
<ttcol>Name</ttcol>
<ttcol>Code</ttcol>
<ttcol>Length</ttcol>
<ttcol>Description</ttcol>
<c>ns_dnsname</c>
<c>2</c>
<c>Variable</c>
<c>An ascii string containing the name of the machine (DNS server) used to perform the name resolution.</c>
</texttable>
</section>
<section title="Interface Statistics Block (optional)">
<t>The Interface Statistics Block contains the capture statistics for a given interface and it is optional. The statistics are referred to the interface defined in the current Section identified by the Interface ID field.</t>
<t>The format of the Interface Statistics Block is shown in <xref target="formatisb"/>.</t>
<figure anchor="formatisb" title="Interface Statistics Block format.">
<artwork>
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| IfRecv |
| (high + low) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| IfDrop |
| (high + low) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| FilterAccept |
| (high + low) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| OSDrop |
| (high + low) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| UsrDelivered |
| (high + low) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Interface ID | Reserved |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
/ /
/ Options (variable) /
/ /
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
</artwork>
</figure>
<t>The fields have the following meaning:</t>
<list style="symbols">
<t>IfRecv: number of packets received from the interface during the capture. This number is reported as a 64 bits value, in which the most significat bits are located in the first four bytes of the field.</t>
<t>IfDrop: number of packets dropped by the interface during the capture due to lack of resources.</t>
<t>FilterAccept: number of packets accepeted by filter during current capture.</t>
<t>OSDrop: number of packets dropped by the operating system during the capture.</t>
<t>UsrDelivered: number of packets delivered to the user. UsrDelivered can be different from the value 'FilterAccept - OSDropped' because some packets could still lay in the OS buffers when the capture ended.</t>
<t>Interface ID: reference to an Interface Description Block.</t>
<t>Reserved: Reserved to future use.</t>
<t>Options: optionally, a list of options (formatted according to the rules defined in <xref target="sectionopt"/>) can be present.</t>
</list>
<t>In addiction to the options defined in <xref target="sectionopt"/>, the following options are valid within this block:</t>
<texttable>
<ttcol>Name</ttcol>
<ttcol>Code</ttcol>
<ttcol>Length</ttcol>
<ttcol>Description</ttcol>
<c>isb_starttime</c>
<c>2</c>
<c>8</c>
<c>Time in which the capture started; time will be stored in two blocks of four bytes each, containing the timestamp in seconds and nanoseconds.</c>
<c>isb_endtime</c>
<c>3</c>
<c>8</c>
<c>Time in which the capture started; time will be stored in two blocks of four bytes each, containing the timestamp in seconds and nanoseconds.</c>
</texttable>
</section>
</section>
<section anchor="sectionopt" title="Options">
<t>Almost all blocks have the possibility to embed optional fields. Optional fields can be used to insert some information that may be useful when reading data, but that it is not really needed for packet processing. Therefore, each tool can be either read the content of the optional fields (if any), or skip them at once.</t>
<t>Skipping all the optional fields at once is straightforward because most of the blocks have a fixed length, therefore the field Block Length (present in the General Block Structure, see <xref target="sectionblock"/>) can be used to skip everything till the next block.</t>
<t>Options are a list of Type - Length - Value fields, each one containing a single value:</t>
<list style="symbols">
<t>Option Type (2 bytes): it contains the code that specifies the type of the current TLV record. Option types whose Most Significant Bit is equal to one are reserved for local use; therefore, there is no guarantee that the code used is unique among all capture files (generated by other applications). In case of vendor-specific extensions that have to be identified uniquely, vendors must request an Option Code whose MSB is equal to zero.</t>
<t>Option Length (2 bytes): it contains the length of the following 'Option Value' field.</t>
<t>Option Value (variable length): it contains the value of the given option. The length of this field as been specified by the Option Length field.</t>
</list>
<t>Options may be repeated several times (e.g. an interface that has several IP addresses associated to it). The option list is terminated by a special code which is the 'End of Option'.</t>
<t>The format of the optional fields is shown in <xref target="formatopt"/>.</t>
<figure anchor="formatopt" title="Options format.">
<artwork>
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Option Code | Option Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Option Value |
| /* variable length, byte-aligned */ |
| + + + + + + + + + + + + + + + + + + + + + + + + +
| / / / |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
/ /
/ . . . other options . . . /
/ /
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Option Code == opt_endofopt | Option Length == 0 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
</artwork>
</figure>
<t>The following codes can always be present in any optional field:</t>
<texttable>
<ttcol>Name</ttcol>
<ttcol>Code</ttcol>
<ttcol>Length</ttcol>
<ttcol>Description</ttcol>
<c>opt_endofopt</c>
<c>0</c>
<c>0</c>
<c>End of options: it is used to delimit the end of the optional fields. This block cannot be repeated within a given list of options.</c>
<c>opt_comment</c>
<c>1</c>
<c>variable</c>
<c>Comment: it is an ascii string containing a comment that is associated to the current block.</c>
</texttable>
</section>
<section title="Experimental Blocks (deserved to a further investigation)">
<section title="Other Packet Blocks (experimental)">
<t>Can some other packet blocks (besides the two described in the previous paragraphs) be useful?</t>
</section>
<section title="Compression Block (experimental)">
<t>The Compression Block is optional. A file can contain an arbitrary number of these blocks. A Compression Block, as the name says, is used to store compressed data. Its format is shown in <xref target="formatcb"/>.</t>
<figure anchor="formatcb" title="Compression Block format.">
<artwork>
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Compr. Type | |
+-+-+-+-+-+-+-+-+ |
| |
| Compressed Data |
| |
| /* variable length, byte-aligned */ |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
</artwork>
</figure>
<t>The fields have the following meaning:</t>
<list style="symbols">
<t>Compression Type: specifies the compression algorithm. Possible values for this field are 0 (uncompressed), 1 (Lempel Ziv), 2 (Gzip), other?? Probably some kind of dumb and fast compression algorithm could be effective with some types of traffic (for example web), but which?</t>
<t>Compressed Data: data of this block. Once decompressed, it is made of other blocks.</t>
</list>
</section>
<section title="Encryption Block (experimental)">
<t>The Encryption Block is optional. A file can contain an arbitrary number of these blocks. An Encryption Block is used to sotre encrypted data. Its format is shown in <xref target="formateb"/>.</t>
<figure anchor="formateb" title="Encryption Block format.">
<artwork>
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Encr. Type | |
+-+-+-+-+-+-+-+-+ |
| |
| Compressed Data |
| |
| /* variable length, byte-aligned */ |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
</artwork>
</figure>
<t>The fields have the following meaning:</t>
<list style="symbols">
<t>Compression Type: specifies the encryption algorithm. Possible values for this field are ??? NOTE: this block should probably contain other fields, depending on the encryption algorithm. To be define precisely.</t>
<t>Encrypted Data: data of this block. Once decripted, it consists of other blocks.</t>
</list>
</section>
<section title="Fixed Length Block (experimental)">
<t>The Fixed Length Block is optional. A file can contain an arbitrary number of these blocks. A Fixed Length Block can be used to optimize the access to the file. Its format is shown in <xref target="formatflm"/>.
A Fixed Length Block stores records with constant size. It contains a set of Blocks (normally Packet Blocks or Simple Packet Blocks), of wihich it specifies the size. Knowing this size a priori helps to scan the file and to load some portions of it without truncating a block, and is particularly useful with cell-based networks like ATM.</t>
<figure anchor="formatflm" title="Fixed Length Block format.">
<artwork>
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Cell Size | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| |
| Fixed Size Data |
| |
| /* variable length, byte-aligned */ |
| |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
</artwork>
</figure>
<t>The fields have the following meaning:</t>
<list style="symbols">
<t>Cell size: the size of the blocks contained in the data field.</t>
<t>Fixed Size Data: data of this block.</t>
</list>
</section>
<section title="Directory Block (experimental)">
<t>If present, this block contains the following information:</t>
<list style="symbols">
<t>number of indexed packets (N)</t>
<t>table with position and length of any indexed packet (N entries)</t>
</list>
<t>A directory block must be followed by at least N packets, otherwise it must be considered invalid. It can be used to efficiently load portions of the file to memory and to support operations on memory mapped files. This block can be added by tools like network analyzers as a consequence of file processing.</t>
</section>
<section title="Traffic Statistics and Monitoring Blocks (experimental)">
<t>One or more blocks could be defined to contain network statistics or traffic monitoring information. They could be use to store data collected from RMON or Netflow probes, or from other network monitoring tools.</t>
</section>
<section title="Event/Security Block (experimental)">
<t>This block could be used to store events. Events could contain generic information (for example network load over 50%, server down...) or security alerts. An event could be:</t>
<list style="symbols">
<t>skipped, if the application doesn't know how to do with it</t>
<t>processed independently by the packets. In other words, the applications skips the packets and processes only the alerts</t>
<t>processed in relation to packets: for example, a security tool could load only the packets of the file that are near a security alert; a monitorg tool could skip the packets captured while the server was down.</t>
</list>
</section>
</section>
<section title="Conclusions">
<t>The file format proposed in this document should be very versatile and satisfy a wide range of applications.
In the simplest case, it can contain a raw dump of the network data, made of a series of Simple Packet Blocks.
In the most complex case, it can be used as a repository for heterogeneous information.
In every case, the file remains easy to parse and an application can always skip the data it is not interested in; at the same time, different applications can share the file, and each of them can benfit of the information produced by the others.
Two or more files can be concatenated obtaining another valid file.</t>
</section>
<section title="Most important open issues">
<list style="symbols">
<t>Data, in the file, must be byte or word aligned? Currently, the structure of this document is not consistent with respect to this point.</t>
</list>
</section>
</middle>
</rfc>

View File

@ -21,7 +21,7 @@
#ifndef lint
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/etherent.c,v 1.22 2003/11/15 23:23:57 guy Exp $ (LBL)";
"@(#) $Header: /tcpdump/master/libpcap/etherent.c,v 1.23 2006/10/04 18:09:22 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@ -37,7 +37,7 @@ static const char rcsid[] _U_ =
#include "pcap-int.h"
#include <pcap-namedb.h>
#include <pcap/namedb.h>
#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"

View File

@ -18,7 +18,7 @@
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* @(#) $Header: /tcpdump/master/libpcap/ethertype.h,v 1.13.2.1 2005/09/05 09:08:03 guy Exp $ (LBL)
* @(#) $Header: /tcpdump/master/libpcap/ethertype.h,v 1.14 2005/09/05 09:06:58 guy Exp $ (LBL)
*/
/*

View File

@ -34,7 +34,7 @@
#ifndef lint
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/fad-getad.c,v 1.10.2.2 2007/09/14 00:45:17 guy Exp $ (LBL)";
"@(#) $Header: /tcpdump/master/libpcap/fad-getad.c,v 1.12 2007/09/14 00:44:55 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H

View File

@ -34,7 +34,7 @@
#ifndef lint
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/fad-gifc.c,v 1.8.2.2 2005/06/29 06:43:31 guy Exp $ (LBL)";
"@(#) $Header: /tcpdump/master/libpcap/fad-gifc.c,v 1.11.2.1 2008-08-06 07:35:01 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@ -42,7 +42,6 @@ static const char rcsid[] _U_ =
#endif
#include <sys/param.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#ifdef HAVE_SYS_SOCKIO_H

View File

@ -34,7 +34,7 @@
#ifndef lint
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/fad-glifc.c,v 1.5.2.1 2005/04/19 00:54:16 guy Exp $ (LBL)";
"@(#) $Header: /tcpdump/master/libpcap/fad-glifc.c,v 1.6.2.1 2008/01/30 09:36:09 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@ -75,9 +75,9 @@ struct rtentry; /* declarations in <net/if.h> */
* 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
* This is the implementation used on platforms that have SIOCGLIFCONF
* but don't have "getifaddrs()". (Solaris 8 and later; we use
* SIOCLGIFCONF rather than SIOCGIFCONF in order to get IPv6 addresses.)
* SIOCGLIFCONF rather than SIOCGIFCONF in order to get IPv6 addresses.)
*/
int
pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)

61
fad-sita.c Normal file
View File

@ -0,0 +1,61 @@
/*
* fad-sita.c: Packet capture interface additions for SITA ACN devices
*
* Copyright (c) 2007 Fulko Hew, SITA INC Canada, Inc <fulko.hew@sita.aero>
*
* 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.
*/
/* $Id: fad-sita.c */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <string.h>
#include "pcap-int.h"
#include "pcap-sita.h"
extern pcap_if_t *acn_if_list; /* pcap's list of available interfaces */
int pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) {
//printf("pcap_findalldevs()\n"); // fulko
*alldevsp = 0; /* initialize the returned variables before we do anything */
strcpy(errbuf, "");
if (acn_parse_hosts_file(errbuf)) /* scan the hosts file for potential IOPs */
{
//printf("pcap_findalldevs() returning BAD after parsehosts\n"); // fulko
return -1;
}
//printf("pcap_findalldevs() got hostlist now finding devs\n"); // fulko
if (acn_findalldevs(errbuf)) /* then ask the IOPs for their monitorable devices */
{
//printf("pcap_findalldevs() returning BAD after findalldevs\n"); // fulko
return -1;
}
*alldevsp = acn_if_list;
acn_if_list = 0; /* then forget our list head, because someone will call pcap_freealldevs() to empty the malloc'ed stuff */
//printf("pcap_findalldevs() returning ZERO OK\n"); // fulko
return 0;
}

View File

@ -33,7 +33,7 @@
#ifndef lint
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/fad-win32.c,v 1.11.2.3 2006/02/22 17:09:32 gianluca Exp $ (LBL)";
"@(#) $Header: /tcpdump/master/libpcap/fad-win32.c,v 1.15 2007/09/25 20:34:36 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@ -301,6 +301,15 @@ pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
name += strlen(name) + 1;
desc += strlen(desc) + 1;
}
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) {
/*

254
filtertest.c Normal file
View File

@ -0,0 +1,254 @@
/*
* Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000
* 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 copyright[] _U_ =
"@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000\n\
The Regents of the University of California. All rights reserved.\n";
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/filtertest.c,v 1.2 2005/08/08 17:50:13 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <pcap.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifndef HAVE___ATTRIBUTE__
#define __attribute__(x)
#endif
static char *program_name;
/* Forwards */
static void usage(void) __attribute__((noreturn));
static void error(const char *, ...)
__attribute__((noreturn, format (printf, 1, 2)));
extern int optind;
extern int opterr;
extern char *optarg;
/*
* On Windows, we need to open the file in binary mode, so that
* we get all the bytes specified by the size we get from "fstat()".
* On UNIX, that's not necessary. O_BINARY is defined on Windows;
* we define it as 0 if it's not defined, so it does nothing.
*/
#ifndef O_BINARY
#define O_BINARY 0
#endif
static char *
read_infile(char *fname)
{
register int i, fd, cc;
register char *cp;
struct stat buf;
fd = open(fname, O_RDONLY|O_BINARY);
if (fd < 0)
error("can't open %s: %s", fname, pcap_strerror(errno));
if (fstat(fd, &buf) < 0)
error("can't stat %s: %s", fname, pcap_strerror(errno));
cp = malloc((u_int)buf.st_size + 1);
if (cp == NULL)
error("malloc(%d) for %s: %s", (u_int)buf.st_size + 1,
fname, pcap_strerror(errno));
cc = read(fd, cp, (u_int)buf.st_size);
if (cc < 0)
error("read %s: %s", fname, pcap_strerror(errno));
if (cc != buf.st_size)
error("short read %s (%d != %d)", fname, cc, (int)buf.st_size);
close(fd);
/* replace "# comment" with spaces */
for (i = 0; i < cc; i++) {
if (cp[i] == '#')
while (i < cc && cp[i] != '\n')
cp[i++] = ' ';
}
cp[cc] = '\0';
return (cp);
}
/* VARARGS */
static void
error(const char *fmt, ...)
{
va_list ap;
(void)fprintf(stderr, "%s: ", program_name);
va_start(ap, fmt);
(void)vfprintf(stderr, fmt, ap);
va_end(ap);
if (*fmt) {
fmt += strlen(fmt);
if (fmt[-1] != '\n')
(void)fputc('\n', stderr);
}
exit(1);
/* NOTREACHED */
}
/*
* Copy arg vector into a new buffer, concatenating arguments with spaces.
*/
static char *
copy_argv(register char **argv)
{
register char **p;
register u_int len = 0;
char *buf;
char *src, *dst;
p = argv;
if (*p == 0)
return 0;
while (*p)
len += strlen(*p++) + 1;
buf = (char *)malloc(len);
if (buf == NULL)
error("copy_argv: malloc");
p = argv;
dst = buf;
while ((src = *p++) != NULL) {
while ((*dst++ = *src++) != '\0')
;
dst[-1] = ' ';
}
dst[-1] = '\0';
return buf;
}
int
main(int argc, char **argv)
{
char *cp;
int op;
int dflag;
char *infile;
int Oflag;
long snaplen;
int dlt;
char *cmdbuf;
pcap_t *pd;
struct bpf_program fcode;
#ifdef WIN32
if(wsockinit() != 0) return 1;
#endif /* WIN32 */
dflag = 1;
infile = NULL;
Oflag = 1;
snaplen = 68;
if ((cp = strrchr(argv[0], '/')) != NULL)
program_name = cp + 1;
else
program_name = argv[0];
opterr = 0;
while ((op = getopt(argc, argv, "dF:Os:")) != -1) {
switch (op) {
case 'd':
++dflag;
break;
case 'F':
infile = optarg;
break;
case 'O':
Oflag = 0;
break;
case 's': {
char *end;
snaplen = strtol(optarg, &end, 0);
if (optarg == end || *end != '\0'
|| snaplen < 0 || snaplen > 65535)
error("invalid snaplen %s", optarg);
else if (snaplen == 0)
snaplen = 65535;
break;
}
default:
usage();
/* NOTREACHED */
}
}
if (optind >= argc) {
usage();
/* NOTREACHED */
}
dlt = pcap_datalink_name_to_val(argv[optind]);
if (dlt < 0)
error("invalid data link type %s", argv[optind]);
if (infile)
cmdbuf = read_infile(infile);
else
cmdbuf = copy_argv(&argv[optind+1]);
pd = pcap_open_dead(dlt, snaplen);
if (pd == NULL)
error("Can't open fake pcap_t");
if (pcap_compile(pd, &fcode, cmdbuf, Oflag, 0) < 0)
error("%s", pcap_geterr(pd));
bpf_dump(&fcode, dflag);
pcap_close(pd);
exit(0);
}
static void
usage(void)
{
(void)fprintf(stderr, "%s, with %s\n", program_name,
pcap_lib_version());
(void)fprintf(stderr,
"Usage: %s [-dO] [ -F file ] [ -s snaplen ] dlt [ expression ]\n",
program_name);
exit(1);
}

131
findalldevstest.c Normal file
View File

@ -0,0 +1,131 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <pcap.h>
static void ifprint(pcap_if_t *d);
static char *iptos(bpf_u_int32 in);
int main(int argc, char **argv)
{
pcap_if_t *alldevs;
pcap_if_t *d;
char *s;
bpf_u_int32 net, mask;
char errbuf[PCAP_ERRBUF_SIZE+1];
if (pcap_findalldevs(&alldevs, errbuf) == -1)
{
fprintf(stderr,"Error in pcap_findalldevs: %s\n",errbuf);
exit(1);
}
for(d=alldevs;d;d=d->next)
{
ifprint(d);
}
if ( (s = pcap_lookupdev(errbuf)) == NULL)
{
fprintf(stderr,"Error in pcap_lookupdev: %s\n",errbuf);
}
else
{
printf("Preferred device name: %s\n",s);
}
if (pcap_lookupnet(s, &net, &mask, errbuf) < 0)
{
fprintf(stderr,"Error in pcap_lookupnet: %s\n",errbuf);
}
else
{
printf("Preferred device is on network: %s/%s\n",iptos(net), iptos(mask));
}
exit(0);
}
static void ifprint(pcap_if_t *d)
{
pcap_addr_t *a;
#ifdef INET6
char ntop_buf[INET6_ADDRSTRLEN];
#endif
printf("%s\n",d->name);
if (d->description)
printf("\tDescription: %s\n",d->description);
printf("\tLoopback: %s\n",(d->flags & PCAP_IF_LOOPBACK)?"yes":"no");
for(a=d->addresses;a;a=a->next) {
switch(a->addr->sa_family)
{
case AF_INET:
printf("\tAddress Family: AF_INET\n");
if (a->addr)
printf("\t\tAddress: %s\n",
inet_ntoa(((struct sockaddr_in *)(a->addr))->sin_addr));
if (a->netmask)
printf("\t\tNetmask: %s\n",
inet_ntoa(((struct sockaddr_in *)(a->netmask))->sin_addr));
if (a->broadaddr)
printf("\t\tBroadcast Address: %s\n",
inet_ntoa(((struct sockaddr_in *)(a->broadaddr))->sin_addr));
if (a->dstaddr)
printf("\t\tDestination Address: %s\n",
inet_ntoa(((struct sockaddr_in *)(a->dstaddr))->sin_addr));
break;
#ifdef INET6
case AF_INET6:
printf("\tAddress Family: AF_INET6\n");
if (a->addr)
printf("\t\tAddress: %s\n",
inet_ntop(AF_INET6,
((struct sockaddr_in6 *)(a->addr))->sin6_addr.s6_addr,
ntop_buf, sizeof ntop_buf));
if (a->netmask)
printf("\t\tNetmask: %s\n",
inet_ntop(AF_INET6,
((struct sockaddr_in6 *)(a->netmask))->sin6_addr.s6_addr,
ntop_buf, sizeof ntop_buf));
if (a->broadaddr)
printf("\t\tBroadcast Address: %s\n",
inet_ntop(AF_INET6,
((struct sockaddr_in6 *)(a->broadaddr))->sin6_addr.s6_addr,
ntop_buf, sizeof ntop_buf));
if (a->dstaddr)
printf("\t\tDestination Address: %s\n",
inet_ntop(AF_INET6,
((struct sockaddr_in6 *)(a->dstaddr))->sin6_addr.s6_addr,
ntop_buf, sizeof ntop_buf));
break;
#endif
default:
printf("\tAddress Family: Unknown (%d)\n", a->addr->sa_family);
break;
}
}
printf("\n");
}
/* From tcptraceroute */
#define IPTOSBUFFERS 12
static char *iptos(bpf_u_int32 in)
{
static char output[IPTOSBUFFERS][3*4+3+1];
static short which;
u_char *p;
p = (u_char *)&in;
which = (which + 1 == IPTOSBUFFERS ? 0 : which + 1);
sprintf(output[which], "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
return output[which];
}

2423
gencode.c

File diff suppressed because it is too large Load Diff

View File

@ -18,7 +18,7 @@
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* @(#) $Header: /tcpdump/master/libpcap/gencode.h,v 1.60.2.11 2007/06/11 09:52:04 guy Exp $ (LBL)
* @(#) $Header: /tcpdump/master/libpcap/gencode.h,v 1.70.2.1 2007/11/18 02:04:55 guy Exp $ (LBL)
*/
/*
@ -132,6 +132,10 @@
#define Q_DST 2
#define Q_OR 3
#define Q_AND 4
#define Q_ADDR1 5
#define Q_ADDR2 6
#define Q_ADDR3 7
#define Q_ADDR4 8
#define Q_DEFAULT 0
#define Q_UNDEF 255
@ -312,6 +316,9 @@ struct block *gen_pf_reason(int);
struct block *gen_pf_action(int);
struct block *gen_pf_dir(int);
struct block *gen_p80211_type(int, int);
struct block *gen_p80211_fcdir(int);
void bpf_optimize(struct block **);
void bpf_error(const char *, ...)
__attribute__((noreturn, format (printf, 1, 2)));

198
grammar.y
View File

@ -22,7 +22,7 @@
*/
#ifndef lint
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/grammar.y,v 1.86.2.9 2007/09/12 19:17:25 guy Exp $ (LBL)";
"@(#) $Header: /tcpdump/master/libpcap/grammar.y,v 1.99.2.2 2007/11/18 02:04:55 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@ -57,7 +57,8 @@ struct rtentry;
#include <net/pfvar.h>
#include <net/if_pflog.h>
#endif
#include <pcap-namedb.h>
#include "ieee80211.h"
#include <pcap/namedb.h>
#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
@ -67,6 +68,92 @@ struct rtentry;
(q).dir = (d),\
(q).addr = (a)
struct tok {
int v; /* value */
const char *s; /* string */
};
static const struct tok ieee80211_types[] = {
{ IEEE80211_FC0_TYPE_DATA, "data" },
{ IEEE80211_FC0_TYPE_MGT, "mgt" },
{ IEEE80211_FC0_TYPE_MGT, "management" },
{ IEEE80211_FC0_TYPE_CTL, "ctl" },
{ IEEE80211_FC0_TYPE_CTL, "control" },
{ 0, NULL }
};
static const struct tok ieee80211_mgt_subtypes[] = {
{ IEEE80211_FC0_SUBTYPE_ASSOC_REQ, "assocreq" },
{ IEEE80211_FC0_SUBTYPE_ASSOC_REQ, "assoc-req" },
{ IEEE80211_FC0_SUBTYPE_ASSOC_RESP, "assocresp" },
{ IEEE80211_FC0_SUBTYPE_ASSOC_RESP, "assoc-resp" },
{ IEEE80211_FC0_SUBTYPE_REASSOC_REQ, "reassocreq" },
{ IEEE80211_FC0_SUBTYPE_REASSOC_REQ, "reassoc-req" },
{ IEEE80211_FC0_SUBTYPE_REASSOC_RESP, "reassocresp" },
{ IEEE80211_FC0_SUBTYPE_REASSOC_RESP, "reassoc-resp" },
{ IEEE80211_FC0_SUBTYPE_PROBE_REQ, "probereq" },
{ IEEE80211_FC0_SUBTYPE_PROBE_REQ, "probe-req" },
{ IEEE80211_FC0_SUBTYPE_PROBE_RESP, "proberesp" },
{ IEEE80211_FC0_SUBTYPE_PROBE_RESP, "probe-resp" },
{ IEEE80211_FC0_SUBTYPE_BEACON, "beacon" },
{ IEEE80211_FC0_SUBTYPE_ATIM, "atim" },
{ IEEE80211_FC0_SUBTYPE_DISASSOC, "disassoc" },
{ IEEE80211_FC0_SUBTYPE_DISASSOC, "disassociation" },
{ IEEE80211_FC0_SUBTYPE_AUTH, "auth" },
{ IEEE80211_FC0_SUBTYPE_AUTH, "authentication" },
{ IEEE80211_FC0_SUBTYPE_DEAUTH, "deauth" },
{ IEEE80211_FC0_SUBTYPE_DEAUTH, "deauthentication" },
{ 0, NULL }
};
static const struct tok ieee80211_ctl_subtypes[] = {
{ IEEE80211_FC0_SUBTYPE_PS_POLL, "ps-poll" },
{ IEEE80211_FC0_SUBTYPE_RTS, "rts" },
{ IEEE80211_FC0_SUBTYPE_CTS, "cts" },
{ IEEE80211_FC0_SUBTYPE_ACK, "ack" },
{ IEEE80211_FC0_SUBTYPE_CF_END, "cf-end" },
{ IEEE80211_FC0_SUBTYPE_CF_END_ACK, "cf-end-ack" },
{ 0, NULL }
};
static const struct tok ieee80211_data_subtypes[] = {
{ IEEE80211_FC0_SUBTYPE_DATA, "data" },
{ IEEE80211_FC0_SUBTYPE_CF_ACK, "data-cf-ack" },
{ IEEE80211_FC0_SUBTYPE_CF_POLL, "data-cf-poll" },
{ IEEE80211_FC0_SUBTYPE_CF_ACPL, "data-cf-ack-poll" },
{ IEEE80211_FC0_SUBTYPE_NODATA, "null" },
{ IEEE80211_FC0_SUBTYPE_NODATA_CF_ACK, "cf-ack" },
{ IEEE80211_FC0_SUBTYPE_NODATA_CF_POLL, "cf-poll" },
{ IEEE80211_FC0_SUBTYPE_NODATA_CF_ACPL, "cf-ack-poll" },
{ IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_DATA, "qos-data" },
{ IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_CF_ACK, "qos-data-cf-ack" },
{ IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_CF_POLL, "qos-data-cf-poll" },
{ IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_CF_ACPL, "qos-data-cf-ack-poll" },
{ IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_NODATA, "qos" },
{ IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_NODATA_CF_POLL, "qos-cf-poll" },
{ IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_NODATA_CF_ACPL, "qos-cf-ack-poll" },
{ 0, NULL }
};
struct type2tok {
int type;
const struct tok *tok;
};
static const struct type2tok ieee80211_type_subtypes[] = {
{ IEEE80211_FC0_TYPE_MGT, ieee80211_mgt_subtypes },
{ IEEE80211_FC0_TYPE_CTL, ieee80211_ctl_subtypes },
{ IEEE80211_FC0_TYPE_DATA, ieee80211_data_subtypes },
{ 0, NULL }
};
static int
str2tok(const char *str, const struct tok *toks)
{
int i;
for (i = 0; toks[i].s != NULL; i++) {
if (pcap_strcasecmp(toks[i].s, str) == 0)
return (toks[i].v);
}
return (-1);
}
int n_errors = 0;
static struct qual qerr = { Q_UNDEF, Q_UNDEF, Q_UNDEF, Q_UNDEF };
@ -113,6 +200,16 @@ pfaction_to_num(const char *action)
else if (pcap_strcasecmp(action, "drop") == 0 ||
pcap_strcasecmp(action, "block") == 0)
return (PF_DROP);
#if HAVE_PF_NAT_THROUGH_PF_NORDR
else if (pcap_strcasecmp(action, "rdr") == 0)
return (PF_RDR);
else if (pcap_strcasecmp(action, "nat") == 0)
return (PF_NAT);
else if (pcap_strcasecmp(action, "binat") == 0)
return (PF_BINAT);
else if (pcap_strcasecmp(action, "nordr") == 0)
return (PF_NORDR);
#endif
else {
bpf_error("unknown PF action");
/*NOTREACHED*/
@ -124,6 +221,9 @@ pfreason_to_num(const char *reason)
{
bpf_error("libpcap was compiled on a machine without pf support");
/*NOTREACHED*/
/* this is to make the VC compiler happy */
return -1;
}
static int
@ -131,6 +231,9 @@ pfaction_to_num(const char *action)
{
bpf_error("libpcap was compiled on a machine without pf support");
/*NOTREACHED*/
/* this is to make the VC compiler happy */
return -1;
}
#endif /* HAVE_NET_PFVAR_H */
%}
@ -157,7 +260,7 @@ pfaction_to_num(const char *action)
%type <a> arth narth
%type <i> byteop pname pnum relop irelop
%type <blk> and or paren not null prog
%type <rblk> other pfvar
%type <rblk> other pfvar p80211
%type <i> atmtype atmmultitype
%type <blk> atmfield
%type <blk> atmfieldvalue atmvalue atmlistvalue
@ -173,6 +276,7 @@ pfaction_to_num(const char *action)
%token TK_BROADCAST TK_MULTICAST
%token NUM INBOUND OUTBOUND
%token PF_IFNAME PF_RSET PF_RNR PF_SRNR PF_REASON PF_ACTION
%token TYPE SUBTYPE DIR ADDR1 ADDR2 ADDR3 ADDR4
%token LINK
%token GEQ LEQ NEQ
%token ID EID HID HID6 AID
@ -196,7 +300,7 @@ pfaction_to_num(const char *action)
%type <e> EID
%type <e> AID
%type <s> HID HID6
%type <i> NUM action reason
%type <i> NUM action reason type subtype type_subtype dir
%left OR AND
%nonassoc '!'
@ -238,6 +342,14 @@ nid: ID { $$.b = gen_scode($1, $$.q = $<blk>0.q); }
| HID {
/* Decide how to parse HID based on proto */
$$.q = $<blk>0.q;
if ($$.q.addr == Q_PORT)
bpf_error("'port' modifier applied to ip host");
else if ($$.q.addr == Q_PORTRANGE)
bpf_error("'portrange' modifier applied to ip host");
else if ($$.q.addr == Q_PROTO)
bpf_error("'proto' modifier applied to ip host");
else if ($$.q.addr == Q_PROTOCHAIN)
bpf_error("'protochain' modifier applied to ip host");
$$.b = gen_ncode($1, 0, $$.q);
}
| HID6 '/' NUM {
@ -325,6 +437,10 @@ dqual: SRC { $$ = Q_SRC; }
| DST OR SRC { $$ = Q_OR; }
| SRC AND DST { $$ = Q_AND; }
| DST AND SRC { $$ = Q_AND; }
| ADDR1 { $$ = Q_ADDR1; }
| ADDR2 { $$ = Q_ADDR2; }
| ADDR3 { $$ = Q_ADDR3; }
| ADDR4 { $$ = Q_ADDR4; }
;
/* address type qualifiers */
aqual: HOST { $$ = Q_HOST; }
@ -388,6 +504,7 @@ other: pqual TK_BROADCAST { $$ = gen_broadcast($1); }
| PPPOED { $$ = gen_pppoed(); }
| PPPOES { $$ = gen_pppoes(); }
| pfvar { $$ = $1; }
| pqual p80211 { $$ = $2; }
;
pfvar: PF_IFNAME ID { $$ = gen_pf_ifname($2); }
@ -398,6 +515,79 @@ pfvar: PF_IFNAME ID { $$ = gen_pf_ifname($2); }
| PF_ACTION action { $$ = gen_pf_action($2); }
;
p80211: TYPE type SUBTYPE subtype
{ $$ = gen_p80211_type($2 | $4,
IEEE80211_FC0_TYPE_MASK |
IEEE80211_FC0_SUBTYPE_MASK);
}
| TYPE type { $$ = gen_p80211_type($2,
IEEE80211_FC0_TYPE_MASK);
}
| SUBTYPE type_subtype { $$ = gen_p80211_type($2,
IEEE80211_FC0_TYPE_MASK |
IEEE80211_FC0_SUBTYPE_MASK);
}
| DIR dir { $$ = gen_p80211_fcdir($2); }
;
type: NUM
| ID { $$ = str2tok($1, ieee80211_types);
if ($$ == -1)
bpf_error("unknown 802.11 type name");
}
;
subtype: NUM
| ID { const struct tok *types = NULL;
int i;
for (i = 0;; i++) {
if (ieee80211_type_subtypes[i].tok == NULL) {
/* Ran out of types */
bpf_error("unknown 802.11 type");
break;
}
if ($<i>-1 == ieee80211_type_subtypes[i].type) {
types = ieee80211_type_subtypes[i].tok;
break;
}
}
$$ = str2tok($1, types);
if ($$ == -1)
bpf_error("unknown 802.11 subtype name");
}
;
type_subtype: ID { int i;
for (i = 0;; i++) {
if (ieee80211_type_subtypes[i].tok == NULL) {
/* Ran out of types */
bpf_error("unknown 802.11 type name");
break;
}
$$ = str2tok($1, ieee80211_type_subtypes[i].tok);
if ($$ != -1) {
$$ |= ieee80211_type_subtypes[i].type;
break;
}
}
}
;
dir: NUM
| ID { if (pcap_strcasecmp($1, "nods") == 0)
$$ = IEEE80211_FC1_DIR_NODS;
else if (pcap_strcasecmp($1, "tods") == 0)
$$ = IEEE80211_FC1_DIR_TODS;
else if (pcap_strcasecmp($1, "fromds") == 0)
$$ = IEEE80211_FC1_DIR_FROMDS;
else if (pcap_strcasecmp($1, "dstods") == 0)
$$ = IEEE80211_FC1_DIR_DSTODS;
else
bpf_error("unknown 802.11 direction");
}
;
reason: NUM { $$ = $1; }
| ID { $$ = pfreason_to_num($1); }
;

146
ieee80211.h Normal file
View File

@ -0,0 +1,146 @@
/*-
* Copyright (c) 2001 Atsushi Onoe
* Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
* 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. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* Alternatively, this software may be distributed under the terms of the
* GNU General Public License ("GPL") version 2 as published by the Free
* Software Foundation.
*
* 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.
*
* $FreeBSD$
*/
#ifndef _NET80211_IEEE80211_H_
#define _NET80211_IEEE80211_H_
/*
* 802.11 protocol definitions.
*/
#define IEEE80211_FC0_VERSION_MASK 0x03
#define IEEE80211_FC0_VERSION_SHIFT 0
#define IEEE80211_FC0_VERSION_0 0x00
#define IEEE80211_FC0_TYPE_MASK 0x0c
#define IEEE80211_FC0_TYPE_SHIFT 2
#define IEEE80211_FC0_TYPE_MGT 0x00
#define IEEE80211_FC0_TYPE_CTL 0x04
#define IEEE80211_FC0_TYPE_DATA 0x08
#define IEEE80211_FC0_SUBTYPE_MASK 0xf0
#define IEEE80211_FC0_SUBTYPE_SHIFT 4
/* for TYPE_MGT */
#define IEEE80211_FC0_SUBTYPE_ASSOC_REQ 0x00
#define IEEE80211_FC0_SUBTYPE_ASSOC_RESP 0x10
#define IEEE80211_FC0_SUBTYPE_REASSOC_REQ 0x20
#define IEEE80211_FC0_SUBTYPE_REASSOC_RESP 0x30
#define IEEE80211_FC0_SUBTYPE_PROBE_REQ 0x40
#define IEEE80211_FC0_SUBTYPE_PROBE_RESP 0x50
#define IEEE80211_FC0_SUBTYPE_BEACON 0x80
#define IEEE80211_FC0_SUBTYPE_ATIM 0x90
#define IEEE80211_FC0_SUBTYPE_DISASSOC 0xa0
#define IEEE80211_FC0_SUBTYPE_AUTH 0xb0
#define IEEE80211_FC0_SUBTYPE_DEAUTH 0xc0
/* for TYPE_CTL */
#define IEEE80211_FC0_SUBTYPE_PS_POLL 0xa0
#define IEEE80211_FC0_SUBTYPE_RTS 0xb0
#define IEEE80211_FC0_SUBTYPE_CTS 0xc0
#define IEEE80211_FC0_SUBTYPE_ACK 0xd0
#define IEEE80211_FC0_SUBTYPE_CF_END 0xe0
#define IEEE80211_FC0_SUBTYPE_CF_END_ACK 0xf0
/* for TYPE_DATA (bit combination) */
#define IEEE80211_FC0_SUBTYPE_DATA 0x00
#define IEEE80211_FC0_SUBTYPE_CF_ACK 0x10
#define IEEE80211_FC0_SUBTYPE_CF_POLL 0x20
#define IEEE80211_FC0_SUBTYPE_CF_ACPL 0x30
#define IEEE80211_FC0_SUBTYPE_NODATA 0x40
#define IEEE80211_FC0_SUBTYPE_NODATA_CF_ACK 0x50
#define IEEE80211_FC0_SUBTYPE_NODATA_CF_POLL 0x60
#define IEEE80211_FC0_SUBTYPE_NODATA_CF_ACPL 0x70
#define IEEE80211_FC0_SUBTYPE_QOS 0x80
#define IEEE80211_FC0_SUBTYPE_QOS_NULL 0xc0
#define IEEE80211_FC1_DIR_MASK 0x03
#define IEEE80211_FC1_DIR_NODS 0x00 /* STA->STA */
#define IEEE80211_FC1_DIR_TODS 0x01 /* STA->AP */
#define IEEE80211_FC1_DIR_FROMDS 0x02 /* AP ->STA */
#define IEEE80211_FC1_DIR_DSTODS 0x03 /* AP ->AP */
#define IEEE80211_FC1_MORE_FRAG 0x04
#define IEEE80211_FC1_RETRY 0x08
#define IEEE80211_FC1_PWR_MGT 0x10
#define IEEE80211_FC1_MORE_DATA 0x20
#define IEEE80211_FC1_WEP 0x40
#define IEEE80211_FC1_ORDER 0x80
#define IEEE80211_SEQ_FRAG_MASK 0x000f
#define IEEE80211_SEQ_FRAG_SHIFT 0
#define IEEE80211_SEQ_SEQ_MASK 0xfff0
#define IEEE80211_SEQ_SEQ_SHIFT 4
#define IEEE80211_NWID_LEN 32
#define IEEE80211_QOS_TXOP 0x00ff
/* bit 8 is reserved */
#define IEEE80211_QOS_ACKPOLICY 0x60
#define IEEE80211_QOS_ACKPOLICY_S 5
#define IEEE80211_QOS_ESOP 0x10
#define IEEE80211_QOS_ESOP_S 4
#define IEEE80211_QOS_TID 0x0f
#define IEEE80211_MGT_SUBTYPE_NAMES { \
"assoc-req", "assoc-resp", \
"reassoc-req", "reassoc-resp", \
"probe-req", "probe-resp", \
"reserved#6", "reserved#7", \
"beacon", "atim", \
"disassoc", "auth", \
"deauth", "reserved#13", \
"reserved#14", "reserved#15" \
}
#define IEEE80211_CTL_SUBTYPE_NAMES { \
"reserved#0", "reserved#1", \
"reserved#2", "reserved#3", \
"reserved#3", "reserved#5", \
"reserved#6", "reserved#7", \
"reserved#8", "reserved#9", \
"ps-poll", "rts", \
"cts", "ack", \
"cf-end", "cf-end-ack" \
}
#define IEEE80211_DATA_SUBTYPE_NAMES { \
"data", "data-cf-ack", \
"data-cf-poll", "data-cf-ack-poll", \
"null", "cf-ack", \
"cf-poll", "cf-ack-poll", \
"qos-data", "qos-data-cf-ack", \
"qos-data-cf-poll", "qos-data-cf-ack-poll", \
"qos", "reserved#13", \
"qos-cf-poll", "qos-cf-ack-poll" \
}
#define IEEE80211_TYPE_NAMES { "mgt", "ctl", "data", "reserved#4" }
#endif /* _NET80211_IEEE80211_H_ */

67
inet.c
View File

@ -34,7 +34,7 @@
#ifndef lint
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/inet.c,v 1.66.2.6 2007/06/11 09:52:04 guy Exp $ (LBL)";
"@(#) $Header: /tcpdump/master/libpcap/inet.c,v 1.75.2.4 2008-04-20 18:19:24 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@ -356,6 +356,40 @@ add_or_find_if(pcap_if_t **curdev_ret, pcap_if_t **alldevs, const char *name,
return (0);
}
/*
* XXX - on FreeBSDs that support it, should it get the sysctl named
* "dev.{adapter family name}.{adapter unit}.%desc" to get a description
* of the adapter? Note that "dev.an.0.%desc" is "Aironet PC4500/PC4800"
* with my Cisco 350 card, so the name isn't entirely descriptive. The
* "dev.an.0.%pnpinfo" has a better description, although one might argue
* that the problem is really a driver bug - if it can find out that it's
* a Cisco 340 or 350, rather than an old Aironet card, it should use
* that in the description.
*
* Do NetBSD, DragonflyBSD, or OpenBSD support this as well? OpenBSD
* lets you get a description, but it's not generated by the OS, it's
* set with another ioctl that ifconfig supports; we use that to get
* the description in OpenBSD.
*
* In OS X, the System Configuration framework can apparently return
* names in 10.4 and later; it also appears that freedesktop.org's HAL
* offers an "info.product" string, but the HAL specification says
* it "should not be used in any UI" and "subsystem/capability
* specific properties" should be used instead. Using that would
* require that libpcap applications be linked with the frameworks/
* libraries in question, which would be a bit of a pain unless we
* offer, for example, a pkg-config:
*
* http://pkg-config.freedesktop.org/wiki/
*
* script, so applications can just use that script to find out what
* libraries you need to link with when linking with libpcap.
* pkg-config is GPLed; I don't know whether that would prevent its
* use with a BSD-licensed library such as libpcap.
*
* Do any other UN*Xes, or desktop environments support getting a
* description?
*/
int
add_addr_to_iflist(pcap_if_t **alldevs, const char *name, u_int flags,
struct sockaddr *addr, size_t addr_size,
@ -365,9 +399,32 @@ add_addr_to_iflist(pcap_if_t **alldevs, const char *name, u_int flags,
char *errbuf)
{
pcap_if_t *curdev;
char *description = NULL;
pcap_addr_t *curaddr, *prevaddr, *nextaddr;
#ifdef SIOCGIFDESCR
struct ifreq ifrdesc;
char ifdescr[IFDESCRSIZE];
int s;
#endif
if (add_or_find_if(&curdev, alldevs, name, flags, NULL, errbuf) == -1) {
#ifdef SIOCGIFDESCR
/*
* Get the description for the interface.
*/
memset(&ifrdesc, 0, sizeof ifrdesc);
strlcpy(ifrdesc.ifr_name, name, sizeof ifrdesc.ifr_name);
ifrdesc.ifr_data = (caddr_t)&ifdescr;
s = socket(AF_INET, SOCK_DGRAM, 0);
if (s >= 0) {
if (ioctl(s, SIOCGIFDESCR, &ifrdesc) == 0 &&
strlen(ifrdesc.ifr_data) != 0)
description = ifrdesc.ifr_data;
close(s);
}
#endif
if (add_or_find_if(&curdev, alldevs, name, flags, description,
errbuf) == -1) {
/*
* Error - give up.
*/
@ -607,6 +664,12 @@ pcap_lookupnet(device, netp, maskp, errbuf)
#endif
#ifdef HAVE_SEPTEL_API
|| strstr(device, "septel") != NULL
#endif
#ifdef PCAP_SUPPORT_BT
|| strstr(device, "bluetooth") != NULL
#endif
#ifdef PCAP_SUPPORT_USB
|| strstr(device, "usb") != NULL
#endif
) {
*netp = *maskp = 0;

View File

@ -1,43 +0,0 @@
/* @(#) $Header: /tcpdump/master/libpcap/lbl/gnuc.h,v 1.3.1.1 1999/10/07 23:46:41 mcr Exp $ (LBL) */
/* Define __P() macro, if necessary */
#ifndef __P
#if __STDC__
#define __P(protos) protos
#else
#define __P(protos) ()
#endif
#endif
/* inline foo */
#ifdef __GNUC__
#define inline __inline
#else
#define inline
#endif
/*
* Handle new and old "dead" routine prototypes
*
* For example:
*
* __dead void foo(void) __attribute__((volatile));
*
*/
#ifdef __GNUC__
#ifndef __dead
#define __dead volatile
#endif
#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5)
#ifndef __attribute__
#define __attribute__(args)
#endif
#endif
#else
#ifndef __dead
#define __dead
#endif
#ifndef __attribute__
#define __attribute__(args)
#endif
#endif

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*/
/* $Id: snprintf.c,v 1.1 2003/12/15 01:35:05 guy Exp $ */
/* $Id: snprintf.c,v 1.1 2004/04/05 22:43:51 guy Exp $ */
#ifdef HAVE_CONFIG_H
#include <config.h>
@ -39,7 +39,7 @@
#ifndef lint
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/snprintf.c,v 1.1 2003/12/15 01:35:05 guy Exp $";
"@(#) $Header: /tcpdump/master/libpcap/missing/snprintf.c,v 1.1 2004/04/05 22:43:51 guy Exp $";
#endif
#include <stdio.h>

2
mkdep
View File

@ -13,7 +13,7 @@
# @(#)mkdep.sh 5.11 (Berkeley) 5/5/88
#
PATH=/bin:/usr/bin:/usr/ucb:/usr/local:/usr/local/bin
PATH=/bin:/usr/bin:/usr/ucb:/usr/local:/usr/local/bin:/usr/sfw/bin
export PATH
MAKE=Makefile # default makefile name is "Makefile"

View File

@ -24,7 +24,7 @@
#ifndef lint
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/nametoaddr.c,v 1.77.2.4 2007/06/11 09:52:05 guy Exp $ (LBL)";
"@(#) $Header: /tcpdump/master/libpcap/nametoaddr.c,v 1.82.2.1 2008/02/06 10:21:47 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@ -80,7 +80,7 @@ struct rtentry; /* declarations in <net/if.h> */
#include "pcap-int.h"
#include "gencode.h"
#include <pcap-namedb.h>
#include <pcap/namedb.h>
#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
@ -398,7 +398,15 @@ __pcap_atodn(const char *s, bpf_u_int32 *addr)
}
/*
* Convert 's' which has the form "xx:xx:xx:xx:xx:xx" into a new
* Convert 's', which can have the one of the forms:
*
* "xx:xx:xx:xx:xx:xx"
* "xx.xx.xx.xx.xx.xx"
* "xx-xx-xx-xx-xx-xx"
* "xxxx.xxxx.xxxx"
* "xxxxxxxxxxxx"
*
* (or various mixes of ':', '.', and '-') into a new
* ethernet address. Assumes 's' is well formed.
*/
u_char *
@ -410,7 +418,7 @@ pcap_ether_aton(const char *s)
e = ep = (u_char *)malloc(6);
while (*s) {
if (*s == ':')
if (*s == ':' || *s == '.' || *s == '-')
s += 1;
d = xdtoi(*s++);
if (isxdigit((unsigned char)*s)) {

666
net/bpf_filter.c Normal file
View File

@ -0,0 +1,666 @@
/*-
* 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.45.2.1 2008/01/02 04:22:16 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 const struct bpf_insn *pc;
register const 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, that memory accesses are within valid ranges (to the
* extent that this can be checked statically; loads of packet
* data have to be, and are, also checked at run time), and that
* the code terminates with either an accept or reject.
*
* 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)
const struct bpf_insn *f;
int len;
{
u_int i, from;
const struct bpf_insn *p;
if (len < 1)
return 0;
/*
* There's no maximum program length in userland.
*/
#if defined(KERNEL) || defined(_KERNEL)
if (len > BPF_MAXINSNS)
return 0;
#endif
for (i = 0; i < len; ++i) {
p = &f[i];
switch (BPF_CLASS(p->code)) {
/*
* Check that memory operations use valid addresses.
*/
case BPF_LD:
case BPF_LDX:
switch (BPF_MODE(p->code)) {
case BPF_IMM:
break;
case BPF_ABS:
case BPF_IND:
case BPF_MSH:
/*
* There's no maximum packet data size
* in userland. The runtime packet length
* check suffices.
*/
#if defined(KERNEL) || defined(_KERNEL)
/*
* More strict check with actual packet length
* is done runtime.
*/
if (p->k >= bpf_maxbufsize)
return 0;
#endif
break;
case BPF_MEM:
if (p->k >= BPF_MEMWORDS)
return 0;
break;
case BPF_LEN:
break;
default:
return 0;
}
break;
case BPF_ST:
case BPF_STX:
if (p->k >= BPF_MEMWORDS)
return 0;
break;
case BPF_ALU:
switch (BPF_OP(p->code)) {
case BPF_ADD:
case BPF_SUB:
case BPF_MUL:
case BPF_OR:
case BPF_AND:
case BPF_LSH:
case BPF_RSH:
case BPF_NEG:
break;
case BPF_DIV:
/*
* Check for constant division by 0.
*/
if (BPF_RVAL(p->code) == BPF_K && p->k == 0)
return 0;
break;
default:
return 0;
}
break;
case BPF_JMP:
/*
* Check that jumps are within the code block,
* and that unconditional branches don't go
* backwards as a result of an overflow.
* Unconditional branches have a 32-bit offset,
* so they could overflow; we check to make
* sure they don't. Conditional branches have
* an 8-bit offset, and the from address is <=
* BPF_MAXINSNS, and we assume that BPF_MAXINSNS
* is sufficiently small that adding 255 to it
* won't overflow.
*
* We know that len is <= BPF_MAXINSNS, and we
* assume that BPF_MAXINSNS is < the maximum size
* of a u_int, so that i + 1 doesn't overflow.
*
* For userland, we don't know that the from
* or len are <= BPF_MAXINSNS, but we know that
* from <= len, and, except on a 64-bit system,
* it's unlikely that len, if it truly reflects
* the size of the program we've been handed,
* will be anywhere near the maximum size of
* a u_int. We also don't check for backward
* branches, as we currently support them in
* userland for the protochain operation.
*/
from = i + 1;
switch (BPF_OP(p->code)) {
case BPF_JA:
#if defined(KERNEL) || defined(_KERNEL)
if (from + p->k < from || from + p->k >= len)
#else
if (from + p->k >= len)
#endif
return 0;
break;
case BPF_JEQ:
case BPF_JGT:
case BPF_JGE:
case BPF_JSET:
if (from + p->jt >= len || from + p->jf >= len)
return 0;
break;
default:
return 0;
}
break;
case BPF_RET:
break;
case BPF_MISC:
break;
default:
return 0;
}
}
return BPF_CLASS(f[len - 1].code) == BPF_RET;
}

View File

@ -22,7 +22,7 @@
*/
#ifndef lint
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/optimize.c,v 1.85.2.3 2007/09/12 21:29:45 guy Exp $ (LBL)";
"@(#) $Header: /tcpdump/master/libpcap/optimize.c,v 1.90.2.1 2008/01/02 04:22:16 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@ -53,6 +53,10 @@ extern int _w32_ffs (int mask);
#define ffs _w32_ffs
#endif
#if defined(WIN32) && defined (_MSC_VER)
int ffs(int mask);
#endif
/*
* Represents a deleted instruction.
*/
@ -905,6 +909,17 @@ opt_peep(b)
if (b->s.k == 0xffffffff)
JF(b) = JT(b);
}
/*
* If we're comparing against the index register, and the index
* register is a known constant, we can just compare against that
* constant.
*/
val = b->val[X_ATOM];
if (vmap[val].is_const && BPF_SRC(b->s.code) == BPF_X) {
bpf_int32 v = vmap[val].const_val;
b->s.code &= ~BPF_X;
b->s.k = v;
}
/*
* If the accumulator is a known constant, we can compute the
* comparison result.
@ -2276,6 +2291,15 @@ install_bpf_program(pcap_t *p, struct bpf_program *fp)
{
size_t prog_size;
/*
* Validate the program.
*/
if (!bpf_validate(fp->bf_insns, fp->bf_len)) {
snprintf(p->errbuf, sizeof(p->errbuf),
"BPF program is not valid");
return (-1);
}
/*
* Free up any already installed program.
*/

View File

@ -1,65 +0,0 @@
%define prefix /usr
%define version 0.9.4
Summary: packet capture library
Name: libpcap
Version: %version
Release: 1
Group: Development/Libraries
Copyright: BSD
Source: libpcap-0.9.4.tar.gz
BuildRoot: /tmp/%{name}-buildroot
URL: http://www.tcpdump.org
%description
Packet-capture library LIBPCAP 0.9.4
Now maintained by "The Tcpdump Group"
See http://www.tcpdump.org
Please send inquiries/comments/reports to tcpdump-workers@tcpdump.org
%prep
%setup
%post
ldconfig
%build
CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=%prefix
make
%install
rm -rf $RPM_BUILD_ROOT
mkdir -p $RPM_BUILD_ROOT/usr/{lib,include}
mkdir -p $RPM_BUILD_ROOT/usr/share/man
mkdir -p $RPM_BUILD_ROOT/usr/include/net
mkdir -p $RPM_BUILD_ROOT/usr/man/man3
make install DESTDIR=$RPM_BUILD_ROOT mandir=/usr/share/man
cd $RPM_BUILD_ROOT/usr/lib
V1=`echo 0.9.4 | sed 's/\\.[^\.]*$//g'`
V2=`echo 0.9.4 | sed 's/\\.[^\.]*\.[^\.]*$//g'`
ln -sf libpcap.so.0.9.4 libpcap.so.$V1
if test "$V2" -ne "$V1"; then
ln -sf libpcap.so.$V1 libpcap.so.$V2
ln -sf libpcap.so.$V2 libpcap.so
else
ln -sf libpcap.so.$V1 libpcap.so
fi
#install -m 755 -o root libpcap.a $RPM_BUILD_ROOT/usr/lib
#install -m 644 -o root pcap.3 $RPM_BUILD_ROOT/usr/man/man3
#install -m 644 -o root pcap.h $RPM_BUILD_ROOT/usr/include
#install -m 644 -o root pcap-bpf.h $RPM_BUILD_ROOT/usr/include/net
#install -m 644 -o root pcap-namedb.h $RPM_BUILD_ROOT/usr/include
%clean
rm -rf $RPM_BUILD_ROOT
%files
%defattr(-,root,root)
%doc LICENSE CHANGES INSTALL.txt README.linux TODO VERSION CREDITS packaging/pcap.spec
/usr/lib/libpcap.a
/usr/share/man/man3/*
/usr/include/pcap.h
/usr/include/pcap-bpf.h
/usr/include/pcap-namedb.h
/usr/lib/libpcap.so*

View File

@ -15,7 +15,7 @@ URL: http://www.tcpdump.org
Packet-capture library LIBPCAP @VERSION@
Now maintained by "The Tcpdump Group"
See http://www.tcpdump.org
Please send inquiries/comments/reports to tcpdump-workers@tcpdump.org
Please send inquiries/comments/reports to tcpdump-workers@lists.tcpdump.org
%prep
%setup
@ -29,10 +29,6 @@ make
%install
rm -rf $RPM_BUILD_ROOT
mkdir -p $RPM_BUILD_ROOT/usr/{lib,include}
mkdir -p $RPM_BUILD_ROOT/usr/share/man
mkdir -p $RPM_BUILD_ROOT/usr/include/net
mkdir -p $RPM_BUILD_ROOT/usr/man/man3
make install DESTDIR=$RPM_BUILD_ROOT mandir=/usr/share/man
cd $RPM_BUILD_ROOT/usr/lib
V1=`echo @VERSION@ | sed 's/\\.[^\.]*$//g'`
@ -45,12 +41,6 @@ else
ln -sf libpcap.so.$V1 libpcap.so
fi
#install -m 755 -o root libpcap.a $RPM_BUILD_ROOT/usr/lib
#install -m 644 -o root pcap.3 $RPM_BUILD_ROOT/usr/man/man3
#install -m 644 -o root pcap.h $RPM_BUILD_ROOT/usr/include
#install -m 644 -o root pcap-bpf.h $RPM_BUILD_ROOT/usr/include/net
#install -m 644 -o root pcap-namedb.h $RPM_BUILD_ROOT/usr/include
%clean
rm -rf $RPM_BUILD_ROOT
@ -59,7 +49,10 @@ rm -rf $RPM_BUILD_ROOT
%doc LICENSE CHANGES INSTALL.txt README.linux TODO VERSION CREDITS packaging/pcap.spec
/usr/lib/libpcap.a
/usr/share/man/man3/*
/usr/share/man/man5/*
/usr/share/man/man7/*
/usr/include/pcap.h
/usr/include/pcap/*.h
/usr/include/pcap-bpf.h
/usr/include/pcap-namedb.h
/usr/lib/libpcap.so*

1858
pcap-bpf.c

File diff suppressed because it is too large Load Diff

View File

@ -35,800 +35,13 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)bpf.h 7.1 (Berkeley) 5/7/91
* @(#) $Header: /tcpdump/master/libpcap/pcap-bpf.h,v 1.50 2007/04/01 21:43:55 guy Exp $ (LBL)
*/
/*
* For backwards compatibility.
*
* @(#) $Header: /tcpdump/master/libpcap/pcap-bpf.h,v 1.34.2.24 2007/09/19 02:52:12 guy Exp $ (LBL)
* Note to OS vendors: do NOT get rid of this file! Some applications
* might expect to be able to include <pcap-bpf.h>.
*/
/*
* This is libpcap's cut-down version of bpf.h; it includes only
* the stuff needed for the code generator and the userland BPF
* interpreter, and the libpcap APIs for setting filters, etc..
*
* "pcap-bpf.c" will include the native OS version, as it deals with
* the OS's BPF implementation.
*
* XXX - should this all just be moved to "pcap.h"?
*/
#ifndef BPF_MAJOR_VERSION
#ifdef __cplusplus
extern "C" {
#endif
/* BSD style release date */
#define BPF_RELEASE 199606
#ifdef MSDOS /* must be 32-bit */
typedef long bpf_int32;
typedef unsigned long bpf_u_int32;
#else
typedef int bpf_int32;
typedef u_int bpf_u_int32;
#endif
/*
* Alignment macros. BPF_WORDALIGN rounds up to the next
* even multiple of BPF_ALIGNMENT.
*/
#ifndef __NetBSD__
#define BPF_ALIGNMENT sizeof(bpf_int32)
#else
#define BPF_ALIGNMENT sizeof(long)
#endif
#define BPF_WORDALIGN(x) (((x)+(BPF_ALIGNMENT-1))&~(BPF_ALIGNMENT-1))
#define BPF_MAXINSNS 512
#define BPF_MAXBUFSIZE 0x8000
#define BPF_MINBUFSIZE 32
/*
* Structure for "pcap_compile()", "pcap_setfilter()", etc..
*/
struct bpf_program {
u_int bf_len;
struct bpf_insn *bf_insns;
};
/*
* Struct return by BIOCVERSION. This represents the version number of
* the filter language described by the instruction encodings below.
* bpf understands a program iff kernel_major == filter_major &&
* kernel_minor >= filter_minor, that is, if the value returned by the
* running kernel has the same major number and a minor number equal
* equal to or less than the filter being downloaded. Otherwise, the
* results are undefined, meaning an error may be returned or packets
* may be accepted haphazardly.
* It has nothing to do with the source code version.
*/
struct bpf_version {
u_short bv_major;
u_short bv_minor;
};
/* Current version number of filter architecture. */
#define BPF_MAJOR_VERSION 1
#define BPF_MINOR_VERSION 1
/*
* Data-link level type codes.
*
* Do *NOT* add new values to this list without asking
* "tcpdump-workers@tcpdump.org" for a value. Otherwise, you run the
* risk of using a value that's already being used for some other purpose,
* and of having tools that read libpcap-format captures not being able
* to handle captures with your new DLT_ value, with no hope that they
* will ever be changed to do so (as that would destroy their ability
* to read captures using that value for that other purpose).
*/
/*
* These are the types that are the same on all platforms, and that
* have been defined by <net/bpf.h> for ages.
*/
#define DLT_NULL 0 /* BSD loopback encapsulation */
#define DLT_EN10MB 1 /* Ethernet (10Mb) */
#define DLT_EN3MB 2 /* Experimental Ethernet (3Mb) */
#define DLT_AX25 3 /* Amateur Radio AX.25 */
#define DLT_PRONET 4 /* Proteon ProNET Token Ring */
#define DLT_CHAOS 5 /* Chaos */
#define DLT_IEEE802 6 /* 802.5 Token Ring */
#define DLT_ARCNET 7 /* ARCNET, with BSD-style header */
#define DLT_SLIP 8 /* Serial Line IP */
#define DLT_PPP 9 /* Point-to-point Protocol */
#define DLT_FDDI 10 /* FDDI */
/*
* These are types that are different on some platforms, and that
* have been defined by <net/bpf.h> for ages. We use #ifdefs to
* detect the BSDs that define them differently from the traditional
* libpcap <net/bpf.h>
*
* XXX - DLT_ATM_RFC1483 is 13 in BSD/OS, and DLT_RAW is 14 in BSD/OS,
* but I don't know what the right #define is for BSD/OS.
*/
#define DLT_ATM_RFC1483 11 /* LLC-encapsulated ATM */
#ifdef __OpenBSD__
#define DLT_RAW 14 /* raw IP */
#else
#define DLT_RAW 12 /* raw IP */
#endif
/*
* Given that the only OS that currently generates BSD/OS SLIP or PPP
* is, well, BSD/OS, arguably everybody should have chosen its values
* for DLT_SLIP_BSDOS and DLT_PPP_BSDOS, which are 15 and 16, but they
* didn't. So it goes.
*/
#if defined(__NetBSD__) || defined(__FreeBSD__)
#ifndef DLT_SLIP_BSDOS
#define DLT_SLIP_BSDOS 13 /* BSD/OS Serial Line IP */
#define DLT_PPP_BSDOS 14 /* BSD/OS Point-to-point Protocol */
#endif
#else
#define DLT_SLIP_BSDOS 15 /* BSD/OS Serial Line IP */
#define DLT_PPP_BSDOS 16 /* BSD/OS Point-to-point Protocol */
#endif
/*
* 17 is used for DLT_OLD_PFLOG in OpenBSD;
* OBSOLETE: DLT_PFLOG is 117 in OpenBSD now as well. See below.
* 18 is used for DLT_PFSYNC in OpenBSD; don't use it for anything else.
*/
#define DLT_ATM_CLIP 19 /* Linux Classical-IP over ATM */
/*
* Apparently Redback uses this for its SmartEdge 400/800. I hope
* nobody else decided to use it, too.
*/
#define DLT_REDBACK_SMARTEDGE 32
/*
* These values are defined by NetBSD; other platforms should refrain from
* using them for other purposes, so that NetBSD savefiles with link
* types of 50 or 51 can be read as this type on all platforms.
*/
#define DLT_PPP_SERIAL 50 /* PPP over serial with HDLC encapsulation */
#define DLT_PPP_ETHER 51 /* PPP over Ethernet */
/*
* The Axent Raptor firewall - now the Symantec Enterprise Firewall - uses
* a link-layer type of 99 for the tcpdump it supplies. The link-layer
* header has 6 bytes of unknown data, something that appears to be an
* Ethernet type, and 36 bytes that appear to be 0 in at least one capture
* I've seen.
*/
#define DLT_SYMANTEC_FIREWALL 99
/*
* Values between 100 and 103 are used in capture file headers as
* link-layer types corresponding to DLT_ types that differ
* between platforms; don't use those values for new DLT_ new types.
*/
/*
* This value was defined by libpcap 0.5; platforms that have defined
* it with a different value should define it here with that value -
* a link type of 104 in a save file will be mapped to DLT_C_HDLC,
* whatever value that happens to be, so programs will correctly
* handle files with that link type regardless of the value of
* DLT_C_HDLC.
*
* The name DLT_C_HDLC was used by BSD/OS; we use that name for source
* compatibility with programs written for BSD/OS.
*
* libpcap 0.5 defined it as DLT_CHDLC; we define DLT_CHDLC as well,
* for source compatibility with programs written for libpcap 0.5.
*/
#define DLT_C_HDLC 104 /* Cisco HDLC */
#define DLT_CHDLC DLT_C_HDLC
#define DLT_IEEE802_11 105 /* IEEE 802.11 wireless */
/*
* 106 is reserved for Linux Classical IP over ATM; it's like DLT_RAW,
* except when it isn't. (I.e., sometimes it's just raw IP, and
* sometimes it isn't.) We currently handle it as DLT_LINUX_SLL,
* so that we don't have to worry about the link-layer header.)
*/
/*
* Frame Relay; BSD/OS has a DLT_FR with a value of 11, but that collides
* with other values.
* DLT_FR and DLT_FRELAY packets start with the Q.922 Frame Relay header
* (DLCI, etc.).
*/
#define DLT_FRELAY 107
/*
* OpenBSD DLT_LOOP, for loopback devices; it's like DLT_NULL, except
* that the AF_ type in the link-layer header is in network byte order.
*
* DLT_LOOP is 12 in OpenBSD, but that's DLT_RAW in other OSes, so
* we don't use 12 for it in OSes other than OpenBSD.
*/
#ifdef __OpenBSD__
#define DLT_LOOP 12
#else
#define DLT_LOOP 108
#endif
/*
* Encapsulated packets for IPsec; DLT_ENC is 13 in OpenBSD, but that's
* DLT_SLIP_BSDOS in NetBSD, so we don't use 13 for it in OSes other
* than OpenBSD.
*/
#ifdef __OpenBSD__
#define DLT_ENC 13
#else
#define DLT_ENC 109
#endif
/*
* Values between 110 and 112 are reserved for use in capture file headers
* as link-layer types corresponding to DLT_ types that might differ
* between platforms; don't use those values for new DLT_ types
* other than the corresponding DLT_ types.
*/
/*
* This is for Linux cooked sockets.
*/
#define DLT_LINUX_SLL 113
/*
* Apple LocalTalk hardware.
*/
#define DLT_LTALK 114
/*
* Acorn Econet.
*/
#define DLT_ECONET 115
/*
* Reserved for use with OpenBSD ipfilter.
*/
#define DLT_IPFILTER 116
/*
* OpenBSD DLT_PFLOG; DLT_PFLOG is 17 in OpenBSD, but that's DLT_LANE8023
* in SuSE 6.3, so we can't use 17 for it in capture-file headers.
*
* XXX: is there a conflict with DLT_PFSYNC 18 as well?
*/
#ifdef __OpenBSD__
#define DLT_OLD_PFLOG 17
#define DLT_PFSYNC 18
#endif
#define DLT_PFLOG 117
/*
* Registered for Cisco-internal use.
*/
#define DLT_CISCO_IOS 118
/*
* For 802.11 cards using the Prism II chips, with a link-layer
* header including Prism monitor mode information plus an 802.11
* header.
*/
#define DLT_PRISM_HEADER 119
/*
* Reserved for Aironet 802.11 cards, with an Aironet link-layer header
* (see Doug Ambrisko's FreeBSD patches).
*/
#define DLT_AIRONET_HEADER 120
/*
* Reserved for Siemens HiPath HDLC.
*/
#define DLT_HHDLC 121
/*
* This is for RFC 2625 IP-over-Fibre Channel.
*
* This is not for use with raw Fibre Channel, where the link-layer
* header starts with a Fibre Channel frame header; it's for IP-over-FC,
* where the link-layer header starts with an RFC 2625 Network_Header
* field.
*/
#define DLT_IP_OVER_FC 122
/*
* This is for Full Frontal ATM on Solaris with SunATM, with a
* pseudo-header followed by an AALn PDU.
*
* There may be other forms of Full Frontal ATM on other OSes,
* with different pseudo-headers.
*
* If ATM software returns a pseudo-header with VPI/VCI information
* (and, ideally, packet type information, e.g. signalling, ILMI,
* LANE, LLC-multiplexed traffic, etc.), it should not use
* DLT_ATM_RFC1483, but should get a new DLT_ value, so tcpdump
* and the like don't have to infer the presence or absence of a
* pseudo-header and the form of the pseudo-header.
*/
#define DLT_SUNATM 123 /* Solaris+SunATM */
/*
* Reserved as per request from Kent Dahlgren <kent@praesum.com>
* for private use.
*/
#define DLT_RIO 124 /* RapidIO */
#define DLT_PCI_EXP 125 /* PCI Express */
#define DLT_AURORA 126 /* Xilinx Aurora link layer */
/*
* Header for 802.11 plus a number of bits of link-layer information
* including radio information, used by some recent BSD drivers as
* well as the madwifi Atheros driver for Linux.
*/
#define DLT_IEEE802_11_RADIO 127 /* 802.11 plus radiotap radio header */
/*
* Reserved for the TZSP encapsulation, as per request from
* Chris Waters <chris.waters@networkchemistry.com>
* TZSP is a generic encapsulation for any other link type,
* which includes a means to include meta-information
* with the packet, e.g. signal strength and channel
* for 802.11 packets.
*/
#define DLT_TZSP 128 /* Tazmen Sniffer Protocol */
/*
* BSD's ARCNET headers have the source host, destination host,
* and type at the beginning of the packet; that's what's handed
* up to userland via BPF.
*
* Linux's ARCNET headers, however, have a 2-byte offset field
* between the host IDs and the type; that's what's handed up
* to userland via PF_PACKET sockets.
*
* We therefore have to have separate DLT_ values for them.
*/
#define DLT_ARCNET_LINUX 129 /* ARCNET */
/*
* Juniper-private data link types, as per request from
* Hannes Gredler <hannes@juniper.net>. The DLT_s are used
* for passing on chassis-internal metainformation such as
* QOS profiles, etc..
*/
#define DLT_JUNIPER_MLPPP 130
#define DLT_JUNIPER_MLFR 131
#define DLT_JUNIPER_ES 132
#define DLT_JUNIPER_GGSN 133
#define DLT_JUNIPER_MFR 134
#define DLT_JUNIPER_ATM2 135
#define DLT_JUNIPER_SERVICES 136
#define DLT_JUNIPER_ATM1 137
/*
* Apple IP-over-IEEE 1394, as per a request from Dieter Siegmund
* <dieter@apple.com>. The header that's presented is an Ethernet-like
* header:
*
* #define FIREWIRE_EUI64_LEN 8
* struct firewire_header {
* u_char firewire_dhost[FIREWIRE_EUI64_LEN];
* u_char firewire_shost[FIREWIRE_EUI64_LEN];
* u_short firewire_type;
* };
*
* with "firewire_type" being an Ethernet type value, rather than,
* for example, raw GASP frames being handed up.
*/
#define DLT_APPLE_IP_OVER_IEEE1394 138
/*
* Various SS7 encapsulations, as per a request from Jeff Morriss
* <jeff.morriss[AT]ulticom.com> and subsequent discussions.
*/
#define DLT_MTP2_WITH_PHDR 139 /* pseudo-header with various info, followed by MTP2 */
#define DLT_MTP2 140 /* MTP2, without pseudo-header */
#define DLT_MTP3 141 /* MTP3, without pseudo-header or MTP2 */
#define DLT_SCCP 142 /* SCCP, without pseudo-header or MTP2 or MTP3 */
/*
* DOCSIS MAC frames.
*/
#define DLT_DOCSIS 143
/*
* Linux-IrDA packets. Protocol defined at http://www.irda.org.
* Those packets include IrLAP headers and above (IrLMP...), but
* don't include Phy framing (SOF/EOF/CRC & byte stuffing), because Phy
* framing can be handled by the hardware and depend on the bitrate.
* This is exactly the format you would get capturing on a Linux-IrDA
* interface (irdaX), but not on a raw serial port.
* Note the capture is done in "Linux-cooked" mode, so each packet include
* a fake packet header (struct sll_header). This is because IrDA packet
* decoding is dependant on the direction of the packet (incomming or
* outgoing).
* When/if other platform implement IrDA capture, we may revisit the
* issue and define a real DLT_IRDA...
* Jean II
*/
#define DLT_LINUX_IRDA 144
/*
* Reserved for IBM SP switch and IBM Next Federation switch.
*/
#define DLT_IBM_SP 145
#define DLT_IBM_SN 146
/*
* Reserved for private use. If you have some link-layer header type
* that you want to use within your organization, with the capture files
* using that link-layer header type not ever be sent outside your
* organization, you can use these values.
*
* No libpcap release will use these for any purpose, nor will any
* tcpdump release use them, either.
*
* Do *NOT* use these in capture files that you expect anybody not using
* your private versions of capture-file-reading tools to read; in
* particular, do *NOT* use them in products, otherwise you may find that
* people won't be able to use tcpdump, or snort, or Ethereal, or... to
* read capture files from your firewall/intrusion detection/traffic
* monitoring/etc. appliance, or whatever product uses that DLT_ value,
* and you may also find that the developers of those applications will
* not accept patches to let them read those files.
*
* Also, do not use them if somebody might send you a capture using them
* for *their* private type and tools using them for *your* private type
* would have to read them.
*
* Instead, ask "tcpdump-workers@tcpdump.org" for a new DLT_ value,
* as per the comment above, and use the type you're given.
*/
#define DLT_USER0 147
#define DLT_USER1 148
#define DLT_USER2 149
#define DLT_USER3 150
#define DLT_USER4 151
#define DLT_USER5 152
#define DLT_USER6 153
#define DLT_USER7 154
#define DLT_USER8 155
#define DLT_USER9 156
#define DLT_USER10 157
#define DLT_USER11 158
#define DLT_USER12 159
#define DLT_USER13 160
#define DLT_USER14 161
#define DLT_USER15 162
/*
* For future use with 802.11 captures - defined by AbsoluteValue
* Systems to store a number of bits of link-layer information
* including radio information:
*
* http://www.shaftnet.org/~pizza/software/capturefrm.txt
*
* but it might be used by some non-AVS drivers now or in the
* future.
*/
#define DLT_IEEE802_11_RADIO_AVS 163 /* 802.11 plus AVS radio header */
/*
* Juniper-private data link type, as per request from
* Hannes Gredler <hannes@juniper.net>. The DLT_s are used
* for passing on chassis-internal metainformation such as
* QOS profiles, etc..
*/
#define DLT_JUNIPER_MONITOR 164
/*
* Reserved for BACnet MS/TP.
*/
#define DLT_BACNET_MS_TP 165
/*
* Another PPP variant as per request from Karsten Keil <kkeil@suse.de>.
*
* This is used in some OSes to allow a kernel socket filter to distinguish
* between incoming and outgoing packets, on a socket intended to
* supply pppd with outgoing packets so it can do dial-on-demand and
* hangup-on-lack-of-demand; incoming packets are filtered out so they
* don't cause pppd to hold the connection up (you don't want random
* input packets such as port scans, packets from old lost connections,
* etc. to force the connection to stay up).
*
* The first byte of the PPP header (0xff03) is modified to accomodate
* the direction - 0x00 = IN, 0x01 = OUT.
*/
#define DLT_PPP_PPPD 166
/*
* Names for backwards compatibility with older versions of some PPP
* software; new software should use DLT_PPP_PPPD.
*/
#define DLT_PPP_WITH_DIRECTION DLT_PPP_PPPD
#define DLT_LINUX_PPP_WITHDIRECTION DLT_PPP_PPPD
/*
* Juniper-private data link type, as per request from
* Hannes Gredler <hannes@juniper.net>. The DLT_s are used
* for passing on chassis-internal metainformation such as
* QOS profiles, cookies, etc..
*/
#define DLT_JUNIPER_PPPOE 167
#define DLT_JUNIPER_PPPOE_ATM 168
#define DLT_GPRS_LLC 169 /* GPRS LLC */
#define DLT_GPF_T 170 /* GPF-T (ITU-T G.7041/Y.1303) */
#define DLT_GPF_F 171 /* GPF-F (ITU-T G.7041/Y.1303) */
/*
* Requested by Oolan Zimmer <oz@gcom.com> for use in Gcom's T1/E1 line
* monitoring equipment.
*/
#define DLT_GCOM_T1E1 172
#define DLT_GCOM_SERIAL 173
/*
* Juniper-private data link type, as per request from
* Hannes Gredler <hannes@juniper.net>. The DLT_ is used
* for internal communication to Physical Interface Cards (PIC)
*/
#define DLT_JUNIPER_PIC_PEER 174
/*
* Link types requested by Gregor Maier <gregor@endace.com> of Endace
* Measurement Systems. They add an ERF header (see
* http://www.endace.com/support/EndaceRecordFormat.pdf) in front of
* the link-layer header.
*/
#define DLT_ERF_ETH 175 /* Ethernet */
#define DLT_ERF_POS 176 /* Packet-over-SONET */
/*
* Requested by Daniele Orlandi <daniele@orlandi.com> for raw LAPD
* for vISDN (http://www.orlandi.com/visdn/). Its link-layer header
* includes additional information before the LAPD header, so it's
* not necessarily a generic LAPD header.
*/
#define DLT_LINUX_LAPD 177
/*
* Juniper-private data link type, as per request from
* Hannes Gredler <hannes@juniper.net>.
* The DLT_ are used for prepending meta-information
* like interface index, interface name
* before standard Ethernet, PPP, Frelay & C-HDLC Frames
*/
#define DLT_JUNIPER_ETHER 178
#define DLT_JUNIPER_PPP 179
#define DLT_JUNIPER_FRELAY 180
#define DLT_JUNIPER_CHDLC 181
/*
* Multi Link Frame Relay (FRF.16)
*/
#define DLT_MFR 182
/*
* Juniper-private data link type, as per request from
* Hannes Gredler <hannes@juniper.net>.
* The DLT_ is used for internal communication with a
* voice Adapter Card (PIC)
*/
#define DLT_JUNIPER_VP 183
/*
* Arinc 429 frames.
* DLT_ requested by Gianluca Varenni <gianluca.varenni@cacetech.com>.
* Every frame contains a 32bit A429 label.
* More documentation on Arinc 429 can be found at
* http://www.condoreng.com/support/downloads/tutorials/ARINCTutorial.pdf
*/
#define DLT_A429 184
/*
* Arinc 653 Interpartition Communication messages.
* DLT_ requested by Gianluca Varenni <gianluca.varenni@cacetech.com>.
* Please refer to the A653-1 standard for more information.
*/
#define DLT_A653_ICM 185
/*
* USB packets, beginning with a USB setup header; requested by
* Paolo Abeni <paolo.abeni@email.it>.
*/
#define DLT_USB 186
/*
* Bluetooth HCI UART transport layer (part H:4); requested by
* Paolo Abeni.
*/
#define DLT_BLUETOOTH_HCI_H4 187
/*
* IEEE 802.16 MAC Common Part Sublayer; requested by Maria Cruz
* <cruz_petagay@bah.com>.
*/
#define DLT_IEEE802_16_MAC_CPS 188
/*
* USB packets, beginning with a Linux USB header; requested by
* Paolo Abeni <paolo.abeni@email.it>.
*/
#define DLT_USB_LINUX 189
/*
* Controller Area Network (CAN) v. 2.0B packets.
* DLT_ requested by Gianluca Varenni <gianluca.varenni@cacetech.com>.
* Used to dump CAN packets coming from a CAN Vector board.
* More documentation on the CAN v2.0B frames can be found at
* http://www.can-cia.org/downloads/?269
*/
#define DLT_CAN20B 190
/*
* IEEE 802.15.4, with address fields padded, as is done by Linux
* drivers; requested by Juergen Schimmer.
*/
#define DLT_IEEE802_15_4_LINUX 191
/*
* Per Packet Information encapsulated packets.
* DLT_ requested by Gianluca Varenni <gianluca.varenni@cacetech.com>.
*/
#define DLT_PPI 192
/*
* Header for 802.16 MAC Common Part Sublayer plus a radiotap radio header;
* requested by Charles Clancy.
*/
#define DLT_IEEE802_16_MAC_CPS_RADIO 193
/*
* Juniper-private data link type, as per request from
* Hannes Gredler <hannes@juniper.net>.
* The DLT_ is used for internal communication with a
* integrated service module (ISM).
*/
#define DLT_JUNIPER_ISM 194
/*
* IEEE 802.15.4, exactly as it appears in the spec (no padding, no
* nothing); requested by Mikko Saarnivala <mikko.saarnivala@sensinode.com>.
*/
#define DLT_IEEE802_15_4 195
/*
* Various link-layer types, with a pseudo-header, for SITA
* (http://www.sita.aero/); requested by Fulko Hew (fulko.hew@gmail.com).
*/
#define DLT_SITA 196
/*
* Various link-layer types, with a pseudo-header, for Endace DAG cards;
* encapsulates Endace ERF records. Requested by Stephen Donnelly
* <stephen@endace.com>.
*/
#define DLT_ERF 197
/*
* Special header prepended to Ethernet packets when capturing from a
* u10 Networks board. Requested by Phil Mulholland
* <phil@u10networks.com>.
*/
#define DLT_RAIF1 198
/*
* IPMB packet for IPMI, beginning with the I2C slave address, followed
* by the netFn and LUN, etc.. Requested by Chanthy Toeung
* <chanthy.toeung@ca.kontron.com>.
*/
#define DLT_IPMB 199
/*
* Juniper-private data link type, as per request from
* Hannes Gredler <hannes@juniper.net>.
* The DLT_ is used for capturing data on a secure tunnel interface.
*/
#define DLT_JUNIPER_ST 200
/*
* Bluetooth HCI UART transport layer (part H:4), with pseudo-header
* that includes direction information; requested by Paolo Abeni.
*/
#define DLT_BLUETOOTH_HCI_H4_WITH_PHDR 201
/*
* The instruction encodings.
*/
/* instruction classes */
#define BPF_CLASS(code) ((code) & 0x07)
#define BPF_LD 0x00
#define BPF_LDX 0x01
#define BPF_ST 0x02
#define BPF_STX 0x03
#define BPF_ALU 0x04
#define BPF_JMP 0x05
#define BPF_RET 0x06
#define BPF_MISC 0x07
/* ld/ldx fields */
#define BPF_SIZE(code) ((code) & 0x18)
#define BPF_W 0x00
#define BPF_H 0x08
#define BPF_B 0x10
#define BPF_MODE(code) ((code) & 0xe0)
#define BPF_IMM 0x00
#define BPF_ABS 0x20
#define BPF_IND 0x40
#define BPF_MEM 0x60
#define BPF_LEN 0x80
#define BPF_MSH 0xa0
/* alu/jmp fields */
#define BPF_OP(code) ((code) & 0xf0)
#define BPF_ADD 0x00
#define BPF_SUB 0x10
#define BPF_MUL 0x20
#define BPF_DIV 0x30
#define BPF_OR 0x40
#define BPF_AND 0x50
#define BPF_LSH 0x60
#define BPF_RSH 0x70
#define BPF_NEG 0x80
#define BPF_JA 0x00
#define BPF_JEQ 0x10
#define BPF_JGT 0x20
#define BPF_JGE 0x30
#define BPF_JSET 0x40
#define BPF_SRC(code) ((code) & 0x08)
#define BPF_K 0x00
#define BPF_X 0x08
/* ret - BPF_K and BPF_X also apply */
#define BPF_RVAL(code) ((code) & 0x18)
#define BPF_A 0x10
/* misc */
#define BPF_MISCOP(code) ((code) & 0xf8)
#define BPF_TAX 0x00
#define BPF_TXA 0x80
/*
* The instruction data structure.
*/
struct bpf_insn {
u_short code;
u_char jt;
u_char jf;
bpf_int32 k;
};
/*
* Macros for insn array initializers.
*/
#define BPF_STMT(code, k) { (u_short)(code), 0, 0, k }
#define BPF_JUMP(code, k, jt, jf) { (u_short)(code), jt, jf, k }
#if __STDC__ || defined(__cplusplus)
extern int bpf_validate(struct bpf_insn *, int);
extern u_int bpf_filter(struct bpf_insn *, u_char *, u_int, u_int);
#else
extern int bpf_validate();
extern u_int bpf_filter();
#endif
/*
* Number of scratch memory words (for BPF_LD|BPF_MEM and BPF_ST).
*/
#define BPF_MEMWORDS 16
#ifdef __cplusplus
}
#endif
#endif
#include <pcap/bpf.h>

372
pcap-bt-linux.c Normal file
View File

@ -0,0 +1,372 @@
/*
* Copyright (c) 2006 Paolo Abeni (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. 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 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.
*
* Bluetooth sniffing API implementation for Linux platform
* By Paolo Abeni <paolo.abeni@email.it>
*
*/
#ifndef lint
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/pcap-bt-linux.c,v 1.9.2.6 2008-07-01 07:06:37 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "pcap-int.h"
#include "pcap-bt-linux.h"
#include "pcap/bluetooth.h"
#ifdef NEED_STRERROR_H
#include "strerror.h"
#endif
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#define BT_IFACE "bluetooth"
#define BT_CTRL_SIZE 128
/* forward declaration */
static int bt_activate(pcap_t *);
static int bt_read_linux(pcap_t *, int , pcap_handler , u_char *);
static int bt_inject_linux(pcap_t *, const void *, size_t);
static int bt_setfilter_linux(pcap_t *, struct bpf_program *);
static int bt_setdirection_linux(pcap_t *, pcap_direction_t);
static int bt_stats_linux(pcap_t *, struct pcap_stat *);
int
bt_platform_finddevs(pcap_if_t **alldevsp, char *err_str)
{
pcap_if_t *found_dev = *alldevsp;
struct hci_dev_list_req *dev_list;
struct hci_dev_req *dev_req;
int i, sock;
int ret = 0;
sock = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
if (sock < 0)
{
/* if bluetooth is not supported this this is not fatal*/
if (errno == EAFNOSUPPORT)
return 0;
snprintf(err_str, PCAP_ERRBUF_SIZE, "Can't open raw Bluetooth socket %d:%s",
errno, strerror(errno));
return -1;
}
dev_list = malloc(HCI_MAX_DEV * sizeof(*dev_req) + sizeof(*dev_list));
if (!dev_list)
{
snprintf(err_str, PCAP_ERRBUF_SIZE, "Can't allocate %zu bytes for Bluetooth device list",
HCI_MAX_DEV * sizeof(*dev_req) + sizeof(*dev_list));
ret = -1;
goto done;
}
dev_list->dev_num = HCI_MAX_DEV;
if (ioctl(sock, HCIGETDEVLIST, (void *) dev_list) < 0)
{
snprintf(err_str, PCAP_ERRBUF_SIZE, "Can't get Bluetooth device list via ioctl %d:%s",
errno, strerror(errno));
ret = -1;
goto free;
}
dev_req = dev_list->dev_req;
for (i = 0; i < dev_list->dev_num; i++, dev_req++) {
char dev_name[20], dev_descr[30];
snprintf(dev_name, 20, BT_IFACE"%d", dev_req->dev_id);
snprintf(dev_descr, 30, "Bluetooth adapter number %d", i);
if (pcap_add_if(&found_dev, dev_name, 0,
dev_descr, err_str) < 0)
{
ret = -1;
break;
}
}
free:
free(dev_list);
done:
close(sock);
return ret;
}
pcap_t *
bt_create(const char *device, char *ebuf)
{
pcap_t *p;
p = pcap_create_common(device, ebuf);
if (p == NULL)
return (NULL);
p->activate_op = bt_activate;
return (p);
}
static int
bt_activate(pcap_t* handle)
{
struct sockaddr_hci addr;
int opt;
int dev_id;
struct hci_filter flt;
int err = PCAP_ERROR;
/* get bt interface id */
if (sscanf(handle->opt.source, BT_IFACE"%d", &dev_id) != 1)
{
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't get Bluetooth device index from %s",
handle->opt.source);
return PCAP_ERROR;
}
/* Initialize some components of the pcap structure. */
handle->bufsize = handle->snapshot+BT_CTRL_SIZE+sizeof(pcap_bluetooth_h4_header);
handle->offset = BT_CTRL_SIZE;
handle->linktype = DLT_BLUETOOTH_HCI_H4_WITH_PHDR;
handle->read_op = bt_read_linux;
handle->inject_op = bt_inject_linux;
handle->setfilter_op = bt_setfilter_linux;
handle->setdirection_op = bt_setdirection_linux;
handle->set_datalink_op = NULL; /* can't change data link type */
handle->getnonblock_op = pcap_getnonblock_fd;
handle->setnonblock_op = pcap_setnonblock_fd;
handle->stats_op = bt_stats_linux;
handle->md.ifindex = dev_id;
/* Create HCI socket */
handle->fd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
if (handle->fd < 0) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't create raw socket %d:%s",
errno, strerror(errno));
return PCAP_ERROR;
}
handle->buffer = malloc(handle->bufsize);
if (!handle->buffer) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't allocate dump buffer: %s",
pcap_strerror(errno));
goto close_fail;
}
opt = 1;
if (setsockopt(handle->fd, SOL_HCI, HCI_DATA_DIR, &opt, sizeof(opt)) < 0) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't enable data direction info %d:%s",
errno, strerror(errno));
goto close_fail;
}
opt = 1;
if (setsockopt(handle->fd, SOL_HCI, HCI_TIME_STAMP, &opt, sizeof(opt)) < 0) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't enable time stamp %d:%s",
errno, strerror(errno));
goto close_fail;
}
/* Setup filter, do not call hci function to avoid dependence on
* external libs */
memset(&flt, 0, sizeof(flt));
memset((void *) &flt.type_mask, 0xff, sizeof(flt.type_mask));
memset((void *) &flt.event_mask, 0xff, sizeof(flt.event_mask));
if (setsockopt(handle->fd, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't set filter %d:%s",
errno, strerror(errno));
goto close_fail;
}
/* Bind socket to the HCI device */
addr.hci_family = AF_BLUETOOTH;
addr.hci_dev = handle->md.ifindex;
if (bind(handle->fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't attach to device %d %d:%s",
handle->md.ifindex, errno, strerror(errno));
goto close_fail;
}
if (handle->opt.rfmon) {
/*
* Monitor mode doesn't apply to Bluetooth devices.
*/
err = PCAP_ERROR_RFMON_NOTSUP;
goto close_fail;
}
if (handle->opt.buffer_size == 0) {
/*
* Set the socket buffer size to the specified value.
*/
if (setsockopt(handle->fd, SOL_SOCKET, SO_RCVBUF,
&handle->opt.buffer_size,
sizeof(handle->opt.buffer_size)) == -1) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"SO_RCVBUF: %s", pcap_strerror(errno));
goto close_fail;
}
}
handle->selectable_fd = handle->fd;
return 0;
close_fail:
pcap_cleanup_live_common(handle);
return err;
}
static int
bt_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user)
{
struct cmsghdr *cmsg;
struct msghdr msg;
struct iovec iv;
struct pcap_pkthdr pkth;
pcap_bluetooth_h4_header* bthdr;
bthdr = (pcap_bluetooth_h4_header*) &handle->buffer[handle->offset];
iv.iov_base = &handle->buffer[handle->offset+sizeof(pcap_bluetooth_h4_header)];
iv.iov_len = handle->snapshot;
memset(&msg, 0, sizeof(msg));
msg.msg_iov = &iv;
msg.msg_iovlen = 1;
msg.msg_control = handle->buffer;
msg.msg_controllen = handle->offset;
/* ignore interrupt system call error */
do {
pkth.caplen = recvmsg(handle->fd, &msg, 0);
if (handle->break_loop)
{
handle->break_loop = 0;
return -2;
}
} while ((pkth.caplen == -1) && (errno == EINTR));
if (pkth.caplen < 0) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't receive packet %d:%s",
errno, strerror(errno));
return -1;
}
/* get direction and timestamp*/
cmsg = CMSG_FIRSTHDR(&msg);
int in=0;
while (cmsg) {
switch (cmsg->cmsg_type) {
case HCI_CMSG_DIR:
in = *((int *) CMSG_DATA(cmsg));
break;
case HCI_CMSG_TSTAMP:
pkth.ts = *((struct timeval *) CMSG_DATA(cmsg));
break;
}
cmsg = CMSG_NXTHDR(&msg, cmsg);
}
if ((in && (handle->direction == PCAP_D_OUT)) ||
((!in) && (handle->direction == PCAP_D_IN)))
return 0;
bthdr->direction = htonl(in != 0);
pkth.caplen+=sizeof(pcap_bluetooth_h4_header);
pkth.len = pkth.caplen;
callback(user, &pkth, &handle->buffer[handle->offset]);
return 1;
}
static int
bt_inject_linux(pcap_t *handle, const void *buf, size_t size)
{
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "inject not supported on "
"bluetooth devices");
return (-1);
}
static int
bt_stats_linux(pcap_t *handle, struct pcap_stat *stats)
{
int ret;
struct hci_dev_info dev_info;
struct hci_dev_stats * s = &dev_info.stat;
dev_info.dev_id = handle->md.ifindex;
/* ingnore eintr */
do {
ret = ioctl(handle->fd, HCIGETDEVINFO, (void *)&dev_info);
} while ((ret == -1) && (errno == EINTR));
if (ret < 0) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "can get stats"
" via ioctl %d:%s", errno, strerror(errno));
return (-1);
}
/* we receive both rx and tx frames, so comulate all stats */
stats->ps_recv = s->evt_rx + s->acl_rx + s->sco_rx + s->cmd_tx +
s->acl_tx +s->sco_tx;
stats->ps_drop = s->err_rx + s->err_tx;
stats->ps_ifdrop = 0;
return 0;
}
static int
bt_setfilter_linux(pcap_t *p, struct bpf_program *fp)
{
return 0;
}
static int
bt_setdirection_linux(pcap_t *p, pcap_direction_t d)
{
p->direction = d;
return 0;
}

40
pcap-bt-linux.h Normal file
View File

@ -0,0 +1,40 @@
/*
* Copyright (c) 2006 Paolo Abeni (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. 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 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.
*
* Bluetooth sniffing API implementation for Linux platform
* By Paolo Abeni <paolo.abeni@email.it>
*
* @(#) $Header: /tcpdump/master/libpcap/pcap-bt-linux.h,v 1.4.2.1 2008-04-04 19:39:05 guy Exp $ (LBL)
*/
/*
* Prototypes for Bluetooth-related functions
*/
int bt_platform_finddevs(pcap_if_t **alldevsp, char *err_str);
pcap_t *bt_create(const char *device, char *ebuf);

54
pcap-config.1 Normal file
View File

@ -0,0 +1,54 @@
.\" @(#) $Header: /tcpdump/master/libpcap/pcap-config.1,v 1.1.2.2 2008-09-23 18:06:01 guy Exp $ (LBL)
.\"
.\" Copyright (c) 1987, 1988, 1989, 1990, 1991, 1992, 1994, 1995, 1996, 1997
.\" The Regents of the University of California. All rights reserved.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that: (1) source code distributions
.\" retain the above copyright notice and this paragraph in its entirety, (2)
.\" distributions including binary code include the above copyright notice and
.\" this paragraph in its entirety in the documentation or other materials
.\" provided with the distribution, and (3) all advertising materials mentioning
.\" features or use of this software display the following acknowledgement:
.\" ``This product includes software developed by the University of California,
.\" Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
.\" the University nor the names of its contributors may be used to endorse
.\" or promote products derived from this software without specific prior
.\" written permission.
.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\"
.TH PCAP-CONFIG 1 "23 September 2008"
.SH NAME
pcap-config \- write libpcap compiler and linker flags to standard output
.SH SYNOPSIS
.na
.B pcap-config
[
.B \-\-cflags | \-\-libs
]
.ad
.SH DESCRIPTION
.LP
When run with the
.B \-\-cflags
option,
.I pcap-config
writes to the standard output the
.B \-I
compiler flags required to include libpcap's header files.
When run with the
.B \-\-libs
option,
.I pcap-config
writes to the standard output the
.B \-L
and
.B \-l
linker required to link with libpcap, including
.B \-l
flags for libraries required by libpcap.
.SH "SEE ALSO"
pcap(3PCAP)

16
pcap-config.in Normal file
View File

@ -0,0 +1,16 @@
#! /bin/sh
#
# Script to give the appropriate compiler flags and linker flags
# to use when building code that uses libpcap.
#
case "$1" in
--cflags)
echo "-I @includedir@"
;;
--libs)
echo "-L @libdir@ -lpcap @DEPLIBS@"
;;
esac

File diff suppressed because it is too large Load Diff

View File

@ -7,8 +7,94 @@
*
* Author: Richard Littin, Sean Irvine ({richard,sean}@reeltwo.com)
*
* @(#) $Header: /tcpdump/master/libpcap/pcap-dag.h,v 1.3.4.1 2005/07/07 06:56:04 guy Exp $ (LBL)
* @(#) $Header: /tcpdump/master/libpcap/pcap-dag.h,v 1.4.2.3 2008-04-04 19:39:06 guy Exp $ (LBL)
*/
pcap_t *dag_open_live(const char *device, int snaplen, int promisc, int to_ms, char *ebuf);
pcap_t *dag_create(const char *, char *);
int dag_platform_finddevs(pcap_if_t **devlistp, char *errbuf);
#ifndef TYPE_AAL5
#define TYPE_AAL5 4
#endif
#ifndef TYPE_MC_HDLC
#define TYPE_MC_HDLC 5
#endif
#ifndef TYPE_MC_RAW
#define TYPE_MC_RAW 6
#endif
#ifndef TYPE_MC_ATM
#define TYPE_MC_ATM 7
#endif
#ifndef TYPE_MC_RAW_CHANNEL
#define TYPE_MC_RAW_CHANNEL 8
#endif
#ifndef TYPE_MC_AAL5
#define TYPE_MC_AAL5 9
#endif
#ifndef TYPE_COLOR_HDLC_POS
#define TYPE_COLOR_HDLC_POS 10
#endif
#ifndef TYPE_COLOR_ETH
#define TYPE_COLOR_ETH 11
#endif
#ifndef TYPE_MC_AAL2
#define TYPE_MC_AAL2 12
#endif
#ifndef TYPE_IP_COUNTER
#define TYPE_IP_COUNTER 13
#endif
#ifndef TYPE_TCP_FLOW_COUNTER
#define TYPE_TCP_FLOW_COUNTER 14
#endif
#ifndef TYPE_DSM_COLOR_HDLC_POS
#define TYPE_DSM_COLOR_HDLC_POS 15
#endif
#ifndef TYPE_DSM_COLOR_ETH
#define TYPE_DSM_COLOR_ETH 16
#endif
#ifndef TYPE_COLOR_MC_HDLC_POS
#define TYPE_COLOR_MC_HDLC_POS 17
#endif
#ifndef TYPE_AAL2
#define TYPE_AAL2 18
#endif
#ifndef TYPE_COLOR_HASH_POS
#define TYPE_COLOR_HASH_POS 19
#endif
#ifndef TYPE_COLOR_HASH_ETH
#define TYPE_COLOR_HASH_ETH 20
#endif
#ifndef TYPE_INFINIBAND
#define TYPE_INFINIBAND 21
#endif
#ifndef TYPE_IPV4
#define TYPE_IPV4 22
#endif
#ifndef TYPE_IPV6
#define TYPE_IPV6 23
#endif
#ifndef TYPE_PAD
#define TYPE_PAD 48
#endif

View File

@ -22,7 +22,7 @@
* University College London, and subsequently modified by
* Guy Harris (guy@alum.mit.edu), Mark Pizzolato
* <List-tcpdump-workers@subscriptions.pizzolato.net>,
* and Mark C. Brown (mbrown@hp.com).
* Mark C. Brown (mbrown@hp.com), and Sagun Shakya <Sagun.Shakya@Sun.COM>.
*/
/*
@ -70,7 +70,7 @@
#ifndef lint
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/pcap-dlpi.c,v 1.108.2.7 2006/04/04 05:33:02 guy Exp $ (LBL)";
"@(#) $Header: /tcpdump/master/libpcap/pcap-dlpi.c,v 1.116.2.11 2008-04-14 20:41:51 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@ -121,6 +121,7 @@ static const char rcsid[] _U_ =
#endif
#include "pcap-int.h"
#include "dlpisubs.h"
#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
@ -136,33 +137,6 @@ static const char rcsid[] _U_ =
#define MAXDLBUF 8192
#ifdef HAVE_SYS_BUFMOD_H
/*
* Size of a bufmod chunk to pass upstream; that appears to be the biggest
* value to which you can set it, and setting it to that value (which
* is bigger than what appears to be the Solaris default of 8192)
* reduces the number of packet drops.
*/
#define CHUNKSIZE 65536
/*
* Size of the buffer to allocate for packet data we read; it must be
* large enough to hold a chunk.
*/
#define PKTBUFSIZE CHUNKSIZE
#else /* HAVE_SYS_BUFMOD_H */
/*
* Size of the buffer to allocate for packet data we read; this is
* what the value used to be - there's no particular reason why it
* should be tied to MAXDLBUF, but we'll leave it as this for now.
*/
#define PKTBUFSIZE (MAXDLBUF * sizeof(bpf_u_int32))
#endif
/* Forwards */
static char *split_dname(char *, int *, char *);
static int dl_doattach(int, int, char *);
@ -176,6 +150,11 @@ static int dlpromisconreq(int, bpf_u_int32, char *);
static int dlokack(int, const char *, char *, char *);
static int dlinforeq(int, char *);
static int dlinfoack(int, char *, char *);
#ifdef HAVE_DLPI_PASSIVE
static void dlpassive(int, char *);
#endif
#ifdef DL_HP_RAWDLS
static int dlrawdatareq(int, const u_char *, int);
#endif
@ -186,9 +165,6 @@ static char *dlprim(bpf_u_int32);
static char *get_release(bpf_u_int32 *, bpf_u_int32 *, bpf_u_int32 *);
#endif
static int send_request(int, char *, int, char *, char *);
#ifdef HAVE_SYS_BUFMOD_H
static int strioctl(int, int, int, char *);
#endif
#ifdef HAVE_HPUX9
static int dlpi_kread(int, off_t, void *, u_int, char *);
#endif
@ -196,42 +172,6 @@ static int dlpi_kread(int, off_t, void *, u_int, char *);
static int get_dlpi_ppa(int, const char *, int, char *);
#endif
static int
pcap_stats_dlpi(pcap_t *p, struct pcap_stat *ps)
{
/*
* "ps_recv" counts packets handed to the filter, not packets
* that passed the filter. As filtering is done in userland,
* this would not include packets dropped because we ran out
* of buffer space; in order to make this more like other
* platforms (Linux 2.4 and later, BSDs with BPF), where the
* "packets received" count includes packets received but dropped
* due to running out of buffer space, and to keep from confusing
* applications that, for example, compute packet drop percentages,
* we also make it count packets dropped by "bufmod" (otherwise we
* might run the risk of the packet drop count being bigger than
* the received-packet count).
*
* "ps_drop" counts packets dropped by "bufmod" because of
* flow control requirements or resource exhaustion; it doesn't
* count packets dropped by the interface driver, or packets
* dropped upstream. As filtering is done in userland, it counts
* packets regardless of whether they would've passed the filter.
*
* These statistics don't include packets not yet read from
* the kernel by libpcap, but they may include packets not
* yet read from libpcap by the application.
*/
*ps = p->md.stat;
/*
* Add in the drop count, as per the above comment.
*/
ps->ps_recv += ps->ps_drop;
return (0);
}
/* XXX Needed by HP-UX (at least) */
static bpf_u_int32 ctlbuf[MAXDLBUF];
static struct strbuf ctl = {
@ -243,18 +183,10 @@ static struct strbuf ctl = {
static int
pcap_read_dlpi(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
{
register int cc, n, caplen, origlen;
register u_char *bp, *ep, *pk;
register struct bpf_insn *fcode;
#ifdef HAVE_SYS_BUFMOD_H
register struct sb_hdr *sbp;
#ifdef LBL_ALIGN
struct sb_hdr sbhdr;
#endif
#endif
int cc;
u_char *bp;
int flags;
struct strbuf data;
struct pcap_pkthdr pkthdr;
flags = 0;
cc = p->cc;
@ -302,74 +234,7 @@ pcap_read_dlpi(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
} else
bp = p->bp;
/* Loop through packets */
fcode = p->fcode.bf_insns;
ep = bp + cc;
n = 0;
#ifdef HAVE_SYS_BUFMOD_H
while (bp < ep) {
/*
* Has "pcap_breakloop()" been called?
* If so, return immediately - if we haven't read any
* packets, clear the flag and return -2 to indicate
* that we were told to break out of the loop, otherwise
* leave the flag set, so that the *next* call will break
* out of the loop without having read any packets, and
* return the number of packets we've processed so far.
*/
if (p->break_loop) {
if (n == 0) {
p->break_loop = 0;
return (-2);
} else {
p->bp = bp;
p->cc = ep - bp;
return (n);
}
}
#ifdef LBL_ALIGN
if ((long)bp & 3) {
sbp = &sbhdr;
memcpy(sbp, bp, sizeof(*sbp));
} else
#endif
sbp = (struct sb_hdr *)bp;
p->md.stat.ps_drop = sbp->sbh_drops;
pk = bp + sizeof(*sbp);
bp += sbp->sbh_totlen;
origlen = sbp->sbh_origlen;
caplen = sbp->sbh_msglen;
#else
origlen = cc;
caplen = min(p->snapshot, cc);
pk = bp;
bp += caplen;
#endif
++p->md.stat.ps_recv;
if (bpf_filter(fcode, pk, origlen, caplen)) {
#ifdef HAVE_SYS_BUFMOD_H
pkthdr.ts.tv_sec = sbp->sbh_timestamp.tv_sec;
pkthdr.ts.tv_usec = sbp->sbh_timestamp.tv_usec;
#else
(void)gettimeofday(&pkthdr.ts, NULL);
#endif
pkthdr.len = origlen;
pkthdr.caplen = caplen;
/* Insure caplen does not exceed snapshot */
if (pkthdr.caplen > p->snapshot)
pkthdr.caplen = p->snapshot;
(*callback)(user, &pkthdr, pk);
if (++n >= cnt && cnt >= 0) {
p->cc = ep - bp;
p->bp = bp;
return (n);
}
}
#ifdef HAVE_SYS_BUFMOD_H
}
#endif
p->cc = 0;
return (n);
return (pcap_process_pkts(p, callback, user, cnt, bp, cc));
}
static int
@ -449,26 +314,26 @@ pcap_inject_dlpi(pcap_t *p, const void *buf, size_t size)
#endif /* HAVE_SOLARIS */
static void
pcap_close_dlpi(pcap_t *p)
pcap_cleanup_dlpi(pcap_t *p)
{
pcap_close_common(p);
if (p->send_fd >= 0)
if (p->send_fd >= 0) {
close(p->send_fd);
p->send_fd = -1;
}
pcap_cleanup_live_common(p);
}
pcap_t *
pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
char *ebuf)
static int
pcap_activate_dlpi(pcap_t *p)
{
register char *cp;
register pcap_t *p;
int ppa;
#ifdef HAVE_SOLARIS
int isatm = 0;
#endif
register dl_info_ack_t *infop;
#ifdef HAVE_SYS_BUFMOD_H
bpf_u_int32 ss, chunksize;
bpf_u_int32 ss;
#ifdef HAVE_SOLARIS
register char *release;
bpf_u_int32 osmajor, osminor, osmicro;
@ -479,23 +344,15 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
#ifndef HAVE_DEV_DLPI
char dname2[100];
#endif
p = (pcap_t *)malloc(sizeof(*p));
if (p == NULL) {
strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
return (NULL);
}
memset(p, 0, sizeof(*p));
p->fd = -1; /* indicate that it hasn't been opened yet */
p->send_fd = -1;
int status = PCAP_ERROR;
#ifdef HAVE_DEV_DLPI
/*
** Remove any "/dev/" on the front of the device.
*/
cp = strrchr(device, '/');
cp = strrchr(p->opt.source, '/');
if (cp == NULL)
strlcpy(dname, device, sizeof(dname));
strlcpy(dname, p->opt.source, sizeof(dname));
else
strlcpy(dname, cp + 1, sizeof(dname));
@ -503,9 +360,11 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
* Split the device name into a device type name and a unit number;
* chop off the unit number, so "dname" is just a device type name.
*/
cp = split_dname(dname, &ppa, ebuf);
if (cp == NULL)
cp = split_dname(dname, &ppa, p->errbuf);
if (cp == NULL) {
status = PCAP_ERROR_NO_SUCH_DEVICE;
goto bad;
}
*cp = '\0';
/*
@ -521,7 +380,9 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
*/
cp = "/dev/dlpi";
if ((p->fd = open(cp, O_RDWR)) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE,
if (errno == EPERM || errno == EACCES)
status = PCAP_ERROR_PERM_DENIED;
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"%s: %s", cp, pcap_strerror(errno));
goto bad;
}
@ -545,9 +406,11 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
* Get a table of all PPAs for that device, and search that
* table for the specified device type name and unit number.
*/
ppa = get_dlpi_ppa(p->fd, dname, ppa, ebuf);
if (ppa < 0)
ppa = get_dlpi_ppa(p->fd, dname, ppa, p->errbuf);
if (ppa < 0) {
status = ppa;
goto bad;
}
#else
/*
* If the device name begins with "/", assume it begins with
@ -555,19 +418,21 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
* otherwise, concatenate the device directory name and the
* device name.
*/
if (*device == '/')
strlcpy(dname, device, sizeof(dname));
if (*p->opt.source == '/')
strlcpy(dname, p->opt.source, sizeof(dname));
else
snprintf(dname, sizeof(dname), "%s/%s", PCAP_DEV_PREFIX,
device);
p->opt.source);
/*
* Get the unit number, and a pointer to the end of the device
* type name.
*/
cp = split_dname(dname, &ppa, ebuf);
if (cp == NULL)
cp = split_dname(dname, &ppa, p->errbuf);
if (cp == NULL) {
status = PCAP_ERROR_NO_SUCH_DEVICE;
goto bad;
}
/*
* Make a copy of the device pathname, and then remove the unit
@ -579,7 +444,9 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
/* Try device without unit number */
if ((p->fd = open(dname, O_RDWR)) < 0) {
if (errno != ENOENT) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s: %s", dname,
if (errno == EACCES)
status = PCAP_ERROR_PERM_DENIED;
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s", dname,
pcap_strerror(errno));
goto bad;
}
@ -587,10 +454,18 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
/* Try again with unit number */
if ((p->fd = open(dname2, O_RDWR)) < 0) {
if (errno == ENOENT) {
status = PCAP_ERROR_NO_SUCH_DEVICE;
/*
* We just report "No DLPI device found"
* with the device name, so people don't
* get confused and think, for example,
* We provide an error message even
* for this error, for diagnostic
* purposes (so that, for example,
* the app can show the message if the
* user requests it).
*
* In it, we just report "No DLPI device
* found" with the device name, so people
* don't get confused and think, for example,
* that if they can't capture on "lo0"
* on Solaris the fix is to change libpcap
* (or the application that uses it) to
@ -602,10 +477,12 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
* for the loopback interface is just a
* symptom of that inability.
*/
snprintf(ebuf, PCAP_ERRBUF_SIZE,
"%s: No DLPI device found", device);
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"%s: No DLPI device found", p->opt.source);
} else {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s: %s",
if (errno == EACCES)
status = PCAP_ERROR_PERM_DENIED;
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s",
dname2, pcap_strerror(errno));
}
goto bad;
@ -615,13 +492,11 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
}
#endif
p->snapshot = snaplen;
/*
** Attach if "style 2" provider
*/
if (dlinforeq(p->fd, ebuf) < 0 ||
dlinfoack(p->fd, (char *)buf, ebuf) < 0)
if (dlinforeq(p->fd, p->errbuf) < 0 ||
dlinfoack(p->fd, (char *)buf, p->errbuf) < 0)
goto bad;
infop = &((union DL_primitives *)buf)->info_ack;
#ifdef HAVE_SOLARIS
@ -629,16 +504,33 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
isatm = 1;
#endif
if (infop->dl_provider_style == DL_STYLE2) {
if (dl_doattach(p->fd, ppa, ebuf) < 0)
status = dl_doattach(p->fd, ppa, p->errbuf);
if (status < 0)
goto bad;
#ifdef DL_HP_RAWDLS
if (p->send_fd >= 0) {
if (dl_doattach(p->send_fd, ppa, ebuf) < 0)
if (dl_doattach(p->send_fd, ppa, p->errbuf) < 0)
goto bad;
}
#endif
}
if (p->opt.rfmon) {
/*
* This device exists, but we don't support monitor mode
* any platforms that support DLPI.
*/
status = PCAP_ERROR_RFMON_NOTSUP;
goto bad;
}
#ifdef HAVE_DLPI_PASSIVE
/*
* Enable Passive mode to be able to capture on aggregated link.
* Not supported in all Solaris versions.
*/
dlpassive(p->fd, p->errbuf);
#endif
/*
** Bind (defer if using HP-UX 9 or HP-UX 10.20 or later, totally
** skip if using SINIX)
@ -663,15 +555,15 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
** assume the SAP value in a DLPI bind is an LLC SAP for network
** types that use 802.2 LLC).
*/
if ((dlbindreq(p->fd, 1537, ebuf) < 0 &&
dlbindreq(p->fd, 2, ebuf) < 0) ||
dlbindack(p->fd, (char *)buf, ebuf, NULL) < 0)
if ((dlbindreq(p->fd, 1537, p->errbuf) < 0 &&
dlbindreq(p->fd, 2, p->errbuf) < 0) ||
dlbindack(p->fd, (char *)buf, p->errbuf, NULL) < 0)
goto bad;
#elif defined(DL_HP_RAWDLS)
/*
** HP-UX 10.0x and 10.1x.
*/
if (dl_dohpuxbind(p->fd, ebuf) < 0)
if (dl_dohpuxbind(p->fd, p->errbuf) < 0)
goto bad;
if (p->send_fd >= 0) {
/*
@ -679,7 +571,7 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
** set it to -1, so that you can't send but can
** still receive?
*/
if (dl_dohpuxbind(p->send_fd, ebuf) < 0)
if (dl_dohpuxbind(p->send_fd, p->errbuf) < 0)
goto bad;
}
#else /* neither AIX nor HP-UX */
@ -687,8 +579,8 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
** Not Sinix, and neither AIX nor HP-UX - Solaris, and any other
** OS using DLPI.
**/
if (dlbindreq(p->fd, 0, ebuf) < 0 ||
dlbindack(p->fd, (char *)buf, ebuf, NULL) < 0)
if (dlbindreq(p->fd, 0, p->errbuf) < 0 ||
dlbindack(p->fd, (char *)buf, p->errbuf, NULL) < 0)
goto bad;
#endif /* AIX vs. HP-UX vs. other */
#endif /* !HP-UX 9 and !HP-UX 10.20 or later and !SINIX */
@ -702,18 +594,18 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
** help, and may break things.
*/
if (strioctl(p->fd, A_PROMISCON_REQ, 0, NULL) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "A_PROMISCON_REQ: %s",
pcap_strerror(errno));
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"A_PROMISCON_REQ: %s", pcap_strerror(errno));
goto bad;
}
} else
#endif
if (promisc) {
if (p->opt.promisc) {
/*
** Enable promiscuous (not necessary on send FD)
*/
if (dlpromisconreq(p->fd, DL_PROMISC_PHYS, ebuf) < 0 ||
dlokack(p->fd, "promisc_phys", (char *)buf, ebuf) < 0)
if (dlpromisconreq(p->fd, DL_PROMISC_PHYS, p->errbuf) < 0 ||
dlokack(p->fd, "promisc_phys", (char *)buf, p->errbuf) < 0)
goto bad;
/*
@ -722,10 +614,9 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
** HP-UX or SINIX) (Not necessary on send FD)
*/
#if !defined(__hpux) && !defined(sinix)
if (dlpromisconreq(p->fd, DL_PROMISC_MULTI, ebuf) < 0 ||
dlokack(p->fd, "promisc_multi", (char *)buf, ebuf) < 0)
fprintf(stderr,
"WARNING: DL_PROMISC_MULTI failed (%s)\n", ebuf);
if (dlpromisconreq(p->fd, DL_PROMISC_MULTI, p->errbuf) < 0 ||
dlokack(p->fd, "promisc_multi", (char *)buf, p->errbuf) < 0)
status = PCAP_WARNING;
#endif
}
/*
@ -736,17 +627,16 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
#ifndef sinix
if (
#ifdef __hpux
!promisc &&
!p->opt.promisc &&
#endif
#ifdef HAVE_SOLARIS
!isatm &&
#endif
(dlpromisconreq(p->fd, DL_PROMISC_SAP, ebuf) < 0 ||
dlokack(p->fd, "promisc_sap", (char *)buf, ebuf) < 0)) {
(dlpromisconreq(p->fd, DL_PROMISC_SAP, p->errbuf) < 0 ||
dlokack(p->fd, "promisc_sap", (char *)buf, p->errbuf) < 0)) {
/* Not fatal if promisc since the DL_PROMISC_PHYS worked */
if (promisc)
fprintf(stderr,
"WARNING: DL_PROMISC_SAP failed (%s)\n", ebuf);
if (p->opt.promisc)
status = PCAP_WARNING;
else
goto bad;
}
@ -757,7 +647,7 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
** promiscuous options.
*/
#if defined(HAVE_HPUX9) || defined(HAVE_HPUX10_20_OR_LATER)
if (dl_dohpuxbind(p->fd, ebuf) < 0)
if (dl_dohpuxbind(p->fd, p->errbuf) < 0)
goto bad;
/*
** We don't set promiscuous mode on the send FD, but we'll defer
@ -770,7 +660,7 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
** set it to -1, so that you can't send but can
** still receive?
*/
if (dl_dohpuxbind(p->send_fd, ebuf) < 0)
if (dl_dohpuxbind(p->send_fd, p->errbuf) < 0)
goto bad;
}
#endif
@ -780,63 +670,13 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
** XXX - get SAP length and address length as well, for use
** when sending packets.
*/
if (dlinforeq(p->fd, ebuf) < 0 ||
dlinfoack(p->fd, (char *)buf, ebuf) < 0)
if (dlinforeq(p->fd, p->errbuf) < 0 ||
dlinfoack(p->fd, (char *)buf, p->errbuf) < 0)
goto bad;
infop = &((union DL_primitives *)buf)->info_ack;
switch (infop->dl_mac_type) {
case DL_CSMACD:
case DL_ETHER:
p->linktype = DLT_EN10MB;
p->offset = 2;
/*
* This is (presumably) a real Ethernet capture; give it a
* link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so
* that an application can let you choose it, in case you're
* capturing DOCSIS traffic that a Cisco Cable Modem
* Termination System is putting out onto an Ethernet (it
* doesn't put an Ethernet header onto the wire, it puts raw
* DOCSIS frames out on the wire inside the low-level
* Ethernet framing).
*/
p->dlt_list = (u_int *) malloc(sizeof(u_int) * 2);
/*
* If that fails, just leave the list empty.
*/
if (p->dlt_list != NULL) {
p->dlt_list[0] = DLT_EN10MB;
p->dlt_list[1] = DLT_DOCSIS;
p->dlt_count = 2;
}
break;
case DL_FDDI:
p->linktype = DLT_FDDI;
p->offset = 3;
break;
case DL_TPR:
/*
* XXX - what about DL_TPB? Is that Token Bus?
*/
p->linktype = DLT_IEEE802;
p->offset = 2;
break;
#ifdef HAVE_SOLARIS
case DL_IPATM:
p->linktype = DLT_SUNATM;
p->offset = 0; /* works for LANE and LLC encapsulation */
break;
#endif
default:
snprintf(ebuf, PCAP_ERRBUF_SIZE, "unknown mac type %lu",
(unsigned long)infop->dl_mac_type);
if (pcap_process_mactype(p, infop->dl_mac_type) != 0)
goto bad;
}
#ifdef DLIOCRAW
/*
@ -844,93 +684,56 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
** header.
*/
if (strioctl(p->fd, DLIOCRAW, 0, NULL) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "DLIOCRAW: %s",
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "DLIOCRAW: %s",
pcap_strerror(errno));
goto bad;
}
#endif
#ifdef HAVE_SYS_BUFMOD_H
/*
** Another non standard call to get the data nicely buffered
*/
if (ioctl(p->fd, I_PUSH, "bufmod") != 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "I_PUSH bufmod: %s",
pcap_strerror(errno));
goto bad;
}
ss = p->snapshot;
/*
** Now that the bufmod is pushed lets configure it.
**
** There is a bug in bufmod(7). When dealing with messages of
** less than snaplen size it strips data from the beginning not
** the end.
**
** This bug is supposed to be fixed in 5.3.2. Also, there is a
** patch available. Ask for bugid 1149065.
** This bug is fixed in 5.3.2. Also, there is a patch available.
** Ask for bugid 1149065.
*/
ss = snaplen;
#ifdef HAVE_SOLARIS
release = get_release(&osmajor, &osminor, &osmicro);
if (osmajor == 5 && (osminor <= 2 || (osminor == 3 && osmicro < 2)) &&
getenv("BUFMOD_FIXED") == NULL) {
fprintf(stderr,
"WARNING: bufmod is broken in SunOS %s; ignoring snaplen.\n",
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"WARNING: bufmod is broken in SunOS %s; ignoring snaplen.",
release);
ss = 0;
status = PCAP_WARNING;
}
#endif
if (ss > 0 &&
strioctl(p->fd, SBIOCSSNAP, sizeof(ss), (char *)&ss) != 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "SBIOCSSNAP: %s",
pcap_strerror(errno));
#ifdef HAVE_SYS_BUFMOD_H
/* Push and configure bufmod. */
if (pcap_conf_bufmod(p, ss, p->md.timeout) != 0)
goto bad;
}
/*
** Set up the bufmod timeout
*/
if (to_ms != 0) {
struct timeval to;
to.tv_sec = to_ms / 1000;
to.tv_usec = (to_ms * 1000) % 1000000;
if (strioctl(p->fd, SBIOCSTIME, sizeof(to), (char *)&to) != 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "SBIOCSTIME: %s",
pcap_strerror(errno));
goto bad;
}
}
/*
** Set the chunk length.
*/
chunksize = CHUNKSIZE;
if (strioctl(p->fd, SBIOCSCHUNK, sizeof(chunksize), (char *)&chunksize)
!= 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "SBIOCSCHUNKP: %s",
pcap_strerror(errno));
goto bad;
}
#endif
/*
** As the last operation flush the read side.
*/
if (ioctl(p->fd, I_FLUSH, FLUSHR) != 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "FLUSHR: %s",
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "FLUSHR: %s",
pcap_strerror(errno));
goto bad;
}
/* Allocate data buffer */
p->bufsize = PKTBUFSIZE;
p->buffer = (u_char *)malloc(p->bufsize + p->offset);
if (p->buffer == NULL) {
strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
/* Allocate data buffer. */
if (pcap_alloc_databuf(p) != 0)
goto bad;
}
/* Success - but perhaps with a warning */
if (status < 0)
status = 0;
/*
* "p->fd" is an FD for a STREAMS device, so "select()" and
@ -946,21 +749,12 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
p->getnonblock_op = pcap_getnonblock_fd;
p->setnonblock_op = pcap_setnonblock_fd;
p->stats_op = pcap_stats_dlpi;
p->close_op = pcap_close_dlpi;
p->cleanup_op = pcap_cleanup_dlpi;
return (p);
return (status);
bad:
if (p->fd >= 0)
close(p->fd);
if (p->send_fd >= 0)
close(p->send_fd);
/*
* Get rid of any link-layer type list we allocated.
*/
if (p->dlt_list != NULL)
free(p->dlt_list);
free(p);
return (NULL);
pcap_cleanup_dlpi(p);
return (status);
}
/*
@ -1016,10 +810,13 @@ static int
dl_doattach(int fd, int ppa, char *ebuf)
{
bpf_u_int32 buf[MAXDLBUF];
int err;
if (dlattachreq(fd, ppa, ebuf) < 0 ||
dlokack(fd, "attach", (char *)buf, ebuf) < 0)
return (-1);
if (dlattachreq(fd, ppa, ebuf) < 0)
return (PCAP_ERROR);
err = dlokack(fd, "attach", (char *)buf, ebuf);
if (err < 0)
return (err);
return (0);
}
@ -1159,7 +956,7 @@ recv_ack(int fd, int size, const char *what, char *bufp, char *ebuf, int *uerror
if (getmsg(fd, &ctl, (struct strbuf*)NULL, &flags) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "recv_ack: %s getmsg: %s",
what, pcap_strerror(errno));
return (-1);
return (PCAP_ERROR);
}
dlp = (union DL_primitives *) ctl.buf;
@ -1183,27 +980,33 @@ recv_ack(int fd, int size, const char *what, char *bufp, char *ebuf, int *uerror
snprintf(ebuf, PCAP_ERRBUF_SIZE,
"recv_ack: %s: UNIX error - %s",
what, pcap_strerror(dlp->error_ack.dl_unix_errno));
if (dlp->error_ack.dl_unix_errno == EACCES)
return (PCAP_ERROR_PERM_DENIED);
break;
default:
snprintf(ebuf, PCAP_ERRBUF_SIZE, "recv_ack: %s: %s",
what, dlstrerror(dlp->error_ack.dl_errno));
if (dlp->error_ack.dl_errno == DL_BADPPA)
return (PCAP_ERROR_NO_SUCH_DEVICE);
else if (dlp->error_ack.dl_errno == DL_ACCESS)
return (PCAP_ERROR_PERM_DENIED);
break;
}
return (-1);
return (PCAP_ERROR);
default:
snprintf(ebuf, PCAP_ERRBUF_SIZE,
"recv_ack: %s: Unexpected primitive ack %s",
what, dlprim(dlp->dl_primitive));
return (-1);
return (PCAP_ERROR);
}
if (ctl.len < size) {
snprintf(ebuf, PCAP_ERRBUF_SIZE,
"recv_ack: %s: Ack too small (%d < %d)",
what, ctl.len, size);
return (-1);
return (PCAP_ERROR);
}
return (ctl.len);
}
@ -1486,6 +1289,24 @@ dlinfoack(int fd, char *bufp, char *ebuf)
return (recv_ack(fd, DL_INFO_ACK_SIZE, "info", bufp, ebuf, NULL));
}
#ifdef HAVE_DLPI_PASSIVE
/*
* Enable DLPI passive mode. We do not care if this request fails, as this
* indicates the underlying DLPI device does not support link aggregation.
*/
static void
dlpassive(int fd, char *ebuf)
{
dl_passive_req_t req;
bpf_u_int32 buf[MAXDLBUF];
req.dl_primitive = DL_PASSIVE_REQ;
if (send_request(fd, (char *)&req, sizeof(req), "dlpassive", ebuf) == 0)
(void) dlokack(fd, "dlpassive", (char *)buf, ebuf);
}
#endif
#ifdef DL_HP_RAWDLS
/*
* There's an ack *if* there's an error.
@ -1522,26 +1343,6 @@ dlrawdatareq(int fd, const u_char *datap, int datalen)
}
#endif /* DL_HP_RAWDLS */
#ifdef HAVE_SYS_BUFMOD_H
static int
strioctl(int fd, int cmd, int len, char *dp)
{
struct strioctl str;
int rc;
str.ic_cmd = cmd;
str.ic_timout = -1;
str.ic_len = len;
str.ic_dp = dp;
rc = ioctl(fd, I_STR, &str);
if (rc < 0)
return (rc);
else
return (str.ic_len);
}
#endif
#if defined(HAVE_SOLARIS) && defined(HAVE_SYS_BUFMOD_H)
static char *
get_release(bpf_u_int32 *majorp, bpf_u_int32 *minorp, bpf_u_int32 *microp)
@ -1631,7 +1432,7 @@ get_dlpi_ppa(register int fd, register const char *device, register int unit,
memset((char *)buf, 0, sizeof(buf));
if (send_request(fd, (char *)&req, sizeof(req), "hpppa", ebuf) < 0)
return (-1);
return (PCAP_ERROR);
ctl.maxlen = DL_HP_PPA_ACK_SIZE;
ctl.len = 0;
@ -1654,7 +1455,7 @@ get_dlpi_ppa(register int fd, register const char *device, register int unit,
if (getmsg(fd, &ctl, (struct strbuf *)NULL, &flags) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE,
"get_dlpi_ppa: hpppa getmsg: %s", pcap_strerror(errno));
return (-1);
return (PCAP_ERROR);
}
dlp = (dl_hp_ppa_ack_t *)ctl.buf;
@ -1662,21 +1463,21 @@ get_dlpi_ppa(register int fd, register const char *device, register int unit,
snprintf(ebuf, PCAP_ERRBUF_SIZE,
"get_dlpi_ppa: hpppa unexpected primitive ack 0x%x",
(bpf_u_int32)dlp->dl_primitive);
return (-1);
return (PCAP_ERROR);
}
if (ctl.len < DL_HP_PPA_ACK_SIZE) {
snprintf(ebuf, PCAP_ERRBUF_SIZE,
"get_dlpi_ppa: hpppa ack too small (%d < %lu)",
ctl.len, (unsigned long)DL_HP_PPA_ACK_SIZE);
return (-1);
return (PCAP_ERROR);
}
/* allocate buffer */
if ((ppa_data_buf = (char *)malloc(dlp->dl_length)) == NULL) {
snprintf(ebuf, PCAP_ERRBUF_SIZE,
"get_dlpi_ppa: hpppa malloc: %s", pcap_strerror(errno));
return (-1);
return (PCAP_ERROR);
}
ctl.maxlen = dlp->dl_length;
ctl.len = 0;
@ -1686,14 +1487,14 @@ get_dlpi_ppa(register int fd, register const char *device, register int unit,
snprintf(ebuf, PCAP_ERRBUF_SIZE,
"get_dlpi_ppa: hpppa getmsg: %s", pcap_strerror(errno));
free(ppa_data_buf);
return (-1);
return (PCAP_ERROR);
}
if (ctl.len < dlp->dl_length) {
snprintf(ebuf, PCAP_ERRBUF_SIZE,
"get_dlpi_ppa: hpppa ack too small (%d < %d)",
ctl.len, dlp->dl_length);
free(ppa_data_buf);
return (-1);
return (PCAP_ERROR);
}
ap = (dl_hp_ppa_ack_t *)buf;
@ -1750,7 +1551,7 @@ get_dlpi_ppa(register int fd, register const char *device, register int unit,
if (stat(dname, &statbuf) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "stat: %s: %s",
dname, pcap_strerror(errno));
return (-1);
return (PCAP_ERROR);
}
majdev = major(statbuf.st_rdev);
@ -1767,13 +1568,13 @@ get_dlpi_ppa(register int fd, register const char *device, register int unit,
if (i == ap->dl_count) {
snprintf(ebuf, PCAP_ERRBUF_SIZE,
"can't find /dev/dlpi PPA for %s%d", device, unit);
return (-1);
return (PCAP_ERROR_NO_SUCH_DEVICE);
}
if (ip->dl_hdw_state == HDW_DEAD) {
snprintf(ebuf, PCAP_ERRBUF_SIZE,
"%s%d: hardware state: DOWN\n", device, unit);
free(ppa_data_buf);
return (-1);
return (PCAP_ERROR);
}
ppa = ip->dl_ppa;
free(ppa_data_buf);
@ -1871,3 +1672,18 @@ dlpi_kread(register int fd, register off_t addr,
return (cc);
}
#endif
pcap_t *
pcap_create(const char *device, char *ebuf)
{
pcap_t *p;
p = pcap_create_common(device, ebuf);
if (p == NULL)
return (NULL);
p->send_fd = -1; /* it hasn't been opened yet */
p->activate_op = pcap_activate_dlpi;
return (p);
}

View File

@ -1,11 +1,11 @@
/*
* This file is part of DOS-libpcap
* Ported to DOS/DOSX by G. Vanem <giva@bgnett.no>
* Ported to DOS/DOSX by G. Vanem <gvanem@broadpark.no>
*
* pcap-dos.c: Interface to PKTDRVR, NDIS2 and 32-bit pmode
* network drivers.
*
* @(#) $Header: /tcpdump/master/libpcap/pcap-dos.c,v 1.1.2.1 2005/05/03 18:54:35 guy Exp $ (LBL)
* @(#) $Header: /tcpdump/master/libpcap/pcap-dos.c,v 1.2.2.5 2008-04-22 17:16:49 guy Exp $ (LBL)
*/
#include <stdio.h>
@ -97,9 +97,10 @@ static volatile BOOL exc_occured = 0;
static struct device *handle_to_device [20];
static int pcap_activate_dos (pcap_t *p);
static int pcap_read_dos (pcap_t *p, int cnt, pcap_handler callback,
u_char *data);
static void pcap_close_dos (pcap_t *p);
static void pcap_cleanup_dos (pcap_t *p);
static int pcap_stats_dos (pcap_t *p, struct pcap_stat *ps);
static int pcap_sendpacket_dos (pcap_t *p, const void *buf, size_t len);
static int pcap_setfilter_dos (pcap_t *p, struct bpf_program *fp);
@ -142,59 +143,64 @@ static struct device *get_device (int fd)
return handle_to_device [fd-1];
}
pcap_t *pcap_create (const char *device, char *ebuf)
{
pcap_t *p;
p = pcap_create_common(device, ebuf);
if (p == NULL)
return (NULL);
p->activate_op = pcap_activate_dos;
return (p);
}
/*
* Open MAC-driver with name 'device_name' for live capture of
* network packets.
*/
pcap_t *pcap_open_live (const char *device_name, int snaplen, int promisc,
int timeout_ms, char *errbuf)
static int pcap_activate_dos (pcap_t *pcap)
{
struct pcap *pcap;
if (snaplen < ETH_MIN)
snaplen = ETH_MIN;
if (snaplen > ETH_MAX) /* silently accept and truncate large MTUs */
snaplen = ETH_MAX;
pcap = calloc (sizeof(*pcap), 1);
if (!pcap)
{
strcpy (errbuf, "Not enough memory (pcap)");
return (NULL);
if (pcap->opt.rfmon) {
/*
* No monitor mode on DOS.
*/
return (PCAP_ERROR_RFMON_NOTSUP);
}
pcap->snapshot = max (ETH_MIN+8, snaplen);
if (pcap->snapshot < ETH_MIN+8)
pcap->snapshot = ETH_MIN+8;
if (pcap->snapshot > ETH_MAX) /* silently accept and truncate large MTUs */
pcap->snapshot = ETH_MAX;
pcap->linktype = DLT_EN10MB; /* !! */
pcap->inter_packet_wait = timeout_ms;
pcap->close_op = pcap_close_dos;
pcap->cleanup_op = pcap_cleanup_dos;
pcap->read_op = pcap_read_dos;
pcap->stats_op = pcap_stats_dos;
pcap->inject_op = pcap_sendpacket_dos;
pcap->setfilter_op = pcap_setfilter_dos;
pcap->setdirection_op = NULL; /* Not implemented.*/
pcap->setdirection_op = NULL; /* Not implemented.*/
pcap->fd = ++ref_count;
if (pcap->fd == 1) /* first time we're called */
{
if (!init_watt32(pcap, device_name, errbuf) ||
!first_init(device_name, errbuf, promisc))
if (!init_watt32(pcap, pcap->opt.source, pcap->errbuf) ||
!first_init(pcap->opt.source, pcap->errbuf, pcap->opt.promisc))
{
free (pcap);
return (NULL);
return (PCAP_ERROR);
}
atexit (close_driver);
}
else if (stricmp(active_dev->name,device_name))
else if (stricmp(active_dev->name,pcap->opt.source))
{
snprintf (errbuf, PCAP_ERRBUF_SIZE,
snprintf (pcap->errbuf, PCAP_ERRBUF_SIZE,
"Cannot use different devices simultaneously "
"(`%s' vs. `%s')", active_dev->name, device_name);
free (pcap);
pcap = NULL;
"(`%s' vs. `%s')", active_dev->name, pcap->opt.source);
return (PCAP_ERROR);
}
handle_to_device [pcap->fd-1] = active_dev;
return (pcap);
return (0);
}
/*
@ -205,15 +211,14 @@ static int
pcap_read_one (pcap_t *p, pcap_handler callback, u_char *data)
{
struct pcap_pkthdr pcap;
struct bpf_insn *fcode = p->fcode.bf_insns;
struct timeval now, expiry;
BYTE *rx_buf;
int rx_len = 0;
if (p->inter_packet_wait > 0)
if (p->md.timeout > 0)
{
gettimeofday2 (&now, NULL);
expiry.tv_usec = now.tv_usec + 1000UL * p->inter_packet_wait;
expiry.tv_usec = now.tv_usec + 1000UL * p->md.timeout;
expiry.tv_sec = now.tv_sec;
while (expiry.tv_usec >= 1000000L)
{
@ -258,7 +263,7 @@ pcap_read_one (pcap_t *p, pcap_handler callback, u_char *data)
pcap.len = rx_len;
if (callback &&
(!fcode || bpf_filter(fcode, rx_buf, pcap.len, pcap.caplen)))
(!p->fcode.bf_insns || bpf_filter(p->fcode.bf_insns, rx_buf, pcap.len, pcap.caplen)))
{
filter_count++;
@ -285,7 +290,7 @@ pcap_read_one (pcap_t *p, pcap_handler callback, u_char *data)
/* If not to wait for a packet or pcap_close() called from
* e.g. SIGINT handler, exit loop now.
*/
if (p->inter_packet_wait <= 0 || (volatile int)p->fd <= 0)
if (p->md.timeout <= 0 || (volatile int)p->fd <= 0)
break;
gettimeofday2 (&now, NULL);
@ -421,7 +426,7 @@ u_long pcap_filter_packets (void)
/*
* Close pcap device. Not called for offline captures.
*/
static void pcap_close_dos (pcap_t *p)
static void pcap_cleanup_dos (pcap_t *p)
{
if (p && !exc_occured)
{
@ -477,7 +482,7 @@ int pcap_lookupnet (const char *device, bpf_u_int32 *localnet,
{
if (!_watt_is_init)
{
strcpy (errbuf, "pcap_open_offline() or pcap_open_live() must be "
strcpy (errbuf, "pcap_open_offline() or pcap_activate() must be "
"called first");
return (-1);
}
@ -588,7 +593,7 @@ void pcap_set_wait (pcap_t *p, void (*yield)(void), int wait)
if (p)
{
p->wait_proc = yield;
p->inter_packet_wait = wait;
p->md.timeout = wait;
}
}
@ -734,13 +739,13 @@ static void exc_handler (int sig)
fprintf (stderr, "Catching signal %d.\n", sig);
}
exc_occured = 1;
pcap_close_dos (NULL);
pcap_cleanup_dos (NULL);
}
#endif /* __DJGPP__ */
/*
* Open the pcap device for the first client calling pcap_open_live()
* Open the pcap device for the first client calling pcap_activate()
*/
static int first_init (const char *name, char *ebuf, int promisc)
{
@ -991,7 +996,7 @@ int EISA_bus = 0; /* Where is natural place for this? */
* Application config hooks to set various driver parameters.
*/
static struct config_table debug_tab[] = {
static const struct config_table debug_tab[] = {
{ "PKT.DEBUG", ARG_ATOI, &pcap_pkt_debug },
{ "PKT.VECTOR", ARG_ATOX_W, NULL },
{ "NDIS.DEBUG", ARG_ATOI, NULL },

View File

@ -8,7 +8,7 @@
*/
#ifndef lint
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/pcap-enet.c,v 1.8 2003/11/15 23:24:02 guy Exp $";
"@(#) $Header: /tcpdump/master/libpcap/pcap-enet.c,v 1.9 2006/10/04 18:09:22 guy Exp $";
#endif
#ifdef HAVE_CONFIG_H
@ -22,7 +22,7 @@ static const char rcsid[] _U_ =
#include <sys/socket.h>
#include <net/if.h>
#include <pcap-bpf.h>
#include <pcap/bpf.h>
#include <net/enet.h>
#include <netinet/in.h>

949
pcap-filter.manmisc.in Normal file
View File

@ -0,0 +1,949 @@
.\" @(#) $Header: /tcpdump/master/libpcap/pcap-filter.manmisc.in,v 1.1.2.2 2008-10-21 07:44:56 guy Exp $ (LBL)
.\"
.\" Copyright (c) 1987, 1988, 1989, 1990, 1991, 1992, 1994, 1995, 1996, 1997
.\" The Regents of the University of California. All rights reserved.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that: (1) source code distributions
.\" retain the above copyright notice and this paragraph in its entirety, (2)
.\" distributions including binary code include the above copyright notice and
.\" this paragraph in its entirety in the documentation or other materials
.\" provided with the distribution, and (3) all advertising materials mentioning
.\" features or use of this software display the following acknowledgement:
.\" ``This product includes software developed by the University of California,
.\" Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
.\" the University nor the names of its contributors may be used to endorse
.\" or promote products derived from this software without specific prior
.\" written permission.
.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\"
.TH PCAP-FILTER @MAN_MISC_INFO@ "6 January 2008"
.SH NAME
pcap-filter \- packet filter syntax
.br
.ad
.SH DESCRIPTION
.LP
.B pcap_compile()
is used to compile a string into a filter program.
The resulting filter program can then be applied to
some stream of packets to determine which packets will be supplied to
.BR pcap_loop() ,
.BR pcap_dispatch() ,
.BR pcap_next() ,
or
.BR pcap_next_ex() .
.LP
The \fIfilter expression\fP consists of one or more
.IR primitives .
Primitives usually consist of an
.I id
(name or number) preceded by one or more qualifiers.
There are three
different kinds of qualifier:
.IP \fItype\fP
qualifiers say what kind of thing the id name or number refers to.
Possible types are
.BR host ,
.B net ,
.B port
and
.BR portrange .
E.g., `host foo', `net 128.3', `port 20', `portrange 6000-6008'.
If there is no type
qualifier,
.B host
is assumed.
.IP \fIdir\fP
qualifiers specify a particular transfer direction to and/or from
.IR id .
Possible directions are
.BR src ,
.BR dst ,
.BR "src or dst" ,
.BR "src and dst" ,
.BR addr1 ,
.BR addr2 ,
.BR addr3 ,
and
.BR addr4 .
E.g., `src foo', `dst net 128.3', `src or dst port ftp-data'.
If
there is no dir qualifier,
.B "src or dst"
is assumed.
The
.BR addr1 ,
.BR addr2 ,
.BR addr3 ,
and
.B addr4
qualifiers are only valid for IEEE 802.11 Wireless LAN link layers.
For some link layers, such as SLIP and the ``cooked'' Linux capture mode
used for the ``any'' device and for some other device types, the
.B inbound
and
.B outbound
qualifiers can be used to specify a desired direction.
.IP \fIproto\fP
qualifiers restrict the match to a particular protocol.
Possible
protos are:
.BR ether ,
.BR fddi ,
.BR tr ,
.BR wlan ,
.BR ip ,
.BR ip6 ,
.BR arp ,
.BR rarp ,
.BR decnet ,
.B tcp
and
.BR udp .
E.g., `ether src foo', `arp net 128.3', `tcp port 21', `udp portrange
7000-7009', `wlan addr2 0:2:3:4:5:6'.
If there is
no proto qualifier, all protocols consistent with the type are
assumed.
E.g., `src foo' means `(ip or arp or rarp) src foo'
(except the latter is not legal syntax), `net bar' means `(ip or
arp or rarp) net bar' and `port 53' means `(tcp or udp) port 53'.
.LP
[`fddi' is actually an alias for `ether'; the parser treats them
identically as meaning ``the data link level used on the specified
network interface.'' FDDI headers contain Ethernet-like source
and destination addresses, and often contain Ethernet-like packet
types, so you can filter on these FDDI fields just as with the
analogous Ethernet fields.
FDDI headers also contain other fields,
but you cannot name them explicitly in a filter expression.
.LP
Similarly, `tr' and `wlan' are aliases for `ether'; the previous
paragraph's statements about FDDI headers also apply to Token Ring
and 802.11 wireless LAN headers. For 802.11 headers, the destination
address is the DA field and the source address is the SA field; the
BSSID, RA, and TA fields aren't tested.]
.LP
In addition to the above, there are some special `primitive' keywords
that don't follow the pattern:
.BR gateway ,
.BR broadcast ,
.BR less ,
.B greater
and arithmetic expressions.
All of these are described below.
.LP
More complex filter expressions are built up by using the words
.BR and ,
.B or
and
.B not
to combine primitives.
E.g., `host foo and not port ftp and not port ftp-data'.
To save typing, identical qualifier lists can be omitted.
E.g.,
`tcp dst port ftp or ftp-data or domain' is exactly the same as
`tcp dst port ftp or tcp dst port ftp-data or tcp dst port domain'.
.LP
Allowable primitives are:
.IP "\fBdst host \fIhost\fR"
True if the IPv4/v6 destination field of the packet is \fIhost\fP,
which may be either an address or a name.
.IP "\fBsrc host \fIhost\fR"
True if the IPv4/v6 source field of the packet is \fIhost\fP.
.IP "\fBhost \fIhost\fP
True if either the IPv4/v6 source or destination of the packet is \fIhost\fP.
.IP
Any of the above host expressions can be prepended with the keywords,
\fBip\fP, \fBarp\fP, \fBrarp\fP, or \fBip6\fP as in:
.in +.5i
.nf
\fBip host \fIhost\fR
.fi
.in -.5i
which is equivalent to:
.in +.5i
.nf
\fBether proto \fI\\ip\fB and host \fIhost\fR
.fi
.in -.5i
If \fIhost\fR is a name with multiple IP addresses, each address will
be checked for a match.
.IP "\fBether dst \fIehost\fP
True if the Ethernet destination address is \fIehost\fP.
\fIEhost\fP
may be either a name from /etc/ethers or a number (see
.IR ethers (3N)
for numeric format).
.IP "\fBether src \fIehost\fP
True if the Ethernet source address is \fIehost\fP.
.IP "\fBether host \fIehost\fP
True if either the Ethernet source or destination address is \fIehost\fP.
.IP "\fBgateway\fP \fIhost\fP
True if the packet used \fIhost\fP as a gateway.
I.e., the Ethernet
source or destination address was \fIhost\fP but neither the IP source
nor the IP destination was \fIhost\fP.
\fIHost\fP must be a name and
must be found both by the machine's host-name-to-IP-address resolution
mechanisms (host name file, DNS, NIS, etc.) and by the machine's
host-name-to-Ethernet-address resolution mechanism (/etc/ethers, etc.).
(An equivalent expression is
.in +.5i
.nf
\fBether host \fIehost \fBand not host \fIhost\fR
.fi
.in -.5i
which can be used with either names or numbers for \fIhost / ehost\fP.)
This syntax does not work in IPv6-enabled configuration at this moment.
.IP "\fBdst net \fInet\fR"
True if the IPv4/v6 destination address of the packet has a network
number of \fInet\fP.
\fINet\fP may be either a name from the networks database
(/etc/networks, etc.) or a network number.
An IPv4 network number can be written as a dotted quad (e.g., 192.168.1.0),
dotted triple (e.g., 192.168.1), dotted pair (e.g, 172.16), or single
number (e.g., 10); the netmask is 255.255.255.255 for a dotted quad
(which means that it's really a host match), 255.255.255.0 for a dotted
triple, 255.255.0.0 for a dotted pair, or 255.0.0.0 for a single number.
An IPv6 network number must be written out fully; the netmask is
ff:ff:ff:ff:ff:ff:ff:ff, so IPv6 "network" matches are really always
host matches, and a network match requires a netmask length.
.IP "\fBsrc net \fInet\fR"
True if the IPv4/v6 source address of the packet has a network
number of \fInet\fP.
.IP "\fBnet \fInet\fR"
True if either the IPv4/v6 source or destination address of the packet has a network
number of \fInet\fP.
.IP "\fBnet \fInet\fR \fBmask \fInetmask\fR"
True if the IPv4 address matches \fInet\fR with the specific \fInetmask\fR.
May be qualified with \fBsrc\fR or \fBdst\fR.
Note that this syntax is not valid for IPv6 \fInet\fR.
.IP "\fBnet \fInet\fR/\fIlen\fR"
True if the IPv4/v6 address matches \fInet\fR with a netmask \fIlen\fR
bits wide.
May be qualified with \fBsrc\fR or \fBdst\fR.
.IP "\fBdst port \fIport\fR"
True if the packet is ip/tcp, ip/udp, ip6/tcp or ip6/udp and has a
destination port value of \fIport\fP.
The \fIport\fP can be a number or a name used in /etc/services (see
.IR tcp (4P)
and
.IR udp (4P)).
If a name is used, both the port
number and protocol are checked.
If a number or ambiguous name is used,
only the port number is checked (e.g., \fBdst port 513\fR will print both
tcp/login traffic and udp/who traffic, and \fBport domain\fR will print
both tcp/domain and udp/domain traffic).
.IP "\fBsrc port \fIport\fR"
True if the packet has a source port value of \fIport\fP.
.IP "\fBport \fIport\fR"
True if either the source or destination port of the packet is \fIport\fP.
.IP "\fBdst portrange \fIport1\fB-\fIport2\fR"
True if the packet is ip/tcp, ip/udp, ip6/tcp or ip6/udp and has a
destination port value between \fIport1\fP and \fIport2\fP.
.I port1
and
.I port2
are interpreted in the same fashion as the
.I port
parameter for
.BR port .
.IP "\fBsrc portrange \fIport1\fB-\fIport2\fR"
True if the packet has a source port value between \fIport1\fP and
\fIport2\fP.
.IP "\fBportrange \fIport1\fB-\fIport2\fR"
True if either the source or destination port of the packet is between
\fIport1\fP and \fIport2\fP.
.IP
Any of the above port or port range expressions can be prepended with
the keywords, \fBtcp\fP or \fBudp\fP, as in:
.in +.5i
.nf
\fBtcp src port \fIport\fR
.fi
.in -.5i
which matches only tcp packets whose source port is \fIport\fP.
.IP "\fBless \fIlength\fR"
True if the packet has a length less than or equal to \fIlength\fP.
This is equivalent to:
.in +.5i
.nf
\fBlen <= \fIlength\fP.
.fi
.in -.5i
.IP "\fBgreater \fIlength\fR"
True if the packet has a length greater than or equal to \fIlength\fP.
This is equivalent to:
.in +.5i
.nf
\fBlen >= \fIlength\fP.
.fi
.in -.5i
.IP "\fBip proto \fIprotocol\fR"
True if the packet is an IPv4 packet (see
.IR ip (4P))
of protocol type \fIprotocol\fP.
\fIProtocol\fP can be a number or one of the names
\fBicmp\fP, \fBicmp6\fP, \fBigmp\fP, \fBigrp\fP, \fBpim\fP, \fBah\fP,
\fBesp\fP, \fBvrrp\fP, \fBudp\fP, or \fBtcp\fP.
Note that the identifiers \fBtcp\fP, \fBudp\fP, and \fBicmp\fP are also
keywords and must be escaped via backslash (\\), which is \\\\ in the C-shell.
Note that this primitive does not chase the protocol header chain.
.IP "\fBip6 proto \fIprotocol\fR"
True if the packet is an IPv6 packet of protocol type \fIprotocol\fP.
Note that this primitive does not chase the protocol header chain.
.IP "\fBip6 protochain \fIprotocol\fR"
True if the packet is IPv6 packet,
and contains protocol header with type \fIprotocol\fR
in its protocol header chain.
For example,
.in +.5i
.nf
\fBip6 protochain 6\fR
.fi
.in -.5i
matches any IPv6 packet with TCP protocol header in the protocol header chain.
The packet may contain, for example,
authentication header, routing header, or hop-by-hop option header,
between IPv6 header and TCP header.
The BPF code emitted by this primitive is complex and
cannot be optimized by the BPF optimizer code, so this can be somewhat
slow.
.IP "\fBip protochain \fIprotocol\fR"
Equivalent to \fBip6 protochain \fIprotocol\fR, but this is for IPv4.
.IP "\fBether broadcast\fR"
True if the packet is an Ethernet broadcast packet.
The \fIether\fP
keyword is optional.
.IP "\fBip broadcast\fR"
True if the packet is an IPv4 broadcast packet.
It checks for both the all-zeroes and all-ones broadcast conventions,
and looks up the subnet mask on the interface on which the capture is
being done.
.IP
If the subnet mask of the interface on which the capture is being done
is not available, either because the interface on which capture is being
done has no netmask or because the capture is being done on the Linux
"any" interface, which can capture on more than one interface, this
check will not work correctly.
.IP "\fBether multicast\fR"
True if the packet is an Ethernet multicast packet.
The \fBether\fP
keyword is optional.
This is shorthand for `\fBether[0] & 1 != 0\fP'.
.IP "\fBip multicast\fR"
True if the packet is an IPv4 multicast packet.
.IP "\fBip6 multicast\fR"
True if the packet is an IPv6 multicast packet.
.IP "\fBether proto \fIprotocol\fR"
True if the packet is of ether type \fIprotocol\fR.
\fIProtocol\fP can be a number or one of the names
\fBip\fP, \fBip6\fP, \fBarp\fP, \fBrarp\fP, \fBatalk\fP, \fBaarp\fP,
\fBdecnet\fP, \fBsca\fP, \fBlat\fP, \fBmopdl\fP, \fBmoprc\fP,
\fBiso\fP, \fBstp\fP, \fBipx\fP, or \fBnetbeui\fP.
Note these identifiers are also keywords
and must be escaped via backslash (\\).
.IP
[In the case of FDDI (e.g., `\fBfddi protocol arp\fR'), Token Ring
(e.g., `\fBtr protocol arp\fR'), and IEEE 802.11 wireless LANS (e.g.,
`\fBwlan protocol arp\fR'), for most of those protocols, the
protocol identification comes from the 802.2 Logical Link Control (LLC)
header, which is usually layered on top of the FDDI, Token Ring, or
802.11 header.
.IP
When filtering for most protocol identifiers on FDDI, Token Ring, or
802.11, the filter checks only the protocol ID field of an LLC header
in so-called SNAP format with an Organizational Unit Identifier (OUI) of
0x000000, for encapsulated Ethernet; it doesn't check whether the packet
is in SNAP format with an OUI of 0x000000.
The exceptions are:
.RS
.TP
\fBiso\fP
the filter checks the DSAP (Destination Service Access Point) and
SSAP (Source Service Access Point) fields of the LLC header;
.TP
\fBstp\fP and \fBnetbeui\fP
the filter checks the DSAP of the LLC header;
.TP
\fBatalk\fP
the filter checks for a SNAP-format packet with an OUI of 0x080007
and the AppleTalk etype.
.RE
.IP
In the case of Ethernet, the filter checks the Ethernet type field
for most of those protocols. The exceptions are:
.RS
.TP
\fBiso\fP, \fBstp\fP, and \fBnetbeui\fP
the filter checks for an 802.3 frame and then checks the LLC header as
it does for FDDI, Token Ring, and 802.11;
.TP
\fBatalk\fP
the filter checks both for the AppleTalk etype in an Ethernet frame and
for a SNAP-format packet as it does for FDDI, Token Ring, and 802.11;
.TP
\fBaarp\fP
the filter checks for the AppleTalk ARP etype in either an Ethernet
frame or an 802.2 SNAP frame with an OUI of 0x000000;
.TP
\fBipx\fP
the filter checks for the IPX etype in an Ethernet frame, the IPX
DSAP in the LLC header, the 802.3-with-no-LLC-header encapsulation of
IPX, and the IPX etype in a SNAP frame.
.RE
.IP "\fBdecnet src \fIhost\fR"
True if the DECNET source address is
.IR host ,
which may be an address of the form ``10.123'', or a DECNET host
name.
[DECNET host name support is only available on ULTRIX systems
that are configured to run DECNET.]
.IP "\fBdecnet dst \fIhost\fR"
True if the DECNET destination address is
.IR host .
.IP "\fBdecnet host \fIhost\fR"
True if either the DECNET source or destination address is
.IR host .
.IP "\fBifname \fIinterface\fR"
True if the packet was logged as coming from the specified interface (applies
only to packets logged by OpenBSD's or FreeBSD's
.BR pf (4)).
.IP "\fBon \fIinterface\fR"
Synonymous with the
.B ifname
modifier.
.IP "\fBrnr \fInum\fR"
True if the packet was logged as matching the specified PF rule number
(applies only to packets logged by OpenBSD's or FreeBSD's
.BR pf (4)).
.IP "\fBrulenum \fInum\fR"
Synonymous with the
.B rnr
modifier.
.IP "\fBreason \fIcode\fR"
True if the packet was logged with the specified PF reason code. The known
codes are:
.BR match ,
.BR bad-offset ,
.BR fragment ,
.BR short ,
.BR normalize ,
and
.B memory
(applies only to packets logged by OpenBSD's or FreeBSD's
.BR pf (4)).
.IP "\fBrset \fIname\fR"
True if the packet was logged as matching the specified PF ruleset
name of an anchored ruleset (applies only to packets logged by OpenBSD's
or FreeBSD's
.BR pf (4)).
.IP "\fBruleset \fIname\fR"
Synonomous with the
.B rset
modifier.
.IP "\fBsrnr \fInum\fR"
True if the packet was logged as matching the specified PF rule number
of an anchored ruleset (applies only to packets logged by OpenBSD's or
FreeBSD's
.BR pf (4)).
.IP "\fBsubrulenum \fInum\fR"
Synonomous with the
.B srnr
modifier.
.IP "\fBaction \fIact\fR"
True if PF took the specified action when the packet was logged. Known actions
are:
.B pass
and
.B block
and, with later versions of
.BR pf (4)),
.BR nat ,
.BR rdr ,
.B binat
and
.B scrub
(applies only to packets logged by OpenBSD's or FreeBSD's
.BR pf (4)).
.IP "\fBwlan addr1 \fIehost\fR"
True if the first IEEE 802.11 address is
.IR ehost .
.IP "\fBwlan addr2 \fIehost\fR"
True if the second IEEE 802.11 address, if present, is
.IR ehost .
The second address field is used in all frames except for CTS (Clear To
Send) and ACK (Acknowledgment) control frames.
.IP "\fBwlan addr3 \fIehost\fR"
True if the third IEEE 802.11 address, if present, is
.IR ehost .
The third address field is used in management and data frames, but not
in control frames.
.IP "\fBwlan addr4 \fIehost\fR"
True if the fourth IEEE 802.11 address, if present, is
.IR ehost .
The fourth address field is only used for
WDS (Wireless Distribution System) frames.
.IP "\fBip\fR, \fBip6\fR, \fBarp\fR, \fBrarp\fR, \fBatalk\fR, \fBaarp\fR, \fBdecnet\fR, \fBiso\fR, \fBstp\fR, \fBipx\fR, \fInetbeui\fP"
Abbreviations for:
.in +.5i
.nf
\fBether proto \fIp\fR
.fi
.in -.5i
where \fIp\fR is one of the above protocols.
.IP "\fBlat\fR, \fBmoprc\fR, \fBmopdl\fR"
Abbreviations for:
.in +.5i
.nf
\fBether proto \fIp\fR
.fi
.in -.5i
where \fIp\fR is one of the above protocols.
Note that not all applications using
.BR pcap (3)
currently know how to parse these protocols.
.IP "\fBtype \fIwlan_type\fR"
True if the IEEE 802.11 frame type matches the specified \fIwlan_type\fR.
Valid \fIwlan_type\fRs are:
\fBmgt\fP,
\fBctl\fP
and \fBdata\fP.
.IP "\fBtype \fIwlan_type \fBsubtype \fIwlan_subtype\fR"
True if the IEEE 802.11 frame type matches the specified \fIwlan_type\fR
and frame subtype matches the specified \fIwlan_subtype\fR.
.IP
If the specified \fIwlan_type\fR is \fBmgt\fP,
then valid \fIwlan_subtype\fRs are:
\fBassoc-req\fP,
\fBassoc-resp\fP,
\fBreassoc-req\fP,
\fBreassoc-resp\fP,
\fBprobe-req\fP,
\fBprobe-resp\fP,
\fBbeacon\fP,
\fBatim\fP,
\fBdisassoc\fP,
\fBauth\fP and
\fBdeauth\fP.
.IP
If the specified \fIwlan_type\fR is \fBctl\fP,
then valid \fIwlan_subtype\fRs are:
\fBps-poll\fP,
\fBrts\fP,
\fBcts\fP,
\fBack\fP,
\fBcf-end\fP and
\fBcf-end-ack\fP.
.IP
If the specified \fIwlan_type\fR is \fBdata\fP,
then valid \fIwlan_subtype\fRs are:
\fBdata\fP,
\fBdata-cf-ack\fP,
\fBdata-cf-poll\fP,
\fBdata-cf-ack-poll\fP,
\fBnull\fP,
\fBcf-ack\fP,
\fBcf-poll\fP,
\fBcf-ack-poll\fP,
\fBqos-data\fP,
\fBqos-data-cf-ack\fP,
\fBqos-data-cf-poll\fP,
\fBqos-data-cf-ack-poll\fP,
\fBqos\fP,
\fBqos-cf-poll\fP and
\fBqos-cf-ack-poll\fP.
.IP "\fBsubtype \fIwlan_subtype\fR"
True if the IEEE 802.11 frame subtype matches the specified \fIwlan_subtype\fR
and frame has the type to which the specified \fIwlan_subtype\fR belongs.
.IP "\fBdir \fIdir\fR"
True if the IEEE 802.11 frame direction matches the specified
.IR dir .
Valid directions are:
.BR nods ,
.BR tods ,
.BR fromds ,
.BR dstods ,
or a numeric value.
.IP "\fBvlan \fI[vlan_id]\fR"
True if the packet is an IEEE 802.1Q VLAN packet.
If \fI[vlan_id]\fR is specified, only true if the packet has the specified
\fIvlan_id\fR.
Note that the first \fBvlan\fR keyword encountered in \fIexpression\fR
changes the decoding offsets for the remainder of \fIexpression\fR on
the assumption that the packet is a VLAN packet. The \fBvlan
\fI[vlan_id]\fR expression may be used more than once, to filter on VLAN
hierarchies. Each use of that expression increments the filter offsets
by 4.
.IP
For example:
.in +.5i
.nf
\fBvlan 100 && vlan 200\fR
.fi
.in -.5i
filters on VLAN 200 encapsulated within VLAN 100, and
.in +.5i
.nf
\fBvlan && vlan 300 && ip\fR
.fi
.in -.5i
filters IPv4 protocols encapsulated in VLAN 300 encapsulated within any
higher order VLAN.
.IP "\fBmpls \fI[label_num]\fR"
True if the packet is an MPLS packet.
If \fI[label_num]\fR is specified, only true is the packet has the specified
\fIlabel_num\fR.
Note that the first \fBmpls\fR keyword encountered in \fIexpression\fR
changes the decoding offsets for the remainder of \fIexpression\fR on
the assumption that the packet is a MPLS-encapsulated IP packet. The
\fBmpls \fI[label_num]\fR expression may be used more than once, to
filter on MPLS hierarchies. Each use of that expression increments the
filter offsets by 4.
.IP
For example:
.in +.5i
.nf
\fBmpls 100000 && mpls 1024\fR
.fi
.in -.5i
filters packets with an outer label of 100000 and an inner label of
1024, and
.in +.5i
.nf
\fBmpls && mpls 1024 && host 192.9.200.1\fR
.fi
.in -.5i
filters packets to or from 192.9.200.1 with an inner label of 1024 and
any outer label.
.IP \fBpppoed\fP
True if the packet is a PPP-over-Ethernet Discovery packet (Ethernet
type 0x8863).
.IP \fBpppoes\fP
True if the packet is a PPP-over-Ethernet Session packet (Ethernet
type 0x8864).
Note that the first \fBpppoes\fR keyword encountered in \fIexpression\fR
changes the decoding offsets for the remainder of \fIexpression\fR on
the assumption that the packet is a PPPoE session packet.
.IP
For example:
.in +.5i
.nf
\fBpppoes && ip\fR
.fi
.in -.5i
filters IPv4 protocols encapsulated in PPPoE.
.IP "\fBtcp\fR, \fBudp\fR, \fBicmp\fR"
Abbreviations for:
.in +.5i
.nf
\fBip proto \fIp\fR\fB or ip6 proto \fIp\fR
.fi
.in -.5i
where \fIp\fR is one of the above protocols.
.IP "\fBiso proto \fIprotocol\fR"
True if the packet is an OSI packet of protocol type \fIprotocol\fP.
\fIProtocol\fP can be a number or one of the names
\fBclnp\fP, \fBesis\fP, or \fBisis\fP.
.IP "\fBclnp\fR, \fBesis\fR, \fBisis\fR"
Abbreviations for:
.in +.5i
.nf
\fBiso proto \fIp\fR
.fi
.in -.5i
where \fIp\fR is one of the above protocols.
.IP "\fBl1\fR, \fBl2\fR, \fBiih\fR, \fBlsp\fR, \fBsnp\fR, \fBcsnp\fR, \fBpsnp\fR"
Abbreviations for IS-IS PDU types.
.IP "\fBvpi\fP \fIn\fR
True if the packet is an ATM packet, for SunATM on Solaris, with a
virtual path identifier of
.IR n .
.IP "\fBvci\fP \fIn\fR
True if the packet is an ATM packet, for SunATM on Solaris, with a
virtual channel identifier of
.IR n .
.IP \fBlane\fP
True if the packet is an ATM packet, for SunATM on Solaris, and is
an ATM LANE packet.
Note that the first \fBlane\fR keyword encountered in \fIexpression\fR
changes the tests done in the remainder of \fIexpression\fR
on the assumption that the packet is either a LANE emulated Ethernet
packet or a LANE LE Control packet. If \fBlane\fR isn't specified, the
tests are done under the assumption that the packet is an
LLC-encapsulated packet.
.IP \fBllc\fP
True if the packet is an ATM packet, for SunATM on Solaris, and is
an LLC-encapsulated packet.
.IP \fBoamf4s\fP
True if the packet is an ATM packet, for SunATM on Solaris, and is
a segment OAM F4 flow cell (VPI=0 & VCI=3).
.IP \fBoamf4e\fP
True if the packet is an ATM packet, for SunATM on Solaris, and is
an end-to-end OAM F4 flow cell (VPI=0 & VCI=4).
.IP \fBoamf4\fP
True if the packet is an ATM packet, for SunATM on Solaris, and is
a segment or end-to-end OAM F4 flow cell (VPI=0 & (VCI=3 | VCI=4)).
.IP \fBoam\fP
True if the packet is an ATM packet, for SunATM on Solaris, and is
a segment or end-to-end OAM F4 flow cell (VPI=0 & (VCI=3 | VCI=4)).
.IP \fBmetac\fP
True if the packet is an ATM packet, for SunATM on Solaris, and is
on a meta signaling circuit (VPI=0 & VCI=1).
.IP \fBbcc\fP
True if the packet is an ATM packet, for SunATM on Solaris, and is
on a broadcast signaling circuit (VPI=0 & VCI=2).
.IP \fBsc\fP
True if the packet is an ATM packet, for SunATM on Solaris, and is
on a signaling circuit (VPI=0 & VCI=5).
.IP \fBilmic\fP
True if the packet is an ATM packet, for SunATM on Solaris, and is
on an ILMI circuit (VPI=0 & VCI=16).
.IP \fBconnectmsg\fP
True if the packet is an ATM packet, for SunATM on Solaris, and is
on a signaling circuit and is a Q.2931 Setup, Call Proceeding, Connect,
Connect Ack, Release, or Release Done message.
.IP \fBmetaconnect\fP
True if the packet is an ATM packet, for SunATM on Solaris, and is
on a meta signaling circuit and is a Q.2931 Setup, Call Proceeding, Connect,
Release, or Release Done message.
.IP "\fIexpr relop expr\fR"
True if the relation holds, where \fIrelop\fR is one of >, <, >=, <=, =,
!=, and \fIexpr\fR is an arithmetic expression composed of integer
constants (expressed in standard C syntax), the normal binary operators
[+, -, *, /, &, |, <<, >>], a length operator, and special packet data
accessors. Note that all comparisons are unsigned, so that, for example,
0x80000000 and 0xffffffff are > 0.
To access
data inside the packet, use the following syntax:
.in +.5i
.nf
\fIproto\fB [ \fIexpr\fB : \fIsize\fB ]\fR
.fi
.in -.5i
\fIProto\fR is one of \fBether, fddi, tr, wlan, ppp, slip, link,
ip, arp, rarp, tcp, udp, icmp, ip6\fR or \fBradio\fR, and
indicates the protocol layer for the index operation.
(\fBether, fddi, wlan, tr, ppp, slip\fR and \fBlink\fR all refer to the
link layer. \fBradio\fR refers to the "radio header" added to some
802.11 captures.)
Note that \fItcp, udp\fR and other upper-layer protocol types only
apply to IPv4, not IPv6 (this will be fixed in the future).
The byte offset, relative to the indicated protocol layer, is
given by \fIexpr\fR.
\fISize\fR is optional and indicates the number of bytes in the
field of interest; it can be either one, two, or four, and defaults to one.
The length operator, indicated by the keyword \fBlen\fP, gives the
length of the packet.
For example, `\fBether[0] & 1 != 0\fP' catches all multicast traffic.
The expression `\fBip[0] & 0xf != 5\fP'
catches all IPv4 packets with options.
The expression
`\fBip[6:2] & 0x1fff = 0\fP'
catches only unfragmented IPv4 datagrams and frag zero of fragmented
IPv4 datagrams.
This check is implicitly applied to the \fBtcp\fP and \fBudp\fP
index operations.
For instance, \fBtcp[0]\fP always means the first
byte of the TCP \fIheader\fP, and never means the first byte of an
intervening fragment.
Some offsets and field values may be expressed as names rather than
as numeric values.
The following protocol header field offsets are
available: \fBicmptype\fP (ICMP type field), \fBicmpcode\fP (ICMP
code field), and \fBtcpflags\fP (TCP flags field).
The following ICMP type field values are available: \fBicmp-echoreply\fP,
\fBicmp-unreach\fP, \fBicmp-sourcequench\fP, \fBicmp-redirect\fP,
\fBicmp-echo\fP, \fBicmp-routeradvert\fP, \fBicmp-routersolicit\fP,
\fBicmp-timxceed\fP, \fBicmp-paramprob\fP, \fBicmp-tstamp\fP,
\fBicmp-tstampreply\fP, \fBicmp-ireq\fP, \fBicmp-ireqreply\fP,
\fBicmp-maskreq\fP, \fBicmp-maskreply\fP.
The following TCP flags field values are available: \fBtcp-fin\fP,
\fBtcp-syn\fP, \fBtcp-rst\fP, \fBtcp-push\fP,
\fBtcp-ack\fP, \fBtcp-urg\fP.
.LP
Primitives may be combined using:
.IP
A parenthesized group of primitives and operators
(parentheses are special to the Shell and must be escaped).
.IP
Negation (`\fB!\fP' or `\fBnot\fP').
.IP
Concatenation (`\fB&&\fP' or `\fBand\fP').
.IP
Alternation (`\fB||\fP' or `\fBor\fP').
.LP
Negation has highest precedence.
Alternation and concatenation have equal precedence and associate
left to right.
Note that explicit \fBand\fR tokens, not juxtaposition,
are now required for concatenation.
.LP
If an identifier is given without a keyword, the most recent keyword
is assumed.
For example,
.in +.5i
.nf
\fBnot host vs and ace\fR
.fi
.in -.5i
is short for
.in +.5i
.nf
\fBnot host vs and host ace\fR
.fi
.in -.5i
which should not be confused with
.in +.5i
.nf
\fBnot ( host vs or ace )\fR
.fi
.in -.5i
.SH EXAMPLES
.LP
To select all packets arriving at or departing from \fIsundown\fP:
.RS
.nf
\fBhost sundown\fP
.fi
.RE
.LP
To select traffic between \fIhelios\fR and either \fIhot\fR or \fIace\fR:
.RS
.nf
\fBhost helios and \\( hot or ace \\)\fP
.fi
.RE
.LP
To select all IP packets between \fIace\fR and any host except \fIhelios\fR:
.RS
.nf
\fBip host ace and not helios\fP
.fi
.RE
.LP
To select all traffic between local hosts and hosts at Berkeley:
.RS
.nf
.B
net ucb-ether
.fi
.RE
.LP
To select all ftp traffic through internet gateway \fIsnup\fP:
.RS
.nf
.B
gateway snup and (port ftp or ftp-data)
.fi
.RE
.LP
To select traffic neither sourced from nor destined for local hosts
(if you gateway to one other net, this stuff should never make it
onto your local net).
.RS
.nf
.B
ip and not net \fIlocalnet\fP
.fi
.RE
.LP
To select the start and end packets (the SYN and FIN packets) of each
TCP conversation that involves a non-local host.
.RS
.nf
.B
tcp[tcpflags] & (tcp-syn|tcp-fin) != 0 and not src and dst net \fIlocalnet\fP
.fi
.RE
.LP
To select all IPv4 HTTP packets to and from port 80, i.e. print only
packets that contain data, not, for example, SYN and FIN packets and
ACK-only packets. (IPv6 is left as an exercise for the reader.)
.RS
.nf
.B
tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)
.fi
.RE
.LP
To select IP packets longer than 576 bytes sent through gateway \fIsnup\fP:
.RS
.nf
.B
gateway snup and ip[2:2] > 576
.fi
.RE
.LP
To select IP broadcast or multicast packets that were
.I not
sent via Ethernet broadcast or multicast:
.RS
.nf
.B
ether[0] & 1 = 0 and ip[16] >= 224
.fi
.RE
.LP
To select all ICMP packets that are not echo requests/replies (i.e., not
ping packets):
.RS
.nf
.B
icmp[icmptype] != icmp-echo and icmp[icmptype] != icmp-echoreply
.fi
.RE
.SH "SEE ALSO"
pcap(3PCAP)
.SH AUTHORS
The original authors are:
.LP
Van Jacobson,
Craig Leres and
Steven McCanne, all of the
Lawrence Berkeley National Laboratory, University of California, Berkeley, CA.
.LP
It is currently being maintained by tcpdump.org.
.LP
The current version of libpcap is available via http:
.LP
.RS
.I http://www.tcpdump.org/
.RE
.LP
The original distribution is available via anonymous ftp:
.LP
.RS
.I ftp://ftp.ee.lbl.gov/tcpdump.tar.Z
.RE
.SH BUGS
Please send problems, bugs, questions, desirable enhancements, etc. to:
.LP
.RS
tcpdump-workers@lists.tcpdump.org
.RE
.LP
Filter expressions on fields other than those in Token Ring headers will
not correctly handle source-routed Token Ring packets.
.LP
Filter expressions on fields other than those in 802.11 headers will not
correctly handle 802.11 data packets with both To DS and From DS set.
.LP
.BR "ip6 proto"
should chase header chain, but at this moment it does not.
.BR "ip6 protochain"
is supplied for this behavior.
.LP
Arithmetic expression against transport layer headers, like \fBtcp[0]\fP,
does not work against IPv6 packets.
It only looks at IPv4 packets.

View File

@ -30,17 +30,21 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#) $Header: /tcpdump/master/libpcap/pcap-int.h,v 1.68.2.11 2007/06/22 06:43:58 guy Exp $ (LBL)
* @(#) $Header: /tcpdump/master/libpcap/pcap-int.h,v 1.85.2.9 2008-09-16 00:21:08 guy Exp $ (LBL)
*/
#ifndef pcap_int_h
#define pcap_int_h
#define pcap_int_h
#include <pcap/pcap.h>
#ifdef __cplusplus
extern "C" {
#endif
#include <pcap.h>
#ifdef HAVE_LIBDLPI
#include <libdlpi.h>
#endif
#ifdef WIN32
#include <Packet32.h>
@ -51,6 +55,23 @@ extern "C" {
#include <io.h>
#endif
#if (defined(_MSC_VER) && (_MSC_VER <= 1200)) /* we are compiling with Visual Studio 6, that doesn't support the LL suffix*/
/*
* Swap byte ordering of unsigned long long timestamp on a big endian
* machine.
*/
#define SWAPLL(ull) ((ull & 0xff00000000000000) >> 56) | \
((ull & 0x00ff000000000000) >> 40) | \
((ull & 0x0000ff0000000000) >> 24) | \
((ull & 0x000000ff00000000) >> 8) | \
((ull & 0x00000000ff000000) << 8) | \
((ull & 0x0000000000ff0000) << 24) | \
((ull & 0x000000000000ff00) << 40) | \
((ull & 0x00000000000000ff) << 56)
#else /* A recent Visual studio compiler or not VC */
/*
* Swap byte ordering of unsigned long long timestamp on a big endian
* machine.
@ -64,6 +85,8 @@ extern "C" {
((ull & 0x000000000000ff00LL) << 40) | \
((ull & 0x00000000000000ffLL) << 56)
#endif /* _MSC_VER */
/*
* Savefile
*/
@ -73,16 +96,22 @@ typedef enum {
MAYBE_SWAPPED
} swapped_type_t;
/*
* Used when reading a savefile.
*/
struct pcap_sf {
FILE *rfile;
int swapped;
int hdrsize;
size_t hdrsize;
swapped_type_t lengths_swapped;
int version_major;
int version_minor;
u_char *base;
};
/*
* Used when doing a live capture.
*/
struct pcap_md {
struct pcap_stat stat;
/*XXX*/
@ -93,22 +122,25 @@ struct pcap_md {
long TotMissed; /* missed by i/f during this run */
long OrigMissed; /* missed by i/f before this run */
char *device; /* device name */
int timeout; /* timeout for buffering */
int must_clear; /* stuff we must clear when we close */
struct pcap *next; /* list of open pcaps that need stuff cleared on close */
#ifdef linux
int sock_packet; /* using Linux 2.0 compatible interface */
int timeout; /* timeout specified to pcap_open_live */
int clear_promisc; /* must clear promiscuous mode when we close */
int cooked; /* using SOCK_DGRAM rather than SOCK_RAW */
int ifindex; /* interface index of device we're bound to */
int lo_ifindex; /* interface index of the loopback device */
struct pcap *next; /* list of open promiscuous sock_packet pcaps */
u_int packets_read; /* count of packets read with recvfrom() */
#endif
bpf_u_int32 oldmode; /* mode to restore when turning monitor mode off */
u_int tp_version; /* version of tpacket_hdr for mmaped ring */
u_int tp_hdrlen; /* hdrlen of tpacket_hdr for mmaped ring */
#endif /* linux */
#ifdef HAVE_DAG_API
#ifdef HAVE_DAG_STREAMS_API
u_char *dag_mem_bottom; /* DAG card current memory bottom pointer */
u_char *dag_mem_top; /* DAG card current memory top pointer */
#else
#else /* HAVE_DAG_STREAMS_API */
void *dag_mem_base; /* DAG card memory base address */
u_int dag_mem_bottom; /* DAG card current memory bottom offset */
u_int dag_mem_top; /* DAG card current memory top offset */
@ -120,6 +152,41 @@ struct pcap_md {
* Same as in linux above, introduce
* generally? */
#endif /* HAVE_DAG_API */
#ifdef HAVE_ZEROCOPY_BPF
/*
* Zero-copy read buffer -- for zero-copy BPF. 'buffer' above will
* alternative between these two actual mmap'd buffers as required.
* As there is a header on the front size of the mmap'd buffer, only
* some of the buffer is exposed to libpcap as a whole via bufsize;
* zbufsize is the true size. zbuffer tracks the current zbuf
* assocated with buffer so that it can be used to decide which the
* next buffer to read will be.
*/
u_char *zbuf1, *zbuf2, *zbuffer;
u_int zbufsize;
u_int zerocopy;
u_int interrupted;
struct timespec firstsel;
/*
* If there's currently a buffer being actively processed, then it is
* referenced here; 'buffer' is also pointed at it, but offset by the
* size of the header.
*/
struct bpf_zbuf_header *bzh;
#endif /* HAVE_ZEROCOPY_BPF */
};
/*
* Stuff to clear when we close.
*/
#define MUST_CLEAR_PROMISC 0x00000001 /* promiscuous mode */
#define MUST_CLEAR_RFMON 0x00000002 /* rfmon (monitor) mode */
struct pcap_opt {
int buffer_size;
char *source;
int promisc;
int rfmon;
};
/*
@ -135,21 +202,44 @@ struct pcap_md {
#define PCAP_FDDIPAD 3
#endif
typedef int (*activate_op_t)(pcap_t *);
typedef int (*can_set_rfmon_op_t)(pcap_t *);
typedef int (*read_op_t)(pcap_t *, int cnt, pcap_handler, u_char *);
typedef int (*inject_op_t)(pcap_t *, const void *, size_t);
typedef int (*setfilter_op_t)(pcap_t *, struct bpf_program *);
typedef int (*setdirection_op_t)(pcap_t *, pcap_direction_t);
typedef int (*set_datalink_op_t)(pcap_t *, int);
typedef int (*getnonblock_op_t)(pcap_t *, char *);
typedef int (*setnonblock_op_t)(pcap_t *, int, char *);
typedef int (*stats_op_t)(pcap_t *, struct pcap_stat *);
#ifdef WIN32
typedef int (*setbuff_op_t)(pcap_t *, int);
typedef int (*setmode_op_t)(pcap_t *, int);
typedef int (*setmintocopy_op_t)(pcap_t *, int);
#endif
typedef void (*cleanup_op_t)(pcap_t *);
struct pcap {
#ifdef WIN32
ADAPTER *adapter;
LPPACKET Packet;
int timeout;
int nonblock;
#else
int fd;
int selectable_fd;
int send_fd;
#endif /* WIN32 */
#ifdef HAVE_LIBDLPI
dlpi_handle_t dlpi_hd;
#endif
int snapshot;
int linktype;
int linktype; /* Network linktype */
int linktype_ext; /* Extended information stored in the linktype field of a file */
int tzoff; /* timezone offset */
int offset; /* offset for proper alignment */
int activated; /* true if the capture is really started */
int oldstyle; /* if we're opening with pcap_open_live() */
int break_loop; /* flag set to force break from packet-reading loop */
@ -158,12 +248,12 @@ struct pcap {
#endif
#ifdef MSDOS
int inter_packet_wait; /* offline: wait between packets */
void (*wait_proc)(void); /* call proc while waiting */
#endif
struct pcap_sf sf;
struct pcap_md md;
struct pcap_opt opt;
/*
* Read buffer.
@ -184,15 +274,27 @@ struct pcap {
/*
* Methods.
*/
int (*read_op)(pcap_t *, int cnt, pcap_handler, u_char *);
int (*inject_op)(pcap_t *, const void *, size_t);
int (*setfilter_op)(pcap_t *, struct bpf_program *);
int (*setdirection_op)(pcap_t *, pcap_direction_t);
int (*set_datalink_op)(pcap_t *, int);
int (*getnonblock_op)(pcap_t *, char *);
int (*setnonblock_op)(pcap_t *, int, char *);
int (*stats_op)(pcap_t *, struct pcap_stat *);
void (*close_op)(pcap_t *);
activate_op_t activate_op;
can_set_rfmon_op_t can_set_rfmon_op;
read_op_t read_op;
inject_op_t inject_op;
setfilter_op_t setfilter_op;
setdirection_op_t setdirection_op;
set_datalink_op_t set_datalink_op;
getnonblock_op_t getnonblock_op;
setnonblock_op_t setnonblock_op;
stats_op_t stats_op;
#ifdef WIN32
/*
* These are, at least currently, specific to the Win32 NPF
* driver.
*/
setbuff_op_t setbuff_op;
setmode_op_t setmode_op;
setmintocopy_op_t setmintocopy_op;
#endif
cleanup_op_t cleanup_op;
/*
* Placeholder for filter code if bpf not in kernel.
@ -231,8 +333,8 @@ struct pcap_timeval {
*
* introduce a new structure for the new format;
*
* send mail to "tcpdump-workers@tcpdump.org", requesting a new
* magic number for your new capture file format, and, when
* send mail to "tcpdump-workers@lists.tcpdump.org", requesting
* a new magic number for your new capture file format, and, when
* you get the new magic number, put it in "savefile.c";
*
* use that magic number for save files with the changed record
@ -242,9 +344,12 @@ struct pcap_timeval {
* the old record header as well as files with the new record header
* (using the magic number to determine the header format).
*
* Then supply the changes to "patches@tcpdump.org", so that future
* versions of libpcap and programs that use it (such as tcpdump) will
* be able to read your new capture file format.
* Then supply the changes as a patch at
*
* http://sourceforge.net/projects/libpcap/
*
* so that future versions of libpcap and programs that use it (such as
* tcpdump) will be able to read your new capture file format.
*/
struct pcap_sf_pkthdr {
@ -309,7 +414,13 @@ int pcap_getnonblock_fd(pcap_t *, char *);
int pcap_setnonblock_fd(pcap_t *p, int, char *);
#endif
void pcap_close_common(pcap_t *);
pcap_t *pcap_create_common(const char *, char *);
int pcap_do_addexit(pcap_t *);
void pcap_add_to_pcaps_to_close(pcap_t *);
void pcap_remove_from_pcaps_to_close(pcap_t *);
void pcap_cleanup_live_common(pcap_t *);
int pcap_not_initialized(pcap_t *);
int pcap_check_activated(pcap_t *);
/*
* Internal interfaces for "pcap_findalldevs()".

370
pcap-libdlpi.c Normal file
View File

@ -0,0 +1,370 @@
/*
* Copyright (c) 1993, 1994, 1995, 1996, 1997
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that: (1) source code distributions
* retain the above copyright notice and this paragraph in its entirety, (2)
* distributions including binary code include the above copyright notice and
* this paragraph in its entirety in the documentation or other materials
* provided with the distribution, and (3) all advertising materials mentioning
* features or use of this software display the following acknowledgement:
* ``This product includes software developed by the University of California,
* Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
* the University nor the names of its contributors may be used to endorse
* or promote products derived from this software without specific prior
* written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* This code contributed by Sagun Shakya (sagun.shakya@sun.com)
*/
/*
* Packet capture routines for DLPI using libdlpi under SunOS 5.11.
*/
#ifndef lint
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/pcap-libdlpi.c,v 1.1.2.6 2008-04-14 20:41:52 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <sys/types.h>
#include <sys/time.h>
#include <sys/bufmod.h>
#include <sys/stream.h>
#include <libdlpi.h>
#include <errno.h>
#include <memory.h>
#include <stropts.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "pcap-int.h"
#include "dlpisubs.h"
/* Forwards. */
static int pcap_read_libdlpi(pcap_t *, int, pcap_handler, u_char *);
static int pcap_inject_libdlpi(pcap_t *, const void *, size_t);
static void pcap_close_libdlpi(pcap_t *);
static void pcap_libdlpi_err(const char *, const char *, int, char *);
/*
* list_interfaces() will list all the network links that are
* available on a system.
*/
static boolean_t list_interfaces(const char *, void *);
typedef struct linknamelist {
char linkname[DLPI_LINKNAME_MAX];
struct linknamelist *lnl_next;
} linknamelist_t;
typedef struct linkwalk {
linknamelist_t *lw_list;
int lw_err;
} linkwalk_t;
/*
* The caller of this function should free the memory allocated
* for each linknamelist_t "entry" allocated.
*/
static boolean_t
list_interfaces(const char *linkname, void *arg)
{
linkwalk_t *lwp = arg;
linknamelist_t *entry;
if ((entry = calloc(1, sizeof(linknamelist_t))) == NULL) {
lwp->lw_err = ENOMEM;
return (B_TRUE);
}
(void) strlcpy(entry->linkname, linkname, DLPI_LINKNAME_MAX);
if (lwp->lw_list == NULL) {
lwp->lw_list = entry;
} else {
entry->lnl_next = lwp->lw_list;
lwp->lw_list = entry;
}
return (B_FALSE);
}
static int
pcap_activate_libdlpi(pcap_t *p)
{
int retv;
dlpi_handle_t dh;
dlpi_info_t dlinfo;
int err = PCAP_ERROR;
/*
* Enable Solaris raw and passive DLPI extensions;
* dlpi_open() will not fail if the underlying link does not support
* passive mode. See dlpi(7P) for details.
*/
retv = dlpi_open(p->opt.source, &dh, DLPI_RAW|DLPI_PASSIVE);
if (retv != DLPI_SUCCESS) {
if (retv == DLPI_ELINKNAMEINVAL || retv == DLPI_ENOLINK)
err = PCAP_ERROR_NO_SUCH_DEVICE;
else if (retv == DLPI_SYSERR && errno == EACCES)
err = PCAP_ERROR_PERM_DENIED;
pcap_libdlpi_err(p->opt.source, "dlpi_open", retv,
p->errbuf);
return (err);
}
p->dlpi_hd = dh;
if (p->opt.rfmon) {
/*
* This device exists, but we don't support monitor mode
* any platforms that support DLPI.
*/
err = PCAP_ERROR_RFMON_NOTSUP;
goto bad;
}
/* Bind with DLPI_ANY_SAP. */
if ((retv = dlpi_bind(p->dlpi_hd, DLPI_ANY_SAP, 0)) != DLPI_SUCCESS) {
pcap_libdlpi_err(p->opt.source, "dlpi_bind", retv, p->errbuf);
goto bad;
}
/* Enable promiscuous mode. */
if (p->opt.promisc) {
retv = dlpi_promiscon(p->dlpi_hd, DL_PROMISC_PHYS);
if (retv != DLPI_SUCCESS) {
pcap_libdlpi_err(p->opt.source,
"dlpi_promisc(PHYSICAL)", retv, p->errbuf);
goto bad;
}
} else {
/* Try to enable multicast. */
retv = dlpi_promiscon(p->dlpi_hd, DL_PROMISC_MULTI);
if (retv != DLPI_SUCCESS) {
pcap_libdlpi_err(p->opt.source, "dlpi_promisc(MULTI)",
retv, p->errbuf);
goto bad;
}
}
/* Try to enable SAP promiscuity. */
if ((retv = dlpi_promiscon(p->dlpi_hd, DL_PROMISC_SAP)) != DLPI_SUCCESS) {
if (!promisc) {
pcap_libdlpi_err(p->opt.source, "dlpi_promisc(SAP)",
retv, p->errbuf);
goto bad;
}
/* Not fatal, since the DL_PROMISC_PHYS mode worked. */
fprintf(stderr, "WARNING: dlpi_promisc(SAP) failed on"
" %s:(%s)\n", p->opt.source, dlpi_strerror(retv));
}
/* Determine link type. */
if ((retv = dlpi_info(p->dlpi_hd, &dlinfo, 0)) != DLPI_SUCCESS) {
pcap_libdlpi_err(p->opt.source, "dlpi_info", retv, p->errbuf);
goto bad;
}
if (pcap_process_mactype(p, dlinfo.di_mactype) != 0)
goto bad;
p->fd = dlpi_fd(p->dlpi_hd);
/* Push and configure bufmod. */
if (pcap_conf_bufmod(p, snaplen, p->md.timeout) != 0)
goto bad;
/*
* Flush the read side.
*/
if (ioctl(p->fd, I_FLUSH, FLUSHR) != 0) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "FLUSHR: %s",
pcap_strerror(errno));
goto bad;
}
/* Allocate data buffer. */
if (pcap_alloc_databuf(p) != 0)
goto bad;
/*
* "p->fd" is a FD for a STREAMS device, so "select()" and
* "poll()" should work on it.
*/
p->selectable_fd = p->fd;
p->read_op = pcap_read_libdlpi;
p->inject_op = pcap_inject_libdlpi;
p->setfilter_op = install_bpf_program; /* No kernel filtering */
p->setdirection_op = NULL; /* Not implemented */
p->set_datalink_op = NULL; /* Can't change data link type */
p->getnonblock_op = pcap_getnonblock_fd;
p->setnonblock_op = pcap_setnonblock_fd;
p->stats_op = pcap_stats_dlpi;
p->cleanup_op = pcap_cleanup_libdlpi;
return (0);
bad:
pcap_cleanup_libdlpi(p);
return (err);
}
/*
* In Solaris, the "standard" mechanism" i.e SIOCGLIFCONF will only find
* network links that are plumbed and are up. dlpi_walk(3DLPI) will find
* additional network links present in the system.
*/
int
pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
{
int retv = 0;
linknamelist_t *entry, *next;
linkwalk_t lw = {NULL, 0};
int save_errno;
/* dlpi_walk() for loopback will be added here. */
dlpi_walk(list_interfaces, &lw, 0);
if (lw.lw_err != 0) {
snprintf(errbuf, PCAP_ERRBUF_SIZE,
"dlpi_walk: %s", pcap_strerror(lw.lw_err));
retv = -1;
goto done;
}
/* Add linkname if it does not exist on the list. */
for (entry = lw.lw_list; entry != NULL; entry = entry->lnl_next) {
if (pcap_add_if(alldevsp, entry->linkname, 0, NULL, errbuf) < 0)
retv = -1;
}
done:
save_errno = errno;
for (entry = lw.lw_list; entry != NULL; entry = next) {
next = entry->lnl_next;
free(entry);
}
errno = save_errno;
return (retv);
}
/*
* Read data received on DLPI handle. Returns -2 if told to terminate, else
* returns the number of packets read.
*/
static int
pcap_read_libdlpi(pcap_t *p, int count, pcap_handler callback, u_char *user)
{
int len;
u_char *bufp;
size_t msglen;
int retv;
len = p->cc;
if (len != 0) {
bufp = p->bp;
goto process_pkts;
}
do {
/* Has "pcap_breakloop()" been called? */
if (p->break_loop) {
/*
* Yes - clear the flag that indicates that it has,
* and return -2 to indicate that we were told to
* break out of the loop.
*/
p->break_loop = 0;
return (-2);
}
msglen = p->bufsize;
bufp = p->buffer + p->offset;
retv = dlpi_recv(p->dlpi_hd, NULL, NULL, bufp,
&msglen, -1, NULL);
if (retv != DLPI_SUCCESS) {
/*
* This is most likely a call to terminate out of the
* loop. So, do not return an error message, instead
* check if "pcap_breakloop()" has been called above.
*/
if (retv == DL_SYSERR && errno == EINTR) {
len = 0;
continue;
}
pcap_libdlpi_err(dlpi_linkname(p->dlpi_hd),
"dlpi_recv", retv, p->errbuf);
return (-1);
}
len = msglen;
} while (len == 0);
process_pkts:
return (pcap_process_pkts(p, callback, user, count, bufp, len));
}
static int
pcap_inject_libdlpi(pcap_t *p, const void *buf, size_t size)
{
int retv;
retv = dlpi_send(p->dlpi_hd, NULL, 0, buf, size, NULL);
if (retv != DLPI_SUCCESS) {
pcap_libdlpi_err(dlpi_linkname(p->dlpi_hd), "dlpi_send", retv,
p->errbuf);
return (-1);
}
/*
* dlpi_send(3DLPI) does not provide a way to return the number of
* bytes sent on the wire. Based on the fact that DLPI_SUCCESS was
* returned we are assuming 'size' bytes were sent.
*/
return (size);
}
/*
* Close dlpi handle.
*/
static void
pcap_cleanup_libdlpi(pcap_t *p)
{
if (p->dlpi_hd != NULL) {
dlpi_close(p->dlpi_hd);
p->dlpi_hd = NULL;
p->fd = -1;
}
pcap_cleanup_live_common(p);
}
/*
* Write error message to buffer.
*/
static void
pcap_libdlpi_err(const char *linkname, const char *func, int err, char *errbuf)
{
snprintf(errbuf, PCAP_ERRBUF_SIZE, "libpcap: %s failed on %s: %s",
func, linkname, dlpi_strerror(err));
}
pcap_t *
pcap_create(const char *device, char *ebuf)
{
pcap_t *p;
p = pcap_create_common(device, ebuf);
if (p == NULL)
return (NULL);
p->activate_op = pcap_activate_libdlpi;
return (p);
}

282
pcap-linktype.manmisc.in Normal file
View File

@ -0,0 +1,282 @@
.\" @(#) $Header: /tcpdump/master/libpcap/pcap-linktype.manmisc.in,v 1.1.2.4 2008-10-27 22:52:05 guy Exp $
.\"
.\" Copyright (c) 1987, 1988, 1989, 1990, 1991, 1992, 1994, 1995, 1996, 1997
.\" The Regents of the University of California. All rights reserved.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that: (1) source code distributions
.\" retain the above copyright notice and this paragraph in its entirety, (2)
.\" distributions including binary code include the above copyright notice and
.\" this paragraph in its entirety in the documentation or other materials
.\" provided with the distribution, and (3) all advertising materials mentioning
.\" features or use of this software display the following acknowledgement:
.\" ``This product includes software developed by the University of California,
.\" Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
.\" the University nor the names of its contributors may be used to endorse
.\" or promote products derived from this software without specific prior
.\" written permission.
.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\"
.TH PCAP-LINKTYPE @MAN_MISC_INFO@ "23 October 2008"
.SH NAME
pcap-linktype \- link-layer header types supported by libpcap
.SH DESCRIPTION
For a live capture or ``savefile'', libpcap supplies, as the return
value of the
.BR pcap_datalink (3PCAP)
routine, a value that indicates the type of link-layer header at the
beginning of the packets it provides. This is not necessarily the type
of link-layer header that the packets being captured have on the network
from which they're being captured; for example, packets from an IEEE
802.11 network might be provided by libpcap with Ethernet headers that
the network adapter or the network adapter driver generates from the
802.11 headers. The names for those values begin with
.BR DLT_ ,
so they are sometimes called "DLT_ values".
.PP
The values stored in the link-layer header type field in the savefile
header are, in most but not all cases, the same as the values returned
by
.BR pcap_datalink() .
The names for those values begin with
.BR LINKTYPE_ .
.PP
The link-layer header types supported by libpcap are listed here. The
value corresponding to
.B LINKTYPE_
names are given; the value corresponding to
.B DLT_
values are, in some cases, platform dependent, and are not given;
applications should check for particular
.B DLT_
values by name.
.RS 5
.TP 5
.BR DLT_NULL "; " LINKTYPE_NULL = 0
BSD loopback encapsulation; the link layer header is a 4-byte field, in
.I host
byte order, containing a PF_ value from
.B socket.h
for the network-layer protocol of the packet.
.IP
Note that ``host byte order'' is the byte order of the machine on which
the packets are captured, and the PF_ values are for the OS of the
machine on which the packets are captured; if a live capture is being
done, ``host byte order'' is the byte order of the machine capturing the
packets, and the PF_ values are those of the OS of the machine capturing
the packets, but if a ``savefile'' is being read, the byte order and PF_
values are
.I not
necessarily those of the machine reading the capture file.
.TP 5
.BR DLT_EN10MB "; " LINKTYPE_ETHERNET = 1
Ethernet (10Mb, 100Mb, 1000Mb, and up); the
.B 10MB
in the
.B DLT_
name is historical.
.TP 5
.BR DLT_IEEE802 "; " LINKTYPE_TOKEN_RING = 6
IEEE 802.5 Token Ring; the
.B IEEE802
in the
.B DLT_
name is historical.
.TP 5
.BR DLT_ARCNET "; " LINKTYPE_ARCNET = 7
ARCNET
.TP 5
.BR DLT_SLIP "; " LINKTYPE_SLIP = 8
SLIP; the link layer header contains, in order:
.RS 10
.LP
a 1-byte flag, which is 0 for packets received by the machine and 1 for
packets sent by the machine;
.LP
a 1-byte field, the upper 4 bits of which indicate the type of packet,
as per RFC 1144:
.RS 5
.TP 5
0x40
an unmodified IP datagram (TYPE_IP);
.TP 5
0x70
an uncompressed-TCP IP datagram (UNCOMPRESSED_TCP), with that byte being
the first byte of the raw IP header on the wire, containing the
connection number in the protocol field;
.TP 5
0x80
a compressed-TCP IP datagram (COMPRESSED_TCP), with that byte being the
first byte of the compressed TCP/IP datagram header;
.RE
.LP
for UNCOMPRESSED_TCP, the rest of the modified IP header, and for
COMPRESSED_TCP, the compressed TCP/IP datagram header;
.RE
.RS 5
.LP
for a total of 16 bytes; the uncompressed IP datagram follows the header.
.RE
.TP 5
.BR DLT_PPP "; " LINKTYPE_PPP = 9
PPP; if the first 2 bytes are 0xff and 0x03, it's PPP in HDLC-like
framing, with the PPP header following those two bytes, otherwise it's
PPP without framing, and the packet begins with the PPP header.
.TP 5
.BR DLT_FDDI "; " LINKTYPE_FDDI = 10
FDDI
.TP 5
.BR DLT_ATM_RFC1483 "; " LINKTYPE_ATM_RFC1483 = 100
RFC 1483 LLC/SNAP-encapsulated ATM; the packet begins with an IEEE 802.2
LLC header.
.TP 5
.BR DLT_RAW "; " LINKTYPE_RAW = 101
raw IP; the packet begins with an IP header.
.TP 5
.BR DLT_PPP_SERIAL "; " LINKTYPE_PPP_HDLC = 50
PPP in HDLC-like framing, as per RFC 1662, or Cisco PPP with HDLC
framing, as per section 4.3.1 of RFC 1547; the first byte will be 0xFF
for PPP in HDLC-like framing, and will be 0x0F or 0x8F for Cisco PPP
with HDLC framing.
.TP 5
.BR DLT_PPP_ETHER "; " LINKTYPE_PPP_ETHER = 51
PPPoE; the packet begins with a PPPoE header, as per RFC 2516.
.TP 5
.BR DLT_C_HDLC "; " LINKTYPE_C_HDLC = 104
Cisco PPP with HDLC framing, as per section 4.3.1 of RFC 1547.
.TP 5
.BR DLT_IEEE802_11 "; " LINKTYPE_IEEE802_11 = 105
IEEE 802.11 wireless LAN
.TP 5
.BR DLT_FRELAY "; " LINKTYPE_FRELAY = 107
Frame Relay
.TP 5
.BR DLT_LOOP "; " LINKTYPE_LOOP = 108
OpenBSD loopback encapsulation; the link layer header is a 4-byte field, in
.I network
byte order, containing a PF_ value from OpenBSD's
.B socket.h
for the network-layer protocol of the packet.
.IP
Note that, if a ``savefile'' is being read, those PF_ values are
.I not
necessarily those of the machine reading the capture file.
.TP 5
.BR DLT_LINUX_SLL "; " LINKTYPE_LINUX_SLL = 113
Linux "cooked" capture encapsulation; the link layer header contains, in
order:
.RS 10
.LP
a 2-byte "packet type", in network byte order, which is one of:
.RS 5
.TP 5
0
packet was sent to us by somebody else
.TP 5
1
packet was broadcast by somebody else
.TP 5
2
packet was multicast, but not broadcast, by somebody else
.TP 5
3
packet was sent by somebody else to somebody else
.TP 5
4
packet was sent by us
.RE
.LP
a 2-byte field, in network byte order, containing a Linux ARPHRD_ value
for the link layer device type;
.LP
a 2-byte field, in network byte order, containing the length of the
link layer address of the sender of the packet (which could be 0);
.LP
an 8-byte field containing that number of bytes of the link layer header
(if there are more than 8 bytes, only the first 8 are present);
.LP
a 2-byte field containing an Ethernet protocol type, in network byte
order, or containing 1 for Novell 802.3 frames without an 802.2 LLC
header or 4 for frames beginning with an 802.2 LLC header.
.RE
.TP 5
.BR DLT_LTALK "; " LINKTYPE_LTALK = 104
Apple LocalTalk; the packet begins with an AppleTalk LLAP header.
.TP 5
.BR DLT_PFLOG "; " LINKTYPE_PFLOG = 117
OpenBSD pflog; the link layer header contains a
.B "struct pfloghdr"
structure, as defined by the host on which the file was saved. (This
differs from operating system to operating system and release to
release; there is nothing in the file to indicate what the layout of
that structure is.)
.TP 5
.BR DLT_PRISM_HEADER "; " LINKTYPE_PRISM_HEADER = 119
Prism monitor mode information followed by an 802.11 header.
.TP 5
.BR DLT_IP_OVER_FC "; " LINKTYPE_IP_OVER_FC = 122
RFC 2625 IP-over-Fibre Channel, with the link-layer header being the
Network_Header as described in that RFC.
.TP 5
.BR DLT_SUNATM "; " LINKTYPE_SUNATM = 123
SunATM devices; the link layer header contains, in order:
.RS 10
.LP
a 1-byte flag field, containing a direction flag in the uppermost bit,
which is set for packets transmitted by the machine and clear for
packets received by the machine, and a 4-byte traffic type in the
low-order 4 bits, which is one of:
.RS 5
.TP 5
0
raw traffic
.TP 5
1
LANE traffic
.TP 5
2
LLC-encapsulated traffic
.TP 5
3
MARS traffic
.TP 5
4
IFMP traffic
.TP 5
5
ILMI traffic
.TP 5
6
Q.2931 traffic
.RE
.LP
a 1-byte VPI value;
.LP
a 2-byte VCI field, in network byte order.
.RE
.TP 5
.BR DLT_IEEE802_11_RADIO "; " LINKTYPE_IEEE802_11_RADIO = 127
link-layer information followed by an 802.11 header - see
http://www.shaftnet.org/~pizza/software/capturefrm.txt for a description
of the link-layer information.
.TP 5
.BR DLT_ARCNET_LINUX "; " LINKTYPE_ARCNET_LINUX = 129
ARCNET, with no exception frames, reassembled packets rather than raw
frames, and an extra 16-bit offset field between the destination host
and type bytes.
.TP 5
.BR DLT_LINUX_IRDA "; " LINKTYPE_LINUX_IRDA = 144
Linux-IrDA packets, with a
.B DLT_LINUX_SLL
header followed by the IrLAP header.
.TP 5
.BR DLT_LINUX_LAPD "; " LINKTYPE_LINUX_LAPD = 177
LAPD (Q.921) frames, with a
.B DLT_LINUX_SLL
header captured via vISDN.
.RE
.SH SEE ALSO
pcap_datalink(3PCAP)

File diff suppressed because it is too large Load Diff

View File

@ -30,60 +30,13 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#) $Header: /tcpdump/master/libpcap/pcap-namedb.h,v 1.10.2.1 2005/04/19 04:26:08 guy Exp $ (LBL)
* @(#) $Header: /tcpdump/master/libpcap/pcap-namedb.h,v 1.13 2006/10/04 18:13:32 guy Exp $ (LBL)
*/
#ifndef lib_pcap_namedb_h
#define lib_pcap_namedb_h
#ifdef __cplusplus
extern "C" {
#endif
/*
* As returned by the pcap_next_etherent()
* XXX this stuff doesn't belong in this interface, but this
* library already must do name to address translation, so
* on systems that don't have support for /etc/ethers, we
* export these hooks since they'll
* For backwards compatibility.
*
* Note to OS vendors: do NOT get rid of this file! Some applications
* might expect to be able to include <pcap-namedb.h>.
*/
struct pcap_etherent {
u_char addr[6];
char name[122];
};
#ifndef PCAP_ETHERS_FILE
#define PCAP_ETHERS_FILE "/etc/ethers"
#endif
struct pcap_etherent *pcap_next_etherent(FILE *);
u_char *pcap_ether_hostton(const char*);
u_char *pcap_ether_aton(const char *);
bpf_u_int32 **pcap_nametoaddr(const char *);
#ifdef INET6
struct addrinfo *pcap_nametoaddrinfo(const char *);
#endif
bpf_u_int32 pcap_nametonetaddr(const char *);
int pcap_nametoport(const char *, int *, int *);
int pcap_nametoportrange(const char *, int *, int *, int *);
int pcap_nametoproto(const char *);
int pcap_nametoeproto(const char *);
int pcap_nametollc(const char *);
/*
* If a protocol is unknown, PROTO_UNDEF is returned.
* Also, pcap_nametoport() returns the protocol along with the port number.
* If there are ambiguous entried in /etc/services (i.e. domain
* can be either tcp or udp) PROTO_UNDEF is returned.
*/
#define PROTO_UNDEF -1
/* XXX move these to pcap-int.h? */
int __pcap_atodn(const char *, bpf_u_int32 *);
int __pcap_atoin(const char *, bpf_u_int32 *);
u_short __pcap_nametodnaddr(const char *);
#ifdef __cplusplus
}
#endif
#endif
#include <pcap/namedb.h>

View File

@ -20,7 +20,7 @@
*/
#ifndef lint
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/pcap-nit.c,v 1.57.2.1 2005/05/03 18:54:37 guy Exp $ (LBL)";
"@(#) $Header: /tcpdump/master/libpcap/pcap-nit.c,v 1.58.2.4 2008-04-14 20:41:52 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@ -99,7 +99,6 @@ static int
pcap_read_nit(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
{
register int cc, n;
register struct bpf_insn *fcode = p->fcode.bf_insns;
register u_char *bp, *cp, *ep;
register struct nit_hdr *nh;
register int caplen;
@ -175,13 +174,13 @@ pcap_read_nit(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
caplen = nh->nh_wirelen;
if (caplen > p->snapshot)
caplen = p->snapshot;
if (bpf_filter(fcode, cp, nh->nh_wirelen, caplen)) {
if (bpf_filter(p->fcode.bf_insns, cp, nh->nh_wirelen, caplen)) {
struct pcap_pkthdr h;
h.ts = nh->nh_timestamp;
h.len = nh->nh_wirelen;
h.caplen = caplen;
(*callback)(user, &h, cp);
if (++n >= cnt && cnt >= 0) {
if (++n >= cnt && cnt > 0) {
p->cc = ep - bp;
p->bp = bp;
return (n);
@ -238,51 +237,43 @@ nit_setflags(int fd, int promisc, int to_ms, char *ebuf)
return (0);
}
static void
pcap_close_nit(pcap_t *p)
{
pcap_close_common(p);
if (p->device != NULL)
free(p->device);
}
pcap_t *
pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
char *ebuf)
static int
pcap_activate_nit(pcap_t *p)
{
int fd;
struct sockaddr_nit snit;
register pcap_t *p;
p = (pcap_t *)malloc(sizeof(*p));
if (p == NULL) {
strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
return (NULL);
if (p->opt.rfmon) {
/*
* No monitor mode on SunOS 3.x or earlier (no
* Wi-Fi *devices* for the hardware that supported
* them!).
*/
return (PCAP_ERROR_RFMON_NOTSUP);
}
if (snaplen < 96)
if (p->snapshot < 96)
/*
* NIT requires a snapshot length of at least 96.
*/
snaplen = 96;
p->snapshot = 96;
memset(p, 0, sizeof(*p));
p->fd = fd = socket(AF_NIT, SOCK_RAW, NITPROTO_RAW);
if (fd < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE,
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"socket: %s", pcap_strerror(errno));
goto bad;
}
snit.snit_family = AF_NIT;
(void)strncpy(snit.snit_ifname, device, NITIFSIZ);
(void)strncpy(snit.snit_ifname, p->opt.source, NITIFSIZ);
if (bind(fd, (struct sockaddr *)&snit, sizeof(snit))) {
snprintf(ebuf, PCAP_ERRBUF_SIZE,
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"bind: %s: %s", snit.snit_ifname, pcap_strerror(errno));
goto bad;
}
p->snapshot = snaplen;
nit_setflags(p->fd, promisc, to_ms, ebuf);
nit_setflags(p->fd, p->opt.promisc, p->md.timeout, p->errbuf);
/*
* NIT supports only ethernets.
@ -292,17 +283,7 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
p->bufsize = BUFSPACE;
p->buffer = (u_char *)malloc(p->bufsize);
if (p->buffer == NULL) {
strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
goto bad;
}
/*
* We need the device name in order to send packets.
*/
p->device = strdup(device);
if (p->device == NULL) {
strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
free(p->buffer);
strlcpy(p->errbuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
goto bad;
}
@ -339,14 +320,23 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
p->getnonblock_op = pcap_getnonblock_fd;
p->setnonblock_op = pcap_setnonblock_fd;
p->stats_op = pcap_stats_nit;
p->close_op = pcap_close_nit;
return (p);
return (0);
bad:
if (fd >= 0)
close(fd);
free(p);
return (NULL);
return (PCAP_ERROR);
}
pcap_t *
pcap_create(const char *device, char *ebuf)
{
pcap_t *p;
p = pcap_create_common(device, ebuf);
if (p == NULL)
return (NULL);
p->activate_op = pcap_activate_nit;
return (p);
}
int

View File

@ -1,19 +0,0 @@
/*
* Copyright (c) 1990, 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Lawrence Berkeley Laboratory,
* Berkeley, CA. The name of the University may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* @(#) $Header: /tcpdump/master/libpcap/pcap-nit.h,v 1.2.1.1 1999/10/07 23:46:40 mcr Exp $ (LBL)
*/

View File

@ -20,7 +20,7 @@
*/
#ifndef lint
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/pcap-null.c,v 1.21 2003/11/15 23:24:03 guy Exp $ (LBL)";
"@(#) $Header: /tcpdump/master/libpcap/pcap-null.c,v 1.21.4.1 2008-04-04 19:39:06 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@ -40,10 +40,9 @@ static const char rcsid[] _U_ =
static char nosup[] = "live packet capture not supported on this system";
pcap_t *
pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
char *ebuf)
pcap_activate(pcap_t *p)
{
(void)strlcpy(ebuf, nosup, PCAP_ERRBUF_SIZE);
(void)strlcpy(p->errbuf, nosup, PCAP_ERRBUF_SIZE);
return (NULL);
}

View File

@ -24,7 +24,7 @@
#ifndef lint
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/pcap-pf.c,v 1.91.2.2 2005/05/03 18:54:37 guy Exp $ (LBL)";
"@(#) $Header: /tcpdump/master/libpcap/pcap-pf.c,v 1.94.2.3 2008-04-14 20:41:52 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@ -62,7 +62,7 @@ struct rtentry;
#include <unistd.h>
/*
* Make "pcap.h" not include "pcap-bpf.h"; we are going to include the
* Make "pcap.h" not include "pcap/bpf.h"; we are going to include the
* native OS version, as we need various BPF ioctls from it.
*/
#define PCAP_DONT_INCLUDE_PCAP_BPF_H
@ -88,7 +88,6 @@ static int
pcap_read_pf(pcap_t *pc, int cnt, pcap_handler callback, u_char *user)
{
register u_char *p, *bp;
struct bpf_insn *fcode;
register int cc, n, buflen, inc;
register struct enstamp *sp;
#ifdef LBL_ALIGN
@ -98,7 +97,6 @@ pcap_read_pf(pcap_t *pc, int cnt, pcap_handler callback, u_char *user)
register int pad;
#endif
fcode = pc->md.use_bpf ? NULL : pc->fcode.bf_insns;
again:
cc = pc->cc;
if (cc == 0) {
@ -187,7 +185,8 @@ pcap_read_pf(pcap_t *pc, int cnt, pcap_handler callback, u_char *user)
/*
* Short-circuit evaluation: if using BPF filter
* in kernel, no need to do it now.
* in kernel, no need to do it now - we already know
* the packet passed the filter.
*
#ifdef PCAP_FDDIPAD
* Note: the filter code was generated assuming
@ -197,8 +196,8 @@ pcap_read_pf(pcap_t *pc, int cnt, pcap_handler callback, u_char *user)
* skipping that padding.
#endif
*/
if (fcode == NULL ||
bpf_filter(fcode, p, sp->ens_count, buflen)) {
if (pc->md.use_bpf ||
bpf_filter(pc->fcode.bf_insns, p, sp->ens_count, buflen)) {
struct pcap_pkthdr h;
pc->md.TotAccepted++;
h.ts = sp->ens_tstamp;
@ -285,30 +284,21 @@ pcap_stats_pf(pcap_t *p, struct pcap_stat *ps)
}
/*
* We include the OS's <net/bpf.h>, not our "pcap-bpf.h", so we probably
* We include the OS's <net/bpf.h>, not our "pcap/bpf.h", so we probably
* don't get DLT_DOCSIS defined.
*/
#ifndef DLT_DOCSIS
#define DLT_DOCSIS 143
#endif
pcap_t *
pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
char *ebuf)
static int
pcap_activate_pf(pcap_t *p)
{
pcap_t *p;
short enmode;
int backlog = -1; /* request the most */
struct enfilter Filter;
struct endevp devparams;
p = (pcap_t *)malloc(sizeof(*p));
if (p == NULL) {
snprintf(ebuf, PCAP_ERRBUF_SIZE,
"pcap_open_live: %s", pcap_strerror(errno));
return (0);
}
memset(p, 0, sizeof(*p));
/*
* Initially try a read/write open (to allow the inject
* method to work). If that fails due to permission
@ -328,21 +318,21 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
* "const char *" as its first argument. That appears to be
* the case, at least on Digital UNIX 4.0.
*/
p->fd = pfopen(device, O_RDWR);
p->fd = pfopen(p->opt.source, O_RDWR);
if (p->fd == -1 && errno == EACCES)
p->fd = pfopen(device, O_RDONLY);
p->fd = pfopen(p->opt.source, O_RDONLY);
if (p->fd < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "pf open: %s: %s\n\
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "pf open: %s: %s\n\
your system may not be properly configured; see the packetfilter(4) man page\n",
device, pcap_strerror(errno));
p->opt.source, pcap_strerror(errno));
goto bad;
}
p->md.OrigMissed = -1;
enmode = ENTSTAMP|ENBATCH|ENNONEXCL;
if (promisc)
if (p->opt.promisc)
enmode |= ENPROMISC;
if (ioctl(p->fd, EIOCMBIS, (caddr_t)&enmode) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "EIOCMBIS: %s",
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCMBIS: %s",
pcap_strerror(errno));
goto bad;
}
@ -353,13 +343,13 @@ your system may not be properly configured; see the packetfilter(4) man page\n",
#endif
/* set the backlog */
if (ioctl(p->fd, EIOCSETW, (caddr_t)&backlog) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "EIOCSETW: %s",
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCSETW: %s",
pcap_strerror(errno));
goto bad;
}
/* discover interface type */
if (ioctl(p->fd, EIOCDEVP, (caddr_t)&devparams) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "EIOCDEVP: %s",
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCDEVP: %s",
pcap_strerror(errno));
goto bad;
}
@ -441,8 +431,8 @@ your system may not be properly configured; see the packetfilter(4) man page\n",
* framing", there's not much we can do, as that
* doesn't specify a particular type of header.
*/
snprintf(ebuf, PCAP_ERRBUF_SIZE, "unknown data-link type %u",
devparams.end_dev_type);
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"unknown data-link type %u", devparams.end_dev_type);
goto bad;
}
/* set truncation */
@ -451,32 +441,31 @@ your system may not be properly configured; see the packetfilter(4) man page\n",
p->fddipad = PCAP_FDDIPAD;
/* packetfilter includes the padding in the snapshot */
snaplen += PCAP_FDDIPAD;
p->snapshot += PCAP_FDDIPAD;
} else
p->fddipad = 0;
#endif
if (ioctl(p->fd, EIOCTRUNCATE, (caddr_t)&snaplen) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "EIOCTRUNCATE: %s",
if (ioctl(p->fd, EIOCTRUNCATE, (caddr_t)&p->snapshot) < 0) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCTRUNCATE: %s",
pcap_strerror(errno));
goto bad;
}
p->snapshot = snaplen;
/* accept all packets */
memset(&Filter, 0, sizeof(Filter));
Filter.enf_Priority = 37; /* anything > 2 */
Filter.enf_FilterLen = 0; /* means "always true" */
if (ioctl(p->fd, EIOCSETF, (caddr_t)&Filter) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "EIOCSETF: %s",
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCSETF: %s",
pcap_strerror(errno));
goto bad;
}
if (to_ms != 0) {
if (p->md.timeout != 0) {
struct timeval timeout;
timeout.tv_sec = to_ms / 1000;
timeout.tv_usec = (to_ms * 1000) % 1000000;
timeout.tv_sec = p->md.timeout / 1000;
timeout.tv_usec = (p->md.timeout * 1000) % 1000000;
if (ioctl(p->fd, EIOCSRTIMEOUT, (caddr_t)&timeout) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "EIOCSRTIMEOUT: %s",
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCSRTIMEOUT: %s",
pcap_strerror(errno));
goto bad;
}
@ -485,7 +474,7 @@ your system may not be properly configured; see the packetfilter(4) man page\n",
p->bufsize = BUFSPACE;
p->buffer = (u_char*)malloc(p->bufsize + p->offset);
if (p->buffer == NULL) {
strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
strlcpy(p->errbuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
goto bad;
}
@ -502,19 +491,23 @@ your system may not be properly configured; see the packetfilter(4) man page\n",
p->getnonblock_op = pcap_getnonblock_fd;
p->setnonblock_op = pcap_setnonblock_fd;
p->stats_op = pcap_stats_pf;
p->close_op = pcap_close_common;
return (p);
return (0);
bad:
if (p->fd >= 0)
close(p->fd);
/*
* Get rid of any link-layer type list we allocated.
*/
if (p->dlt_list != NULL)
free(p->dlt_list);
free(p);
return (NULL);
return (PCAP_ERROR);
}
pcap_t *
pcap_create(const char *device, char *ebuf)
{
pcap_t *p;
p = pcap_create_common(device, ebuf);
if (p == NULL)
return (NULL);
p->activate_op = pcap_activate_pf;
return (p);
}
int

View File

@ -1,19 +0,0 @@
/*
* Copyright (c) 1990, 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Lawrence Berkeley Laboratory,
* Berkeley, CA. The name of the University may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* @(#) $Header: /tcpdump/master/libpcap/pcap-pf.h,v 1.2.1.1 1999/10/07 23:46:40 mcr Exp $ (LBL)
*/

127
pcap-savefile.manfile.in Normal file
View File

@ -0,0 +1,127 @@
'\" t
.\" @(#) $Header: /tcpdump/master/libpcap/pcap-savefile.manfile.in,v 1.1.2.3 2008-10-24 07:34:06 guy Exp $
.\"
.\" Copyright (c) 1994, 1996, 1997
.\" The Regents of the University of California. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that: (1) source code distributions
.\" retain the above copyright notice and this paragraph in its entirety, (2)
.\" distributions including binary code include the above copyright notice and
.\" this paragraph in its entirety in the documentation or other materials
.\" provided with the distribution, and (3) all advertising materials mentioning
.\" features or use of this software display the following acknowledgement:
.\" ``This product includes software developed by the University of California,
.\" Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
.\" the University nor the names of its contributors may be used to endorse
.\" or promote products derived from this software without specific prior
.\" written permission.
.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\"
.TH PCAP-SAVEFILE @MAN_FILE_FORMATS@ "21 October 2008"
.SH NAME
pcap-savefile \- libpcap savefile format
.SH DESCRIPTION
NOTE: applications and libraries should, if possible, use libpcap to
read savefiles, rather than having their own code to read savefiles.
If, in the future, a new file format is supported by libpcap,
applications and libraries using libpcap to read savefiles will be able
to read the new format of savefiles, but applications and libraries
using their own code to read savefiles will have to be changed to
support the new file format.
.PP
``Savefiles'' read and written by libpcap and applications using libpcap
start with a per-file header. The format of the per-file header is:
.RS
.TS
box;
c s
c | c
c s.
Magic number
_
Major version Minor version
_
Time zone offset
_
Time stamp accuracy
_
Snapshot length
_
Link-layer header type
.TE
.RE
.PP
All fields in the per-file header are in the byte order of the host
writing the file. The first field in the per-file header is a 4-byte
magic number, with the value 0xa1b2c3d4. The magic number, when read by
a host with the same byte order as the host that wrote the file, will
have the value 0xa1b2c3d4, and, when read by a host with the opposite
byte order as the host that wrote the file, will have the value
0xd4c3b2a1. That allows software reading the file to determine whether
the byte order of the host that wrote the file is the same as the byte
order of the host on which the file is being read, and thus whether the
values in the per-file and per-packet headers need to be byte-swapped.
.PP
Following this are:
.IP
A 2-byte file format major version number; the current version number is
2.
.IP
A 2-byte file format minor version number; the current version number is
4.
.IP
A 4-byte time zone offset; this is always 0.
.IP
A 4-byte number giving the accuracy of time stamps in the file; this is
always 0.
.IP
A 4-byte number giving the "snapshot length" of the capture; packets
longer than the snapshot length are truncated to the snapshot length, so
that, if the snapshot length is
.IR N ,
only the first
.I N
bytes of a packet longer than
.I N
bytes will be saved in the capture.
.IP
a 4-byte number giving the link-layer header type for packets in the
capture; see
.BR pcap-linktype (@MAN_MISC_INFO@)
for the
.B LINKTYPE_
values that can appear in this field.
.PP
Following the per-file header are zero or more packets; each packet
begins with a per-packet header, which is immediately followed by the
raw packet data. The format of the per-packet header is:
.RS
.TS
box;
c.
Time stamp, seconds value
_
Time stamp, microseconds value
_
Length of captured packet data
_
Un-truncated length of the packet data
.TE
.RE
.PP
All fields in the per-packet header are in the byte order of the host
writing the file. The per-packet header begins with a time stamp giving
the approximate time the packet was captured; the time stamp consists of
a 4-byte value, giving the time in seconds since January 1, 1970,
00:00:00 UTC, followed by a 4-byte value, giving the time in
microseconds since that second. Following that are a 4-byte value
giving the number of bytes of captured data that follow the per-packet
header and a 4-byte value giving the number of bytes that would have
been present had the packet not been truncated by the snapshot length.
The two lengths will be equal if the number of bytes of packet data are
less than or equal to the snapshot length.
.SH SEE ALSO
pcap(3PCAP), pcap-linktype(@MAN_MISC_INFO@)

View File

@ -16,7 +16,7 @@
#ifndef lint
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/pcap-septel.c,v 1.1.2.2 2005/06/21 01:03:23 guy Exp $";
"@(#) $Header: /tcpdump/master/libpcap/pcap-septel.c,v 1.2.2.2 2008-04-14 20:41:52 guy Exp $";
#endif
#ifdef HAVE_CONFIG_H
@ -50,8 +50,8 @@ static const char rcsid[] _U_ =
/* This code is required when compiling for a Septel device only. */
#include "pcap-septel.h"
/* Replace dag function names with pcap equivalent. */
#define septel_open_live pcap_open_live
/* Replace septel function names with pcap equivalent. */
#define septel_create pcap_create
#define septel_platform_finddevs pcap_platform_finddevs
#endif /* SEPTEL_ONLY */
@ -59,12 +59,6 @@ static int septel_setfilter(pcap_t *p, struct bpf_program *fp);
static int septel_stats(pcap_t *p, struct pcap_stat *ps);
static int septel_setnonblock(pcap_t *p, int nonblock, char *errbuf);
static void septel_platform_close(pcap_t *p) {
}
/*
* Read at most max_packets from the capture queue and call the callback
* for each of them. Returns the number of packets handled, -1 if an
@ -199,28 +193,14 @@ septel_inject(pcap_t *handle, const void *buf _U_, size_t size _U_)
}
/*
* Get a handle for a live capture from the given Septel device. Always pass a NULL device
* Activate a handle for a live capture from the given Septel device. Always pass a NULL device
* The promisc flag is ignored because Septel cards have built-in tracing.
* The to_ms parameter is also ignored as it is
* not supported in hardware.
* The timeout is also ignored as it is not supported in hardware.
*
* See also pcap(3).
*/
pcap_t *septel_open_live(const char *device, int snaplen, int promisc, int to_ms, char *ebuf) {
pcap_t *handle;
handle = malloc(sizeof(*handle));
if (handle == NULL) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc %s: %s", device, pcap_strerror(errno));
return NULL;
}
/* Initialize some components of the pcap structure. */
memset(handle, 0, sizeof(*handle));
handle->snapshot = snaplen;
static pcap_t *septel_activate(pcap_t* handle) {
/* Initialize some components of the pcap structure. */
handle->linktype = DLT_MTP2;
handle->bufsize = 0;
@ -237,16 +217,19 @@ pcap_t *septel_open_live(const char *device, int snaplen, int promisc, int to_ms
handle->getnonblock_op = pcap_getnonblock_fd;
handle->setnonblock_op = septel_setnonblock;
handle->stats_op = septel_stats;
handle->close_op = septel_platform_close;
return handle;
return 0;
}
fail:
if (handle != NULL) {
free(handle);
}
pcap_t *septel_create(const char *device, char *ebuf) {
pcap_t *p;
return NULL;
p = pcap_create_common(device, ebuf);
if (p == NULL)
return NULL;
p->activate_op = septel_activate;
return p;
}
static int septel_stats(pcap_t *p, struct pcap_stat *ps) {

View File

@ -8,8 +8,8 @@
* Authors: Gilbert HOYEK (gil_hoyek@hotmail.com), Elias M. KHOURY
* (+961 3 485343);
*
* @(#) $Header: /tcpdump/master/libpcap/pcap-septel.h,v 1.1.2.1 2005/06/20 21:30:19 guy Exp $
* @(#) $Header: /tcpdump/master/libpcap/pcap-septel.h,v 1.1.4.1 2008-04-04 19:39:06 guy Exp $
*/
pcap_t *septel_open_live(const char *device, int snaplen, int promisc, int to_ms, char *ebuf);
pcap_t *septel_create(const char *device, char *ebuf);

980
pcap-sita.c Normal file
View File

@ -0,0 +1,980 @@
/*
* pcap-sita.c: Packet capture interface additions for SITA ACN devices
*
* Copyright (c) 2007 Fulko Hew, SITA INC Canada, Inc <fulko.hew@sita.aero>
*
* 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.
*/
/* $Id: pcap-sita.c */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "pcap-int.h"
#include "pcap-sita.h"
/* non-configureable manifests follow */
#define IOP_SNIFFER_PORT 49152 /* TCP port on the IOP used for 'distributed pcap' usage */
#define MAX_LINE_SIZE 255 /* max size of a buffer/line in /etc/hosts we allow */
#define MAX_CHASSIS 8 /* number of chassis in an ACN site */
#define MAX_GEOSLOT 8 /* max number of access units in an ACN site */
#define FIND 0
#define LIVE 1
typedef struct iface {
struct iface *next; /* a pointer to the next interface */
char *name; /* this interface's name on Wireshark */
char *IOPname; /* this interface's name on an IOP */
uint32_t iftype; /* the type of interface (DLT values) */
} iface_t;
typedef struct unit {
char *ip; /* this unit's IP address (as extracted from /etc/hosts) */
int fd; /* the connection to this unit (if it exists) */
int find_fd; /* a big kludge to avoid my programming limitations since I could have this unit open for findalldevs purposes */
int first_time; /* 0 = just opened via acn_open_live(), ie. the first time, NZ = nth time */
struct sockaddr_in *serv_addr; /* the address control block for comms to this unit */
int chassis;
int geoslot;
iface_t *iface; /* a pointer to a linked list of interface structures */
char *imsg; /* a pointer to an inbound message */
int len; /* the current size of the inbound message */
} unit_t;
static char *errorString;
static unit_t units[MAX_CHASSIS+1][MAX_GEOSLOT+1]; /* we use indexes of 1 through 8, but we reserve/waste index 0 */
static fd_set readfds; /* a place to store the file descriptors for the connections to the IOPs */
static fd_set working_set;
static int max_fs;
static char static_buf[32];
pcap_if_t *acn_if_list; /* pcap's list of available interfaces */
static void dump_interface_list(void) {
pcap_if_t *iff;
pcap_addr_t *addr;
int longest_name_len = 0;
char *n, *d, *f;
int if_number = 0;
iff = acn_if_list;
while (iff) {
if (iff->name && (strlen(iff->name) > longest_name_len)) longest_name_len = strlen(iff->name);
iff = iff->next;
}
iff = acn_if_list;
printf("Interface List:\n");
while (iff) {
n = (iff->name) ? iff->name : "";
d = (iff->description) ? iff->description : "";
f = (iff->flags == PCAP_IF_LOOPBACK) ? "L" : "";
printf("%3d: %*s %s '%s'\n", if_number++, longest_name_len, n, f, d);
addr = iff->addresses;
while (addr) {
printf("%*s ", (5 + longest_name_len), ""); /* add some indentation */
printf("%15s ", (addr->addr) ? inet_ntoa(((struct sockaddr_in *)addr->addr)->sin_addr) : "");
printf("%15s ", (addr->netmask) ? inet_ntoa(((struct sockaddr_in *)addr->netmask)->sin_addr) : "");
printf("%15s ", (addr->broadaddr) ? inet_ntoa(((struct sockaddr_in *)addr->broadaddr)->sin_addr) : "");
printf("%15s ", (addr->dstaddr) ? inet_ntoa(((struct sockaddr_in *)addr->dstaddr)->sin_addr) : "");
printf("\n");
addr = addr->next;
}
iff = iff->next;
}
}
static void dump(unsigned char *ptr, int i, int indent) {
fprintf(stderr, "%*s", indent, " ");
for (; i > 0; i--) {
fprintf(stderr, "%2.2x ", *ptr++);
}
fprintf(stderr, "\n");
}
static void dump_interface_list_p(void) {
pcap_if_t *iff;
pcap_addr_t *addr;
int if_number = 0;
iff = acn_if_list;
printf("Interface Pointer @ %p is %p:\n", &acn_if_list, iff);
while (iff) {
printf("%3d: %p %p next: %p\n", if_number++, iff->name, iff->description, iff->next);
dump((unsigned char *)iff, sizeof(pcap_if_t), 5);
addr = iff->addresses;
while (addr) {
printf(" %p %p %p %p, next: %p\n", addr->addr, addr->netmask, addr->broadaddr, addr->dstaddr, addr->next);
dump((unsigned char *)addr, sizeof(pcap_addr_t), 10);
addr = addr->next;
}
iff = iff->next;
}
}
static void dump_unit_table(void) {
int chassis, geoslot;
iface_t *p;
printf("%c:%c %s %s\n", 'C', 'S', "fd", "IP Address");
for (chassis = 0; chassis <= MAX_CHASSIS; chassis++) {
for (geoslot = 0; geoslot <= MAX_GEOSLOT; geoslot++) {
if (units[chassis][geoslot].ip != NULL)
printf("%d:%d %2d %s\n", chassis, geoslot, units[chassis][geoslot].fd, units[chassis][geoslot].ip);
p = units[chassis][geoslot].iface;
while (p) {
char *n = (p->name) ? p->name : "";
char *i = (p->IOPname) ? p->IOPname : "";
p = p->next;
printf(" %12s -> %12s\n", i, n);
}
}
}
}
static int find_unit_by_fd(int fd, int *chassis, int *geoslot, unit_t **unit_ptr) {
int c, s;
for (c = 0; c <= MAX_CHASSIS; c++) {
for (s = 0; s <= MAX_GEOSLOT; s++) {
if (units[c][s].fd == fd || units[c][s].find_fd == fd) {
if (chassis) *chassis = c;
if (geoslot) *geoslot = s;
if (unit_ptr) *unit_ptr = &units[c][s];
return 1;
}
}
}
return 0;
}
static int read_client_nbytes(int fd, int count, unsigned char *buf) {
unit_t *u;
int chassis, geoslot;
int len;
find_unit_by_fd(fd, &chassis, &geoslot, &u);
while (count) {
if ((len = recv(fd, buf, count, 0)) <= 0) return -1; /* read in whatever data was sent to us */
count -= len;
buf += len;
} /* till we have everything we are looking for */
return 0;
}
static void empty_unit_iface(unit_t *u) {
iface_t *p, *cur;
cur = u->iface;
while (cur) { /* loop over all the interface entries */
if (cur->name) free(cur->name); /* throwing away the contents if they exist */
if (cur->IOPname) free(cur->IOPname);
p = cur->next;
free(cur); /* then throw away the structure itself */
cur = p;
}
u->iface = 0; /* and finally remember that there are no remaining structure */
}
static void empty_unit(int chassis, int geoslot) {
unit_t *u = &units[chassis][geoslot];
empty_unit_iface(u);
if (u->imsg) { /* then if an inbound message buffer exists */
u->imsg = (char *)realloc(u->imsg, 1); /* and re-allocate the old large buffer into a new small one */
}
}
static void empty_unit_table(void) {
int chassis, geoslot;
for (chassis = 0; chassis <= MAX_CHASSIS; chassis++) {
for (geoslot = 0; geoslot <= MAX_GEOSLOT; geoslot++) {
if (units[chassis][geoslot].ip != NULL) {
free(units[chassis][geoslot].ip); /* get rid of the malloc'ed space that holds the IP address */
units[chassis][geoslot].ip = 0; /* then set the pointer to NULL */
}
empty_unit(chassis, geoslot);
}
}
}
static char *find_nth_interface_name(int n) {
int chassis, geoslot;
iface_t *p;
char *last_name = 0;
if (n < 0) n = 0; /* ensure we are working with a valid number */
for (chassis = 0; chassis <= MAX_CHASSIS; chassis++) { /* scan the table... */
for (geoslot = 0; geoslot <= MAX_GEOSLOT; geoslot++) {
if (units[chassis][geoslot].ip != NULL) {
p = units[chassis][geoslot].iface;
while (p) { /* and all interfaces... */
if (p->IOPname) last_name = p->name; /* remembering the last name found */
if (n-- == 0) return last_name; /* and if we hit the instance requested */
p = p->next;
}
}
}
}
/* if we couldn't fine the selected entry */
if (last_name) return last_name; /* ... but we did have at least one entry... return the last entry found */
return ""; /* ... but if there wasn't any entry... return an empty string instead */
}
int acn_parse_hosts_file(char *errbuf) { /* returns: -1 = error, 0 = OK */
FILE *fp;
char buf[MAX_LINE_SIZE];
char *ptr, *ptr2;
int pos;
int chassis, geoslot;
unit_t *u;
empty_unit_table();
if ((fp = fopen("/etc/hosts", "r")) == NULL) { /* try to open the hosts file and if it fails */
snprintf(errbuf, PCAP_ERRBUF_SIZE, "Cannot open '/etc/hosts' for reading."); /* return the nohostsfile error response */
return -1;
}
while (fgets(buf, MAX_LINE_SIZE-1, fp)) { /* while looping over the file */
pos = strcspn(buf, "#\n\r"); /* find the first comment character or EOL */
*(buf + pos) = '\0'; /* and clobber it and anything that follows it */
pos = strspn(buf, " \t"); /* then find the first non-white space */
if (pos == strlen(buf)) /* if there is nothing but white space on the line */
continue; /* ignore that empty line */
ptr = buf + pos; /* and skip over any of that leading whitespace */
if ((ptr2 = strstr(ptr, "_I_")) == NULL) /* skip any lines that don't have names that look like they belong to IOPs */
continue;
if (*(ptr2 + 4) != '_') /* and skip other lines that have names that don't look like ACN components */
continue;
*(ptr + strcspn(ptr, " \t")) = '\0'; /* null terminate the IP address so its a standalone string */
chassis = *(ptr2 + 3) - '0'; /* extract the chassis number */
geoslot = *(ptr2 + 5) - '0'; /* and geo-slot number */
if (chassis < 1 || chassis > MAX_CHASSIS ||
geoslot < 1 || geoslot > MAX_GEOSLOT) { /* if the chassis and/or slot numbers appear to be bad... */
snprintf(errbuf, PCAP_ERRBUF_SIZE, "Invalid ACN name in '/etc/hosts'."); /* warn the user */
continue; /* and ignore the entry */
}
if ((ptr2 = (char *)malloc(strlen(ptr) + 1)) == NULL) {
snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
continue;
}
strcpy(ptr2, ptr); /* copy the IP address into our malloc'ed memory */
u = &units[chassis][geoslot];
u->ip = ptr2; /* and remember the whole shebang */
u->chassis = chassis;
u->geoslot = geoslot;
}
fclose(fp);
if (*errbuf) return -1;
else return 0;
}
static int open_with_IOP(unit_t *u, int flag) {
int sockfd;
char *ip;
if (u->serv_addr == NULL) {
u->serv_addr = malloc(sizeof(struct sockaddr_in));
}
ip = u->ip;
bzero((char *)u->serv_addr, sizeof(struct sockaddr_in));
u->serv_addr->sin_family = AF_INET;
u->serv_addr->sin_addr.s_addr = inet_addr(ip);
u->serv_addr->sin_port = htons(IOP_SNIFFER_PORT);
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
fprintf(stderr, "pcap can't open a socket for connecting to IOP at %s\n", ip);
return 0;
}
if (connect(sockfd, (struct sockaddr *)u->serv_addr, sizeof(struct sockaddr_in)) < 0) {
fprintf(stderr, "pcap can't connect to IOP at %s\n", ip);
return 0;
}
if (flag == LIVE) u->fd = sockfd;
else u->find_fd = sockfd;
u->first_time = 0;
return sockfd; /* return the non-zero file descriptor as a 'success' indicator */
}
static void close_with_IOP(int chassis, int geoslot, int flag) {
int *id;
if (flag == LIVE) id = &units[chassis][geoslot].fd;
else id = &units[chassis][geoslot].find_fd;
if (*id) { /* this was the last time, so... if we are connected... */
close(*id); /* disconnect us */
*id = 0; /* and forget that the descriptor exists because we are not open */
}
}
static void pcap_cleanup_acn(pcap_t *handle) {
int chassis, geoslot;
unit_t *u;
if (find_unit_by_fd(handle->fd, &chassis, &geoslot, &u) == 0)
return;
close_with_IOP(chassis, geoslot, LIVE);
if (u)
u->first_time = 0;
pcap_cleanup_live_common(handle);
}
static void send_to_fd(int fd, int len, unsigned char *str) {
int nwritten;
int chassis, geoslot;
while (len > 0) {
if ((nwritten = write(fd, str, len)) <= 0) {
find_unit_by_fd(fd, &chassis, &geoslot, NULL);
if (units[chassis][geoslot].fd == fd) close_with_IOP(chassis, geoslot, LIVE);
else if (units[chassis][geoslot].find_fd == fd) close_with_IOP(chassis, geoslot, FIND);
empty_unit(chassis, geoslot);
return;
}
len -= nwritten;
str += nwritten;
}
}
static void acn_freealldevs(void) {
pcap_if_t *iff, *next_iff;
pcap_addr_t *addr, *next_addr;
for (iff = acn_if_list; iff != NULL; iff = next_iff) {
next_iff = iff->next;
for (addr = iff->addresses; addr != NULL; addr = next_addr) {
next_addr = addr->next;
if (addr->addr) free(addr->addr);
if (addr->netmask) free(addr->netmask);
if (addr->broadaddr) free(addr->broadaddr);
if (addr->dstaddr) free(addr->dstaddr);
free(addr);
}
if (iff->name) free(iff->name);
if (iff->description) free(iff->description);
free(iff);
}
}
static char *nonUnified_port_num(unit_t *u, int IOPportnum) {
sprintf(static_buf, "%d_%d", u->chassis, u->geoslot);
return static_buf;
}
static char *unified_port_num(unit_t *u, int IOPportnum) {
int portnum;
portnum = ((u->chassis - 1) * 64) + ((u->geoslot - 1) * 8) + IOPportnum + 1;
sprintf(static_buf, "%d", portnum);
return static_buf;
}
static char *translate_IOP_to_pcap_name(unit_t *u, char *IOPname, bpf_u_int32 iftype) {
iface_t *iface_ptr, *iface;
char *name;
char buf[32];
char *proto;
char *port;
int IOPportnum = 0;
iface = malloc(sizeof(iface_t)); /* get memory for a structure */
bzero((char *)iface, sizeof(iface_t));
iface->iftype = iftype; /* remember the interface type of this interface */
name = malloc(strlen(IOPname) + 1); /* get memory for the IOP's name */
strcpy(name, IOPname); /* and copy it in */
iface->IOPname = name; /* and stick it into the structure */
if (strncmp(IOPname, "lo", 2) == 0) {
IOPportnum = atoi(&IOPname[2]);
switch (iftype) {
case DLT_EN10MB: proto = "lo"; port = nonUnified_port_num(u, IOPportnum); break;
default: proto = "???"; port = unified_port_num(u, IOPportnum); break;
}
} else if (strncmp(IOPname, "eth", 3) == 0) {
IOPportnum = atoi(&IOPname[3]);
switch (iftype) {
case DLT_EN10MB: proto = "eth"; port = nonUnified_port_num(u, IOPportnum); break;
default: proto = "???"; port = unified_port_num(u, IOPportnum); break;
}
} else if (strncmp(IOPname, "wan", 3) == 0) {
IOPportnum = atoi(&IOPname[3]);
switch (iftype) {
case DLT_SITA: proto = "wan"; port = unified_port_num(u, IOPportnum); break;
default: proto = "???"; port = unified_port_num(u, IOPportnum); break;
}
}
sprintf(buf, "%s_%s", proto, port); /* compose the user's name for that IOP port name */
name = malloc(strlen(buf) + 1); /* get memory for that name */
strcpy(name, buf); /* and copy it in */
iface->name = name; /* and stick it into the structure */
if (u->iface == 0) { /* if this is the first name */
u->iface = iface; /* stick this entry at the head of the list */
} else {
iface_ptr = u->iface;
while (iface_ptr->next) { /* othewise scan the list */
iface_ptr = iface_ptr->next; /* till we're at the last entry */
}
iface_ptr->next = iface; /* then tack this entry on the end of the list */
}
return iface->name;
}
static int if_sort(char *s1, char *s2) {
char *s1_p2, *s2_p2;
char str1[MAX_LINE_SIZE], str2[MAX_LINE_SIZE];
int s1_p1_len, s2_p1_len;
int retval;
if ((s1_p2 = strchr(s1, '_'))) { /* if an underscore is found... */
s1_p1_len = s1_p2 - s1; /* the prefix length is the difference in pointers */
s1_p2++; /* the suffix actually starts _after_ the underscore */
} else { /* otherwise... */
s1_p1_len = strlen(s1); /* the prefix length is the length of the string itself */
s1_p2 = 0; /* and there is no suffix */
}
if ((s2_p2 = strchr(s2, '_'))) { /* now do the same for the second string */
s2_p1_len = s2_p2 - s2;
s2_p2++;
} else {
s2_p1_len = strlen(s2);
s2_p2 = 0;
}
strncpy(str1, s1, (s1_p1_len > sizeof(str1)) ? s1_p1_len : sizeof(str1)); *(str1 + s1_p1_len) = 0;
strncpy(str2, s2, (s2_p1_len > sizeof(str2)) ? s2_p1_len : sizeof(str2)); *(str2 + s2_p1_len) = 0;
retval = strcmp(str1, str2);
if (retval != 0) return retval; /* if they are not identical, then we can quit now and return the indication */
return strcmp(s1_p2, s2_p2); /* otherwise we return the result of comparing the 2nd half of the string */
}
static void sort_if_table(void) {
pcap_if_t *p1, *p2, *prev, *temp;
int has_swapped;
if (!acn_if_list) return; /* nothing to do if the list is empty */
while (1) {
p1 = acn_if_list; /* start at the head of the list */
prev = 0;
has_swapped = 0;
while ((p2 = p1->next)) {
if (if_sort(p1->name, p2->name) > 0) {
if (prev) { /* we are swapping things that are _not_ at the head of the list */
temp = p2->next;
prev->next = p2;
p2->next = p1;
p1->next = temp;
} else { /* special treatment if we are swapping with the head of the list */
temp = p2->next;
acn_if_list= p2;
p2->next = p1;
p1->next = temp;
}
p1 = p2;
prev = p1;
has_swapped = 1;
}
prev = p1;
p1 = p1->next;
}
if (has_swapped == 0)
return;
}
return;
}
static int process_client_data (char *errbuf) { /* returns: -1 = error, 0 = OK */
int chassis, geoslot;
unit_t *u;
pcap_if_t *iff, *prev_iff;
pcap_addr_t *addr, *prev_addr;
char *ptr;
int address_count;
struct sockaddr_in *s;
char *newname;
bpf_u_int32 interfaceType;
unsigned char flags;
prev_iff = 0;
for (chassis = 0; chassis <= MAX_CHASSIS; chassis++) {
for (geoslot = 0; geoslot <= MAX_GEOSLOT; geoslot++) { /* now loop over all the devices */
u = &units[chassis][geoslot];
empty_unit_iface(u);
ptr = u->imsg; /* point to the start of the msg for this IOP */
while (ptr < (u->imsg + u->len)) {
if ((iff = malloc(sizeof(pcap_if_t))) == NULL) {
snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
return -1;
}
bzero((char *)iff, sizeof(pcap_if_t));
if (acn_if_list == 0) acn_if_list = iff; /* remember the head of the list */
if (prev_iff) prev_iff->next = iff; /* insert a forward link */
if (*ptr) { /* if there is a count for the name */
if ((iff->name = malloc(*ptr + 1)) == NULL) { /* get that amount of space */
snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
return -1;
}
memcpy(iff->name, (ptr + 1), *ptr); /* copy the name into the malloc'ed space */
*(iff->name + *ptr) = 0; /* and null terminate the string */
ptr += *ptr; /* now move the pointer forwards by the length of the count plus the length of the string */
}
ptr++;
if (*ptr) { /* if there is a count for the description */
if ((iff->description = malloc(*ptr + 1)) == NULL) { /* get that amount of space */
snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
return -1;
}
memcpy(iff->description, (ptr + 1), *ptr); /* copy the name into the malloc'ed space */
*(iff->description + *ptr) = 0; /* and null terminate the string */
ptr += *ptr; /* now move the pointer forwards by the length of the count plus the length of the string */
}
ptr++;
interfaceType = ntohl(*(bpf_u_int32 *)ptr);
ptr += 4; /* skip over the interface type */
flags = *ptr++;
if (flags) iff->flags = PCAP_IF_LOOPBACK; /* if this is a loopback style interface, lets mark it as such */
address_count = *ptr++;
prev_addr = 0;
while (address_count--) {
if ((addr = malloc(sizeof(pcap_addr_t))) == NULL) {
snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
return -1;
}
bzero((char *)addr, sizeof(pcap_addr_t));
if (iff->addresses == 0) iff->addresses = addr;
if (prev_addr) prev_addr->next = addr; /* insert a forward link */
if (*ptr) { /* if there is a count for the address */
if ((s = malloc(sizeof(struct sockaddr_in))) == NULL) { /* get that amount of space */
snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
return -1;
}
bzero((char *)s, sizeof(struct sockaddr_in));
addr->addr = (struct sockaddr *)s;
s->sin_family = AF_INET;
s->sin_addr.s_addr = *(bpf_u_int32 *)(ptr + 1); /* copy the address in */
ptr += *ptr; /* now move the pointer forwards according to the specified length of the address */
}
ptr++; /* then forwards one more for the 'length of the address' field */
if (*ptr) { /* process any netmask */
if ((s = malloc(sizeof(struct sockaddr_in))) == NULL) {
snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
return -1;
}
bzero((char *)s, sizeof(struct sockaddr_in));
addr->netmask = (struct sockaddr *)s;
s->sin_family = AF_INET;
s->sin_addr.s_addr = *(bpf_u_int32*)(ptr + 1);
ptr += *ptr;
}
ptr++;
if (*ptr) { /* process any broadcast address */
if ((s = malloc(sizeof(struct sockaddr_in))) == NULL) {
snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
return -1;
}
bzero((char *)s, sizeof(struct sockaddr_in));
addr->broadaddr = (struct sockaddr *)s;
s->sin_family = AF_INET;
s->sin_addr.s_addr = *(bpf_u_int32*)(ptr + 1);
ptr += *ptr;
}
ptr++;
if (*ptr) { /* process any destination address */
if ((s = malloc(sizeof(struct sockaddr_in))) == NULL) {
snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
return -1;
}
bzero((char *)s, sizeof(struct sockaddr_in));
addr->dstaddr = (struct sockaddr *)s;
s->sin_family = AF_INET;
s->sin_addr.s_addr = *(bpf_u_int32*)(ptr + 1);
ptr += *ptr;
}
ptr++;
prev_addr = addr;
}
prev_iff = iff;
newname = translate_IOP_to_pcap_name(u, iff->name, interfaceType); /* add a translation entry and get a point to the mangled name */
if ((iff->name = realloc(iff->name, strlen(newname) + 1)) == NULL) { /* we now re-write the name stored in the interface list */
snprintf(errbuf, PCAP_ERRBUF_SIZE, "realloc: %s", pcap_strerror(errno));
return -1;
}
strcpy(iff->name, newname); /* to this new name */
}
}
}
return 0;
}
static int read_client_data (int fd) {
unsigned char buf[256];
int chassis, geoslot;
unit_t *u;
int len;
find_unit_by_fd(fd, &chassis, &geoslot, &u);
if ((len = recv(fd, buf, sizeof(buf), 0)) <= 0) return 0; /* read in whatever data was sent to us */
if ((u->imsg = realloc(u->imsg, (u->len + len))) == NULL) /* extend the buffer for the new data */
return 0;
memcpy((u->imsg + u->len), buf, len); /* append the new data */
u->len += len;
return 1;
}
static void wait_for_all_answers(void) {
int retval;
struct timeval tv;
int fd;
int chassis, geoslot;
tv.tv_sec = 2;
tv.tv_usec = 0;
while (1) {
int flag = 0;
for (fd = 0; fd <= max_fs; fd++) { /* scan the list of descriptors we may be listening to */
if (FD_ISSET(fd, &readfds)) flag = 1; /* and see if there are any still set */
}
if (flag == 0) return; /* we are done, when they are all gone */
memcpy(&working_set, &readfds, sizeof(readfds)); /* otherwise, we still have to listen for more stuff, till we timeout */
retval = select(max_fs + 1, &working_set, NULL, NULL, &tv);
if (retval == -1) { /* an error occured !!!!! */
return;
} else if (retval == 0) { /* timeout occured, so process what we've got sofar and return */
printf("timeout\n");
return;
} else {
for (fd = 0; fd <= max_fs; fd++) { /* scan the list of things to do, and do them */
if (FD_ISSET(fd, &working_set)) {
if (read_client_data(fd) == 0) { /* if the socket has closed */
FD_CLR(fd, &readfds); /* and descriptors we listen to for errors */
find_unit_by_fd(fd, &chassis, &geoslot, NULL);
close_with_IOP(chassis, geoslot, FIND); /* and close out connection to him */
}
}
}
}
}
}
static char *get_error_response(int fd, char *errbuf) { /* return a pointer on error, NULL on no error */
char byte;
int len = 0;
while (1) {
recv(fd, &byte, 1, 0); /* read another byte in */
if (errbuf && (len++ < PCAP_ERRBUF_SIZE)) { /* and if there is still room in the buffer */
*errbuf++ = byte; /* stick it in */
*errbuf = '\0'; /* ensure the string is null terminated just in case we might exceed the buffer's size */
}
if (byte == '\0') {
if (len > 1) { return errbuf; }
else { return NULL; }
}
}
}
int acn_findalldevs(char *errbuf) { /* returns: -1 = error, 0 = OK */
int chassis, geoslot;
unit_t *u;
FD_ZERO(&readfds);
max_fs = 0;
for (chassis = 0; chassis <= MAX_CHASSIS; chassis++) {
for (geoslot = 0; geoslot <= MAX_GEOSLOT; geoslot++) {
u = &units[chassis][geoslot];
if (u->ip && (open_with_IOP(u, FIND))) { /* connect to the remote IOP */
send_to_fd(u->find_fd, 1, (unsigned char *)"\0");
if (get_error_response(u->find_fd, errbuf))
close_with_IOP(chassis, geoslot, FIND);
else {
if (u->find_fd > max_fs)
max_fs = u->find_fd; /* remember the highest number currently in use */
FD_SET(u->find_fd, &readfds); /* we are going to want to read this guy's response to */
u->len = 0;
send_to_fd(u->find_fd, 1, (unsigned char *)"Q"); /* this interface query request */
}
}
}
}
wait_for_all_answers();
if (process_client_data(errbuf))
return -1;
sort_if_table();
return 0;
}
static int pcap_stats_acn(pcap_t *handle, struct pcap_stat *ps) {
unsigned char buf[12];
send_to_fd(handle->fd, 1, (unsigned char *)"S"); /* send the get_stats command to the IOP */
if (read_client_nbytes(handle->fd, sizeof(buf), buf) == -1) return -1; /* try reading the required bytes */
ps->ps_recv = ntohl(*(uint32_t *)&buf[0]); /* break the buffer into its three 32 bit components */
ps->ps_drop = ntohl(*(uint32_t *)&buf[4]);
ps->ps_ifdrop = ntohl(*(uint32_t *)&buf[8]);
return 0;
}
static int acn_open_live(const char *name, char *errbuf, int *linktype) { /* returns 0 on error, else returns the file descriptor */
int chassis, geoslot;
unit_t *u;
iface_t *p;
pcap_if_t *alldevsp;
pcap_findalldevs(&alldevsp, errbuf);
for (chassis = 0; chassis <= MAX_CHASSIS; chassis++) { /* scan the table... */
for (geoslot = 0; geoslot <= MAX_GEOSLOT; geoslot++) {
u = &units[chassis][geoslot];
if (u->ip != NULL) {
p = u->iface;
while (p) { /* and all interfaces... */
if (p->IOPname && p->name && (strcmp(p->name, name) == 0)) { /* and if we found the interface we want... */
*linktype = p->iftype;
open_with_IOP(u, LIVE); /* start a connection with that IOP */
send_to_fd(u->fd, strlen(p->IOPname)+1, (unsigned char *)p->IOPname); /* send the IOP's interface name, and a terminating null */
if (get_error_response(u->fd, errbuf)) {
return -1;
}
return u->fd; /* and return that open descriptor */
}
p = p->next;
}
}
}
}
return -1; /* if the interface wasn't found, return an error */
}
static void acn_start_monitor(int fd, int snaplen, int timeout, int promiscuous, int direction) {
unsigned char buf[8];
unit_t *u;
//printf("acn_start_monitor()\n"); // fulko
find_unit_by_fd(fd, NULL, NULL, &u);
if (u->first_time == 0) {
buf[0] = 'M';
*(uint32_t *)&buf[1] = htonl(snaplen);
buf[5] = timeout;
buf[6] = promiscuous;
buf[7] = direction;
//printf("acn_start_monitor() first time\n"); // fulko
send_to_fd(fd, 8, buf); /* send the start monitor command with its parameters to the IOP */
u->first_time = 1;
}
//printf("acn_start_monitor() complete\n"); // fulko
}
static int pcap_inject_acn(pcap_t *p, const void *buf _U_, size_t size _U_) {
strlcpy(p->errbuf, "Sending packets isn't supported on ACN adapters",
PCAP_ERRBUF_SIZE);
return (-1);
}
static int pcap_setfilter_acn(pcap_t *handle, struct bpf_program *bpf) {
int fd = handle->fd;
int count;
struct bpf_insn *p;
uint16_t shortInt;
uint32_t longInt;
send_to_fd(fd, 1, (unsigned char *)"F"); /* BPF filter follows command */
count = bpf->bf_len;
longInt = htonl(count);
send_to_fd(fd, 4, (unsigned char *)&longInt); /* send the instruction sequence count */
p = bpf->bf_insns;
while (count--) { /* followed by the list of instructions */
shortInt = htons(p->code);
longInt = htonl(p->k);
send_to_fd(fd, 2, (unsigned char *)&shortInt);
send_to_fd(fd, 1, (unsigned char *)&p->jt);
send_to_fd(fd, 1, (unsigned char *)&p->jf);
send_to_fd(fd, 4, (unsigned char *)&longInt);
p++;
}
if (get_error_response(fd, NULL))
return -1;
return 0;
}
static int pcap_setdirection_acn(pcap_t *handle, pcap_direction_t d) {
snprintf(handle->errbuf, sizeof(handle->errbuf),
"Setting direction is not supported on ACN adapters");
return -1;
}
static int acn_read_n_bytes_with_timeout(pcap_t *handle, int count) {
struct timeval tv;
int retval, fd;
fd_set r_fds;
fd_set w_fds;
u_char *bp;
int len = 0;
int offset = 0;
tv.tv_sec = 5;
tv.tv_usec = 0;
fd = handle->fd;
FD_ZERO(&r_fds);
FD_SET(fd, &r_fds);
memcpy(&w_fds, &r_fds, sizeof(r_fds));
bp = handle->bp;
while (count) {
retval = select(fd + 1, &w_fds, NULL, NULL, &tv);
if (retval == -1) { /* an error occured !!!!! */
// fprintf(stderr, "error during packet data read\n");
return -1; /* but we need to return a good indication to prevent unneccessary popups */
} else if (retval == 0) { /* timeout occured, so process what we've got sofar and return */
// fprintf(stderr, "timeout during packet data read\n");
return -1;
} else {
if ((len = recv(fd, (bp + offset), count, 0)) <= 0) {
// fprintf(stderr, "premature exit during packet data rx\n");
return -1;
}
count -= len;
offset += len;
}
}
return 0;
}
static int pcap_read_acn(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user) {
#define HEADER_SIZE (4 * 4)
unsigned char packet_header[HEADER_SIZE];
struct pcap_pkthdr pcap_header;
//printf("pcap_read_acn()\n"); // fulko
acn_start_monitor(handle->fd, handle->snapshot, handle->md.timeout, handle->md.clear_promisc, handle->direction); /* maybe tell him to start monitoring */
//printf("pcap_read_acn() after start monitor\n"); // fulko
handle->bp = packet_header;
if (acn_read_n_bytes_with_timeout(handle, HEADER_SIZE) == -1) return 0; /* try to read a packet header in so we can get the sizeof the packet data */
pcap_header.ts.tv_sec = ntohl(*(uint32_t *)&packet_header[0]); /* tv_sec */
pcap_header.ts.tv_usec = ntohl(*(uint32_t *)&packet_header[4]); /* tv_usec */
pcap_header.caplen = ntohl(*(uint32_t *)&packet_header[8]); /* caplen */
pcap_header.len = ntohl(*(uint32_t *)&packet_header[12]); /* len */
handle->bp = handle->buffer + handle->offset; /* start off the receive pointer at the right spot */
if (acn_read_n_bytes_with_timeout(handle, pcap_header.caplen) == -1) return 0; /* then try to read in the rest of the data */
callback(user, &pcap_header, handle->bp); /* call the user supplied callback function */
return 1;
}
static int pcap_activate_sita(pcap_t *handle) {
int fd;
if (handle->opt.rfmon) {
/*
* No monitor mode on SITA devices (they're not Wi-Fi
* devices).
*/
return PCAP_ERROR_RFMON_NOTSUP;
}
/* Initialize some components of the pcap structure. */
handle->inject_op = pcap_inject_acn;
handle->setfilter_op = pcap_setfilter_acn;
handle->setdirection_op = pcap_setdirection_acn;
handle->set_datalink_op = NULL; /* can't change data link type */
handle->getnonblock_op = pcap_getnonblock_fd;
handle->setnonblock_op = pcap_setnonblock_fd;
handle->cleanup_op = pcap_cleanup_acn;
handle->read_op = pcap_read_acn;
handle->stats_op = pcap_stats_acn;
fd = acn_open_live(handle->opt.source, handle->errbuf,
&handle->linktype);
if (fd == -1)
return PCAP_ERROR;
handle->md.clear_promisc = handle->md.promisc;
handle->fd = fd;
handle->bufsize = handle->snapshot;
/* Allocate the buffer */
handle->buffer = malloc(handle->bufsize + handle->offset);
if (!handle->buffer) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"malloc: %s", pcap_strerror(errno));
pcap_cleanup_acn(handle);
return PCAP_ERROR;
}
/*
* "handle->fd" is a socket, so "select()" and "poll()"
* should work on it.
*/
handle->selectable_fd = handle->fd;
return 0;
}
pcap_t *pcap_create(const char *device, char *ebuf) {
pcap_t *p;
p = pcap_create_common(device, ebuf);
if (p == NULL)
return (NULL);
p->activate_op = pcap_activate_sita;
return (p);
}

10
pcap-sita.h Normal file
View File

@ -0,0 +1,10 @@
/*
* pcap-sita.h: Packet capture interface for SITA WAN devices
*
* Authors: Fulko Hew (fulko.hew@sita.aero) (+1 905 6815570);
*
* @(#) $Header: /tcpdump/master/libpcap/pcap-sita.h
*/
extern int acn_parse_hosts_file(char *errbuf);
extern int acn_findalldevs(char *errbuf);

943
pcap-sita.html Normal file
View File

@ -0,0 +1,943 @@
<HTML><HEAD>
<STYLE type="text/css">
<!--
A { text-decoration:none }
-->
</STYLE>
</HEAD>
<BODY>
<TABLE WIDTH=100%><TR>
<TD ALIGN=LEFT VALIGN=TOP>
<FONT SIZE=+0 FACE="COURIER"><B>A "Distributed Pcap" for<BR>Remote Monitoring LANs & WANs</B><BR>
(Design Notes for the SITA ACN device)</FONT>
</TD>
<TD ALIGN=RIGHT VALIGN=TOP>
Fulko Hew<BR>SITA INC Canada, Inc.<BR>Revised: October 2, 2007
</TD>
</TR></TABLE>
<H3>SUMMARY</H3>
<UL>
<STRONG>Note:</STRONG> This document is part of the libpcap CVS and was derived from 'pcap.3' (circa Aug/07).
<P>
The ACN provides a customized/distributed version of this library that alows SMPs to
interact with the various IOPs within the site providing a standard mechanism
to capture LAN and WAN message traffic.
<P>
<CENTER>
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=3 WIDTH=75%>
<TR>
<TH VALIGN=TOP>SMP</TH>
<TD VALIGN=TOP>The Supervisory Management Processor where Wireshark (or equivalent)
runs in conjuction with a libpcap front-end.</TD>
</TR>
<TR>
<TH VALIGN=TOP>IOP</TH>
<TD VALIGN=TOP>I/O Processors where the monitored ports exist in conjunction
with a custom device driver/libpcap back-end.</TD>
</TR>
</TABLE>
</CENTER>
<P>
Each IOP will be capable of supporting multiple connections from an SMP
enabling monitoring of more than one interface at a time, each through
its own seperate connection. The IOP is responsible to ensure and report
an error if any attempt is made to monitor the same interface more than once.
<P>
There are three applications that will be supported by the ACN version of libpcap.
They each use a slightly different mode for looping/capturing and termination
as summarized in the following table:
<P>
<CENTER>
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=3>
<TR><TH>Application</TH> <TH>Capture</TH> <TH>Termination</TH></TR>
<TR><TH VALIGN=TOP NOWRAP>wireshark</TH>
<TD VALIGN=TOP>pcap_dispatch(all packets in one buffer of capture only)</TD>
<TD VALIGN=TOP>pcap_breakloop()</TD>
</TR>
<TR><TH VALIGN=TOP NOWRAP>tshark</TH>
<TD VALIGN=TOP>pcap_dispatch(one buffer of capture only)</TD>
<TD VALIGN=TOP>Since a CTRL-C was used to terminate the application, pcap_breakloop() is never called.</TD>
</TR>
<TR><TH VALIGN=TOP NOWRAP>tcpdump</TH>
<TD VALIGN=TOP>pcap_loop(all packets in the next buffer, and loop forever)</TD>
<TD VALIGN=TOP>pcap_breakloop()</TD>
</TR>
</TABLE>
</CENTER>
<P>
<B>Note: </B>In all cases, the termination of capturing is always (apparently) followed by
pcap_close(). Pcap_breakloop() is only used to stop/suspend looping/processing,
and upon close interpretation of the function definitions, it is possible to resume
capturing following a pcap_breakloop() without any re-initialization.
<P>
<H4>ACN Limitations</H4>
<OL>
<LI>Monitoring of backup IOPs is not currently supported.
<LI>Ethernet interfaces cannot be monitored in promiscuous mode.
</OL>
</UL>
<H3>ROUTINES</H3>
<UL>
The following list of functions is the sub-set of Pcap functions that have been
altered/enhanced to support the ACN remote monitoring facility. The remainder of the Pcap
functions continue to perform their duties un-altered. Libpcap only supports this
mode of operation if it has been configured/compiled for SITA/ACN support.
<P>
<UL><FONT FACE=COURIER>
pcap_findalldevs<BR>
pcap_freealldevs<BR>
pcap_open_live<BR>
pcap_close<BR>
pcap_setfilter<BR>
pcap_dispatch<BR>
pcap_loop<BR>
pcap_next<BR>
pcap_next_ex<BR>
pcap_stats<BR>
</FONT></UL>
These subroutines have been modified for the ACN specific distributed and remote monitoring
ability perform the following basic functions. More detail is provided in the
"SMP/IOP Inter-Process Communication Protocol" section.
<P>
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=3>
<TR>
<TD VALIGN=TOP ROWSPAN=2><B>pcap_open_live()</B></TD>
<TD VALIGN=TOP>Used to obtain a packet capture descriptor to look at packets on the network.</TD>
</TR>
<TR><TD><TABLE BORDER=0 CELLSPACING=0 CELLPADDING=3 WIDTH=100%>
<TR><TH VALIGN=TOP NOWRAP>SMP -> IOP</TH>
<TD>
The SMP will open a connection to the selected IOP on its 'sniffer' port
to ensure it is available. It sends a null terminated string identifying
the interface to be monitored.
</TD>
</TR>
<TR><TH VALIGN=TOP NOWRAP>IOP -> SMP</TH>
<TD>
After any required processing is complete, the IOP will return a
null terminated string containing an error message if one occured.
If no error occured, a empty string is still returned.
Errors are:
<UL>
<LI>"Interface (xxx) does not exist."
<LI>"Interface (xxx) not configured."
<LI>"Interface (xxx) already being monitored."
</UL>
</TD>
</TR>
</TABLE></TD></TR>
<TR>
<TD VALIGN=TOP ROWSPAN=2><B>pcap_findalldevs()</B></TD>
<TD VALIGN=TOP>It constructs a list of network devices that can be opened with pcap_open_live().</TD>
</TR>
<TR><TD><TABLE BORDER=0 CELLSPACING=0 CELLPADDING=3 WIDTH=100%>
<TR><TH VALIGN=TOP NOWRAP>SMP</TH>
<TD>
It obtains a list of IOPs currently available (via /etc/hosts).
</TD>
</TR>
<TR><TH VALIGN=TOP NOWRAP>SMP -> IOP</TH>
<TD>
The SMP will sequentially open a connection to each IOP on its 'sniffer' port to ensure
the IOP is available.
It sends a null terminated empty interface ID followed by the query request command.
</TD>
</TR>
<TR><TH VALIGN=TOP NOWRAP>IOP -> SMP</TH>
<TD>The IOP returns an error response and its list of devices.
</TD>
</TR>
<TR><TH VALIGN=TOP NOWRAP>SMP -> IOP</TH>
<TD>
The SMP closes the TCP connection with each IOP.
</TD>
</TR>
<TR><TH VALIGN=TOP NOWRAP>SMP</TH>
<TD>
The SMP adds the received information to its internal structure.
</TD>
</TR>
</TABLE></TD></TR>
<TR>
<TD VALIGN=TOP ROWSPAN=2><B>pcap_freealldevs()</B></TD>
<TD VALIGN=TOP>Used to free a list allocated by pcap_findalldevs().</TD>
</TR>
<TR><TD><TABLE BORDER=0 CELLSPACING=0 CELLPADDING=3 WIDTH=100%>
<TR><TH VALIGN=TOP NOWRAP>SMP</TH>
<TD>
The SMP frees the structure it built as a result of the previous
invocation of pcap_findalldevs().
</TD>
</TR>
</TABLE></TD></TR>
<TR>
<TD VALIGN=TOP ROWSPAN=2><B>pcap_dispatch()</B></TD>
<TD VALIGN=TOP>Used to collect and process packets.</TD>
</TR>
<TR><TD><TABLE BORDER=0 CELLSPACING=0 CELLPADDING=3 WIDTH=100%>
<TR><TH VALIGN=TOP NOWRAP>SMP -> IOP</TH>
<TD>
On the first invocation of pcap_dispatch(), pcap_loop(), or pcap_next(), or pcap_next_ex() following a pcap_open_live(),
the SMP will pass down the monitor start command and various parameters the IOP should use.
</TD>
</TR>
<TR><TH VALIGN=TOP NOWRAP>IOP -> SMP</TH>
<TD>
The IOP now sends a stream of captured data.
</TD>
</TR>
<TR><TH VALIGN=TOP NOWRAP>SMP</TH>
<TD>
The SMP will read the reverse channel of the connection between the SMP and the
IOP that provides the captured data (via 'p->read_op' which is 'pcap_read_linux()'
until the select() call returns a 'no more data' indication.
It will the process (at most) the next 'cnt' packets and invoke the specified
callback function for each packet processed.
</TD>
</TR>
<TR><TH VALIGN=TOP NOWRAP>IOP</TH>
<TD>
The IOP continues to listen for additional commands as well as capturing and forwarding data to the SMP.
</TD>
</TR>
</TABLE></TD></TR>
<TR>
<TD VALIGN=TOP ROWSPAN=2><B>pcap_loop()</B></TD>
<TD VALIGN=TOP>
Is similar to pcap_dispatch() except it keeps reading packets until
the requested number of packets are processed or an error occurs.
</TD>
</TR>
<TR><TD><TABLE BORDER=0 CELLSPACING=0 CELLPADDING=3 WIDTH=100%>
<TR><TH VALIGN=TOP NOWRAP>SMP -> IOP</TH>
<TD>
On the first invocation of pcap_dispatch(), pcap_loop(), or pcap_next(), or pcap_next_ex() following a pcap_open_live(),
the SMP will pass down the monitor start command and various parameters the IOP should use.
</TD>
</TR>
<TR><TH VALIGN=TOP NOWRAP>IOP -> SMP</TH>
<TD>
The IOP now sends a stream of captured data.
</TD>
</TR>
<TR><TH VALIGN=TOP NOWRAP>SMP</TH>
<TD>
The SMP continuously reads the next packet from the reverse channel of the connection
between the SMP and the IOP that provides the captured data (via 'p->read_op'
which is 'pcap_read_linux()' until 'cnt' packets have been received.
The specified callback function will be invoked for each packet received.
</TD>
</TR>
<TR><TH VALIGN=TOP NOWRAP>IOP</TH>
<TD>
The IOP continues to listen for additional commands as well as capturing and forwarding data to the SMP.
</TD>
</TR>
</TABLE></TD></TR>
<TR>
<TD VALIGN=TOP ROWSPAN=2><B>pcap_next()</B></TD>
<TD VALIGN=TOP>
It reads the next packet (by calling pcap_dispatch() with a count of 1)
and returns a pointer to the data in that packet.
</TD>
</TR>
<TR><TD><TABLE BORDER=0 CELLSPACING=0 CELLPADDING=3 WIDTH=100%>
<TR><TH VALIGN=TOP NOWRAP>SMP -> IOP</TH>
<TD>
On the first invocation of pcap_dispatch(), pcap_loop(), or pcap_next(), or pcap_next_ex() following a pcap_open_live(),
the SMP will pass down the monitor start command and various parameters the IOP should use.
</TD>
</TR>
<TR><TH VALIGN=TOP NOWRAP>IOP -> SMP</TH>
<TD>
The IOP now sends a stream of captured data.
</TD>
</TR>
<TR><TH VALIGN=TOP NOWRAP>SMP</TH>
<TD>
The SMP reads only the next packet from the reverse channel of the connection
between the SMP and the IOP that provides the captured data (via calling pcap_dispatch()
with a count of 1) and returns a pointer to that data by invoking an internal callback.
</TD>
</TR>
<TR><TH VALIGN=TOP NOWRAP>IOP</TH>
<TD>
The IOP continues to listen for additional commands as well as capturing and forwarding data to the SMP.
</TD>
</TR>
</TABLE></TD></TR>
<TR>
<TD VALIGN=TOP ROWSPAN=2><B>pcap_next_ex()</B></TD>
<TD VALIGN=TOP>Reads the next packet and returns a success/failure indication.</TD>
</TR>
<TR><TD><TABLE BORDER=0 CELLSPACING=0 CELLPADDING=3 WIDTH=100%>
<TR><TH VALIGN=TOP NOWRAP>SMP -> IOP</TH>
<TD>
On the first invocation of pcap_dispatch(), pcap_loop(), or pcap_next(), or pcap_next_ex() following a pcap_open_live(),
the SMP will pass down the monitor start command and various parameters the IOP should use.
</TD>
</TR>
<TR><TH VALIGN=TOP NOWRAP>IOP -> SMP</TH>
<TD>
The IOP now sends a stream of captured data.
</TD>
</TR>
<TR><TH VALIGN=TOP NOWRAP>SMP</TH>
<TD>
The SMP reads only the next packet from the reverse channel of the connection
between the SMP and the IOP that provides the captured data (via calling pcap_dispatch()
with a count of 1) and returns seperate pointers to both the
packet header and packet data by invoking an internal callback.
</TD>
</TR>
<TR><TH VALIGN=TOP NOWRAP>IOP</TH>
<TD>
The IOP continues to listen for additional commands as well as capturing and forwarding data to the SMP.
</TD>
</TR>
</TABLE></TD></TR>
<TR>
<TD VALIGN=TOP ROWSPAN=2><B>pcap_setfilter()</B></TD>
<TD VALIGN=TOP>Used to specify a filter program.</TD>
</TR>
<TR><TD><TABLE BORDER=0 CELLSPACING=0 CELLPADDING=3 WIDTH=100%>
<TR><TH VALIGN=TOP NOWRAP>SMP -> IOP</TH>
<TD>
The SMP sends a 'set filter' command followed by the BPF commands.
</TD>
</TR>
<TR><TH VALIGN=TOP NOWRAP>IOP -> SMP</TH>
<TD>
The IOP returns a null terminated error string if it failed to accept the filter.
If no error occured, then a NULL terminated empty string is returned instead.
Errors are:
<UL>
<LI>"Invalid BPF."
<LI>"Insufficient resources for BPF."
</UL>
</TD>
</TR>
</TABLE></TD></TR>
<TR>
<TD VALIGN=TOP ROWSPAN=2><B>pcap_stats()</B></TD>
<TD VALIGN=TOP>Fills in a pcap_stat struct with packet statistics.</TD>
</TR>
<TR><TD><TABLE BORDER=0 CELLSPACING=0 CELLPADDING=3 WIDTH=100%>
<TR><TH VALIGN=TOP NOWRAP>SMP -> IOP</TH>
<TD>
The SMP sends a message to the IOP requesting its statistics.
</TD>
</TR>
<TR><TH VALIGN=TOP NOWRAP>IOP -> SMP</TH>
<TD>
The IOP returns the statistics.
</TD>
</TR>
<TR><TH VALIGN=TOP NOWRAP>SMP</TH>
<TD>
The SMP fills in the structure provided with the information retrieved from the IOP.
</TD>
</TR>
</TABLE></TD></TR>
<TR>
<TD VALIGN=TOP ROWSPAN=2><B>pcap_close()</B></TD>
<TD VALIGN=TOP>Closes the file and deallocates resources.</TD>
</TR>
<TR><TD><TABLE BORDER=0 CELLSPACING=0 CELLPADDING=3 WIDTH=100%>
<TR><TH VALIGN=TOP NOWRAP>SMP -> IOP</TH>
<TD>
The SMP closes the file descriptor, and if the descriptor is that of
the comminucation session with an IOP, it too is terminated.
</TD>
</TR>
<TR><TH VALIGN=TOP NOWRAP>IOP</TH>
<TD>
If the IOP detects that its communication session with an SMP
has closed, it will terminate any monitoring in progress,
release any resources and close its end of the session.
It will not maintain persistance of any information or prior mode of operation.
</TD>
</TR>
</TABLE></TD></TR>
</TABLE>
</UL>
<P>
<H3>SMP/IOP Inter-Process Communication Protocol</H3>
<UL>
<LI><P>Communications between an SMP and an IOP consists of a TCP session
between an ephemeral port on the SMP and the well known port of 49152
(which is the first available port in the 'dynamic and/or private port'
range) on an IOP.
<LI><P>Following a TCP open operation the IOP receives a null terminated
'interface ID' string to determine the type of operation that follows:
<LI><P>Every command received by an IOP implies a 'stop trace/stop forwarding' operation must
occur before executing the received command.
<LI><P>A session is closed when the SMP closes the TCP session with the IOP.
Obviously monitoring and forwarding is also stopped at that time.
<B>Note: </B>All multi-octet entities are sent in network neutral order.
<P>
<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=5>
<TR><TH COLSPAN=3><HR WIDTH=100%></TH></TR>
<TR>
<TD VALIGN=TOP ROWSPAN=6>pcap_findalldevs()</TD>
<TD VALIGN=TOP ALIGN=CENTER NOWRAP>SMP -> IOP</TD>
<TD VALIGN=TOP>Open socket (to each IOP), and sends:
<P>
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=3>
<TR>
<TH VALIGN=TOP ALIGN=CENTER>Name/<BR>Purpose</TH>
<TH VALIGN=TOP ALIGN=CENTER NOWRAP>Size<BR>(in bytes)</TH>
<TH VALIGN=TOP ALIGN=CENTER>Description</TH>
</TR>
<TR>
<TD VALIGN=TOP>Interface ID</TD>
<TD VALIGN=TOP ALIGN=CENTER>1</TD>
<TD VALIGN=TOP>A NULL to indicate an an empty 'interface ID'.</TD>
</TR>
</TABLE>
</TD>
</TR>
<TR>
<TD VALIGN=TOP ALIGN=CENTER NOWRAP>IOP -> SMP</TD>
<TD VALIGN=TOP>Send its (possibly empty) NULL terminated error response string.</TD>
</TR>
<TR>
<TD VALIGN=TOP ALIGN=CENTER NOWRAP>SMP -> IOP</TD>
<TD VALIGN=TOP>Sends the 'interface query request':
<P>
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=3>
<TR>
<TH VALIGN=TOP ALIGN=CENTER>Name/<BR>Purpose</TH>
<TH VALIGN=TOP ALIGN=CENTER NOWRAP>Size<BR>(in bytes)</TH>
<TH VALIGN=TOP ALIGN=CENTER>Description</TH>
</TR>
<TR>
<TD VALIGN=TOP>Interface ID</TD>
<TD VALIGN=TOP ALIGN=CENTER>1</TD>
<TD VALIGN=TOP>A 'Q' (indicating 'interface query request').</TD>
</TR>
</TABLE>
</TD>
</TR>
<TR>
<TD VALIGN=TOP ALIGN=CENTER NOWRAP>IOP -> SMP</TD>
<TD VALIGN=TOP>The IOP returns a list of sequences of information as
defined by the return parameter of this function call (as shown in the following table).
Elements are specified by providing an unsigned byte preceeding the actual data that contains length information.
<P>
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=3>
<TR>
<TH VALIGN=TOP ALIGN=CENTER>Notes:</TH>
<TH VALIGN=TOP ALIGN=CENTER>Name/<BR>Purpose</TH>
<TH VALIGN=TOP ALIGN=CENTER NOWRAP>Size<BR>(in bytes)</TH>
<TH VALIGN=TOP ALIGN=CENTER>Description</TH>
</TR>
<TR>
<TD ROWSPAN=7>&nbsp;</TD>
<TD VALIGN=TOP ALIGN=RIGHT>length</TD>
<TD VALIGN=TOP ALIGN=CENTER>1</TD>
<TD VALIGN=TOP>The number of octets in the name field that follows.</TD>
</TR>
<TR><TD VALIGN=TOP ALIGN=LEFT>Name</TD>
<TD VALIGN=TOP ALIGN=CENTER>1-255</TD>
<TD VALIGN=TOP>The name of the interface. The format of the name is an alphabetic string (indicating
the type of interface) followed by an optional numeric string (indicating the interface's
sequence number).
Sequence numbers (if needed) will begin at zero and progress monotonically upwards.
(i.e. 'eth0', 'lo', 'wan0', etc.)
<P>
For an IOP, the alphabetic string will be one of: 'eth', 'wan', and 'lo'
for Ethernet, WAN ports and the IP loopback device respectively.
An IOP currently supports: 'eth0', 'eth1', 'lo', 'wan0' ... 'wan7'.
<P>
<B>Note:</B> IOPs and ACNs will not currently support the concept of 'any' interface.</TD>
</TR>
<TR><TD VALIGN=TOP ALIGN=RIGHT>length</TD>
<TD VALIGN=TOP ALIGN=CENTER>1</TD>
<TD VALIGN=TOP>The number of octets in the interface description field that follows.</TD>
</TR>
<TR><TD VALIGN=TOP ALIGN=LEFT>Interface Description</TD>
<TD VALIGN=TOP ALIGN=CENTER>0-255</TD>
<TD VALIGN=TOP>A description of the interface or it may be an empty string. (i.e. 'ALC')</TD>
</TR>
<TR><TD VALIGN=TOP ALIGN=LEFT>Interface Type</TD>
<TD VALIGN=TOP ALIGN=CENTER>4</TD>
<TD VALIGN=TOP>The type of interface as defined in the description for pcap_datalink() (in network neutral order).</TD>
</TR>
<TR><TD VALIGN=TOP ALIGN=LEFT>Loopback Flag</TD>
<TD VALIGN=TOP ALIGN=CENTER>1</TD>
<TD VALIGN=TOP>1 = if the interface is a loopback interface, zero = otherwise.</TD>
</TR>
<TR><TD VALIGN=TOP ALIGN=RIGHT>count</TD>
<TD VALIGN=TOP ALIGN=CENTER>1</TD>
<TD VALIGN=TOP># of address entries that follow.
Each entry is a series of bytes in network neutral order.
See the parameter definition above for more details.</TD>
</TR>
<TR>
<TD ALIGN=CENTER ROWSPAN=8 WIDTH=1%>Repeated 'count' number of times.</TD>
<TD VALIGN=TOP ALIGN=RIGHT>length</TD>
<TD VALIGN=TOP ALIGN=CENTER>1</TD>
<TD VALIGN=TOP>The number of octets in the address field that follows.</TD>
</TR>
<TR><TD VALIGN=TOP ALIGN=LEFT>Address</TD>
<TD VALIGN=TOP ALIGN=CENTER>1-255</TD>
<TD VALIGN=TOP>The address of this interface (in network neutral order).</TD>
</TR>
<TR><TD VALIGN=TOP ALIGN=RIGHT>length</TD>
<TD VALIGN=TOP ALIGN=CENTER>1</TD>
<TD VALIGN=TOP>The number of octets in the netmask field that follows.</TD>
</TR>
<TR><TD VALIGN=TOP ALIGN=LEFT>Network Mask</TD>
<TD VALIGN=TOP ALIGN=CENTER>0-255</TD>
<TD VALIGN=TOP>The network mask used on this interface (if applicable) (in network neutral order).</TD>
</TR>
<TR><TD VALIGN=TOP ALIGN=RIGHT>length</TD>
<TD VALIGN=TOP ALIGN=CENTER>1</TD>
<TD VALIGN=TOP>The number of octets in the broadcast address field that follows.</TD>
</TR>
<TR><TD VALIGN=TOP ALIGN=LEFT>Broadcast Address</TD>
<TD VALIGN=TOP ALIGN=CENTER>0-255</TD>
<TD VALIGN=TOP>The broadcast address of this interface (if applicable) (in network neutral order).</TD>
</TR>
<TR><TD VALIGN=TOP ALIGN=RIGHT>length</TD>
<TD VALIGN=TOP ALIGN=CENTER>1</TD>
<TD VALIGN=TOP>The number of octets in the destination address field that follows.</TD>
</TR>
<TR><TD VALIGN=TOP ALIGN=LEFT>Destination Address</TD>
<TD VALIGN=TOP ALIGN=CENTER>0-255</TD>
<TD VALIGN=TOP>The destination address of this interface (if applicable) (in network neutral order).</TD>
</TR>
</TABLE>
</TR>
<TR>
<TD VALIGN=TOP ALIGN=CENTER NOWRAP>SMP -> IOP</TD>
<TD VALIGN=TOP>Close the socket.</TD>
</TR>
<TR>
<TD VALIGN=TOP ALIGN=CENTER NOWRAP>IOP -> SMP</TD>
<TD VALIGN=TOP>Close the socket.</TD>
</TR>
<TR><TH COLSPAN=3><HR WIDTH=100%></TH></TR>
<TR>
<TD VALIGN=TOP ROWSPAN=2>pcap_open_live()</TD>
<TD VALIGN=TOP ALIGN=CENTER NOWRAP>SMP -> IOP</TD>
<TD VALIGN=TOP>Open socket, and sends:
<P>
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=3>
<TR>
<TH VALIGN=TOP ALIGN=CENTER>Name/<BR>Purpose</TH>
<TH VALIGN=TOP ALIGN=CENTER NOWRAP>Size<BR>(in bytes)</TH>
<TH VALIGN=TOP ALIGN=CENTER>Description</TH>
</TR>
<TR>
<TD VALIGN=TOP>Interface ID</TD>
<TD VALIGN=TOP ALIGN=CENTER>'n'</TD>
<TD VALIGN=TOP>'n' octets containing a NULL terminated interface name string.</TD>
</TR>
</TABLE>
</TD>
</TR>
<TR>
<TD VALIGN=TOP ALIGN=CENTER NOWRAP>IOP -> SMP</TD>
<TD VALIGN=TOP>Send its NULL terminated error response string.</TD>
</TR>
<TR><TH COLSPAN=3><HR WIDTH=100%></TH></TR>
<TR>
<TD VALIGN=TOP NOWRAP ROWSPAN=2>pcap_dispatch()<BR>pcap_loop()<BR>pcap_next()<BR>pcap_next_ex()</TD>
<TD VALIGN=TOP ALIGN=CENTER NOWRAP>SMP -> IOP</TD>
<TD VALIGN=TOP>On the first invocation following a pcap_open_live() or pcap_breakloop() additional information is sent:
<P>
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=3>
<TR>
<TH VALIGN=TOP ALIGN=CENTER>Name/<BR>Purpose</TH>
<TH VALIGN=TOP ALIGN=CENTER NOWRAP>Size<BR>(in bytes)</TH>
<TH VALIGN=TOP ALIGN=CENTER>Description</TH>
</TR>
<TR>
<TD VALIGN=TOP>command</TD>
<TD VALIGN=TOP ALIGN=CENTER>1</TD>
<TD VALIGN=TOP>'M' (indicating 'monitor start')</TD>
</TR>
<TR>
<TD VALIGN=TOP>snaplen</TD>
<TD VALIGN=TOP ALIGN=CENTER>4</TD>
<TD VALIGN=TOP>snaplen</TD>
</TR>
<TR>
<TD VALIGN=TOP>timeout</TD>
<TD VALIGN=TOP ALIGN=CENTER>1</TD>
<TD VALIGN=TOP>timeout value (in milliseconds)</TD>
</TR>
<TR>
<TD VALIGN=TOP>promiscuous</TD>
<TD VALIGN=TOP ALIGN=CENTER>1</TD>
<TD VALIGN=TOP>A flag indicating that the interface being monitored show operate
in promiscuous mode. [off(0) / on(NZ)]</TD>
</TR>
<TR>
<TD VALIGN=TOP>direction</TD>
<TD VALIGN=TOP ALIGN=CENTER>1</TD>
<TD VALIGN=TOP>A flag indicating the direction of traffic that should be captuted [both(0) / in(1) / out(2)]</TD>
</TR>
</TABLE>
</TD>
</TR>
<TR>
<TD VALIGN=TOP ALIGN=CENTER NOWRAP>IOP -> SMP</TD>
<TD VALIGN=TOP>Sends captured packets.</TD>
</TR>
<TR><TH COLSPAN=3><HR WIDTH=100%></TH></TR>
<TR>
<TD VALIGN=TOP ROWSPAN=2>pcap_setfilter()</TD>
<TD VALIGN=TOP ALIGN=CENTER NOWRAP>SMP -> IOP</TD>
<TD VALIGN=TOP>At any time, the SMP can issue a set filter command which contains
an indicator, a count of the number of statements in the filter,
followed by the sequence of filter commands represented as a sequence
of C-style structures.
<P>
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=3>
<TR>
<TH VALIGN=TOP ALIGN=CENTER>Name/<BR>Purpose</TH>
<TH VALIGN=TOP ALIGN=CENTER NOWRAP>Size<BR>(in bytes)</TH>
<TH VALIGN=TOP ALIGN=CENTER>Description</TH>
</TR>
<TR>
<TD VALIGN=TOP>command</TD>
<TD VALIGN=TOP ALIGN=CENTER>1</TD>
<TD VALIGN=TOP>'F' (indicating 'filter')</TD>
</TR>
<TR>
<TD VALIGN=TOP>count</TD>
<TD VALIGN=TOP ALIGN=CENTER>4</TD>
<TD VALIGN=TOP>The number of command in the Berkeley Packet Filter that follow.</TD>
</TR>
<TR>
<TD VALIGN=TOP>BPF program</TD>
<TD VALIGN=TOP ALIGN=CENTER>'n'</TD>
<TD VALIGN=TOP>8 bytes of each command (repeated 'n' times).<BR>
Each command consists of that C-style structure which contains:
<P>
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=3>
<TR>
<TH VALIGN=TOP ALIGN=CENTER>Name/<BR>Purpose</TH>
<TH VALIGN=TOP ALIGN=CENTER NOWRAP>Size<BR>(in bytes)</TH>
<TH VALIGN=TOP ALIGN=CENTER>Description</TH>
</TR>
<TR>
<TD VALIGN=TOP>opcode</TD>
<TD VALIGN=TOP ALIGN=CENTER>2</TD>
<TD VALIGN=TOP>The command's opcode.</TD>
</TR>
<TR>
<TD VALIGN=TOP>'jt'</TD>
<TD VALIGN=TOP ALIGN=CENTER>1</TD>
<TD VALIGN=TOP>The 'jump if true' program counter offset.</TD>
</TR>
<TR>
<TD VALIGN=TOP>'jf'</TD>
<TD VALIGN=TOP ALIGN=CENTER>1</TD>
<TD VALIGN=TOP>The 'jump if false' program counter offset.</TD>
</TR>
<TR>
<TD VALIGN=TOP>'k'</TD>
<TD VALIGN=TOP ALIGN=CENTER>4</TD>
<TD VALIGN=TOP>The 'other' data field.</TD>
</TR>
</TABLE>
<P>
Refer to the bpf(4) man page for more details.
</TD>
</TR>
</TABLE>
</TD>
</TR>
<TR>
<TD VALIGN=TOP ALIGN=CENTER NOWRAP>IOP -> SMP</TD>
<TD VALIGN=TOP>In return the IOP will send its (possibly empty) NULL terminated error response string.</TD>
</TR>
<TR><TH COLSPAN=3><HR WIDTH=100%></TH></TR>
<TR>
<TD VALIGN=TOP ROWSPAN=2>pcap_stats()</TD>
<TD VALIGN=TOP ALIGN=CENTER NOWRAP>SMP -> IOP</TD>
<TD VALIGN=TOP>At any time, the SMP can issue a 'retrieve statistics' command which contains:<BR>
<P>
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=3>
<TR>
<TH VALIGN=TOP ALIGN=CENTER>Name/<BR>Purpose</TH>
<TH VALIGN=TOP ALIGN=CENTER NOWRAP>Size<BR>(in bytes)</TH>
<TH VALIGN=TOP ALIGN=CENTER>Description</TH>
</TR>
<TR>
<TD VALIGN=TOP>command</TD>
<TD VALIGN=TOP ALIGN=CENTER>1</TD>
<TD VALIGN=TOP>'S' (indicating 'request statistics')</TD>
</TR>
</TABLE>
</TD>
</TR>
<TR>
<TD VALIGN=TOP ALIGN=CENTER NOWRAP>IOP -> SMP</TD>
<TD VALIGN=TOP>In return the IOP will send:
<P>
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=3>
<TR>
<TH VALIGN=TOP ALIGN=CENTER>Name/<BR>Purpose</TH>
<TH VALIGN=TOP ALIGN=CENTER NOWRAP>Size<BR>(in bytes)</TH>
<TH VALIGN=TOP ALIGN=CENTER>Description</TH>
</TR>
<TR>
<TD VALIGN=TOP>ps_recv</TD>
<TD VALIGN=TOP ALIGN=CENTER>4</TD>
<TD VALIGN=TOP>The number of packets that passed the filter.</TD>
</TR>
<TR>
<TD VALIGN=TOP>ps_drop</TD>
<TD VALIGN=TOP ALIGN=CENTER>4</TD>
<TD VALIGN=TOP>The number of packets that were dropped because the input queue was full,
regardless of whether they passed the filter.</TD>
</TR>
<TR>
<TD VALIGN=TOP>ps_ifdrop</TD>
<TD VALIGN=TOP ALIGN=CENTER>4</TD>
<TD VALIGN=TOP>The number of packets dropped by the network inteface
(regardless of whether they would have passed the input filter).</TD>
</TR>
</TABLE>
</TD>
</TR>
<TR><TH COLSPAN=3><HR WIDTH=100%></TH></TR>
<TR>
<TD VALIGN=TOP ROWSPAN=1>pcap_close()</TD>
<TD VALIGN=TOP ALIGN=CENTER NOWRAP>SMP -> IOP</TD>
<TD VALIGN=TOP>At any time, the SMP can close the TCP session with the IOP.</TD>
</TR>
<TR><TH COLSPAN=3><HR WIDTH=100%></TH></TR>
</TABLE>
</UL>
<H3>Interface ID Naming Convention</H3>
<UL>
Each interface within an IOP will be referred to uniquely. Since an currently contains
8 monitorable WAN ports and a monitorable Ethernet port, the naming convention is:
<P>
<CENTER>
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=3>
<TR><TH>Interface #</TH> <TH>Type</TH> <TH>Name</TH></TR>
<TR><TD ALIGN=CENTER>1</TD> <TD ALIGN=CENTER>WAN</TD> <TD ALIGN=CENTER>wan0</TD></TR>
<TR><TD ALIGN=CENTER>2</TD> <TD ALIGN=CENTER>WAN</TD> <TD ALIGN=CENTER>wan1</TD></TR>
<TR><TD ALIGN=CENTER>3</TD> <TD ALIGN=CENTER>WAN</TD> <TD ALIGN=CENTER>wan2</TD></TR>
<TR><TD ALIGN=CENTER>4</TD> <TD ALIGN=CENTER>WAN</TD> <TD ALIGN=CENTER>wan3</TD></TR>
<TR><TD ALIGN=CENTER>5</TD> <TD ALIGN=CENTER>WAN</TD> <TD ALIGN=CENTER>wan4</TD></TR>
<TR><TD ALIGN=CENTER>6</TD> <TD ALIGN=CENTER>WAN</TD> <TD ALIGN=CENTER>wan5</TD></TR>
<TR><TD ALIGN=CENTER>7</TD> <TD ALIGN=CENTER>WAN</TD> <TD ALIGN=CENTER>wan6</TD></TR>
<TR><TD ALIGN=CENTER>8</TD> <TD ALIGN=CENTER>WAN</TD> <TD ALIGN=CENTER>wan7</TD></TR>
<TR><TD ALIGN=CENTER>9</TD> <TD ALIGN=CENTER>Ethernet</TD> <TD ALIGN=CENTER>eth0</TD></TR>
<TR><TD ALIGN=CENTER>10</TD> <TD ALIGN=CENTER>Ethernet</TD> <TD ALIGN=CENTER>eth1</TD></TR>
</TABLE>
</CENTER>
</UL>
<H3>Packet Trace Data Format</H3>
<UL>
The format of the trace data that is sent to the SMP follows a portion of the libpcap file format
and is summarized here. This format specifies the generic requirements needed to
be able to decode packets, but does not cover ACN specifics such as custom MAC addressing
and WAN protocol support.
<P>
Although a libpcap file begins with a global header followed by zero or
more records for each captured packet, trace data sent to the SMP does NOT begin with a global header.
A trace sequence looks like this:
<P>
<TABLE>
<TR>
<TD STYLE="background-color: #c0FFc0">&nbsp;[Packet Header]&nbsp;</TD>
<TD STYLE="background-color: #c0FFc0">&nbsp;[Packet Data]&nbsp;</TD>
<TD STYLE="background-color: #c0c0FF">&nbsp;[Packet Header]&nbsp;</TD>
<TD STYLE="background-color: #c0c0FF">&nbsp;[Packet Data]&nbsp;</TD>
<TD STYLE="background-color: #e0c0c0">&nbsp;[Packet Header]&nbsp;</TD>
<TD STYLE="background-color: #e0c0c0">&nbsp;[Packet Data]&nbsp;</TD>
<TD>...</TD>
</TR>
</TABLE>
<H4>Packet Header</H4>
<UL>
Each captured packet starts with a header that contains the following values
(in network neutral order):
<FONT SIZE=-1>
<PRE>
uint32 tv_sec; /* timestamp seconds */
uint32 tv_usec; /* timestamp microseconds */
uint32 caplen; /* number of octets in the following packet */
uint32 len; /* original length of packet on the wire */
</PRE>
</FONT>
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=3>
<TR>
<TD VALIGN=TOP>tv_sec</TD>
<TD>The date and time when this packet was captured.
This value is in seconds since January 1, 1970 00:00:00 GMT;
this is also known as a UN*X time_t. You can use the ANSI C
<em>time()</em> function from <em>time.h</em> to get this value,
but you might use a more optimized way to get this timestamp value.
If this timestamp isn't based on GMT (UTC), use <em>thiszone</em>
from the global header for adjustments.</TD>
</TR>
<TR>
<TD VALIGN=TOP>tv_usec</TD>
<TD>The microseconds when this packet was captured, as an offset to <em>ts_sec</em>.
<B>Beware: </B>this value must never reach 1 second (1,000,000),
in this case <em>ts_sec</em> must be increased instead!</TD>
</TR>
<TR>
<TD VALIGN=TOP>caplen</TD>
<TD>The number of bytes actually provided in the capture record.
This value should never become larger than <em>len</em> or the
<em>snaplen</em> value specified during the capture.</TD>
</TR>
<TR>
<TD VALIGN=TOP>len</TD>
<TD>The length of the packet "on the wire" when it was captured.
If <em>caplen</em> and <em>len</em> differ, the actually
saved packet size was limited by the value of <em>snaplen</em> specified
during one of the capture directives such as pcap_dispatch().</TD>
</TR>
</TABLE>
</UL>
<H4>Packet Data</H4>
<UL>
The actual packet data will immediately follow the packet header as a sequence of <em>caplen</em> octets.
Depending on the DLT encoding number assigned to the interface, the packet data will contain an additional
custom header used to convey WAN port related information.
</UL>
<H4>ACN Custom Packet Header</H4>
<UL>
PCAP, Wireshark and Tcpdump enhancements have been added to the ACN to support
monitoring of its ports, however each of these facilities were focused on capturing
and displaying traffic from LAN interfaces. The SITA extentions to these facilities
are used to also provide the ability to capture, filter, and display information from
an ACN's WAN ports.
<P>
Although each packet follows the standard libpcap format, since there are
two types of interfaces that can be monitored, the format of the data
packet varies slightly.
<P>
<UL TYPE=DISC>
<LI>For Ethernet (like) devices, the packet format is unchanged from the standard Pcap format.
<LI>For WAN devices, the packet contains a 5 byte header that preceeds the actual captured data
described by the following table:
</UL>
<P>
<CENTER>
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=3>
<TR> <TH>Octet</TH>
<TH>Name</TH>
<TH>Mask/Value</TH>
<TH COLSPAN=2>Definition</TH> </TR>
<TR> <TH VALIGN=TOP ALIGN=CENTER ROWSPAN=3>0</TH>
<TH VALIGN=TOP ALIGN=CENTER ROWSPAN=3>Control / Status</TH>
<TD VALIGN=TOP ALIGN=CENTER><FONT FACE="COURIER">xxxxxxx0</FONT></TD>
<TD>Transmitted by capture device</TD>
<TD ROWSPAN=2 ALIGN=CENTER>(see 'Errors' octets)</TD> </TR>
<TR> <TD VALIGN=TOP ALIGN=CENTER><FONT FACE="COURIER">xxxxxxx1</FONT></TD>
<TD>Received by capture device</TD> </TR>
<TR> <TD VALIGN=TOP ALIGN=CENTER><FONT FACE="COURIER">1xxxxxxx</FONT></TD>
<TD COLSPAN=2>No buffer was available during capture of previous packet.</TD> </TR>
<TR> <TH VALIGN=TOP ALIGN=CENTER ROWSPAN=8>1</TH>
<TH VALIGN=TOP ALIGN=CENTER ROWSPAN=8>Signals</TH>
<TD VALIGN=TOP ALIGN=CENTER><FONT FACE="COURIER">xxxxxxx1</FONT></TD> <TD COLSPAN=2>DSR asserted</TD> </TR>
<TR> <TD VALIGN=TOP ALIGN=CENTER><FONT FACE="COURIER">xxxxxx1x</FONT></TD> <TD COLSPAN=2>DTR asserted</TD> </TR>
<TR> <TD VALIGN=TOP ALIGN=CENTER><FONT FACE="COURIER">xxxxx1xx</FONT></TD> <TD COLSPAN=2>CTS asserted</TD> </TR>
<TR> <TD VALIGN=TOP ALIGN=CENTER><FONT FACE="COURIER">xxxx1xxx</FONT></TD> <TD COLSPAN=2>RTS asserted</TD> </TR>
<TR> <TD VALIGN=TOP ALIGN=CENTER><FONT FACE="COURIER">xxx1xxxx</FONT></TD> <TD COLSPAN=2>DCD asserted</TD> </TR>
<TR> <TD VALIGN=TOP ALIGN=CENTER><FONT FACE="COURIER">xx1xxxxx</FONT></TD> <TD COLSPAN=2>Undefined</TD> </TR>
<TR> <TD VALIGN=TOP ALIGN=CENTER><FONT FACE="COURIER">x1xxxxxx</FONT></TD> <TD COLSPAN=2>Undefined</TD> </TR>
<TR> <TD VALIGN=TOP ALIGN=CENTER><FONT FACE="COURIER">1xxxxxxx</FONT></TD> <TD COLSPAN=2>Undefined</TD> </TR>
<TR> <TH VALIGN=TOP ALIGN=CENTER ROWSPAN=9>2</TH>
<TH VALIGN=TOP ALIGN=CENTER ROWSPAN=9>Errors<BR>(octet 1)</TH>
<TH>&nbsp;</TH> <TH>Tx</TH> <TH>Rx</TH> </TR>
<TR> <TD VALIGN=TOP ALIGN=CENTER><FONT FACE="COURIER">xxxxxxx1</FONT></TD> <TD>Underrun</TD> <TD>Framing</TD> </TR>
<TR> <TD VALIGN=TOP ALIGN=CENTER><FONT FACE="COURIER">xxxxxx1x</FONT></TD> <TD>CTS Lost</TD> <TD>Parity</TD> </TR>
<TR> <TD VALIGN=TOP ALIGN=CENTER><FONT FACE="COURIER">xxxxx1xx</FONT></TD> <TD>UART Error</TD> <TD>Collision</TD> </TR>
<TR> <TD VALIGN=TOP ALIGN=CENTER><FONT FACE="COURIER">xxxx1xxx</FONT></TD> <TD>Re-Tx Limit Reached</TD> <TD>Long Frame</TD> </TR>
<TR> <TD VALIGN=TOP ALIGN=CENTER><FONT FACE="COURIER">xxx1xxxx</FONT></TD> <TD>Undefined</TD> <TD>Short Frame</TD> </TR>
<TR> <TD VALIGN=TOP ALIGN=CENTER><FONT FACE="COURIER">xx1xxxxx</FONT></TD> <TD>Undefined</TD> <TD>Undefined</TD> </TR>
<TR> <TD VALIGN=TOP ALIGN=CENTER><FONT FACE="COURIER">x1xxxxxx</FONT></TD> <TD>Undefined</TD> <TD>Undefined</TD> </TR>
<TR> <TD VALIGN=TOP ALIGN=CENTER><FONT FACE="COURIER">1xxxxxxx</FONT></TD> <TD>Undefined</TD> <TD>Undefined</TD> </TR>
<TR> <TH VALIGN=TOP ALIGN=CENTER ROWSPAN=9>3</TH>
<TH VALIGN=TOP ALIGN=CENTER ROWSPAN=9>Errors<BR>(octet 2)</TH>
<TH>&nbsp;</TH> <TH>Tx</TH> <TH>Rx</TH> </TR>
<TR> <TD VALIGN=TOP ALIGN=CENTER><FONT FACE="COURIER">xxxxxxx1</FONT></TD> <TD>Undefined</TD> <TD>Non-Octet Aligned</TD> </TR>
<TR> <TD VALIGN=TOP ALIGN=CENTER><FONT FACE="COURIER">xxxxxx1x</FONT></TD> <TD>Undefined</TD> <TD>Abort Received</TD> </TR>
<TR> <TD VALIGN=TOP ALIGN=CENTER><FONT FACE="COURIER">xxxxx1xx</FONT></TD> <TD>Undefined</TD> <TD>CD Lost</TD> </TR>
<TR> <TD VALIGN=TOP ALIGN=CENTER><FONT FACE="COURIER">xxxx1xxx</FONT></TD> <TD>Undefined</TD> <TD>Digital PLL Error</TD> </TR>
<TR> <TD VALIGN=TOP ALIGN=CENTER><FONT FACE="COURIER">xxx1xxxx</FONT></TD> <TD>Undefined</TD> <TD>Overrun</TD> </TR>
<TR> <TD VALIGN=TOP ALIGN=CENTER><FONT FACE="COURIER">xx1xxxxx</FONT></TD> <TD>Undefined</TD> <TD>Frame Length Violation</TD> </TR>
<TR> <TD VALIGN=TOP ALIGN=CENTER><FONT FACE="COURIER">x1xxxxxx</FONT></TD> <TD>Undefined</TD> <TD>CRC Error</TD> </TR>
<TR> <TD VALIGN=TOP ALIGN=CENTER><FONT FACE="COURIER">1xxxxxxx</FONT></TD> <TD>Undefined</TD> <TD>Break Received</TD> </TR>
<TR> <TH VALIGN=TOP ALIGN=CENTER ROWSPAN=12>4</TH>
<TH VALIGN=TOP ALIGN=CENTER>Protocol</TH>
<TD COLSPAN=3>
<CENTER>
<TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0>
<TR VALIGN=BOTTOM><TD ALIGN=CENTER>0x01</TD> <TD>-</TD> <TD>LAPB (BOP) <SUP>&nbsp;</SUP> </TD> </TR>
<TR VALIGN=BOTTOM><TD ALIGN=CENTER>0x02</TD> <TD>-</TD> <TD>Ethernet <SUP>1</SUP> </TD> </TR>
<TR VALIGN=BOTTOM><TD ALIGN=CENTER>0x03</TD> <TD>-</TD> <TD>Async (Interrupt IO) <SUP>&nbsp;</SUP> </TD> </TR>
<TR VALIGN=BOTTOM><TD ALIGN=CENTER>0x04</TD> <TD>-</TD> <TD>Async (Block IO) <SUP>&nbsp;</SUP> </TD> </TR>
<TR VALIGN=BOTTOM><TD ALIGN=CENTER>0x05</TD> <TD>-</TD> <TD>IPARS <SUP>&nbsp;</SUP> </TD> </TR>
<TR VALIGN=BOTTOM><TD ALIGN=CENTER>0x06</TD> <TD>-</TD> <TD>UTS <SUP>&nbsp;</SUP> </TD> </TR>
<TR VALIGN=BOTTOM><TD ALIGN=CENTER>0x07</TD> <TD>-</TD> <TD>PPP (HDLC) <SUP>&nbsp;</SUP> </TD> </TR>
<TR VALIGN=BOTTOM><TD ALIGN=CENTER>0x08</TD> <TD>-</TD> <TD>SDLC <SUP>&nbsp;</SUP> </TD> </TR>
<TR VALIGN=BOTTOM><TD ALIGN=CENTER>0x09</TD> <TD>-</TD> <TD>Token Ring <SUP>1</SUP> </TD> </TR>
<TR VALIGN=BOTTOM><TD ALIGN=CENTER>0x10</TD> <TD>-</TD> <TD>I2C <SUP>&nbsp;</SUP> </TD> </TR>
<TR VALIGN=BOTTOM><TD ALIGN=CENTER>0x11</TD> <TD>-</TD> <TD>DPM Link <SUP>&nbsp;</SUP> </TD> </TR>
<TR VALIGN=BOTTOM><TD ALIGN=CENTER>0x12</TD> <TD>-</TD> <TD>Frame Relay (BOP) <SUP>&nbsp;</SUP> </TD> </TR>
</TABLE>
</CENTER>
<P>
<STRONG>Note 1:</STRONG>
Ethernet and Token Ring frames will never be sent as DLT_SITA (with the 5 octet header),
but will be sent as their corresponding DLT types instead.
</TD>
</TR>
</TABLE>
</CENTER>
</UL>
<P>
</UL>
</UL>

View File

@ -25,7 +25,7 @@
#ifndef lint
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/pcap-snit.c,v 1.72.2.1 2005/05/03 18:54:38 guy Exp $ (LBL)";
"@(#) $Header: /tcpdump/master/libpcap/pcap-snit.c,v 1.73.2.4 2008-04-14 20:41:52 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@ -113,7 +113,6 @@ static int
pcap_read_snit(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
{
register int cc, n;
register struct bpf_insn *fcode = p->fcode.bf_insns;
register u_char *bp, *cp, *ep;
register struct nit_bufhdr *hdrp;
register struct nit_iftime *ntp;
@ -187,13 +186,13 @@ pcap_read_snit(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
if (caplen > p->snapshot)
caplen = p->snapshot;
if (bpf_filter(fcode, cp, nlp->nh_pktlen, caplen)) {
if (bpf_filter(p->fcode.bf_insns, cp, nlp->nh_pktlen, caplen)) {
struct pcap_pkthdr h;
h.ts = ntp->nh_timestamp;
h.len = nlp->nh_pktlen;
h.caplen = caplen;
(*callback)(user, &h, cp);
if (++n >= cnt && cnt >= 0) {
if (++n >= cnt && cnt > 0) {
p->cc = ep - bp;
p->bp = bp;
return (n);
@ -261,30 +260,29 @@ nit_setflags(int fd, int promisc, int to_ms, char *ebuf)
return (0);
}
pcap_t *
pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
char *ebuf)
static int
pcap_activate_snit(pcap_t *p)
{
struct strioctl si; /* struct for ioctl() */
struct ifreq ifr; /* interface request struct */
int chunksize = CHUNKSIZE;
int fd;
static char dev[] = "/dev/nit";
register pcap_t *p;
p = (pcap_t *)malloc(sizeof(*p));
if (p == NULL) {
strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
return (NULL);
if (p->opt.rfmon) {
/*
* No monitor mode on SunOS 4.x (no Wi-Fi devices on
* hardware supported by SunOS 4.x).
*/
return (PCAP_ERROR_RFMON_NOTSUP);
}
if (snaplen < 96)
if (p->snapshot < 96)
/*
* NIT requires a snapshot length of at least 96.
*/
snaplen = 96;
p->snapshot = 96;
memset(p, 0, sizeof(*p));
/*
* Initially try a read/write open (to allow the inject
* method to work). If that fails due to permission
@ -303,19 +301,19 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
if (fd < 0 && errno == EACCES)
p->fd = fd = open(dev, O_RDONLY);
if (fd < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s: %s", dev,
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s", dev,
pcap_strerror(errno));
goto bad;
}
/* arrange to get discrete messages from the STREAM and use NIT_BUF */
if (ioctl(fd, I_SRDOPT, (char *)RMSGD) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "I_SRDOPT: %s",
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "I_SRDOPT: %s",
pcap_strerror(errno));
goto bad;
}
if (ioctl(fd, I_PUSH, "nbuf") < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "push nbuf: %s",
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "push nbuf: %s",
pcap_strerror(errno));
goto bad;
}
@ -325,34 +323,33 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
si.ic_len = sizeof(chunksize);
si.ic_dp = (char *)&chunksize;
if (ioctl(fd, I_STR, (char *)&si) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "NIOCSCHUNK: %s",
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "NIOCSCHUNK: %s",
pcap_strerror(errno));
goto bad;
}
/* request the interface */
strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
strncpy(ifr.ifr_name, p->opt.source, sizeof(ifr.ifr_name));
ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0';
si.ic_cmd = NIOCBIND;
si.ic_len = sizeof(ifr);
si.ic_dp = (char *)&ifr;
if (ioctl(fd, I_STR, (char *)&si) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "NIOCBIND: %s: %s",
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "NIOCBIND: %s: %s",
ifr.ifr_name, pcap_strerror(errno));
goto bad;
}
/* set the snapshot length */
si.ic_cmd = NIOCSSNAP;
si.ic_len = sizeof(snaplen);
si.ic_dp = (char *)&snaplen;
si.ic_len = sizeof(p->snapshot);
si.ic_dp = (char *)&p->snapshot;
if (ioctl(fd, I_STR, (char *)&si) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "NIOCSSNAP: %s",
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "NIOCSSNAP: %s",
pcap_strerror(errno));
goto bad;
}
p->snapshot = snaplen;
if (nit_setflags(p->fd, promisc, to_ms, ebuf) < 0)
if (nit_setflags(p->fd, p->opt.promisc, p->md.timeout, p->errbuf) < 0)
goto bad;
(void)ioctl(fd, I_FLUSH, (char *)FLUSHR);
@ -364,7 +361,7 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
p->bufsize = BUFSPACE;
p->buffer = (u_char *)malloc(p->bufsize);
if (p->buffer == NULL) {
strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
strlcpy(p->errbuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
goto bad;
}
@ -402,14 +399,23 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
p->getnonblock_op = pcap_getnonblock_fd;
p->setnonblock_op = pcap_setnonblock_fd;
p->stats_op = pcap_stats_snit;
p->close_op = pcap_close_common;
return (p);
return (0);
bad:
if (fd >= 0)
close(fd);
free(p);
return (NULL);
return (PCAP_ERROR);
}
pcap_t *
pcap_create(const char *device, char *ebuf)
{
pcap_t *p;
p = pcap_create_common(device, ebuf);
if (p == NULL)
return (NULL);
p->activate_op = pcap_activate_snit;
return (p);
}
int

View File

@ -20,7 +20,7 @@
*/
#ifndef lint
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/pcap-snoop.c,v 1.54.2.1 2005/05/03 18:54:38 guy Exp $ (LBL)";
"@(#) $Header: /tcpdump/master/libpcap/pcap-snoop.c,v 1.55.2.3 2008-04-14 20:41:52 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@ -194,9 +194,8 @@ pcap_stats_snoop(pcap_t *p, struct pcap_stat *ps)
}
/* XXX can't disable promiscuous */
pcap_t *
pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
char *ebuf)
static int
pcap_activate_snoop(pcap_t *p)
{
int fd;
struct sockaddr_raw sr;
@ -204,55 +203,50 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
u_int v;
int ll_hdrlen;
int snooplen;
pcap_t *p;
struct ifreq ifr;
p = (pcap_t *)malloc(sizeof(*p));
if (p == NULL) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
pcap_strerror(errno));
return (NULL);
}
memset(p, 0, sizeof(*p));
fd = socket(PF_RAW, SOCK_RAW, RAWPROTO_SNOOP);
if (fd < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "snoop socket: %s",
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "snoop socket: %s",
pcap_strerror(errno));
goto bad;
}
p->fd = fd;
memset(&sr, 0, sizeof(sr));
sr.sr_family = AF_RAW;
(void)strncpy(sr.sr_ifname, device, sizeof(sr.sr_ifname));
(void)strncpy(sr.sr_ifname, p->opt.source, sizeof(sr.sr_ifname));
if (bind(fd, (struct sockaddr *)&sr, sizeof(sr))) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "snoop bind: %s",
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "snoop bind: %s",
pcap_strerror(errno));
goto bad;
}
memset(&sf, 0, sizeof(sf));
if (ioctl(fd, SIOCADDSNOOP, &sf) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "SIOCADDSNOOP: %s",
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "SIOCADDSNOOP: %s",
pcap_strerror(errno));
goto bad;
}
v = 64 * 1024;
if (handle->opt.buffer_size != 0)
v = handle->opt.buffer_size;
else
v = 64 * 1024; /* default to 64K buffer size */
(void)setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (char *)&v, sizeof(v));
/*
* XXX hack - map device name to link layer type
*/
if (strncmp("et", device, 2) == 0 || /* Challenge 10 Mbit */
strncmp("ec", device, 2) == 0 || /* Indigo/Indy 10 Mbit,
O2 10/100 */
strncmp("ef", device, 2) == 0 || /* O200/2000 10/100 Mbit */
strncmp("eg", device, 2) == 0 || /* Octane/O2xxx/O3xxx Gigabit */
strncmp("gfe", device, 3) == 0 || /* GIO 100 Mbit */
strncmp("fxp", device, 3) == 0 || /* Challenge VME Enet */
strncmp("ep", device, 2) == 0 || /* Challenge 8x10 Mbit EPLEX */
strncmp("vfe", device, 3) == 0 || /* Challenge VME 100Mbit */
strncmp("fa", device, 2) == 0 ||
strncmp("qaa", device, 3) == 0 ||
strncmp("cip", device, 3) == 0 ||
strncmp("el", device, 2) == 0) {
if (strncmp("et", p->opt.source, 2) == 0 || /* Challenge 10 Mbit */
strncmp("ec", p->opt.source, 2) == 0 || /* Indigo/Indy 10 Mbit,
O2 10/100 */
strncmp("ef", p->opt.source, 2) == 0 || /* O200/2000 10/100 Mbit */
strncmp("eg", p->opt.source, 2) == 0 || /* Octane/O2xxx/O3xxx Gigabit */
strncmp("gfe", p->opt.source, 3) == 0 || /* GIO 100 Mbit */
strncmp("fxp", p->opt.source, 3) == 0 || /* Challenge VME Enet */
strncmp("ep", p->opt.source, 2) == 0 || /* Challenge 8x10 Mbit EPLEX */
strncmp("vfe", p->opt.source, 3) == 0 || /* Challenge VME 100Mbit */
strncmp("fa", p->opt.source, 2) == 0 ||
strncmp("qaa", p->opt.source, 3) == 0 ||
strncmp("cip", p->opt.source, 3) == 0 ||
strncmp("el", p->opt.source, 2) == 0) {
p->linktype = DLT_EN10MB;
p->offset = RAW_HDRPAD(sizeof(struct ether_header));
ll_hdrlen = sizeof(struct ether_header);
@ -285,29 +279,38 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
p->dlt_list[1] = DLT_DOCSIS;
p->dlt_count = 2;
}
} else if (strncmp("ipg", device, 3) == 0 ||
strncmp("rns", device, 3) == 0 || /* O2/200/2000 FDDI */
strncmp("xpi", device, 3) == 0) {
} else if (strncmp("ipg", p->opt.source, 3) == 0 ||
strncmp("rns", p->opt.source, 3) == 0 || /* O2/200/2000 FDDI */
strncmp("xpi", p->opt.source, 3) == 0) {
p->linktype = DLT_FDDI;
p->offset = 3; /* XXX yeah? */
ll_hdrlen = 13;
} else if (strncmp("ppp", device, 3) == 0) {
} else if (strncmp("ppp", p->opt.source, 3) == 0) {
p->linktype = DLT_RAW;
ll_hdrlen = 0; /* DLT_RAW meaning "no PPP header, just the IP packet"? */
} else if (strncmp("qfa", device, 3) == 0) {
} else if (strncmp("qfa", p->opt.source, 3) == 0) {
p->linktype = DLT_IP_OVER_FC;
ll_hdrlen = 24;
} else if (strncmp("pl", device, 2) == 0) {
} else if (strncmp("pl", p->opt.source, 2) == 0) {
p->linktype = DLT_RAW;
ll_hdrlen = 0; /* Cray UNICOS/mp pseudo link */
} else if (strncmp("lo", device, 2) == 0) {
} else if (strncmp("lo", p->opt.source, 2) == 0) {
p->linktype = DLT_NULL;
ll_hdrlen = 4;
} else {
snprintf(ebuf, PCAP_ERRBUF_SIZE,
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"snoop: unknown physical layer type");
goto bad;
}
if (p->opt.rfmon) {
/*
* No monitor mode on Irix (no Wi-Fi devices on
* hardware supported by Irix).
*/
return (PCAP_ERROR_RFMON_NOTSUP);
}
#ifdef SIOCGIFMTU
/*
* XXX - IRIX appears to give you an error if you try to set the
@ -315,9 +318,9 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
* the MTU first and, if that succeeds, trim the snap length
* to be no greater than the MTU.
*/
(void)strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
(void)strncpy(ifr.ifr_name, p->opt.source, sizeof(ifr.ifr_name));
if (ioctl(fd, SIOCGIFMTU, (char *)&ifr) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "SIOCGIFMTU: %s",
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "SIOCGIFMTU: %s",
pcap_strerror(errno));
goto bad;
}
@ -338,8 +341,8 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
#ifndef ifr_mtu
#define ifr_mtu ifr_metric
#endif
if (snaplen > ifr.ifr_mtu + ll_hdrlen)
snaplen = ifr.ifr_mtu + ll_hdrlen;
if (p->snapshot > ifr.ifr_mtu + ll_hdrlen)
p->snapshot = ifr.ifr_mtu + ll_hdrlen;
#endif
/*
@ -347,18 +350,17 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
* payload bytes to capture - it doesn't count link-layer
* header bytes.
*/
snooplen = snaplen - ll_hdrlen;
snooplen = p->snapshot - ll_hdrlen;
if (snooplen < 0)
snooplen = 0;
if (ioctl(fd, SIOCSNOOPLEN, &snooplen) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "SIOCSNOOPLEN: %s",
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "SIOCSNOOPLEN: %s",
pcap_strerror(errno));
goto bad;
}
p->snapshot = snaplen;
v = 1;
if (ioctl(fd, SIOCSNOOPING, &v) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "SIOCSNOOPING: %s",
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "SIOCSNOOPING: %s",
pcap_strerror(errno));
goto bad;
}
@ -366,7 +368,7 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
p->bufsize = 4096; /* XXX */
p->buffer = (u_char *)malloc(p->bufsize);
if (p->buffer == NULL) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "malloc: %s",
pcap_strerror(errno));
goto bad;
}
@ -384,18 +386,23 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
p->getnonblock_op = pcap_getnonblock_fd;
p->setnonblock_op = pcap_setnonblock_fd;
p->stats_op = pcap_stats_snoop;
p->close_op = pcap_close_common;
return (p);
return (0);
bad:
(void)close(fd);
/*
* Get rid of any link-layer type list we allocated.
*/
if (p->dlt_list != NULL)
free(p->dlt_list);
free(p);
return (NULL);
return (PCAP_ERROR);
}
pcap_t *
pcap_create(const char *device, char *ebuf)
{
pcap_t *p;
p = pcap_create_common(device, ebuf);
if (p == NULL)
return (NULL);
p->activate_op = pcap_activate_snoop;
return (p);
}
int

View File

@ -28,6 +28,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* @(#) $Header: /tcpdump/master/libpcap/pcap-stdinc.h,v 1.10.2.1 2008-10-06 15:38:39 gianluca Exp $ (LBL)
*/
#define SIZEOF_CHAR 1
@ -61,4 +62,29 @@
#define snprintf _snprintf
#define vsnprintf _vsnprintf
#define strdup _strdup
#define inline __inline
#ifdef __MINGW32__
#include <stdint.h>
#else /*__MINGW32__*/
/* MSVC compiler */
#ifndef _UINTPTR_T_DEFINED
#ifdef _WIN64
typedef unsigned __int64 uintptr_t;
#else
typedef _W64 unsigned int uintptr_t;
#endif
#define _UINTPTR_T_DEFINED
#endif
#ifndef _INTPTR_T_DEFINED
#ifdef _WIN64
typedef __int64 intptr_t;
#else
typedef _W64 int intptr_t;
#endif
#define _INTPTR_T_DEFINED
#endif
#endif /*__MINGW32__*/

730
pcap-usb-linux.c Normal file
View File

@ -0,0 +1,730 @@
/*
* Copyright (c) 2006 Paolo Abeni (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. 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 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.
*
* USB sniffing API implementation for Linux platform
* By Paolo Abeni <paolo.abeni@email.it>
* Modifications: Kris Katterjohn <katterjohn@gmail.com>
*
*/
#ifndef lint
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/pcap-usb-linux.c,v 1.16.2.8 2008-04-14 21:06:29 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "pcap-int.h"
#include "pcap-usb-linux.h"
#include "pcap/usb.h"
#ifdef NEED_STRERROR_H
#include "strerror.h"
#endif
#include <ctype.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <dirent.h>
#include <byteswap.h>
#include <netinet/in.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#define USB_IFACE "usb"
#define USB_TEXT_DIR "/sys/kernel/debug/usbmon"
#define USB_BUS_DIR "/proc/bus/usb"
#define USB_LINE_LEN 4096
#define PIPE_IN 0x80
#define PIPE_ISOCHRONOUS 0
#define PIPE_INTERRUPT 1
#define PIPE_CONTROL 2
#define PIPE_BULK 3
#if __BYTE_ORDER == __LITTLE_ENDIAN
#define htols(s) s
#define htoll(l) l
#define htol64(ll) ll
#else
#define htols(s) bswap_16(s)
#define htoll(l) bswap_32(l)
#define htol64(ll) bswap_64(ll)
#endif
struct mon_bin_stats {
u_int32_t queued;
u_int32_t dropped;
};
struct mon_bin_get {
pcap_usb_header *hdr;
void *data;
size_t data_len; /* Length of data (can be zero) */
};
struct mon_bin_mfetch {
int32_t *offvec; /* Vector of events fetched */
int32_t nfetch; /* Number of events to fetch (out: fetched) */
int32_t nflush; /* Number of events to flush */
};
#define MON_IOC_MAGIC 0x92
#define MON_IOCQ_URB_LEN _IO(MON_IOC_MAGIC, 1)
#define MON_IOCX_URB _IOWR(MON_IOC_MAGIC, 2, struct mon_bin_hdr)
#define MON_IOCG_STATS _IOR(MON_IOC_MAGIC, 3, struct mon_bin_stats)
#define MON_IOCT_RING_SIZE _IO(MON_IOC_MAGIC, 4)
#define MON_IOCQ_RING_SIZE _IO(MON_IOC_MAGIC, 5)
#define MON_IOCX_GET _IOW(MON_IOC_MAGIC, 6, struct mon_bin_get)
#define MON_IOCX_MFETCH _IOWR(MON_IOC_MAGIC, 7, struct mon_bin_mfetch)
#define MON_IOCH_MFLUSH _IO(MON_IOC_MAGIC, 8)
#define MON_BIN_SETUP 0x1 /* setup hdr is present*/
#define MON_BIN_SETUP_ZERO 0x2 /* setup buffer is not available */
#define MON_BIN_DATA_ZERO 0x4 /* data buffer is not available */
#define MON_BIN_ERROR 0x8
/* forward declaration */
static int usb_activate(pcap_t *);
static int usb_stats_linux(pcap_t *, struct pcap_stat *);
static int usb_stats_linux_bin(pcap_t *, struct pcap_stat *);
static int usb_read_linux(pcap_t *, int , pcap_handler , u_char *);
static int usb_read_linux_bin(pcap_t *, int , pcap_handler , u_char *);
static int usb_read_linux_mmap(pcap_t *, int , pcap_handler , u_char *);
static int usb_inject_linux(pcap_t *, const void *, size_t);
static int usb_setfilter_linux(pcap_t *, struct bpf_program *);
static int usb_setdirection_linux(pcap_t *, pcap_direction_t);
static void usb_cleanup_linux_mmap(pcap_t *);
/* facility to add an USB device to the device list*/
static int
usb_dev_add(pcap_if_t** alldevsp, int n, char *err_str)
{
char dev_name[10];
char dev_descr[30];
snprintf(dev_name, 10, USB_IFACE"%d", n);
snprintf(dev_descr, 30, "USB bus number %d", n);
if (pcap_add_if(alldevsp, dev_name, 0,
dev_descr, err_str) < 0)
return -1;
return 0;
}
int
usb_platform_finddevs(pcap_if_t **alldevsp, char *err_str)
{
struct dirent* data;
int ret = 0;
DIR* dir;
/* scan procfs usb bus directory */
dir = opendir(USB_BUS_DIR);
if (!dir) return 0;
while ((ret == 0) && ((data = readdir(dir)) != 0)) {
int n;
char* name = data->d_name;
int len = strlen(name);
/* if this file name does not end with a number it's not of our interest */
if ((len < 1) || !isdigit(name[--len]))
continue;
while (isdigit(name[--len]));
if (sscanf(&name[len+1], "%d", &n) != 1)
continue;
ret = usb_dev_add(alldevsp, n, err_str);
}
closedir(dir);
return ret;
}
static
int usb_mmap(pcap_t* handle)
{
int len = ioctl(handle->fd, MON_IOCQ_RING_SIZE);
if (len < 0)
return 0;
handle->buffer = mmap(0, len, PROT_READ, MAP_SHARED, handle->fd, 0);
return handle->buffer != MAP_FAILED;
}
pcap_t *
usb_create(const char *device, char *ebuf)
{
pcap_t *p;
p = pcap_create_common(device, ebuf);
if (p == NULL)
return (NULL);
p->activate_op = usb_activate;
return (p);
}
static int
usb_activate(pcap_t* handle)
{
char full_path[USB_LINE_LEN];
/* Initialize some components of the pcap structure. */
handle->bufsize = handle->snapshot;
handle->offset = 0;
handle->linktype = DLT_USB_LINUX;
handle->inject_op = usb_inject_linux;
handle->setfilter_op = usb_setfilter_linux;
handle->setdirection_op = usb_setdirection_linux;
handle->set_datalink_op = NULL; /* can't change data link type */
handle->getnonblock_op = pcap_getnonblock_fd;
handle->setnonblock_op = pcap_setnonblock_fd;
/*get usb bus index from device name */
if (sscanf(handle->opt.source, USB_IFACE"%d", &handle->md.ifindex) != 1)
{
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't get USB bus index from %s", handle->opt.source);
return PCAP_ERROR;
}
/*now select the read method: try to open binary interface */
snprintf(full_path, USB_LINE_LEN, LINUX_USB_MON_DEV"%d", handle->md.ifindex);
handle->fd = open(full_path, O_RDONLY, 0);
if (handle->fd >= 0)
{
if (handle->opt.rfmon) {
/*
* Monitor mode doesn't apply to USB devices.
*/
return PCAP_ERROR_RFMON_NOTSUP;
}
/* binary api is available, try to use fast mmap access */
if (usb_mmap(handle)) {
handle->stats_op = usb_stats_linux_bin;
handle->read_op = usb_read_linux_mmap;
handle->cleanup_op = usb_cleanup_linux_mmap;
/*
* "handle->fd" is a real file, so "select()" and
* "poll()" work on it.
*/
handle->selectable_fd = handle->fd;
return 0;
}
/* can't mmap, use plain binary interface access */
handle->stats_op = usb_stats_linux_bin;
handle->read_op = usb_read_linux_bin;
}
else {
/*Binary interface not available, try open text interface */
snprintf(full_path, USB_LINE_LEN, USB_TEXT_DIR"/%dt", handle->md.ifindex);
handle->fd = open(full_path, O_RDONLY, 0);
if (handle->fd < 0)
{
/* no more fallback, give it up*/
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't open USB bus file %s: %s", full_path, strerror(errno));
return PCAP_ERROR;
}
handle->stats_op = usb_stats_linux;
handle->read_op = usb_read_linux;
}
if (handle->opt.rfmon) {
/*
* Monitor mode doesn't apply to USB devices.
*/
return PCAP_ERROR_RFMON_NOTSUP;
}
/*
* "handle->fd" is a real file, so "select()" and "poll()"
* work on it.
*/
handle->selectable_fd = handle->fd;
/* for plain binary access and text access we need to allocate the read
* buffer */
handle->buffer = malloc(handle->bufsize);
if (!handle->buffer) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"malloc: %s", pcap_strerror(errno));
return PCAP_ERROR;
}
return 0;
}
static inline int
ascii_to_int(char c)
{
return c < 'A' ? c- '0': ((c<'a') ? c - 'A' + 10: c-'a'+10);
}
/*
* see <linux-kernel-source>/Documentation/usb/usbmon.txt and
* <linux-kernel-source>/drivers/usb/mon/mon_text.c for urb string
* format description
*/
static int
usb_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user)
{
/* see:
* /usr/src/linux/Documentation/usb/usbmon.txt
* for message format
*/
unsigned timestamp;
int tag, cnt, ep_num, dev_addr, dummy, ret, urb_len, data_len;
char etype, pipeid1, pipeid2, status[16], urb_tag, line[USB_LINE_LEN];
char *string = line;
u_char * rawdata = handle->buffer;
struct pcap_pkthdr pkth;
pcap_usb_header* uhdr = (pcap_usb_header*)handle->buffer;
u_char urb_transfer=0;
int incoming=0;
/* ignore interrupt system call errors */
do {
ret = read(handle->fd, line, USB_LINE_LEN - 1);
if (handle->break_loop)
{
handle->break_loop = 0;
return -2;
}
} while ((ret == -1) && (errno == EINTR));
if (ret < 0)
{
if (errno == EAGAIN)
return 0; /* no data there */
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't read from fd %d: %s", handle->fd, strerror(errno));
return -1;
}
/* read urb header; %n argument may increment return value, but it's
* not mandatory, so does not count on it*/
string[ret] = 0;
ret = sscanf(string, "%x %d %c %c%c:%d:%d %s%n", &tag, &timestamp, &etype,
&pipeid1, &pipeid2, &dev_addr, &ep_num, status,
&cnt);
if (ret < 8)
{
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't parse USB bus message '%s', too few tokens (expected 8 got %d)",
string, ret);
return -1;
}
uhdr->id = tag;
uhdr->endpoint_number = ep_num;
uhdr->device_address = dev_addr;
uhdr->bus_id = handle->md.ifindex;
uhdr->status = 0;
string += cnt;
/* don't use usbmon provided timestamp, since it have low precision*/
if (gettimeofday(&pkth.ts, NULL) < 0)
{
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't get timestamp for message '%s' %d:%s",
string, errno, strerror(errno));
return -1;
}
uhdr->ts_sec = pkth.ts.tv_sec;
uhdr->ts_usec = pkth.ts.tv_usec;
/* parse endpoint information */
if (pipeid1 == 'C')
urb_transfer = URB_CONTROL;
else if (pipeid1 == 'Z')
urb_transfer = URB_ISOCHRONOUS;
else if (pipeid1 == 'I')
urb_transfer = URB_INTERRUPT;
else if (pipeid1 == 'B')
urb_transfer = URB_BULK;
if (pipeid2 == 'i') {
urb_transfer |= URB_TRANSFER_IN;
incoming = 1;
}
if (etype == 'C')
incoming = !incoming;
/* direction check*/
if (incoming)
{
if (handle->direction == PCAP_D_OUT)
return 0;
}
else
if (handle->direction == PCAP_D_IN)
return 0;
uhdr->event_type = etype;
uhdr->transfer_type = urb_transfer;
pkth.caplen = sizeof(pcap_usb_header);
rawdata += sizeof(pcap_usb_header);
/* check if this is a setup packet */
ret = sscanf(status, "%d", &dummy);
if (ret != 1)
{
/* this a setup packet, setup data can be filled with underscore if
* usbmon has not been able to read them, so we must parse this fields as
* strings */
pcap_usb_setup* shdr;
char str1[3], str2[3], str3[5], str4[5], str5[5];
ret = sscanf(string, "%s %s %s %s %s%n", str1, str2, str3, str4,
str5, &cnt);
if (ret < 5)
{
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't parse USB bus message '%s', too few tokens (expected 5 got %d)",
string, ret);
return -1;
}
string += cnt;
/* try to convert to corresponding integer */
shdr = &uhdr->setup;
shdr->bmRequestType = strtoul(str1, 0, 16);
shdr->bRequest = strtoul(str2, 0, 16);
shdr->wValue = htols(strtoul(str3, 0, 16));
shdr->wIndex = htols(strtoul(str4, 0, 16));
shdr->wLength = htols(strtoul(str5, 0, 16));
uhdr->setup_flag = 0;
}
else
uhdr->setup_flag = 1;
/* read urb data */
ret = sscanf(string, " %d%n", &urb_len, &cnt);
if (ret < 1)
{
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't parse urb length from '%s'", string);
return -1;
}
string += cnt;
/* urb tag is not present if urb length is 0, so we can stop here
* text parsing */
pkth.len = urb_len+pkth.caplen;
uhdr->urb_len = urb_len;
uhdr->data_flag = 1;
data_len = 0;
if (uhdr->urb_len == pkth.caplen)
goto got;
/* check for data presence; data is present if and only if urb tag is '=' */
if (sscanf(string, " %c", &urb_tag) != 1)
{
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't parse urb tag from '%s'", string);
return -1;
}
if (urb_tag != '=')
goto got;
/* skip urb tag and following space */
string += 3;
/* if we reach this point we got some urb data*/
uhdr->data_flag = 0;
/* read all urb data; if urb length is greater then the usbmon internal
* buffer length used by the kernel to spool the URB, we get only
* a partial information.
* At least until linux 2.6.17 there is no way to set usbmon intenal buffer
* length and default value is 130. */
while ((string[0] != 0) && (string[1] != 0) && (pkth.caplen < handle->snapshot))
{
rawdata[0] = ascii_to_int(string[0]) * 16 + ascii_to_int(string[1]);
rawdata++;
string+=2;
if (string[0] == ' ')
string++;
pkth.caplen++;
data_len++;
}
got:
uhdr->data_len = data_len;
handle->md.packets_read++;
if (pkth.caplen > handle->snapshot)
pkth.caplen = handle->snapshot;
callback(user, &pkth, handle->buffer);
return 1;
}
static int
usb_inject_linux(pcap_t *handle, const void *buf, size_t size)
{
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "inject not supported on "
"USB devices");
return (-1);
}
static int
usb_stats_linux(pcap_t *handle, struct pcap_stat *stats)
{
int dummy, ret, consumed, cnt;
char string[USB_LINE_LEN];
char token[USB_LINE_LEN];
char * ptr = string;
snprintf(string, USB_LINE_LEN, USB_TEXT_DIR"/%ds", handle->md.ifindex);
int fd = open(string, O_RDONLY, 0);
if (fd < 0)
{
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't open USB stats file %s: %s",
string, strerror(errno));
return -1;
}
/* read stats line */
do {
ret = read(fd, string, USB_LINE_LEN-1);
} while ((ret == -1) && (errno == EINTR));
close(fd);
if (ret < 0)
{
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't read stats from fd %d ", fd);
return -1;
}
string[ret] = 0;
/* extract info on dropped urbs */
for (consumed=0; consumed < ret; ) {
/* from the sscanf man page:
* The C standard says: "Execution of a %n directive does
* not increment the assignment count returned at the completion
* of execution" but the Corrigendum seems to contradict this.
* Do not make any assumptions on the effect of %n conversions
* on the return value and explicitly check for cnt assignmet*/
cnt = -1;
int ntok = sscanf(ptr, "%s%n", token, &cnt);
if ((ntok < 1) || (cnt < 0))
break;
consumed += cnt;
ptr += cnt;
if (strcmp(token, "nreaders") == 0)
ret = sscanf(ptr, "%d", &stats->ps_drop);
else
ret = sscanf(ptr, "%d", &dummy);
if (ntok != 1)
break;
consumed += cnt;
ptr += cnt;
}
stats->ps_recv = handle->md.packets_read;
stats->ps_ifdrop = 0;
return 0;
}
static int
usb_setfilter_linux(pcap_t *p, struct bpf_program *fp)
{
return 0;
}
static int
usb_setdirection_linux(pcap_t *p, pcap_direction_t d)
{
p->direction = d;
return 0;
}
static int
usb_stats_linux_bin(pcap_t *handle, struct pcap_stat *stats)
{
int ret;
struct mon_bin_stats st;
ret = ioctl(handle->fd, MON_IOCG_STATS, &st);
if (ret < 0)
{
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't read stats from fd %d:%s ", handle->fd, strerror(errno));
return -1;
}
stats->ps_recv = handle->md.packets_read + st.queued;
stats->ps_ifdrop = st.dropped;
return 0;
}
/*
* see <linux-kernel-source>/Documentation/usb/usbmon.txt and
* <linux-kernel-source>/drivers/usb/mon/mon_bin.c binary ABI
*/
static int
usb_read_linux_bin(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user)
{
struct mon_bin_get info;
int ret;
struct pcap_pkthdr pkth;
int clen = handle->snapshot - sizeof(pcap_usb_header);
/* the usb header is going to be part of 'packet' data*/
info.hdr = (pcap_usb_header*) handle->buffer;
info.data = handle->buffer + sizeof(pcap_usb_header);
info.data_len = clen;
/* ignore interrupt system call errors */
do {
ret = ioctl(handle->fd, MON_IOCX_GET, &info);
if (handle->break_loop)
{
handle->break_loop = 0;
return -2;
}
} while ((ret == -1) && (errno == EINTR));
if (ret < 0)
{
if (errno == EAGAIN)
return 0; /* no data there */
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't read from fd %d: %s", handle->fd, strerror(errno));
return -1;
}
/* we can get less that than really captured from kernel, depending on
* snaplen, so adjust header accordingly */
if (info.hdr->data_len < clen)
clen = info.hdr->data_len;
info.hdr->data_len = clen;
pkth.caplen = clen + sizeof(pcap_usb_header);
pkth.len = info.hdr->urb_len + sizeof(pcap_usb_header);
pkth.ts.tv_sec = info.hdr->ts_sec;
pkth.ts.tv_usec = info.hdr->ts_usec;
handle->md.packets_read++;
callback(user, &pkth, handle->buffer);
return 1;
}
/*
* see <linux-kernel-source>/Documentation/usb/usbmon.txt and
* <linux-kernel-source>/drivers/usb/mon/mon_bin.c binary ABI
*/
#define VEC_SIZE 32
static int
usb_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user)
{
struct mon_bin_mfetch fetch;
int32_t vec[VEC_SIZE];
struct pcap_pkthdr pkth;
pcap_usb_header* hdr;
int nflush = 0;
int packets = 0;
for (;;) {
int i, ret;
int limit = max_packets - packets;
if (limit <= 0)
limit = VEC_SIZE;
if (limit > VEC_SIZE)
limit = VEC_SIZE;
/* try to fetch as many events as possible*/
fetch.offvec = vec;
fetch.nfetch = limit;
fetch.nflush = nflush;
/* ignore interrupt system call errors */
do {
ret = ioctl(handle->fd, MON_IOCX_MFETCH, &fetch);
if (handle->break_loop)
{
handle->break_loop = 0;
return -2;
}
} while ((ret == -1) && (errno == EINTR));
if (ret < 0)
{
if (errno == EAGAIN)
return 0; /* no data there */
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't mfetch fd %d: %s", handle->fd, strerror(errno));
return -1;
}
/* keep track of processed events, we will flush them later */
nflush = fetch.nfetch;
for (i=0; i<fetch.nfetch; ++i) {
/* discard filler */
hdr = (pcap_usb_header*) &handle->buffer[vec[i]];
if (hdr->event_type == '@')
continue;
/* get packet info from header*/
pkth.caplen = hdr->data_len + sizeof(pcap_usb_header);
pkth.len = hdr->urb_len + sizeof(pcap_usb_header);
pkth.ts.tv_sec = hdr->ts_sec;
pkth.ts.tv_usec = hdr->ts_usec;
handle->md.packets_read++;
callback(user, &pkth, (u_char*) hdr);
packets++;
}
/* with max_packets <= 0 we stop afer the first chunk*/
if ((max_packets <= 0) || (packets == max_packets))
break;
}
/* flush pending events*/
ioctl(handle->fd, MON_IOCH_MFLUSH, nflush);
return packets;
}
static void
usb_cleanup_linux_mmap(pcap_t* handle)
{
/* buffer must not be freed because it's memory mapped */
/* XXX - does it need to be unmapped? */
handle->buffer = NULL;
pcap_cleanup_live_common(handle);
}

40
pcap-usb-linux.h Normal file
View File

@ -0,0 +1,40 @@
/*
* Copyright (c) 2006 Paolo Abeni (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. 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 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.
*
* USB sniffing API implementation for Linux platform
* By Paolo Abeni <paolo.abeni@email.it>
*
* @(#) $Header: /tcpdump/master/libpcap/pcap-usb-linux.h,v 1.4.2.1 2008-04-04 19:39:06 guy Exp $ (LBL)
*/
/*
* Prototypes for USB-related functions
*/
int usb_platform_finddevs(pcap_if_t **alldevsp, char *err_str);
pcap_t *usb_create(const char *device, char *ebuf);

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy)
* Copyright (c) 2005 - 2007 CACE Technologies, Davis (California)
* Copyright (c) 2005 - 2008 CACE Technologies, Davis (California)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -33,12 +33,16 @@
#ifndef lint
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/pcap-win32.c,v 1.25.2.7 2007/06/14 22:07:14 gianluca Exp $ (LBL)";
"@(#) $Header: /tcpdump/master/libpcap/pcap-win32.c,v 1.34.2.8 2008-05-21 22:11:26 gianluca Exp $ (LBL)";
#endif
#include <pcap-int.h>
#include <Packet32.h>
#include <Ntddndis.h>
#ifdef __MINGW32__
#include <ddk/ndis.h>
#else /*__MINGW32__*/
#include <ntddndis.h>
#endif /*__MINGW32__*/
#ifdef HAVE_DAG_API
#include <dagnew.h>
#include <dagapi.h>
@ -53,8 +57,11 @@ static int pcap_setfilter_win32_dag(pcap_t *, struct bpf_program *);
static int pcap_getnonblock_win32(pcap_t *, char *);
static int pcap_setnonblock_win32(pcap_t *, int, char *);
#define PcapBufSize 256000 /*dimension of the buffer in the pcap_t structure*/
#define SIZE_BUF 1000000
/*dimension of the buffer in the pcap_t structure*/
#define WIN32_DEFAULT_USER_BUFFER_SIZE 256000
/*dimension of the buffer in the kernel driver NPF */
#define WIN32_DEFAULT_KERNEL_BUFFER_SIZE 1000000
/* Equivalent to ntohs(), but a lot faster under Windows */
#define SWAPS(_X) ((_X & 0xff) << 8) | (_X >> 8)
@ -100,6 +107,43 @@ pcap_stats_win32(pcap_t *p, struct pcap_stat *ps)
return 0;
}
/* Set the dimension of the kernel-level capture buffer */
static int
pcap_setbuff_win32(pcap_t *p, int dim)
{
if(PacketSetBuff(p->adapter,dim)==FALSE)
{
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: not enough memory to allocate the kernel buffer");
return -1;
}
return 0;
}
/* Set the driver working mode */
static int
pcap_setmode_win32(pcap_t *p, int mode)
{
if(PacketSetMode(p->adapter,mode)==FALSE)
{
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: working mode not recognized");
return -1;
}
return 0;
}
/*set the minimum amount of data that will release a read call*/
static int
pcap_setmintocopy_win32(pcap_t *p, int size)
{
if(PacketSetMinToCopy(p->adapter, size)==FALSE)
{
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: unable to set the requested mintocopy size");
return -1;
}
return 0;
}
static int
pcap_read_win32_npf(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
{
@ -376,9 +420,8 @@ pcap_inject_win32(pcap_t *p, const void *buf, size_t size){
}
static void
pcap_close_win32(pcap_t *p)
pcap_cleanup_win32(pcap_t *p)
{
pcap_close_common(p);
if (p->adapter != NULL) {
PacketCloseAdapter(p->adapter);
p->adapter = NULL;
@ -387,41 +430,39 @@ pcap_close_win32(pcap_t *p)
PacketFreePacket(p->Packet);
p->Packet = NULL;
}
pcap_cleanup_live_common(p);
}
pcap_t *
pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
char *ebuf)
static int
pcap_activate_win32(pcap_t *p)
{
register pcap_t *p;
NetType type;
if (p->opt.rfmon) {
/*
* No monitor mode on Windows. It could be done on
* Vista with drivers that support the native 802.11
* mechanism and monitor mode.
*/
return (PCAP_ERROR_RFMON_NOTSUP);
}
/* Init WinSock */
wsockinit();
p = (pcap_t *)malloc(sizeof(*p));
if (p == NULL)
{
snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
return (NULL);
}
memset(p, 0, sizeof(*p));
p->adapter=NULL;
p->adapter = PacketOpenAdapter((char*)device);
p->adapter = PacketOpenAdapter(p->opt.source);
if (p->adapter == NULL)
{
free(p);
/* Adapter detected but we are not able to open it. Return failure. */
snprintf(ebuf, PCAP_ERRBUF_SIZE, "Error opening adapter: %s", pcap_win32strerror());
return NULL;
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Error opening adapter: %s", pcap_win32strerror());
return PCAP_ERROR;
}
/*get network type*/
if(PacketGetNetType (p->adapter,&type) == FALSE)
{
snprintf(ebuf, PCAP_ERRBUF_SIZE, "Cannot determine the network type: %s", pcap_win32strerror());
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Cannot determine the network type: %s", pcap_win32strerror());
goto bad;
}
@ -505,12 +546,12 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
}
/* Set promiscuous mode */
if (promisc)
if (p->opt.promisc)
{
if (PacketSetHwFilter(p->adapter,NDIS_PACKET_TYPE_PROMISCUOUS) == FALSE)
{
snprintf(ebuf, PCAP_ERRBUF_SIZE, "failed to set hardware filter to promiscuous mode");
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "failed to set hardware filter to promiscuous mode");
goto bad;
}
}
@ -518,21 +559,18 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
{
if (PacketSetHwFilter(p->adapter,NDIS_PACKET_TYPE_ALL_LOCAL) == FALSE)
{
snprintf(ebuf, PCAP_ERRBUF_SIZE, "failed to set hardware filter to non-promiscuous mode");
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "failed to set hardware filter to non-promiscuous mode");
goto bad;
}
}
/* Set the buffer size */
p->bufsize = PcapBufSize;
/* Store the timeout. Used by pcap_setnonblock() */
p->timeout= to_ms;
p->bufsize = WIN32_DEFAULT_USER_BUFFER_SIZE;
/* allocate Packet structure used during the capture */
if((p->Packet = PacketAllocatePacket())==NULL)
{
snprintf(ebuf, PCAP_ERRBUF_SIZE, "failed to allocate the PACKET structure");
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "failed to allocate the PACKET structure");
goto bad;
}
@ -541,29 +579,32 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
/*
* Traditional Adapter
*/
/*
* If the buffer size wasn't explicitly set, default to
* WIN32_DEFAULT_USER_BUFFER_SIZE.
*/
if (p->opt.buffer_size == 0)
p->opt.buffer_size = WIN32_DEFAULT_KERNEL_BUFFER_SIZE;
if(PacketSetBuff(p->adapter,p->opt.buffer_size)==FALSE)
{
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: not enough memory to allocate the kernel buffer");
goto bad;
}
p->buffer = (u_char *)malloc(PcapBufSize);
p->buffer = (u_char *)malloc(p->bufsize);
if (p->buffer == NULL)
{
snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
goto bad;
}
PacketInitPacket(p->Packet,(BYTE*)p->buffer,p->bufsize);
p->snapshot = snaplen;
/* allocate the standard buffer in the driver */
if(PacketSetBuff( p->adapter, SIZE_BUF)==FALSE)
{
snprintf(ebuf, PCAP_ERRBUF_SIZE,"driver error: not enough memory to allocate the kernel buffer\n");
goto bad;
}
/* tell the driver to copy the buffer only if it contains at least 16K */
if(PacketSetMinToCopy(p->adapter,16000)==FALSE)
{
snprintf(ebuf, PCAP_ERRBUF_SIZE,"Error calling PacketSetMinToCopy: %s\n", pcap_win32strerror());
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,"Error calling PacketSetMinToCopy: %s", pcap_win32strerror());
goto bad;
}
}
@ -582,7 +623,7 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
snprintf(keyname, sizeof(keyname), "%s\\CardParams\\%s",
"SYSTEM\\CurrentControlSet\\Services\\DAG",
strstr(_strlwr((char*)device), "dag"));
strstr(_strlwr(p->opt.source), "dag"));
do
{
status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyname, 0, KEY_READ, &dagkey);
@ -616,7 +657,7 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
goto bad;
#endif /* HAVE_DAG_API */
PacketSetReadTimeout(p->adapter, to_ms);
PacketSetReadTimeout(p->adapter, p->md.timeout);
#ifdef HAVE_DAG_API
if(p->adapter->Flags & INFO_FLAG_DAG_CARD)
@ -641,25 +682,60 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
p->getnonblock_op = pcap_getnonblock_win32;
p->setnonblock_op = pcap_setnonblock_win32;
p->stats_op = pcap_stats_win32;
p->close_op = pcap_close_win32;
p->setbuff_op = pcap_setbuff_win32;
p->setmode_op = pcap_setmode_win32;
p->setmintocopy_op = pcap_setmintocopy_win32;
p->cleanup_op = pcap_cleanup_win32;
return (p);
return (0);
bad:
if (p->adapter)
PacketCloseAdapter(p->adapter);
if (p->buffer != NULL)
free(p->buffer);
if(p->Packet)
PacketFreePacket(p->Packet);
/*
* Get rid of any link-layer type list we allocated.
*/
if (p->dlt_list != NULL)
free(p->dlt_list);
free(p);
return (NULL);
pcap_cleanup_win32(p);
return (PCAP_ERROR);
}
pcap_t *
pcap_create(const char *device, char *ebuf)
{
pcap_t *p;
if (strlen(device) == 1)
{
/*
* It's probably a unicode string
* Convert to ascii and pass it to pcap_create_common
*
* This wonderful hack is needed because pcap_lookupdev still returns
* unicode strings, and it's used by windump when no device is specified
* in the command line
*/
size_t length;
char* deviceAscii;
length = wcslen((wchar_t*)device);
deviceAscii = (char*)malloc(length + 1);
if (deviceAscii == NULL)
{
snprintf(ebuf, PCAP_ERRBUF_SIZE, "Malloc failed");
return NULL;
}
snprintf(deviceAscii, length + 1, "%ws", (wchar_t*)device);
p = pcap_create_common(deviceAscii, ebuf);
free(deviceAscii);
}
else
{
p = pcap_create_common(device, ebuf);
}
if (p == NULL)
return (NULL);
p->activate_op = pcap_activate_win32;
return (p);
}
static int
pcap_setfilter_win32_npf(pcap_t *p, struct bpf_program *fp)
@ -736,7 +812,7 @@ pcap_setnonblock_win32(pcap_t *p, int nonblock, char *errbuf)
* (Note that this may be -1, in which case we're not
* really leaving non-blocking mode.)
*/
newtimeout = p->timeout;
newtimeout = p->md.timeout;
}
if (!PacketSetReadTimeout(p->adapter, newtimeout)) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
@ -747,57 +823,9 @@ pcap_setnonblock_win32(pcap_t *p, int nonblock, char *errbuf)
return (0);
}
/* Set the driver working mode */
int
pcap_setmode(pcap_t *p, int mode){
if (p->adapter==NULL)
{
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "impossible to set mode while reading from a file");
return -1;
}
if(PacketSetMode(p->adapter,mode)==FALSE)
{
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: working mode not recognized");
return -1;
}
return 0;
}
/* Set the dimension of the kernel-level capture buffer */
int
pcap_setbuff(pcap_t *p, int dim)
/*platform-dependent routine to add devices other than NDIS interfaces*/
int
pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
{
if (p->adapter==NULL)
{
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "The kernel buffer size cannot be set while reading from a file");
return -1;
}
if(PacketSetBuff(p->adapter,dim)==FALSE)
{
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: not enough memory to allocate the kernel buffer");
return -1;
}
return 0;
}
/*set the minimum amount of data that will release a read call*/
int
pcap_setmintocopy(pcap_t *p, int size)
{
if (p->adapter==NULL)
{
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Impossible to set the mintocopy parameter on an offline capture");
return -1;
}
if(PacketSetMinToCopy(p->adapter, size)==FALSE)
{
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: unable to set the requested mintocopy size");
return -1;
}
return 0;
return (0);
}

1312
pcap.3

File diff suppressed because it is too large Load Diff

386
pcap.3pcap.in Normal file
View File

@ -0,0 +1,386 @@
.\" @(#) $Header: /tcpdump/master/libpcap/pcap.3pcap.in,v 1.1.2.2 2008-10-21 07:44:57 guy Exp $
.\"
.\" Copyright (c) 1994, 1996, 1997
.\" The Regents of the University of California. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that: (1) source code distributions
.\" retain the above copyright notice and this paragraph in its entirety, (2)
.\" distributions including binary code include the above copyright notice and
.\" this paragraph in its entirety in the documentation or other materials
.\" provided with the distribution, and (3) all advertising materials mentioning
.\" features or use of this software display the following acknowledgement:
.\" ``This product includes software developed by the University of California,
.\" Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
.\" the University nor the names of its contributors may be used to endorse
.\" or promote products derived from this software without specific prior
.\" written permission.
.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\"
.TH PCAP 3PCAP "4 April 2008"
.SH NAME
pcap \- Packet Capture library
.SH SYNOPSIS
.nf
.ft B
#include <pcap/pcap.h>
.LP
.ft B
.ft
.fi
.SH DESCRIPTION
The Packet Capture library
provides a high level interface to packet capture systems. All packets
on the network, even those destined for other hosts, are accessible
through this mechanism.
It also supports saving captured packets to a ``savefile'', and reading
packets from a ``savefile''.
.PP
To open a handle for a live capture, call
.BR pcap_create() ,
set the appropriate options on the handle, and then activate it with
.BR pcap_activate() .
To open a handle for a ``savefile'' with captured packets, call
.BR pcap_open_offline() .
Both
.B pcap_create()
and
.B pcap_open_offline()
return a pointer to a
.BR pcap_t ,
which is the handle used for reading packets from the capture stream or
the ``savefile'', and for finding out information about the capture
stream or ``savefile''.
.PP
The options that can be set on a capture handle include
.IP "snapshot length"
If, when capturing, you capture the entire contents of the packet, that
requires more CPU time to copy the packet to your application, more disk
and possibly network bandwidth to write the packet data to a file, and
more disk space to save the packet. If you don't need the entire
contents of the packet - for example, if you are only interested in the
TCP headers of packets - you can set the "snapshot length" for the
capture to an appropriate value. If the snapshot length is set to
.IR snaplen ,
and
.I snaplen
is less
than the size of a packet that is captured, only the first
.I snaplen
bytes of that packet will be captured and provided as packet data.
.IP
A snapshot length of 65535 should be sufficient, on most if not all
networks, to capture all the data available from the packet.
.IP
The snapshot length is set with
.BR pcap_set_snaplen() .
.IP "promiscuous mode"
On broadcast LANs such as Ethernet, if the network isn't switched, or if
the adapter is connected to a "mirror port" on a switch to which all
packets passing through the switch are sent, a network adapter receives
all packets on the LAN, including unicast or multicast packets not sent
to a network address that the network adapter isn't configured to
recognize.
.IP
Normally, the adapter will discard those packets; however, many network
adapters support "promiscuous mode", which is a mode in which all
packets, even if they are not sent to an address that the adapter
recognizes, are provided to the host. This is useful for passively
capturing traffic between two or more other hosts for analysis.
.IP
Note that even if an application does not set promiscuous mode, the
adapter could well be in promiscuous mode for some other reason.
.IP
For now, this doesn't work on the "any" device; if an argument of "any"
or NULL is supplied, the setting of promiscuous mode is ignored.
.IP
Promiscuous mode is set with
.BR pcap_set_promisc() .
.IP "monitor mode"
On IEEE 802.11 wireless LANs, even if an adapter is in promiscuous mode,
it will supply to the host only frames for the network with which it's
associated. It might also supply only data frames, not management or
control frames, and might not provide the 802.11 header or radio
information pseudo-header for those frames.
.IP
In "monitor mode", sometimes also called "rfmon mode" (for "Radio
Frequency MONitor"), the adapter will supply all frames that it
receives, with 802.11 headers, and might supply a pseudo-header with
radio information about the frame as well.
.IP
Note that in monitor mode the adapter might disassociate from the
network with which it's associated, so that you will not be able to use
any wireless networks with that adapter. This could prevent accessing
files on a network server, or resolving host names or network addresses,
if you are capturing in monitor mode and are not connected to another
network with another adapter.
.IP
Monitor mode is set with
.BR pcap_set_rfmon() ,
and
.B pcap_can_set_rfmon()
can be used to determine whether an adapter can be put into monitor
mode.
.IP "read timeout"
If, when capturing, packets are delivered as soon as they arrive, the
application capturing the packets will be woken up for each packet as it
arrives, and might have to make one or more calls to the operating
system to fetch each packet.
.IP
If, instead, packets are not delivered as soon as they arrive, but are
delivered after a short delay (called a "read timeout"), more than one
packet can be accumulated before the packets are delivered, so that a
single wakeup would be done for multiple packets, and each set of calls
made to the operating system would supply multiple packets, rather than
a single packet. This reduces the per-packet CPU overhead if packets
are arriving at a high rate, increasing the number of packets per second
that can be captured.
.IP
The read timeout is required so that an application won't wait for the
operating system's capture buffer to fill up before packets are
delivered; if packets are arriving slowly, that wait could take an
arbitrarily long period of time.
.IP
Not all platforms support a read timeout; on platforms that
don't, the read timeout is ignored. A zero value for the timeout,
on platforms that support a read timeout,
will cause a read to wait forever to allow enough packets to
arrive, with no timeout.
.IP
.BR NOTE :
the read timeout cannot be used to cause calls that read
packets to return within a limited period of time, because, on some
platforms, the read timeout isn't supported, and, on other platforms,
the timer doesn't start until at least one packet arrives. This means
that the read timeout should
.B NOT
be used, for example, in an interactive application to allow the packet
capture loop to ``poll'' for user input periodically, as there's no
guarantee that a call reading packets will return after the timeout
expires even if no packets have arrived.
.IP
The read timeout is set with
.BR pcap_set_timeout() .
.IP "buffer size"
Packets that arrive for a capture are stored in a buffer, so that they
do not have to be read by the application as soon as they arrive. On
some platforms, the buffer's size can be set; a size that's too small
could mean that, if too many packets are being captured and the snapshot
length doesn't limit the amount of data that's buffered, packets could
be dropped if the buffer fills up before the application can read
packets from it, while a size that's too large could use more
non-pageable operating system memory than is necessary to prevent
packets from being dropped.
.IP
The buffer size is set with
.BR pcap_set_buffer_size() .
.PP
Reading packets from a network interface may require that you have
special privileges:
.TP
.B Under SunOS 3.x or 4.x with NIT or BPF:
You must have read access to
.I /dev/nit
or
.IR /dev/bpf* .
.TP
.B Under Solaris with DLPI:
You must have read/write access to the network pseudo device, e.g.
.IR /dev/le .
On at least some versions of Solaris, however, this is not sufficient to
allow
.I tcpdump
to capture in promiscuous mode; on those versions of Solaris, you must
be root, or the application capturing packets
must be installed setuid to root, in order to capture in promiscuous
mode. Note that, on many (perhaps all) interfaces, if you don't capture
in promiscuous mode, you will not see any outgoing packets, so a capture
not done in promiscuous mode may not be very useful.
.IP
In newer versions of Solaris, you must have been given the
.B net_rawaccess
privilege; this is both necessary and sufficient to give you access to the
network pseudo-device - there is no need to change the privileges on
that device. A user can be given that privilege by, for example, adding
that privilege to the user's
.B defaultpriv
key with the
.B usermod (1M)
command.
.TP
.B Under HP-UX with DLPI:
You must be root or the application capturing packets must be installed
setuid to root.
.TP
.B Under IRIX with snoop:
You must be root or the application capturing packets must be installed
setuid to root.
.TP
.B Under Linux:
You must be root or the application capturing packets must be installed
setuid to root (unless your distribution has a kernel
that supports capability bits such as CAP_NET_RAW and code to allow
those capability bits to be given to particular accounts and to cause
those bits to be set on a user's initial processes when they log in, in
which case you must have CAP_NET_RAW in order to capture and
CAP_NET_ADMIN to enumerate network devices with, for example, the
.B \-D
flag).
.TP
.B Under ULTRIX and Digital UNIX/Tru64 UNIX:
Any user may capture network traffic.
However, no user (not even the super-user) can capture in promiscuous
mode on an interface unless the super-user has enabled promiscuous-mode
operation on that interface using
.IR pfconfig (8),
and no user (not even the super-user) can capture unicast traffic
received by or sent by the machine on an interface unless the super-user
has enabled copy-all-mode operation on that interface using
.IR pfconfig ,
so
.I useful
packet capture on an interface probably requires that either
promiscuous-mode or copy-all-mode operation, or both modes of
operation, be enabled on that interface.
.TP
.B Under BSD (this includes Mac OS X):
You must have read access to
.I /dev/bpf*
on systems that don't have a cloning BPF device, or to
.I /dev/bpf
on systems that do.
On BSDs with a devfs (this includes Mac OS X), this might involve more
than just having somebody with super-user access setting the ownership
or permissions on the BPF devices - it might involve configuring devfs
to set the ownership or permissions every time the system is booted,
if the system even supports that; if it doesn't support that, you might
have to find some other way to make that happen at boot time.
.PP
Reading a saved packet file doesn't require special privileges.
.PP
To open a ``savefile`` to which to write packets, call
.BR pcap_dump_open() .
It returns a pointer to a
.BR pcap_dumper_t ,
which is the handle used for writing packets to the ``savefile''.
.PP
Packets are read with
.B pcap_dispatch()
or
.BR pcap_loop() ,
which process one or more packets, calling a callback routine for each
packet, or with
.B pcap_next()
or
.BR pcap_next_ex() ,
which return the next packet.
The callback for
.B pcap_dispatch()
and
.BR pcap_loop()
is supplied a pointer to a
.IR "struct pcap_pkthdr" ,
which includes the following members:
.RS
.TP
.B ts
a
.I struct timeval
containing the time when the packet was captured
.TP
.B caplen
a
.I bpf_u_int32
giving the number of bytes of the packet that are available from the
capture
.TP
.B len
a
.I bpf_u_int32
giving the length of the packet, in bytes (which might be more than the
number of bytes available from the capture, if the length of the packet
is larger than the maximum number of bytes to capture).
.RE
.PP
.B pcap_next_ex()
supplies that pointer through a pointer argument.
.B pcap_next()
is passed an argument that points to a
.I struct pcap_pkthdr
structure, and fills it in.
.PP
The callback is also supplied a
.I const u_char
pointer to the first
.B caplen
(as given in the
.I struct pcap_pkthdr
a pointer to which is passed to the callback routine)
bytes of data from the packet. This won't necessarily be the entire
packet; to capture the entire packet, you will have to provide a value
for
.I snaplen
in your call to
.B pcap_open_live()
that is sufficiently large to get all of the packet's data - a value of
65535 should be sufficient on most if not all networks). When reading
from a ``savefile'', the snapshot length specified when the capture was
performed will limit the amount of packet data available.
.B pcap_next()
returns that pointer;
.B pcap_next_ex()
supplies that pointer through a pointer argument.
.SH BACKWARDS COMPATIBILITY
.PP
In versions of libpcap prior to 1.0, the
.B pcap.h
header file was not in a
.B pcap
directory on most platforms; if you are writing an application that must
work on versions of libpcap prior to 1.0, include
.BR <pcap.h> ,
which will include
.B <pcap/pcap.h>
for you, rather than including
.BR <pcap/pcap.h> .
.PP
.B pcap_create()
and
.B pcap_activate()
were not available in versions of libpcap prior to 1.0; if you are
writing an application that must work on versions of libpcap prior to
1.0, either use
.B pcap_open_live()
to get a handle for a live capture or, if you want to be able to use the
additional capabilities offered by using
.B pcap_create()
and
.BR pcap_activate() ,
use an
.BR autoconf (1)
script or some other configuration script to check whether the libpcap
1.0 APIs are available and use them only if they are.
.SH SEE ALSO
autoconf(1), tcpdump(1), tcpslice(1), pcap-filter(@MAN_MISC_INFO@), pfconfig(8),
usermod(1M)
.SH AUTHORS
The original authors of libpcap are:
.LP
Van Jacobson,
Craig Leres and
Steven McCanne, all of the
Lawrence Berkeley National Laboratory, University of California, Berkeley, CA.
.LP
The current version is available from "The Tcpdump Group"'s Web site at
.LP
.RS
.I http://www.tcpdump.org/
.RE
.SH BUGS
Please send problems, bugs, questions, desirable enhancements, etc. to:
.LP
.RS
tcpdump-workers@lists.tcpdump.org
.RE

508
pcap.c
View File

@ -33,7 +33,7 @@
#ifndef lint
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/pcap.c,v 1.88.2.19 2007/09/19 02:50:52 guy Exp $ (LBL)";
"@(#) $Header: /tcpdump/master/libpcap/pcap.c,v 1.112.2.12 2008-09-22 20:16:01 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@ -70,10 +70,205 @@ static const char rcsid[] _U_ =
#include <dagapi.h>
#endif
int
pcap_not_initialized(pcap_t *pcap)
{
/* this means 'not initialized' */
return PCAP_ERROR_NOT_ACTIVATED;
}
/*
* Returns 1 if rfmon mode can be set on the pcap_t, 0 if it can't,
* a PCAP_ERROR value on an error.
*/
int
pcap_can_set_rfmon(pcap_t *p)
{
return (p->can_set_rfmon_op(p));
}
/*
* For systems where rfmon mode is never supported.
*/
static int
pcap_cant_set_rfmon(pcap_t *p _U_)
{
return (0);
}
pcap_t *
pcap_create_common(const char *source, char *ebuf)
{
pcap_t *p;
p = malloc(sizeof(*p));
if (p == NULL) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
pcap_strerror(errno));
return (NULL);
}
memset(p, 0, sizeof(*p));
#ifndef WIN32
p->fd = -1; /* not opened yet */
#endif
p->opt.source = strdup(source);
if (p->opt.source == NULL) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
pcap_strerror(errno));
free(p);
return (NULL);
}
/*
* Default to "can't set rfmon mode"; if it's supported by
* a platform, it can set the op to its routine to check
* whether a particular device supports it.
*/
p->can_set_rfmon_op = pcap_cant_set_rfmon;
/*
* Some operations can be performed only on activated pcap_t's;
* have those operations handled by a "not supported" handler
* until the pcap_t is activated.
*/
p->read_op = (read_op_t)pcap_not_initialized;
p->inject_op = (inject_op_t)pcap_not_initialized;
p->setfilter_op = (setfilter_op_t)pcap_not_initialized;
p->setdirection_op = (setdirection_op_t)pcap_not_initialized;
p->set_datalink_op = (set_datalink_op_t)pcap_not_initialized;
p->getnonblock_op = (getnonblock_op_t)pcap_not_initialized;
p->setnonblock_op = (setnonblock_op_t)pcap_not_initialized;
p->stats_op = (stats_op_t)pcap_not_initialized;
#ifdef WIN32
p->setbuff_op = (setbuff_op_t)pcap_not_initialized;
p->setmode_op = (setmode_op_t)pcap_not_initialized;
p->setmintocopy_op = (setmintocopy_op_t)pcap_not_initialized;
#endif
p->cleanup_op = pcap_cleanup_live_common;
/* put in some defaults*/
pcap_set_timeout(p, 0);
pcap_set_snaplen(p, 65535); /* max packet size */
p->opt.promisc = 0;
p->opt.buffer_size = 0;
return (p);
}
int
pcap_check_activated(pcap_t *p)
{
if (p->activated) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "can't perform "
" operation on activated capture");
return -1;
}
return 0;
}
int
pcap_set_snaplen(pcap_t *p, int snaplen)
{
if (pcap_check_activated(p))
return PCAP_ERROR_ACTIVATED;
p->snapshot = snaplen;
return 0;
}
int
pcap_set_promisc(pcap_t *p, int promisc)
{
if (pcap_check_activated(p))
return PCAP_ERROR_ACTIVATED;
p->opt.promisc = promisc;
return 0;
}
int
pcap_set_rfmon(pcap_t *p, int rfmon)
{
if (pcap_check_activated(p))
return PCAP_ERROR_ACTIVATED;
p->opt.rfmon = rfmon;
return 0;
}
int
pcap_set_timeout(pcap_t *p, int timeout_ms)
{
if (pcap_check_activated(p))
return PCAP_ERROR_ACTIVATED;
p->md.timeout = timeout_ms;
return 0;
}
int
pcap_set_buffer_size(pcap_t *p, int buffer_size)
{
if (pcap_check_activated(p))
return PCAP_ERROR_ACTIVATED;
p->opt.buffer_size = buffer_size;
return 0;
}
int
pcap_activate(pcap_t *p)
{
int status;
status = p->activate_op(p);
if (status >= 0)
p->activated = 1;
return (status);
}
pcap_t *
pcap_open_live(const char *source, int snaplen, int promisc, int to_ms, char *errbuf)
{
pcap_t *p;
int status;
p = pcap_create(source, errbuf);
if (p == NULL)
return (NULL);
status = pcap_set_snaplen(p, snaplen);
if (status < 0)
goto fail;
status = pcap_set_promisc(p, promisc);
if (status < 0)
goto fail;
status = pcap_set_timeout(p, to_ms);
if (status < 0)
goto fail;
/*
* Mark this as opened with pcap_open_live(), so that, for
* example, we show the full list of DLT_ values, rather
* than just the ones that are compatible with capturing
* when not in monitor mode. That allows existing applications
* to work the way they used to work, but allows new applications
* that know about the new open API to, for example, find out the
* DLT_ values that they can select without changing whether
* the adapter is in monitor mode or not.
*/
p->oldstyle = 1;
status = pcap_activate(p);
if (status < 0)
goto fail;
return (p);
fail:
if (status == PCAP_ERROR || status == PCAP_ERROR_NO_SUCH_DEVICE ||
status == PCAP_ERROR_PERM_DENIED)
strlcpy(errbuf, p->errbuf, PCAP_ERRBUF_SIZE);
else
snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", source,
pcap_statustostr(status));
pcap_close(p);
return (NULL);
}
int
pcap_dispatch(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
{
return p->read_op(p, cnt, callback, user);
}
@ -221,6 +416,12 @@ pcap_datalink(pcap_t *p)
return (p->linktype);
}
int
pcap_datalink_ext(pcap_t *p)
{
return (p->linktype_ext);
}
int
pcap_list_datalinks(pcap_t *p, int **dlt_buffer)
{
@ -252,6 +453,23 @@ pcap_list_datalinks(pcap_t *p, int **dlt_buffer)
}
}
/*
* In Windows, you might have a library built with one version of the
* C runtime library and an application built with another version of
* the C runtime library, which means that the library might use one
* version of malloc() and free() and the application might use another
* version of malloc() and free(). If so, that means something
* allocated by the library cannot be freed by the application, so we
* need to have a pcap_free_datalinks() routine to free up the list
* allocated by pcap_list_datalinks(), even though it's just a wrapper
* around free().
*/
void
pcap_free_datalinks(int *dlt_list)
{
free(dlt_list);
}
int
pcap_set_datalink(pcap_t *p, int dlt)
{
@ -327,7 +545,7 @@ static struct dlt_choice dlt_choices[] = {
DLT_CHOICE(DLT_NULL, "BSD loopback"),
DLT_CHOICE(DLT_EN10MB, "Ethernet"),
DLT_CHOICE(DLT_IEEE802, "Token ring"),
DLT_CHOICE(DLT_ARCNET, "ARCNET"),
DLT_CHOICE(DLT_ARCNET, "BSD ARCNET"),
DLT_CHOICE(DLT_SLIP, "SLIP"),
DLT_CHOICE(DLT_PPP, "PPP"),
DLT_CHOICE(DLT_FDDI, "FDDI"),
@ -338,6 +556,7 @@ static struct dlt_choice dlt_choices[] = {
DLT_CHOICE(DLT_ATM_CLIP, "Linux Classical IP-over-ATM"),
DLT_CHOICE(DLT_PPP_SERIAL, "PPP over serial"),
DLT_CHOICE(DLT_PPP_ETHER, "PPPoE"),
DLT_CHOICE(DLT_SYMANTEC_FIREWALL, "Symantec Firewall"),
DLT_CHOICE(DLT_C_HDLC, "Cisco HDLC"),
DLT_CHOICE(DLT_IEEE802_11, "802.11"),
DLT_CHOICE(DLT_FRELAY, "Frame Relay"),
@ -349,17 +568,25 @@ static struct dlt_choice dlt_choices[] = {
DLT_CHOICE(DLT_PRISM_HEADER, "802.11 plus Prism header"),
DLT_CHOICE(DLT_IP_OVER_FC, "RFC 2625 IP-over-Fibre Channel"),
DLT_CHOICE(DLT_SUNATM, "Sun raw ATM"),
DLT_CHOICE(DLT_IEEE802_11_RADIO, "802.11 plus BSD radio information header"),
DLT_CHOICE(DLT_APPLE_IP_OVER_IEEE1394, "Apple IP-over-IEEE 1394"),
DLT_CHOICE(DLT_IEEE802_11_RADIO, "802.11 plus radiotap header"),
DLT_CHOICE(DLT_ARCNET_LINUX, "Linux ARCNET"),
DLT_CHOICE(DLT_JUNIPER_MLPPP, "Juniper Multi-Link PPP"),
DLT_CHOICE(DLT_JUNIPER_MLFR, "Juniper Multi-Link Frame Relay"),
DLT_CHOICE(DLT_JUNIPER_ES, "Juniper Encryption Services PIC"),
DLT_CHOICE(DLT_JUNIPER_GGSN, "Juniper GGSN PIC"),
DLT_CHOICE(DLT_JUNIPER_MFR, "Juniper FRF.16 Frame Relay"),
DLT_CHOICE(DLT_JUNIPER_ATM2, "Juniper ATM2 PIC"),
DLT_CHOICE(DLT_JUNIPER_SERVICES, "Juniper Advanced Services PIC"),
DLT_CHOICE(DLT_JUNIPER_ATM1, "Juniper ATM1 PIC"),
DLT_CHOICE(DLT_APPLE_IP_OVER_IEEE1394, "Apple IP-over-IEEE 1394"),
DLT_CHOICE(DLT_MTP2_WITH_PHDR, "SS7 MTP2 with Pseudo-header"),
DLT_CHOICE(DLT_MTP2, "SS7 MTP2"),
DLT_CHOICE(DLT_MTP3, "SS7 MTP3"),
DLT_CHOICE(DLT_SCCP, "SS7 SCCP"),
DLT_CHOICE(DLT_DOCSIS, "DOCSIS"),
DLT_CHOICE(DLT_LINUX_IRDA, "Linux IrDA"),
DLT_CHOICE(DLT_LINUX_LAPD, "Linux vISDN LAPD"),
DLT_CHOICE(DLT_IEEE802_11_RADIO_AVS, "802.11 plus AVS radio information header"),
DLT_CHOICE(DLT_SYMANTEC_FIREWALL, "Symantec Firewall"),
DLT_CHOICE(DLT_JUNIPER_ATM1, "Juniper ATM1 PIC"),
DLT_CHOICE(DLT_JUNIPER_ATM2, "Juniper ATM2 PIC"),
DLT_CHOICE(DLT_JUNIPER_MLPPP, "Juniper Multi-Link PPP"),
DLT_CHOICE(DLT_JUNIPER_MONITOR, "Juniper Passive Monitor PIC"),
DLT_CHOICE(DLT_PPP_PPPD, "PPP for pppd, with direction flag"),
DLT_CHOICE(DLT_JUNIPER_PPPOE, "Juniper PPPoE"),
DLT_CHOICE(DLT_JUNIPER_PPPOE_ATM, "Juniper PPPoE/ATM"),
@ -367,27 +594,35 @@ static struct dlt_choice dlt_choices[] = {
DLT_CHOICE(DLT_GPF_T, "GPF-T"),
DLT_CHOICE(DLT_GPF_F, "GPF-F"),
DLT_CHOICE(DLT_JUNIPER_PIC_PEER, "Juniper PIC Peer"),
DLT_CHOICE(DLT_JUNIPER_MLFR, "Juniper Multi-Link Frame Relay"),
DLT_CHOICE(DLT_ERF_ETH, "Ethernet with Endace ERF header"),
DLT_CHOICE(DLT_ERF_POS, "Packet-over-SONET with Endace ERF header"),
DLT_CHOICE(DLT_JUNIPER_GGSN, "Juniper GGSN PIC"),
DLT_CHOICE(DLT_JUNIPER_ES, "Juniper Encryption Services PIC"),
DLT_CHOICE(DLT_JUNIPER_MONITOR, "Juniper Passive Monitor PIC"),
DLT_CHOICE(DLT_JUNIPER_SERVICES, "Juniper Advanced Services PIC"),
DLT_CHOICE(DLT_JUNIPER_MFR, "Juniper FRF.16 Frame Relay"),
DLT_CHOICE(DLT_LINUX_LAPD, "Linux vISDN LAPD"),
DLT_CHOICE(DLT_JUNIPER_ETHER, "Juniper Ethernet"),
DLT_CHOICE(DLT_JUNIPER_PPP, "Juniper PPP"),
DLT_CHOICE(DLT_JUNIPER_FRELAY, "Juniper Frame Relay"),
DLT_CHOICE(DLT_JUNIPER_CHDLC, "Juniper C-HDLC"),
DLT_CHOICE(DLT_MFR, "FRF.16 Frame Relay"),
DLT_CHOICE(DLT_JUNIPER_VP, "Juniper Voice PIC"),
DLT_CHOICE(DLT_MTP2, "SS7 MTP2"),
DLT_CHOICE(DLT_A429, "Arinc 429"),
DLT_CHOICE(DLT_A653_ICM, "Arinc 653 Interpartition Communication"),
DLT_CHOICE(DLT_USB, "USB"),
DLT_CHOICE(DLT_BLUETOOTH_HCI_H4, "Bluetooth HCI UART transport layer"),
DLT_CHOICE(DLT_IEEE802_16_MAC_CPS, "IEEE 802.16 MAC Common Part Sublayer"),
DLT_CHOICE(DLT_USB_LINUX, "USB with Linux header"),
DLT_CHOICE(DLT_CAN20B, "Controller Area Network (CAN) v. 2.0B"),
DLT_CHOICE(DLT_MTP2_WITH_PHDR, "SS7 MTP2 with Pseudo-header"),
DLT_CHOICE(DLT_IEEE802_15_4_LINUX, "IEEE 802.15.4 with Linux padding"),
DLT_CHOICE(DLT_PPI, "Per-Packet Information"),
DLT_CHOICE(DLT_IEEE802_16_MAC_CPS_RADIO, "IEEE 802.16 MAC Common Part Sublayer plus radiotap header"),
DLT_CHOICE(DLT_JUNIPER_ISM, "Juniper Integrated Service Module"),
DLT_CHOICE(DLT_IEEE802_15_4, "IEEE 802.15.4"),
DLT_CHOICE(DLT_SITA, "SITA pseudo-header"),
DLT_CHOICE(DLT_ERF, "Endace ERF header"),
DLT_CHOICE(DLT_RAIF1, "Ethernet with u10 Networks pseudo-header"),
DLT_CHOICE(DLT_IPMB, "IPMB"),
DLT_CHOICE(DLT_JUNIPER_ST, "Juniper Secure Tunnel"),
DLT_CHOICE(DLT_BLUETOOTH_HCI_H4_WITH_PHDR, "Bluetooth HCI UART transport layer plus pseudo-header"),
DLT_CHOICE(DLT_AX25_KISS, "AX.25 with KISS header"),
DLT_CHOICE(DLT_IEEE802_15_4_NONASK_PHY, "IEEE 802.15.4 with non-ASK PHY data"),
DLT_CHOICE_SENTINEL
};
@ -678,6 +913,53 @@ pcap_win32strerror(void)
}
#endif
/*
* Generate error strings for PCAP_ERROR_ and PCAP_WARNING_ values.
*/
const char *
pcap_statustostr(int errnum)
{
static char ebuf[15+10+1];
switch (errnum) {
case PCAP_WARNING:
return("Generic warning");
case PCAP_WARNING_PROMISC_NOTSUP:
return ("That device doesn't support promiscuous mode");
case PCAP_ERROR:
return("Generic error");
case PCAP_ERROR_BREAK:
return("Loop terminated by pcap_breakloop");
case PCAP_ERROR_NOT_ACTIVATED:
return("The pcap_t has not been activated");
case PCAP_ERROR_ACTIVATED:
return ("The setting can't be changed after the pcap_t is activated");
case PCAP_ERROR_NO_SUCH_DEVICE:
return ("No such device exists");
case PCAP_ERROR_RFMON_NOTSUP:
return ("That device doesn't support monitor mode");
case PCAP_ERROR_NOT_RFMON:
return ("That operation is supported only in monitor mode");
case PCAP_ERROR_PERM_DENIED:
return ("You don't have permission to capture on that device");
case PCAP_ERROR_IFACE_NOT_UP:
return ("That device is not up");
}
(void)snprintf(ebuf, sizeof ebuf, "Unknown error: %d", errnum);
return(ebuf);
}
/*
* Not all systems have strerror().
*/
@ -689,7 +971,7 @@ pcap_strerror(int errnum)
#else
extern int sys_nerr;
extern const char *const sys_errlist[];
static char ebuf[20];
static char ebuf[15+10+1];
if ((unsigned int)errnum < sys_nerr)
return ((char *)sys_errlist[errnum]);
@ -735,19 +1017,162 @@ pcap_stats_dead(pcap_t *p, struct pcap_stat *ps _U_)
return (-1);
}
void
pcap_close_common(pcap_t *p)
#ifdef WIN32
int
pcap_setbuff(pcap_t *p, int dim)
{
if (p->buffer != NULL)
return p->setbuff_op(p, dim);
}
static int
pcap_setbuff_dead(pcap_t *p, int dim)
{
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"The kernel buffer size cannot be set on a pcap_open_dead pcap_t");
return (-1);
}
int
pcap_setmode(pcap_t *p, int mode)
{
return p->setmode_op(p, mode);
}
static int
pcap_setmode_dead(pcap_t *p, int mode)
{
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"impossible to set mode on a pcap_open_dead pcap_t");
return (-1);
}
int
pcap_setmintocopy(pcap_t *p, int size)
{
return p->setmintocopy_op(p, size);
}
static int
pcap_setmintocopy_dead(pcap_t *p, int size)
{
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"The mintocopy parameter cannot be set on a pcap_open_dead pcap_t");
return (-1);
}
#endif
/*
* On some platforms, we need to clean up promiscuous or monitor mode
* when we close a device - and we want that to happen even if the
* application just exits without explicitl closing devices.
* On those platforms, we need to register a "close all the pcaps"
* routine to be called when we exit, and need to maintain a list of
* pcaps that need to be closed to clean up modes.
*
* XXX - not thread-safe.
*/
/*
* List of pcaps on which we've done something that needs to be
* cleaned up.
* If there are any such pcaps, we arrange to call "pcap_close_all()"
* when we exit, and have it close all of them.
*/
static struct pcap *pcaps_to_close;
/*
* TRUE if we've already called "atexit()" to cause "pcap_close_all()" to
* be called on exit.
*/
static int did_atexit;
static void
pcap_close_all(void)
{
struct pcap *handle;
while ((handle = pcaps_to_close) != NULL)
pcap_close(handle);
}
int
pcap_do_addexit(pcap_t *p)
{
/*
* If we haven't already done so, arrange to have
* "pcap_close_all()" called when we exit.
*/
if (!did_atexit) {
if (atexit(pcap_close_all) == -1) {
/*
* "atexit()" failed; let our caller know.
*/
strncpy(p->errbuf, "atexit failed",
PCAP_ERRBUF_SIZE);
return (0);
}
did_atexit = 1;
}
return (1);
}
void
pcap_add_to_pcaps_to_close(pcap_t *p)
{
p->md.next = pcaps_to_close;
pcaps_to_close = p;
}
void
pcap_remove_from_pcaps_to_close(pcap_t *p)
{
pcap_t *pc, *prevpc;
for (pc = pcaps_to_close, prevpc = NULL; pc != NULL;
prevpc = pc, pc = pc->md.next) {
if (pc == p) {
/*
* Found it. Remove it from the list.
*/
if (prevpc == NULL) {
/*
* It was at the head of the list.
*/
pcaps_to_close = pc->md.next;
} else {
/*
* It was in the middle of the list.
*/
prevpc->md.next = pc->md.next;
}
break;
}
}
}
void
pcap_cleanup_live_common(pcap_t *p)
{
if (p->buffer != NULL) {
free(p->buffer);
p->buffer = NULL;
}
if (p->dlt_list != NULL) {
free(p->dlt_list);
p->dlt_list = NULL;
p->dlt_count = 0;
}
pcap_freecode(&p->fcode);
#if !defined(WIN32) && !defined(MSDOS)
if (p->fd >= 0)
if (p->fd >= 0) {
close(p->fd);
p->fd = -1;
}
#endif
}
static void
pcap_close_dead(pcap_t *p _U_)
pcap_cleanup_dead(pcap_t *p _U_)
{
/* Nothing to do. */
}
@ -764,7 +1189,13 @@ pcap_open_dead(int linktype, int snaplen)
p->snapshot = snaplen;
p->linktype = linktype;
p->stats_op = pcap_stats_dead;
p->close_op = pcap_close_dead;
#ifdef WIN32
p->setbuff_op = pcap_setbuff_dead;
p->setmode_op = pcap_setmode_dead;
p->setmintocopy_op = pcap_setmintocopy_dead;
#endif
p->cleanup_op = pcap_cleanup_dead;
p->activated = 1;
return p;
}
@ -795,13 +1226,30 @@ pcap_inject(pcap_t *p, const void *buf, size_t size)
void
pcap_close(pcap_t *p)
{
p->close_op(p);
if (p->dlt_list != NULL)
free(p->dlt_list);
pcap_freecode(&p->fcode);
if (p->opt.source != NULL)
free(p->opt.source);
p->cleanup_op(p);
free(p);
}
/*
* Given a BPF program, a pcap_pkthdr structure for a packet, and the raw
* data for the packet, check whether the packet passes the filter.
* Returns the return value of the filter program, which will be zero if
* the packet doesn't pass and non-zero if the packet does pass.
*/
int
pcap_offline_filter(struct bpf_program *fp, const struct pcap_pkthdr *h,
const u_char *pkt)
{
struct bpf_insn *fcode = fp->bf_insns;
if (fcode != NULL)
return (bpf_filter(fcode, pkt, h->len, h->caplen));
else
return (0);
}
/*
* We make the version string static, and return a pointer to it, rather
* than exporting the version string directly. On at least some UNIXes,
@ -817,7 +1265,7 @@ pcap_close(pcap_t *p)
#ifdef HAVE_VERSION_H
#include "version.h"
#else
static const char pcap_version_string[] = "libpcap version 0.9.8";
static const char pcap_version_string[] = "libpcap version 0.9[.x]";
#endif
#ifdef WIN32

295
pcap.h
View File

@ -1,4 +1,3 @@
/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */
/*
* Copyright (c) 1993, 1994, 1995, 1996, 1997
* The Regents of the University of California. All rights reserved.
@ -31,294 +30,16 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#) $Header: /tcpdump/master/libpcap/pcap.h,v 1.52.2.7 2007/06/11 09:52:05 guy Exp $ (LBL)
* @(#) $Header: /tcpdump/master/libpcap/pcap.h,v 1.59 2006/10/04 18:09:22 guy Exp $ (LBL)
*/
#ifndef lib_pcap_h
#define lib_pcap_h
#if defined(WIN32)
#include <pcap-stdinc.h>
#elif defined(MSDOS)
#include <sys/types.h>
#include <sys/socket.h> /* u_int, u_char etc. */
#else /* UN*X */
#include <sys/types.h>
#include <sys/time.h>
#endif /* WIN32/MSDOS/UN*X */
#ifndef PCAP_DONT_INCLUDE_PCAP_BPF_H
#include <pcap-bpf.h>
#endif
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
#define PCAP_VERSION_MAJOR 2
#define PCAP_VERSION_MINOR 4
#define PCAP_ERRBUF_SIZE 256
/*
* Compatibility for systems that have a bpf.h that
* predates the bpf typedefs for 64-bit support.
*/
#if BPF_RELEASE - 0 < 199406
typedef int bpf_int32;
typedef u_int bpf_u_int32;
#endif
typedef struct pcap pcap_t;
typedef struct pcap_dumper pcap_dumper_t;
typedef struct pcap_if pcap_if_t;
typedef struct pcap_addr pcap_addr_t;
/*
* The first record in the file contains saved values for some
* of the flags used in the printout phases of tcpdump.
* Many fields here are 32 bit ints so compilers won't insert unwanted
* padding; these files need to be interchangeable across architectures.
* For backwards compatibility.
*
* Do not change the layout of this structure, in any way (this includes
* changes that only affect the length of fields in this structure).
*
* Also, do not change the interpretation of any of the members of this
* structure, in any way (this includes using values other than
* LINKTYPE_ values, as defined in "savefile.c", in the "linktype"
* field).
*
* Instead:
*
* introduce a new structure for the new format, if the layout
* of the structure changed;
*
* send mail to "tcpdump-workers@tcpdump.org", requesting a new
* magic number for your new capture file format, and, when
* you get the new magic number, put it in "savefile.c";
*
* use that magic number for save files with the changed file
* header;
*
* make the code in "savefile.c" capable of reading files with
* the old file header as well as files with the new file header
* (using the magic number to determine the header format).
*
* Then supply the changes to "patches@tcpdump.org", so that future
* versions of libpcap and programs that use it (such as tcpdump) will
* be able to read your new capture file format.
* Note to OS vendors: do NOT get rid of this file! Many applications
* expect to be able to include <pcap.h>, and at least some of them
* go through contortions in their configure scripts to try to detect
* OSes that have "helpfully" moved pcap.h to <pcap/pcap.h> without
* leaving behind a <pcap.h> file.
*/
struct pcap_file_header {
bpf_u_int32 magic;
u_short version_major;
u_short version_minor;
bpf_int32 thiszone; /* gmt to local correction */
bpf_u_int32 sigfigs; /* accuracy of timestamps */
bpf_u_int32 snaplen; /* max length saved portion of each pkt */
bpf_u_int32 linktype; /* data link type (LINKTYPE_*) */
};
typedef enum {
PCAP_D_INOUT = 0,
PCAP_D_IN,
PCAP_D_OUT
} pcap_direction_t;
/*
* Generic per-packet information, as supplied by libpcap.
*
* The time stamp can and should be a "struct timeval", regardless of
* whether your system supports 32-bit tv_sec in "struct timeval",
* 64-bit tv_sec in "struct timeval", or both if it supports both 32-bit
* and 64-bit applications. The on-disk format of savefiles uses 32-bit
* tv_sec (and tv_usec); this structure is irrelevant to that. 32-bit
* and 64-bit versions of libpcap, even if they're on the same platform,
* should supply the appropriate version of "struct timeval", even if
* that's not what the underlying packet capture mechanism supplies.
*/
struct pcap_pkthdr {
struct timeval ts; /* time stamp */
bpf_u_int32 caplen; /* length of portion present */
bpf_u_int32 len; /* length this packet (off wire) */
};
/*
* As returned by the pcap_stats()
*/
struct pcap_stat {
u_int ps_recv; /* number of packets received */
u_int ps_drop; /* number of packets dropped */
u_int ps_ifdrop; /* drops by interface XXX not yet supported */
#ifdef WIN32
u_int bs_capt; /* number of packets that reach the application */
#endif /* WIN32 */
};
#ifdef MSDOS
/*
* As returned by the pcap_stats_ex()
*/
struct pcap_stat_ex {
u_long rx_packets; /* total packets received */
u_long tx_packets; /* total packets transmitted */
u_long rx_bytes; /* total bytes received */
u_long tx_bytes; /* total bytes transmitted */
u_long rx_errors; /* bad packets received */
u_long tx_errors; /* packet transmit problems */
u_long rx_dropped; /* no space in Rx buffers */
u_long tx_dropped; /* no space available for Tx */
u_long multicast; /* multicast packets received */
u_long collisions;
/* detailed rx_errors: */
u_long rx_length_errors;
u_long rx_over_errors; /* receiver ring buff overflow */
u_long rx_crc_errors; /* recv'd pkt with crc error */
u_long rx_frame_errors; /* recv'd frame alignment error */
u_long rx_fifo_errors; /* recv'r fifo overrun */
u_long rx_missed_errors; /* recv'r missed packet */
/* detailed tx_errors */
u_long tx_aborted_errors;
u_long tx_carrier_errors;
u_long tx_fifo_errors;
u_long tx_heartbeat_errors;
u_long tx_window_errors;
};
#endif
/*
* Item in a list of interfaces.
*/
struct pcap_if {
struct pcap_if *next;
char *name; /* name to hand to "pcap_open_live()" */
char *description; /* textual description of interface, or NULL */
struct pcap_addr *addresses;
bpf_u_int32 flags; /* PCAP_IF_ interface flags */
};
#define PCAP_IF_LOOPBACK 0x00000001 /* interface is loopback */
/*
* Representation of an interface address.
*/
struct pcap_addr {
struct pcap_addr *next;
struct sockaddr *addr; /* address */
struct sockaddr *netmask; /* netmask for that address */
struct sockaddr *broadaddr; /* broadcast address for that address */
struct sockaddr *dstaddr; /* P2P destination address for that address */
};
typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *,
const u_char *);
char *pcap_lookupdev(char *);
int pcap_lookupnet(const char *, bpf_u_int32 *, bpf_u_int32 *, char *);
pcap_t *pcap_open_live(const char *, int, int, int, char *);
pcap_t *pcap_open_dead(int, int);
pcap_t *pcap_open_offline(const char *, char *);
pcap_t *pcap_fopen_offline(FILE *, char *);
void pcap_close(pcap_t *);
int pcap_loop(pcap_t *, int, pcap_handler, u_char *);
int pcap_dispatch(pcap_t *, int, pcap_handler, u_char *);
const u_char*
pcap_next(pcap_t *, struct pcap_pkthdr *);
int pcap_next_ex(pcap_t *, struct pcap_pkthdr **, const u_char **);
void pcap_breakloop(pcap_t *);
int pcap_stats(pcap_t *, struct pcap_stat *);
int pcap_setfilter(pcap_t *, struct bpf_program *);
int pcap_setdirection(pcap_t *, pcap_direction_t);
int pcap_getnonblock(pcap_t *, char *);
int pcap_setnonblock(pcap_t *, int, char *);
void pcap_perror(pcap_t *, char *);
int pcap_inject(pcap_t *, const void *, size_t);
int pcap_sendpacket(pcap_t *, const u_char *, int);
const char *pcap_strerror(int);
char *pcap_geterr(pcap_t *);
int pcap_compile(pcap_t *, struct bpf_program *, const char *, int,
bpf_u_int32);
int pcap_compile_nopcap(int, int, struct bpf_program *,
const char *, int, bpf_u_int32);
void pcap_freecode(struct bpf_program *);
int pcap_datalink(pcap_t *);
int pcap_list_datalinks(pcap_t *, int **);
int pcap_set_datalink(pcap_t *, int);
int pcap_datalink_name_to_val(const char *);
const char *pcap_datalink_val_to_name(int);
const char *pcap_datalink_val_to_description(int);
int pcap_snapshot(pcap_t *);
int pcap_is_swapped(pcap_t *);
int pcap_major_version(pcap_t *);
int pcap_minor_version(pcap_t *);
/* XXX */
FILE *pcap_file(pcap_t *);
int pcap_fileno(pcap_t *);
pcap_dumper_t *pcap_dump_open(pcap_t *, const char *);
pcap_dumper_t *pcap_dump_fopen(pcap_t *, FILE *fp);
FILE *pcap_dump_file(pcap_dumper_t *);
long pcap_dump_ftell(pcap_dumper_t *);
int pcap_dump_flush(pcap_dumper_t *);
void pcap_dump_close(pcap_dumper_t *);
void pcap_dump(u_char *, const struct pcap_pkthdr *, const u_char *);
int pcap_findalldevs(pcap_if_t **, char *);
void pcap_freealldevs(pcap_if_t *);
const char *pcap_lib_version(void);
/* XXX this guy lives in the bpf tree */
u_int bpf_filter(struct bpf_insn *, u_char *, u_int, u_int);
int bpf_validate(struct bpf_insn *f, int len);
char *bpf_image(struct bpf_insn *, int);
void bpf_dump(struct bpf_program *, int);
#if defined(WIN32)
/*
* Win32 definitions
*/
int pcap_setbuff(pcap_t *p, int dim);
int pcap_setmode(pcap_t *p, int mode);
int pcap_setmintocopy(pcap_t *p, int size);
#ifdef WPCAP
/* Include file with the wpcap-specific extensions */
#include <Win32-Extensions.h>
#endif /* WPCAP */
#define MODE_CAPT 0
#define MODE_STAT 1
#define MODE_MON 2
#elif defined(MSDOS)
/*
* MS-DOS definitions
*/
int pcap_stats_ex (pcap_t *, struct pcap_stat_ex *);
void pcap_set_wait (pcap_t *p, void (*yield)(void), int wait);
u_long pcap_mac_packets (void);
#else /* UN*X */
/*
* UN*X definitions
*/
int pcap_get_selectable_fd(pcap_t *);
#endif /* WIN32/MSDOS/UN*X */
#ifdef __cplusplus
}
#endif
#endif
#include <pcap/pcap.h>

48
pcap/bluetooth.h Normal file
View File

@ -0,0 +1,48 @@
/*
* Copyright (c) 2006 Paolo Abeni (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. 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 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.
*
* bluetooth data struct
* By Paolo Abeni <paolo.abeni@email.it>
*
* @(#) $Header: /tcpdump/master/libpcap/pcap/bluetooth.h,v 1.1 2007/09/22 02:10:17 guy Exp $
*/
#ifndef _PCAP_BLUETOOTH_STRUCTS_H__
#define _PCAP_BLUETOOTH_STRUCTS_H__
/*
* Header prepended libpcap to each bluetooth h:4 frame.
* fields are in network byte order
*/
typedef struct _pcap_bluetooth_h4_header {
u_int32_t direction; /* if first bit is set direction is incoming */
} pcap_bluetooth_h4_header;
#endif

934
pcap/bpf.h Normal file
View File

@ -0,0 +1,934 @@
/*-
* Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
* The Regents of the University of California. All rights reserved.
*
* This code is derived from the Stanford/CMU enet packet filter,
* (net/enet.c) distributed as part of 4.3BSD, and code contributed
* to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
* Berkeley Laboratory.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)bpf.h 7.1 (Berkeley) 5/7/91
*
* @(#) $Header: /tcpdump/master/libpcap/pcap/bpf.h,v 1.19.2.8 2008-09-22 20:16:01 guy Exp $ (LBL)
*/
/*
* This is libpcap's cut-down version of bpf.h; it includes only
* the stuff needed for the code generator and the userland BPF
* interpreter, and the libpcap APIs for setting filters, etc..
*
* "pcap-bpf.c" will include the native OS version, as it deals with
* the OS's BPF implementation.
*
* XXX - should this all just be moved to "pcap.h"?
*/
#ifndef BPF_MAJOR_VERSION
#ifdef __cplusplus
extern "C" {
#endif
/* BSD style release date */
#define BPF_RELEASE 199606
#ifdef MSDOS /* must be 32-bit */
typedef long bpf_int32;
typedef unsigned long bpf_u_int32;
#else
typedef int bpf_int32;
typedef u_int bpf_u_int32;
#endif
/*
* Alignment macros. BPF_WORDALIGN rounds up to the next
* even multiple of BPF_ALIGNMENT.
*/
#ifndef __NetBSD__
#define BPF_ALIGNMENT sizeof(bpf_int32)
#else
#define BPF_ALIGNMENT sizeof(long)
#endif
#define BPF_WORDALIGN(x) (((x)+(BPF_ALIGNMENT-1))&~(BPF_ALIGNMENT-1))
#define BPF_MAXBUFSIZE 0x8000
#define BPF_MINBUFSIZE 32
/*
* Structure for "pcap_compile()", "pcap_setfilter()", etc..
*/
struct bpf_program {
u_int bf_len;
struct bpf_insn *bf_insns;
};
/*
* Struct return by BIOCVERSION. This represents the version number of
* the filter language described by the instruction encodings below.
* bpf understands a program iff kernel_major == filter_major &&
* kernel_minor >= filter_minor, that is, if the value returned by the
* running kernel has the same major number and a minor number equal
* equal to or less than the filter being downloaded. Otherwise, the
* results are undefined, meaning an error may be returned or packets
* may be accepted haphazardly.
* It has nothing to do with the source code version.
*/
struct bpf_version {
u_short bv_major;
u_short bv_minor;
};
/* Current version number of filter architecture. */
#define BPF_MAJOR_VERSION 1
#define BPF_MINOR_VERSION 1
/*
* Data-link level type codes.
*
* Do *NOT* add new values to this list without asking
* "tcpdump-workers@lists.tcpdump.org" for a value. Otherwise, you run
* the risk of using a value that's already being used for some other
* purpose, and of having tools that read libpcap-format captures not
* being able to handle captures with your new DLT_ value, with no hope
* that they will ever be changed to do so (as that would destroy their
* ability to read captures using that value for that other purpose).
*/
/*
* These are the types that are the same on all platforms, and that
* have been defined by <net/bpf.h> for ages.
*/
#define DLT_NULL 0 /* BSD loopback encapsulation */
#define DLT_EN10MB 1 /* Ethernet (10Mb) */
#define DLT_EN3MB 2 /* Experimental Ethernet (3Mb) */
#define DLT_AX25 3 /* Amateur Radio AX.25 */
#define DLT_PRONET 4 /* Proteon ProNET Token Ring */
#define DLT_CHAOS 5 /* Chaos */
#define DLT_IEEE802 6 /* 802.5 Token Ring */
#define DLT_ARCNET 7 /* ARCNET, with BSD-style header */
#define DLT_SLIP 8 /* Serial Line IP */
#define DLT_PPP 9 /* Point-to-point Protocol */
#define DLT_FDDI 10 /* FDDI */
/*
* These are types that are different on some platforms, and that
* have been defined by <net/bpf.h> for ages. We use #ifdefs to
* detect the BSDs that define them differently from the traditional
* libpcap <net/bpf.h>
*
* XXX - DLT_ATM_RFC1483 is 13 in BSD/OS, and DLT_RAW is 14 in BSD/OS,
* but I don't know what the right #define is for BSD/OS.
*/
#define DLT_ATM_RFC1483 11 /* LLC-encapsulated ATM */
#ifdef __OpenBSD__
#define DLT_RAW 14 /* raw IP */
#else
#define DLT_RAW 12 /* raw IP */
#endif
/*
* Given that the only OS that currently generates BSD/OS SLIP or PPP
* is, well, BSD/OS, arguably everybody should have chosen its values
* for DLT_SLIP_BSDOS and DLT_PPP_BSDOS, which are 15 and 16, but they
* didn't. So it goes.
*/
#if defined(__NetBSD__) || defined(__FreeBSD__)
#ifndef DLT_SLIP_BSDOS
#define DLT_SLIP_BSDOS 13 /* BSD/OS Serial Line IP */
#define DLT_PPP_BSDOS 14 /* BSD/OS Point-to-point Protocol */
#endif
#else
#define DLT_SLIP_BSDOS 15 /* BSD/OS Serial Line IP */
#define DLT_PPP_BSDOS 16 /* BSD/OS Point-to-point Protocol */
#endif
/*
* 17 is used for DLT_OLD_PFLOG in OpenBSD;
* OBSOLETE: DLT_PFLOG is 117 in OpenBSD now as well. See below.
* 18 is used for DLT_PFSYNC in OpenBSD; don't use it for anything else.
*/
#define DLT_ATM_CLIP 19 /* Linux Classical-IP over ATM */
/*
* Apparently Redback uses this for its SmartEdge 400/800. I hope
* nobody else decided to use it, too.
*/
#define DLT_REDBACK_SMARTEDGE 32
/*
* These values are defined by NetBSD; other platforms should refrain from
* using them for other purposes, so that NetBSD savefiles with link
* types of 50 or 51 can be read as this type on all platforms.
*/
#define DLT_PPP_SERIAL 50 /* PPP over serial with HDLC encapsulation */
#define DLT_PPP_ETHER 51 /* PPP over Ethernet */
/*
* The Axent Raptor firewall - now the Symantec Enterprise Firewall - uses
* a link-layer type of 99 for the tcpdump it supplies. The link-layer
* header has 6 bytes of unknown data, something that appears to be an
* Ethernet type, and 36 bytes that appear to be 0 in at least one capture
* I've seen.
*/
#define DLT_SYMANTEC_FIREWALL 99
/*
* Values between 100 and 103 are used in capture file headers as
* link-layer types corresponding to DLT_ types that differ
* between platforms; don't use those values for new DLT_ new types.
*/
/*
* This value was defined by libpcap 0.5; platforms that have defined
* it with a different value should define it here with that value -
* a link type of 104 in a save file will be mapped to DLT_C_HDLC,
* whatever value that happens to be, so programs will correctly
* handle files with that link type regardless of the value of
* DLT_C_HDLC.
*
* The name DLT_C_HDLC was used by BSD/OS; we use that name for source
* compatibility with programs written for BSD/OS.
*
* libpcap 0.5 defined it as DLT_CHDLC; we define DLT_CHDLC as well,
* for source compatibility with programs written for libpcap 0.5.
*/
#define DLT_C_HDLC 104 /* Cisco HDLC */
#define DLT_CHDLC DLT_C_HDLC
#define DLT_IEEE802_11 105 /* IEEE 802.11 wireless */
/*
* 106 is reserved for Linux Classical IP over ATM; it's like DLT_RAW,
* except when it isn't. (I.e., sometimes it's just raw IP, and
* sometimes it isn't.) We currently handle it as DLT_LINUX_SLL,
* so that we don't have to worry about the link-layer header.)
*/
/*
* Frame Relay; BSD/OS has a DLT_FR with a value of 11, but that collides
* with other values.
* DLT_FR and DLT_FRELAY packets start with the Q.922 Frame Relay header
* (DLCI, etc.).
*/
#define DLT_FRELAY 107
/*
* OpenBSD DLT_LOOP, for loopback devices; it's like DLT_NULL, except
* that the AF_ type in the link-layer header is in network byte order.
*
* DLT_LOOP is 12 in OpenBSD, but that's DLT_RAW in other OSes, so
* we don't use 12 for it in OSes other than OpenBSD.
*/
#ifdef __OpenBSD__
#define DLT_LOOP 12
#else
#define DLT_LOOP 108
#endif
/*
* Encapsulated packets for IPsec; DLT_ENC is 13 in OpenBSD, but that's
* DLT_SLIP_BSDOS in NetBSD, so we don't use 13 for it in OSes other
* than OpenBSD.
*/
#ifdef __OpenBSD__
#define DLT_ENC 13
#else
#define DLT_ENC 109
#endif
/*
* Values between 110 and 112 are reserved for use in capture file headers
* as link-layer types corresponding to DLT_ types that might differ
* between platforms; don't use those values for new DLT_ types
* other than the corresponding DLT_ types.
*/
/*
* This is for Linux cooked sockets.
*/
#define DLT_LINUX_SLL 113
/*
* Apple LocalTalk hardware.
*/
#define DLT_LTALK 114
/*
* Acorn Econet.
*/
#define DLT_ECONET 115
/*
* Reserved for use with OpenBSD ipfilter.
*/
#define DLT_IPFILTER 116
/*
* OpenBSD DLT_PFLOG; DLT_PFLOG is 17 in OpenBSD, but that's DLT_LANE8023
* in SuSE 6.3, so we can't use 17 for it in capture-file headers.
*
* XXX: is there a conflict with DLT_PFSYNC 18 as well?
*/
#ifdef __OpenBSD__
#define DLT_OLD_PFLOG 17
#define DLT_PFSYNC 18
#endif
#define DLT_PFLOG 117
/*
* Registered for Cisco-internal use.
*/
#define DLT_CISCO_IOS 118
/*
* For 802.11 cards using the Prism II chips, with a link-layer
* header including Prism monitor mode information plus an 802.11
* header.
*/
#define DLT_PRISM_HEADER 119
/*
* Reserved for Aironet 802.11 cards, with an Aironet link-layer header
* (see Doug Ambrisko's FreeBSD patches).
*/
#define DLT_AIRONET_HEADER 120
/*
* Reserved for Siemens HiPath HDLC.
*/
#define DLT_HHDLC 121
/*
* This is for RFC 2625 IP-over-Fibre Channel.
*
* This is not for use with raw Fibre Channel, where the link-layer
* header starts with a Fibre Channel frame header; it's for IP-over-FC,
* where the link-layer header starts with an RFC 2625 Network_Header
* field.
*/
#define DLT_IP_OVER_FC 122
/*
* This is for Full Frontal ATM on Solaris with SunATM, with a
* pseudo-header followed by an AALn PDU.
*
* There may be other forms of Full Frontal ATM on other OSes,
* with different pseudo-headers.
*
* If ATM software returns a pseudo-header with VPI/VCI information
* (and, ideally, packet type information, e.g. signalling, ILMI,
* LANE, LLC-multiplexed traffic, etc.), it should not use
* DLT_ATM_RFC1483, but should get a new DLT_ value, so tcpdump
* and the like don't have to infer the presence or absence of a
* pseudo-header and the form of the pseudo-header.
*/
#define DLT_SUNATM 123 /* Solaris+SunATM */
/*
* Reserved as per request from Kent Dahlgren <kent@praesum.com>
* for private use.
*/
#define DLT_RIO 124 /* RapidIO */
#define DLT_PCI_EXP 125 /* PCI Express */
#define DLT_AURORA 126 /* Xilinx Aurora link layer */
/*
* Header for 802.11 plus a number of bits of link-layer information
* including radio information, used by some recent BSD drivers as
* well as the madwifi Atheros driver for Linux.
*/
#define DLT_IEEE802_11_RADIO 127 /* 802.11 plus radiotap radio header */
/*
* Reserved for the TZSP encapsulation, as per request from
* Chris Waters <chris.waters@networkchemistry.com>
* TZSP is a generic encapsulation for any other link type,
* which includes a means to include meta-information
* with the packet, e.g. signal strength and channel
* for 802.11 packets.
*/
#define DLT_TZSP 128 /* Tazmen Sniffer Protocol */
/*
* BSD's ARCNET headers have the source host, destination host,
* and type at the beginning of the packet; that's what's handed
* up to userland via BPF.
*
* Linux's ARCNET headers, however, have a 2-byte offset field
* between the host IDs and the type; that's what's handed up
* to userland via PF_PACKET sockets.
*
* We therefore have to have separate DLT_ values for them.
*/
#define DLT_ARCNET_LINUX 129 /* ARCNET */
/*
* Juniper-private data link types, as per request from
* Hannes Gredler <hannes@juniper.net>. The DLT_s are used
* for passing on chassis-internal metainformation such as
* QOS profiles, etc..
*/
#define DLT_JUNIPER_MLPPP 130
#define DLT_JUNIPER_MLFR 131
#define DLT_JUNIPER_ES 132
#define DLT_JUNIPER_GGSN 133
#define DLT_JUNIPER_MFR 134
#define DLT_JUNIPER_ATM2 135
#define DLT_JUNIPER_SERVICES 136
#define DLT_JUNIPER_ATM1 137
/*
* Apple IP-over-IEEE 1394, as per a request from Dieter Siegmund
* <dieter@apple.com>. The header that's presented is an Ethernet-like
* header:
*
* #define FIREWIRE_EUI64_LEN 8
* struct firewire_header {
* u_char firewire_dhost[FIREWIRE_EUI64_LEN];
* u_char firewire_shost[FIREWIRE_EUI64_LEN];
* u_short firewire_type;
* };
*
* with "firewire_type" being an Ethernet type value, rather than,
* for example, raw GASP frames being handed up.
*/
#define DLT_APPLE_IP_OVER_IEEE1394 138
/*
* Various SS7 encapsulations, as per a request from Jeff Morriss
* <jeff.morriss[AT]ulticom.com> and subsequent discussions.
*/
#define DLT_MTP2_WITH_PHDR 139 /* pseudo-header with various info, followed by MTP2 */
#define DLT_MTP2 140 /* MTP2, without pseudo-header */
#define DLT_MTP3 141 /* MTP3, without pseudo-header or MTP2 */
#define DLT_SCCP 142 /* SCCP, without pseudo-header or MTP2 or MTP3 */
/*
* DOCSIS MAC frames.
*/
#define DLT_DOCSIS 143
/*
* Linux-IrDA packets. Protocol defined at http://www.irda.org.
* Those packets include IrLAP headers and above (IrLMP...), but
* don't include Phy framing (SOF/EOF/CRC & byte stuffing), because Phy
* framing can be handled by the hardware and depend on the bitrate.
* This is exactly the format you would get capturing on a Linux-IrDA
* interface (irdaX), but not on a raw serial port.
* Note the capture is done in "Linux-cooked" mode, so each packet include
* a fake packet header (struct sll_header). This is because IrDA packet
* decoding is dependant on the direction of the packet (incomming or
* outgoing).
* When/if other platform implement IrDA capture, we may revisit the
* issue and define a real DLT_IRDA...
* Jean II
*/
#define DLT_LINUX_IRDA 144
/*
* Reserved for IBM SP switch and IBM Next Federation switch.
*/
#define DLT_IBM_SP 145
#define DLT_IBM_SN 146
/*
* Reserved for private use. If you have some link-layer header type
* that you want to use within your organization, with the capture files
* using that link-layer header type not ever be sent outside your
* organization, you can use these values.
*
* No libpcap release will use these for any purpose, nor will any
* tcpdump release use them, either.
*
* Do *NOT* use these in capture files that you expect anybody not using
* your private versions of capture-file-reading tools to read; in
* particular, do *NOT* use them in products, otherwise you may find that
* people won't be able to use tcpdump, or snort, or Ethereal, or... to
* read capture files from your firewall/intrusion detection/traffic
* monitoring/etc. appliance, or whatever product uses that DLT_ value,
* and you may also find that the developers of those applications will
* not accept patches to let them read those files.
*
* Also, do not use them if somebody might send you a capture using them
* for *their* private type and tools using them for *your* private type
* would have to read them.
*
* Instead, ask "tcpdump-workers@lists.tcpdump.org" for a new DLT_ value,
* as per the comment above, and use the type you're given.
*/
#define DLT_USER0 147
#define DLT_USER1 148
#define DLT_USER2 149
#define DLT_USER3 150
#define DLT_USER4 151
#define DLT_USER5 152
#define DLT_USER6 153
#define DLT_USER7 154
#define DLT_USER8 155
#define DLT_USER9 156
#define DLT_USER10 157
#define DLT_USER11 158
#define DLT_USER12 159
#define DLT_USER13 160
#define DLT_USER14 161
#define DLT_USER15 162
/*
* For future use with 802.11 captures - defined by AbsoluteValue
* Systems to store a number of bits of link-layer information
* including radio information:
*
* http://www.shaftnet.org/~pizza/software/capturefrm.txt
*
* but it might be used by some non-AVS drivers now or in the
* future.
*/
#define DLT_IEEE802_11_RADIO_AVS 163 /* 802.11 plus AVS radio header */
/*
* Juniper-private data link type, as per request from
* Hannes Gredler <hannes@juniper.net>. The DLT_s are used
* for passing on chassis-internal metainformation such as
* QOS profiles, etc..
*/
#define DLT_JUNIPER_MONITOR 164
/*
* Reserved for BACnet MS/TP.
*/
#define DLT_BACNET_MS_TP 165
/*
* Another PPP variant as per request from Karsten Keil <kkeil@suse.de>.
*
* This is used in some OSes to allow a kernel socket filter to distinguish
* between incoming and outgoing packets, on a socket intended to
* supply pppd with outgoing packets so it can do dial-on-demand and
* hangup-on-lack-of-demand; incoming packets are filtered out so they
* don't cause pppd to hold the connection up (you don't want random
* input packets such as port scans, packets from old lost connections,
* etc. to force the connection to stay up).
*
* The first byte of the PPP header (0xff03) is modified to accomodate
* the direction - 0x00 = IN, 0x01 = OUT.
*/
#define DLT_PPP_PPPD 166
/*
* Names for backwards compatibility with older versions of some PPP
* software; new software should use DLT_PPP_PPPD.
*/
#define DLT_PPP_WITH_DIRECTION DLT_PPP_PPPD
#define DLT_LINUX_PPP_WITHDIRECTION DLT_PPP_PPPD
/*
* Juniper-private data link type, as per request from
* Hannes Gredler <hannes@juniper.net>. The DLT_s are used
* for passing on chassis-internal metainformation such as
* QOS profiles, cookies, etc..
*/
#define DLT_JUNIPER_PPPOE 167
#define DLT_JUNIPER_PPPOE_ATM 168
#define DLT_GPRS_LLC 169 /* GPRS LLC */
#define DLT_GPF_T 170 /* GPF-T (ITU-T G.7041/Y.1303) */
#define DLT_GPF_F 171 /* GPF-F (ITU-T G.7041/Y.1303) */
/*
* Requested by Oolan Zimmer <oz@gcom.com> for use in Gcom's T1/E1 line
* monitoring equipment.
*/
#define DLT_GCOM_T1E1 172
#define DLT_GCOM_SERIAL 173
/*
* Juniper-private data link type, as per request from
* Hannes Gredler <hannes@juniper.net>. The DLT_ is used
* for internal communication to Physical Interface Cards (PIC)
*/
#define DLT_JUNIPER_PIC_PEER 174
/*
* Link types requested by Gregor Maier <gregor@endace.com> of Endace
* Measurement Systems. They add an ERF header (see
* http://www.endace.com/support/EndaceRecordFormat.pdf) in front of
* the link-layer header.
*/
#define DLT_ERF_ETH 175 /* Ethernet */
#define DLT_ERF_POS 176 /* Packet-over-SONET */
/*
* Requested by Daniele Orlandi <daniele@orlandi.com> for raw LAPD
* for vISDN (http://www.orlandi.com/visdn/). Its link-layer header
* includes additional information before the LAPD header, so it's
* not necessarily a generic LAPD header.
*/
#define DLT_LINUX_LAPD 177
/*
* Juniper-private data link type, as per request from
* Hannes Gredler <hannes@juniper.net>.
* The DLT_ are used for prepending meta-information
* like interface index, interface name
* before standard Ethernet, PPP, Frelay & C-HDLC Frames
*/
#define DLT_JUNIPER_ETHER 178
#define DLT_JUNIPER_PPP 179
#define DLT_JUNIPER_FRELAY 180
#define DLT_JUNIPER_CHDLC 181
/*
* Multi Link Frame Relay (FRF.16)
*/
#define DLT_MFR 182
/*
* Juniper-private data link type, as per request from
* Hannes Gredler <hannes@juniper.net>.
* The DLT_ is used for internal communication with a
* voice Adapter Card (PIC)
*/
#define DLT_JUNIPER_VP 183
/*
* Arinc 429 frames.
* DLT_ requested by Gianluca Varenni <gianluca.varenni@cacetech.com>.
* Every frame contains a 32bit A429 label.
* More documentation on Arinc 429 can be found at
* http://www.condoreng.com/support/downloads/tutorials/ARINCTutorial.pdf
*/
#define DLT_A429 184
/*
* Arinc 653 Interpartition Communication messages.
* DLT_ requested by Gianluca Varenni <gianluca.varenni@cacetech.com>.
* Please refer to the A653-1 standard for more information.
*/
#define DLT_A653_ICM 185
/*
* USB packets, beginning with a USB setup header; requested by
* Paolo Abeni <paolo.abeni@email.it>.
*/
#define DLT_USB 186
/*
* Bluetooth HCI UART transport layer (part H:4); requested by
* Paolo Abeni.
*/
#define DLT_BLUETOOTH_HCI_H4 187
/*
* IEEE 802.16 MAC Common Part Sublayer; requested by Maria Cruz
* <cruz_petagay@bah.com>.
*/
#define DLT_IEEE802_16_MAC_CPS 188
/*
* USB packets, beginning with a Linux USB header; requested by
* Paolo Abeni <paolo.abeni@email.it>.
*/
#define DLT_USB_LINUX 189
/*
* Controller Area Network (CAN) v. 2.0B packets.
* DLT_ requested by Gianluca Varenni <gianluca.varenni@cacetech.com>.
* Used to dump CAN packets coming from a CAN Vector board.
* More documentation on the CAN v2.0B frames can be found at
* http://www.can-cia.org/downloads/?269
*/
#define DLT_CAN20B 190
/*
* IEEE 802.15.4, with address fields padded, as is done by Linux
* drivers; requested by Juergen Schimmer.
*/
#define DLT_IEEE802_15_4_LINUX 191
/*
* Per Packet Information encapsulated packets.
* DLT_ requested by Gianluca Varenni <gianluca.varenni@cacetech.com>.
*/
#define DLT_PPI 192
/*
* Header for 802.16 MAC Common Part Sublayer plus a radiotap radio header;
* requested by Charles Clancy.
*/
#define DLT_IEEE802_16_MAC_CPS_RADIO 193
/*
* Juniper-private data link type, as per request from
* Hannes Gredler <hannes@juniper.net>.
* The DLT_ is used for internal communication with a
* integrated service module (ISM).
*/
#define DLT_JUNIPER_ISM 194
/*
* IEEE 802.15.4, exactly as it appears in the spec (no padding, no
* nothing); requested by Mikko Saarnivala <mikko.saarnivala@sensinode.com>.
*/
#define DLT_IEEE802_15_4 195
/*
* Various link-layer types, with a pseudo-header, for SITA
* (http://www.sita.aero/); requested by Fulko Hew (fulko.hew@gmail.com).
*/
#define DLT_SITA 196
/*
* Various link-layer types, with a pseudo-header, for Endace DAG cards;
* encapsulates Endace ERF records. Requested by Stephen Donnelly
* <stephen@endace.com>.
*/
#define DLT_ERF 197
/*
* Special header prepended to Ethernet packets when capturing from a
* u10 Networks board. Requested by Phil Mulholland
* <phil@u10networks.com>.
*/
#define DLT_RAIF1 198
/*
* IPMB packet for IPMI, beginning with the I2C slave address, followed
* by the netFn and LUN, etc.. Requested by Chanthy Toeung
* <chanthy.toeung@ca.kontron.com>.
*/
#define DLT_IPMB 199
/*
* Juniper-private data link type, as per request from
* Hannes Gredler <hannes@juniper.net>.
* The DLT_ is used for capturing data on a secure tunnel interface.
*/
#define DLT_JUNIPER_ST 200
/*
* Bluetooth HCI UART transport layer (part H:4), with pseudo-header
* that includes direction information; requested by Paolo Abeni.
*/
#define DLT_BLUETOOTH_HCI_H4_WITH_PHDR 201
/*
* AX.25 packet with a 1-byte KISS header; see
*
* http://www.ax25.net/kiss.htm
*
* as per Richard Stearn <richard@rns-stearn.demon.co.uk>.
*/
#define DLT_AX25_KISS 202
/*
* LAPD packets from an ISDN channel, starting with the address field,
* with no pseudo-header.
* Requested by Varuna De Silva <varunax@gmail.com>.
*/
#define DLT_LAPD 203
/*
* Variants of various link-layer headers, with a one-byte direction
* pseudo-header prepended - zero means "received by this host",
* non-zero (any non-zero value) means "sent by this host" - as per
* Will Barker <w.barker@zen.co.uk>.
*/
#define DLT_PPP_WITH_DIR 204 /* PPP - don't confuse with DLT_PPP_WITH_DIRECTION */
#define DLT_C_HDLC_WITH_DIR 205 /* Cisco HDLC */
#define DLT_FRELAY_WITH_DIR 206 /* Frame Relay */
#define DLT_LAPB_WITH_DIR 207 /* LAPB */
/*
* 208 is reserved for an as-yet-unspecified proprietary link-layer
* type, as requested by Will Barker.
*/
/*
* IPMB with a Linux-specific pseudo-header; as requested by Alexey Neyman
* <avn@pigeonpoint.com>.
*/
#define DLT_IPMB_LINUX 209
/*
* FlexRay automotive bus - http://www.flexray.com/ - as requested
* by Hannes Kaelber <hannes.kaelber@x2e.de>.
*/
#define DLT_FLEXRAY 210
/*
* Media Oriented Systems Transport (MOST) bus for multimedia
* transport - http://www.mostcooperation.com/ - as requested
* by Hannes Kaelber <hannes.kaelber@x2e.de>.
*/
#define DLT_MOST 211
/*
* Local Interconnect Network (LIN) bus for vehicle networks -
* http://www.lin-subbus.org/ - as requested by Hannes Kaelber
* <hannes.kaelber@x2e.de>.
*/
#define DLT_LIN 212
/*
* X2E-private data link type used for serial line capture,
* as requested by Hannes Kaelber <hannes.kaelber@x2e.de>.
*/
#define DLT_X2E_SERIAL 213
/*
* X2E-private data link type used for the Xoraya data logger
* family, as requested by Hannes Kaelber <hannes.kaelber@x2e.de>.
*/
#define DLT_X2E_XORAYA 214
/*
* IEEE 802.15.4, exactly as it appears in the spec (no padding, no
* nothing), but with the PHY-level data for non-ASK PHYs (4 octets
* of 0 as preamble, one octet of SFD, one octet of frame length+
* reserved bit, and then the MAC-layer data, starting with the
* frame control field).
*
* Requested by Max Filippov <jcmvbkbc@gmail.com>.
*/
#define DLT_IEEE802_15_4_NONASK_PHY 215
/*
* DLT and savefile link type values are split into a class and
* a member of that class. A class value of 0 indicates a regular
* DLT_/LINKTYPE_ value.
*/
#define DLT_CLASS(x) ((x) & 0x03ff0000)
/*
* NetBSD-specific generic "raw" link type. The class value indicates
* that this is the generic raw type, and the lower 16 bits are the
* address family we're dealing with. Those values are NetBSD-specific;
* do not assume that they correspond to AF_ values for your operating
* system.
*/
#define DLT_CLASS_NETBSD_RAWAF 0x02240000
#define DLT_NETBSD_RAWAF(af) (DLT_CLASS_NETBSD_RAWAF | (af))
#define DLT_NETBSD_RAWAF_AF(x) ((x) & 0x0000ffff)
#define DLT_IS_NETBSD_RAWAF(x) (DLT_CLASS(x) == DLT_CLASS_NETBSD_RAWAF)
/*
* The instruction encodings.
*/
/* instruction classes */
#define BPF_CLASS(code) ((code) & 0x07)
#define BPF_LD 0x00
#define BPF_LDX 0x01
#define BPF_ST 0x02
#define BPF_STX 0x03
#define BPF_ALU 0x04
#define BPF_JMP 0x05
#define BPF_RET 0x06
#define BPF_MISC 0x07
/* ld/ldx fields */
#define BPF_SIZE(code) ((code) & 0x18)
#define BPF_W 0x00
#define BPF_H 0x08
#define BPF_B 0x10
#define BPF_MODE(code) ((code) & 0xe0)
#define BPF_IMM 0x00
#define BPF_ABS 0x20
#define BPF_IND 0x40
#define BPF_MEM 0x60
#define BPF_LEN 0x80
#define BPF_MSH 0xa0
/* alu/jmp fields */
#define BPF_OP(code) ((code) & 0xf0)
#define BPF_ADD 0x00
#define BPF_SUB 0x10
#define BPF_MUL 0x20
#define BPF_DIV 0x30
#define BPF_OR 0x40
#define BPF_AND 0x50
#define BPF_LSH 0x60
#define BPF_RSH 0x70
#define BPF_NEG 0x80
#define BPF_JA 0x00
#define BPF_JEQ 0x10
#define BPF_JGT 0x20
#define BPF_JGE 0x30
#define BPF_JSET 0x40
#define BPF_SRC(code) ((code) & 0x08)
#define BPF_K 0x00
#define BPF_X 0x08
/* ret - BPF_K and BPF_X also apply */
#define BPF_RVAL(code) ((code) & 0x18)
#define BPF_A 0x10
/* misc */
#define BPF_MISCOP(code) ((code) & 0xf8)
#define BPF_TAX 0x00
#define BPF_TXA 0x80
/*
* The instruction data structure.
*/
struct bpf_insn {
u_short code;
u_char jt;
u_char jf;
bpf_u_int32 k;
};
/*
* Macros for insn array initializers.
*/
#define BPF_STMT(code, k) { (u_short)(code), 0, 0, k }
#define BPF_JUMP(code, k, jt, jf) { (u_short)(code), jt, jf, k }
#if __STDC__ || defined(__cplusplus)
extern int bpf_validate(const struct bpf_insn *, int);
extern u_int bpf_filter(const struct bpf_insn *, const u_char *, u_int, u_int);
#else
extern int bpf_validate();
extern u_int bpf_filter();
#endif
/*
* Number of scratch memory words (for BPF_LD|BPF_MEM and BPF_ST).
*/
#define BPF_MEMWORDS 16
#ifdef __cplusplus
}
#endif
#endif

89
pcap/namedb.h Normal file
View File

@ -0,0 +1,89 @@
/*
* Copyright (c) 1994, 1996
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Computer Systems
* Engineering Group at Lawrence Berkeley Laboratory.
* 4. Neither the name of the University nor of the Laboratory may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#) $Header: /tcpdump/master/libpcap/pcap/namedb.h,v 1.1 2006/10/04 18:09:22 guy Exp $ (LBL)
*/
#ifndef lib_pcap_namedb_h
#define lib_pcap_namedb_h
#ifdef __cplusplus
extern "C" {
#endif
/*
* As returned by the pcap_next_etherent()
* XXX this stuff doesn't belong in this interface, but this
* library already must do name to address translation, so
* on systems that don't have support for /etc/ethers, we
* export these hooks since they'll
*/
struct pcap_etherent {
u_char addr[6];
char name[122];
};
#ifndef PCAP_ETHERS_FILE
#define PCAP_ETHERS_FILE "/etc/ethers"
#endif
struct pcap_etherent *pcap_next_etherent(FILE *);
u_char *pcap_ether_hostton(const char*);
u_char *pcap_ether_aton(const char *);
bpf_u_int32 **pcap_nametoaddr(const char *);
#ifdef INET6
struct addrinfo *pcap_nametoaddrinfo(const char *);
#endif
bpf_u_int32 pcap_nametonetaddr(const char *);
int pcap_nametoport(const char *, int *, int *);
int pcap_nametoportrange(const char *, int *, int *, int *);
int pcap_nametoproto(const char *);
int pcap_nametoeproto(const char *);
int pcap_nametollc(const char *);
/*
* If a protocol is unknown, PROTO_UNDEF is returned.
* Also, pcap_nametoport() returns the protocol along with the port number.
* If there are ambiguous entried in /etc/services (i.e. domain
* can be either tcp or udp) PROTO_UNDEF is returned.
*/
#define PROTO_UNDEF -1
/* XXX move these to pcap-int.h? */
int __pcap_atodn(const char *, bpf_u_int32 *);
int __pcap_atoin(const char *, bpf_u_int32 *);
u_short __pcap_nametodnaddr(const char *);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -31,21 +31,24 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#) $Header: /tcpdump/master/libpcap/pcap1.h,v 1.2 2004/03/30 14:42:50 mcr Exp $ (LBL)
* @(#) $Header: /tcpdump/master/libpcap/pcap/pcap.h,v 1.4.2.11 2008-10-06 15:38:39 gianluca Exp $ (LBL)
*/
#ifndef lib_pcap_h
#define lib_pcap_h
#ifndef lib_pcap_pcap_h
#define lib_pcap_pcap_h
#ifdef WIN32
#include <pcap-stdinc.h>
#else /* WIN32 */
#include <sys/types.h>
#include <sys/time.h>
#endif /* WIN32 */
#if defined(WIN32)
#include <pcap-stdinc.h>
#elif defined(MSDOS)
#include <sys/types.h>
#include <sys/socket.h> /* u_int, u_char etc. */
#else /* UN*X */
#include <sys/types.h>
#include <sys/time.h>
#endif /* WIN32/MSDOS/UN*X */
#ifndef PCAP_DONT_INCLUDE_PCAP_BPF_H
#include <pcap-bpf.h>
#include <pcap/bpf.h>
#endif
#include <stdio.h>
@ -54,8 +57,8 @@
extern "C" {
#endif
#define PCAP_VERSION_MAJOR 3
#define PCAP_VERSION_MINOR 0
#define PCAP_VERSION_MAJOR 2
#define PCAP_VERSION_MINOR 4
#define PCAP_ERRBUF_SIZE 256
@ -92,8 +95,8 @@ typedef struct pcap_addr pcap_addr_t;
* introduce a new structure for the new format, if the layout
* of the structure changed;
*
* send mail to "tcpdump-workers@tcpdump.org", requesting a new
* magic number for your new capture file format, and, when
* send mail to "tcpdump-workers@lists.tcpdump.org", requesting
* a new magic number for your new capture file format, and, when
* you get the new magic number, put it in "savefile.c";
*
* use that magic number for save files with the changed file
@ -103,75 +106,56 @@ typedef struct pcap_addr pcap_addr_t;
* the old file header as well as files with the new file header
* (using the magic number to determine the header format).
*
* Then supply the changes to "patches@tcpdump.org", so that future
* versions of libpcap and programs that use it (such as tcpdump) will
* be able to read your new capture file format.
* Then supply the changes as a patch at
*
* http://sourceforge.net/projects/libpcap/
*
* so that future versions of libpcap and programs that use it (such as
* tcpdump) will be able to read your new capture file format.
*/
enum pcap1_info_types {
PCAP_DATACAPTURE,
PCAP_TIMESTAMP,
PCAP_WALLTIME,
PCAP_TIMESKEW,
PCAP_PROBEPLACE, /* aka direction */
PCAP_COMMENT, /* comment */
};
struct pcap1_info_container {
bpf_u_int32 info_len; /* in bytes */
bpf_u_int32 info_type; /* enum pcap1_info_types */
unsigned char info_data[0];
};
struct pcap1_info_timestamp {
struct pcap1_info_container pic;
bpf_u_int32 nanoseconds; /* 10^-9 of seconds */
bpf_u_int32 seconds; /* seconds since Unix epoch - GMT */
bpf_u_int16 macroseconds; /* 16 bits more of MSB of time */
bpf_u_int16 sigfigs; /* accuracy of timestamps - LSB bits */
};
struct pcap1_info_packet {
struct pcap1_info_container pic;
bpf_u_int32 caplen; /* length of portion present */
bpf_u_int32 len; /* length this packet (off wire) */
bpf_u_int32 linktype; /* data link type (LINKTYPE_*) */
bpf_u_int32 ifIndex; /* abstracted interface index */
unsigned char packet_data[0];
};
enum pcap1_probe {
INBOUND =1,
OUTBOUND =2,
FORWARD =3,
PREENCAP =4,
POSTDECAP=5,
};
struct pcap1_info_probe {
struct pcap1_info_container pic;
bpf_u_int32 probeloc; /* enum pcap1_probe */
unsigned char probe_desc[0];
};
struct pcap1_info_comment {
struct pcap1_info_container pic;
unsigned char comment[0];
};
struct pcap1_packet_header {
struct pcap_file_header {
bpf_u_int32 magic;
u_short version_major;
u_short version_minor;
bpf_u_int32 block_len;
struct pcap1_info_container pics[0];
u_short version_major;
u_short version_minor;
bpf_int32 thiszone; /* gmt to local correction */
bpf_u_int32 sigfigs; /* accuracy of timestamps */
bpf_u_int32 snaplen; /* max length saved portion of each pkt */
bpf_u_int32 linktype; /* data link type (LINKTYPE_*) */
};
/*
* Each packet in the dump file is prepended with this generic header.
* This gets around the problem of different headers for different
* packet interfaces.
* Macros for the value returned by pcap_datalink_ext().
*
* If LT_FCS_LENGTH_PRESENT(x) is true, the LT_FCS_LENGTH(x) macro
* gives the FCS length of packets in the capture.
*/
#define LT_FCS_LENGTH_PRESENT(x) ((x) & 0x04000000)
#define LT_FCS_LENGTH(x) (((x) & 0xF0000000) >> 28)
#define LT_FCS_DATALINK_EXT(x) ((((x) & 0xF) << 28) | 0x04000000)
typedef enum {
PCAP_D_INOUT = 0,
PCAP_D_IN,
PCAP_D_OUT
} pcap_direction_t;
/*
* Generic per-packet information, as supplied by libpcap.
*
* The time stamp can and should be a "struct timeval", regardless of
* whether your system supports 32-bit tv_sec in "struct timeval",
* 64-bit tv_sec in "struct timeval", or both if it supports both 32-bit
* and 64-bit applications. The on-disk format of savefiles uses 32-bit
* tv_sec (and tv_usec); this structure is irrelevant to that. 32-bit
* and 64-bit versions of libpcap, even if they're on the same platform,
* should supply the appropriate version of "struct timeval", even if
* that's not what the underlying packet capture mechanism supplies.
*/
struct pcap_pkthdr {
struct timeval ts; /* time stamp */
bpf_u_int32 caplen; /* length of portion present */
bpf_u_int32 len; /* length this packet (off wire) */
};
/*
* As returned by the pcap_stats()
@ -185,6 +169,39 @@ struct pcap_stat {
#endif /* WIN32 */
};
#ifdef MSDOS
/*
* As returned by the pcap_stats_ex()
*/
struct pcap_stat_ex {
u_long rx_packets; /* total packets received */
u_long tx_packets; /* total packets transmitted */
u_long rx_bytes; /* total bytes received */
u_long tx_bytes; /* total bytes transmitted */
u_long rx_errors; /* bad packets received */
u_long tx_errors; /* packet transmit problems */
u_long rx_dropped; /* no space in Rx buffers */
u_long tx_dropped; /* no space available for Tx */
u_long multicast; /* multicast packets received */
u_long collisions;
/* detailed rx_errors: */
u_long rx_length_errors;
u_long rx_over_errors; /* receiver ring buff overflow */
u_long rx_crc_errors; /* recv'd pkt with crc error */
u_long rx_frame_errors; /* recv'd frame alignment error */
u_long rx_fifo_errors; /* recv'r fifo overrun */
u_long rx_missed_errors; /* recv'r missed packet */
/* detailed tx_errors */
u_long tx_aborted_errors;
u_long tx_carrier_errors;
u_long tx_fifo_errors;
u_long tx_heartbeat_errors;
u_long tx_window_errors;
};
#endif
/*
* Item in a list of interfaces.
*/
@ -212,11 +229,57 @@ struct pcap_addr {
typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *,
const u_char *);
/*
* Error codes for the pcap API.
* These will all be negative, so you can check for the success or
* failure of a call that returns these codes by checking for a
* negative value.
*/
#define PCAP_ERROR -1 /* generic error code */
#define PCAP_ERROR_BREAK -2 /* loop terminated by pcap_breakloop */
#define PCAP_ERROR_NOT_ACTIVATED -3 /* the capture needs to be activated */
#define PCAP_ERROR_ACTIVATED -4 /* the operation can't be performed on already activated captures */
#define PCAP_ERROR_NO_SUCH_DEVICE -5 /* no such device exists */
#define PCAP_ERROR_RFMON_NOTSUP -6 /* this device doesn't support rfmon (monitor) mode */
#define PCAP_ERROR_NOT_RFMON -7 /* operation supported only in monitor mode */
#define PCAP_ERROR_PERM_DENIED -8 /* no permission to open the device */
#define PCAP_ERROR_IFACE_NOT_UP -9 /* interface isn't up */
/*
* Warning codes for the pcap API.
* These will all be positive and non-zero, so they won't look like
* errors.
*/
#define PCAP_WARNING 1 /* generic warning code */
#define PCAP_WARNING_PROMISC_NOTSUP 2 /* this device doesn't support promiscuous mode */
char *pcap_lookupdev(char *);
int pcap_lookupnet(const char *, bpf_u_int32 *, bpf_u_int32 *, char *);
pcap_t *pcap_create(const char *, char *);
int pcap_set_snaplen(pcap_t *, int);
int pcap_set_promisc(pcap_t *, int);
int pcap_can_set_rfmon(pcap_t *);
int pcap_set_rfmon(pcap_t *, int);
int pcap_set_timeout(pcap_t *, int);
int pcap_set_buffer_size(pcap_t *, int);
int pcap_activate(pcap_t *);
pcap_t *pcap_open_live(const char *, int, int, int, char *);
pcap_t *pcap_open_dead(int, int);
pcap_t *pcap_open_offline(const char *, char *);
#if defined(WIN32)
pcap_t *pcap_hopen_offline(intptr_t, char *);
#if !defined(LIBPCAP_EXPORTS)
#define pcap_fopen_offline(f,b) \
pcap_hopen_offline(_get_osfhandle(_fileno(f)), b)
#else /*LIBPCAP_EXPORTS*/
static pcap_t *pcap_fopen_offline(FILE *, char *);
#endif
#else /*WIN32*/
pcap_t *pcap_fopen_offline(FILE *, char *);
#endif /*WIN32*/
void pcap_close(pcap_t *);
int pcap_loop(pcap_t *, int, pcap_handler, u_char *);
int pcap_dispatch(pcap_t *, int, pcap_handler, u_char *);
@ -226,19 +289,27 @@ int pcap_next_ex(pcap_t *, struct pcap_pkthdr **, const u_char **);
void pcap_breakloop(pcap_t *);
int pcap_stats(pcap_t *, struct pcap_stat *);
int pcap_setfilter(pcap_t *, struct bpf_program *);
int pcap_setdirection(pcap_t *, pcap_direction_t);
int pcap_getnonblock(pcap_t *, char *);
int pcap_setnonblock(pcap_t *, int, char *);
void pcap_perror(pcap_t *, char *);
char *pcap_strerror(int);
int pcap_inject(pcap_t *, const void *, size_t);
int pcap_sendpacket(pcap_t *, const u_char *, int);
const char *pcap_statustostr(int);
const char *pcap_strerror(int);
char *pcap_geterr(pcap_t *);
int pcap_compile(pcap_t *, struct bpf_program *, char *, int,
void pcap_perror(pcap_t *, char *);
int pcap_compile(pcap_t *, struct bpf_program *, const char *, int,
bpf_u_int32);
int pcap_compile_nopcap(int, int, struct bpf_program *,
char *, int, bpf_u_int32);
const char *, int, bpf_u_int32);
void pcap_freecode(struct bpf_program *);
int pcap_offline_filter(struct bpf_program *, const struct pcap_pkthdr *,
const u_char *);
int pcap_datalink(pcap_t *);
int pcap_datalink_ext(pcap_t *);
int pcap_list_datalinks(pcap_t *, int **);
int pcap_set_datalink(pcap_t *, int);
void pcap_free_datalinks(int *);
int pcap_datalink_name_to_val(const char *);
const char *pcap_datalink_val_to_name(int);
const char *pcap_datalink_val_to_description(int);
@ -252,10 +323,12 @@ FILE *pcap_file(pcap_t *);
int pcap_fileno(pcap_t *);
pcap_dumper_t *pcap_dump_open(pcap_t *, const char *);
pcap_dumper_t *pcap_dump_fopen(pcap_t *, FILE *fp);
FILE *pcap_dump_file(pcap_dumper_t *);
long pcap_dump_ftell(pcap_dumper_t *);
int pcap_dump_flush(pcap_dumper_t *);
void pcap_dump_close(pcap_dumper_t *);
void pcap_dump(u_char *, const struct pcap_pkthdr *, const u_char *);
FILE *pcap_dump_file(pcap_dumper_t *);
int pcap_findalldevs(pcap_if_t **, char *);
void pcap_freealldevs(pcap_if_t *);
@ -263,37 +336,49 @@ void pcap_freealldevs(pcap_if_t *);
const char *pcap_lib_version(void);
/* XXX this guy lives in the bpf tree */
u_int bpf_filter(struct bpf_insn *, u_char *, u_int, u_int);
int bpf_validate(struct bpf_insn *f, int len);
char *bpf_image(struct bpf_insn *, int);
void bpf_dump(struct bpf_program *, int);
u_int bpf_filter(const struct bpf_insn *, const u_char *, u_int, u_int);
int bpf_validate(const struct bpf_insn *f, int len);
char *bpf_image(const struct bpf_insn *, int);
void bpf_dump(const struct bpf_program *, int);
#if defined(WIN32)
#ifdef WIN32
/*
* Win32 definitions
*/
int pcap_setbuff(pcap_t *p, int dim);
int pcap_setmode(pcap_t *p, int mode);
int pcap_sendpacket(pcap_t *p, u_char *buf, int size);
int pcap_setmintocopy(pcap_t *p, int size);
#ifdef WPCAP
/* Include file with the wpcap-specific extensions */
#include <Win32-Extensions.h>
#endif
#endif /* WPCAP */
#define MODE_CAPT 0
#define MODE_STAT 1
#define MODE_MON 2
#elif defined(MSDOS)
/*
* MS-DOS definitions
*/
int pcap_stats_ex (pcap_t *, struct pcap_stat_ex *);
void pcap_set_wait (pcap_t *p, void (*yield)(void), int wait);
u_long pcap_mac_packets (void);
#else /* UN*X */
#else
/*
* UN*X definitions
*/
int pcap_get_selectable_fd(pcap_t *);
#endif /* WIN32 */
#endif /* WIN32/MSDOS/UN*X */
#ifdef __cplusplus
}

View File

@ -35,7 +35,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#) $Header: /tcpdump/master/libpcap/sll.h,v 1.7 2002/06/11 17:04:48 itojun Exp $ (LBL)
* @(#) $Header: /tcpdump/master/libpcap/pcap/sll.h,v 1.2.2.1 2008-05-30 01:36:06 guy Exp $ (LBL)
*/
/*
@ -64,8 +64,8 @@
* DO NOT change the layout of this structure, or change any of the
* LINUX_SLL_ values below. If you must change the link-layer header
* for a "cooked" Linux capture, introduce a new DLT_ type (ask
* "tcpdump-workers@tcpdump.org" for one, so that you don't give it a
* value that collides with a value already being used), and use the
* "tcpdump-workers@lists.tcpdump.org" for one, so that you don't give it
* a value that collides with a value already being used), and use the
* new header in captures of that type, so that programs that can
* handle DLT_LINUX_SLL captures will continue to handle them correctly
* without any change, and so that capture files with different headers
@ -73,6 +73,9 @@
* packets in them.
*/
#ifndef lib_pcap_sll_h
#define lib_pcap_sll_h
/*
* A DLT_LINUX_SLL fake link-layer header.
*/
@ -122,3 +125,5 @@ struct sll_header {
*/
#define LINUX_SLL_P_802_3 0x0001 /* Novell 802.3 frames without 802.2 LLC header */
#define LINUX_SLL_P_802_2 0x0004 /* 802.2 frames (not D/I/X Ethernet) */
#endif

90
pcap/usb.h Normal file
View File

@ -0,0 +1,90 @@
/*
* Copyright (c) 2006 Paolo Abeni (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. 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 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.
*
* Basic USB data struct
* By Paolo Abeni <paolo.abeni@email.it>
*
* @(#) $Header: /tcpdump/master/libpcap/pcap/usb.h,v 1.6 2007/09/22 02:06:08 guy Exp $
*/
#ifndef _PCAP_USB_STRUCTS_H__
#define _PCAP_USB_STRUCTS_H__
/*
* possible transfer mode
*/
#define URB_TRANSFER_IN 0x80
#define URB_ISOCHRONOUS 0x0
#define URB_INTERRUPT 0x1
#define URB_CONTROL 0x2
#define URB_BULK 0x3
/*
* possible event type
*/
#define URB_SUBMIT 'S'
#define URB_COMPLETE 'C'
#define URB_ERROR 'E'
/*
* USB setup header as defined in USB specification.
* Appears at the front of each packet in DLT_USB captures.
*/
typedef struct _usb_setup {
u_int8_t bmRequestType;
u_int8_t bRequest;
u_int16_t wValue;
u_int16_t wIndex;
u_int16_t wLength;
} pcap_usb_setup;
/*
* Header prepended by linux kernel to each event.
* Appears at the front of each packet in DLT_USB_LINUX captures.
*/
typedef struct _usb_header {
u_int64_t id;
u_int8_t event_type;
u_int8_t transfer_type;
u_int8_t endpoint_number;
u_int8_t device_address;
u_int16_t bus_id;
char setup_flag;/*if !=0 the urb setup header is not present*/
char data_flag; /*if !=0 no urb data is present*/
int64_t ts_sec;
int32_t ts_usec;
int32_t status;
u_int32_t urb_len;
u_int32_t data_len; /* amount of urb data really present in this event*/
pcap_usb_setup setup;
} pcap_usb_header;
#endif

46
pcap/vlan.h Normal file
View File

@ -0,0 +1,46 @@
/*-
* Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#) $Header: /tcpdump/master/libpcap/pcap/vlan.h,v 1.1.2.2 2008-08-06 07:45:59 guy Exp $
*/
#ifndef lib_pcap_vlan_h
#define lib_pcap_vlan_h
struct vlan_tag {
u_int16_t vlan_tpid; /* ETH_P_8021Q */
u_int16_t vlan_tci; /* VLAN TCI */
};
#define VLAN_TAG_LEN 4
#endif

89
pcap_activate.3pcap Normal file
View File

@ -0,0 +1,89 @@
.\" @(#) $Header: /tcpdump/master/libpcap/pcap_activate.3pcap,v 1.1.2.5 2008-07-01 08:04:03 guy Exp $
.\"
.\" Copyright (c) 1994, 1996, 1997
.\" The Regents of the University of California. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that: (1) source code distributions
.\" retain the above copyright notice and this paragraph in its entirety, (2)
.\" distributions including binary code include the above copyright notice and
.\" this paragraph in its entirety in the documentation or other materials
.\" provided with the distribution, and (3) all advertising materials mentioning
.\" features or use of this software display the following acknowledgement:
.\" ``This product includes software developed by the University of California,
.\" Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
.\" the University nor the names of its contributors may be used to endorse
.\" or promote products derived from this software without specific prior
.\" written permission.
.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\"
.TH PCAP_ACTIVATE 3PCAP "5 April 2008"
.SH NAME
pcap_activate \- activate a capture handle
.SH SYNOPSIS
.nf
.ft B
#include <pcap/pcap.h>
.ft
.LP
.ft B
int pcap_activate(pcap_t *p);
.ft
.fi
.SH DESCRIPTION
.B pcap_activate()
is used to activate a packet capture handle to look
at packets on the network, with the options that were set on the handle
being in effect.
.SH RETURN VALUE
.B pcap_activate()
returns 0 on success without warnings,
.B PCAP_WARNING_PROMISC_NOTSUP
on success on a device that doesn't support promiscuous mode if
promiscuous mode was requested,
.B PCAP_WARNING
on success with any other warning,
.B PCAP_ERROR_ACTIVATED
if the handle has already been activated,
.B PCAP_ERROR_NO_SUCH_DEVICE
if the capture source specified when the handle was created doesn't
exist,
.B PCAP_ERROR_PERM_DENIED
if the process doesn't have permission to open the capture source,
.B PCAP_ERROR_RFMON_NOTSUP
if monitor mode was specified but the capture source doesn't support
monitor mode,
.B PCAP_ERROR_IFACE_NOT_UP
if the capture source is not up, and
.B PCAP_ERROR
if another error occurred.
If
.B PCAP_WARNING
or
.B PCAP_ERROR
is returned,
.B pcap_geterr()
or
.B pcap_perror()
may be called with
.I p
as an argument to fetch or display a message describing the warning or
error.
If
.BR PCAP_WARNING_PROMISC_NOTSUP ,
.BR PCAP_ERROR_NO_SUCH_DEVICE ,
or
.B PCAP_ERROR_PERM_DENIED
is returned,
.B pcap_geterr()
or
.B pcap_perror()
may be called with
.I p
as an argument to fetch or display an message giving additional details
about the problem that might be useful for debugging the problem if it's
unexpected.
.SH SEE ALSO
pcap(3PCAP)

Some files were not shown because too many files have changed in this diff Show More