This commit is contained in:
Bruce M Simpson 2004-03-31 09:07:39 +00:00
parent 09f33d614a
commit feb4ecdbac
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/vendor/libpcap/dist/; revision=127664
64 changed files with 16546 additions and 3582 deletions

View File

@ -10,3 +10,4 @@ scanner.c
grammar.c
tokdefs.h
version.c
version.h

View File

@ -1,4 +1,45 @@
@(#) $Header: /tcpdump/master/libpcap/CHANGES,v 1.56 2001/10/23 04:37:31 mcr Exp $ (LBL)
@(#) $Header: /tcpdump/master/libpcap/CHANGES,v 1.56.4.3 2004/03/30 14:29:16 mcr Exp $ (LBL)
Tue. March 30, 2004. mcr@sandelman.ottawa.on.ca. Summary for 3.8.3 release
Fixed minor problem in gencode.c that would appear on 64-bit
platforms.
Version number is now sane.
Mon. March 29, 2004. mcr@sandelman.ottawa.on.ca. Summary for 3.8.2 release
updates for autoconf 2.5
fixes for ppp interfaces for freebsd 4.1
pcap gencode can generate code for 802.11, IEEE1394, and pflog.
Wed. November 12, 2003. mcr@sandelman.ottawa.on.ca. Summary for 0.8 release
added pcap_findalldevs()
Win32 patches from NetGroup, Politecnico di Torino (Italy)
OpenBSD pf, DLT_PFLOG added
Many changes to ATM support.
lookup pcap_lookupnet()
Added DLT_ARCNET_LINUX, DLT_ENC, DLT_IEEE802_11_RADIO, DLT_SUNATM,
DLT_IP_OVER_FC, DLT_FRELAY, others.
Sigh. More AIX wonderfulness.
Document updates.
Changes to API: pcap_next_ex(), pcap_breakloop(), pcap_dump_flush(),
pcap_list_datalinks(), pcap_set_datalink(),
pcap_lib_version(), pcap_datalink_val_to_name(),
pcap_datalink_name_to_val(), new error returns.
Tuesday, February 25, 2003. fenner@research.att.com. 0.7.2 release
Support link types that use 802.2 always, never, and sometimes.
Don't decrease the size of the BPF buffer from the default.
Support frame relay.
Handle 32-bit timestamps in DLPI, and pass the right buffer size.
Handle Linux systems with modern kernel but without
SOL_PACKET in the userland headers.
Linux support for ARPHRD_RAWHDLC.
Handle 32-bit timestamps in snoop.
Support eg (Octane/O2xxx/O3xxx Gigabit) devices.
Add new reserved DLT types.
Monday October 23, 2001. mcr@sandelman.ottawa.on.ca. Summary for 0.7 release

View File

@ -2,52 +2,85 @@ This file lists people who have contributed to libpcap:
The current maintainers:
Bill Fenner <fenner@research.att.com>
Assar Westerlund <assar@sics.se>
Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
Jun-ichiro itojun Hagino <itojun@iijlab.net>
Fulvio Risso <risso@polito.it>
Guy Harris <guy@alum.mit.edu>
Torsten Landschoff <torsten@debian.org>
Hannes Gredler <hannes@juniper.net>
Jun-ichiro itojun Hagino <itojun@iijlab.net>
Michael Richardson <mcr@sandelman.ottawa.on.ca>
Sebastian Krahmer <krahmer@cs.uni-potsdam.de>
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>
Fulvio Risso <risso@polito.it>
Assar Westerlund <assar@sics.se>
Brian Ginsbach <ginsbach@cray.com>
Charles M. Hannum <mycroft@netbsd.org>
Chris G. Demetriou <cgd@netbsd.org>
Chris Pepper <pepper@mail.reppep.com>
Darren Reed <darrenr@reed.wattle.id.au>
David Kaelbling <drk@sgi.com>
David Young <dyoung@ojctech.com>
Don Ebright <Don.Ebright@compuware.com>
Eric Anderson <anderse@hpl.hp.com>
Franz Schaefer <schaefer@mond.at>
Gianluca Varenni <varenni@netgroup-serv.polito.it>
Gisle Vanem <giva@bgnett.no>
Graeme Hewson <ghewson@cix.compulink.co.uk>
Greg Stark <gsstark@mit.edu>
Greg Troxel <gdt@ir.bbn.com>
Guillaume Pelat <endymion_@users.sourceforge.net>
Hyung Sik Yoon <hsyn@kr.ibm.com>
Igor Khristophorov <igor@atdot.org>
Jason R. Thorpe <thorpej@zembu.com>
Jan-Philip Velders <jpv@veldersjes.net>
Jason R. Thorpe <thorpej@netbsd.org>
Javier Achirica <achirica@ttd.net>
Jean Tourrilhes <jt@hpl.hp.com>
Jefferson Ogata <jogata@nodc.noaa.gov>
Jesper Peterson <jesper@endace.com>
John Bankier <jbankier@rainfinity.com>
Jon Lindgren <jonl@yubyub.net>
Juergen Schoenwaelder <schoenw@ibr.cs.tu-bs.de>
Kazushi Sugyo <sugyo@pb.jp.nec.com>
Klaus Klein <kleink@netbsd.org>
Koryn Grant <koryn@endace.com>
Krzysztof Halasa <khc@pm.waw.pl>
Lorenzo Cavallaro <sullivan@sikurezza.org>
Loris Degioanni <loris@netgroup-serv.polito.it>
Love Hörnquist-Åstrand <lha@stacken.kth.se>
Maciej W. Rozycki <macro@ds2.pg.gda.pl>
Marcus Felipe Pereira <marcus@task.com.br>
Martin Husemann <martin@netbsd.org>
Mike Wiacek <mike@iroot.net>
Monroe Williams <monroe@pobox.com>
Octavian Cerna <tavy@ylabs.com>
Olaf Kirch <okir@caldera.de>
Onno van der Linden <onno@simplex.nl>
Paul Mundt <lethal@linux-sh.org>
Pavel Kankovsky <kan@dcit.cz>
Peter Fales <peter@fales-lorenz.net>
Peter Jeremy <peter.jeremy@alcatel.com.au>
Phil Wood <cpw@lanl.gov>
Rafal Maszkowski <rzm@icm.edu.pl>
Rick Jones <raj@cup.hp.com>
Scott Barron <sb125499@ohiou.edu>
Scott Gifford <sgifford@tir.com>
Sebastian Krahmer <krahmer@cs.uni-potsdam.de>
Shaun Clowes <delius@progsoc.uts.edu.au>
Solomon Peachy <pizza@shaftnet.org>
Stefan Hudson <hudson@mbay.net>
Tony Li <tli@jnx.com>
Takashi Yamamoto <yamt@mwd.biglobe.ne.jp>
Tony Li <tli@procket.com>
Torsten Landschoff <torsten@debian.org>
Uns Lider <unslider@miranda.org>
Uwe Girlich <Uwe.Girlich@philosys.de>
Xianjie Zhang <xzhang@cup.hp.com>
Yen Yen Lim
Yoann Vandoorselaere <yoann@prelude-ids.org>
The original LBL crew:
Steve McCanne

View File

@ -6,15 +6,20 @@ LICENSE
Makefile.in
README
README.aix
README.dag
README.hpux
README.linux
README.tru64
README.Win32
SUNOS4/nit_if.o.sparc
SUNOS4/nit_if.o.sun3
SUNOS4/nit_if.o.sun4c.4.0.3c
TODO
VERSION
acconfig.h
aclocal.m4
arcnet.h
bpf/net/bpf.h
atmuni31.h
bpf/net/bpf_filter.c
bpf_dump.c
bpf_image.c
@ -25,12 +30,20 @@ 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
@ -39,7 +52,11 @@ mkdep
nametoaddr.c
nlpid.h
optimize.c
packaging/pcap.spec
pcap-bpf.c
pcap-bpf.h
pcap-dag.c
pcap-dag.h
pcap-dlpi.c
pcap-enet.c
pcap-int.h
@ -50,12 +67,38 @@ pcap-nit.h
pcap-null.c
pcap-pf.c
pcap-pf.h
pcap-stdinc.h
pcap-snit.c
pcap-snoop.c
pcap-win32.c
pcap.3
pcap.c
pcap.h
pf.h
ppp.h
rawss7.h
savefile.c
scanner.l
sll.h
snprintf.c
sunatmpos.h
Win32/Include/Gnuc.h
Win32/Include/addrinfo.h
Win32/Include/bittypes.h
Win32/Include/cdecl_ext.h
Win32/Include/inetprivate.h
Win32/Include/ip6_misc.h
Win32/Include/sockstorage.h
Win32/Include/arpa/nameser.h
Win32/Include/net/if.h
Win32/Include/net/netdb.h
Win32/Include/net/paths.h
Win32/Src/ffs.c
Win32/Src/getaddrinfo.c
Win32/Src/getnetbynm.c
Win32/Src/getnetent.c
Win32/Src/getopt.c
Win32/Src/getservent.c
Win32/Src/inet_aton.c
Win32/Src/inet_net.c
Win32/Src/inet_pton.c

View File

@ -1,4 +1,4 @@
@(#) $Header: /tcpdump/master/libpcap/INSTALL.txt,v 1.2 2001/06/05 03:45:53 guy Exp $ (LBL)
@(#) $Header: /tcpdump/master/libpcap/INSTALL.txt,v 1.7.2.2 2003/12/15 02:05:00 guy Exp $ (LBL)
To build libpcap, run "./configure" (a shell script). The configure
script will determine your system attributes and generate an
@ -295,48 +295,80 @@ timestamp resolution if it finds it's running on a SS-1).
FILES
-----
CHANGES - description of differences between releases
CREDITS - people that have helped libpcap along
FILES - list of files exported as part of the distribution
INSTALL - this file
INSTALL.txt - this file
LICENSE - the license under which tcpdump is distributed
Makefile.in - compilation rules (input to the configure script)
README - description of distribution
README.aix - notes on using libpcap on AIX
README.dag - notes on using libpcap to capture on Endace DAG devices
README.hpux - notes on using libpcap on HP-UX
README.linux - notes on using libpcap on Linux
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
VERSION - version of this release
acconfig.h - support for post-2.13 autoconf
aclocal.m4 - autoconf macros
bpf/net - copies of bpf_filter.c and bpf.h
arcnet.h - ARCNET definitions
atmuni31.h - ATM Q.2931 definitions
bpf/net - copy of bpf_filter.c
bpf_dump.c - BPF program printing routines
bpf_filter.c - symlink to bpf/net/bpf_filter.c
bpf_image.c - bpf disassembly routine
bpf_image.c - BPF disassembly routine
config.guess - autoconf support
config.h.in - autoconf input
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
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-win32.c - pcap_findalldevs() for WinPcap
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
lbl/os-*.h - OS-dependent defines and prototypes
llc.h - 802.2 LLC SAP definitions
mkdep - construct Makefile dependency list
nametoaddr.c - hostname to address routines
nlpid.h - OSI network layer protocol identifier definitions
net - symlink to bpf/net
optimize.c - bpf optimization routines
optimize.c - BPF optimization routines
packaging - packaging information for building libpcap RPMs
pcap-bpf.c - BSD Packet Filter support
pcap-bpf.h - BPF definitions
pcap-dag.c - Endace DAG device capture support
pcap-dag.h - Endace DAG device capture support
pcap-dlpi.c - Data Link Provider Interface support
pcap-enet.c - enet support
pcap-int.h - internal libpcap definitions
pcap-linux.c - Linux packet socket support
pcap-namedb.h - public libpcap name database definitions
pcap-nit.c - Network Interface Tap support
pcap-nit.h - Network Interface Tap definitions
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 - 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-pf.c - Ultrix and Digital/Tru64 UNIX Packet Filter support
pcap-pf.h - Ultrix and Digital/Tru64 UNIX Packet Filter definitions
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-win32.c - WinPcap capture support
pcap.3 - manual entry
pcap.c - pcap utility routines
pcap.h - public libpcap definitions
pf.h - OpenBSD DLT_PFLOG definitions
ppp.h - Point to Point Protocol definitions
rawss7.h - information on DLT_ types for SS7
savefile.c - offline support
scanner.l - filter string scanner
sll.h - definitions for Linux cooked mode fake link-layer header
snprintf.c - snprintf and vsnprintf for platforms that lack them
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.88 2001/01/18 04:05:12 guy Exp $ (LBL)
# @(#) $Header: /tcpdump/master/libpcap/Makefile.in,v 1.96.2.1 2003/12/15 01:42:23 guy Exp $ (LBL)
#
# Various configurable paths (remember to edit Makefile.in, not Makefile)
@ -44,7 +44,8 @@ VPATH = @srcdir@
CC = @CC@
CCOPT = @V_CCOPT@
INCLS = -I. @V_INCLS@
DEFS = @DEFS@
DEFS = @DEFS@ @V_DEFS@
LIBS = @V_LIBS@
# Standard CFLAGS
CFLAGS = $(CCOPT) $(INCLS) $(DEFS)
@ -70,23 +71,25 @@ YACC = @V_YACC@
$(CC) $(CFLAGS) -c $(srcdir)/$*.c
PSRC = pcap-@V_PCAP@.c
FSRC = fad-@V_FINDALLDEVS@.c
SSRC = @SSRC@
CSRC = pcap.c inet.c gencode.c optimize.c nametoaddr.c \
etherent.c savefile.c bpf_filter.c bpf_image.c bpf_dump.c
GENSRC = scanner.c grammar.c version.c
LIBOBJS = @LIBOBJS@
SRC = $(PSRC) $(CSRC) $(GENSRC)
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) $(CSRC:.c=.o) $(GENSRC:.c=.o) # $(LIBOBJS)
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
GENHDR = \
tokdefs.h
tokdefs.h version.h
TAGHDR = \
bpf/net/bpf.h
pcap-bpf.h
TAGFILES = \
$(SRC) $(HDR) $(TAGHDR)
@ -97,7 +100,7 @@ all: libpcap.a
libpcap.a: $(OBJ)
@rm -f $@
ar rc $@ $(OBJ)
ar rc $@ $(OBJ) $(LIBS)
$(RANLIB) $@
scanner.c: $(srcdir)/scanner.l
@ -107,6 +110,8 @@ scanner.c: $(srcdir)/scanner.l
scanner.o: scanner.c tokdefs.h
$(CC) $(CFLAGS) -c scanner.c
pcap.o: version.h
tokdefs.h: grammar.c
grammar.c: $(srcdir)/grammar.y
@rm -f grammar.c tokdefs.h
@ -121,13 +126,24 @@ grammar.o: grammar.c
version.o: version.c
$(CC) $(CFLAGS) -c version.c
snprintf.o: $(srcdir)/../tcpdump/missing/snprintf.c
$(CC) $(CFLAGS) -o $@ -c $(srcdir)/../tcpdump/missing/snprintf.c
snprintf.o: $(srcdir)/missing/snprintf.c
$(CC) $(CFLAGS) -o $@ -c $(srcdir)/missing/snprintf.c
version.c: $(srcdir)/VERSION
@rm -f $@
sed -e 's/.*/char pcap_version[] = "&";/' $(srcdir)/VERSION > $@
#
# NOTE: this really is supposed to be static; importing a string
# from a shared library does not work very well on many
# versions of UNIX (Solaris, Linux, and the BSDs, for example),
# so we make the version string static and return it from
# a function, which does work.
#
version.h: $(srcdir)/VERSION
@rm -f $@
sed -e 's/.*/static const char pcap_version_string[] = "libpcap version &";/' $(srcdir)/VERSION > $@
bpf_filter.c: $(srcdir)/bpf/net/bpf_filter.c
rm -f bpf_filter.c
ln -s $(srcdir)/bpf/net/bpf_filter.c bpf_filter.c
@ -143,12 +159,10 @@ install:
[ -d $(DESTDIR)$(includedir) ] || \
(mkdir -p $(DESTDIR)$(includedir); chmod 755 $(DESTDIR)$(includedir))
$(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)$(includedir)/net ] || \
(mkdir -p $(DESTDIR)$(includedir)/net; chmod 755 $(DESTDIR)$(includedir)/net)
$(INSTALL_DATA) $(srcdir)/bpf/net/bpf.h \
$(DESTDIR)$(includedir)/net/bpf.h
[ -d $(DESTDIR)$(mandir)/man3 ] || \
(mkdir -p $(DESTDIR)$(mandir)/man3; chmod 755 $(DESTDIR)$(mandir)/man3)
$(INSTALL_DATA) $(srcdir)/pcap.3 \
@ -157,8 +171,8 @@ install:
uninstall:
rm -f $(DESTDIR)$(libdir)/libpcap.a
rm -f $(DESTDIR)$(includedir)/pcap.h
rm -f $(DESTDIR)$(includedir)/pcap-bpf.h
rm -f $(DESTDIR)$(includedir)/pcap-namedb.h
rm -f $(DESTDIR)$(includedir)/net/bpf.h
rm -f $(DESTDIR)$(mandir)/man3/pcap.3
clean:
@ -166,7 +180,7 @@ clean:
distclean:
rm -f $(CLEANFILES) Makefile config.cache config.log config.status \
config.h gnuc.h os-proto.h net bpf_filter.c stamp-h stamp-h.in
config.h gnuc.h os-proto.h bpf_filter.c stamp-h stamp-h.in
tags: $(TAGFILES)
ctags -wtd $(TAGFILES)
@ -185,5 +199,5 @@ tar:
"rm -f ../$$name" ; \
rm -f ../$$name
depend: $(GENSRC) bpf_filter.c
depend: $(GENSRC) $(GENHDR) bpf_filter.c
./mkdep -c $(CC) $(DEFS) $(INCLS) $(SRC)

View File

@ -1,6 +1,6 @@
@(#) $Header: /tcpdump/master/libpcap/README,v 1.24 2001/06/05 03:45:55 guy Exp $ (LBL)
@(#) $Header: /tcpdump/master/libpcap/README,v 1.27.2.1 2003/11/15 23:29:19 guy Exp $ (LBL)
LIBPCAP 0.6.2
LIBPCAP 0.8
Now maintained by "The Tcpdump Group"
See www.tcpdump.org
@ -11,8 +11,8 @@ Anonymous CVS is available via:
(password "anoncvs")
cvs -d :pserver:tcpdump@cvs.tcpdump.org:/tcpdump/master checkout libpcap
Version 0.6.2 of LIBPCAP can be retrieved with the CVS tag "libpcap_0_6rel2":
cvs -d :pserver:tcpdump@cvs.tcpdump.org:/tcpdump/master checkout -r libpcap_0_6rel2 libpcap
Version 0.8 of LIBPCAP can be retrieved with the CVS tag "libpcap_0_8rel1":
cvs -d :pserver:tcpdump@cvs.tcpdump.org:/tcpdump/master checkout -r libpcap_0_8rel1 libpcap
Please send patches against the master copy to patches@tcpdump.org.
@ -32,12 +32,30 @@ system-dependent packet capture modules in each application.
Note well: this interface is new and is likely to change.
For some platforms there are README.{system} files that discuss issues
with the OS's interface for packet capture on those platforms, such as
how to enable support for that interface in the OS, if it's not built in
by default.
The libpcap interface supports a filtering mechanism based on the
architecture in the BSD packet filter. BPF is described in the 1993
Winter Usenix paper ``The BSD Packet Filter: A New Architecture for
User-level Packet Capture''. A compressed postscript version is in:
User-level Packet Capture''. A compressed PostScript version can be
found at
ftp://ftp.ee.lbl.gov/papers/bpf-usenix93.ps.Z.
ftp://ftp.ee.lbl.gov/papers/bpf-usenix93.ps.Z
or
http://www.tcpdump.org/papers/bpf-usenix93.ps.Z
and a gzipped version can be found at
http://www.tcpdump.org/papers/bpf-usenix93.ps.gz
A PDF version can be found at
http://www.tcpdump.org/papers/bpf-usenix93.pdf
Although most packet capture interfaces support in-kernel filtering,
libpcap utilizes in-kernel filtering only for the BPF interface.
@ -47,19 +65,30 @@ added overhead (especially, for selective filters). Ideally, libpcap
would translate BPF filters into a filter program that is compatible
with the underlying kernel subsystem, but this is not yet implemented.
BPF is standard in 4.4BSD, BSD/OS, NetBSD, FreeBSD, and OpenBSD. DEC OSF/1
uses the packetfilter interface but has been extended to accept BPF
filters (which libpcap utilizes). Also, you can add BPF filter support
to Ultrix using the kernel source and/or object patches available in:
BPF is standard in 4.4BSD, BSD/OS, NetBSD, FreeBSD, and OpenBSD. DEC
OSF/1/Digital UNIX/Tru64 UNIX uses the packetfilter interface but has
been extended to accept BPF filters (which libpcap utilizes). Also, you
can add BPF filter support to Ultrix using the kernel source and/or
object patches available in:
ftp://gatekeeper.dec.com/pub/DEC/net/bpfext42.tar.Z.
Problems, bugs, questions, desirable enhancements, etc.
should be sent to the address "tcpdump-workers@tcpdump.org".
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.
Source code contributions, etc. should be sent to the email address
"patches@tcpdump.org".
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
Current versions can be found at www.tcpdump.org
http://sourceforge.net/projects/libpcap/
Source code contributions, etc. should be sent to the email address
"patches@tcpdump.org", or submitted as patches on the SourceForge site
for libpcap.
Current versions can be found at www.tcpdump.org, or the SourceForge
site for libpcap.
- The TCPdump team

View File

@ -0,0 +1,46 @@
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,11 +1,20 @@
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, but, lacking an AIX machine on which to compile it, we don't
know whether the BPF support for AIX will compile.
that; it appears to compile and work on at least one AIX 4.3.3
machine.
If it doesn't, 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
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).
@ -22,39 +31,48 @@
to the "configure" script for libpcap.
(2) Also, 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:
If you use DLPI:
lslpp -l bos.rte.tty
(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:
bos.rte.tty 4.3.2.4 COMMITTED Base TTY Support and Commands
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.
(3) After compiling libpcap, you need to make sure that the DLPI driver
(2) After compiling libpcap, you need to make sure that the DLPI driver
is loaded. Type:
strload -q -d dlpi
strload -q -d dlpi
If the result is:
dlpi: yes
dlpi: yes
then the DLPI driver is loaded correctly.
If it is:
dlpi: no
dlpi: no
Then you need to type:
strload -f /etc/dlpi.conf
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

@ -0,0 +1,48 @@
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.
----------------------------------------------------------------------
Please submit bug reports via <support@endace.com>.
Please also visit our Web pages at:
http://www.endace.com/
http://dag.cs.waikato.ac.nz/
For more information about Endace DAG cards contact <sales@endace.com>.

246
contrib/libpcap/README.hpux Normal file
View File

@ -0,0 +1,246 @@
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.
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 +1 @@
0.7+multidlt
0.8.3

View File

@ -1,4 +1,4 @@
dnl @(#) $Header: /tcpdump/master/libpcap/aclocal.m4,v 1.75 2001/12/10 08:33:41 guy Exp $ (LBL)
dnl @(#) $Header: /tcpdump/master/libpcap/aclocal.m4,v 1.81.2.2 2003/11/16 09:45:51 guy Exp $ (LBL)
dnl
dnl Copyright (c) 1995, 1996, 1997, 1998
dnl The Regents of the University of California. All rights reserved.
@ -157,6 +157,51 @@ AC_DEFUN(AC_LBL_C_INIT,
fi
])
#
# Try compiling a sample of the type of code that appears in
# gencode.c with "inline", "__inline__", and "__inline".
#
# Autoconf's AC_C_INLINE, at least in autoconf 2.13, isn't good enough,
# as it just tests whether a function returning "int" can be inlined;
# at least some versions of HP's C compiler can inline that, but can't
# inline a function that returns a struct pointer.
#
AC_DEFUN(AC_LBL_C_INLINE,
[AC_MSG_CHECKING(for inline)
AC_CACHE_VAL(ac_cv_lbl_inline, [
ac_cv_lbl_inline=""
ac_lbl_cc_inline=no
for ac_lbl_inline in inline __inline__ __inline
do
AC_TRY_COMPILE(
[#define inline $ac_lbl_inline
static inline struct iltest *foo(void);
struct iltest {
int iltest1;
int iltest2;
};
static inline struct iltest *
foo()
{
static struct iltest xxx;
return &xxx;
}],,ac_lbl_cc_inline=yes,)
if test "$ac_lbl_cc_inline" = yes ; then
break;
fi
done
if test "$ac_lbl_cc_inline" = yes ; then
ac_cv_lbl_inline=$ac_lbl_inline
fi])
if test ! -z "$ac_cv_lbl_inline" ; then
AC_MSG_RESULT($ac_cv_lbl_inline)
else
AC_MSG_RESULT(no)
fi
AC_DEFINE_UNQUOTED(inline, $ac_cv_lbl_inline, [Define as token for inline if inlining supported])])
dnl
dnl Use pfopen.c if available and pfopen() not in standard libraries
dnl Require libpcap
@ -414,6 +459,31 @@ AC_DEFUN(AC_LBL_SOCKADDR_SA_LEN,
AC_DEFINE(HAVE_SOCKADDR_SA_LEN,1,[if struct sockaddr has sa_len])
fi])
dnl
dnl Checks to see if there's a sockaddr_storage structure
dnl
dnl usage:
dnl
dnl AC_LBL_SOCKADDR_STORAGE
dnl
dnl results:
dnl
dnl HAVE_SOCKADDR_STORAGE (defined)
dnl
AC_DEFUN(AC_LBL_SOCKADDR_STORAGE,
[AC_MSG_CHECKING(if sockaddr_storage struct exists)
AC_CACHE_VAL(ac_cv_lbl_has_sockaddr_storage,
AC_TRY_COMPILE([
# include <sys/types.h>
# include <sys/socket.h>],
[u_int i = sizeof (struct sockaddr_storage)],
ac_cv_lbl_has_sockaddr_storage=yes,
ac_cv_lbl_has_sockaddr_storage=no))
AC_MSG_RESULT($ac_cv_lbl_has_sockaddr_storage)
if test $ac_cv_lbl_has_sockaddr_storage = yes ; then
AC_DEFINE(HAVE_SOCKADDR_STORAGE,1,[if struct sockaddr_storage exists])
fi])
dnl
dnl Checks to see if the dl_hp_ppa_info_t struct has the HP-UX 11.00
dnl dl_module_id_1 member
@ -519,8 +589,39 @@ AC_DEFUN(AC_LBL_UNALIGNED_ACCESS,
AC_CACHE_VAL(ac_cv_lbl_unaligned_fail,
[case "$host_cpu" in
#
# These are CPU types where:
#
# the CPU faults on an unaligned access, but at least some
# OSes that support that CPU catch the fault and simulate
# the unaligned access (e.g., Alpha/{Digital,Tru64} UNIX) -
# the simulation is slow, so we don't want to use it;
#
# the CPU, I infer (from the old
#
# XXX: should also check that they don't do weird things (like on arm)
alpha*|arm*|hp*|mips*|sparc*|ia64)
#
# comment) doesn't fault on unaligned accesses, but doesn't
# do a normal unaligned fetch, either (e.g., presumably, ARM);
#
# for whatever reason, the test program doesn't work
# (this has been claimed to be the case for several of those
# CPUs - I don't know what the problem is; the problem
# was reported as "the test program dumps core" for SuperH,
# but that's what the test program is *supposed* to do -
# it dumps core before it writes anything, so the test
# for an empty output file should find an empty output
# file and conclude that unaligned accesses don't work).
#
# This run-time test won't work if you're cross-compiling, so
# in order to support cross-compiling for a particular CPU,
# we have to wire in the list of CPU types anyway, as far as
# I know, so perhaps we should just have a set of CPUs on
# which we know it doesn't work, a set of CPUs on which we
# 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)
ac_cv_lbl_unaligned_fail=yes
;;
@ -763,6 +864,9 @@ ac_cv___attribute__=yes,
ac_cv___attribute__=no)])
if test "$ac_cv___attribute__" = "yes"; then
AC_DEFINE(HAVE___ATTRIBUTE__, 1, [define if your compiler has __attribute__])
V_DEFS="$V_DEFS -D_U_=\"__attribute__((unused))\""
else
V_DEFS="$V_DEFS -D_U_=\"\""
fi
AC_MSG_RESULT($ac_cv___attribute__)
])

View File

@ -0,0 +1,87 @@
/*
* Copyright (c) 1997 Yen Yen Lim and North Dakota State University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Yen Yen Lim and
North Dakota State University
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @(#) $Header: /tcpdump/master/libpcap/atmuni31.h,v 1.1 2002/07/11 09:06:32 guy Exp $ (LBL)
*/
/* Based on UNI3.1 standard by ATM Forum */
/* ATM traffic types based on VPI=0 and (the following VCI */
#define PPC 0x05 /* Point-to-point signal msg */
#define BCC 0x02 /* Broadcast signal msg */
#define OAMF4SC 0x03 /* Segment OAM F4 flow cell */
#define OAMF4EC 0x04 /* End-to-end OAM F4 flow cell */
#define METAC 0x01 /* Meta signal msg */
#define ILMIC 0x10 /* ILMI msg */
/* Q.2931 signalling messages */
#define CALL_PROCEED 0x02 /* call proceeding */
#define CONNECT 0x07 /* connect */
#define CONNECT_ACK 0x0f /* connect_ack */
#define SETUP 0x05 /* setup */
#define RELEASE 0x4d /* release */
#define RELEASE_DONE 0x5a /* release_done */
#define RESTART 0x46 /* restart */
#define RESTART_ACK 0x4e /* restart ack */
#define STATUS 0x7d /* status */
#define STATUS_ENQ 0x75 /* status ack */
#define ADD_PARTY 0x80 /* add party */
#define ADD_PARTY_ACK 0x81 /* add party ack */
#define ADD_PARTY_REJ 0x82 /* add party rej */
#define DROP_PARTY 0x83 /* drop party */
#define DROP_PARTY_ACK 0x84 /* drop party ack */
/* Information Element Parameters in the signalling messages */
#define CAUSE 0x08 /* cause */
#define ENDPT_REF 0x54 /* endpoint reference */
#define AAL_PARA 0x58 /* ATM adaptation layer parameters */
#define TRAFF_DESCRIP 0x59 /* atm traffic descriptors */
#define CONNECT_ID 0x5a /* connection identifier */
#define QOS_PARA 0x5c /* quality of service parameters */
#define B_HIGHER 0x5d /* broadband higher layer information */
#define B_BEARER 0x5e /* broadband bearer capability */
#define B_LOWER 0x5f /* broadband lower information */
#define CALLING_PARTY 0x6c /* calling party number */
#define CALLED_PARTY 0x70 /* called party nmber */
#define Q2931 0x09
/* Q.2931 signalling general messages format */
#define PROTO_POS 0 /* offset of protocol discriminator */
#define CALL_REF_POS 2 /* offset of call reference value */
#define MSG_TYPE_POS 5 /* offset of message type */
#define MSG_LEN_POS 7 /* offset of mesage length */
#define IE_BEGIN_POS 9 /* offset of first information element */
/* format of signalling messages */
#define TYPE_POS 0
#define LEN_POS 2
#define FIELD_BEGIN_POS 4

View File

@ -4,7 +4,7 @@
*
* 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
* to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
* Berkeley Laboratory.
*
* Redistribution and use in source and binary forms, with or without
@ -39,10 +39,20 @@
*/
#if !(defined(lint) || defined(KERNEL) || defined(_KERNEL))
static const char rcsid[] =
"@(#) $Header: /tcpdump/master/libpcap/bpf/net/bpf_filter.c,v 1.35 2000/10/23 19:32:21 fenner Exp $ (LBL)";
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/bpf/net/bpf_filter.c,v 1.43.2.1 2003/11/15 23:26:49 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef WIN32
#include <pcap-stdinc.h>
#else /* WIN32 */
#include <sys/param.h>
#include <sys/types.h>
#include <sys/time.h>
@ -59,7 +69,9 @@ static const char rcsid[] =
# define MLEN(m) ((m)->m_len)
#endif
#include <net/bpf.h>
#endif /* WIN32 */
#include <pcap-bpf.h>
#if !defined(KERNEL) && !defined(_KERNEL)
#include <stdlib.h>
@ -69,14 +81,23 @@ static const char rcsid[] =
#define u_int32 bpf_u_int32
#ifndef LBL_ALIGN
#if defined(sparc) || defined(mips) || defined(ibm032) || \
defined(__alpha) || defined(__hpux)
/*
* 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))
@ -216,7 +237,7 @@ bpf_filter(pc, p, wirelen, buflen)
return 0;
#else
abort();
#endif
#endif
case BPF_RET|BPF_K:
return (u_int)pc->k;
@ -361,7 +382,7 @@ bpf_filter(pc, p, wirelen, buflen)
case BPF_LD|BPF_MEM:
A = mem[pc->k];
continue;
case BPF_LDX|BPF_MEM:
X = mem[pc->k];
continue;
@ -413,25 +434,25 @@ bpf_filter(pc, p, wirelen, buflen)
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;
@ -447,23 +468,23 @@ bpf_filter(pc, p, wirelen, buflen)
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;
@ -495,9 +516,9 @@ 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.
* 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).
* 'len' bytes long).
*
* The kernel needs to be able to verify an application's filter code.
* Otherwise, a bogus program could easily crash the system.
@ -512,7 +533,7 @@ bpf_validate(f, len)
for (i = 0; i < len; ++i) {
/*
* Check that that jumps are forward, and within
* Check that that jumps are forward, and within
* the code block.
*/
p = &f[i];
@ -530,7 +551,7 @@ bpf_validate(f, len)
* Check that memory operations use valid addresses.
*/
if ((BPF_CLASS(p->code) == BPF_ST ||
(BPF_CLASS(p->code) == BPF_LD &&
(BPF_CLASS(p->code) == BPF_LD &&
(p->code & 0xe0) == BPF_MEM)) &&
(p->k >= BPF_MEMWORDS || p->k < 0))
return 0;

View File

@ -19,17 +19,14 @@
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef lint
static const char rcsid[] =
"@(#) $Header: /tcpdump/master/libpcap/bpf_dump.c,v 1.12 2000/06/26 04:17:05 assar Exp $ (LBL)";
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/bpf_dump.c,v 1.13.2.1 2003/11/15 23:26:37 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <sys/types.h>
#include <sys/time.h>
#include <pcap.h>
#include <stdio.h>

View File

@ -20,17 +20,14 @@
*/
#ifndef lint
static const char rcsid[] =
"@(#) $Header: /tcpdump/master/libpcap/bpf_image.c,v 1.24 2000/07/11 00:37:04 assar Exp $ (LBL)";
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/bpf_image.c,v 1.25.2.1 2003/11/15 23:26:38 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <sys/types.h>
#include <sys/time.h>
#include <stdio.h>
#include <string.h>

File diff suppressed because it is too large Load Diff

View File

@ -3,9 +3,6 @@
/* Define to empty if the keyword does not work. */
#undef const
/* Define as __inline if that's what the C compiler calls it. */
#undef inline
/* Long story short: aclocal.m4 depends on autoconf 2.13
* implementation details wrt "const"; newer versions
* have different implementation details so for now we
@ -17,12 +14,18 @@
/* Define if you have the ether_hostton function. */
#undef HAVE_ETHER_HOSTTON
/* Define if you have the snprintf function. */
#undef HAVE_SNPRINTF
/* Define if you have the strerror function. */
#undef HAVE_STRERROR
/* Define if you have the strlcpy function. */
#undef HAVE_STRLCPY
/* Define if you have the vsnprintf function. */
#undef HAVE_VSNPRINTF
/* Define if you have the <ifaddrs.h> header file. */
#undef HAVE_IFADDRS_H
@ -47,6 +50,9 @@
/* needed on HP-UX */
#undef _HPUX_SOURCE
/* Define as token for inline if inlining supported */
#undef inline
/* define if your compiler has __attribute__ */
#undef HAVE___ATTRIBUTE__
@ -83,6 +89,9 @@
/* define if you have a /proc/net/dev */
#undef HAVE_PROC_NET_DEV
/* define if you have a DAG API */
#undef HAVE_DAG_API
/* define on AIX to get certain functions */
#undef _SUN
@ -104,6 +113,9 @@
/* if struct sockaddr has sa_len */
#undef HAVE_SOCKADDR_SA_LEN
/* if struct sockaddr_storage exists */
#undef HAVE_SOCKADDR_STORAGE
/* if ppa_info_t_dl_module_id exists */
#undef HAVE_HP_PPA_INFO_T_DL_MODULE_ID_1

View File

@ -1,9 +1,9 @@
#! /bin/sh
# Configuration validation subroutine script.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
# Free Software Foundation, Inc.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
# 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
timestamp='2001-04-20'
timestamp='2003-11-03'
# This file is (in principle) common to ALL GNU software.
# The presence of a machine in this file suggests that SOME GNU software
@ -29,7 +29,8 @@ timestamp='2001-04-20'
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Please send patches to <config-patches@gnu.org>.
# Please send patches to <config-patches@gnu.org>. Submit a context
# diff and a properly formatted ChangeLog entry.
#
# Configuration subroutine to validate and canonicalize a configuration type.
# Supply the specified configuration type as an argument.
@ -117,7 +118,8 @@ esac
# Here we must recognize all the valid KERNEL-OS combinations.
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in
nto-qnx* | linux-gnu* | storm-chaos* | os2-emx*)
nto-qnx* | linux-gnu* | linux-dietlibc | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \
kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*)
os=-$maybe_os
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
;;
@ -157,6 +159,14 @@ case $os in
os=-vxworks
basic_machine=$1
;;
-chorusos*)
os=-chorusos
basic_machine=$1
;;
-chorusrdb)
os=-chorusrdb
basic_machine=$1
;;
-hiux*)
os=-hiuxwe2
;;
@ -215,26 +225,50 @@ esac
case $basic_machine in
# Recognize the basic CPU types without company name.
# Some are omitted here because they have special meanings below.
tahoe | i860 | ia64 | m32r | m68k | m68000 | m88k | ns32k | arc \
| arm | arme[lb] | arm[bl]e | armv[2345] | armv[345][lb] | strongarm | xscale \
| pyramid | mn10200 | mn10300 | tron | a29k \
| 580 | i960 | h8300 \
| x86 | ppcbe | mipsbe | mipsle | shbe | shle \
| hppa | hppa1.0 | hppa1.1 | hppa2.0 | hppa2.0w | hppa2.0n \
| hppa64 \
| alpha | alphaev[4-8] | alphaev56 | alphapca5[67] \
| alphaev6[78] \
| we32k | ns16k | clipper | i370 | sh | sh[34] \
| powerpc | powerpcle \
| 1750a | dsp16xx | pdp10 | pdp11 \
| mips16 | mips64 | mipsel | mips64el \
| mips64orion | mips64orionel | mipstx39 | mipstx39el \
| mips64vr4300 | mips64vr4300el | mips64vr4100 | mips64vr4100el \
| mips64vr5000 | miprs64vr5000el | mcore | s390 | s390x \
| sparc | sparclet | sparclite | sparc64 | sparcv9 | sparcv9b \
| v850 | c4x \
| thumb | d10v | d30v | fr30 | avr | openrisc | tic80 \
| pj | pjl | h8500)
1750a | 580 \
| a29k \
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
| am33_2.0 \
| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
| c4x | clipper \
| d10v | d30v | dlx | dsp16xx \
| fr30 | frv \
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
| i370 | i860 | i960 | ia64 \
| ip2k | iq2000 \
| m32r | m68000 | m68k | m88k | mcore \
| mips | mipsbe | mipseb | mipsel | mipsle \
| mips16 \
| mips64 | mips64el \
| mips64vr | mips64vrel \
| mips64orion | mips64orionel \
| mips64vr4100 | mips64vr4100el \
| mips64vr4300 | mips64vr4300el \
| mips64vr5000 | mips64vr5000el \
| mipsisa32 | mipsisa32el \
| mipsisa32r2 | mipsisa32r2el \
| mipsisa64 | mipsisa64el \
| mipsisa64r2 | mipsisa64r2el \
| mipsisa64sb1 | mipsisa64sb1el \
| mipsisa64sr71k | mipsisa64sr71kel \
| mipstx39 | mipstx39el \
| mn10200 | mn10300 \
| msp430 \
| ns16k | ns32k \
| openrisc | or32 \
| pdp10 | pdp11 | pj | pjl \
| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
| pyramid \
| sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
| sh64 | sh64le \
| sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \
| strongarm \
| tahoe | thumb | tic4x | tic80 | tron \
| v850 | v850e \
| we32k \
| x86 | xscale | xstormy16 | xtensa \
| z8k)
basic_machine=$basic_machine-unknown
;;
m6811 | m68hc11 | m6812 | m68hc12)
@ -242,7 +276,7 @@ case $basic_machine in
basic_machine=$basic_machine-unknown
os=-none
;;
m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | z8k | v70 | w65)
m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
;;
# We use `pc' rather than `unknown'
@ -257,31 +291,61 @@ case $basic_machine in
exit 1
;;
# Recognize the basic CPU types with company name.
# FIXME: clean up the formatting here.
vax-* | tahoe-* | i*86-* | i860-* | ia64-* | m32r-* | m68k-* | m68000-* \
| m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | c[123]* \
| arm-* | armbe-* | armle-* | armv*-* | strongarm-* | xscale-* \
| mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \
| power-* | none-* | 580-* | cray2-* | h8300-* | h8500-* | i960-* \
| xmp-* | ymp-* \
| x86-* | ppcbe-* | mipsbe-* | mipsle-* | shbe-* | shle-* \
| hppa-* | hppa1.0-* | hppa1.1-* | hppa2.0-* | hppa2.0w-* \
| hppa2.0n-* | hppa64-* \
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphapca5[67]-* \
| alphaev6[78]-* \
| we32k-* | cydra-* | ns16k-* | pn-* | np1-* | xps100-* \
| clipper-* | orion-* \
| sparclite-* | pdp10-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \
| sparc64-* | sparcv9-* | sparcv9b-* | sparc86x-* \
| mips16-* | mips64-* | mipsel-* \
| mips64el-* | mips64orion-* | mips64orionel-* \
| mips64vr4100-* | mips64vr4100el-* | mips64vr4300-* | mips64vr4300el-* \
| mipstx39-* | mipstx39el-* | mcore-* \
| f30[01]-* | f700-* | s390-* | s390x-* | sv1-* | t3e-* \
| [cjt]90-* \
| m88110-* | m680[01234]0-* | m683?2-* | m68360-* | z8k-* | d10v-* \
| thumb-* | v850-* | d30v-* | tic30-* | tic80-* | c30-* | fr30-* \
| bs2000-* | tic54x-* | c54x-* | x86_64-* | pj-* | pjl-*)
580-* \
| a29k-* \
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \
| avr-* \
| bs2000-* \
| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
| clipper-* | cydra-* \
| d10v-* | d30v-* | dlx-* \
| elxsi-* \
| f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
| h8300-* | h8500-* \
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
| i*86-* | i860-* | i960-* | ia64-* \
| ip2k-* | iq2000-* \
| m32r-* \
| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
| m88110-* | m88k-* | mcore-* \
| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
| mips16-* \
| mips64-* | mips64el-* \
| mips64vr-* | mips64vrel-* \
| mips64orion-* | mips64orionel-* \
| mips64vr4100-* | mips64vr4100el-* \
| mips64vr4300-* | mips64vr4300el-* \
| mips64vr5000-* | mips64vr5000el-* \
| mipsisa32-* | mipsisa32el-* \
| mipsisa32r2-* | mipsisa32r2el-* \
| mipsisa64-* | mipsisa64el-* \
| mipsisa64r2-* | mipsisa64r2el-* \
| mipsisa64sb1-* | mipsisa64sb1el-* \
| mipsisa64sr71k-* | mipsisa64sr71kel-* \
| mipstx39-* | mipstx39el-* \
| msp430-* \
| none-* | np1-* | nv1-* | ns16k-* | ns32k-* \
| orion-* \
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
| pyramid-* \
| romp-* | rs6000-* \
| sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
| sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \
| sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
| tahoe-* | thumb-* \
| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
| tron-* \
| v850-* | v850e-* | vax-* \
| we32k-* \
| x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \
| xtensa-* \
| ymp-* \
| z8k-*)
;;
# Recognize the various machine names and aliases which stand
# for a CPU type and a company and sometimes even an OS.
@ -313,6 +377,9 @@ case $basic_machine in
basic_machine=a29k-none
os=-bsd
;;
amd64)
basic_machine=x86_64-pc
;;
amdahl)
basic_machine=580-amdahl
os=-sysv
@ -344,6 +411,10 @@ case $basic_machine in
basic_machine=ns32k-sequent
os=-dynix
;;
c90)
basic_machine=c90-cray
os=-unicos
;;
convex-c1)
basic_machine=c1-convex
os=-bsd
@ -364,16 +435,8 @@ case $basic_machine in
basic_machine=c38-convex
os=-bsd
;;
cray | ymp)
basic_machine=ymp-cray
os=-unicos
;;
cray2)
basic_machine=cray2-cray
os=-unicos
;;
[cjt]90)
basic_machine=${basic_machine}-cray
cray | j90)
basic_machine=j90-cray
os=-unicos
;;
crds | unos)
@ -388,6 +451,14 @@ case $basic_machine in
decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
basic_machine=mips-dec
;;
decsystem10* | dec10*)
basic_machine=pdp10-dec
os=-tops10
;;
decsystem20* | dec20*)
basic_machine=pdp10-dec
os=-tops20
;;
delta | 3300 | motorola-3300 | motorola-delta \
| 3300-motorola | delta-motorola)
basic_machine=m68k-motorola
@ -568,14 +639,6 @@ case $basic_machine in
basic_machine=m68k-atari
os=-mint
;;
mipsel*-linux*)
basic_machine=mipsel-unknown
os=-linux-gnu
;;
mips*-linux*)
basic_machine=mips-unknown
os=-linux-gnu
;;
mips3*-*)
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
;;
@ -590,6 +653,10 @@ case $basic_machine in
basic_machine=m68k-rom68k
os=-coff
;;
morphos)
basic_machine=powerpc-unknown
os=-morphos
;;
msdos)
basic_machine=i386-pc
os=-msdos
@ -662,6 +729,10 @@ case $basic_machine in
np1)
basic_machine=np1-gould
;;
nv1)
basic_machine=nv1-cray
os=-unicosmp
;;
nsr-tandem)
basic_machine=nsr-tandem
;;
@ -669,6 +740,14 @@ case $basic_machine in
basic_machine=hppa1.1-oki
os=-proelf
;;
or32 | or32-*)
basic_machine=or32-unknown
os=-coff
;;
os400)
basic_machine=powerpc-ibm
os=-os400
;;
OSE68000 | ose68000)
basic_machine=m68000-ericsson
os=-ose
@ -691,42 +770,58 @@ case $basic_machine in
pbb)
basic_machine=m68k-tti
;;
pc532 | pc532-*)
pc532 | pc532-*)
basic_machine=ns32k-pc532
;;
pentium | p5 | k5 | k6 | nexgen)
pentium | p5 | k5 | k6 | nexgen | viac3)
basic_machine=i586-pc
;;
pentiumpro | p6 | 6x86 | athlon)
pentiumpro | p6 | 6x86 | athlon | athlon_*)
basic_machine=i686-pc
;;
pentiumii | pentium2)
pentiumii | pentium2 | pentiumiii | pentium3)
basic_machine=i686-pc
;;
pentium-* | p5-* | k5-* | k6-* | nexgen-*)
pentium4)
basic_machine=i786-pc
;;
pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pentiumpro-* | p6-* | 6x86-* | athlon-*)
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pentiumii-* | pentium2-*)
pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pentium4-*)
basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pn)
basic_machine=pn-gould
;;
power) basic_machine=power-ibm
;;
ppc) basic_machine=powerpc-unknown
;;
;;
ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppcle | powerpclittle | ppc-le | powerpc-little)
basic_machine=powerpcle-unknown
;;
;;
ppcle-* | powerpclittle-*)
basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppc64) basic_machine=powerpc64-unknown
;;
ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppc64le | powerpc64little | ppc64-le | powerpc64-little)
basic_machine=powerpc64le-unknown
;;
ppc64le-* | powerpc64little-*)
basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ps2)
basic_machine=i386-ibm
;;
@ -744,10 +839,26 @@ case $basic_machine in
rtpc | rtpc-*)
basic_machine=romp-ibm
;;
s390 | s390-*)
basic_machine=s390-ibm
;;
s390x | s390x-*)
basic_machine=s390x-ibm
;;
sa29200)
basic_machine=a29k-amd
os=-udi
;;
sb1)
basic_machine=mipsisa64sb1-unknown
;;
sb1el)
basic_machine=mipsisa64sb1el-unknown
;;
sei)
basic_machine=mips-sei
os=-seiux
;;
sequent)
basic_machine=i386-sequent
;;
@ -755,7 +866,10 @@ case $basic_machine in
basic_machine=sh-hitachi
os=-hms
;;
sparclite-wrs)
sh64)
basic_machine=sh64-unknown
;;
sparclite-wrs | simso-wrs)
basic_machine=sparclite-wrs
os=-vxworks
;;
@ -822,22 +936,42 @@ case $basic_machine in
os=-dynix
;;
t3e)
basic_machine=t3e-cray
basic_machine=alphaev5-cray
os=-unicos
;;
t90)
basic_machine=t90-cray
os=-unicos
;;
tic54x | c54x*)
basic_machine=tic54x-unknown
os=-coff
;;
tic55x | c55x*)
basic_machine=tic55x-unknown
os=-coff
;;
tic6x | c6x*)
basic_machine=tic6x-unknown
os=-coff
;;
tx39)
basic_machine=mipstx39-unknown
;;
tx39el)
basic_machine=mipstx39el-unknown
;;
toad1)
basic_machine=pdp10-xkl
os=-tops20
;;
tower | tower-32)
basic_machine=m68k-ncr
;;
tpf)
basic_machine=s390x-ibm
os=-tpf
;;
udi29k)
basic_machine=a29k-amd
os=-udi
@ -859,8 +993,8 @@ case $basic_machine in
os=-vms
;;
vpp*|vx|vx-*)
basic_machine=f301-fujitsu
;;
basic_machine=f301-fujitsu
;;
vxworks960)
basic_machine=i960-wrs
os=-vxworks
@ -881,13 +1015,13 @@ case $basic_machine in
basic_machine=hppa1.1-winbond
os=-proelf
;;
xmp)
basic_machine=xmp-cray
os=-unicos
;;
xps | xps100)
xps | xps100)
basic_machine=xps100-honeywell
;;
ymp)
basic_machine=ymp-cray
os=-unicos
;;
z8k-*-coff)
basic_machine=z8k-unknown
os=-sim
@ -908,13 +1042,6 @@ case $basic_machine in
op60c)
basic_machine=hppa1.1-oki
;;
mips)
if [ x$os = x-linux-gnu ]; then
basic_machine=mips-unknown
else
basic_machine=mips-mips
fi
;;
romp)
basic_machine=romp-ibm
;;
@ -934,13 +1061,16 @@ case $basic_machine in
we32k)
basic_machine=we32k-att
;;
sh3 | sh4)
sh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele)
basic_machine=sh-unknown
;;
sh64)
basic_machine=sh64-unknown
;;
sparc | sparcv9 | sparcv9b)
basic_machine=sparc-sun
;;
cydra)
cydra)
basic_machine=cydra-cydrome
;;
orion)
@ -955,10 +1085,6 @@ case $basic_machine in
pmac | pmac-mpw)
basic_machine=powerpc-apple
;;
c4x*)
basic_machine=c4x-none
os=-coff
;;
*-unknown)
# Make sure to match an already-canonicalized machine name.
;;
@ -1014,15 +1140,19 @@ case $os in
| -aos* \
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
| -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
| -hiux* | -386bsd* | -knetbsd* | -netbsd* | -openbsd* | -kfreebsd* | -freebsd* | -riscix* \
| -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
| -chorusos* | -chorusrdb* \
| -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
| -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
| -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \
| -mingw32* | -linux-gnu* | -linux-uclibc* | -uxpv* | -beos* | -mpeix* | -udk* \
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* | -os2*)
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
-qnx*)
@ -1034,8 +1164,10 @@ case $os in
;;
esac
;;
-nto-qnx*)
;;
-nto*)
os=-nto-qnx
os=`echo $os | sed -e 's|nto|nto-qnx|'`
;;
-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
| -windows* | -osx | -abug | -netware* | -os9* | -beos* \
@ -1044,6 +1176,9 @@ case $os in
-mac*)
os=`echo $os | sed -e 's|mac|macos|'`
;;
-linux-dietlibc)
os=-linux-dietlibc
;;
-linux*)
os=`echo $os | sed -e 's|linux|linux-gnu|'`
;;
@ -1056,6 +1191,9 @@ case $os in
-opened*)
os=-openedition
;;
-os400*)
os=-os400
;;
-wince*)
os=-wince
;;
@ -1074,14 +1212,20 @@ case $os in
-acis*)
os=-aos
;;
-atheos*)
os=-atheos
;;
-386bsd)
os=-bsd
;;
-ctix* | -uts*)
os=-sysv
;;
-nova*)
os=-rtmk-nova
;;
-ns2 )
os=-nextstep2
os=-nextstep2
;;
-nsk*)
os=-nsk
@ -1093,6 +1237,9 @@ case $os in
-sinix*)
os=-sysv4
;;
-tpf*)
os=-tpf
;;
-triton*)
os=-sysv3
;;
@ -1120,8 +1267,14 @@ case $os in
-xenix)
os=-xenix
;;
-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
os=-mint
-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
os=-mint
;;
-aros*)
os=-aros
;;
-kaos*)
os=-kaos
;;
-none)
;;
@ -1154,10 +1307,14 @@ case $basic_machine in
arm*-semi)
os=-aout
;;
c4x-* | tic4x-*)
os=-coff
;;
# This must come before the *-dec entry.
pdp10-*)
os=-tops20
;;
pdp11-*)
pdp11-*)
os=-none
;;
*-dec | vax-*)
@ -1184,6 +1341,9 @@ case $basic_machine in
mips*-*)
os=-elf
;;
or32-*)
os=-coff
;;
*-tti) # must be before sparc entry or we get the wrong os.
os=-sysv3
;;
@ -1247,19 +1407,19 @@ case $basic_machine in
*-next)
os=-nextstep3
;;
*-gould)
*-gould)
os=-sysv
;;
*-highlevel)
*-highlevel)
os=-bsd
;;
*-encore)
os=-bsd
;;
*-sgi)
*-sgi)
os=-irix
;;
*-siemens)
*-siemens)
os=-sysv4
;;
*-masscomp)
@ -1328,10 +1488,16 @@ case $basic_machine in
-mvs* | -opened*)
vendor=ibm
;;
-os400*)
vendor=ibm
;;
-ptx*)
vendor=sequent
;;
-vxsim* | -vxworks*)
-tpf*)
vendor=ibm
;;
-vxsim* | -vxworks* | -windiss*)
vendor=wrs
;;
-aux*)
@ -1346,6 +1512,9 @@ case $basic_machine in
-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
vendor=atari
;;
-vos*)
vendor=stratus
;;
esac
basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
;;

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.94 2001/12/10 08:33:42 guy Exp $ (LBL)
dnl @(#) $Header: /tcpdump/master/libpcap/configure.in,v 1.100.2.4 2004/03/28 21:43:34 fenner Exp $ (LBL)
dnl
dnl Copyright (c) 1994, 1995, 1996, 1997
dnl The Regents of the University of California. All rights reserved.
@ -6,13 +6,14 @@ dnl
dnl Process this file with autoconf to produce a configure script.
dnl
AC_REVISION($Revision: 1.94 $)
AC_REVISION($Revision: 1.100.2.4 $)
AC_PREREQ(2.50)
AC_INIT(pcap.c)
AC_CANONICAL_SYSTEM
AC_LBL_C_INIT(V_CCOPT, V_INCLS)
AC_C_INLINE
AC_LBL_C_INIT(V_CCOPT, V_INCLS, V_LIBS)
AC_LBL_C_INLINE
AC_C___ATTRIBUTE__
AC_LBL_CHECK_TYPE(u_int8_t, u_char)
@ -25,12 +26,21 @@ dnl in "AC_LBL_FIXINCLUDES" in "aclocal.m4" uses it, so we have to
dnl test for it and set "HAVE_SYS_IOCCOM_H" if we have it, otherwise
dnl "AC_LBL_FIXINCLUDES" won't work on some platforms such as Solaris.
dnl
AC_CHECK_HEADERS(sys/ioccom.h sys/sockio.h ifaddrs.h limits.h netinet/if_ether.h)
AC_CHECK_HEADERS(sys/ioccom.h sys/sockio.h ifaddrs.h limits.h)
AC_CHECK_HEADERS(netinet/if_ether.h, , , [#include <sys/types.h>
#include <sys/socket.h>])
AC_LBL_FIXINCLUDES
AC_CHECK_FUNCS(ether_hostton strerror strlcpy)
needsnprintf=no
AC_CHECK_FUNCS(vsnprintf snprintf,,
[needsnprintf=yes])
if test $needsnprintf = yes; then
AC_LIBOBJ(snprintf)
fi
dnl to pacify those who hate protochain insn
AC_MSG_CHECKING(if --disable-protochain option is specified)
AC_ARG_ENABLE(protochain, [ --disable-protochain disable \"protochain\" insn])
@ -70,12 +80,19 @@ elif test -r /dev/nit ; then
V_PCAP=snit
elif test -r /usr/include/sys/net/nit.h ; then
V_PCAP=nit
elif test -r /usr/include/net/raw.h ; then
V_PCAP=snoop
elif test -r /usr/include/sys/dlpi.h ; then
V_PCAP=dlpi
elif test -r /usr/include/linux/socket.h ; then
V_PCAP=linux
elif test -r /usr/include/net/raw.h ; then
V_PCAP=snoop
elif test -r /usr/include/odmi.h ; then
#
# On AIX, the BPF devices might not yet be present - they're
# created the first time libpcap runs after booting.
# We check for odmi.h instead.
#
V_PCAP=bpf
elif test -r /usr/include/sys/dlpi.h ; then
V_PCAP=dlpi
elif test -c /dev/bpf0 ; then # check again in case not readable
V_PCAP=bpf
elif test -c /dev/enet ; then # check again in case not readable
@ -87,6 +104,67 @@ else
fi
AC_MSG_RESULT($V_PCAP)
dnl
dnl Now figure out how we get a list of interfaces and addresses.
dnl
AC_CHECK_FUNC(getifaddrs,[
#
# We have "getifaddrs()", so we use that to get the list
#
V_FINDALLDEVS=getad
],[
#
# Well, we don't have "getifaddrs()", so we have to use some
# other mechanism; determine what that mechanism is.
#
# The first thing we use is the type of capture mechanism,
# which is somewhat of a proxy for the OS we're using.
#
case "$V_PCAP" in
dlpi)
#
# This might be Solaris 8 or later, with SIOCGLIFCONF,
# or it might be some other OS, with just SIOCGIFCONF.
#
AC_MSG_CHECKING(whether we have SIOCGLIFCONF)
AC_CACHE_VAL(ac_cv_lbl_have_siocglifconf,
AC_TRY_COMPILE(
[#include <sys/param.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/sockio.h>],
[ioctl(0, SIOCGLIFCONF, (char *)0);],
ac_cv_lbl_have_siocglifconf=yes,
ac_cv_lbl_have_siocglifconf=no))
AC_MSG_RESULT($ac_cv_lbl_have_siocglifconf)
if test $ac_cv_lbl_have_siocglifconf = yes ; then
V_FINDALLDEVS=glifc
else
V_FINDALLDEVS=gifc
fi
;;
null)
#
# We can't capture, so we can't open any capture
# devices, so we won't return any interfaces.
#
V_FINDALLDEVS=null
;;
*)
#
# Assume we just have SIOCGIFCONF.
# (XXX - on at least later Linux kernels, there's
# another mechanism, and we should be using that
# instead.)
#
V_FINDALLDEVS=gifc
;;
esac])
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
@ -149,6 +227,10 @@ linux)
AC_LBL_TPACKET_STATS
;;
dag)
V_DEFS="$V_DEFS -DDAG_ONLY"
;;
null)
AC_MSG_WARN(cannot determine packet capture interface)
AC_MSG_WARN((see the INSTALL doc for more info))
@ -167,6 +249,99 @@ if test $ac_cv_lbl_proc_net_dev = yes; then
fi
AC_MSG_RESULT($ac_cv_lbl_proc_net_dev)
AC_ARG_WITH(dag, [ --with-dag[=DIR] include DAG support (located in directory DIR, if supplied). [default=yes, on BSD and Linux, if present]],
[
if test "$withval" = no
then
want_dag=no
elif test "$withval" = yes
then
want_dag=yes
dag_root=
else
want_dag=yes
dag_root=$withval
fi
],[
#
# Use DAG API if present, otherwise don't
#
want_dag=ifpresent
dag_root=/root/dag
])
ac_cv_lbl_dag_api=no
case "$V_PCAP" in
linux|bpf|dag)
#
# We support the DAG API on Linux or BSD, or if we're building a
# DAG-only libpcap.
#
;;
*)
#
# If the user explicitly requested DAG, tell them it's not
# supported.
#
# If they expressed no preference, don't include it.
#
if test $want_dag = yes; then
AC_MSG_ERROR(DAG support only available with 'linux' 'bpf' and 'dag' packet capture types)
elif test $want_dag = yes; then
want_dag=no
fi
;;
esac
if test "$with_dag" != no; then
AC_MSG_CHECKING(whether we have DAG API)
if test -z "$dag_root"; then
dag_root=$srcdir/../dag
fi
if test -r "$dag_root/tools" -a -r "$dag_root/include"; then
dag_tools_dir="$dag_root/tools"
dag_include_dir="$dag_root/include"
else
dag_tools_dir="$dag_root"
dag_include_dir="$dag_root"
fi
ac_cv_lbl_dag_api=no
if test -r "$dag_include_dir/dagapi.h" -a -r "$dag_tools_dir/dagapi.o" -a -r "$dag_tools_dir/dagopts.o"; then
V_INCLS="$V_INCLS -I $dag_include_dir"
V_LIBS="$V_LIBS $dag_tools_dir/dagapi.o $dag_tools_dir/dagopts.o"
if test "$V_PCAP" != dag ; then
SSRC="pcap-dag.c"
fi
ac_cv_lbl_dag_api=yes
fi
if test -r "$dag_root/lib/dagreg.c"; then # DAG 2.5.x
if test -r "$dag_tools_dir/dagreg.o"; then
V_LIBS="$V_LIBS $dag_tools_dir/dagreg.o"
else
ac_cv_lbl_dag_api=no
fi
fi
dag_version=
if test $ac_cv_lbl_dag_api = yes -a -r "$dag_root/VERSION"; then
dag_version=" (`cat $dag_root/VERSION`)"
fi
AC_MSG_RESULT($ac_cv_lbl_dag_api$dag_version)
if test $ac_cv_lbl_dag_api = no; then
if test "$want_dag" = yes; then
AC_MSG_ERROR(DAG API not found under directory $dag_root; use --without-dag)
fi
else
AC_DEFINE(HAVE_DAG_API, 1, [define if you have a DAG API])
fi
fi
if test "$V_PCAP" = dag -a "$ac_cv_lbl_dag_api" = no; then
AC_MSG_ERROR(Specifying the capture type as 'dag' requires the DAG API to be present; use --with-dag=DIR)
fi
AC_LBL_LEX_AND_YACC(V_LEX, V_YACC, pcap_)
if test "$V_LEX" = lex ; then
# Some versions of lex can't handle the definitions section of scanner.l .
@ -232,6 +407,8 @@ AC_LBL_DEVEL(V_CCOPT)
AC_LBL_SOCKADDR_SA_LEN
AC_LBL_SOCKADDR_STORAGE
AC_LBL_HP_PPA_INFO_T_DL_MODULE_ID_1
AC_LBL_UNALIGNED_ACCESS
@ -240,11 +417,15 @@ rm -f net
ln -s ${srcdir}/bpf/net net
AC_SUBST(V_CCOPT)
AC_SUBST(V_DEFS)
AC_SUBST(V_INCLS)
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_PROG_INSTALL

View File

@ -20,8 +20,8 @@
*/
#ifndef lint
static const char rcsid[] =
"@(#) $Header: /tcpdump/master/libpcap/etherent.c,v 1.21 2000/07/11 00:37:04 assar Exp $ (LBL)";
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/etherent.c,v 1.21.6.1 2003/11/15 23:26:38 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H

243
contrib/libpcap/fad-getad.c Normal file
View File

@ -0,0 +1,243 @@
/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */
/*
* Copyright (c) 1994, 1995, 1996, 1997, 1998
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Computer Systems
* Engineering Group at Lawrence Berkeley Laboratory.
* 4. Neither the name of the University nor of the Laboratory may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef lint
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/fad-getad.c,v 1.7.2.2 2004/03/11 23:04:52 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <net/if.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <ifaddrs.h>
#include "pcap-int.h"
#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
/*
* This is fun.
*
* In older BSD systems, socket addresses were fixed-length, and
* "sizeof (struct sockaddr)" gave the size of the structure.
* All addresses fit within a "struct sockaddr".
*
* In newer BSD systems, the socket address is variable-length, and
* there's an "sa_len" field giving the length of the structure;
* this allows socket addresses to be longer than 2 bytes of family
* and 14 bytes of data.
*
* Some commercial UNIXes use the old BSD scheme, some use the RFC 2553
* variant of the old BSD scheme (with "struct sockaddr_storage" rather
* than "struct sockaddr"), and some use the new BSD scheme.
*
* Some versions of GNU libc use neither scheme, but has an "SA_LEN()"
* macro that determines the size based on the address family. Other
* versions don't have "SA_LEN()" (as it was in drafts of RFC 2553
* but not in the final version). On the latter systems, we explicitly
* check the AF_ type to determine the length; we assume that on
* all those systems we have "struct sockaddr_storage".
*/
#ifndef SA_LEN
#ifdef HAVE_SOCKADDR_SA_LEN
#define SA_LEN(addr) ((addr)->sa_len)
#else /* HAVE_SOCKADDR_SA_LEN */
#ifdef HAVE_SOCKADDR_STORAGE
static size_t
get_sa_len(struct sockaddr *addr)
{
switch (addr->sa_family) {
#ifdef AF_INET
case AF_INET:
return (sizeof (struct sockaddr_in));
#endif
#ifdef AF_INET6
case AF_INET6:
return (sizeof (struct sockaddr_in6));
#endif
default:
return (sizeof (struct sockaddr));
}
}
#define SA_LEN(addr) (get_sa_len(addr))
#else /* HAVE_SOCKADDR_STORAGE */
#define SA_LEN(addr) (sizeof (struct sockaddr))
#endif /* HAVE_SOCKADDR_STORAGE */
#endif /* HAVE_SOCKADDR_SA_LEN */
#endif /* SA_LEN */
/*
* Get a list of all interfaces that are up and that we can open.
* Returns -1 on error, 0 otherwise.
* The list, as returned through "alldevsp", may be null if no interfaces
* were up and could be opened.
*
* This is the implementation used on platforms that have "getifaddrs()".
*/
int
pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
{
pcap_if_t *devlist = NULL;
struct ifaddrs *ifap, *ifa;
struct sockaddr *addr, *netmask, *broadaddr, *dstaddr;
size_t addr_size, broadaddr_size, dstaddr_size;
int ret = 0;
/*
* Get the list of interface addresses.
*
* Note: this won't return information about interfaces
* with no addresses; are there any such interfaces
* that would be capable of receiving packets?
* (Interfaces incapable of receiving packets aren't
* very interesting from libpcap's point of view.)
*
* LAN interfaces will probably have link-layer
* addresses; I don't know whether all implementations
* of "getifaddrs()" now, or in the future, will return
* those.
*/
if (getifaddrs(&ifap) != 0) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"getifaddrs: %s", pcap_strerror(errno));
return (-1);
}
for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
/*
* Is this interface up?
*/
if (!(ifa->ifa_flags & IFF_UP)) {
/*
* No, so don't add it to the list.
*/
continue;
}
/*
* "ifa_addr" was apparently null on at least one
* interface on some system.
*
* "ifa_broadaddr" may be non-null even on
* non-broadcast interfaces, and was null on
* at least one OpenBSD 3.4 system on at least
* one interface with IFF_BROADCAST set.
*
* "ifa_dstaddr" was, on at least one FreeBSD 4.1
* system, non-null on a non-point-to-point
* interface.
*
* Therefore, we supply the address and netmask only
* if "ifa_addr" is non-null (if there's no address,
* there's obviously no netmask), and supply the
* broadcast and destination addresses if the appropriate
* flag is set *and* the appropriate "ifa_" entry doesn't
* evaluate to a null pointer.
*/
if (ifa->ifa_addr != NULL) {
addr = ifa->ifa_addr;
addr_size = SA_LEN(addr);
netmask = ifa->ifa_netmask;
} else {
addr = NULL;
addr_size = 0;
netmask = NULL;
}
if (ifa->ifa_flags & IFF_BROADCAST &&
ifa->ifa_broadaddr != NULL) {
broadaddr = ifa->ifa_broadaddr;
broadaddr_size = SA_LEN(broadaddr);
} else {
broadaddr = NULL;
broadaddr_size = 0;
}
if (ifa->ifa_flags & IFF_POINTOPOINT &&
ifa->ifa_dstaddr != NULL) {
dstaddr = ifa->ifa_dstaddr;
dstaddr_size = SA_LEN(ifa->ifa_dstaddr);
} else {
dstaddr = NULL;
dstaddr_size = 0;
}
/*
* Add information for this address to the list.
*/
if (add_addr_to_iflist(&devlist, ifa->ifa_name,
ifa->ifa_flags, addr, addr_size, netmask, addr_size,
broadaddr, broadaddr_size, dstaddr, dstaddr_size,
errbuf) < 0) {
ret = -1;
break;
}
}
freeifaddrs(ifap);
if (ret != -1) {
/*
* We haven't had any errors yet; do any platform-specific
* operations to add devices.
*/
if (pcap_platform_finddevs(&devlist, errbuf) < 0)
ret = -1;
}
if (ret == -1) {
/*
* We had an error; free the list we've been constructing.
*/
if (devlist != NULL) {
pcap_freealldevs(devlist);
devlist = NULL;
}
}
*alldevsp = devlist;
return (ret);
}

502
contrib/libpcap/fad-gifc.c Normal file
View File

@ -0,0 +1,502 @@
/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */
/*
* Copyright (c) 1994, 1995, 1996, 1997, 1998
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Computer Systems
* Engineering Group at Lawrence Berkeley Laboratory.
* 4. Neither the name of the University nor of the Laboratory may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef lint
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/fad-gifc.c,v 1.4.2.1 2003/11/15 23:26:39 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <sys/param.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#ifdef HAVE_SYS_SOCKIO_H
#include <sys/sockio.h>
#endif
#include <sys/time.h> /* concession to AIX */
struct mbuf; /* Squelch compiler warnings on some platforms for */
struct rtentry; /* declarations in <net/if.h> */
#include <net/if.h>
#include <netinet/in.h>
#include <ctype.h>
#include <errno.h>
#include <memory.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "pcap-int.h"
#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
/*
* This is fun.
*
* In older BSD systems, socket addresses were fixed-length, and
* "sizeof (struct sockaddr)" gave the size of the structure.
* All addresses fit within a "struct sockaddr".
*
* In newer BSD systems, the socket address is variable-length, and
* there's an "sa_len" field giving the length of the structure;
* this allows socket addresses to be longer than 2 bytes of family
* and 14 bytes of data.
*
* Some commercial UNIXes use the old BSD scheme, some use the RFC 2553
* variant of the old BSD scheme (with "struct sockaddr_storage" rather
* than "struct sockaddr"), and some use the new BSD scheme.
*
* Some versions of GNU libc use neither scheme, but has an "SA_LEN()"
* macro that determines the size based on the address family. Other
* versions don't have "SA_LEN()" (as it was in drafts of RFC 2553
* but not in the final version).
*
* We assume that a UNIX that doesn't have "getifaddrs()" and doesn't have
* SIOCGLIFCONF, but has SIOCGIFCONF, uses "struct sockaddr" for the
* address in an entry returned by SIOCGIFCONF.
*/
#ifndef SA_LEN
#ifdef HAVE_SOCKADDR_SA_LEN
#define SA_LEN(addr) ((addr)->sa_len)
#else /* HAVE_SOCKADDR_SA_LEN */
#define SA_LEN(addr) (sizeof (struct sockaddr))
#endif /* HAVE_SOCKADDR_SA_LEN */
#endif /* SA_LEN */
#ifdef HAVE_PROC_NET_DEV
/*
* Get from "/proc/net/dev" all interfaces listed there; if they're
* already in the list of interfaces we have, that won't add another
* instance, but if they're not, that'll add them.
*
* We don't bother getting any addresses for them; it appears you can't
* use SIOCGIFADDR on Linux to get IPv6 addresses for interfaces, and,
* although some other types of addresses can be fetched with SIOCGIFADDR,
* we don't bother with them for now.
*
* We also don't fail if we couldn't open "/proc/net/dev"; we just leave
* the list of interfaces as is.
*/
static int
scan_proc_net_dev(pcap_if_t **devlistp, int fd, char *errbuf)
{
FILE *proc_net_f;
char linebuf[512];
int linenum;
unsigned char *p;
char name[512]; /* XXX - pick a size */
char *q, *saveq;
struct ifreq ifrflags;
int ret = 0;
proc_net_f = fopen("/proc/net/dev", "r");
if (proc_net_f == NULL)
return (0);
for (linenum = 1;
fgets(linebuf, sizeof linebuf, proc_net_f) != NULL; linenum++) {
/*
* Skip the first two lines - they're headers.
*/
if (linenum <= 2)
continue;
p = &linebuf[0];
/*
* Skip leading white space.
*/
while (*p != '\0' && isspace(*p))
p++;
if (*p == '\0' || *p == '\n')
continue; /* blank line */
/*
* Get the interface name.
*/
q = &name[0];
while (*p != '\0' && !isspace(*p)) {
if (*p == ':') {
/*
* This could be the separator between a
* name and an alias number, or it could be
* the separator between a name with no
* alias number and the next field.
*
* If there's a colon after digits, it
* separates the name and the alias number,
* otherwise it separates the name and the
* next field.
*/
saveq = q;
while (isdigit(*p))
*q++ = *p++;
if (*p != ':') {
/*
* That was the next field,
* not the alias number.
*/
q = saveq;
}
break;
} else
*q++ = *p++;
}
*q = '\0';
/*
* Get the flags for this interface, and skip it if
* it's not up.
*/
strncpy(ifrflags.ifr_name, name, sizeof(ifrflags.ifr_name));
if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifrflags) < 0) {
if (errno == ENXIO)
continue;
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"SIOCGIFFLAGS: %.*s: %s",
(int)sizeof(ifrflags.ifr_name),
ifrflags.ifr_name,
pcap_strerror(errno));
ret = -1;
break;
}
if (!(ifrflags.ifr_flags & IFF_UP))
continue;
/*
* Add an entry for this interface, with no addresses.
*/
if (pcap_add_if(devlistp, name, ifrflags.ifr_flags, NULL,
errbuf) == -1) {
/*
* Failure.
*/
ret = -1;
break;
}
}
if (ret != -1) {
/*
* Well, we didn't fail for any other reason; did we
* fail due to an error reading the file?
*/
if (ferror(proc_net_f)) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"Error reading /proc/net/dev: %s",
pcap_strerror(errno));
ret = -1;
}
}
(void)fclose(proc_net_f);
return (ret);
}
#endif /* HAVE_PROC_NET_DEV */
/*
* Get a list of all interfaces that are up and that we can open.
* Returns -1 on error, 0 otherwise.
* The list, as returned through "alldevsp", may be null if no interfaces
* were up and could be opened.
*
* This is the implementation used on platforms that have SIOCGIFCONF but
* don't have any other mechanism for getting a list of interfaces.
*
* XXX - or platforms that have other, better mechanisms but for which
* we don't yet have code to use that mechanism; I think there's a better
* way on Linux, for example.
*/
int
pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
{
pcap_if_t *devlist = NULL;
register int fd;
register struct ifreq *ifrp, *ifend, *ifnext;
int n;
struct ifconf ifc;
char *buf = NULL;
unsigned buf_size;
struct ifreq ifrflags, ifrnetmask, ifrbroadaddr, ifrdstaddr;
struct sockaddr *netmask, *broadaddr, *dstaddr;
size_t netmask_size, broadaddr_size, dstaddr_size;
int ret = 0;
/*
* Create a socket from which to fetch the list of interfaces.
*/
fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd < 0) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"socket: %s", pcap_strerror(errno));
return (-1);
}
/*
* Start with an 8K buffer, and keep growing the buffer until
* we get the entire interface list or fail to get it for some
* reason other than EINVAL (which is presumed here to mean
* "buffer is too small").
*/
buf_size = 8192;
for (;;) {
buf = malloc(buf_size);
if (buf == NULL) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"malloc: %s", pcap_strerror(errno));
(void)close(fd);
return (-1);
}
ifc.ifc_len = buf_size;
ifc.ifc_buf = buf;
memset(buf, 0, buf_size);
if (ioctl(fd, SIOCGIFCONF, (char *)&ifc) < 0
&& errno != EINVAL) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"SIOCGIFCONF: %s", pcap_strerror(errno));
(void)close(fd);
free(buf);
return (-1);
}
if (ifc.ifc_len < buf_size)
break;
free(buf);
buf_size *= 2;
}
ifrp = (struct ifreq *)buf;
ifend = (struct ifreq *)(buf + ifc.ifc_len);
for (; ifrp < ifend; ifrp = ifnext) {
/*
* XXX - what if this isn't an IPv4 address? Can
* we still get the netmask, etc. with ioctls on
* an IPv4 socket?
*
* The answer is probably platform-dependent, and
* if the answer is "no" on more than one platform,
* the way you work around it is probably platform-
* dependent as well.
*/
n = SA_LEN(&ifrp->ifr_addr) + sizeof(ifrp->ifr_name);
if (n < sizeof(*ifrp))
ifnext = ifrp + 1;
else
ifnext = (struct ifreq *)((char *)ifrp + n);
/*
* Get the flags for this interface, and skip it if it's
* not up.
*/
strncpy(ifrflags.ifr_name, ifrp->ifr_name,
sizeof(ifrflags.ifr_name));
if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifrflags) < 0) {
if (errno == ENXIO)
continue;
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"SIOCGIFFLAGS: %.*s: %s",
(int)sizeof(ifrflags.ifr_name),
ifrflags.ifr_name,
pcap_strerror(errno));
ret = -1;
break;
}
if (!(ifrflags.ifr_flags & IFF_UP))
continue;
/*
* Get the netmask for this address on this interface.
*/
strncpy(ifrnetmask.ifr_name, ifrp->ifr_name,
sizeof(ifrnetmask.ifr_name));
memcpy(&ifrnetmask.ifr_addr, &ifrp->ifr_addr,
sizeof(ifrnetmask.ifr_addr));
if (ioctl(fd, SIOCGIFNETMASK, (char *)&ifrnetmask) < 0) {
if (errno == EADDRNOTAVAIL) {
/*
* Not available.
*/
netmask = NULL;
netmask_size = 0;
} else {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"SIOCGIFNETMASK: %.*s: %s",
(int)sizeof(ifrnetmask.ifr_name),
ifrnetmask.ifr_name,
pcap_strerror(errno));
ret = -1;
break;
}
} else {
netmask = &ifrnetmask.ifr_addr;
netmask_size = SA_LEN(netmask);
}
/*
* Get the broadcast address for this address on this
* interface (if any).
*/
if (ifrflags.ifr_flags & IFF_BROADCAST) {
strncpy(ifrbroadaddr.ifr_name, ifrp->ifr_name,
sizeof(ifrbroadaddr.ifr_name));
memcpy(&ifrbroadaddr.ifr_addr, &ifrp->ifr_addr,
sizeof(ifrbroadaddr.ifr_addr));
if (ioctl(fd, SIOCGIFBRDADDR,
(char *)&ifrbroadaddr) < 0) {
if (errno == EADDRNOTAVAIL) {
/*
* Not available.
*/
broadaddr = NULL;
broadaddr_size = 0;
} else {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"SIOCGIFBRDADDR: %.*s: %s",
(int)sizeof(ifrbroadaddr.ifr_name),
ifrbroadaddr.ifr_name,
pcap_strerror(errno));
ret = -1;
break;
}
} else {
broadaddr = &ifrbroadaddr.ifr_broadaddr;
broadaddr_size = SA_LEN(broadaddr);
}
} else {
/*
* Not a broadcast interface, so no broadcast
* address.
*/
broadaddr = NULL;
broadaddr_size = 0;
}
/*
* Get the destination address for this address on this
* interface (if any).
*/
if (ifrflags.ifr_flags & IFF_POINTOPOINT) {
strncpy(ifrdstaddr.ifr_name, ifrp->ifr_name,
sizeof(ifrdstaddr.ifr_name));
memcpy(&ifrdstaddr.ifr_addr, &ifrp->ifr_addr,
sizeof(ifrdstaddr.ifr_addr));
if (ioctl(fd, SIOCGIFDSTADDR,
(char *)&ifrdstaddr) < 0) {
if (errno == EADDRNOTAVAIL) {
/*
* Not available.
*/
dstaddr = NULL;
dstaddr_size = 0;
} else {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"SIOCGIFDSTADDR: %.*s: %s",
(int)sizeof(ifrdstaddr.ifr_name),
ifrdstaddr.ifr_name,
pcap_strerror(errno));
ret = -1;
break;
}
} else {
dstaddr = &ifrdstaddr.ifr_dstaddr;
dstaddr_size = SA_LEN(dstaddr);
}
} else {
/*
* Not a point-to-point interface, so no destination
* address.
*/
dstaddr = NULL;
dstaddr_size = 0;
}
/*
* Add information for this address to the list.
*/
if (add_addr_to_iflist(&devlist, ifrp->ifr_name,
ifrflags.ifr_flags, &ifrp->ifr_addr,
SA_LEN(&ifrp->ifr_addr), netmask, netmask_size,
broadaddr, broadaddr_size, dstaddr, dstaddr_size,
errbuf) < 0) {
ret = -1;
break;
}
}
free(buf);
#ifdef HAVE_PROC_NET_DEV
if (ret != -1) {
/*
* We haven't had any errors yet; now read "/proc/net/dev",
* and add to the list of interfaces all interfaces listed
* there that we don't already have, because, on Linux,
* SIOCGIFCONF reports only interfaces with IPv4 addresses,
* so you need to read "/proc/net/dev" to get the names of
* the rest of the interfaces.
*/
ret = scan_proc_net_dev(&devlist, fd, errbuf);
}
#endif
(void)close(fd);
if (ret != -1) {
/*
* We haven't had any errors yet; do any platform-specific
* operations to add devices.
*/
if (pcap_platform_finddevs(&devlist, errbuf) < 0)
ret = -1;
}
if (ret == -1) {
/*
* We had an error; free the list we've been constructing.
*/
if (devlist != NULL) {
pcap_freealldevs(devlist);
devlist = NULL;
}
}
*alldevsp = devlist;
return (ret);
}

325
contrib/libpcap/fad-glifc.c Normal file
View File

@ -0,0 +1,325 @@
/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */
/*
* Copyright (c) 1994, 1995, 1996, 1997, 1998
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Computer Systems
* Engineering Group at Lawrence Berkeley Laboratory.
* 4. Neither the name of the University nor of the Laboratory may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef lint
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/fad-glifc.c,v 1.2.2.1 2003/11/15 23:26:39 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <sys/param.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#ifdef HAVE_SYS_SOCKIO_H
#include <sys/sockio.h>
#endif
#include <sys/time.h> /* concession to AIX */
struct mbuf; /* Squelch compiler warnings on some platforms for */
struct rtentry; /* declarations in <net/if.h> */
#include <net/if.h>
#include <netinet/in.h>
#include <ctype.h>
#include <errno.h>
#include <memory.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "pcap-int.h"
#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
/*
* Get a list of all interfaces that are up and that we can open.
* Returns -1 on error, 0 otherwise.
* The list, as returned through "alldevsp", may be null if no interfaces
* were up and could be opened.
*
* This is the implementation used on platforms that have SIOCLGIFCONF
* but don't have "getifaddrs()". (Solaris 8 and later; we use
* SIOCLGIFCONF rather than SIOCGIFCONF in order to get IPv6 addresses.)
*/
int
pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
{
pcap_if_t *devlist = NULL;
register int fd4, fd6, fd;
register struct lifreq *ifrp, *ifend;
struct lifnum ifn;
struct lifconf ifc;
char *buf = NULL;
unsigned buf_size;
struct lifreq ifrflags, ifrnetmask, ifrbroadaddr, ifrdstaddr;
struct sockaddr *netmask, *broadaddr, *dstaddr;
int ret = 0;
/*
* Create a socket from which to fetch the list of interfaces,
* and from which to fetch IPv4 information.
*/
fd4 = socket(AF_INET, SOCK_DGRAM, 0);
if (fd4 < 0) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"socket: %s", pcap_strerror(errno));
return (-1);
}
/*
* Create a socket from which to fetch IPv6 information.
*/
fd6 = socket(AF_INET6, SOCK_DGRAM, 0);
if (fd6 < 0) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"socket: %s", pcap_strerror(errno));
(void)close(fd4);
return (-1);
}
/*
* How many entries will SIOCGLIFCONF return?
*/
ifn.lifn_family = AF_UNSPEC;
ifn.lifn_flags = 0;
ifn.lifn_count = 0;
if (ioctl(fd4, SIOCGLIFNUM, (char *)&ifn) < 0) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"SIOCGLIFNUM: %s", pcap_strerror(errno));
(void)close(fd6);
(void)close(fd4);
return (-1);
}
/*
* Allocate a buffer for those entries.
*/
buf_size = ifn.lifn_count * sizeof (struct lifreq);
buf = malloc(buf_size);
if (buf == NULL) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"malloc: %s", pcap_strerror(errno));
(void)close(fd6);
(void)close(fd4);
return (-1);
}
/*
* Get the entries.
*/
ifc.lifc_len = buf_size;
ifc.lifc_buf = buf;
ifc.lifc_family = AF_UNSPEC;
ifc.lifc_flags = 0;
memset(buf, 0, buf_size);
if (ioctl(fd4, SIOCGLIFCONF, (char *)&ifc) < 0) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"SIOCGLIFCONF: %s", pcap_strerror(errno));
(void)close(fd6);
(void)close(fd4);
free(buf);
return (-1);
}
/*
* Loop over the entries.
*/
ifrp = (struct lifreq *)buf;
ifend = (struct lifreq *)(buf + ifc.lifc_len);
for (; ifrp < ifend; ifrp++) {
/*
* IPv6 or not?
*/
if (((struct sockaddr *)&ifrp->lifr_addr)->sa_family == AF_INET6)
fd = fd6;
else
fd = fd4;
/*
* Get the flags for this interface, and skip it if it's
* not up.
*/
strncpy(ifrflags.lifr_name, ifrp->lifr_name,
sizeof(ifrflags.lifr_name));
if (ioctl(fd, SIOCGLIFFLAGS, (char *)&ifrflags) < 0) {
if (errno == ENXIO)
continue;
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"SIOCGLIFFLAGS: %.*s: %s",
(int)sizeof(ifrflags.lifr_name),
ifrflags.lifr_name,
pcap_strerror(errno));
ret = -1;
break;
}
if (!(ifrflags.lifr_flags & IFF_UP))
continue;
/*
* Get the netmask for this address on this interface.
*/
strncpy(ifrnetmask.lifr_name, ifrp->lifr_name,
sizeof(ifrnetmask.lifr_name));
memcpy(&ifrnetmask.lifr_addr, &ifrp->lifr_addr,
sizeof(ifrnetmask.lifr_addr));
if (ioctl(fd, SIOCGLIFNETMASK, (char *)&ifrnetmask) < 0) {
if (errno == EADDRNOTAVAIL) {
/*
* Not available.
*/
netmask = NULL;
} else {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"SIOCGLIFNETMASK: %.*s: %s",
(int)sizeof(ifrnetmask.lifr_name),
ifrnetmask.lifr_name,
pcap_strerror(errno));
ret = -1;
break;
}
} else
netmask = (struct sockaddr *)&ifrnetmask.lifr_addr;
/*
* Get the broadcast address for this address on this
* interface (if any).
*/
if (ifrflags.lifr_flags & IFF_BROADCAST) {
strncpy(ifrbroadaddr.lifr_name, ifrp->lifr_name,
sizeof(ifrbroadaddr.lifr_name));
memcpy(&ifrbroadaddr.lifr_addr, &ifrp->lifr_addr,
sizeof(ifrbroadaddr.lifr_addr));
if (ioctl(fd, SIOCGLIFBRDADDR,
(char *)&ifrbroadaddr) < 0) {
if (errno == EADDRNOTAVAIL) {
/*
* Not available.
*/
broadaddr = NULL;
} else {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"SIOCGLIFBRDADDR: %.*s: %s",
(int)sizeof(ifrbroadaddr.lifr_name),
ifrbroadaddr.lifr_name,
pcap_strerror(errno));
ret = -1;
break;
}
} else
broadaddr = (struct sockaddr *)&ifrbroadaddr.lifr_broadaddr;
} else {
/*
* Not a broadcast interface, so no broadcast
* address.
*/
broadaddr = NULL;
}
/*
* Get the destination address for this address on this
* interface (if any).
*/
if (ifrflags.lifr_flags & IFF_POINTOPOINT) {
strncpy(ifrdstaddr.lifr_name, ifrp->lifr_name,
sizeof(ifrdstaddr.lifr_name));
memcpy(&ifrdstaddr.lifr_addr, &ifrp->lifr_addr,
sizeof(ifrdstaddr.lifr_addr));
if (ioctl(fd, SIOCGLIFDSTADDR,
(char *)&ifrdstaddr) < 0) {
if (errno == EADDRNOTAVAIL) {
/*
* Not available.
*/
dstaddr = NULL;
} else {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"SIOCGLIFDSTADDR: %.*s: %s",
(int)sizeof(ifrdstaddr.lifr_name),
ifrdstaddr.lifr_name,
pcap_strerror(errno));
ret = -1;
break;
}
} else
dstaddr = (struct sockaddr *)&ifrdstaddr.lifr_dstaddr;
} else
dstaddr = NULL;
/*
* Add information for this address to the list.
*/
if (add_addr_to_iflist(&devlist, ifrp->lifr_name,
ifrflags.lifr_flags, (struct sockaddr *)&ifrp->lifr_addr,
sizeof (struct sockaddr_storage),
netmask, sizeof (struct sockaddr_storage),
broadaddr, sizeof (struct sockaddr_storage),
dstaddr, sizeof (struct sockaddr_storage), errbuf) < 0) {
ret = -1;
break;
}
}
free(buf);
(void)close(fd6);
(void)close(fd4);
if (ret != -1) {
/*
* We haven't had any errors yet; do any platform-specific
* operations to add devices.
*/
if (pcap_platform_finddevs(&devlist, errbuf) < 0)
ret = -1;
}
if (ret == -1) {
/*
* We had an error; free the list we've been constructing.
*/
if (devlist != NULL) {
pcap_freealldevs(devlist);
devlist = NULL;
}
}
*alldevsp = devlist;
return (ret);
}

View File

@ -0,0 +1,65 @@
/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */
/*
* Copyright (c) 1994, 1995, 1996, 1997, 1998
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Computer Systems
* Engineering Group at Lawrence Berkeley Laboratory.
* 4. Neither the name of the University nor of the Laboratory may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef lint
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/fad-null.c,v 1.1.2.1 2003/11/15 23:26:39 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <pcap.h>
/*
* Get a list of all interfaces that are up and that we can open.
* Returns -1 on error, 0 otherwise.
* The list, as returned through "alldevsp", may be null if no interfaces
* were up and could be opened.
*
* This is the implementation used on platforms that have no support for
* packet capture.
*/
int
pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
{
/*
* Succeed, but don't return any interfaces; we return only those
* we can open, and we can't open any if there's no support
* for packet capture.
*/
*alldevsp = NULL;
return (0);
}

291
contrib/libpcap/fad-win32.c Normal file
View File

@ -0,0 +1,291 @@
/*
* Copyright (c) 2002 - 2003
* NetGroup, Politecnico di Torino (Italy)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Politecnico di Torino nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef lint
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/fad-win32.c,v 1.7.2.1 2003/11/15 23:26:40 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <pcap.h>
#include <pcap-int.h>
#include <packet32.h>
#include <errno.h>
/*
* Add an entry to the list of addresses for an interface.
* "curdev" is the entry for that interface.
*/
static int
add_addr_to_list(pcap_if_t *curdev, struct sockaddr *addr,
struct sockaddr *netmask, struct sockaddr *broadaddr,
struct sockaddr *dstaddr, char *errbuf)
{
pcap_addr_t *curaddr, *prevaddr, *nextaddr;
/*
* Allocate the new entry and fill it in.
*/
curaddr = (pcap_addr_t*)malloc(sizeof(pcap_addr_t));
if (curaddr == NULL) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"malloc: %s", pcap_strerror(errno));
return (-1);
}
curaddr->next = NULL;
if (addr != NULL) {
curaddr->addr = (struct sockaddr*)dup_sockaddr(addr, sizeof(struct sockaddr_storage));
if (curaddr->addr == NULL) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"malloc: %s", pcap_strerror(errno));
free(curaddr);
return (-1);
}
} else
curaddr->addr = NULL;
if (netmask != NULL) {
curaddr->netmask = (struct sockaddr*)dup_sockaddr(netmask, sizeof(struct sockaddr_storage));
if (curaddr->netmask == NULL) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"malloc: %s", pcap_strerror(errno));
free(curaddr);
return (-1);
}
} else
curaddr->netmask = NULL;
if (broadaddr != NULL) {
curaddr->broadaddr = (struct sockaddr*)dup_sockaddr(broadaddr, sizeof(struct sockaddr_storage));
if (curaddr->broadaddr == NULL) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"malloc: %s", pcap_strerror(errno));
free(curaddr);
return (-1);
}
} else
curaddr->broadaddr = NULL;
if (dstaddr != NULL) {
curaddr->dstaddr = (struct sockaddr*)dup_sockaddr(dstaddr, sizeof(struct sockaddr_storage));
if (curaddr->dstaddr == NULL) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"malloc: %s", pcap_strerror(errno));
free(curaddr);
return (-1);
}
} else
curaddr->dstaddr = NULL;
/*
* Find the end of the list of addresses.
*/
for (prevaddr = curdev->addresses; prevaddr != NULL; prevaddr = nextaddr) {
nextaddr = prevaddr->next;
if (nextaddr == NULL) {
/*
* This is the end of the list.
*/
break;
}
}
if (prevaddr == NULL) {
/*
* The list was empty; this is the first member.
*/
curdev->addresses = curaddr;
} else {
/*
* "prevaddr" is the last member of the list; append
* this member to it.
*/
prevaddr->next = curaddr;
}
return (0);
}
static int
pcap_add_if_win32(pcap_if_t **devlist, char *name, const char *desc,
char *errbuf)
{
pcap_if_t *curdev;
npf_if_addr if_addrs[MAX_NETWORK_ADDRESSES];
LONG if_addr_size;
int res = 0;
if_addr_size = MAX_NETWORK_ADDRESSES;
/*
* Add an entry for this interface, with no addresses.
*/
if (add_or_find_if(&curdev, devlist, (char *)name, 0, (char *)desc,
errbuf) == -1) {
/*
* Failure.
*/
return (-1);
}
/*
* Get the list of addresses for the interface.
*/
if (!PacketGetNetInfoEx((void *)name, if_addrs, &if_addr_size)) {
/*
* Failure.
*
* We don't return an error, because this can happen with
* NdisWan interfaces, and we want to supply them even
* if we can't supply their addresses.
*
* We return an entry with an empty address list.
*/
return (0);
}
/*
* Now add the addresses.
*/
while (if_addr_size-- > 0) {
/*
* "curdev" is an entry for this interface; add an entry for
* this address to its list of addresses.
*/
if(curdev == NULL)
break;
res = add_addr_to_list(curdev,
(struct sockaddr *)&if_addrs[if_addr_size].IPAddress,
(struct sockaddr *)&if_addrs[if_addr_size].SubnetMask,
(struct sockaddr *)&if_addrs[if_addr_size].Broadcast,
NULL,
errbuf);
if (res == -1) {
/*
* Failure.
*/
break;
}
}
return (res);
}
/*
* Get a list of all interfaces that are up and that we can open.
* Returns -1 on error, 0 otherwise.
* The list, as returned through "alldevsp", may be null if no interfaces
* were up and could be opened.
*
* Win32 implementation, based on WinPcap
*/
int
pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
{
pcap_if_t *devlist = NULL;
int ret = 0;
const char *desc;
char AdaptersName[8192];
ULONG NameLength = 8192;
char *name;
if (!PacketGetAdapterNames(AdaptersName, &NameLength)) {
snprintf(errbuf, PCAP_ERRBUF_SIZE,
"PacketGetAdapterNames: %s",
pcap_win32strerror());
return (-1);
}
/*
* "PacketGetAdapterNames()" returned a list of
* null-terminated ASCII interface name strings,
* terminated by a null string, followed by a list
* of null-terminated ASCII interface description
* strings, terminated by a null string.
* This means there are two ASCII nulls at the end
* of the first list.
*
* Find the end of the first list; that's the
* beginning of the second list.
*/
desc = &AdaptersName[0];
while (*desc != '\0' || *(desc + 1) != '\0')
desc++;
/*
* Found it - "desc" points to the first of the two
* nulls at the end of the list of names, so the
* first byte of the list of descriptions is two bytes
* after it.
*/
desc += 2;
/*
* Loop over the elements in the first list.
*/
name = &AdaptersName[0];
while (*name != '\0') {
/*
* Add an entry for this interface.
*/
if (pcap_add_if_win32(&devlist, name, desc,
errbuf) == -1) {
/*
* Failure.
*/
ret = -1;
break;
}
name += strlen(name) + 1;
desc += strlen(desc) + 1;
}
if (ret == -1) {
/*
* We had an error; free the list we've been constructing.
*/
if (devlist != NULL) {
pcap_freealldevs(devlist);
devlist = NULL;
}
}
*alldevsp = devlist;
return (ret);
}

File diff suppressed because it is too large Load Diff

View File

@ -18,7 +18,41 @@
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* @(#) $Header: /tcpdump/master/libpcap/gencode.h,v 1.53 2001/05/10 14:48:02 fenner Exp $ (LBL)
* @(#) $Header: /tcpdump/master/libpcap/gencode.h,v 1.58.2.1 2004/03/28 21:45:31 fenner Exp $ (LBL)
*/
/*
* ATM support:
*
* Copyright (c) 1997 Yen Yen Lim and North Dakota State University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Yen Yen Lim and
* North Dakota State University
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/* Address qualifiers. */
@ -73,6 +107,18 @@
#define Q_NETBEUI 30
/* IS-IS Levels */
#define Q_ISIS_L1 31
#define Q_ISIS_L2 32
/* PDU types */
#define Q_ISIS_IIH 33
#define Q_ISIS_LAN_IIH 34
#define Q_ISIS_PTP_IIH 35
#define Q_ISIS_SNP 36
#define Q_ISIS_CSNP 37
#define Q_ISIS_PSNP 38
#define Q_ISIS_LSP 39
/* Directional qualifiers. */
#define Q_SRC 1
@ -83,6 +129,43 @@
#define Q_DEFAULT 0
#define Q_UNDEF 255
/* ATM types */
#define A_METAC 22 /* Meta signalling Circuit */
#define A_BCC 23 /* Broadcast Circuit */
#define A_OAMF4SC 24 /* Segment OAM F4 Circuit */
#define A_OAMF4EC 25 /* End-to-End OAM F4 Circuit */
#define A_SC 26 /* Signalling Circuit*/
#define A_ILMIC 27 /* ILMI Circuit */
#define A_OAM 28 /* OAM cells : F4 only */
#define A_OAMF4 29 /* OAM F4 cells: Segment + End-to-end */
#define A_LANE 30 /* LANE traffic */
#define A_LLC 31 /* LLC-encapsulated traffic */
/* Based on Q.2931 signalling protocol */
#define A_SETUP 41 /* Setup message */
#define A_CALLPROCEED 42 /* Call proceeding message */
#define A_CONNECT 43 /* Connect message */
#define A_CONNECTACK 44 /* Connect Ack message */
#define A_RELEASE 45 /* Release message */
#define A_RELEASE_DONE 46 /* Release message */
/* ATM field types */
#define A_VPI 51
#define A_VCI 52
#define A_PROTOTYPE 53
#define A_MSGTYPE 54
#define A_CALLREFTYPE 55
#define A_CONNECTMSG 70 /* returns Q.2931 signalling messages for
establishing and destroying switched
virtual connection */
#define A_METACONNECT 71 /* returns Q.2931 signalling messages for
establishing and destroying predefined
virtual circuits, such as broadcast
circuit, oamf4 segment circuit, oamf4
end-to-end circuits, ILMI circuits or
connection signalling circuit. */
struct slist;
struct stmt {
@ -97,7 +180,7 @@ struct slist {
struct slist *next;
};
/*
/*
* A bit vector to represent definition sets. We assume TOT_REGISTERS
* is smaller than 8*sizeof(atomset).
*/
@ -191,6 +274,18 @@ struct block *gen_inbound(int);
struct block *gen_vlan(int);
struct block *gen_atmfield_code(int atmfield, bpf_u_int32 jvalue, bpf_u_int32 jtype, int reverse);
struct block *gen_atmtype_abbrev(int type);
struct block *gen_atmmulti_abbrev(int type);
struct block *gen_pf_ifname(const char *);
struct block *gen_pf_rnr(int);
struct block *gen_pf_srnr(int);
struct block *gen_pf_ruleset(char *);
struct block *gen_pf_reason(int);
struct block *gen_pf_action(int);
struct block *gen_pf_dir(int);
void bpf_optimize(struct block **);
void bpf_error(const char *, ...)
#if HAVE___ATTRIBUTE__

View File

@ -21,33 +21,40 @@
*
*/
#ifndef lint
static const char rcsid[] =
"@(#) $Header: /tcpdump/master/libpcap/grammar.y,v 1.71 2001/07/03 19:15:48 guy Exp $ (LBL)";
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/grammar.y,v 1.79.2.3 2004/03/28 21:45:32 fenner Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef WIN32
#include <pcap-stdinc.h>
#else /* WIN32 */
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#endif /* WIN32 */
#include <stdlib.h>
#ifndef WIN32
#if __STDC__
struct mbuf;
struct rtentry;
#endif
#include <net/if.h>
#include <netinet/in.h>
#endif /* WIN32 */
#include <stdio.h>
#include <strings.h>
#include "pcap-int.h"
#include "gencode.h"
#include "pf.h"
#include <pcap-namedb.h>
#ifdef HAVE_OS_PROTO_H
@ -91,6 +98,7 @@ pcap_parse()
struct arth *a;
struct {
struct qual q;
int atmfieldtype;
struct block *b;
} blk;
struct block *rblk;
@ -102,14 +110,18 @@ pcap_parse()
%type <a> arth narth
%type <i> byteop pname pnum relop irelop
%type <blk> and or paren not null prog
%type <rblk> other
%type <rblk> other pfvar
%type <i> atmtype atmmultitype
%type <blk> atmfield
%type <blk> atmfieldvalue atmvalue atmlistvalue
%token DST SRC HOST GATEWAY
%token NET MASK PORT LESS GREATER PROTO PROTOCHAIN BYTE
%token NET NETMASK PORT LESS GREATER PROTO PROTOCHAIN CBYTE
%token ARP RARP IP SCTP TCP UDP ICMP IGMP IGRP PIM VRRP
%token ATALK AARP DECNET LAT SCA MOPRC MOPDL
%token TK_BROADCAST TK_MULTICAST
%token NUM INBOUND OUTBOUND
%token PF_IFNAME PF_RSET PF_RNR PF_SRNR PF_REASON PF_ACTION
%token LINK
%token GEQ LEQ NEQ
%token ID EID HID HID6 AID
@ -117,16 +129,19 @@ pcap_parse()
%token LEN
%token IPV6 ICMPV6 AH ESP
%token VLAN
%token ISO ESIS ISIS CLNP
%token ISO ESIS CLNP ISIS L1 L2 IIH LSP SNP CSNP PSNP
%token STP
%token IPX
%token NETBEUI
%token LANE LLC METAC BCC SC ILMIC OAMF4EC OAMF4SC
%token OAM OAMF4 CONNECTMSG METACONNECT
%token VPI VCI
%type <s> ID
%type <e> EID
%type <e> AID
%type <s> HID HID6
%type <i> NUM
%type <i> NUM action reason
%left OR AND
%nonassoc '!'
@ -163,7 +178,7 @@ id: nid
nid: ID { $$.b = gen_scode($1, $$.q = $<blk>0.q); }
| HID '/' NUM { $$.b = gen_mcode($1, NULL, $3,
$$.q = $<blk>0.q); }
| HID MASK HID { $$.b = gen_mcode($1, $3, 0,
| HID NETMASK HID { $$.b = gen_mcode($1, $3, 0,
$$.q = $<blk>0.q); }
| HID {
/* Decide how to parse HID based on proto */
@ -238,6 +253,9 @@ rterm: head id { $$ = $2; }
| arth irelop arth { $$.b = gen_relation($2, $1, $3, 1);
$$.q = qerr; }
| other { $$.b = $1; $$.q = qerr; }
| atmtype { $$.b = gen_atmtype_abbrev($1); $$.q = qerr; }
| atmmultitype { $$.b = gen_atmmulti_abbrev($1); $$.q = qerr; }
| atmfield atmvalue { $$.b = $2.b; $$.q = qerr; }
;
/* protocol level qualifiers */
pqual: pname
@ -285,6 +303,13 @@ pname: LINK { $$ = Q_LINK; }
| ISO { $$ = Q_ISO; }
| ESIS { $$ = Q_ESIS; }
| ISIS { $$ = Q_ISIS; }
| L1 { $$ = Q_ISIS_L1; }
| L2 { $$ = Q_ISIS_L2; }
| IIH { $$ = Q_ISIS_IIH; }
| LSP { $$ = Q_ISIS_LSP; }
| SNP { $$ = Q_ISIS_SNP; }
| PSNP { $$ = Q_ISIS_PSNP; }
| CSNP { $$ = Q_ISIS_CSNP; }
| CLNP { $$ = Q_CLNP; }
| STP { $$ = Q_STP; }
| IPX { $$ = Q_IPX; }
@ -294,12 +319,47 @@ other: pqual TK_BROADCAST { $$ = gen_broadcast($1); }
| pqual TK_MULTICAST { $$ = gen_multicast($1); }
| LESS NUM { $$ = gen_less($2); }
| GREATER NUM { $$ = gen_greater($2); }
| BYTE NUM byteop NUM { $$ = gen_byteop($3, $2, $4); }
| CBYTE NUM byteop NUM { $$ = gen_byteop($3, $2, $4); }
| INBOUND { $$ = gen_inbound(0); }
| OUTBOUND { $$ = gen_inbound(1); }
| VLAN pnum { $$ = gen_vlan($2); }
| VLAN { $$ = gen_vlan(-1); }
| pfvar { $$ = $1; }
;
pfvar: PF_IFNAME ID { $$ = gen_pf_ifname($2); }
| PF_RSET ID { $$ = gen_pf_ruleset($2); }
| PF_RNR NUM { $$ = gen_pf_rnr($2); }
| PF_SRNR NUM { $$ = gen_pf_srnr($2); }
| PF_REASON reason { $$ = gen_pf_reason($2); }
| PF_ACTION action { $$ = gen_pf_action($2); }
;
reason: NUM { $$ = $1; }
| ID { const char *reasons[] = PFRES_NAMES;
int i;
for (i = 0; reasons[i]; i++) {
if (pcap_strcasecmp($1, reasons[i]) == 0) {
$$ = i;
break;
}
}
if (reasons[i] == NULL)
bpf_error("unknown PF reason");
}
;
action: ID { if (pcap_strcasecmp($1, "pass") == 0 ||
pcap_strcasecmp($1, "accept") == 0)
$$ = PF_PASS;
else if (pcap_strcasecmp($1, "drop") == 0 ||
pcap_strcasecmp($1, "block") == 0)
$$ = PF_DROP;
else
bpf_error("unknown PF action");
}
;
relop: '>' { $$ = BPF_JGT; }
| GEQ { $$ = BPF_JGE; }
| '=' { $$ = BPF_JEQ; }
@ -334,4 +394,37 @@ byteop: '&' { $$ = '&'; }
pnum: NUM
| paren pnum ')' { $$ = $2; }
;
atmtype: LANE { $$ = A_LANE; }
| LLC { $$ = A_LLC; }
| METAC { $$ = A_METAC; }
| BCC { $$ = A_BCC; }
| OAMF4EC { $$ = A_OAMF4EC; }
| OAMF4SC { $$ = A_OAMF4SC; }
| SC { $$ = A_SC; }
| ILMIC { $$ = A_ILMIC; }
;
atmmultitype: OAM { $$ = A_OAM; }
| OAMF4 { $$ = A_OAMF4; }
| CONNECTMSG { $$ = A_CONNECTMSG; }
| METACONNECT { $$ = A_METACONNECT; }
;
/* ATM field types quantifier */
atmfield: VPI { $$.atmfieldtype = A_VPI; }
| VCI { $$.atmfieldtype = A_VCI; }
;
atmvalue: atmfieldvalue
| relop NUM { $$.b = gen_atmfield_code($<blk>0.atmfieldtype, (u_int)$2, (u_int)$1, 0); }
| irelop NUM { $$.b = gen_atmfield_code($<blk>0.atmfieldtype, (u_int)$2, (u_int)$1, 1); }
| paren atmlistvalue ')' { $$.b = $2.b; $$.q = qerr; }
;
atmfieldvalue: NUM {
$$.atmfieldtype = $<blk>0.atmfieldtype;
if ($$.atmfieldtype == A_VPI ||
$$.atmfieldtype == A_VCI)
$$.b = gen_atmfield_code($$.atmfieldtype, (u_int) $1, BPF_JEQ, 0);
}
;
atmlistvalue: atmfieldvalue
| atmlistvalue or atmfieldvalue { gen_or($1.b, $3.b); $$ = $3; }
;
%%

View File

@ -33,14 +33,18 @@
*/
#ifndef lint
static const char rcsid[] =
"@(#) $Header: /tcpdump/master/libpcap/inet.c,v 1.45 2001/10/28 20:40:43 guy Exp $ (LBL)";
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/inet.c,v 1.58.2.1 2003/11/15 23:26:41 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef WIN32
#include <pcap-stdinc.h>
#else /* WIN32 */
#include <sys/param.h>
#include <sys/file.h>
#include <sys/ioctl.h>
@ -50,10 +54,11 @@ static const char rcsid[] =
#endif
#include <sys/time.h> /* concession to AIX */
struct mbuf;
struct rtentry;
struct mbuf; /* Squelch compiler warnings on some platforms for */
struct rtentry; /* declarations in <net/if.h> */
#include <net/if.h>
#include <netinet/in.h>
#endif /* WIN32 */
#include <ctype.h>
#include <errno.h>
@ -61,7 +66,9 @@ struct rtentry;
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef WIN32
#include <unistd.h>
#endif /* WIN32 */
#ifdef HAVE_LIMITS_H
#include <limits.h>
#else
@ -85,53 +92,20 @@ struct rtentry;
(isdigit((unsigned char)((name)[2])) || (name)[2] == '\0'))
#endif
/*
* This is fun.
*
* In older BSD systems, socket addresses were fixed-length, and
* "sizeof (struct sockaddr)" gave the size of the structure.
* All addresses fit within a "struct sockaddr".
*
* In newer BSD systems, the socket address is variable-length, and
* there's an "sa_len" field giving the length of the structure;
* this allows socket addresses to be longer than 2 bytes of family
* and 14 bytes of data.
*
* Some commercial UNIXes use the old BSD scheme, and some might use
* the new BSD scheme.
*
* GNU libc uses neither scheme, but has an "SA_LEN()" macro that
* determines the size based on the address family.
*/
#ifndef SA_LEN
#ifdef HAVE_SOCKADDR_SA_LEN
#define SA_LEN(addr) ((addr)->sa_len)
#else /* HAVE_SOCKADDR_SA_LEN */
#define SA_LEN(addr) (sizeof (struct sockaddr))
#endif /* HAVE_SOCKADDR_SA_LEN */
#endif /* SA_LEN */
/*
* Description string for the "any" device.
*/
static const char any_descr[] = "Pseudo-device that captures on all interfaces";
static struct sockaddr *
dup_sockaddr(struct sockaddr *sa)
struct sockaddr *
dup_sockaddr(struct sockaddr *sa, size_t sa_length)
{
struct sockaddr *newsa;
unsigned int size;
size = SA_LEN(sa);
if ((newsa = malloc(size)) == NULL)
if ((newsa = malloc(sa_length)) == NULL)
return (NULL);
return (memcpy(newsa, sa, size));
return (memcpy(newsa, sa, sa_length));
}
static int
get_instance(char *name)
get_instance(const char *name)
{
char *cp, *endcp;
const char *cp, *endcp;
int n;
if (strcmp(name, "any") == 0) {
@ -154,28 +128,13 @@ get_instance(char *name)
return (n);
}
static int
add_or_find_if(pcap_if_t **curdev_ret, pcap_if_t **alldevs, char *name,
int
add_or_find_if(pcap_if_t **curdev_ret, pcap_if_t **alldevs, const char *name,
u_int flags, const char *description, char *errbuf)
{
pcap_t *p;
pcap_if_t *curdev, *prevdev, *nextdev;
int this_instance;
/*
* Can we open this interface for live capture?
*/
p = pcap_open_live(name, 68, 0, 0, errbuf);
if (p == NULL) {
/*
* No. Don't bother including it.
* Don't treat this as an error, though.
*/
*curdev_ret = NULL;
return (0);
}
pcap_close(p);
/*
* Is there already an entry in the list for this interface?
*/
@ -194,7 +153,7 @@ add_or_find_if(pcap_if_t **curdev_ret, pcap_if_t **alldevs, char *name,
"malloc: %s", pcap_strerror(errno));
return (-1);
}
/*
* Fill in the entry.
*/
@ -317,15 +276,18 @@ add_or_find_if(pcap_if_t **curdev_ret, pcap_if_t **alldevs, char *name,
} else
prevdev->next = curdev;
}
*curdev_ret = curdev;
return (0);
}
static int
int
add_addr_to_iflist(pcap_if_t **alldevs, char *name, u_int flags,
struct sockaddr *addr, struct sockaddr *netmask,
struct sockaddr *broadaddr, struct sockaddr *dstaddr, char *errbuf)
struct sockaddr *addr, size_t addr_size,
struct sockaddr *netmask, size_t netmask_size,
struct sockaddr *broadaddr, size_t broadaddr_size,
struct sockaddr *dstaddr, size_t dstaddr_size,
char *errbuf)
{
pcap_if_t *curdev;
pcap_addr_t *curaddr, *prevaddr, *nextaddr;
@ -359,7 +321,7 @@ add_addr_to_iflist(pcap_if_t **alldevs, char *name, u_int flags,
curaddr->next = NULL;
if (addr != NULL) {
curaddr->addr = dup_sockaddr(addr);
curaddr->addr = dup_sockaddr(addr, addr_size);
if (curaddr->addr == NULL) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"malloc: %s", pcap_strerror(errno));
@ -370,7 +332,7 @@ add_addr_to_iflist(pcap_if_t **alldevs, char *name, u_int flags,
curaddr->addr = NULL;
if (netmask != NULL) {
curaddr->netmask = dup_sockaddr(netmask);
curaddr->netmask = dup_sockaddr(netmask, netmask_size);
if (curaddr->netmask == NULL) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"malloc: %s", pcap_strerror(errno));
@ -379,9 +341,9 @@ add_addr_to_iflist(pcap_if_t **alldevs, char *name, u_int flags,
}
} else
curaddr->netmask = NULL;
if (broadaddr != NULL) {
curaddr->broadaddr = dup_sockaddr(broadaddr);
curaddr->broadaddr = dup_sockaddr(broadaddr, broadaddr_size);
if (curaddr->broadaddr == NULL) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"malloc: %s", pcap_strerror(errno));
@ -390,9 +352,9 @@ add_addr_to_iflist(pcap_if_t **alldevs, char *name, u_int flags,
}
} else
curaddr->broadaddr = NULL;
if (dstaddr != NULL) {
curaddr->dstaddr = dup_sockaddr(dstaddr);
curaddr->dstaddr = dup_sockaddr(dstaddr, dstaddr_size);
if (curaddr->dstaddr == NULL) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"malloc: %s", pcap_strerror(errno));
@ -401,7 +363,7 @@ add_addr_to_iflist(pcap_if_t **alldevs, char *name, u_int flags,
}
} else
curaddr->dstaddr = NULL;
/*
* Find the end of the list of addresses.
*/
@ -431,7 +393,7 @@ add_addr_to_iflist(pcap_if_t **alldevs, char *name, u_int flags,
return (0);
}
static int
int
pcap_add_if(pcap_if_t **devlist, char *name, u_int flags,
const char *description, char *errbuf)
{
@ -441,464 +403,6 @@ pcap_add_if(pcap_if_t **devlist, char *name, u_int flags,
errbuf));
}
/*
* Get a list of all interfaces that are up and that we can open.
* Returns -1 on error, 0 otherwise.
* The list, as returned through "alldevsp", may be null if no interfaces
* were up and could be opened.
*/
#ifdef HAVE_IFADDRS_H
int
pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
{
pcap_if_t *devlist = NULL;
struct ifaddrs *ifap, *ifa;
struct sockaddr *broadaddr, *dstaddr;
int ret = 0;
/*
* Get the list of interface addresses.
*
* Note: this won't return information about interfaces
* with no addresses; are there any such interfaces
* that would be capable of receiving packets?
* (Interfaces incapable of receiving packets aren't
* very interesting from libpcap's point of view.)
*
* LAN interfaces will probably have link-layer
* addresses; I don't know whether all implementations
* of "getifaddrs()" now, or in the future, will return
* those.
*/
if (getifaddrs(&ifap) != 0) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"getifaddrs: %s", pcap_strerror(errno));
return (-1);
}
for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
/*
* Is this interface up?
*/
if (!(ifa->ifa_flags & IFF_UP)) {
/*
* No, so don't add it to the list.
*/
continue;
}
/*
* "ifa_broadaddr" may be non-null even on
* non-broadcast interfaces; "ifa_dstaddr"
* was, on at least one FreeBSD 4.1 system,
* non-null on a non-point-to-point
* interface.
*/
if (ifa->ifa_flags & IFF_BROADCAST)
broadaddr = ifa->ifa_broadaddr;
else
broadaddr = NULL;
if (ifa->ifa_flags & IFF_POINTOPOINT)
dstaddr = ifa->ifa_dstaddr;
else
dstaddr = NULL;
/*
* Add information for this address to the list.
*/
if (add_addr_to_iflist(&devlist, ifa->ifa_name,
ifa->ifa_flags, ifa->ifa_addr, ifa->ifa_netmask,
broadaddr, dstaddr, errbuf) < 0) {
ret = -1;
break;
}
}
freeifaddrs(ifap);
if (ret != -1) {
/*
* We haven't had any errors yet; add the "any" device,
* if we can open it.
*/
if (pcap_add_if(&devlist, "any", 0, any_descr, errbuf) < 0)
ret = -1;
}
if (ret == -1) {
/*
* We had an error; free the list we've been constructing.
*/
if (devlist != NULL) {
pcap_freealldevs(devlist);
devlist = NULL;
}
}
*alldevsp = devlist;
return (ret);
}
#else /* HAVE_IFADDRS_H */
#ifdef HAVE_PROC_NET_DEV
/*
* Get from "/proc/net/dev" all interfaces listed there; if they're
* already in the list of interfaces we have, that won't add another
* instance, but if they're not, that'll add them.
*
* We don't bother getting any addresses for them; it appears you can't
* use SIOCGIFADDR on Linux to get IPv6 addresses for interfaces, and,
* although some other types of addresses can be fetched with SIOCGIFADDR,
* we don't bother with them for now.
*
* We also don't fail if we couldn't open "/proc/net/dev"; we just leave
* the list of interfaces as is.
*/
static int
scan_proc_net_dev(pcap_if_t **devlistp, int fd, char *errbuf)
{
FILE *proc_net_f;
char linebuf[512];
int linenum;
unsigned char *p;
char name[512]; /* XXX - pick a size */
char *q, *saveq;
struct ifreq ifrflags;
int ret = 0;
proc_net_f = fopen("/proc/net/dev", "r");
if (proc_net_f == NULL)
return (0);
for (linenum = 1;
fgets(linebuf, sizeof linebuf, proc_net_f) != NULL; linenum++) {
/*
* Skip the first two lines - they're headers.
*/
if (linenum <= 2)
continue;
p = &linebuf[0];
/*
* Skip leading white space.
*/
while (*p != '\0' && isspace(*p))
p++;
if (*p == '\0' || *p == '\n')
continue; /* blank line */
/*
* Get the interface name.
*/
q = &name[0];
while (*p != '\0' && !isspace(*p)) {
if (*p == ':') {
/*
* This could be the separator between a
* name and an alias number, or it could be
* the separator between a name with no
* alias number and the next field.
*
* If there's a colon after digits, it
* separates the name and the alias number,
* otherwise it separates the name and the
* next field.
*/
saveq = q;
while (isdigit(*p))
*q++ = *p++;
if (*p != ':') {
/*
* That was the next field,
* not the alias number.
*/
q = saveq;
}
break;
} else
*q++ = *p++;
}
*q = '\0';
/*
* Get the flags for this interface, and skip it if
* it's not up.
*/
strncpy(ifrflags.ifr_name, name, sizeof(ifrflags.ifr_name));
if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifrflags) < 0) {
if (errno == ENXIO)
continue;
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"SIOCGIFFLAGS: %.*s: %s",
(int)sizeof(ifrflags.ifr_name),
ifrflags.ifr_name,
pcap_strerror(errno));
ret = -1;
break;
}
if (!(ifrflags.ifr_flags & IFF_UP))
continue;
/*
* Add an entry for this interface, with no addresses.
*/
if (pcap_add_if(devlistp, name, ifrflags.ifr_flags, NULL,
errbuf) == -1) {
/*
* Failure.
*/
ret = -1;
break;
}
}
if (ret != -1) {
/*
* Well, we didn't fail for any other reason; did we
* fail due to an error reading the file?
*/
if (ferror(proc_net_f)) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"Error reading /proc/net/dev: %s",
pcap_strerror(errno));
ret = -1;
}
}
(void)fclose(proc_net_f);
return (ret);
}
#endif /* HAVE_PROC_NET_DEV */
int
pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
{
pcap_if_t *devlist = NULL;
register int fd;
register struct ifreq *ifrp, *ifend, *ifnext;
int n;
struct ifconf ifc;
char *buf = NULL;
unsigned buf_size;
struct ifreq ifrflags, ifrnetmask, ifrbroadaddr, ifrdstaddr;
struct sockaddr *netmask, *broadaddr, *dstaddr;
int ret = 0;
/*
* Create a socket from which to fetch the list of interfaces.
*/
fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd < 0) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"socket: %s", pcap_strerror(errno));
return (-1);
}
/*
* Start with an 8K buffer, and keep growing the buffer until
* we get the entire interface list or fail to get it for some
* reason other than EINVAL (which is presumed here to mean
* "buffer is too small").
*/
buf_size = 8192;
for (;;) {
buf = malloc(buf_size);
if (buf == NULL) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"malloc: %s", pcap_strerror(errno));
(void)close(fd);
return (-1);
}
ifc.ifc_len = buf_size;
ifc.ifc_buf = buf;
memset(buf, 0, buf_size);
if (ioctl(fd, SIOCGIFCONF, (char *)&ifc) < 0
&& errno != EINVAL) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"SIOCGIFCONF: %s", pcap_strerror(errno));
(void)close(fd);
free(buf);
return (-1);
}
if (ifc.ifc_len < buf_size)
break;
free(buf);
buf_size *= 2;
}
ifrp = (struct ifreq *)buf;
ifend = (struct ifreq *)(buf + ifc.ifc_len);
for (; ifrp < ifend; ifrp = ifnext) {
n = SA_LEN(&ifrp->ifr_addr) + sizeof(ifrp->ifr_name);
if (n < sizeof(*ifrp))
ifnext = ifrp + 1;
else
ifnext = (struct ifreq *)((char *)ifrp + n);
/*
* Get the flags for this interface, and skip it if it's
* not up.
*/
strncpy(ifrflags.ifr_name, ifrp->ifr_name,
sizeof(ifrflags.ifr_name));
if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifrflags) < 0) {
if (errno == ENXIO)
continue;
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"SIOCGIFFLAGS: %.*s: %s",
(int)sizeof(ifrflags.ifr_name),
ifrflags.ifr_name,
pcap_strerror(errno));
ret = -1;
break;
}
if (!(ifrflags.ifr_flags & IFF_UP))
continue;
/*
* Get the netmask for this address on this interface.
*/
strncpy(ifrnetmask.ifr_name, ifrp->ifr_name,
sizeof(ifrnetmask.ifr_name));
memcpy(&ifrnetmask.ifr_addr, &ifrp->ifr_addr,
sizeof(ifrnetmask.ifr_addr));
if (ioctl(fd, SIOCGIFNETMASK, (char *)&ifrnetmask) < 0) {
if (errno == EADDRNOTAVAIL) {
/*
* Not available.
*/
netmask = NULL;
} else {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"SIOCGIFNETMASK: %.*s: %s",
(int)sizeof(ifrnetmask.ifr_name),
ifrnetmask.ifr_name,
pcap_strerror(errno));
ret = -1;
break;
}
} else
netmask = &ifrnetmask.ifr_addr;
/*
* Get the broadcast address for this address on this
* interface (if any).
*/
if (ifrflags.ifr_flags & IFF_BROADCAST) {
strncpy(ifrbroadaddr.ifr_name, ifrp->ifr_name,
sizeof(ifrbroadaddr.ifr_name));
memcpy(&ifrbroadaddr.ifr_addr, &ifrp->ifr_addr,
sizeof(ifrbroadaddr.ifr_addr));
if (ioctl(fd, SIOCGIFBRDADDR,
(char *)&ifrbroadaddr) < 0) {
if (errno == EADDRNOTAVAIL) {
/*
* Not available.
*/
broadaddr = NULL;
} else {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"SIOCGIFBRDADDR: %.*s: %s",
(int)sizeof(ifrbroadaddr.ifr_name),
ifrbroadaddr.ifr_name,
pcap_strerror(errno));
ret = -1;
break;
}
} else
broadaddr = &ifrbroadaddr.ifr_broadaddr;
} else {
/*
* Not a broadcast interface, so no broadcast
* address.
*/
broadaddr = NULL;
}
/*
* Get the destination address for this address on this
* interface (if any).
*/
if (ifrflags.ifr_flags & IFF_POINTOPOINT) {
strncpy(ifrdstaddr.ifr_name, ifrp->ifr_name,
sizeof(ifrdstaddr.ifr_name));
memcpy(&ifrdstaddr.ifr_addr, &ifrp->ifr_addr,
sizeof(ifrdstaddr.ifr_addr));
if (ioctl(fd, SIOCGIFDSTADDR,
(char *)&ifrdstaddr) < 0) {
if (errno == EADDRNOTAVAIL) {
/*
* Not available.
*/
dstaddr = NULL;
} else {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"SIOCGIFDSTADDR: %.*s: %s",
(int)sizeof(ifrdstaddr.ifr_name),
ifrdstaddr.ifr_name,
pcap_strerror(errno));
ret = -1;
break;
}
} else
dstaddr = &ifrdstaddr.ifr_dstaddr;
} else
dstaddr = NULL;
/*
* Add information for this address to the list.
*/
if (add_addr_to_iflist(&devlist, ifrp->ifr_name,
ifrflags.ifr_flags, &ifrp->ifr_addr,
netmask, broadaddr, dstaddr, errbuf) < 0) {
ret = -1;
break;
}
}
free(buf);
#ifdef HAVE_PROC_NET_DEV
if (ret != -1) {
/*
* We haven't had any errors yet; now read "/proc/net/dev",
* and add to the list of interfaces all interfaces listed
* there that we don't already have, because, on Linux,
* SIOCGIFCONF reports only interfaces with IPv4 addresses,
* so you need to read "/proc/net/dev" to get the names of
* the rest of the interfaces.
*/
ret = scan_proc_net_dev(&devlist, fd, errbuf);
}
#endif
(void)close(fd);
if (ret != -1) {
/*
* We haven't had any errors yet; add the "any" device,
* if we can open it.
*/
if (pcap_add_if(&devlist, "any", 0, any_descr, errbuf) < 0) {
/*
* Oops, we had a fatal error.
*/
ret = -1;
}
}
if (ret == -1) {
/*
* We had an error; free the list we've been constructing.
*/
if (devlist != NULL) {
pcap_freealldevs(devlist);
devlist = NULL;
}
}
*alldevsp = devlist;
return (ret);
}
#endif /* HAVE_IFADDRS_H */
/*
* Free a list of interfaces.
@ -946,6 +450,8 @@ pcap_freealldevs(pcap_if_t *alldevs)
}
}
#ifndef WIN32
/*
* Return the name of a network interface attached to the system, or NULL
* if none can be found. The interface must be configured up; the
@ -965,7 +471,7 @@ pcap_lookupdev(errbuf)
if (pcap_findalldevs(&alldevs, errbuf) == -1)
return (NULL);
if (alldevs == NULL || (alldevs->flags & PCAP_IF_LOOPBACK)) {
/*
* There are no devices on the list, or the first device
@ -995,7 +501,7 @@ pcap_lookupdev(errbuf)
int
pcap_lookupnet(device, netp, maskp, errbuf)
register char *device;
register const char *device;
register bpf_u_int32 *netp, *maskp;
register char *errbuf;
{
@ -1003,12 +509,16 @@ pcap_lookupnet(device, netp, maskp, errbuf)
register struct sockaddr_in *sin;
struct ifreq ifr;
/*
/*
* The pseudo-device "any" listens on all interfaces and therefore
* has the network address and -mask "0.0.0.0" therefore catching
* all traffic. Using NULL for the interface is the same as "any".
*/
if (!device || strcmp(device, "any") == 0) {
if (!device || strcmp(device, "any") == 0
#ifdef HAVE_DAG_API
|| strstr(device, "dag") != NULL
#endif
) {
*netp = *maskp = 0;
return 0;
}
@ -1063,3 +573,121 @@ pcap_lookupnet(device, netp, maskp, errbuf)
*netp &= *maskp;
return (0);
}
#else /* WIN32 */
/*
* Return the name of a network interface attached to the system, or NULL
* if none can be found. The interface must be configured up; the
* lowest unit number is preferred; loopback is ignored.
*/
char *
pcap_lookupdev(errbuf)
register char *errbuf;
{
DWORD dwVersion;
DWORD dwWindowsMajorVersion;
dwVersion = GetVersion(); /* get the OS version */
dwWindowsMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
if (dwVersion >= 0x80000000 && dwWindowsMajorVersion >= 4) {
/*
* Windows 95, 98, ME.
*/
ULONG NameLength = 8192;
static char AdaptersName[8192];
PacketGetAdapterNames(AdaptersName,&NameLength);
return (AdaptersName);
} else {
/*
* Windows NT (NT 4.0, W2K, WXP). Convert the names to UNICODE for backward compatibility
*/
ULONG NameLength = 8192;
static WCHAR AdaptersName[8192];
char *tAstr;
WCHAR *tUstr;
WCHAR *TAdaptersName = (WCHAR*)malloc(8192 * sizeof(WCHAR));
int NAdapts = 0;
if(TAdaptersName == NULL)
{
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE, "memory allocation failure");
return NULL;
}
PacketGetAdapterNames((PTSTR)TAdaptersName,&NameLength);
tAstr = (char*)TAdaptersName;
tUstr = (WCHAR*)AdaptersName;
/*
* Convert and copy the device names
*/
while(sscanf(tAstr, "%S", tUstr) > 0)
{
tAstr += strlen(tAstr) + 1;
tUstr += wcslen(tUstr) + 1;
NAdapts ++;
}
tAstr++;
*tUstr = 0;
tUstr++;
/*
* Copy the descriptions
*/
while(NAdapts--)
{
strcpy((char*)tUstr, tAstr);
(char*)tUstr += strlen(tAstr) + 1;;
tAstr += strlen(tAstr) + 1;
}
return (char *)(AdaptersName);
}
}
int
pcap_lookupnet(device, netp, maskp, errbuf)
const register char *device;
register bpf_u_int32 *netp, *maskp;
register char *errbuf;
{
/*
* We need only the first IPv4 address, so we must scan the array returned by PacketGetNetInfo()
* in order to skip non IPv4 (i.e. IPv6 addresses)
*/
npf_if_addr if_addrs[MAX_NETWORK_ADDRESSES];
LONG if_addr_size = 1;
struct sockaddr_in *t_addr;
unsigned int i;
if (!PacketGetNetInfoEx((void *)device, if_addrs, &if_addr_size)) {
*netp = *maskp = 0;
return (0);
}
for(i=0; i<MAX_NETWORK_ADDRESSES; i++)
{
if(if_addrs[i].IPAddress.ss_family == AF_INET)
{
t_addr = (struct sockaddr_in *) &(if_addrs[i].IPAddress);
*netp = t_addr->sin_addr.S_un.S_addr;
t_addr = (struct sockaddr_in *) &(if_addrs[i].SubnetMask);
*maskp = t_addr->sin_addr.S_un.S_addr;
*netp &= *maskp;
return (0);
}
}
*netp = *maskp = 0;
return (0);
}
#endif /* WIN32 */

View File

@ -0,0 +1,25 @@
/*
* 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.
*
* @(#) $Header: /tcpdump/master/libpcap/lbl/os-aix4.h,v 1.1 2002/06/01 09:37:40 guy Exp $
*/
/* Prototypes missing in AIX 4.x */
int ffs(int i);

View File

@ -0,0 +1,25 @@
/*
* 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.
*
* @(#) $Header: /tcpdump/master/libpcap/lbl/os-hpux11.h,v 1.1 2002/06/01 09:37:41 guy Exp $
*/
/* Prototypes missing in HP-UX 11.x */
int ffs(int i);

View File

@ -0,0 +1,32 @@
/*
* 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.
*
* @(#) $Header: /tcpdump/master/libpcap/lbl/os-osf5.h,v 1.2 2002/08/02 03:24:15 guy Exp $ (LBL)
*/
/*
* Prototypes missing in Tru64 UNIX 5.x
* XXX - "snprintf()" and "vsnprintf()" aren't missing, but you have to
* #define the right value to get them defined by <stdio.h>.
*/
int snprintf(char *, size_t, const char *, ...);
int vsnprintf(char *, size_t, const char *, va_list);
int pfopen(char *, int);

View File

@ -23,37 +23,51 @@
*/
#ifndef lint
static const char rcsid[] =
"@(#) $Header: /tcpdump/master/libpcap/nametoaddr.c,v 1.60 2001/07/28 22:56:35 guy Exp $ (LBL)";
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/nametoaddr.c,v 1.68.2.3 2003/11/19 18:13:48 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef WIN32
#include <pcap-stdinc.h>
#else /* WIN32 */
#include <sys/param.h>
#include <sys/types.h> /* concession to AIX */
#include <sys/socket.h>
#include <sys/time.h>
struct mbuf;
struct rtentry;
#include <net/if.h>
#include <netinet/in.h>
#ifdef HAVE_NETINET_IF_ETHER_H
#include <netinet/if_ether.h>
#endif /* WIN32 */
/*
* XXX - why was this included even on UNIX?
*/
#ifdef __MINGW32__
#include "IP6_misc.h"
#endif
#ifndef WIN32
#ifdef HAVE_ETHER_HOSTTON
#ifdef HAVE_NETINET_IF_ETHER_H
struct mbuf; /* Squelch compiler warnings on some platforms for */
struct rtentry; /* declarations in <net/if.h> */
#include <net/if.h> /* for "struct ifnet" in "struct arpcom" on Solaris */
#include <netinet/if_ether.h>
#endif /* HAVE_NETINET_IF_ETHER_H */
#endif /* HAVE_ETHER_HOSTTON */
#include <arpa/inet.h>
#ifdef INET6
#include <netdb.h>
#include <sys/socket.h>
#endif /*INET6*/
#endif /* WIN32 */
#include <ctype.h>
#include <errno.h>
#include <stdlib.h>
#include <memory.h>
#include <netdb.h>
#include <stdio.h>
#include "pcap-int.h"
@ -125,12 +139,19 @@ pcap_nametoaddrinfo(const char *name)
bpf_u_int32
pcap_nametonetaddr(const char *name)
{
#ifndef WIN32
struct netent *np;
if ((np = getnetbyname(name)) != NULL)
return np->n_net;
else
return 0;
#else
/*
* There's no "getnetbyname()" on Windows.
*/
return 0;
#endif
}
/*
@ -142,38 +163,40 @@ int
pcap_nametoport(const char *name, int *port, int *proto)
{
struct servent *sp;
char *other;
int tcp_port = -1;
int udp_port = -1;
sp = getservbyname(name, (char *)0);
if (sp != NULL) {
NTOHS(sp->s_port);
*port = sp->s_port;
*proto = pcap_nametoproto(sp->s_proto);
/*
* We need to check /etc/services for ambiguous entries.
* If we find the ambiguous entry, and it has the
* same port number, change the proto to PROTO_UNDEF
* so both TCP and UDP will be checked.
*/
if (*proto == IPPROTO_TCP)
other = "udp";
else
other = "tcp";
sp = getservbyname(name, other);
if (sp != 0) {
NTOHS(sp->s_port);
/*
* We need to check /etc/services for ambiguous entries.
* If we find the ambiguous entry, and it has the
* same port number, change the proto to PROTO_UNDEF
* so both TCP and UDP will be checked.
*/
sp = getservbyname(name, "tcp");
if (sp != NULL) tcp_port = ntohs(sp->s_port);
sp = getservbyname(name, "udp");
if (sp != NULL) udp_port = ntohs(sp->s_port);
if (tcp_port >= 0) {
*port = tcp_port;
*proto = IPPROTO_TCP;
if (udp_port >= 0) {
if (udp_port == tcp_port)
*proto = PROTO_UNDEF;
#ifdef notdef
if (*port != sp->s_port)
else
/* Can't handle ambiguous names that refer
to different port numbers. */
warning("ambiguous port %s in /etc/services",
name);
#endif
*proto = PROTO_UNDEF;
}
return 1;
}
if (udp_port >= 0) {
*port = udp_port;
*proto = IPPROTO_UDP;
return 1;
}
#if defined(ultrix) || defined(__osf__)
/* Special hack in case NFS isn't in /etc/services */
if (strcmp(name, "nfs") == 0) {
@ -342,7 +365,7 @@ pcap_ether_hostton(const char *name)
return (NULL);
else
rewind(fp);
while ((ep = pcap_next_etherent(fp)) != NULL) {
if (strcmp(ep->name, name) == 0) {
ap = (u_char *)malloc(6);
@ -366,7 +389,8 @@ pcap_ether_hostton(const char *name)
* "const char *", so no matter how we declare it here, it'll fail to
* compile on one of 3.x or 4.x).
*/
#if !defined(sgi) && !defined(__NetBSD__) && !defined(__FreeBSD__)
#if !defined(sgi) && !defined(__NetBSD__) && !defined(__FreeBSD__) && \
!defined(_UNICOSMP)
extern int ether_hostton(char *, struct ether_addr *);
#endif

View File

@ -15,7 +15,7 @@
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* @(#) $Header: /tcpdump/master/libpcap/nlpid.h,v 1.1 2000/10/28 09:30:22 guy Exp $ (Juniper)
* @(#) $Header: /tcpdump/master/libpcap/nlpid.h,v 1.2 2002/12/06 00:01:34 hannes Exp $ (Juniper)
*/
/* Types missing from some systems */
@ -35,6 +35,21 @@
#ifndef ISO10589_ISIS
#define ISO10589_ISIS 0x83
#endif
/*
* this does not really belong in the nlpid.h file
* however we need it for generating nice
* IS-IS related BPF filters
*/
#define ISIS_L1_LAN_IIH 15
#define ISIS_L2_LAN_IIH 16
#define ISIS_PTP_IIH 17
#define ISIS_L1_LSP 18
#define ISIS_L2_LSP 20
#define ISIS_L1_CSNP 24
#define ISIS_L2_CSNP 25
#define ISIS_L1_PSNP 26
#define ISIS_L2_PSNP 27
#ifndef ISO8878A_CONS
#define ISO8878A_CONS 0x84
#endif

View File

@ -21,17 +21,14 @@
* Optimization module for tcpdump intermediate representation.
*/
#ifndef lint
static const char rcsid[] =
"@(#) $Header: /tcpdump/master/libpcap/optimize.c,v 1.69 2001/11/12 21:57:06 fenner Exp $ (LBL)";
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/optimize.c,v 1.76.2.3 2003/12/22 00:26:36 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <sys/types.h>
#include <sys/time.h>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
@ -120,9 +117,6 @@ static void opt_peep(struct block *);
static void opt_stmt(struct stmt *, int[], int);
static void deadstmt(struct stmt *, struct stmt *[]);
static void opt_deadstores(struct block *);
static void opt_blk(struct block *, int);
static int use_conflict(struct block *, struct block *);
static void opt_j(struct edge *);
static struct block *fold_edge(struct block *, struct edge *);
static inline int eq_blk(struct block *, struct block *);
static int slength(struct slist *);
@ -766,50 +760,39 @@ opt_peep(b)
* is a known constant, we can merge this value into the
* comparison.
*/
if (last->s.code == (BPF_ALU|BPF_SUB|BPF_X) &&
!ATOMELEM(b->out_use, A_ATOM)) {
val = b->val[X_ATOM];
if (vmap[val].is_const) {
int op;
b->s.k += vmap[val].const_val;
op = BPF_OP(b->s.code);
if (op == BPF_JGT || op == BPF_JGE) {
struct block *t = JT(b);
JT(b) = JF(b);
JF(b) = t;
b->s.k += 0x80000000;
if (BPF_OP(b->s.code) == BPF_JEQ) {
if (last->s.code == (BPF_ALU|BPF_SUB|BPF_X) &&
!ATOMELEM(b->out_use, A_ATOM)) {
val = b->val[X_ATOM];
if (vmap[val].is_const) {
/*
* sub x -> nop
* jeq #y jeq #(x+y)
*/
b->s.k += vmap[val].const_val;
last->s.code = NOP;
done = 0;
} else if (b->s.k == 0) {
/*
* sub #x -> nop
* jeq #0 jeq #x
*/
last->s.code = NOP;
b->s.code = BPF_CLASS(b->s.code) |
BPF_OP(b->s.code) | BPF_X;
done = 0;
}
last->s.code = NOP;
done = 0;
} else if (b->s.k == 0) {
/*
* sub x -> nop
* j #0 j x
*/
last->s.code = NOP;
b->s.code = BPF_CLASS(b->s.code) | BPF_OP(b->s.code) |
BPF_X;
done = 0;
}
}
/*
* Likewise, a constant subtract can be simplified.
*/
else if (last->s.code == (BPF_ALU|BPF_SUB|BPF_K) &&
!ATOMELEM(b->out_use, A_ATOM)) {
int op;
/*
* Likewise, a constant subtract can be simplified.
*/
else if (last->s.code == (BPF_ALU|BPF_SUB|BPF_K) &&
!ATOMELEM(b->out_use, A_ATOM)) {
b->s.k += last->s.k;
last->s.code = NOP;
op = BPF_OP(b->s.code);
if (op == BPF_JGT || op == BPF_JGE) {
struct block *t = JT(b);
JT(b) = JF(b);
JF(b) = t;
b->s.k += 0x80000000;
last->s.code = NOP;
b->s.k += last->s.k;
done = 0;
}
done = 0;
}
/*
* and #k nop
@ -823,6 +806,16 @@ opt_peep(b)
done = 0;
opt_not(b);
}
/*
* jset #0 -> never
* jset #ffffffff -> always
*/
if (b->s.code == (BPF_JMP|BPF_K|BPF_JSET)) {
if (b->s.k == 0)
JT(b) = JF(b);
if (b->s.k == 0xffffffff)
JF(b) = JT(b);
}
/*
* If the accumulator is a known constant, we can compute the
* comparison result.
@ -992,18 +985,17 @@ opt_stmt(s, val, alter)
* that is 0, and simplify. This may not seem like
* much of a simplification but it could open up further
* optimizations.
* XXX We could also check for mul by 1, and -1, etc.
* XXX We could also check for mul by 1, etc.
*/
if (alter && vmap[val[A_ATOM]].is_const
&& vmap[val[A_ATOM]].const_val == 0) {
if (op == BPF_ADD || op == BPF_OR ||
op == BPF_LSH || op == BPF_RSH || op == BPF_SUB) {
if (op == BPF_ADD || op == BPF_OR) {
s->code = BPF_MISC|BPF_TXA;
vstore(s, &val[A_ATOM], val[X_ATOM], alter);
break;
}
else if (op == BPF_MUL || op == BPF_DIV ||
op == BPF_AND) {
op == BPF_AND || op == BPF_LSH || op == BPF_RSH) {
s->code = BPF_LD|BPF_IMM;
s->k = 0;
vstore(s, &val[A_ATOM], K(s->k), alter);
@ -1148,7 +1140,7 @@ opt_blk(b, do_stmts)
* already there, or if this block is a return,
* eliminate all the statements.
*/
if (do_stmts &&
if (do_stmts &&
((b->out_use == 0 && aval != 0 &&b->val[A_ATOM] == aval) ||
BPF_CLASS(b->s.code) == BPF_RET)) {
if (b->stmts != 0) {
@ -1851,17 +1843,23 @@ opt_init(root)
unMarkAll();
n = count_blocks(root);
blocks = (struct block **)malloc(n * sizeof(*blocks));
if (blocks == NULL)
bpf_error("malloc");
unMarkAll();
n_blocks = 0;
number_blks_r(root);
n_edges = 2 * n_blocks;
edges = (struct edge **)malloc(n_edges * sizeof(*edges));
if (edges == NULL)
bpf_error("malloc");
/*
* The number of levels is bounded by the number of nodes.
*/
levels = (struct block **)malloc(n_blocks * sizeof(*levels));
if (levels == NULL)
bpf_error("malloc");
edgewords = n_edges / (8 * sizeof(bpf_u_int32)) + 1;
nodewords = n_blocks / (8 * sizeof(bpf_u_int32)) + 1;
@ -1869,6 +1867,8 @@ opt_init(root)
/* XXX */
space = (bpf_u_int32 *)malloc(2 * n_blocks * nodewords * sizeof(*space)
+ n_edges * edgewords * sizeof(*space));
if (space == NULL)
bpf_error("malloc");
p = space;
all_dom_sets = p;
for (i = 0; i < n; ++i) {
@ -1906,6 +1906,8 @@ opt_init(root)
maxval = 3 * max_stmts;
vmap = (struct vmapinfo *)malloc(maxval * sizeof(*vmap));
vnode_base = (struct valnode *)malloc(maxval * sizeof(*vnode_base));
if (vmap == NULL || vnode_base == NULL)
bpf_error("malloc");
}
/*
@ -1954,7 +1956,7 @@ convert_code_r(p)
/* generate offset[] for convenience */
if (slen) {
offset = (struct slist **)calloc(sizeof(struct slist *), slen);
offset = (struct slist **)calloc(slen, sizeof(struct slist *));
if (!offset) {
bpf_error("not enough core");
/*NOTREACHED*/
@ -2100,12 +2102,14 @@ icode_to_fcode(root, lenp)
while (1) {
unMarkAll();
n = *lenp = count_stmts(root);
fp = (struct bpf_insn *)malloc(sizeof(*fp) * n);
if (fp == NULL)
bpf_error("malloc");
memset((char *)fp, 0, sizeof(*fp) * n);
fstart = fp;
ftail = fp + n;
unMarkAll();
if (convert_code_r(root))
break;

View File

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

View File

@ -19,8 +19,8 @@
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef lint
static const char rcsid[] =
"@(#) $Header: /tcpdump/master/libpcap/pcap-bpf.c,v 1.48 2001/12/10 07:14:14 guy Exp $ (LBL)";
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/pcap-bpf.c,v 1.67.2.4 2003/11/22 00:06:28 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@ -33,18 +33,56 @@ static const char rcsid[] =
#include <sys/socket.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#include <sys/utsname.h>
#include <net/if.h>
#ifdef _AIX
/*
* XXX - I'm guessing here AIX defines IFT_ values in <net/if_types.h>,
* as BSD does. If not, this code won't compile, but, if not, you
* want to send us a bug report and fall back on using DLPI.
* It's not as if BPF used to work right on AIX before this change;
* this change attempts to fix the fact that it didn't....
* Make "pcap.h" not include "pcap-bpf.h"; we are going to include the
* native OS version, as we need "struct bpf_config" from it.
*/
#define PCAP_DONT_INCLUDE_PCAP_BPF_H
#include <sys/types.h>
/*
* Prevent bpf.h from redefining the DLT_ values to their
* IFT_ values, as we're going to return the standard libpcap
* values, not IBM's non-standard IFT_ values.
*/
#undef _AIX
#include <net/bpf.h>
#define _AIX
#include <net/if_types.h> /* for IFT_ values */
#endif
#include <sys/sysconfig.h>
#include <sys/device.h>
#include <odmi.h>
#include <cf.h>
#ifdef __64BIT__
#define domakedev makedev64
#define getmajor major64
#define bpf_hdr bpf_hdr32
#else /* __64BIT__ */
#define domakedev makedev
#define getmajor major
#endif /* __64BIT__ */
#define BPF_NAME "bpf"
#define BPF_MINORS 4
#define DRIVER_PATH "/usr/lib/drivers"
#define BPF_NODE "/dev/bpf"
static int bpfloadedflag = 0;
static int odmlockid = 0;
#else /* _AIX */
#include <net/bpf.h>
#endif /* _AIX */
#include <ctype.h>
#include <errno.h>
@ -56,14 +94,21 @@ static const char rcsid[] =
#include "pcap-int.h"
#ifdef HAVE_DAG_API
#include "pcap-dag.h"
#endif /* HAVE_DAG_API */
#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
#include "gencode.h"
#include "gencode.h" /* for "no_optimize" */
int
pcap_stats(pcap_t *p, struct pcap_stat *ps)
static int pcap_setfilter_bpf(pcap_t *p, struct bpf_program *fp);
static int pcap_set_datalink_bpf(pcap_t *p, int dlt);
static int
pcap_stats_bpf(pcap_t *p, struct pcap_stat *ps)
{
struct bpf_stat s;
@ -91,14 +136,28 @@ pcap_stats(pcap_t *p, struct pcap_stat *ps)
return (0);
}
int
pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
static int
pcap_read_bpf(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
{
int cc;
int n = 0;
register u_char *bp, *ep;
struct bpf_insn *fcode;
fcode = p->md.use_bpf ? NULL : p->fcode.bf_insns;
again:
/*
* Has "pcap_breakloop()" been called?
*/
if (p->break_loop) {
/*
* Yes - clear the flag that indicates that it
* has, and return -2 to indicate that we were
* told to break out of the loop.
*/
p->break_loop = 0;
return (-2);
}
cc = p->cc;
if (p->cc == 0) {
cc = read(p->fd, (char *)p->buffer, p->bufsize);
@ -109,6 +168,32 @@ pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
case EINTR:
goto again;
#ifdef _AIX
case EFAULT:
/*
* Sigh. More AIX wonderfulness.
*
* For some unknown reason the uiomove()
* operation in the bpf kernel extension
* used to copy the buffer into user
* space sometimes returns EFAULT. I have
* no idea why this is the case given that
* a kernel debugger shows the user buffer
* is correct. This problem appears to
* be mostly mitigated by the memset of
* the buffer before it is first used.
* Very strange.... Shaun Clowes
*
* In any case this means that we shouldn't
* treat EFAULT as a fatal error; as we
* don't have an API for returning
* a "some packets were dropped since
* the last packet you saw" indication,
* we just ignore EFAULT and keep reading.
*/
goto again;
#endif
case EWOULDBLOCK:
return (0);
#if defined(sun) && !defined(BSD)
@ -141,31 +226,65 @@ pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
ep = bp + cc;
while (bp < ep) {
register int caplen, hdrlen;
/*
* Has "pcap_breakloop()" been called?
* If so, return immediately - if we haven't read any
* packets, clear the flag and return -2 to indicate
* that we were told to break out of the loop, otherwise
* leave the flag set, so that the *next* call will break
* out of the loop without having read any packets, and
* return the number of packets we've processed so far.
*/
if (p->break_loop) {
if (n == 0) {
p->break_loop = 0;
return (-2);
} else {
p->bp = bp;
p->cc = ep - bp;
return (n);
}
}
caplen = bhp->bh_caplen;
hdrlen = bhp->bh_hdrlen;
/*
* XXX A bpf_hdr matches a pcap_pkthdr.
* Short-circuit evaluation: if using BPF filter
* in kernel, no need to do it now.
*/
if (fcode == NULL ||
bpf_filter(fcode, bp + hdrlen, bhp->bh_datalen, caplen)) {
#ifdef _AIX
/*
* AIX's BPF returns seconds/nanoseconds time stamps, not
* seconds/microseconds time stamps.
*
* XXX - I'm guessing here that it's a "struct timestamp";
* if not, this code won't compile, but, if not, you
* want to send us a bug report and fall back on using
* DLPI. It's not as if BPF used to work right on
* AIX before this change; this change attempts to fix
* the fact that it didn't....
*/
bhp->bh_tstamp.tv_usec = bhp->bh_tstamp.tv_usec/1000;
/*
* AIX's BPF returns seconds/nanoseconds time
* stamps, not seconds/microseconds time stamps.
*
* XXX - I'm guessing here that it's a "struct
* timestamp"; if not, this code won't compile,
* but, if not, you want to send us a bug report
* and fall back on using DLPI. It's not as if
* BPF used to work right on AIX before this
* change; this change attempts to fix the fact
* that it didn't....
*/
bhp->bh_tstamp.tv_usec = bhp->bh_tstamp.tv_usec/1000;
#endif
(*callback)(user, (struct pcap_pkthdr*)bp, bp + hdrlen);
bp += BPF_WORDALIGN(caplen + hdrlen);
if (++n >= cnt && cnt > 0) {
p->bp = bp;
p->cc = ep - bp;
return (n);
/*
* XXX A bpf_hdr matches a pcap_pkthdr.
*/
(*callback)(user, (struct pcap_pkthdr*)bp, bp + hdrlen);
bp += BPF_WORDALIGN(caplen + hdrlen);
if (++n >= cnt && cnt > 0) {
p->bp = bp;
p->cc = ep - bp;
return (n);
}
} else {
/*
* Skip this packet.
*/
bp += BPF_WORDALIGN(caplen + hdrlen);
}
}
#undef bhp
@ -173,6 +292,159 @@ pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
return (n);
}
#ifdef _AIX
static int
bpf_odminit(char *errbuf)
{
char *errstr;
if (odm_initialize() == -1) {
if (odm_err_msg(odmerrno, &errstr) == -1)
errstr = "Unknown error";
snprintf(errbuf, PCAP_ERRBUF_SIZE,
"bpf_load: odm_initialize failed: %s",
errstr);
return (-1);
}
if ((odmlockid = odm_lock("/etc/objrepos/config_lock", ODM_WAIT)) == -1) {
if (odm_err_msg(odmerrno, &errstr) == -1)
errstr = "Unknown error";
snprintf(errbuf, PCAP_ERRBUF_SIZE,
"bpf_load: odm_lock of /etc/objrepos/config_lock failed: %s",
errstr);
return (-1);
}
return (0);
}
static int
bpf_odmcleanup(char *errbuf)
{
char *errstr;
if (odm_unlock(odmlockid) == -1) {
if (odm_err_msg(odmerrno, &errstr) == -1)
errstr = "Unknown error";
snprintf(errbuf, PCAP_ERRBUF_SIZE,
"bpf_load: odm_unlock failed: %s",
errstr);
return (-1);
}
if (odm_terminate() == -1) {
if (odm_err_msg(odmerrno, &errstr) == -1)
errstr = "Unknown error";
snprintf(errbuf, PCAP_ERRBUF_SIZE,
"bpf_load: odm_terminate failed: %s",
errstr);
return (-1);
}
return (0);
}
static int
bpf_load(char *errbuf)
{
long major;
int *minors;
int numminors, i, rc;
char buf[1024];
struct stat sbuf;
struct bpf_config cfg_bpf;
struct cfg_load cfg_ld;
struct cfg_kmod cfg_km;
/*
* This is very very close to what happens in the real implementation
* but I've fixed some (unlikely) bug situations.
*/
if (bpfloadedflag)
return (0);
if (bpf_odminit(errbuf) != 0)
return (-1);
major = genmajor(BPF_NAME);
if (major == -1) {
snprintf(errbuf, PCAP_ERRBUF_SIZE,
"bpf_load: genmajor failed: %s", pcap_strerror(errno));
return (-1);
}
minors = getminor(major, &numminors, BPF_NAME);
if (!minors) {
minors = genminor("bpf", major, 0, BPF_MINORS, 1, 1);
if (!minors) {
snprintf(errbuf, PCAP_ERRBUF_SIZE,
"bpf_load: genminor failed: %s",
pcap_strerror(errno));
return (-1);
}
}
if (bpf_odmcleanup(errbuf))
return (-1);
rc = stat(BPF_NODE "0", &sbuf);
if (rc == -1 && errno != ENOENT) {
snprintf(errbuf, PCAP_ERRBUF_SIZE,
"bpf_load: can't stat %s: %s",
BPF_NODE "0", pcap_strerror(errno));
return (-1);
}
if (rc == -1 || getmajor(sbuf.st_rdev) != major) {
for (i = 0; i < BPF_MINORS; i++) {
sprintf(buf, "%s%d", BPF_NODE, i);
unlink(buf);
if (mknod(buf, S_IRUSR | S_IFCHR, domakedev(major, i)) == -1) {
snprintf(errbuf, PCAP_ERRBUF_SIZE,
"bpf_load: can't mknod %s: %s",
buf, pcap_strerror(errno));
return (-1);
}
}
}
/* Check if the driver is loaded */
memset(&cfg_ld, 0x0, sizeof(cfg_ld));
cfg_ld.path = buf;
sprintf(cfg_ld.path, "%s/%s", DRIVER_PATH, BPF_NAME);
if ((sysconfig(SYS_QUERYLOAD, (void *)&cfg_ld, sizeof(cfg_ld)) == -1) ||
(cfg_ld.kmid == 0)) {
/* Driver isn't loaded, load it now */
if (sysconfig(SYS_SINGLELOAD, (void *)&cfg_ld, sizeof(cfg_ld)) == -1) {
snprintf(errbuf, PCAP_ERRBUF_SIZE,
"bpf_load: could not load driver: %s",
strerror(errno));
return (-1);
}
}
/* Configure the driver */
cfg_km.cmd = CFG_INIT;
cfg_km.kmid = cfg_ld.kmid;
cfg_km.mdilen = sizeof(cfg_bpf);
cfg_km.mdiptr = (void *)&cfg_bpf;
for (i = 0; i < BPF_MINORS; i++) {
cfg_bpf.devno = domakedev(major, i);
if (sysconfig(SYS_CFGKMOD, (void *)&cfg_km, sizeof(cfg_km)) == -1) {
snprintf(errbuf, PCAP_ERRBUF_SIZE,
"bpf_load: could not configure driver: %s",
strerror(errno));
return (-1);
}
}
bpfloadedflag = 1;
return (0);
}
#endif
static inline int
bpf_open(pcap_t *p, char *errbuf)
{
@ -180,6 +452,16 @@ bpf_open(pcap_t *p, char *errbuf)
int n = 0;
char device[sizeof "/dev/bpf0000000000"];
#ifdef _AIX
/*
* Load the bpf driver, if it isn't already loaded,
* and create the BPF device entries, if they don't
* already exist.
*/
if (bpf_load(errbuf) == -1)
return (-1);
#endif
/*
* Go through all the minors and find one that isn't in use.
*/
@ -198,17 +480,48 @@ bpf_open(pcap_t *p, char *errbuf)
return (fd);
}
static void
pcap_close_bpf(pcap_t *p)
{
if (p->buffer != NULL)
free(p->buffer);
if (p->fd >= 0)
close(p->fd);
}
/*
* XXX - on AIX, IBM's tcpdump (and perhaps the incompatible-with-everybody-
* else's libpcap in AIX 5.1) appears to forcibly load the BPF driver
* if it's not already loaded, and to create the BPF devices if they
* don't exist.
*
* It'd be nice if we could do the same, although the code to do so
* might be version-dependent, alas (the way to do it isn't necessarily
* documented).
*/
pcap_t *
pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
char *ebuf)
{
int fd;
struct ifreq ifr;
struct bpf_version bv;
#ifdef BIOCGDLTLIST
struct bpf_dltlist bdl;
#endif
u_int v;
pcap_t *p;
struct utsname osinfo;
bzero(&bdl, sizeof(bdl));
#ifdef HAVE_DAG_API
if (strstr(device, "dag")) {
return dag_open_live(device, snaplen, promisc, to_ms, ebuf);
}
#endif /* HAVE_DAG_API */
#ifdef BIOCGDLTLIST
memset(&bdl, 0, sizeof(bdl));
#endif
p = (pcap_t *)malloc(sizeof(*p));
if (p == NULL) {
@ -239,12 +552,15 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
/*
* Try finding a good size for the buffer; 32768 may be too
* big, so keep cutting it in half until we find a size
* that works, or run out of sizes to try.
* that works, or run out of sizes to try. If the default
* is larger, don't make it smaller.
*
* XXX - there should be a user-accessible hook to set the
* initial buffer size.
*/
for (v = 32768; v != 0; v >>= 1) {
if ((ioctl(fd, BIOCGBLEN, (caddr_t)&v) < 0) || v < 32768)
v = 32768;
for ( ; v != 0; v >>= 1) {
/* Ignore the return value - this is because the call fails
* on BPF systems that don't have kernel malloc. And if
* the call fails, it's no big deal, we just continue to
@ -294,11 +610,15 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
v = DLT_IEEE802;
break;
case IFT_LOOP:
v = DLT_NULL;
break;
default:
/*
* We don't know what to map this to yet.
*/
snprintf(ebuf, PCAP_ERRBUF_SIZE, "unknown interface type %lu",
snprintf(ebuf, PCAP_ERRBUF_SIZE, "unknown interface type %u",
v);
goto bad;
}
@ -316,7 +636,7 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
break;
case 11: /*DLT_FR*/
v = DLT_RAW; /*XXX*/
v = DLT_FRELAY;
break;
case 12: /*DLT_C_HDLC*/
@ -326,12 +646,13 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
#endif
p->linktype = v;
#ifdef BIOCGDLTLIST
/*
* We know the default link type -- now determine any additional
* DLTs this interface supports. If this fails, it's not fatal;
* we just don't get to use the feature later.
* We know the default link type -- now determine all the DLTs
* this interface supports. If this fails with EINVAL, it's
* not fatal; we just don't get to use the feature later.
*/
if (ioctl(fd, BIOCGDLTLIST, (caddr_t) &bdl) == 0) {
if (ioctl(fd, BIOCGDLTLIST, (caddr_t)&bdl) == 0) {
bdl.bfl_list = (u_int *) malloc(sizeof(u_int) * bdl.bfl_len);
if (bdl.bfl_list == NULL) {
(void)snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
@ -339,19 +660,30 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
goto bad;
}
if (ioctl(fd, BIOCGDLTLIST, (caddr_t) &bdl) < 0) {
if (ioctl(fd, BIOCGDLTLIST, (caddr_t)&bdl) < 0) {
(void)snprintf(ebuf, PCAP_ERRBUF_SIZE,
"BIOCGDLTLIST: %s", pcap_strerror(errno));
free(bdl.bfl_list);
goto bad;
}
p->dlt_count = bdl.bfl_len;
p->dlt_list = bdl.bfl_list;
} else {
if (errno != EINVAL) {
(void)snprintf(ebuf, PCAP_ERRBUF_SIZE,
"BIOCGDLTLIST: %s", pcap_strerror(errno));
goto bad;
}
}
#endif
/* set timeout */
if (to_ms != 0) {
/*
* XXX - is this seconds/nanoseconds in AIX?
* (Treating it as such doesn't fix the timeout
* problem described below.)
*/
struct timeval to;
to.tv_sec = to_ms / 1000;
to.tv_usec = (to_ms * 1000) % 1000000;
@ -439,18 +771,98 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
pcap_strerror(errno));
goto bad;
}
#ifdef _AIX
/* For some strange reason this seems to prevent the EFAULT
* problems we have experienced from AIX BPF. */
memset(p->buffer, 0x0, p->bufsize);
#endif
/*
* On most BPF platforms, either you can do a "select()" or
* "poll()" on a BPF file descriptor and it works correctly,
* or you can do it and it will return "readable" if the
* hold buffer is full but not if the timeout expires *and*
* a non-blocking read will, if the hold buffer is empty
* but the store buffer isn't empty, rotate the buffers
* and return what packets are available.
*
* In the latter case, the fact that a non-blocking read
* will give you the available packets means you can work
* around the failure of "select()" and "poll()" to wake up
* and return "readable" when the timeout expires by using
* the timeout as the "select()" or "poll()" timeout, putting
* the BPF descriptor into non-blocking mode, and read from
* it regardless of whether "select()" reports it as readable
* or not.
*
* However, in FreeBSD 4.3 and 4.4, "select()" and "poll()"
* won't wake up and return "readable" if the timer expires
* and non-blocking reads return EWOULDBLOCK if the hold
* buffer is empty, even if the store buffer is non-empty.
*
* This means the workaround in question won't work.
*
* Therefore, on FreeBSD 4.3 and 4.4, we set "p->selectable_fd"
* to -1, which means "sorry, you can't use 'select()' or 'poll()'
* here". On all other BPF platforms, we set it to the FD for
* the BPF device; in NetBSD, OpenBSD, and Darwin, a non-blocking
* read will, if the hold buffer is empty and the store buffer
* isn't empty, rotate the buffers and return what packets are
* there (and in sufficiently recent versions of OpenBSD
* "select()" and "poll()" should work correctly).
*
* XXX - what about AIX?
*/
if (uname(&osinfo) == 0) {
/*
* We can check what OS this is.
*/
if (strcmp(osinfo.sysname, "FreeBSD") == 0 &&
(strcmp(osinfo.release, "4.3") == 0 ||
strcmp(osinfo.release, "4.4") == 0))
p->selectable_fd = -1;
else
p->selectable_fd = p->fd;
} else {
/*
* We can't find out what OS this is, so assume we can
* do a "select()" or "poll()".
*/
p->selectable_fd = p->fd;
}
p->read_op = pcap_read_bpf;
p->setfilter_op = pcap_setfilter_bpf;
p->set_datalink_op = pcap_set_datalink_bpf;
p->getnonblock_op = pcap_getnonblock_fd;
p->setnonblock_op = pcap_setnonblock_fd;
p->stats_op = pcap_stats_bpf;
p->close_op = pcap_close_bpf;
return (p);
bad:
(void)close(fd);
#ifdef BIOCGDLTLIST
if (bdl.bfl_list != NULL)
free(bdl.bfl_list);
#endif
free(p);
return (NULL);
}
int
pcap_setfilter(pcap_t *p, struct bpf_program *fp)
pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
{
#ifdef HAVE_DAG_API
if (dag_platform_finddevs(alldevsp, errbuf) < 0)
return (-1);
#endif /* HAVE_DAG_API */
return (0);
}
static int
pcap_setfilter_bpf(pcap_t *p, struct bpf_program *fp)
{
/*
* It looks that BPF code generated by gen_protochain() is not
@ -458,37 +870,41 @@ pcap_setfilter(pcap_t *p, struct bpf_program *fp)
* Take a safer side for now.
*/
if (no_optimize) {
/*
* XXX - what if we already have a filter in the kernel?
*/
if (install_bpf_program(p, fp) < 0)
return (-1);
} else if (p->sf.rfile != NULL) {
if (install_bpf_program(p, fp) < 0)
return (-1);
} else if (ioctl(p->fd, BIOCSETF, (caddr_t)fp) < 0) {
p->md.use_bpf = 0; /* filtering in userland */
return (0);
}
/*
* Free any user-mode filter we might happen to have installed.
*/
pcap_freecode(&p->fcode);
/*
* Try to install the kernel filter.
*/
if (ioctl(p->fd, BIOCSETF, (caddr_t)fp) < 0) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCSETF: %s",
pcap_strerror(errno));
return (-1);
}
p->md.use_bpf = 1; /* filtering in the kernel */
return (0);
}
int
pcap_set_datalink(pcap_t *p, int dlt)
static int
pcap_set_datalink_bpf(pcap_t *p, int dlt)
{
int i;
for (i = 0; i < p->dlt_count; i++)
if (p->dlt_list[i] == dlt)
break;
if (i >= p->dlt_count) {
(void) snprintf(p->errbuf, sizeof(p->errbuf),
"No such DLT as %d", dlt);
return -1;
}
#ifdef BIOCSDLT
if (ioctl(p->fd, BIOCSDLT, &dlt) == -1) {
(void) snprintf(p->errbuf, sizeof(p->errbuf),
"Cannot set DLT %d: %s", dlt, strerror(errno));
return -1;
return (-1);
}
p->linktype = dlt;
return 0;
#endif
return (0);
}

596
contrib/libpcap/pcap-bpf.h Normal file
View File

@ -0,0 +1,596 @@
/*-
* Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
* The Regents of the University of California. All rights reserved.
*
* This code is derived from the Stanford/CMU enet packet filter,
* (net/enet.c) distributed as part of 4.3BSD, and code contributed
* to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
* Berkeley Laboratory.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)bpf.h 7.1 (Berkeley) 5/7/91
*
* @(#) $Header: /tcpdump/master/libpcap/pcap-bpf.h,v 1.9.2.9 2004/03/28 21:45:32 fenner Exp $ (LBL)
*/
/*
* This is libpcap's cut-down version of bpf.h; it includes only
* the stuff needed for the code generator and the userland BPF
* interpreter, and the libpcap APIs for setting filters, etc..
*
* "pcap-bpf.c" will include the native OS version, as it deals with
* the OS's BPF implementation.
*
* XXX - should this all just be moved to "pcap.h"?
*/
#ifndef BPF_MAJOR_VERSION
#ifdef __cplusplus
extern "C" {
#endif
/* BSD style release date */
#define BPF_RELEASE 199606
typedef int bpf_int32;
typedef u_int bpf_u_int32;
/*
* Alignment macros. BPF_WORDALIGN rounds up to the next
* even multiple of BPF_ALIGNMENT.
*/
#ifndef __NetBSD__
#define BPF_ALIGNMENT sizeof(bpf_int32)
#else
#define BPF_ALIGNMENT sizeof(long)
#endif
#define BPF_WORDALIGN(x) (((x)+(BPF_ALIGNMENT-1))&~(BPF_ALIGNMENT-1))
#define BPF_MAXINSNS 512
#define BPF_MAXBUFSIZE 0x8000
#define BPF_MINBUFSIZE 32
/*
* Structure for "pcap_compile()", "pcap_setfilter()", etc..
*/
struct bpf_program {
u_int bf_len;
struct bpf_insn *bf_insns;
};
/*
* Struct return by BIOCVERSION. This represents the version number of
* the filter language described by the instruction encodings below.
* bpf understands a program iff kernel_major == filter_major &&
* kernel_minor >= filter_minor, that is, if the value returned by the
* running kernel has the same major number and a minor number equal
* equal to or less than the filter being downloaded. Otherwise, the
* results are undefined, meaning an error may be returned or packets
* may be accepted haphazardly.
* It has nothing to do with the source code version.
*/
struct bpf_version {
u_short bv_major;
u_short bv_minor;
};
/* Current version number of filter architecture. */
#define BPF_MAJOR_VERSION 1
#define BPF_MINOR_VERSION 1
/*
* Data-link level type codes.
*
* Do *NOT* add new values to this list without asking
* "tcpdump-workers@tcpdump.org" for a value. Otherwise, you run the
* risk of using a value that's already being used for some other purpose,
* and of having tools that read libpcap-format captures not being able
* to handle captures with your new DLT_ value, with no hope that they
* will ever be changed to do so (as that would destroy their ability
* to read captures using that value for that other purpose).
*/
/*
* These are the types that are the same on all platforms, and that
* have been defined by <net/bpf.h> for ages.
*/
#define DLT_NULL 0 /* no link-layer encapsulation */
#define DLT_EN10MB 1 /* Ethernet (10Mb) */
#define DLT_EN3MB 2 /* Experimental Ethernet (3Mb) */
#define DLT_AX25 3 /* Amateur Radio AX.25 */
#define DLT_PRONET 4 /* Proteon ProNET Token Ring */
#define DLT_CHAOS 5 /* Chaos */
#define DLT_IEEE802 6 /* IEEE 802 Networks */
#define DLT_ARCNET 7 /* ARCNET, with BSD-style header */
#define DLT_SLIP 8 /* Serial Line IP */
#define DLT_PPP 9 /* Point-to-point Protocol */
#define DLT_FDDI 10 /* FDDI */
/*
* These are types that are different on some platforms, and that
* have been defined by <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/SNAP encapsulated atm */
#ifdef __OpenBSD__
#define DLT_RAW 14 /* raw IP */
#else
#define DLT_RAW 12 /* raw IP */
#endif
/*
* Given that the only OS that currently generates BSD/OS SLIP or PPP
* is, well, BSD/OS, arguably everybody should have chosen its values
* for DLT_SLIP_BSDOS and DLT_PPP_BSDOS, which are 15 and 16, but they
* didn't. So it goes.
*/
#if defined(__NetBSD__) || defined(__FreeBSD__)
#ifndef DLT_SLIP_BSDOS
#define DLT_SLIP_BSDOS 13 /* BSD/OS Serial Line IP */
#define DLT_PPP_BSDOS 14 /* BSD/OS Point-to-point Protocol */
#endif
#else
#define DLT_SLIP_BSDOS 15 /* BSD/OS Serial Line IP */
#define DLT_PPP_BSDOS 16 /* BSD/OS Point-to-point Protocol */
#endif
/*
* 17 is used for DLT_OLD_PFLOG in OpenBSD;
* OBSOLETE: DLT_PFLOG is 117 in OpenBSD now as well. See below.
* 18 is used for DLT_PFSYNC in OpenBSD; don't use it for anything else.
*/
#define DLT_ATM_CLIP 19 /* Linux Classical-IP over ATM */
/*
* These values are defined by NetBSD; other platforms should refrain from
* using them for other purposes, so that NetBSD savefiles with link
* types of 50 or 51 can be read as this type on all platforms.
*/
#define DLT_PPP_SERIAL 50 /* PPP over serial with HDLC encapsulation */
#define DLT_PPP_ETHER 51 /* PPP over Ethernet */
/*
* The Axent Raptor firewall - now the Symantec Enterprise Firewall - uses
* a link-layer type of 99 for the tcpdump it supplies. The link-layer
* header has 6 bytes of unknown data, something that appears to be an
* Ethernet type, and 36 bytes that appear to be 0 in at least one capture
* I've seen.
*/
#define DLT_SYMANTEC_FIREWALL 99
/*
* Values between 100 and 103 are used in capture file headers as
* link-layer types corresponding to DLT_ types that differ
* between platforms; don't use those values for new DLT_ new types.
*/
/*
* This value was defined by libpcap 0.5; platforms that have defined
* it with a different value should define it here with that value -
* a link type of 104 in a save file will be mapped to DLT_C_HDLC,
* whatever value that happens to be, so programs will correctly
* handle files with that link type regardless of the value of
* DLT_C_HDLC.
*
* The name DLT_C_HDLC was used by BSD/OS; we use that name for source
* compatibility with programs written for BSD/OS.
*
* libpcap 0.5 defined it as DLT_CHDLC; we define DLT_CHDLC as well,
* for source compatibility with programs written for libpcap 0.5.
*/
#define DLT_C_HDLC 104 /* Cisco HDLC */
#define DLT_CHDLC DLT_C_HDLC
#define DLT_IEEE802_11 105 /* IEEE 802.11 wireless */
/*
* 106 is reserved for Linux Classical IP over ATM; it's like DLT_RAW,
* except when it isn't. (I.e., sometimes it's just raw IP, and
* sometimes it isn't.) We currently handle it as DLT_LINUX_SLL,
* so that we don't have to worry about the link-layer header.)
*/
/*
* Frame Relay; BSD/OS has a DLT_FR with a value of 11, but that collides
* with other values.
* DLT_FR and DLT_FRELAY packets start with the Q.922 Frame Relay header
* (DLCI, etc.).
*/
#define DLT_FRELAY 107
/*
* OpenBSD DLT_LOOP, for loopback devices; it's like DLT_NULL, except
* that the AF_ type in the link-layer header is in network byte order.
*
* OpenBSD defines it as 12, but that collides with DLT_RAW, so we
* define it as 108 here. If OpenBSD picks up this file, it should
* define DLT_LOOP as 12 in its version, as per the comment above -
* and should not use 108 as a DLT_ value.
*/
#define DLT_LOOP 108
/*
* Encapsulated packets for IPsec; DLT_ENC is 13 in OpenBSD, but that's
* DLT_SLIP_BSDOS in NetBSD, so we don't use 13 for it in OSes other
* than OpenBSD.
*/
#ifdef __OpenBSD__
#define DLT_ENC 13
#else
#define DLT_ENC 109
#endif
/*
* Values between 110 and 112 are reserved for use in capture file headers
* as link-layer types corresponding to DLT_ types that might differ
* between platforms; don't use those values for new DLT_ types
* other than the corresponding DLT_ types.
*/
/*
* This is for Linux cooked sockets.
*/
#define DLT_LINUX_SLL 113
/*
* Apple LocalTalk hardware.
*/
#define DLT_LTALK 114
/*
* Acorn Econet.
*/
#define DLT_ECONET 115
/*
* Reserved for use with OpenBSD ipfilter.
*/
#define DLT_IPFILTER 116
/*
* OpenBSD DLT_PFLOG; DLT_PFLOG is 17 in OpenBSD, but that's DLT_LANE8023
* in SuSE 6.3, so we can't use 17 for it in capture-file headers.
*
* XXX: is there a conflict with DLT_PFSYNC 18 as well?
*/
#ifdef __OpenBSD__
#define DLT_OLD_PFLOG 17
#define DLT_PFSYNC 18
#endif
#define DLT_PFLOG 117
/*
* Registered for Cisco-internal use.
*/
#define DLT_CISCO_IOS 118
/*
* For 802.11 cards using the Prism II chips, with a link-layer
* header including Prism monitor mode information plus an 802.11
* header.
*/
#define DLT_PRISM_HEADER 119
/*
* Reserved for Aironet 802.11 cards, with an Aironet link-layer header
* (see Doug Ambrisko's FreeBSD patches).
*/
#define DLT_AIRONET_HEADER 120
/*
* Reserved for Siemens HiPath HDLC.
*/
#define DLT_HHDLC 121
/*
* This is for RFC 2625 IP-over-Fibre Channel.
*
* This is not for use with raw Fibre Channel, where the link-layer
* header starts with a Fibre Channel frame header; it's for IP-over-FC,
* where the link-layer header starts with an RFC 2625 Network_Header
* field.
*/
#define DLT_IP_OVER_FC 122
/*
* This is for Full Frontal ATM on Solaris with SunATM, with a
* pseudo-header followed by an AALn PDU.
*
* There may be other forms of Full Frontal ATM on other OSes,
* with different pseudo-headers.
*
* If ATM software returns a pseudo-header with VPI/VCI information
* (and, ideally, packet type information, e.g. signalling, ILMI,
* LANE, LLC-multiplexed traffic, etc.), it should not use
* DLT_ATM_RFC1483, but should get a new DLT_ value, so tcpdump
* and the like don't have to infer the presence or absence of a
* pseudo-header and the form of the pseudo-header.
*/
#define DLT_SUNATM 123 /* Solaris+SunATM */
/*
* Reserved as per request from Kent Dahlgren <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 */
/*
* BSD header for 802.11 plus a number of bits of link-layer information
* including radio information.
*/
#define DLT_IEEE802_11_RADIO 127 /* 802.11 plus BSD radio header */
/*
* Reserved for the TZSP encapsulation, as per request from
* Chris Waters <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
/*
* 139 through 142 are reserved for SS7.
*/
/*
* Reserved for DOCSIS MAC frames.
*/
#define DLT_DOCSIS 143
/*
* Linux-IrDA packets. Protocol defined at http://www.irda.org.
* Those packets include IrLAP headers and above (IrLMP...), but
* don't include Phy framing (SOF/EOF/CRC & byte stuffing), because Phy
* framing can be handled by the hardware and depend on the bitrate.
* This is exactly the format you would get capturing on a Linux-IrDA
* interface (irdaX), but not on a raw serial port.
* Note the capture is done in "Linux-cooked" mode, so each packet include
* a fake packet header (struct sll_header). This is because IrDA packet
* decoding is dependant on the direction of the packet (incomming or
* outgoing).
* When/if other platform implement IrDA capture, we may revisit the
* issue and define a real DLT_IRDA...
* Jean II
*/
#define DLT_LINUX_IRDA 144
/*
* Reserved for IBM SP switch and IBM Next Federation switch.
*/
#define DLT_IBM_SP 145
#define DLT_IBM_SN 146
/*
* Reserved for private use. If you have some link-layer header type
* that you want to use within your organization, with the capture files
* using that link-layer header type not ever be sent outside your
* organization, you can use these values.
*
* No libpcap release will use these for any purpose, nor will any
* tcpdump release use them, either.
*
* Do *NOT* use these in capture files that you expect anybody not using
* your private versions of capture-file-reading tools to read; in
* particular, do *NOT* use them in products, otherwise you may find that
* people won't be able to use tcpdump, or snort, or Ethereal, or... to
* read capture files from your firewall/intrusion detection/traffic
* monitoring/etc. appliance, or whatever product uses that DLT_ value,
* and you may also find that the developers of those applications will
* not accept patches to let them read those files.
*
* Also, do not use them if somebody might send you a capture using them
* for *their* private type and tools using them for *your* private type
* would have to read them.
*
* Instead, ask "tcpdump-workers@tcpdump.org" for a new DLT_ value,
* as per the comment above, and use the type you're given.
*/
#define DLT_USER0 147
#define DLT_USER1 148
#define DLT_USER2 149
#define DLT_USER3 150
#define DLT_USER4 151
#define DLT_USER5 152
#define DLT_USER6 153
#define DLT_USER7 154
#define DLT_USER8 155
#define DLT_USER9 156
#define DLT_USER10 157
#define DLT_USER11 158
#define DLT_USER12 159
#define DLT_USER13 160
#define DLT_USER14 161
#define DLT_USER15 162
/*
* For future use with 802.11 captures - defined by AbsoluteValue
* Systems to store a number of bits of link-layer information
* including radio information:
*
* http://www.shaftnet.org/~pizza/software/capturefrm.txt
*
* but could and arguably should also be used by non-AVS Linux
* 802.11 drivers; that may happen in the future.
*/
#define DLT_IEEE802_11_RADIO_AVS 163 /* 802.11 plus AVS radio header */
/*
* Juniper-private data link type, as per request from
* Hannes Gredler <hannes@juniper.net>. The DLT_s are used
* for passing on chassis-internal metainformation such as
* QOS profiles, etc..
*/
#define DLT_JUNIPER_MONITOR 164
/*
* The instruction encodings.
*/
/* instruction classes */
#define BPF_CLASS(code) ((code) & 0x07)
#define BPF_LD 0x00
#define BPF_LDX 0x01
#define BPF_ST 0x02
#define BPF_STX 0x03
#define BPF_ALU 0x04
#define BPF_JMP 0x05
#define BPF_RET 0x06
#define BPF_MISC 0x07
/* ld/ldx fields */
#define BPF_SIZE(code) ((code) & 0x18)
#define BPF_W 0x00
#define BPF_H 0x08
#define BPF_B 0x10
#define BPF_MODE(code) ((code) & 0xe0)
#define BPF_IMM 0x00
#define BPF_ABS 0x20
#define BPF_IND 0x40
#define BPF_MEM 0x60
#define BPF_LEN 0x80
#define BPF_MSH 0xa0
/* alu/jmp fields */
#define BPF_OP(code) ((code) & 0xf0)
#define BPF_ADD 0x00
#define BPF_SUB 0x10
#define BPF_MUL 0x20
#define BPF_DIV 0x30
#define BPF_OR 0x40
#define BPF_AND 0x50
#define BPF_LSH 0x60
#define BPF_RSH 0x70
#define BPF_NEG 0x80
#define BPF_JA 0x00
#define BPF_JEQ 0x10
#define BPF_JGT 0x20
#define BPF_JGE 0x30
#define BPF_JSET 0x40
#define BPF_SRC(code) ((code) & 0x08)
#define BPF_K 0x00
#define BPF_X 0x08
/* ret - BPF_K and BPF_X also apply */
#define BPF_RVAL(code) ((code) & 0x18)
#define BPF_A 0x10
/* misc */
#define BPF_MISCOP(code) ((code) & 0xf8)
#define BPF_TAX 0x00
#define BPF_TXA 0x80
/*
* The instruction data structure.
*/
struct bpf_insn {
u_short code;
u_char jt;
u_char jf;
bpf_int32 k;
};
/*
* Macros for insn array initializers.
*/
#define BPF_STMT(code, k) { (u_short)(code), 0, 0, k }
#define BPF_JUMP(code, k, jt, jf) { (u_short)(code), jt, jf, k }
#if __STDC__ || defined(__cplusplus)
extern int bpf_validate(struct bpf_insn *, int);
extern u_int bpf_filter(struct bpf_insn *, u_char *, u_int, u_int);
#else
extern int bpf_validate();
extern u_int bpf_filter();
#endif
/*
* Number of scratch memory words (for BPF_LD|BPF_MEM and BPF_ST).
*/
#define BPF_MEMWORDS 16
#ifdef __cplusplus
}
#endif
#endif

710
contrib/libpcap/pcap-dag.c Normal file
View File

@ -0,0 +1,710 @@
/*
* pcap-dag.c: Packet capture interface for Endace DAG card.
*
* The functionality of this code attempts to mimic that of pcap-linux as much
* as possible. This code is compiled in several different ways depending on
* whether DAG_ONLY and HAVE_DAG_API are defined. If HAVE_DAG_API is not
* defined it should not get compiled in, otherwise if DAG_ONLY is defined then
* the 'dag_' function calls are renamed to 'pcap_' equivalents. If DAG_ONLY
* is not defined then nothing is altered - the dag_ functions will be
* called as required from their pcap-linux/bpf equivalents.
*
* Author: Richard Littin, Sean Irvine ({richard,sean}@reeltwo.com)
*
* Modifications:
* 2003 May - Jesper Peterson <support@endace.com>
* Code shuffled around to suit fad-xxx.c structure
* Added atexit() handler to stop DAG if application is too lazy
* 2003 September - Koryn Grant <koryn@endace.com>
* Added support for nonblocking operation.
* Added support for processing more than a single packet in pcap_dispatch().
* Fixed bug in loss counter code.
* Improved portability of loss counter code (e.g. use UINT_MAX instead of 0xffff).
* Removed unused local variables.
* Added required headers (ctype.h, limits.h, unistd.h, netinet/in.h).
* 2003 October - Koryn Grant <koryn@endace.com.>
* Changed semantics to match those of standard pcap on linux.
* - packets rejected by the filter are not counted.
*/
#ifndef lint
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/pcap-dag.c,v 1.10.2.4 2003/11/21 10:20:45 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <sys/param.h> /* optionally get BSD define */
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "pcap-int.h"
#include <ctype.h>
#include <netinet/in.h>
#include <sys/mman.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
struct mbuf; /* Squelch compiler warnings on some platforms for */
struct rtentry; /* declarations in <net/if.h> */
#include <net/if.h>
#include <dagnew.h>
#include <dagapi.h>
#define MIN_DAG_SNAPLEN 12
#define MAX_DAG_SNAPLEN 2040
#define ATM_SNAPLEN 48
typedef struct pcap_dag_node {
struct pcap_dag_node *next;
pcap_t *p;
pid_t pid;
} pcap_dag_node_t;
static pcap_dag_node_t *pcap_dags = NULL;
static int atexit_handler_installed = 0;
static const unsigned short endian_test_word = 0x0100;
#define IS_BIGENDIAN() (*((unsigned char *)&endian_test_word))
/*
* Swap byte ordering of unsigned long long timestamp on a big endian
* machine.
*/
#define SWAP_TS(ull) ((ull & 0xff00000000000000LL) >> 56) | \
((ull & 0x00ff000000000000LL) >> 40) | \
((ull & 0x0000ff0000000000LL) >> 24) | \
((ull & 0x000000ff00000000LL) >> 8) | \
((ull & 0x00000000ff000000LL) << 8) | \
((ull & 0x0000000000ff0000LL) << 24) | \
((ull & 0x000000000000ff00LL) << 40) | \
((ull & 0x00000000000000ffLL) << 56)
#ifdef DAG_ONLY
/* This code is required when compiling for a DAG device only. */
#include "pcap-dag.h"
/* Replace dag function names with pcap equivalent. */
#define dag_open_live pcap_open_live
#define dag_platform_finddevs pcap_platform_finddevs
#endif /* DAG_ONLY */
static int dag_setfilter(pcap_t *p, struct bpf_program *fp);
static int dag_stats(pcap_t *p, struct pcap_stat *ps);
static int dag_set_datalink(pcap_t *p, int dlt);
static int dag_get_datalink(pcap_t *p);
static int dag_setnonblock(pcap_t *p, int nonblock, char *errbuf);
static void delete_pcap_dag(pcap_t *p) {
pcap_dag_node_t *curr = NULL, *prev = NULL;
for (prev = NULL, curr = pcap_dags;
curr != NULL && curr->p != p;
prev = curr, curr = curr->next) {
/* empty */
}
if (curr != NULL && curr->p == p) {
if (prev != NULL) {
prev->next = curr->next;
} else {
pcap_dags = curr->next;
}
}
}
/*
* Performs a graceful shutdown of the DAG card, frees dynamic memory held
* in the pcap_t structure, and closes the file descriptor for the DAG card.
*/
static void dag_platform_close(pcap_t *p) {
#ifdef linux
if (p != NULL && p->md.device != NULL) {
if(dag_stop(p->fd) < 0)
fprintf(stderr,"dag_stop %s: %s\n", p->md.device, strerror(errno));
if(dag_close(p->fd) < 0)
fprintf(stderr,"dag_close %s: %s\n", p->md.device, strerror(errno));
free(p->md.device);
}
#else
if (p != NULL) {
if(dag_stop(p->fd) < 0)
fprintf(stderr,"dag_stop: %s\n", strerror(errno));
if(dag_close(p->fd) < 0)
fprintf(stderr,"dag_close: %s\n", strerror(errno));
}
#endif
delete_pcap_dag(p);
/* Note: don't need to call close(p->fd) here as dag_close(p->fd) does this. */
}
static void atexit_handler(void) {
while (pcap_dags != NULL) {
if (pcap_dags->pid == getpid()) {
dag_platform_close(pcap_dags->p);
} else {
delete_pcap_dag(pcap_dags->p);
}
}
}
static int new_pcap_dag(pcap_t *p) {
pcap_dag_node_t *node = NULL;
if ((node = malloc(sizeof(pcap_dag_node_t))) == NULL) {
return -1;
}
if (!atexit_handler_installed) {
atexit(atexit_handler);
atexit_handler_installed = 1;
}
node->next = pcap_dags;
node->p = p;
node->pid = getpid();
pcap_dags = node;
return 0;
}
/*
* Read at most max_packets from the capture stream and call the callback
* for each of them. Returns the number of packets handled, -1 if an
* error occured, or -2 if we were told to break out of the loop.
*/
static int dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) {
unsigned int processed = 0;
int flags = p->md.dag_offset_flags;
unsigned int nonblocking = flags & DAGF_NONBLOCK;
for (;;)
{
/* Get the next bufferful of packets (if necessary). */
while (p->md.dag_mem_top - p->md.dag_mem_bottom < dag_record_size) {
/*
* Has "pcap_breakloop()" been called?
*/
if (p->break_loop) {
/*
* Yes - clear the flag that indicates that
* it has, and return -2 to indicate that
* we were told to break out of the loop.
*/
p->break_loop = 0;
return -2;
}
p->md.dag_mem_top = dag_offset(p->fd, &(p->md.dag_mem_bottom), flags);
if ((p->md.dag_mem_top - p->md.dag_mem_bottom < dag_record_size) && nonblocking)
{
/* Pcap is configured to process only available packets, and there aren't any. */
return 0;
}
}
/* Process the packets. */
while (p->md.dag_mem_top - p->md.dag_mem_bottom >= dag_record_size) {
unsigned short packet_len = 0;
int caplen = 0;
struct pcap_pkthdr pcap_header;
dag_record_t *header = (dag_record_t *)(p->md.dag_mem_base + p->md.dag_mem_bottom);
u_char *dp = ((u_char *)header) + dag_record_size;
unsigned short rlen;
/*
* Has "pcap_breakloop()" been called?
*/
if (p->break_loop) {
/*
* Yes - clear the flag that indicates that
* it has, and return -2 to indicate that
* we were told to break out of the loop.
*/
p->break_loop = 0;
return -2;
}
if (IS_BIGENDIAN())
{
rlen = header->rlen;
}
else
{
rlen = ntohs(header->rlen);
}
p->md.dag_mem_bottom += rlen;
switch(header->type) {
case TYPE_ATM:
packet_len = ATM_SNAPLEN;
caplen = ATM_SNAPLEN;
dp += 4;
break;
case TYPE_ETH:
if (IS_BIGENDIAN())
{
packet_len = header->wlen;
}
else
{
packet_len = ntohs(header->wlen);
}
packet_len -= (p->md.dag_fcs_bits >> 3);
caplen = rlen - dag_record_size - 2;
if (caplen > packet_len)
{
caplen = packet_len;
}
dp += 2;
break;
case TYPE_HDLC_POS:
if (IS_BIGENDIAN())
{
packet_len = header->wlen;
}
else
{
packet_len = ntohs(header->wlen);
}
packet_len -= (p->md.dag_fcs_bits >> 3);
caplen = rlen - dag_record_size;
if (caplen > packet_len)
{
caplen = packet_len;
}
break;
}
if (caplen > p->snapshot)
caplen = p->snapshot;
/* Count lost packets. */
if (header->lctr) {
if (p->md.stat.ps_drop > (UINT_MAX - header->lctr)) {
p->md.stat.ps_drop = UINT_MAX;
} else {
p->md.stat.ps_drop += header->lctr;
}
}
/* Run the packet filter if there is one. */
if ((p->fcode.bf_insns == NULL) || bpf_filter(p->fcode.bf_insns, dp, packet_len, caplen)) {
/* convert between timestamp formats */
register unsigned long long ts;
if (IS_BIGENDIAN())
{
ts = SWAP_TS(header->ts);
}
else
{
ts = header->ts;
}
pcap_header.ts.tv_sec = ts >> 32;
ts = (ts & 0xffffffffULL) * 1000000;
ts += 0x80000000; /* rounding */
pcap_header.ts.tv_usec = ts >> 32;
if (pcap_header.ts.tv_usec >= 1000000) {
pcap_header.ts.tv_usec -= 1000000;
pcap_header.ts.tv_sec++;
}
/* Fill in our own header data */
pcap_header.caplen = caplen;
pcap_header.len = packet_len;
/* Count the packet. */
p->md.stat.ps_recv++;
/* Call the user supplied callback function */
callback(user, &pcap_header, dp);
/* Only count packets that pass the filter, for consistency with standard Linux behaviour. */
processed++;
if (processed == cnt)
{
/* Reached the user-specified limit. */
return cnt;
}
}
}
if (nonblocking || processed)
{
return processed;
}
}
return processed;
}
/*
* Get a handle for a live capture from the given DAG device. Passing a NULL
* device will result in a failure. The promisc flag is ignored because DAG
* cards are always promiscuous. The to_ms parameter is also ignored as it is
* not supported in hardware.
*
* See also pcap(3).
*/
pcap_t *dag_open_live(const char *device, int snaplen, int promisc, int to_ms, char *ebuf) {
char conf[30]; /* dag configure string */
pcap_t *handle;
char *s;
int n;
if (device == NULL) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "device is NULL: %s", pcap_strerror(errno));
return NULL;
}
/* Allocate a handle for this session. */
handle = malloc(sizeof(*handle));
if (handle == NULL) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc %s: %s", device, pcap_strerror(errno));
return NULL;
}
/* Initialize some components of the pcap structure. */
memset(handle, 0, sizeof(*handle));
if (strstr(device, "/dev") == NULL) {
char * newDev = (char *)malloc(strlen(device) + 6);
newDev[0] = '\0';
strcat(newDev, "/dev/");
strcat(newDev,device);
device = newDev;
} else {
device = strdup(device);
}
if (device == NULL) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "str_dup: %s\n", pcap_strerror(errno));
goto fail;
}
/* setup device parameters */
if((handle->fd = dag_open((char *)device)) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "dag_open %s: %s", device, pcap_strerror(errno));
goto fail;
}
/* set the card snap length to the specified snaplen parameter */
if (snaplen == 0 || snaplen > MAX_DAG_SNAPLEN) {
snaplen = MAX_DAG_SNAPLEN;
} else if (snaplen < MIN_DAG_SNAPLEN) {
snaplen = MIN_DAG_SNAPLEN;
}
/* snap len has to be a multiple of 4 */
snprintf(conf, 30, "varlen slen=%d", (snaplen + 3) & ~3);
fprintf(stderr, "Configuring DAG with '%s'.\n", conf);
if(dag_configure(handle->fd, conf) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE,"dag_configure %s: %s\n", device, pcap_strerror(errno));
goto fail;
}
if((handle->md.dag_mem_base = dag_mmap(handle->fd)) == MAP_FAILED) {
snprintf(ebuf, PCAP_ERRBUF_SIZE,"dag_mmap %s: %s\n", device, pcap_strerror(errno));
goto fail;
}
if(dag_start(handle->fd) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "dag_start %s: %s\n", device, pcap_strerror(errno));
goto fail;
}
/*
* Important! You have to ensure bottom is properly
* initialized to zero on startup, it won't give you
* a compiler warning if you make this mistake!
*/
handle->md.dag_mem_bottom = 0;
handle->md.dag_mem_top = 0;
/* TODO: query the card */
handle->md.dag_fcs_bits = 32;
if ((s = getenv("ERF_FCS_BITS")) != NULL) {
if ((n = atoi(s)) == 0 || n == 16|| n == 32) {
handle->md.dag_fcs_bits = n;
} else {
snprintf(ebuf, PCAP_ERRBUF_SIZE,
"pcap_open_live %s: bad ERF_FCS_BITS value (%d) in environment\n", device, n);
goto fail;
}
}
handle->snapshot = snaplen;
/*handle->md.timeout = to_ms; */
if ((handle->linktype = dag_get_datalink(handle)) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "dag_get_linktype %s: unknown linktype\n", device);
goto fail;
}
handle->bufsize = 0;
if (new_pcap_dag(handle) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "new_pcap_dag %s: %s\n", device, pcap_strerror(errno));
goto fail;
}
/*
* "select()" and "poll()" don't (yet) work on DAG device descriptors.
*/
handle->selectable_fd = -1;
#ifdef linux
handle->md.device = (char *)device;
#else
free((char *)device);
device = NULL;
#endif
handle->read_op = dag_read;
handle->setfilter_op = dag_setfilter;
handle->set_datalink_op = dag_set_datalink;
handle->getnonblock_op = pcap_getnonblock_fd;
handle->setnonblock_op = dag_setnonblock;
handle->stats_op = dag_stats;
handle->close_op = dag_platform_close;
return handle;
fail:
if (device != NULL) {
free((char *)device);
}
if (handle != NULL) {
free(handle);
}
return NULL;
}
static int dag_stats(pcap_t *p, struct pcap_stat *ps) {
/* This needs to be filled out correctly. Hopefully a dagapi call will
provide all necessary information.
*/
/*p->md.stat.ps_recv = 0;*/
/*p->md.stat.ps_drop = 0;*/
*ps = p->md.stat;
return 0;
}
/*
* Get from "/proc/dag" all interfaces listed there; if they're
* already in the list of interfaces we have, that won't add another
* instance, but if they're not, that'll add them.
*
* We don't bother getting any addresses for them.
*
* We also don't fail if we couldn't open "/proc/dag"; we just leave
* the list of interfaces as is.
*/
int
dag_platform_finddevs(pcap_if_t **devlistp, char *errbuf)
{
FILE *proc_dag_f;
char linebuf[512];
int linenum;
unsigned char *p;
char name[512]; /* XXX - pick a size */
char *q;
int ret = 0;
/* Quick exit if /proc/dag not readable */
proc_dag_f = fopen("/proc/dag", "r");
if (proc_dag_f == NULL)
{
int i;
char dev[16] = "dagx";
for (i = '0'; ret == 0 && i <= '9'; i++) {
dev[3] = i;
if (pcap_add_if(devlistp, dev, 0, NULL, errbuf) == -1) {
/*
* Failure.
*/
ret = -1;
}
}
return (ret);
}
for (linenum = 1;
fgets(linebuf, sizeof linebuf, proc_dag_f) != NULL; linenum++) {
/*
* Skip the first two lines - they're headers.
*/
if (linenum <= 2)
continue;
p = &linebuf[0];
if (*p == '\0' || *p == '\n' || *p != 'D')
continue; /* not a Dag line */
/*
* Get the interface name.
*/
q = &name[0];
while (*p != '\0' && *p != ':') {
if (*p != ' ')
*q++ = tolower(*p++);
else
p++;
}
*q = '\0';
/*
* Add an entry for this interface, with no addresses.
*/
p[strlen(p) - 1] = '\0'; /* get rid of \n */
if (pcap_add_if(devlistp, name, 0, strdup(p + 2), errbuf) == -1) {
/*
* Failure.
*/
ret = -1;
break;
}
}
if (ret != -1) {
/*
* Well, we didn't fail for any other reason; did we
* fail due to an error reading the file?
*/
if (ferror(proc_dag_f)) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"Error reading /proc/dag: %s",
pcap_strerror(errno));
ret = -1;
}
}
(void)fclose(proc_dag_f);
return (ret);
}
/*
* Installs the given bpf filter program in the given pcap structure. There is
* no attempt to store the filter in kernel memory as that is not supported
* with DAG cards.
*/
static int dag_setfilter(pcap_t *p, struct bpf_program *fp) {
if (!p)
return -1;
if (!fp) {
strncpy(p->errbuf, "setfilter: No filter specified",
sizeof(p->errbuf));
return -1;
}
/* Make our private copy of the filter */
if (install_bpf_program(p, fp) < 0) {
snprintf(p->errbuf, sizeof(p->errbuf),
"malloc: %s", pcap_strerror(errno));
return -1;
}
p->md.use_bpf = 0;
return (0);
}
static int
dag_set_datalink(pcap_t *p, int dlt)
{
return (0);
}
static int
dag_setnonblock(pcap_t *p, int nonblock, char *errbuf)
{
/*
* Set non-blocking mode on the FD.
* XXX - is that necessary? If not, don't bother calling it,
* and have a "dag_getnonblock()" function that looks at
* "p->md.dag_offset_flags".
*/
if (pcap_setnonblock_fd(p, nonblock, errbuf) < 0)
return (-1);
if (nonblock) {
p->md.dag_offset_flags |= DAGF_NONBLOCK;
} else {
p->md.dag_offset_flags &= ~DAGF_NONBLOCK;
}
return (0);
}
static int
dag_get_datalink(pcap_t *p)
{
int linktype = -1;
/* Check the type through a dagapi call.
*/
switch(dag_linktype(p->fd)) {
case TYPE_HDLC_POS: {
dag_record_t *record;
/* peek at the first available record to see if it is PPP */
while ((p->md.dag_mem_top - p->md.dag_mem_bottom) < (dag_record_size + 4)) {
p->md.dag_mem_top = dag_offset(p->fd, &(p->md.dag_mem_bottom), 0);
}
record = (dag_record_t *)(p->md.dag_mem_base + p->md.dag_mem_bottom);
if ((ntohl(record->rec.pos.hdlc) & 0xffff0000) == 0xff030000) {
linktype = DLT_PPP_SERIAL;
fprintf(stderr, "Set DAG linktype to %d (DLT_PPP_SERIAL)\n", linktype);
} else {
linktype = DLT_CHDLC;
fprintf(stderr, "Set DAG linktype to %d (DLT_CHDLC)\n", linktype);
}
break;
}
case TYPE_ETH:
linktype = DLT_EN10MB;
fprintf(stderr, "Set DAG linktype to %d (DLT_EN10MB)\n", linktype);
break;
case TYPE_ATM:
linktype = DLT_ATM_RFC1483;
fprintf(stderr, "Set DAG linktype to %d (DLT_ATM_RFC1483)\n", linktype);
break;
case TYPE_LEGACY:
linktype = DLT_NULL;
fprintf(stderr, "Set DAG linktype to %d (DLT_NULL)\n", linktype);
break;
default:
fprintf(stderr, "Unknown DAG linktype %d\n", dag_linktype(p->fd));
break;
}
return linktype;
}

View File

@ -0,0 +1,14 @@
/*
* pcap-dag.c: Packet capture interface for Endace DAG card.
*
* The functionality of this code attempts to mimic that of pcap-linux as much
* as possible. This code is only needed when compiling in the DAG card code
* at the same time as another type of device.
*
* Author: Richard Littin, Sean Irvine ({richard,sean}@reeltwo.com)
*
* @(#) $Header: /tcpdump/master/libpcap/pcap-dag.h,v 1.3 2003/07/25 05:32:03 guy Exp $ (LBL)
*/
pcap_t *dag_open_live(const char *device, int snaplen, int promisc, int to_ms, char *ebuf);

View File

@ -23,7 +23,7 @@
*/
/*
* Packet capture routine for dlpi under SunOS 5
* Packet capture routine for DLPI under SunOS 5, HP-UX 9/10/11, and AIX.
*
* Notes:
*
@ -33,12 +33,12 @@
* length results in data being left of the front of the packet.
*
* - It might be desirable to use pfmod(7) to filter packets in the
* kernel.
* kernel when possible.
*/
#ifndef lint
static const char rcsid[] =
"@(#) $Header: /tcpdump/master/libpcap/pcap-dlpi.c,v 1.74 2001/12/10 07:14:15 guy Exp $ (LBL)";
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/pcap-dlpi.c,v 1.91.2.3 2003/11/21 10:20:46 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@ -98,6 +98,33 @@ static const char rcsid[] =
#define MAXDLBUF 8192
#ifdef HAVE_SYS_BUFMOD_H
/*
* Size of a bufmod chunk to pass upstream; that appears to be the biggest
* value to which you can set it, and setting it to that value (which
* is bigger than what appears to be the Solaris default of 8192)
* reduces the number of packet drops.
*/
#define CHUNKSIZE 65536
/*
* Size of the buffer to allocate for packet data we read; it must be
* large enough to hold a chunk.
*/
#define PKTBUFSIZE CHUNKSIZE
#else /* HAVE_SYS_BUFMOD_H */
/*
* Size of the buffer to allocate for packet data we read; this is
* what the value used to be - there's no particular reason why it
* should be tied to MAXDLBUF, but we'll leave it as this for now.
*/
#define PKTBUFSIZE (MAXDLBUF * sizeof(bpf_u_int32))
#endif
/* Forwards */
static char *split_dname(char *, int *, char *);
static int dlattachreq(int, bpf_u_int32, char *);
@ -124,8 +151,8 @@ static int dlpi_kread(int, off_t, void *, u_int, char *);
static int get_dlpi_ppa(int, const char *, int, char *);
#endif
int
pcap_stats(pcap_t *p, struct pcap_stat *ps)
static int
pcap_stats_dlpi(pcap_t *p, struct pcap_stat *ps)
{
/*
@ -157,8 +184,8 @@ static struct strbuf ctl = {
(char *)ctlbuf
};
int
pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
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;
@ -177,9 +204,22 @@ pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
cc = p->cc;
if (cc == 0) {
data.buf = (char *)p->buffer + p->offset;
data.maxlen = MAXDLBUF;
data.maxlen = p->bufsize;
data.len = 0;
do {
/*
* Has "pcap_breakloop()" been called?
*/
if (p->break_loop) {
/*
* Yes - clear the flag that indicates
* that it has, and return -2 to
* indicate that we were told to
* break out of the loop.
*/
p->break_loop = 0;
return (-2);
}
if (getmsg(p->fd, &ctl, &data, &flags) < 0) {
/* Don't choke when we get ptraced */
if (errno == EINTR) {
@ -202,6 +242,25 @@ pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
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;
@ -209,7 +268,7 @@ pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
} else
#endif
sbp = (struct sb_hdr *)bp;
p->md.stat.ps_drop += sbp->sbh_drops;
p->md.stat.ps_drop = sbp->sbh_drops;
pk = bp + sizeof(*sbp);
bp += sbp->sbh_totlen;
origlen = sbp->sbh_origlen;
@ -223,7 +282,8 @@ pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
++p->md.stat.ps_recv;
if (bpf_filter(fcode, pk, origlen, caplen)) {
#ifdef HAVE_SYS_BUFMOD_H
pkthdr.ts = sbp->sbh_timestamp;
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
@ -246,15 +306,44 @@ pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
return (n);
}
#ifndef DL_IPATM
#define DL_IPATM 0x12 /* ATM Classical IP interface */
#endif
#ifdef HAVE_SOLARIS
/*
* For SunATM.
*/
#ifndef A_GET_UNITS
#define A_GET_UNITS (('A'<<8)|118)
#endif /* A_GET_UNITS */
#ifndef A_PROMISCON_REQ
#define A_PROMISCON_REQ (('A'<<8)|121)
#endif /* A_PROMISCON_REQ */
#endif /* HAVE_SOLARIS */
static void
pcap_close_dlpi(pcap_t *p)
{
if (p->buffer != NULL)
free(p->buffer);
if (p->fd >= 0)
close(p->fd);
}
pcap_t *
pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
char *ebuf)
{
register char *cp;
register pcap_t *p;
int ppa;
#ifdef HAVE_SOLARIS
int isatm = 0;
#endif
register dl_info_ack_t *infop;
#ifdef HAVE_SYS_BUFMOD_H
bpf_u_int32 ss, flag;
bpf_u_int32 ss, chunksize;
#ifdef HAVE_SOLARIS
register char *release;
bpf_u_int32 osmajor, osminor, osmicro;
@ -280,10 +369,9 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
*/
cp = strrchr(device, '/');
if (cp == NULL)
cp = device;
strlcpy(dname, device, sizeof(dname));
else
cp++;
strlcpy(dname, cp, sizeof(dname));
strlcpy(dname, cp + 1, sizeof(dname));
/*
* Split the device name into a device type name and a unit number;
@ -320,14 +408,6 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
if (ppa < 0)
goto bad;
#else
/*
* Get the unit number, and a pointer to the end of the device
* type name.
*/
cp = split_dname(device, &ppa, ebuf);
if (cp == NULL)
goto bad;
/*
* If the device name begins with "/", assume it begins with
* the pathname of the directory containing the device to open;
@ -340,12 +420,20 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
snprintf(dname, sizeof(dname), "%s/%s", PCAP_DEV_PREFIX,
device);
/*
* Get the unit number, and a pointer to the end of the device
* type name.
*/
cp = split_dname(dname, &ppa, ebuf);
if (cp == NULL)
goto bad;
/*
* Make a copy of the device pathname, and then remove the unit
* number from the device pathname.
*/
strlcpy(dname2, dname, sizeof(dname));
*(dname + strlen(dname) - strlen(cp)) = '\0';
*cp = '\0';
/* Try device without unit number */
if ((p->fd = open(dname, O_RDWR)) < 0) {
@ -375,6 +463,10 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
dlinfoack(p->fd, (char *)buf, ebuf) < 0)
goto bad;
infop = &((union DL_primitives *)buf)->info_ack;
#ifdef HAVE_SOLARIS
if (infop->dl_mac_type == DL_IPATM)
isatm = 1;
#endif
if (infop->dl_provider_style == DL_STYLE2 &&
(dlattachreq(p->fd, ppa, ebuf) < 0 ||
dlokack(p->fd, "attach", (char *)buf, ebuf) < 0))
@ -410,6 +502,21 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
goto bad;
#endif
#ifdef HAVE_SOLARIS
if (isatm) {
/*
** Have to turn on some special ATM promiscuous mode
** for SunATM.
** Do *NOT* turn regular promiscuous mode on; it doesn't
** help, and may break things.
*/
if (strioctl(p->fd, A_PROMISCON_REQ, 0, NULL) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "A_PROMISCON_REQ: %s",
pcap_strerror(errno));
goto bad;
}
} else
#endif
if (promisc) {
/*
** Enable promiscuous
@ -432,12 +539,16 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
}
/*
** Try to enable sap (when not in promiscuous mode when using
** using HP-UX and never under SINIX)
** using HP-UX, when not doing SunATM on Solaris, and never
** under SINIX)
*/
#ifndef sinix
if (
#ifdef __hpux
!promisc &&
#endif
#ifdef HAVE_SOLARIS
!isatm &&
#endif
(dlpromisconreq(p->fd, DL_PROMISC_SAP, ebuf) < 0 ||
dlokack(p->fd, "promisc_sap", (char *)buf, ebuf) < 0)) {
@ -486,15 +597,23 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
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",
infop->dl_mac_type);
(unsigned long)infop->dl_mac_type);
goto bad;
}
#ifdef DLIOCRAW
/*
** This is a non standard SunOS hack to get the ethernet header.
** This is a non standard SunOS hack to get the full raw link-layer
** header.
*/
if (strioctl(p->fd, DLIOCRAW, 0, NULL) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "DLIOCRAW: %s",
@ -541,20 +660,6 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
goto bad;
}
/*
** Set up the bufmod flags
*/
if (strioctl(p->fd, SBIOCGFLAGS, sizeof(flag), (char *)&flag) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "SBIOCGFLAGS: %s",
pcap_strerror(errno));
goto bad;
}
flag |= SB_NO_DROPS;
if (strioctl(p->fd, SBIOCSFLAGS, sizeof(flag), (char *)&flag) != 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "SBIOCSFLAGS: %s",
pcap_strerror(errno));
goto bad;
}
/*
** Set up the bufmod timeout
*/
@ -569,6 +674,17 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
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
/*
@ -579,9 +695,28 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
pcap_strerror(errno));
goto bad;
}
/* Allocate data buffer */
p->bufsize = MAXDLBUF * sizeof(bpf_u_int32);
p->bufsize = PKTBUFSIZE;
p->buffer = (u_char *)malloc(p->bufsize + p->offset);
if (p->buffer == NULL) {
strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
goto bad;
}
/*
* "p->fd" is an FD for a STREAMS device, so "select()" and
* "poll()" should work on it.
*/
p->selectable_fd = p->fd;
p->read_op = pcap_read_dlpi;
p->setfilter_op = install_bpf_program; /* no kernel filtering */
p->set_datalink_op = NULL; /* can't change data link type */
p->getnonblock_op = pcap_getnonblock_fd;
p->setnonblock_op = pcap_setnonblock_fd;
p->stats_op = pcap_stats_dlpi;
p->close_op = pcap_close_dlpi;
return (p);
bad:
@ -630,11 +765,45 @@ split_dname(char *device, int *unitp, char *ebuf)
}
int
pcap_setfilter(pcap_t *p, struct bpf_program *fp)
pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
{
#ifdef HAVE_SOLARIS
int fd;
union {
u_int nunits;
char pad[516]; /* XXX - must be at least 513; is 516
in "atmgetunits" */
} buf;
char baname[2+1+1];
u_int i;
if (install_bpf_program(p, fp) < 0)
/*
* We may have to do special magic to get ATM devices.
*/
if ((fd = open("/dev/ba", O_RDWR)) < 0) {
/*
* We couldn't open the "ba" device.
* For now, just give up; perhaps we should
* return an error if the problem is neither
* a "that device doesn't exist" error (ENOENT,
* ENXIO, etc.) or a "you're not allowed to do
* that" error (EPERM, EACCES).
*/
return (0);
}
if (strioctl(fd, A_GET_UNITS, sizeof(buf), (char *)&buf) < 0) {
snprintf(errbuf, PCAP_ERRBUF_SIZE, "A_GET_UNITS: %s",
pcap_strerror(errno));
return (-1);
}
for (i = 0; i < buf.nunits; i++) {
snprintf(baname, sizeof baname, "ba%u", i);
if (pcap_add_if(alldevsp, baname, 0, NULL, errbuf) < 0)
return (-1);
}
#endif
return (0);
}
@ -1080,7 +1249,7 @@ get_release(bpf_u_int32 *majorp, bpf_u_int32 *minorp, bpf_u_int32 *microp)
* says that, to see the machine's outgoing traffic, you'd need to
* apply the right patches to your system, and also set that variable
* with:
echo 'lanc_outbound_promisc_flag/W1' | /usr/bin/adb -w /stand/vmunix /dev/kmem
* which could be put in, for example, "/sbin/init.d/lan".
@ -1143,14 +1312,14 @@ get_dlpi_ppa(register int fd, register const char *device, register int unit,
(bpf_u_int32)dlp->dl_primitive);
return (-1);
}
if (ctl.len < DL_HP_PPA_ACK_SIZE) {
snprintf(ebuf, PCAP_ERRBUF_SIZE,
"get_dlpi_ppa: hpppa ack too small (%d < %d)",
ctl.len, DL_HP_PPA_ACK_SIZE);
"get_dlpi_ppa: hpppa ack too small (%d < %lu)",
ctl.len, (unsigned long)DL_HP_PPA_ACK_SIZE);
return (-1);
}
/* allocate buffer */
if ((ppa_data_buf = (char *)malloc(dlp->dl_length)) == NULL) {
snprintf(ebuf, PCAP_ERRBUF_SIZE,

View File

@ -7,8 +7,8 @@
* Rayan Zachariassen, CA*Net
*/
#ifndef lint
static const char rcsid[] =
"@(#) $Header: /tcpdump/master/libpcap/pcap-enet.c,v 1.5 2000/10/12 03:53:59 guy Exp $";
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/pcap-enet.c,v 1.7.2.1 2003/11/15 23:26:44 guy Exp $";
#endif
#ifdef HAVE_CONFIG_H
@ -22,7 +22,7 @@ static const char rcsid[] =
#include <sys/socket.h>
#include <net/if.h>
#include <net/bpf.h>
#include <pcap-bpf.h>
#include <net/enet.h>
#include <netinet/in.h>
@ -133,7 +133,7 @@ wrapup(int fd)
perror("tcpdump: enet ioctl EIOSTATS error");
exit(-1);
}
fprintf(stderr, "%d packets queued", es.enStat_Rcnt);
if (es.enStat_Rdrops > 0)
fprintf(stderr, ", %d dropped", es.enStat_Rdrops);
@ -141,7 +141,7 @@ wrapup(int fd)
fprintf(stderr, ", %d tcpdump %s", es.enStat_Reads,
es.enStat_Reads > 1 ? "reads" : "read");
if (es.enStat_MaxRead > 1)
fprintf(stderr, ", %d packets in largest read",
fprintf(stderr, ", %d packets in largest read",
es.enStat_MaxRead);
putc('\n', stderr);
#endif /* IBMRTPC */

View File

@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#) $Header: /tcpdump/master/libpcap/pcap-int.h,v 1.33 2001/08/24 07:46:52 guy Exp $ (LBL)
* @(#) $Header: /tcpdump/master/libpcap/pcap-int.h,v 1.55.2.4 2003/12/15 01:42:24 guy Exp $ (LBL)
*/
#ifndef pcap_int_h
@ -42,13 +42,24 @@ extern "C" {
#include <pcap.h>
#ifdef WIN32
#include <packet32.h>
#endif /* WIN32 */
/*
* Savefile
*/
typedef enum {
NOT_SWAPPED,
SWAPPED,
MAYBE_SWAPPED
} swapped_type_t;
struct pcap_sf {
FILE *rfile;
int swapped;
int hdrsize;
swapped_type_t lengths_swapped;
int version_major;
int version_minor;
u_char *base;
@ -69,18 +80,36 @@ struct pcap_md {
int clear_promisc; /* must clear promiscuous mode when we close */
int cooked; /* using SOCK_DGRAM rather than SOCK_RAW */
int lo_ifindex; /* interface index of the loopback device */
char *device; /* device name */
char *device; /* device name */
struct pcap *next; /* list of open promiscuous sock_packet pcaps */
#endif
#ifdef HAVE_DAG_API
void *dag_mem_base; /* DAG card memory base address */
u_int dag_mem_bottom; /* DAG card current memory bottom pointer */
u_int dag_mem_top; /* DAG card current memory top pointer */
int dag_fcs_bits; /* Number of checksum bits from link layer */
int dag_offset_flags; /* Flags to pass to dag_offset(). */
#endif
};
struct pcap {
#ifdef WIN32
ADAPTER *adapter;
LPPACKET Packet;
int timeout;
int nonblock;
#else
int fd;
int selectable_fd;
#endif /* WIN32 */
int snapshot;
int linktype;
int tzoff; /* timezone offset */
int offset; /* offset for proper alignment */
int break_loop; /* flag set to force break from packet-reading loop */
struct pcap_sf sf;
struct pcap_md md;
@ -97,15 +126,27 @@ struct pcap {
*/
u_char *pkt;
/*
* Methods.
*/
int (*read_op)(pcap_t *, int cnt, pcap_handler, u_char *);
int (*setfilter_op)(pcap_t *, struct bpf_program *);
int (*set_datalink_op)(pcap_t *, int);
int (*getnonblock_op)(pcap_t *, char *);
int (*setnonblock_op)(pcap_t *, int, char *);
int (*stats_op)(pcap_t *, struct pcap_stat *);
void (*close_op)(pcap_t *);
/*
* Placeholder for filter code if bpf not in kernel.
*/
struct bpf_program fcode;
char errbuf[PCAP_ERRBUF_SIZE];
char errbuf[PCAP_ERRBUF_SIZE + 1];
int dlt_count;
int *dlt_list;
struct pcap_pkthdr pcap_header; /* This is needed for the pcap_next_ex() to work */
};
/*
@ -180,6 +221,7 @@ int yylex(void);
int pcap_offline_read(pcap_t *, int, pcap_handler, u_char *);
int pcap_read(pcap_t *, int cnt, pcap_handler, u_char *);
/*
* Ultrix, DEC OSF/1^H^H^H^H^H^H^H^H^HDigital UNIX^H^H^H^H^H^H^H^H^H^H^H^H
* Tru64 UNIX, and NetBSD pad to make everything line up on a nice boundary.
@ -195,8 +237,46 @@ int pcap_read(pcap_t *, int cnt, pcap_handler, u_char *);
strlen((y)))
#endif
#ifdef linux
void pcap_close_linux(pcap_t *);
#include <stdarg.h>
#if !defined(HAVE_SNPRINTF)
#define snprintf pcap_snprintf
extern int snprintf (char *, size_t, const char *, ...);
#endif
#if !defined(HAVE_VSNPRINTF)
#define vsnprintf pcap_vsnprintf
extern int vsnprintf (char *, size_t, const char *, va_list ap);
#endif
/*
* Routines that most pcap implementations can use for non-blocking mode.
*/
#ifndef WIN32
int pcap_getnonblock_fd(pcap_t *, char *);
int pcap_setnonblock_fd(pcap_t *p, int, char *);
#endif
/*
* Internal interfaces for "pcap_findalldevs()".
*
* "pcap_platform_finddevs()" is a platform-dependent routine to
* add devices not found by the "standard" mechanisms (SIOCGIFCONF,
* "getifaddrs()", etc..
*
* "pcap_add_if()" adds an interface to the list of interfaces.
*/
int pcap_platform_finddevs(pcap_if_t **, char *);
int add_addr_to_iflist(pcap_if_t **, char *, u_int, struct sockaddr *,
size_t, struct sockaddr *, size_t, struct sockaddr *, size_t,
struct sockaddr *, size_t, char *);
int pcap_add_if(pcap_if_t **, char *, u_int, const char *, char *);
struct sockaddr *dup_sockaddr(struct sockaddr *, size_t);
int add_or_find_if(pcap_if_t **, pcap_if_t **, const char *, u_int,
const char *, char *);
#ifdef WIN32
char *pcap_win32strerror(void);
#endif
/* XXX */
@ -204,6 +284,8 @@ extern int pcap_fddipad;
int install_bpf_program(pcap_t *, struct bpf_program *);
int pcap_strcasecmp(const char *, const char *);
#ifdef __cplusplus
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -19,8 +19,8 @@
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef lint
static const char rcsid[] =
"@(#) $Header: /tcpdump/master/libpcap/pcap-nit.c,v 1.41 2001/12/10 07:14:18 guy Exp $ (LBL)";
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/pcap-nit.c,v 1.50.2.4 2004/03/21 08:33:23 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@ -71,8 +71,8 @@ static const char rcsid[] =
/* Forwards */
static int nit_setflags(int, int, int, char *);
int
pcap_stats(pcap_t *p, struct pcap_stat *ps)
static int
pcap_stats_nit(pcap_t *p, struct pcap_stat *ps)
{
/*
@ -95,8 +95,8 @@ pcap_stats(pcap_t *p, struct pcap_stat *ps)
return (0);
}
int
pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
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;
@ -126,6 +126,26 @@ pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
n = 0;
ep = bp + cc;
while (bp < ep) {
/*
* Has "pcap_breakloop()" been called?
* If so, return immediately - if we haven't read any
* packets, clear the flag and return -2 to indicate
* that we were told to break out of the loop, otherwise
* leave the flag set, so that the *next* call will break
* out of the loop without having read any packets, and
* return the number of packets we've processed so far.
*/
if (p->break_loop) {
if (n == 0) {
p->break_loop = 0;
return (-2);
} else {
p->cc = ep - bp;
p->bp = bp;
return (n);
}
}
nh = (struct nit_hdr *)bp;
cp = bp + sizeof(*nh);
@ -201,8 +221,18 @@ nit_setflags(int fd, int promisc, int to_ms, char *ebuf)
return (0);
}
static void
pcap_close_nit(pcap_t *p)
{
if (p->buffer != NULL)
free(p->buffer);
if (p->fd >= 0)
close(p->fd);
}
pcap_t *
pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
char *ebuf)
{
int fd;
struct sockaddr_nit snit;
@ -249,6 +279,20 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
goto bad;
}
/*
* "p->fd" is a socket, so "select()" should work on it.
*/
p->selectable_fd = p->fd;
p->read_op = pcap_read_nit;
p->setfilter_op = install_bpf_program; /* no kernel filtering */
p->set_datalink_op = NULL; /* can't change data link type */
p->getnonblock_op = pcap_getnonblock_fd;
p->setnonblock_op = pcap_setnonblock_fd;
p->stats_op = pcap_stats_nit;
p->close_op = pcap_close_nit;
return (p);
bad:
if (fd >= 0)
@ -258,10 +302,7 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
}
int
pcap_setfilter(pcap_t *p, struct bpf_program *fp)
pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
{
if (install_bpf_program(p, fp) < 0)
return (-1);
return (0);
}

View File

@ -19,8 +19,8 @@
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef lint
static const char rcsid[] =
"@(#) $Header: /tcpdump/master/libpcap/pcap-null.c,v 1.13 2000/10/28 00:01:29 guy Exp $ (LBL)";
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/pcap-null.c,v 1.20.2.1 2003/11/15 23:26:45 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@ -39,36 +39,16 @@ static const char rcsid[] =
static char nosup[] = "live packet capture not supported on this system";
int
pcap_stats(pcap_t *p, struct pcap_stat *ps)
{
(void)snprintf(p->errbuf, sizeof(p->errbuf), "pcap_stats: %s", nosup);
return (-1);
}
int
pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
{
(void)snprintf(p->errbuf, sizeof(p->errbuf), "pcap_read: %s", nosup);
return (-1);
}
pcap_t *
pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
char *ebuf)
{
(void)strlcpy(ebuf, nosup, PCAP_ERRBUF_SIZE);
return (NULL);
}
int
pcap_setfilter(pcap_t *p, struct bpf_program *fp)
pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
{
if (p->sf.rfile == NULL) {
(void)snprintf(p->errbuf, sizeof(p->errbuf),
"pcap_setfilter: %s", nosup);
return (-1);
}
if (install_bpf_program(p, fp) < 0)
return (-1);
return (0);
}

View File

@ -23,8 +23,8 @@
*/
#ifndef lint
static const char rcsid[] =
"@(#) $Header: /tcpdump/master/libpcap/pcap-pf.c,v 1.65 2001/12/10 07:14:19 guy Exp $ (LBL)";
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/pcap-pf.c,v 1.79.2.5 2003/11/22 00:32:55 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@ -61,12 +61,21 @@ struct rtentry;
#include <string.h>
#include <unistd.h>
/*
* Make "pcap.h" not include "pcap-bpf.h"; we are going to include the
* native OS version, as we need various BPF ioctls from it.
*/
#define PCAP_DONT_INCLUDE_PCAP_BPF_H
#include <net/bpf.h>
#include "pcap-int.h"
#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
static int pcap_setfilter_pf(pcap_t *, struct bpf_program *);
/*
* BUFSPACE is the size in bytes of the packet read buffer. Most tcpdump
* applications aren't going to need more than 200 bytes of packet header
@ -75,8 +84,8 @@ struct rtentry;
*/
#define BUFSPACE (200 * 256)
int
pcap_read(pcap_t *pc, int cnt, pcap_handler callback, u_char *user)
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;
@ -126,6 +135,25 @@ pcap_read(pcap_t *pc, int cnt, pcap_handler callback, u_char *user)
pad = 0;
#endif
while (cc > 0) {
/*
* Has "pcap_breakloop()" been called?
* If so, return immediately - if we haven't read any
* packets, clear the flag and return -2 to indicate
* that we were told to break out of the loop, otherwise
* leave the flag set, so that the *next* call will break
* out of the loop without having read any packets, and
* return the number of packets we've processed so far.
*/
if (pc->break_loop) {
if (n == 0) {
pc->break_loop = 0;
return (-2);
} else {
pc->cc = cc;
pc->bp = bp;
return (n);
}
}
if (cc < sizeof(*sp)) {
snprintf(pc->errbuf, sizeof(pc->errbuf),
"pf short read (%d)", cc);
@ -191,8 +219,8 @@ pcap_read(pcap_t *pc, int cnt, pcap_handler callback, u_char *user)
return (n);
}
int
pcap_stats(pcap_t *p, struct pcap_stat *ps)
static int
pcap_stats_pf(pcap_t *p, struct pcap_stat *ps)
{
/*
@ -237,8 +265,18 @@ pcap_stats(pcap_t *p, struct pcap_stat *ps)
return (0);
}
static void
pcap_close_pf(pcap_t *p)
{
if (p->buffer != NULL)
free(p->buffer);
if (p->fd >= 0)
close(p->fd);
}
pcap_t *
pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
char *ebuf)
{
pcap_t *p;
short enmode;
@ -253,10 +291,17 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
return (0);
}
memset(p, 0, sizeof(*p));
/*
* XXX - we assume here that "pfopen()" does not, in fact, modify
* its argument, even though it takes a "char *" rather than a
* "const char *" as its first argument. That appears to be
* the case, at least on Digital UNIX 4.0.
*/
p->fd = pfopen(device, O_RDONLY);
if (p->fd < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "pf open: %s: %s\n\
your system may not be properly configured; see \"man packetfilter(4)\"\n",
your system may not be properly configured; see the packetfilter(4) man page\n",
device, pcap_strerror(errno));
goto bad;
}
@ -345,7 +390,7 @@ your system may not be properly configured; see \"man packetfilter(4)\"\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 %lu",
snprintf(ebuf, PCAP_ERRBUF_SIZE, "unknown data-link type %u",
devparams.end_dev_type);
goto bad;
}
@ -381,51 +426,113 @@ your system may not be properly configured; see \"man packetfilter(4)\"\n",
goto bad;
}
}
p->bufsize = BUFSPACE;
p->buffer = (u_char*)malloc(p->bufsize + p->offset);
if (p->buffer == NULL) {
strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
goto bad;
}
/*
* "select()" and "poll()" work on packetfilter devices.
*/
p->selectable_fd = p->fd;
p->read_op = pcap_read_pf;
p->setfilter_op = pcap_setfilter_pf;
p->set_datalink_op = NULL; /* can't change data link type */
p->getnonblock_op = pcap_getnonblock_fd;
p->setnonblock_op = pcap_setnonblock_fd;
p->stats_op = pcap_stats_pf;
p->close_op = pcap_close_pf;
return (p);
bad:
if (p->fd >= 0)
close(p->fd);
if (p->fd >= 0)
close(p->fd);
free(p);
return (NULL);
}
int
pcap_setfilter(pcap_t *p, struct bpf_program *fp)
pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
{
/*
* See if BIOCSETF works. If it does, the kernel supports
* BPF-style filters, and we do not need to do post-filtering.
*/
p->md.use_bpf = (ioctl(p->fd, BIOCSETF, (caddr_t)fp) >= 0);
if (p->md.use_bpf) {
struct bpf_version bv;
if (ioctl(p->fd, BIOCVERSION, (caddr_t)&bv) < 0) {
snprintf(p->errbuf, sizeof(p->errbuf),
"BIOCVERSION: %s", pcap_strerror(errno));
return (-1);
}
else if (bv.bv_major != BPF_MAJOR_VERSION ||
bv.bv_minor < BPF_MINOR_VERSION) {
fprintf(stderr,
"requires bpf language %d.%d or higher; kernel is %d.%d",
BPF_MAJOR_VERSION, BPF_MINOR_VERSION,
bv.bv_major, bv.bv_minor);
/* don't give up, just be inefficient */
p->md.use_bpf = 0;
}
} else {
if (install_bpf_program(p, fp) < 0)
return (-1);
}
/*XXX this goes in tcpdump*/
if (p->md.use_bpf)
fprintf(stderr, "tcpdump: Using kernel BPF filter\n");
else
fprintf(stderr, "tcpdump: Filtering in user process\n");
return (0);
}
static int
pcap_setfilter_pf(pcap_t *p, struct bpf_program *fp)
{
struct bpf_version bv;
/*
* See if BIOCVERSION works. If not, we assume the kernel doesn't
* support BPF-style filters (it's not documented in the bpf(7)
* or packetfiler(7) man pages, but the code used to fail if
* BIOCSETF worked but BIOCVERSION didn't, and I've seen it do
* kernel filtering in DU 4.0, so presumably BIOCVERSION works
* there, at least).
*/
if (ioctl(p->fd, BIOCVERSION, (caddr_t)&bv) >= 0) {
/*
* OK, we have the version of the BPF interpreter;
* is it the same major version as us, and the same
* or better minor version?
*/
if (bv.bv_major == BPF_MAJOR_VERSION &&
bv.bv_minor >= BPF_MINOR_VERSION) {
/*
* Yes. Try to install the filter.
*/
if (ioctl(p->fd, BIOCSETF, (caddr_t)fp) < 0) {
snprintf(p->errbuf, sizeof(p->errbuf),
"BIOCSETF: %s", pcap_strerror(errno));
return (-1);
}
/*
* OK, that succeeded. We're doing filtering in
* the kernel. (We assume we don't have a
* userland filter installed - that'd require
* a previous version check to have failed but
* this one to succeed.)
*
* XXX - this message should be supplied to the
* application as a warning of some sort,
* except that if it's a GUI application, it's
* not clear that it should be displayed in
* a window to annoy the user.
*/
fprintf(stderr, "tcpdump: Using kernel BPF filter\n");
p->md.use_bpf = 1;
return (0);
}
/*
* We can't use the kernel's BPF interpreter; don't give
* up, just log a message and be inefficient.
*
* XXX - this should really be supplied to the application
* as a warning of some sort.
*/
fprintf(stderr,
"tcpdump: Requires BPF language %d.%d or higher; kernel is %d.%d\n",
BPF_MAJOR_VERSION, BPF_MINOR_VERSION,
bv.bv_major, bv.bv_minor);
}
/*
* We couldn't do filtering in the kernel; do it in userland.
*/
if (install_bpf_program(p, fp) < 0)
return (-1);
/*
* XXX - this message should be supplied by the application as
* a warning of some sort.
*/
fprintf(stderr, "tcpdump: Filtering in user process\n");
p->md.use_bpf = 0;
return (0);
}

View File

@ -24,8 +24,8 @@
*/
#ifndef lint
static const char rcsid[] =
"@(#) $Header: /tcpdump/master/libpcap/pcap-snit.c,v 1.56 2001/12/10 07:14:20 guy Exp $ (LBL)";
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/pcap-snit.c,v 1.66.2.3 2003/11/21 10:20:48 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@ -84,8 +84,8 @@ static const char rcsid[] =
/* Forwards */
static int nit_setflags(int, int, int, char *);
int
pcap_stats(pcap_t *p, struct pcap_stat *ps)
static int
pcap_stats_snit(pcap_t *p, struct pcap_stat *ps)
{
/*
@ -109,8 +109,8 @@ pcap_stats(pcap_t *p, struct pcap_stat *ps)
return (0);
}
int
pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
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;
@ -141,6 +141,26 @@ pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
n = 0;
ep = bp + cc;
while (bp < ep) {
/*
* Has "pcap_breakloop()" been called?
* If so, return immediately - if we haven't read any
* packets, clear the flag and return -2 to indicate
* that we were told to break out of the loop, otherwise
* leave the flag set, so that the *next* call will break
* out of the loop without having read any packets, and
* return the number of packets we've processed so far.
*/
if (p->break_loop) {
if (n == 0) {
p->break_loop = 0;
return (-2);
} else {
p->bp = bp;
p->cc = ep - bp;
return (n);
}
}
++p->md.stat.ps_recv;
cp = bp;
@ -218,8 +238,18 @@ nit_setflags(int fd, int promisc, int to_ms, char *ebuf)
return (0);
}
static void
pcap_close_snit(pcap_t *p)
{
if (p->buffer != NULL)
free(p->buffer);
if (p->fd >= 0)
close(p->fd);
}
pcap_t *
pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
char *ebuf)
{
struct strioctl si; /* struct for ioctl() */
struct ifreq ifr; /* interface request struct */
@ -272,7 +302,7 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
/* request the interface */
strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = ' ';
ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0';
si.ic_cmd = NIOCBIND;
si.ic_len = sizeof(ifr);
si.ic_dp = (char *)&ifr;
@ -307,6 +337,21 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
goto bad;
}
/*
* "p->fd" is an FD for a STREAMS device, so "select()" and
* "poll()" should work on it.
*/
p->selectable_fd = p->fd;
p->read_op = pcap_read_snit;
p->setfilter_op = install_bpf_program; /* no kernel filtering */
p->set_datalink_op = NULL; /* can't change data link type */
p->getnonblock_op = pcap_getnonblock_fd;
p->setnonblock_op = pcap_setnonblock_fd;
p->stats_op = pcap_stats_snit;
p->close_op = pcap_close_snit;
return (p);
bad:
if (fd >= 0)
@ -316,10 +361,7 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
}
int
pcap_setfilter(pcap_t *p, struct bpf_program *fp)
pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
{
if (install_bpf_program(p, fp) < 0)
return (-1);
return (0);
}

View File

@ -19,8 +19,8 @@
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef lint
static const char rcsid[] =
"@(#) $Header: /tcpdump/master/libpcap/pcap-snoop.c,v 1.33 2001/12/10 07:14:21 guy Exp $ (LBL)";
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/pcap-snoop.c,v 1.45.2.5 2004/03/21 08:33:24 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@ -58,8 +58,8 @@ static const char rcsid[] =
#include "os-proto.h"
#endif
int
pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
static int
pcap_read_snoop(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
{
int cc;
register struct snoopheader *sh;
@ -68,13 +68,25 @@ pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
register u_char *cp;
again:
/*
* Has "pcap_breakloop()" been called?
*/
if (p->break_loop) {
/*
* Yes - clear the flag that indicates that it
* has, and return -2 to indicate that we were
* told to break out of the loop.
*/
p->break_loop = 0;
return (-2);
}
cc = read(p->fd, (char *)p->buffer, p->bufsize);
if (cc < 0) {
/* Don't choke when we get ptraced */
switch (errno) {
case EINTR:
goto again;
goto again;
case EWOULDBLOCK:
return (0); /* XXX */
@ -88,11 +100,23 @@ pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
caplen = (datalen < p->snapshot) ? datalen : p->snapshot;
cp = (u_char *)(sh + 1) + p->offset; /* XXX */
/*
* XXX unfortunately snoop loopback isn't exactly like
* BSD's. The address family is encoded in the first 2
* bytes rather than the first 4 bytes! Luckily the last
* two snoop loopback bytes are zeroed.
*/
if (p->linktype == DLT_NULL && *((short *)(cp + 2)) == 0) {
u_int *uip = (u_int *)cp;
*uip >>= 16;
}
if (p->fcode.bf_insns == NULL ||
bpf_filter(p->fcode.bf_insns, cp, datalen, caplen)) {
struct pcap_pkthdr h;
++p->md.stat.ps_recv;
h.ts = sh->snoop_timestamp;
h.ts.tv_sec = sh->snoop_timestamp.tv_sec;
h.ts.tv_usec = sh->snoop_timestamp.tv_usec;
h.len = datalen;
h.caplen = caplen;
(*callback)(user, &h, cp);
@ -101,8 +125,8 @@ pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
return (0);
}
int
pcap_stats(pcap_t *p, struct pcap_stat *ps)
static int
pcap_stats_snoop(pcap_t *p, struct pcap_stat *ps)
{
register struct rawstats *rs;
struct rawstats rawstats;
@ -141,9 +165,19 @@ pcap_stats(pcap_t *p, struct pcap_stat *ps)
return (0);
}
static void
pcap_close_snoop(pcap_t *p)
{
if (p->buffer != NULL)
free(p->buffer);
if (p->fd >= 0)
close(p->fd);
}
/* XXX can't disable promiscuous */
pcap_t *
pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
char *ebuf)
{
int fd;
struct sockaddr_raw sr;
@ -191,6 +225,7 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
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 */
@ -211,9 +246,15 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
} else if (strncmp("ppp", device, 3) == 0) {
p->linktype = DLT_RAW;
ll_hdrlen = 0; /* DLT_RAW meaning "no PPP header, just the IP packet"? */
} else if (strncmp("qfa", device, 3) == 0) {
p->linktype = DLT_IP_OVER_FC;
ll_hdrlen = 24;
} else if (strncmp("pl", device, 2) == 0) {
p->linktype = DLT_RAW;
ll_hdrlen = 0; /* Cray UNICOS/mp pseudo link */
} else if (strncmp("lo", device, 2) == 0) {
p->linktype = DLT_NULL;
ll_hdrlen = 4; /* is this just like BSD's loopback device? */
ll_hdrlen = 4;
} else {
snprintf(ebuf, PCAP_ERRBUF_SIZE,
"snoop: unknown physical layer type");
@ -249,8 +290,8 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
#ifndef ifr_mtu
#define ifr_mtu ifr_metric
#endif
if (snaplen > ifr.ifr_mtu)
snaplen = ifr.ifr_mtu;
if (snaplen > ifr.ifr_mtu + ll_hdrlen)
snaplen = ifr.ifr_mtu + ll_hdrlen;
#endif
/*
@ -282,6 +323,19 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
goto bad;
}
/*
* "p->fd" is a socket, so "select()" should work on it.
*/
p->selectable_fd = p->fd;
p->read_op = pcap_read_snoop;
p->setfilter_op = install_bpf_program; /* no kernel filtering */
p->set_datalink_op = NULL; /* can't change data link type */
p->getnonblock_op = pcap_getnonblock_fd;
p->setnonblock_op = pcap_setnonblock_fd;
p->stats_op = pcap_stats_snoop;
p->close_op = pcap_close_snoop;
return (p);
bad:
(void)close(fd);
@ -290,10 +344,7 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
}
int
pcap_setfilter(pcap_t *p, struct bpf_program *fp)
pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
{
if (install_bpf_program(p, fp) < 0)
return (-1);
return (0);
}

View File

@ -0,0 +1,61 @@
/*
* Copyright (c) 2002 - 2003
* NetGroup, Politecnico di Torino (Italy)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Politecnico di Torino nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#define SIZEOF_CHAR 1
#define SIZEOF_SHORT 2
#define SIZEOF_INT 4
/*
* Avoids a compiler warning in case this was already defined
* (someone defined _WINSOCKAPI_ when including 'windows.h', in order
* to prevent it from including 'winsock.h')
*/
#ifdef _WINSOCKAPI_
#undef _WINSOCKAPI_
#endif
#include <winsock2.h>
#include <fcntl.h>
#include "bittypes.h"
#include <time.h>
#include <io.h>
#ifndef __MINGW32__
#include "IP6_misc.h"
#endif
#define caddr_t char*
#define snprintf _snprintf
#define vsnprintf _vsnprintf
#define inline __inline

View File

@ -0,0 +1,446 @@
/*
* Copyright (c) 1999 - 2003
* NetGroup, Politecnico di Torino (Italy)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Politecnico di Torino nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef lint
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/pcap-win32.c,v 1.15.2.3 2003/11/30 02:32:02 guy Exp $ (LBL)";
#endif
#include <pcap-int.h>
#include <packet32.h>
#include <Ntddndis.h>
#ifdef __MINGW32__
int* _errno();
#define errno (*_errno())
#endif /* __MINGW32__ */
static int pcap_setfilter_win32(pcap_t *, struct bpf_program *);
static int pcap_getnonblock_win32(pcap_t *, char *);
static int pcap_setnonblock_win32(pcap_t *, int, char *);
#define PcapBufSize 256000 /*dimension of the buffer in the pcap_t structure*/
#define SIZE_BUF 1000000
/*
* Header that the WinPcap driver associates to the packets.
* Once was in bpf.h
*/
struct bpf_hdr {
struct timeval bh_tstamp; /* time stamp */
bpf_u_int32 bh_caplen; /* length of captured portion */
bpf_u_int32 bh_datalen; /* original length of packet */
u_short bh_hdrlen; /* length of bpf header (this struct
plus alignment padding) */
};
/* Start winsock */
int
wsockinit()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1);
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 )
{
return -1;
}
return 0;
}
static int
pcap_stats_win32(pcap_t *p, struct pcap_stat *ps)
{
if(PacketGetStats(p->adapter, (struct bpf_stat*)ps) != TRUE){
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "PacketGetStats error: %s", pcap_win32strerror());
return -1;
}
return 0;
}
static int
pcap_read_win32(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
{
int cc;
int n = 0;
register u_char *bp, *ep;
cc = p->cc;
if (p->cc == 0) {
/*
* Has "pcap_breakloop()" been called?
*/
if (p->break_loop) {
/*
* Yes - clear the flag that indicates that it
* has, and return -2 to indicate that we were
* told to break out of the loop.
*/
p->break_loop = 0;
return (-2);
}
/* capture the packets */
if(PacketReceivePacket(p->adapter,p->Packet,TRUE)==FALSE){
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read error: PacketReceivePacket failed");
return (-1);
}
cc = p->Packet->ulBytesReceived;
bp = p->Packet->Buffer;
}
else
bp = p->bp;
/*
* Loop through each packet.
*/
#define bhp ((struct bpf_hdr *)bp)
ep = bp + cc;
while (1) {
register int caplen, hdrlen;
/*
* Has "pcap_breakloop()" been called?
* If so, return immediately - if we haven't read any
* packets, clear the flag and return -2 to indicate
* that we were told to break out of the loop, otherwise
* leave the flag set, so that the *next* call will break
* out of the loop without having read any packets, and
* return the number of packets we've processed so far.
*/
if (p->break_loop) {
if (n == 0) {
p->break_loop = 0;
return (-2);
} else {
p->bp = bp;
p->cc = ep - bp;
return (n);
}
}
if (bp >= ep)
break;
caplen = bhp->bh_caplen;
hdrlen = bhp->bh_hdrlen;
/*
* XXX A bpf_hdr matches a pcap_pkthdr.
*/
(*callback)(user, (struct pcap_pkthdr*)bp, bp + hdrlen);
bp += BPF_WORDALIGN(caplen + hdrlen);
if (++n >= cnt && cnt > 0) {
p->bp = bp;
p->cc = ep - bp;
return (n);
}
}
#undef bhp
p->cc = 0;
return (n);
}
static void
pcap_close_win32(pcap_t *p)
{
if (p->buffer != NULL)
free(p->buffer);
if (p->adapter != NULL) {
PacketCloseAdapter(p->adapter);
p->adapter = NULL;
}
}
pcap_t *
pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
char *ebuf)
{
register pcap_t *p;
NetType type;
/* Init WinSock */
wsockinit();
p = (pcap_t *)malloc(sizeof(*p));
if (p == NULL)
{
snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
return (NULL);
}
memset(p, 0, sizeof(*p));
p->adapter=NULL;
p->adapter = PacketOpenAdapter((char*)device);
if (p->adapter == NULL)
{
/* Adapter detected but we are not able to open it. Return failure. */
snprintf(ebuf, PCAP_ERRBUF_SIZE, "Error opening adapter: %s", pcap_win32strerror());
return NULL;
}
/*get network type*/
if(PacketGetNetType (p->adapter,&type) == FALSE)
{
snprintf(ebuf, PCAP_ERRBUF_SIZE, "Cannot determine the network type: %s", pcap_win32strerror());
goto bad;
}
/*Set the linktype*/
switch (type.LinkType)
{
case NdisMediumWan:
p->linktype = DLT_EN10MB;
break;
case NdisMedium802_3:
p->linktype = DLT_EN10MB;
break;
case NdisMediumFddi:
p->linktype = DLT_FDDI;
break;
case NdisMedium802_5:
p->linktype = DLT_IEEE802;
break;
case NdisMediumArcnetRaw:
p->linktype = DLT_ARCNET;
break;
case NdisMediumArcnet878_2:
p->linktype = DLT_ARCNET;
break;
case NdisMediumAtm:
p->linktype = DLT_ATM_RFC1483;
break;
default:
p->linktype = DLT_EN10MB; /*an unknown adapter is assumed to be ethernet*/
break;
}
/* Set promisquous mode */
if (promisc) PacketSetHwFilter(p->adapter,NDIS_PACKET_TYPE_PROMISCUOUS);
else PacketSetHwFilter(p->adapter,NDIS_PACKET_TYPE_ALL_LOCAL);
/* Set the buffer size */
p->bufsize = PcapBufSize;
p->buffer = (u_char *)malloc(PcapBufSize);
if (p->buffer == NULL)
{
snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
goto bad;
}
p->snapshot = snaplen;
/* allocate Packet structure used during the capture */
if((p->Packet = PacketAllocatePacket())==NULL)
{
snprintf(ebuf, PCAP_ERRBUF_SIZE, "failed to allocate the PACKET structure");
goto bad;
}
PacketInitPacket(p->Packet,(BYTE*)p->buffer,p->bufsize);
/* allocate the standard buffer in the driver */
if(PacketSetBuff( p->adapter, SIZE_BUF)==FALSE)
{
snprintf(ebuf, PCAP_ERRBUF_SIZE,"driver error: not enough memory to allocate the kernel buffer\n");
goto bad;
}
/* tell the driver to copy the buffer only if it contains at least 16K */
if(PacketSetMinToCopy(p->adapter,16000)==FALSE)
{
snprintf(ebuf, PCAP_ERRBUF_SIZE,"Error calling PacketSetMinToCopy: %s\n", pcap_win32strerror());
goto bad;
}
PacketSetReadTimeout(p->adapter, to_ms);
p->read_op = pcap_read_win32;
p->setfilter_op = pcap_setfilter_win32;
p->set_datalink_op = NULL; /* can't change data link type */
p->getnonblock_op = pcap_getnonblock_win32;
p->setnonblock_op = pcap_setnonblock_win32;
p->stats_op = pcap_stats_win32;
p->close_op = pcap_close_win32;
return (p);
bad:
if (p->adapter)
PacketCloseAdapter(p->adapter);
if (p->buffer != NULL)
free(p->buffer);
free(p);
return (NULL);
}
static int
pcap_setfilter_win32(pcap_t *p, struct bpf_program *fp)
{
if(PacketSetBpf(p->adapter,fp)==FALSE){
/* kernel filter not installed. */
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Driver error: cannot set bpf filter: %s", pcap_win32strerror());
return (-1);
}
return (0);
}
static int
pcap_getnonblock_win32(pcap_t *p, char *errbuf)
{
/*
* XXX - if there were a PacketGetReadTimeout() call, we
* would use it, and return 1 if the timeout is -1
* and 0 otherwise.
*/
return (p->nonblock);
}
static int
pcap_setnonblock_win32(pcap_t *p, int nonblock, char *errbuf)
{
int newtimeout;
if (nonblock) {
/*
* Set the read timeout to -1 for non-blocking mode.
*/
newtimeout = -1;
} else {
/*
* Restore the timeout set when the device was opened.
* (Note that this may be -1, in which case we're not
* really leaving non-blocking mode.)
*/
newtimeout = p->timeout;
}
if (!PacketSetReadTimeout(p->adapter, newtimeout)) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"PacketSetReadTimeout: %s", pcap_win32strerror());
return (-1);
}
p->nonblock = (newtimeout == -1);
return (0);
}
/* Set the driver working mode */
int
pcap_setmode(pcap_t *p, int mode){
if (p->adapter==NULL)
{
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "impossible to set mode while reading from a file");
return -1;
}
if(PacketSetMode(p->adapter,mode)==FALSE)
{
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: working mode not recognized");
return -1;
}
return 0;
}
/* Send a packet to the network */
int
pcap_sendpacket(pcap_t *p, u_char *buf, int size){
LPPACKET PacketToSend;
if (p->adapter==NULL)
{
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Writing a packet is allowed only on a physical adapter");
return -1;
}
PacketToSend=PacketAllocatePacket();
PacketInitPacket(PacketToSend,buf,size);
if(PacketSendPacket(p->adapter,PacketToSend,TRUE) == FALSE){
PacketFreePacket(PacketToSend);
return -1;
}
PacketFreePacket(PacketToSend);
return 0;
}
/* Set the dimension of the kernel-level capture buffer */
int
pcap_setbuff(pcap_t *p, int dim)
{
if (p->adapter==NULL)
{
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "The kernel buffer size cannot be set while reading from a file");
return -1;
}
if(PacketSetBuff(p->adapter,dim)==FALSE)
{
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: not enough memory to allocate the kernel buffer");
return -1;
}
return 0;
}
/*set the minimum amount of data that will release a read call*/
int
pcap_setmintocopy(pcap_t *p, int size)
{
if (p->adapter==NULL)
{
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Impossible to set the mintocopy parameter on an offline capture");
return -1;
}
if(PacketSetMinToCopy(p->adapter, size)==FALSE)
{
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: unable to set the requested mintocopy size");
return -1;
}
return 0;
}

View File

@ -1,4 +1,4 @@
.\" @(#) $Header: /tcpdump/master/libpcap/pcap.3,v 1.31 2001/12/29 21:57:07 guy Exp $
.\" @(#) $Header: /tcpdump/master/libpcap/pcap.3,v 1.51.2.9 2004/03/28 21:45:32 fenner Exp $
.\"
.\" Copyright (c) 1994, 1996, 1997
.\" The Regents of the University of California. All rights reserved.
@ -19,7 +19,7 @@
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\"
.TH PCAP 3 "3 January 2001"
.TH PCAP 3 "27 February 2004"
.SH NAME
pcap \- Packet Capture library
.SH SYNOPSIS
@ -34,12 +34,12 @@ char errbuf[PCAP_ERRBUF_SIZE];
.ft
.LP
.ft B
pcap_t *pcap_open_live(char *device, int snaplen,
pcap_t *pcap_open_live(const char *device, int snaplen,
.ti +8
int promisc, int to_ms, char *errbuf)
pcap_t *pcap_open_dead(int linktype, int snaplen)
pcap_t *pcap_open_offline(char *fname, char *errbuf)
pcap_dumper_t *pcap_dump_open(pcap_t *p, char *fname)
pcap_t *pcap_open_offline(const char *fname, char *errbuf)
pcap_dumper_t *pcap_dump_open(pcap_t *p, const char *fname)
.ft
.LP
.ft B
@ -49,9 +49,9 @@ int pcap_getnonblock(pcap_t *p, char *errbuf);
.LP
.ft B
int pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
void pcap_freealldevs(pcap_if_t *)
void pcap_freealldevs(pcap_if_t *alldevs)
char *pcap_lookupdev(char *errbuf)
int pcap_lookupnet(char *device, bpf_u_int32 *netp,
int pcap_lookupnet(const char *device, bpf_u_int32 *netp,
.ti +8
bpf_u_int32 *maskp, char *errbuf)
.ft
@ -77,13 +77,23 @@ void pcap_freecode(struct bpf_program *);
.ft
.LP
.ft B
u_char *pcap_next(pcap_t *p, struct pcap_pkthdr *h)
const u_char *pcap_next(pcap_t *p, struct pcap_pkthdr *h)
int pcap_next_ex(pcap_t *p, struct pcap_pkthdr **pkt_header,
.ti +8
const u_char **pkt_data)
.ft
.LP
.ft B
void pcap_breakloop(pcap_t *)
.ft
.LP
.ft B
int pcap_datalink(pcap_t *p)
int pcap_list_datalinks(pcap_t *p, int **dlt_buf);
int pcap_set_datalink(pcap_t *p, int dlt);
int pcap_datalink_name_to_val(const char *name);
const char *pcap_datalink_val_to_name(int dlt);
const char *pcap_datalink_val_to_description(int dlt);
int pcap_snapshot(pcap_t *p)
int pcap_is_swapped(pcap_t *p)
int pcap_major_version(pcap_t *p)
@ -91,13 +101,17 @@ int pcap_minor_version(pcap_t *p)
int pcap_stats(pcap_t *p, struct pcap_stat *ps)
FILE *pcap_file(pcap_t *p)
int pcap_fileno(pcap_t *p)
int pcap_get_selectable_fd(pcap_t *p)
void pcap_perror(pcap_t *p, char *prefix)
char *pcap_geterr(pcap_t *p)
char *pcap_strerror(int error)
const char *pcap_lib_version(void)
.ft
.LP
.ft B
void pcap_close(pcap_t *p)
int pcap_dump_flush(pcap_dumper_t *p)
FILE *pcap_dump_file(pcap_dumper_t *p)
void pcap_dump_close(pcap_dumper_t *p)
.ft
.fi
@ -135,7 +149,12 @@ argument of "any" or
.B NULL
can be used to capture packets from all interfaces.
.I snaplen
specifies the maximum number of bytes to capture.
specifies the maximum number of bytes to capture. If this value is less
than the size of a packet that is captured, only the first
.I snaplen
bytes of that packet will be captured and provided as packet data. A
value of 65535 should be sufficient, on most if not all networks, to
capture all the data available from the packet.
.I promisc
specifies if the interface is to be put into promiscuous mode.
(Note that even if this parameter is false, the interface
@ -150,7 +169,11 @@ arrange that the read not necessarily return immediately when a packet
is seen, but that it wait for some amount of time to allow more packets
to arrive and to read multiple packets from the OS kernel in one
operation. Not all platforms support a read timeout; on platforms that
don't, the read timeout is ignored.
don't, the read timeout is ignored. A zero value for
.IR to_ms ,
on platforms that support a read timeout,
will cause a read to wait forever to allow enough packets to
arrive, with no timeout.
.I errbuf
is used to return error or warning text. It will be set to error text when
.B pcap_open_live()
@ -331,6 +354,13 @@ to by
may be null if the interface isn't a point-to-point interface
.RE
.PP
.B \-1
is returned on failure, in which case
.B errbuf
is filled in with an appropriate error message;
.B 0
is returned on success.
.PP
.B pcap_freealldevs()
is used to free a list allocated by
.BR pcap_findalldevs() .
@ -379,12 +409,45 @@ a
.I u_char
pointer which is passed in from
.BR pcap_dispatch() ,
a pointer to the
.I pcap_pkthdr
struct (which precede the actual network headers and data),
a
.I const struct pcap_pkthdr
pointer to a structure with the following members:
.RS
.TP
.B ts
a
.I struct timeval
containing the time when the packet was captured
.TP
.B caplen
a
.I bpf_u_int32
giving the number of bytes of the packet that are available from the
capture
.TP
.B len
a
.I bpf_u_int32
giving the length of the packet, in bytes (which might be more than the
number of bytes available from the capture, if the length of the packet
is larger than the maximum number of bytes to capture)
.RE
.PP
and a
.I u_char
pointer to the packet data.
.I const u_char
pointer to the first
.B caplen
(as given in the
.I struct pcap_pkthdr
a pointer to which is passed to the callback routine)
bytes of data from the packet (which won't necessarily be the entire
packet; to capture the entire packet, you will have to provide a value
for
.I snaplen
in your call to
.B pcap_open_live()
that is sufficiently large to get all of the packet's data - a value of
65535 should be sufficient on most if not all networks).
.PP
The number of packets read is returned.
0 is returned if no packets were read from a live capture (if, for
@ -399,6 +462,14 @@ an error in which case
or
.B pcap_geterr()
may be used to display the error text.
A return of \-2 indicates that the loop terminated due to a call to
.B pcap_breakloop()
before any packets were processed.
.ft B
If your application uses pcap_breakloop(),
make sure that you explicitly check for \-1 and \-2, rather than just
checking for a return value < 0.
.ft R
.PP
.BR NOTE :
when reading a live capture,
@ -433,7 +504,17 @@ A negative
.I cnt
causes
.B pcap_loop()
to loop forever (or at least until an error occurs).
to loop forever (or at least until an error occurs). \-1 is returned on
an error; 0 is returned if
.I cnt
is exhausted; \-2 is returned if the loop terminated due to a call to
.B pcap_breakloop()
before any packets were processed.
.ft B
If your application uses pcap_breakloop(),
make sure that you explicitly check for \-1 and \-2, rather than just
checking for a return value < 0.
.ft R
.PP
.B pcap_next()
reads the next packet (by calling
@ -445,6 +526,107 @@ of 1) and returns a
pointer to the data in that packet. (The
.I pcap_pkthdr
struct for that packet is not supplied.)
.B NULL
is returned if an error occured, or if no packets were read from a live
capture (if, for example, they were discarded because they didn't pass
the packet filter, or if, on platforms that support a read timeout that
starts before any packets arrive, the timeout expires before any packets
arrive, or if the file descriptor for the capture device is in
non-blocking mode and no packets were available to be read), or if no
more packets are available in a ``savefile.'' Unfortunately, there is
no way to determine whether an error occured or not.
.PP
.B pcap_next_ex()
reads the next packet and returns a success/failure indication:
.RS
.TP
1
the packet was read without problems
.TP
0
packets are being read from a live capture, and the timeout expired
.TP
\-1
an error occurred while reading the packet
.TP
\-2
packets are being read from a ``savefile'', and there are no more
packets to read from the savefile.
.RE
.PP
If the packet was read without problems, the pointer pointed to by the
.I pkt_header
argument is set to point to the
.I pcap_pkthdr
struct for the packet, and the
pointer pointed to by the
.I pkt_data
argument is set to point to the data in the packet.
.PP
.B pcap_breakloop()
sets a flag that will force
.B pcap_dispatch()
or
.B pcap_loop()
to return rather than looping; they will return the number of packets
that have been processed so far, or \-2 if no packets have been
processed so far.
.PP
This routine is safe to use inside a signal handler on UNIX or a console
control handler on Windows, as it merely sets a flag that is checked
within the loop.
.PP
The flag is checked in loops reading packets from the OS - a signal by
itself will not necessarily terminate those loops - as well as in loops
processing a set of packets returned by the OS.
.ft B
Note that if you are catching signals on UNIX systems that support
restarting system calls after a signal, and calling pcap_breakloop()
in the signal handler, you must specify, when catching those signals,
that system calls should NOT be restarted by that signal. Otherwise,
if the signal interrupted a call reading packets in a live capture,
when your signal handler returns after calling pcap_breakloop(), the
call will be restarted, and the loop will not terminate until more
packets arrive and the call completes.
.PP
Note also that, in a multi-threaded application, if one thread is
blocked in
.BR pcap_dispatch() ,
.BR pcap_loop() ,
.BR pcap_next() ,
or
.BR pcap_next_ex() ,
a call to
.B pcap_breakloop()
in a different thread will not unblock that thread; you will need to use
whatever mechanism the OS provides for breaking a thread out of blocking
calls in order to unblock the thread, such as thread cancellation in
systems that support POSIX threads.
.ft R
.PP
Note that
.B pcap_next()
will, on some platforms, loop reading packets from the OS; that loop
will not necessarily be terminated by a signal, so
.B pcap_breakloop()
should be used to terminate packet processing even if
.B pcap_next()
is being used.
.PP
.B pcap_breakloop()
does not guarantee that no further packets will be processed by
.B pcap_dispatch()
or
.B pcap_loop()
after it is called; at most one more packet might be processed.
.PP
If \-2 is returned from
.B pcap_dispatch()
or
.BR pcap_loop() ,
the flag is cleared, so a subsequent call will resume reading packets.
If a positive number is returned, the flag is not cleared, so a
subsequent call will return \-2 and clear the flag.
.PP
.B pcap_dump()
outputs a packet to the ``savefile'' opened with
@ -472,8 +654,14 @@ struct and is filled in by
.I optimize
controls whether optimization on the resulting code is performed.
.I netmask
specifies the netmask of the local net.
A return of \-1 indicates an error in which case
specifies the IPv4 netmask of the network on which packets are being
captured; it is used only when checking for IPv4 broadcast addresses in
the filter program. If the netmask of the network on which packets are
being captured isn't known to the program, or if packets are being
captured on the Linux "any" pseudo-interface that can capture on more
than one network, a value of 0 can be supplied; tests for IPv4 broadcast
addreses won't be done correctly, but all other tests in the filter
program will be OK. A return of \-1 indicates an error in which case
.BR pcap_geterr()
may be used to display the error text.
.PP
@ -529,7 +717,7 @@ BSD loopback encapsulation; the link layer header is a 4-byte field, in
.I host
byte order, containing a PF_ value from
.B socket.h
for the network-layer protocol of the packet
for the network-layer protocol of the packet.
.IP
Note that ``host byte order'' is the byte order of the machine on which
the packets are captured, and the PF_ values are for the OS of the
@ -579,45 +767,48 @@ COMPRESSED_TCP, the compressed TCP/IP datagram header;
.RE
.RS 5
.LP
for a total of 16 bytes; the uncompressed IP datagram follows the header
for a total of 16 bytes; the uncompressed IP datagram follows the header.
.RE
.TP 5
.B DLT_PPP
PPP; if the first 2 bytes are 0xff and 0x03, it's PPP in HDLC-like
framing, with the PPP header following those two bytes, otherwise it's
PPP without framing, and the packet begins with the PPP header
PPP without framing, and the packet begins with the PPP header.
.TP 5
.B DLT_FDDI
FDDI
.TP 5
.B DLT_ATM_RFC1483
RFC 1483 LLC/SNAP-encapsulated ATM; the packet begins with an IEEE 802.2
LLC header
LLC header.
.TP 5
.B DLT_RAW
raw IP; the packet begins with an IP header
raw IP; the packet begins with an IP header.
.TP 5
.B DLT_PPP_SERIAL
PPP in HDLC-like framing, as per RFC 1662, or Cisco PPP with HDLC
framing, as per section 4.3.1 of RFC 1547; the first byte will be 0xFF
for PPP in HDLC-like framing, and will be 0x0F or 0x8F for Cisco PPP
with HDLC framing
with HDLC framing.
.TP 5
.B DLT_PPP_ETHER
PPPoE; the packet begins with a PPPoE header, as per RFC 2516
PPPoE; the packet begins with a PPPoE header, as per RFC 2516.
.TP 5
.B DLT_C_HDLC
Cisco PPP with HDLC framing, as per section 4.3.1 of RFC 1547
Cisco PPP with HDLC framing, as per section 4.3.1 of RFC 1547.
.TP 5
.B DLT_IEEE802_11
IEEE 802.11 wireless LAN
.TP 5
.B DLT_FRELAY
Frame Relay
.TP 5
.B DLT_LOOP
OpenBSD loopback encapsulation; the link layer header is a 4-byte field, in
.I network
byte order, containing a PF_ value from OpenBSD's
.B socket.h
for the network-layer protocol of the packet
for the network-layer protocol of the packet.
.IP
Note that, if a ``savefile'' is being read, those PF_ values are
.I not
@ -662,7 +853,131 @@ header or 4 for frames beginning with an 802.2 LLC header.
.RE
.TP 5
.B DLT_LTALK
Apple LocalTalk; the packet begins with an AppleTalk LLAP header
Apple LocalTalk; the packet begins with an AppleTalk LLAP header.
.TP 5
.B DLT_PFLOG
OpenBSD pflog; the link layer header contains, in order:
.RS 10
.LP
a 1-byte header length, in host byte order;
.LP
a 4-byte PF_ value, in host byte order;
.LP
a 2-byte action code, in network byte order, which is one of:
.RS 5
.TP 5
0
passed
.TP 5
1
dropped
.TP 5
2
scrubbed
.RE
.LP
a 2-byte reason code, in network byte order, which is one of:
.RS 5
.TP 5
0
match
.TP 5
1
bad offset
.TP 5
2
fragment
.TP 5
3
short
.TP 5
4
normalize
.TP 5
5
memory
.RE
.LP
a 16-character interface name;
.LP
a 16-character ruleset name (only meaningful if subrule is set);
.LP
a 4-byte rule number, in network byte order;
.LP
a 4-byte subrule number, in network byte order;
.LP
a 1-byte direction, in network byte order, which is one of:
.RS 5
.TP 5
0
incoming or outgoing
.TP 5
1
incoming
.TP 5
2
outgoing
.RE
.RE
.TP 5
.B DLT_PRISM_HEADER
Prism monitor mode information followed by an 802.11 header.
.TP 5
.B DLT_IP_OVER_FC
RFC 2625 IP-over-Fibre Channel, with the link-layer header being the
Network_Header as described in that RFC.
.TP 5
.B DLT_SUNATM
SunATM devices; the link layer header contains, in order:
.RS 10
.LP
a 1-byte flag field, containing a direction flag in the uppermost bit,
which is set for packets transmitted by the machine and clear for
packets received by the machine, and a 4-byte traffic type in the
low-order 4 bits, which is one of:
.RS 5
.TP 5
0
raw traffic
.TP 5
1
LANE traffic
.TP 5
2
LLC-encapsulated traffic
.TP 5
3
MARS traffic
.TP 5
4
IFMP traffic
.TP 5
5
ILMI traffic
.TP 5
6
Q.2931 traffic
.RE
.LP
a 1-byte VPI value;
.LP
a 2-byte VCI field, in network byte order.
.RE
.TP 5
.B DLT_IEEE802_11_RADIO
link-layer information followed by an 802.11 header - see
http://www.shaftnet.org/~pizza/software/capturefrm.txt for a description
of the link-layer information.
.TP 5
.B DLT_ARCNET_LINUX
ARCNET, with no exception frames, reassembled packets rather than raw
frames, and an extra 16-bit offset field between the destination host
and type bytes.
.TP 5
.B DLT_LINUX_IRDA
Linux-IrDA packets, with a
.B DLT_LINUX_SLL
header followed by the IrLAP header.
.RE
.PP
.B pcap_list_datalinks()
@ -690,12 +1005,20 @@ name with the
.B DLT_
removed, to the corresponding data link type value. The translation
is case-insensitive.
is used to set the current data link type of the pcap descriptor
NULL is returned on failure.
.B \-1
is returned on failure.
.PP
.B pcap_datalink_val_to_name()
translates a data link type value to the corresponding data link type
name. NULL is returned on failure.
.PP
.B pcap_datalink_val_to_description()
translates a data link type value to a short description of that data
link type. NULL is returned on failure.
.PP
.B pcap_snapshot()
returns the snapshot length specified when
.B pcap_open_live
.B pcap_open_live()
was called.
.PP
.B pcap_is_swapped()
@ -703,12 +1026,10 @@ returns true if the current ``savefile'' uses a different byte order
than the current system.
.PP
.B pcap_major_version()
returns the major number of the version of the pcap used to write the
savefile.
.PP
returns the major number of the file format of the savefile;
.B pcap_minor_version()
returns the minor number of the version of the pcap used to write the
savefile.
returns the minor number of the file format of the savefile. The
version number is stored in the header of the savefile.
.PP
.B pcap_file()
returns the standard I/O stream of the ``savefile,'' if a ``savefile''
@ -739,6 +1060,67 @@ if a network device was opened with
or \-1, if a ``savefile'' was opened with
.BR pcap_open_offline() .
.PP
.B pcap_get_selectable_fd()
returns, on UNIX, a file descriptor number for a file descriptor on
which one can
do a
.B select()
or
.B poll()
to wait for it to be possible to read packets without blocking, if such
a descriptor exists, or \-1, if no such descriptor exists. Some network
devices opened with
.B pcap_open_live()
do not support
.B select()
or
.B poll()
(for example, regular network devices on FreeBSD 4.3 and 4.4, and Endace
DAG devices), so \-1 is returned for those devices.
.PP
Note that on most versions of most BSDs (including Mac OS X)
.B select()
and
.B poll()
do not work correctly on BPF devices;
.B pcap_get_selectable_fd()
will return a file descriptor on most of those versions (the exceptions
being FreeBSD 4.3 and 4.4), a simple
.B select()
or
.B poll()
will not return even after a timeout specified in
.B pcap_open_live()
expires. To work around this, an application that uses
.B select()
or
.B poll()
to wait for packets to arrive must put the
.B pcap_t
in non-blocking mode, and must arrange that the
.B select()
or
.B poll()
have a timeout less than or equal to the timeout specified in
.BR pcap_open_live() ,
and must try to read packets after that timeout expires, regardless of
whether
.B select()
or
.B poll()
indicated that the file descriptor for the
.B pcap_t
is ready to be read or not. (That workaround will not work in FreeBSD
4.3 and later; however, in FreeBSD 4.6 and later,
.B select()
and
.B poll()
work correctly on BPF devices, so the workaround isn't necessary,
although it does no harm.)
.PP
.B pcap_get_selectable_fd()
is not available on Windows.
.PP
.B pcap_perror()
prints the text of the last pcap library error on
.BR stderr ,
@ -760,11 +1142,28 @@ is provided in case
.BR strerror (1)
isn't available.
.PP
.B pcap_lib_version()
returns a pointer to a string giving information about the version of
the libpcap library being used; note that it contains more information
than just a version number.
.PP
.B pcap_close()
closes the files associated with
.I p
and deallocates resources.
.PP
.B pcap_dump_file()
returns the standard I/O stream of the ``savefile'' opened by
.BR pcap_dump_open().
.PP
.B pcap_dump_flush()
flushes the output buffer to the ``savefile,'' so that any packets
written with
.B pcap_dump()
but not yet written to the ``savefile'' will be written.
.B \-1
is returned on error, 0 on success.
.PP
.B pcap_dump_close()
closes the ``savefile.''
.PP

View File

@ -32,20 +32,26 @@
*/
#ifndef lint
static const char rcsid[] =
"@(#) $Header: /tcpdump/master/libpcap/pcap.c,v 1.38 2001/12/29 21:55:32 guy Exp $ (LBL)";
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/pcap.c,v 1.63.2.9 2004/03/25 22:40:52 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef WIN32
#include <pcap-stdinc.h>
#else /* WIN32 */
#include <sys/types.h>
#endif /* WIN32 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef _MSC_VER
#include <unistd.h>
#endif
#include <fcntl.h>
#include <errno.h>
@ -55,13 +61,26 @@ static const char rcsid[] =
#include "pcap-int.h"
#ifdef HAVE_DAG_API
#include <dagnew.h>
#include <dagapi.h>
#endif
int
pcap_dispatch(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
{
if (p->sf.rfile != NULL)
return (pcap_offline_read(p, cnt, callback, user));
return (pcap_read(p, cnt, callback, user));
return p->read_op(p, cnt, callback, user);
}
/*
* XXX - is this necessary?
*/
int
pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
{
return p->read_op(p, cnt, callback, user);
}
int
@ -70,15 +89,18 @@ pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
register int n;
for (;;) {
if (p->sf.rfile != NULL)
if (p->sf.rfile != NULL) {
/*
* 0 means EOF, so don't loop if we get 0.
*/
n = pcap_offline_read(p, cnt, callback, user);
else {
} else {
/*
* XXX keep reading until we get something
* (or an error occurs)
*/
do {
n = pcap_read(p, cnt, callback, user);
n = p->read_op(p, cnt, callback, user);
} while (n == 0);
}
if (n <= 0)
@ -116,6 +138,79 @@ pcap_next(pcap_t *p, struct pcap_pkthdr *h)
return (s.pkt);
}
struct pkt_for_fakecallback {
struct pcap_pkthdr *hdr;
const u_char **pkt;
};
static void
pcap_fakecallback(u_char *userData, const struct pcap_pkthdr *h,
const u_char *pkt)
{
struct pkt_for_fakecallback *sp = (struct pkt_for_fakecallback *)userData;
*sp->hdr = *h;
*sp->pkt = pkt;
}
int
pcap_next_ex(pcap_t *p, struct pcap_pkthdr **pkt_header,
const u_char **pkt_data)
{
struct pkt_for_fakecallback s;
s.hdr = &p->pcap_header;
s.pkt = pkt_data;
/* Saves a pointer to the packet headers */
*pkt_header= &p->pcap_header;
if (p->sf.rfile != NULL) {
int status;
/* We are on an offline capture */
status = pcap_offline_read(p, 1, pcap_fakecallback,
(u_char *)&s);
/*
* Return codes for pcap_offline_read() are:
* - 0: EOF
* - -1: error
* - >1: OK
* The first one ('0') conflicts with the return code of
* 0 from pcap_read() meaning "no packets arrived before
* the timeout expired", so we map it to -2 so you can
* distinguish between an EOF from a savefile and a
* "no packets arrived before the timeout expired, try
* again" from a live capture.
*/
if (status == 0)
return (-2);
else
return (status);
}
/*
* Return codes for pcap_read() are:
* - 0: timeout
* - -1: error
* - -2: loop was broken out of with pcap_breakloop()
* - >1: OK
* The first one ('0') conflicts with the return code of 0 from
* pcap_offline_read() meaning "end of file".
*/
return (p->read_op(p, 1, pcap_fakecallback, (u_char *)&s));
}
/*
* Force the loop in "pcap_read()" or "pcap_read_offline()" to terminate.
*/
void
pcap_breakloop(pcap_t *p)
{
p->break_loop = 1;
}
int
pcap_datalink(pcap_t *p)
{
@ -125,19 +220,243 @@ pcap_datalink(pcap_t *p)
int
pcap_list_datalinks(pcap_t *p, int **dlt_buffer)
{
if (p->dlt_count <= 0) {
*dlt_buffer = NULL;
return -1;
if (p->dlt_count == 0) {
/*
* We couldn't fetch the list of DLTs, which means
* this platform doesn't support changing the
* DLT for an interface. Return a list of DLTs
* containing only the DLT this device supports.
*/
*dlt_buffer = (int*)malloc(sizeof(**dlt_buffer));
if (*dlt_buffer == NULL) {
(void)snprintf(p->errbuf, sizeof(p->errbuf),
"malloc: %s", pcap_strerror(errno));
return (-1);
}
**dlt_buffer = p->linktype;
return (1);
} else {
*dlt_buffer = (int*)malloc(sizeof(**dlt_buffer) * p->dlt_count);
if (*dlt_buffer == NULL) {
(void)snprintf(p->errbuf, sizeof(p->errbuf),
"malloc: %s", pcap_strerror(errno));
return (-1);
}
(void)memcpy(*dlt_buffer, p->dlt_list,
sizeof(**dlt_buffer) * p->dlt_count);
return (p->dlt_count);
}
*dlt_buffer = (int*)malloc(sizeof(**dlt_buffer) * p->dlt_count);
if (*dlt_buffer == NULL) {
(void)snprintf(p->errbuf, sizeof(p->errbuf), "malloc: %s",
pcap_strerror(errno));
return -1;
}
int
pcap_set_datalink(pcap_t *p, int dlt)
{
int i;
const char *dlt_name;
if (p->dlt_count == 0 || p->set_datalink_op == NULL) {
/*
* We couldn't fetch the list of DLTs, or we don't
* have a "set datalink" operation, which means
* this platform doesn't support changing the
* DLT for an interface. Check whether the new
* DLT is the one this interface supports.
*/
if (p->linktype != dlt)
goto unsupported;
/*
* It is, so there's nothing we need to do here.
*/
return (0);
}
(void)memcpy(*dlt_buffer, p->dlt_list,
sizeof(**dlt_buffer) * p->dlt_count);
return (p->dlt_count);
for (i = 0; i < p->dlt_count; i++)
if (p->dlt_list[i] == dlt)
break;
if (i >= p->dlt_count)
goto unsupported;
if (p->set_datalink_op(p, dlt) == -1)
return (-1);
p->linktype = dlt;
return (0);
unsupported:
dlt_name = pcap_datalink_val_to_name(dlt);
if (dlt_name != NULL) {
(void) snprintf(p->errbuf, sizeof(p->errbuf),
"%s is not one of the DLTs supported by this device",
dlt_name);
} else {
(void) snprintf(p->errbuf, sizeof(p->errbuf),
"DLT %d is not one of the DLTs supported by this device",
dlt);
}
return (-1);
}
struct dlt_choice {
const char *name;
const char *description;
int dlt;
};
#define DLT_CHOICE(code, description) { #code, description, code }
#define DLT_CHOICE_SENTINEL { NULL, NULL, 0 }
static struct dlt_choice dlt_choices[] = {
DLT_CHOICE(DLT_NULL, "BSD loopback"),
DLT_CHOICE(DLT_EN10MB, "Ethernet"),
DLT_CHOICE(DLT_IEEE802, "Token ring"),
DLT_CHOICE(DLT_ARCNET, "ARCNET"),
DLT_CHOICE(DLT_SLIP, "SLIP"),
DLT_CHOICE(DLT_PPP, "PPP"),
DLT_CHOICE(DLT_FDDI, "FDDI"),
DLT_CHOICE(DLT_ATM_RFC1483, "RFC 1483 IP-over-ATM"),
DLT_CHOICE(DLT_RAW, "Raw IP"),
DLT_CHOICE(DLT_SLIP_BSDOS, "BSD/OS SLIP"),
DLT_CHOICE(DLT_PPP_BSDOS, "BSD/OS PPP"),
DLT_CHOICE(DLT_ATM_CLIP, "Linux Classical IP-over-ATM"),
DLT_CHOICE(DLT_PPP_SERIAL, "PPP over serial"),
DLT_CHOICE(DLT_PPP_ETHER, "PPPoE"),
DLT_CHOICE(DLT_C_HDLC, "Cisco HDLC"),
DLT_CHOICE(DLT_IEEE802_11, "802.11"),
DLT_CHOICE(DLT_FRELAY, "Frame Relay"),
DLT_CHOICE(DLT_LOOP, "OpenBSD loopback"),
DLT_CHOICE(DLT_ENC, "OpenBSD encapsulated IP"),
DLT_CHOICE(DLT_LINUX_SLL, "Linux cooked"),
DLT_CHOICE(DLT_LTALK, "Localtalk"),
DLT_CHOICE(DLT_PFLOG, "OpenBSD pflog file"),
DLT_CHOICE(DLT_PRISM_HEADER, "802.11 plus Prism header"),
DLT_CHOICE(DLT_IP_OVER_FC, "RFC 2625 IP-over-Fibre Channel"),
DLT_CHOICE(DLT_SUNATM, "Sun raw ATM"),
DLT_CHOICE(DLT_IEEE802_11_RADIO, "802.11 plus BSD radio information header"),
DLT_CHOICE(DLT_APPLE_IP_OVER_IEEE1394, "Apple IP-over-IEEE 1394"),
DLT_CHOICE(DLT_ARCNET_LINUX, "Linux ARCNET"),
DLT_CHOICE(DLT_LINUX_IRDA, "Linux IrDA"),
DLT_CHOICE(DLT_IEEE802_11_RADIO_AVS, "802.11 plus AVS radio information header"),
DLT_CHOICE_SENTINEL
};
/*
* This array is designed for mapping upper and lower case letter
* together for a case independent comparison. The mappings are
* based upon ascii character sequences.
*/
static const u_char charmap[] = {
(u_char)'\000', (u_char)'\001', (u_char)'\002', (u_char)'\003',
(u_char)'\004', (u_char)'\005', (u_char)'\006', (u_char)'\007',
(u_char)'\010', (u_char)'\011', (u_char)'\012', (u_char)'\013',
(u_char)'\014', (u_char)'\015', (u_char)'\016', (u_char)'\017',
(u_char)'\020', (u_char)'\021', (u_char)'\022', (u_char)'\023',
(u_char)'\024', (u_char)'\025', (u_char)'\026', (u_char)'\027',
(u_char)'\030', (u_char)'\031', (u_char)'\032', (u_char)'\033',
(u_char)'\034', (u_char)'\035', (u_char)'\036', (u_char)'\037',
(u_char)'\040', (u_char)'\041', (u_char)'\042', (u_char)'\043',
(u_char)'\044', (u_char)'\045', (u_char)'\046', (u_char)'\047',
(u_char)'\050', (u_char)'\051', (u_char)'\052', (u_char)'\053',
(u_char)'\054', (u_char)'\055', (u_char)'\056', (u_char)'\057',
(u_char)'\060', (u_char)'\061', (u_char)'\062', (u_char)'\063',
(u_char)'\064', (u_char)'\065', (u_char)'\066', (u_char)'\067',
(u_char)'\070', (u_char)'\071', (u_char)'\072', (u_char)'\073',
(u_char)'\074', (u_char)'\075', (u_char)'\076', (u_char)'\077',
(u_char)'\100', (u_char)'\141', (u_char)'\142', (u_char)'\143',
(u_char)'\144', (u_char)'\145', (u_char)'\146', (u_char)'\147',
(u_char)'\150', (u_char)'\151', (u_char)'\152', (u_char)'\153',
(u_char)'\154', (u_char)'\155', (u_char)'\156', (u_char)'\157',
(u_char)'\160', (u_char)'\161', (u_char)'\162', (u_char)'\163',
(u_char)'\164', (u_char)'\165', (u_char)'\166', (u_char)'\167',
(u_char)'\170', (u_char)'\171', (u_char)'\172', (u_char)'\133',
(u_char)'\134', (u_char)'\135', (u_char)'\136', (u_char)'\137',
(u_char)'\140', (u_char)'\141', (u_char)'\142', (u_char)'\143',
(u_char)'\144', (u_char)'\145', (u_char)'\146', (u_char)'\147',
(u_char)'\150', (u_char)'\151', (u_char)'\152', (u_char)'\153',
(u_char)'\154', (u_char)'\155', (u_char)'\156', (u_char)'\157',
(u_char)'\160', (u_char)'\161', (u_char)'\162', (u_char)'\163',
(u_char)'\164', (u_char)'\165', (u_char)'\166', (u_char)'\167',
(u_char)'\170', (u_char)'\171', (u_char)'\172', (u_char)'\173',
(u_char)'\174', (u_char)'\175', (u_char)'\176', (u_char)'\177',
(u_char)'\200', (u_char)'\201', (u_char)'\202', (u_char)'\203',
(u_char)'\204', (u_char)'\205', (u_char)'\206', (u_char)'\207',
(u_char)'\210', (u_char)'\211', (u_char)'\212', (u_char)'\213',
(u_char)'\214', (u_char)'\215', (u_char)'\216', (u_char)'\217',
(u_char)'\220', (u_char)'\221', (u_char)'\222', (u_char)'\223',
(u_char)'\224', (u_char)'\225', (u_char)'\226', (u_char)'\227',
(u_char)'\230', (u_char)'\231', (u_char)'\232', (u_char)'\233',
(u_char)'\234', (u_char)'\235', (u_char)'\236', (u_char)'\237',
(u_char)'\240', (u_char)'\241', (u_char)'\242', (u_char)'\243',
(u_char)'\244', (u_char)'\245', (u_char)'\246', (u_char)'\247',
(u_char)'\250', (u_char)'\251', (u_char)'\252', (u_char)'\253',
(u_char)'\254', (u_char)'\255', (u_char)'\256', (u_char)'\257',
(u_char)'\260', (u_char)'\261', (u_char)'\262', (u_char)'\263',
(u_char)'\264', (u_char)'\265', (u_char)'\266', (u_char)'\267',
(u_char)'\270', (u_char)'\271', (u_char)'\272', (u_char)'\273',
(u_char)'\274', (u_char)'\275', (u_char)'\276', (u_char)'\277',
(u_char)'\300', (u_char)'\341', (u_char)'\342', (u_char)'\343',
(u_char)'\344', (u_char)'\345', (u_char)'\346', (u_char)'\347',
(u_char)'\350', (u_char)'\351', (u_char)'\352', (u_char)'\353',
(u_char)'\354', (u_char)'\355', (u_char)'\356', (u_char)'\357',
(u_char)'\360', (u_char)'\361', (u_char)'\362', (u_char)'\363',
(u_char)'\364', (u_char)'\365', (u_char)'\366', (u_char)'\367',
(u_char)'\370', (u_char)'\371', (u_char)'\372', (u_char)'\333',
(u_char)'\334', (u_char)'\335', (u_char)'\336', (u_char)'\337',
(u_char)'\340', (u_char)'\341', (u_char)'\342', (u_char)'\343',
(u_char)'\344', (u_char)'\345', (u_char)'\346', (u_char)'\347',
(u_char)'\350', (u_char)'\351', (u_char)'\352', (u_char)'\353',
(u_char)'\354', (u_char)'\355', (u_char)'\356', (u_char)'\357',
(u_char)'\360', (u_char)'\361', (u_char)'\362', (u_char)'\363',
(u_char)'\364', (u_char)'\365', (u_char)'\366', (u_char)'\367',
(u_char)'\370', (u_char)'\371', (u_char)'\372', (u_char)'\373',
(u_char)'\374', (u_char)'\375', (u_char)'\376', (u_char)'\377',
};
int
pcap_strcasecmp(const char *s1, const char *s2)
{
register const u_char *cm = charmap,
*us1 = (u_char *)s1,
*us2 = (u_char *)s2;
while (cm[*us1] == cm[*us2++])
if (*us1++ == '\0')
return(0);
return (cm[*us1] - cm[*--us2]);
}
int
pcap_datalink_name_to_val(const char *name)
{
int i;
for (i = 0; dlt_choices[i].name != NULL; i++) {
if (pcap_strcasecmp(dlt_choices[i].name + sizeof("DLT_") - 1,
name) == 0)
return (dlt_choices[i].dlt);
}
return (-1);
}
const char *
pcap_datalink_val_to_name(int dlt)
{
int i;
for (i = 0; dlt_choices[i].name != NULL; i++) {
if (dlt_choices[i].dlt == dlt)
return (dlt_choices[i].name + sizeof("DLT_") - 1);
}
return (NULL);
}
const char *
pcap_datalink_val_to_description(int dlt)
{
int i;
for (i = 0; dlt_choices[i].name != NULL; i++) {
if (dlt_choices[i].dlt == dlt)
return (dlt_choices[i].description);
}
return (NULL);
}
int
@ -173,9 +492,24 @@ pcap_file(pcap_t *p)
int
pcap_fileno(pcap_t *p)
{
#ifndef WIN32
return (p->fd);
#else
if (p->adapter != NULL)
return ((int)(DWORD)p->adapter->hFile);
else
return (-1);
#endif
}
#ifndef WIN32
int
pcap_get_selectable_fd(pcap_t *p)
{
return (p->selectable_fd);
}
#endif
void
pcap_perror(pcap_t *p, char *prefix)
{
@ -188,23 +522,25 @@ pcap_geterr(pcap_t *p)
return (p->errbuf);
}
/*
* NOTE: in the future, these may need to call platform-dependent routines,
* e.g. on platforms with memory-mapped packet-capture mechanisms where
* "pcap_read()" uses "select()" or "poll()" to wait for packets to arrive.
*/
int
pcap_getnonblock(pcap_t *p, char *errbuf)
{
return p->getnonblock_op(p, errbuf);
}
/*
* Get the current non-blocking mode setting, under the assumption that
* it's just the standard POSIX non-blocking flag.
*
* We don't look at "p->nonblock", in case somebody tweaked the FD
* directly.
*/
#ifndef WIN32
int
pcap_getnonblock_fd(pcap_t *p, char *errbuf)
{
int fdflags;
if (p->sf.rfile != NULL) {
/*
* This is a savefile, not a live capture file, so
* never say it's in non-blocking mode.
*/
return (0);
}
fdflags = fcntl(p->fd, F_GETFL, 0);
if (fdflags == -1) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "F_GETFL: %s",
@ -216,19 +552,26 @@ pcap_getnonblock(pcap_t *p, char *errbuf)
else
return (0);
}
#endif
int
pcap_setnonblock(pcap_t *p, int nonblock, char *errbuf)
{
return p->setnonblock_op(p, nonblock, errbuf);
}
#ifndef WIN32
/*
* Set non-blocking mode, under the assumption that it's just the
* standard POSIX non-blocking flag. (This can be called by the
* per-platform non-blocking-mode routine if that routine also
* needs to do some additional work.)
*/
int
pcap_setnonblock_fd(pcap_t *p, int nonblock, char *errbuf)
{
int fdflags;
if (p->sf.rfile != NULL) {
/*
* This is a savefile, not a live capture file, so
* ignore requests to put it in non-blocking mode.
*/
return (0);
}
fdflags = fcntl(p->fd, F_GETFL, 0);
if (fdflags == -1) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "F_GETFL: %s",
@ -246,6 +589,37 @@ pcap_setnonblock(pcap_t *p, int nonblock, char *errbuf)
}
return (0);
}
#endif
#ifdef WIN32
/*
* Generate a string for the last Win32-specific error (i.e. an error generated when
* calling a Win32 API).
* For errors occurred during standard C calls, we still use pcap_strerror()
*/
char *
pcap_win32strerror(void)
{
DWORD error;
static char errbuf[PCAP_ERRBUF_SIZE+1];
int errlen;
error = GetLastError();
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, errbuf,
PCAP_ERRBUF_SIZE, NULL);
/*
* "FormatMessage()" "helpfully" sticks CR/LF at the end of the
* message. Get rid of it.
*/
errlen = strlen(errbuf);
if (errlen >= 2) {
errbuf[errlen - 1] = '\0';
errbuf[errlen - 2] = '\0';
}
return (errbuf);
}
#endif
/*
* Not all systems have strerror().
@ -267,6 +641,32 @@ pcap_strerror(int errnum)
#endif
}
int
pcap_setfilter(pcap_t *p, struct bpf_program *fp)
{
return p->setfilter_op(p, fp);
}
int
pcap_stats(pcap_t *p, struct pcap_stat *ps)
{
return p->stats_op(p, ps);
}
static int
pcap_stats_dead(pcap_t *p, struct pcap_stat *ps)
{
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"Statistics aren't available from a pcap_open_dead pcap_t");
return (-1);
}
static void
pcap_close_dead(pcap_t *p)
{
/* Nothing to do. */
}
pcap_t *
pcap_open_dead(int linktype, int snaplen)
{
@ -276,32 +676,97 @@ pcap_open_dead(int linktype, int snaplen)
if (p == NULL)
return NULL;
memset (p, 0, sizeof(*p));
p->fd = -1;
p->snapshot = snaplen;
p->linktype = linktype;
p->stats_op = pcap_stats_dead;
p->close_op = pcap_close_dead;
return p;
}
void
pcap_close(pcap_t *p)
{
/*XXX*/
if (p->fd >= 0) {
#ifdef linux
pcap_close_linux(p);
#endif
close(p->fd);
}
if (p->sf.rfile != NULL) {
if (p->sf.rfile != stdin)
(void)fclose(p->sf.rfile);
if (p->sf.base != NULL)
free(p->sf.base);
} else if (p->buffer != NULL)
free(p->buffer);
p->close_op(p);
if (p->dlt_list != NULL)
free(p->dlt_list);
pcap_freecode(&p->fcode);
free(p);
}
/*
* We make the version string static, and return a pointer to it, rather
* than exporting the version string directly. On at least some UNIXes,
* if you import data from a shared library into an program, the data is
* bound into the program binary, so if the string in the version of the
* library with which the program was linked isn't the same as the
* string in the version of the library with which the program is being
* run, various undesirable things may happen (warnings, the string
* being the one from the version of the library with which the program
* was linked, or even weirder things, such as the string being the one
* from the library but being truncated).
*/
#ifdef WIN32
/*
* XXX - it'd be nice if we could somehow generate the WinPcap and libpcap
* version numbers when building WinPcap. (It'd be nice to do so for
* the packet.dll version number as well.)
*/
static const char wpcap_version_string[] = "3.0";
static const char pcap_version_string_fmt[] =
"WinPcap version %s, based on libpcap version 0.8";
static const char pcap_version_string_packet_dll_fmt[] =
"WinPcap version %s (packet.dll version %s), based on libpcap version 0.8";
static char *pcap_version_string;
const char *
pcap_lib_version(void)
{
char *packet_version_string;
size_t pcap_version_string_len;
if (pcap_version_string == NULL) {
/*
* Generate the version string.
*/
packet_version_string = PacketGetVersion();
if (strcmp(wpcap_version_string, packet_version_string) == 0) {
/*
* WinPcap version string and packet.dll version
* string are the same; just report the WinPcap
* version.
*/
pcap_version_string_len =
(sizeof pcap_version_string_fmt - 2) +
strlen(wpcap_version_string);
pcap_version_string = malloc(pcap_version_string_len);
sprintf(pcap_version_string, pcap_version_string_fmt,
wpcap_version_string);
} else {
/*
* WinPcap version string and packet.dll version
* string are different; that shouldn't be the
* case (the two libraries should come from the
* same version of WinPcap), so we report both
* versions.
*/
pcap_version_string_len =
(sizeof pcap_version_string_packet_dll_fmt - 4) +
strlen(wpcap_version_string) +
strlen(packet_version_string);
pcap_version_string = malloc(pcap_version_string_len);
sprintf(pcap_version_string,
pcap_version_string_packet_dll_fmt,
wpcap_version_string, packet_version_string);
}
}
return (pcap_version_string);
}
#else
#include "version.h"
const char *
pcap_lib_version(void)
{
return (pcap_version_string);
}
#endif

View File

@ -31,16 +31,22 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#) $Header: /tcpdump/master/libpcap/pcap.h,v 1.34 2001/12/09 05:10:03 guy Exp $ (LBL)
* @(#) $Header: /tcpdump/master/libpcap/pcap.h,v 1.45.2.4 2004/01/27 22:56:20 guy Exp $ (LBL)
*/
#ifndef lib_pcap_h
#define lib_pcap_h
#ifdef WIN32
#include <pcap-stdinc.h>
#else /* WIN32 */
#include <sys/types.h>
#include <sys/time.h>
#endif /* WIN32 */
#include <net/bpf.h>
#ifndef PCAP_DONT_INCLUDE_PCAP_BPF_H
#include <pcap-bpf.h>
#endif
#include <stdio.h>
@ -129,6 +135,9 @@ struct pcap_stat {
u_int ps_recv; /* number of packets received */
u_int ps_drop; /* number of packets dropped */
u_int ps_ifdrop; /* drops by interface XXX not yet supported */
#ifdef WIN32
u_int bs_capt; /* number of packets that reach the application */
#endif /* WIN32 */
};
/*
@ -139,7 +148,7 @@ struct pcap_if {
char *name; /* name to hand to "pcap_open_live()" */
char *description; /* textual description of interface, or NULL */
struct pcap_addr *addresses;
u_int flags; /* PCAP_IF_ interface flags */
bpf_u_int32 flags; /* PCAP_IF_ interface flags */
};
#define PCAP_IF_LOOPBACK 0x00000001 /* interface is loopback */
@ -159,8 +168,8 @@ typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *,
const u_char *);
char *pcap_lookupdev(char *);
int pcap_lookupnet(char *, bpf_u_int32 *, bpf_u_int32 *, char *);
pcap_t *pcap_open_live(char *, int, int, int, char *);
int pcap_lookupnet(const char *, bpf_u_int32 *, bpf_u_int32 *, char *);
pcap_t *pcap_open_live(const char *, int, int, int, char *);
pcap_t *pcap_open_dead(int, int);
pcap_t *pcap_open_offline(const char *, char *);
void pcap_close(pcap_t *);
@ -168,6 +177,8 @@ int pcap_loop(pcap_t *, int, pcap_handler, u_char *);
int pcap_dispatch(pcap_t *, int, pcap_handler, u_char *);
const u_char*
pcap_next(pcap_t *, struct pcap_pkthdr *);
int pcap_next_ex(pcap_t *, struct pcap_pkthdr **, const u_char **);
void pcap_breakloop(pcap_t *);
int pcap_stats(pcap_t *, struct pcap_stat *);
int pcap_setfilter(pcap_t *, struct bpf_program *);
int pcap_getnonblock(pcap_t *, char *);
@ -183,6 +194,9 @@ void pcap_freecode(struct bpf_program *);
int pcap_datalink(pcap_t *);
int pcap_list_datalinks(pcap_t *, int **);
int pcap_set_datalink(pcap_t *, int);
int pcap_datalink_name_to_val(const char *);
const char *pcap_datalink_val_to_name(int);
const char *pcap_datalink_val_to_description(int);
int pcap_snapshot(pcap_t *);
int pcap_is_swapped(pcap_t *);
int pcap_major_version(pcap_t *);
@ -193,18 +207,50 @@ FILE *pcap_file(pcap_t *);
int pcap_fileno(pcap_t *);
pcap_dumper_t *pcap_dump_open(pcap_t *, const char *);
int pcap_dump_flush(pcap_dumper_t *);
void pcap_dump_close(pcap_dumper_t *);
void pcap_dump(u_char *, const struct pcap_pkthdr *, const u_char *);
FILE *pcap_dump_file(pcap_dumper_t *);
int pcap_findalldevs(pcap_if_t **, char *);
void pcap_freealldevs(pcap_if_t *);
const char *pcap_lib_version(void);
/* XXX this guy lives in the bpf tree */
u_int bpf_filter(struct bpf_insn *, u_char *, u_int, u_int);
int bpf_validate(struct bpf_insn *f, int len);
char *bpf_image(struct bpf_insn *, int);
void bpf_dump(struct bpf_program *, int);
#ifdef WIN32
/*
* Win32 definitions
*/
int pcap_setbuff(pcap_t *p, int dim);
int pcap_setmode(pcap_t *p, int mode);
int pcap_sendpacket(pcap_t *p, u_char *buf, int size);
int pcap_setmintocopy(pcap_t *p, int size);
#ifdef WPCAP
/* Include file with the wpcap-specific extensions */
#include <Win32-Extensions.h>
#endif
#define MODE_CAPT 0
#define MODE_STAT 1
#define MODE_MON 2
#else
/*
* UN*X definitions
*/
int pcap_get_selectable_fd(pcap_t *);
#endif /* WIN32 */
#ifdef __cplusplus
}
#endif

77
contrib/libpcap/pf.h Normal file
View File

@ -0,0 +1,77 @@
/*
* Copyright (c) 2001 Daniel Hartmeier
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @(#) $Header: /tcpdump/master/libpcap/pf.h,v 1.1.2.1 2004/03/28 21:45:33 fenner Exp $ (LBL)
*/
/* from $OpenBSD: pfvar.h,v 1.170 2003/08/22 21:50:34 david Exp $ */
enum { PF_INOUT=0, PF_IN=1, PF_OUT=2 };
enum { PF_PASS=0, PF_DROP=1, PF_SCRUB=2, PF_NAT=3, PF_NONAT=4,
PF_BINAT=5, PF_NOBINAT=6, PF_RDR=7, PF_NORDR=8, PF_SYNPROXY_DROP=9 };
/* Reasons code for passing/dropping a packet */
#define PFRES_MATCH 0 /* Explicit match of a rule */
#define PFRES_BADOFF 1 /* Bad offset for pull_hdr */
#define PFRES_FRAG 2 /* Dropping following fragment */
#define PFRES_SHORT 3 /* Dropping short packet */
#define PFRES_NORM 4 /* Dropping by normalizer */
#define PFRES_MEMORY 5 /* Dropped due to lacking mem */
#define PFRES_MAX 6 /* total+1 */
#define PFRES_NAMES { \
"match", \
"bad-offset", \
"fragment", \
"short", \
"normalize", \
"memory", \
NULL \
}
#define PF_RULESET_NAME_SIZE 16
/* from $OpenBSD: if_pflog.h,v 1.9 2003/07/15 20:27:27 dhartmei Exp $ */
#ifndef IFNAMSIZ
#define IFNAMSIZ 16
#endif
struct pfloghdr {
u_int8_t length;
sa_family_t af;
u_int8_t action;
u_int8_t reason;
char ifname[IFNAMSIZ];
char ruleset[PF_RULESET_NAME_SIZE];
u_int32_t rulenr;
u_int32_t subrulenr;
u_int8_t dir;
u_int8_t pad[3];
};
#define PFLOG_HDRLEN sizeof(struct pfloghdr)

105
contrib/libpcap/rawss7.h Normal file
View File

@ -0,0 +1,105 @@
/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */
/*
* Copyright (c) 2003 - The tcpdump group.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor of the Laboratory may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#) $Header: /tcpdump/master/libpcap/rawss7.h,v 1.1 2003/09/10 19:55:36 mcr Exp $ (LBL)
*/
/*
* This file is never used in libpcap or tcpdump. It is provided as
* documentation linktypes 139 through 142 only.
*/
/*
* Date: Tue, 09 Sep 2003 09:41:04 -0400
* From: Jeff Morriss <jeff.morriss[AT]ulticom.com>
* To: tcpdump-workers@tcpdump.org
* Subject: [tcpdump-workers] request for LINKTYPE_
*
* We've had some discussion over on ethereal-dev about a "fake link" or
* "raw SS7" dissector that allows dumping an arbitrary protocol into a
* file without any (otherwise necessary) lower level protocols. The
* common example has been dumping MTP3 into a file without, well, MTP2 or
* M2PA.
*
* We want to store these protocols directly in PCAP file format because
* it's well defined and there isn't another (popular) file format for
* capturing SS7 messages that we can reverse engineer (and we want to read
* these files into Ethereal). Rather than creating a new file format, it's
* a lot easier to just allocate a LINKTYPE_.
*
* Here is the original post thread:
*
* http://ethereal.com/lists/ethereal-dev/200306/threads.html#00200
*
* July's thread on the subject:
*
* http://ethereal.com/lists/ethereal-dev/200307/threads.html#00124
*
* August's thread:
*
* http://ethereal.com/lists/ethereal-dev/200308/threads.html#00193
*
*
* and one of the last messages--which is why I'm mailing you today:
*
* http://ethereal.com/lists/ethereal-dev/200308/msg00193.html
*
*
* Based on the message in the last URL, I'd like to request a new
* LINKTYPE_: LINKTYPE_RAWSS7.
*
* This packets in this file type will contain a header:
*/
typedef struct _rawss7_hdr {
/* NOTE: These are in network-byte order. */
guint32 type;
guint16 length;
guint16 spare;
} rawss7_hdr;
/*
*
* followed by protocol data for whatever protocol 'type' indicates.
*
* There was some discussion about these protocol 'type's being allocated by
* tcpdump-workers as well. In fact it would be handy to have one place to
* allocate such numbers, so what do you think about allocating 3 more (for
* now) LINKTYPE_'s:
*/
#define LINKTYPE_RAWSS7_MTP2 140
#define LINKTYPE_RAWSS7_MTP3 141
#define LINKTYPE_RAWSS7_SCCP 142
/*
*
* There is no reason this can't be used to store non-SS7 protocols, but
* it's what we need to use it for now...
*
*/

View File

@ -29,23 +29,19 @@
*/
#ifndef lint
static const char rcsid[] =
"@(#) $Header: /tcpdump/master/libpcap/savefile.c,v 1.55 2001/11/28 07:16:53 guy Exp $ (LBL)";
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/savefile.c,v 1.92.2.11 2004/03/11 23:46:14 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <sys/types.h>
#include <sys/time.h>
#include <errno.h>
#include <memory.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "pcap-int.h"
@ -61,7 +57,10 @@ static const char rcsid[] =
* because time is at a premium when we are writing the file.
* In other words, the pcap_file_header and pcap_pkthdr,
* records are written in host byte order.
* Note that the packets are always written in network byte order.
* Note that the bytes of packet data are written out in the order in
* which they were received, so multi-byte fields in packets are not
* written in host byte order, they're written in whatever order the
* sending machine put them in.
*
* ntoh[ls] aren't sufficient because we might need to swap on a big-endian
* machine (if the file was written in little-end order).
@ -119,6 +118,12 @@ static const char rcsid[] =
* to handle the new encapsulation type, so that they can also be checked
* into the tcpdump.org CVS repository and so that they will appear in
* future libpcap and tcpdump releases.
*
* Do *NOT* assume that any values after the largest value in this file
* are available; you might not have the most up-to-date version of this
* file, and new values after that one might have been assigned. Also,
* do *NOT* use any values below 100 - those might already have been
* taken by one (or more!) organizations.
*/
#define LINKTYPE_NULL DLT_NULL
#define LINKTYPE_ETHERNET DLT_EN10MB /* also for 100Mb and up */
@ -127,7 +132,7 @@ static const char rcsid[] =
#define LINKTYPE_PRONET DLT_PRONET
#define LINKTYPE_CHAOS DLT_CHAOS
#define LINKTYPE_TOKEN_RING DLT_IEEE802 /* DLT_IEEE802 is used for Token Ring */
#define LINKTYPE_ARCNET DLT_ARCNET
#define LINKTYPE_ARCNET DLT_ARCNET /* BSD-style headers */
#define LINKTYPE_SLIP DLT_SLIP
#define LINKTYPE_PPP DLT_PPP
#define LINKTYPE_FDDI DLT_FDDI
@ -151,6 +156,13 @@ static const char rcsid[] =
#define LINKTYPE_PPP_ETHER 51 /* NetBSD PPP-over-Ethernet */
/*
* This isn't supported in libpcap 0.8[.x], but is supported in the
* current CVS version; we include it here to note that it's not available
* for anybody else to use.
*/
#define LINKTYPE_SYMANTEC_FIREWALL 99 /* Symantec Enterprise Firewall */
#define LINKTYPE_ATM_RFC1483 100 /* LLC/SNAP-encapsulated ATM */
#define LINKTYPE_RAW 101 /* raw IP */
#define LINKTYPE_SLIP_BSDOS 102 /* BSD/OS SLIP BPF header */
@ -158,26 +170,160 @@ static const char rcsid[] =
#define LINKTYPE_C_HDLC 104 /* Cisco HDLC */
#define LINKTYPE_IEEE802_11 105 /* IEEE 802.11 (wireless) */
#define LINKTYPE_ATM_CLIP 106 /* Linux Classical IP over ATM */
#define LINKTYPE_FRELAY 107 /* Frame Relay */
#define LINKTYPE_LOOP 108 /* OpenBSD loopback */
#define LINKTYPE_ENC 109 /* OpenBSD IPSEC enc */
/*
* These three types are reserved for future use.
*/
#define LINKTYPE_LANE8023 110 /* ATM LANE + 802.3 */
#define LINKTYPE_HIPPI 111 /* NetBSD HIPPI */
#define LINKTYPE_HDLC 112 /* NetBSD HDLC framing */
#define LINKTYPE_LINUX_SLL 113 /* Linux cooked socket capture */
#define LINKTYPE_LTALK 114 /* Apple LocalTalk hardware */
#define LINKTYPE_ECONET 115 /* Acorn Econet */
/*
* Reserved for use with OpenBSD ipfilter.
*/
#define LINKTYPE_IPFILTER 116
#define LINKTYPE_PFLOG 117 /* OpenBSD DLT_PFLOG */
#define LINKTYPE_CISCO_IOS 118 /* For Cisco-internal use */
#define LINKTYPE_PRISM_HEADER 119 /* 802.11+Prism II monitor mode */
#define LINKTYPE_AIRONET_HEADER 120 /* FreeBSD Aironet driver stuff */
/*
* These types are reserved for future use.
* Reserved for Siemens HiPath HDLC.
*/
#define LINKTYPE_FR 107 /* BSD/OS Frame Relay */
#define LINKTYPE_ENC 109 /* OpenBSD IPSEC enc */
#define LINKTYPE_LANE8023 110 /* ATM LANE + 802.3 */
#define LINKTYPE_HIPPI 111 /* NetBSD HIPPI */
#define LINKTYPE_HDLC 112 /* NetBSD HDLC framing */
#define LINKTYPE_IPFILTER 116 /* IP Filter capture files */
#define LINKTYPE_PFLOG 117 /* OpenBSD DLT_PFLOG */
#define LINKTYPE_HHDLC 121
#define LINKTYPE_IP_OVER_FC 122 /* RFC 2625 IP-over-Fibre Channel */
#define LINKTYPE_SUNATM 123 /* Solaris+SunATM */
/*
* Reserved as per request from Kent Dahlgren <kent@praesum.com>
* for private use.
*/
#define LINKTYPE_RIO 124 /* RapidIO */
#define LINKTYPE_PCI_EXP 125 /* PCI Express */
#define LINKTYPE_AURORA 126 /* Xilinx Aurora link layer */
#define LINKTYPE_IEEE802_11_RADIO 127 /* 802.11 plus BSD radio header */
/*
* Reserved for the TZSP encapsulation, as per request from
* Chris Waters <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 LINKTYPE_TZSP 128 /* Tazmen Sniffer Protocol */
#define LINKTYPE_ARCNET_LINUX 129 /* Linux-style headers */
/*
* Juniper-private data link types, as per request from
* Hannes Gredler <hannes@juniper.net>. The corresponding
* DLT_s are used for passing on chassis-internal
* metainformation such as QOS profiles, etc..
*/
#define LINKTYPE_JUNIPER_MLPPP 130
#define LINKTYPE_JUNIPER_MLFR 131
#define LINKTYPE_JUNIPER_ES 132
#define LINKTYPE_JUNIPER_GGSN 133
#define LINKTYPE_JUNIPER_MFR 134
#define LINKTYPE_JUNIPER_ATM2 135
#define LINKTYPE_JUNIPER_SERVICES 136
#define LINKTYPE_JUNIPER_ATM1 137
#define LINKTYPE_APPLE_IP_OVER_IEEE1394 138 /* Apple IP-over-IEEE 1394 cooked header */
#define LINKTYPE_RAWSS7 139 /* see rawss7.h for */
#define LINKTYPE_RAWSS7_MTP2 140 /* information on these */
#define LINKTYPE_RAWSS7_MTP3 141 /* definitions */
#define LINKTYPE_RAWSS7_SCCP 142
/*
* This isn't supported in libpcap 0.8[.x], but is supported in the
* current CVS version; we include it here to note that it's not available
* for anybody else to use.
*/
#define LINKTYPE_DOCSIS 143 /* DOCSIS MAC frames */
#define LINKTYPE_LINUX_IRDA 144 /* Linux-IrDA */
/*
* Reserved for IBM SP switch and IBM Next Federation switch.
*/
#define LINKTYPE_IBM_SP 145
#define LINKTYPE_IBM_SN 146
/*
* Reserved for private use. If you have some link-layer header type
* that you want to use within your organization, with the capture files
* using that link-layer header type not ever be sent outside your
* organization, you can use these values.
*
* No libpcap release will use these for any purpose, nor will any
* tcpdump release use them, either.
*
* Do *NOT* use these in capture files that you expect anybody not using
* your private versions of capture-file-reading tools to read; in
* particular, do *NOT* use them in products, otherwise you may find that
* people won't be able to use tcpdump, or snort, or Ethereal, or... to
* read capture files from your firewall/intrusion detection/traffic
* monitoring/etc. appliance, or whatever product uses that LINKTYPE_ value,
* and you may also find that the developers of those applications will
* not accept patches to let them read those files.
*
* Also, do not use them if somebody might send you a capture using them
* for *their* private type and tools using them for *your* private type
* would have to read them.
*
* Instead, in those cases, ask "tcpdump-workers@tcpdump.org" for a new DLT_
* and LINKTYPE_ value, as per the comment in pcap-bpf.h, and use the type
* you're given.
*/
#define LINKTYPE_USER0 147
#define LINKTYPE_USER1 148
#define LINKTYPE_USER2 149
#define LINKTYPE_USER3 150
#define LINKTYPE_USER4 151
#define LINKTYPE_USER5 152
#define LINKTYPE_USER6 153
#define LINKTYPE_USER7 154
#define LINKTYPE_USER8 155
#define LINKTYPE_USER9 156
#define LINKTYPE_USER10 157
#define LINKTYPE_USER11 158
#define LINKTYPE_USER12 159
#define LINKTYPE_USER13 160
#define LINKTYPE_USER14 161
#define LINKTYPE_USER15 162
/*
* For future use with 802.11 captures - defined by AbsoluteValue
* Systems to store a number of bits of link-layer information
* including radio information:
*
* http://www.shaftnet.org/~pizza/software/capturefrm.txt
*
* but could and arguably should also be used by non-AVS Linux
* 802.11 drivers; that may happen in the future.
*/
#define LINKTYPE_IEEE802_11_RADIO_AVS 163 /* 802.11 plus AVS radio header */
/*
* Juniper-private data link type, as per request from
* Hannes Gredler <hannes@juniper.net>. The corresponding
* DLT_s are used for passing on chassis-internal
* metainformation such as QOS profiles, etc..
*/
#define LINKTYPE_JUNIPER_MONITOR 164
static struct linktype_map {
int dlt;
@ -205,6 +351,12 @@ static struct linktype_map {
* have values that should never be equal to any DLT_*
* code.
*/
#ifdef DLT_FR
/* BSD/OS Frame Relay */
{ DLT_FR, LINKTYPE_FRELAY },
#endif
{ DLT_SYMANTEC_FIREWALL, LINKTYPE_SYMANTEC_FIREWALL },
{ DLT_ATM_RFC1483, LINKTYPE_ATM_RFC1483 },
{ DLT_RAW, LINKTYPE_RAW },
{ DLT_SLIP_BSDOS, LINKTYPE_SLIP_BSDOS },
@ -232,6 +384,9 @@ static struct linktype_map {
/* IEEE 802.11 wireless */
{ DLT_IEEE802_11, LINKTYPE_IEEE802_11 },
/* Frame Relay */
{ DLT_FRELAY, LINKTYPE_FRELAY },
/* OpenBSD loopback */
{ DLT_LOOP, LINKTYPE_LOOP },
@ -244,6 +399,9 @@ static struct linktype_map {
/* Acorn Econet */
{ DLT_ECONET, LINKTYPE_ECONET },
/* OpenBSD DLT_PFLOG */
{ DLT_PFLOG, LINKTYPE_PFLOG },
/* For Cisco-internal use */
{ DLT_CISCO_IOS, LINKTYPE_CISCO_IOS },
@ -253,6 +411,59 @@ static struct linktype_map {
/* FreeBSD Aironet driver stuff */
{ DLT_AIRONET_HEADER, LINKTYPE_AIRONET_HEADER },
/* Siemens HiPath HDLC */
{ DLT_HHDLC, LINKTYPE_HHDLC },
/* RFC 2625 IP-over-Fibre Channel */
{ DLT_IP_OVER_FC, LINKTYPE_IP_OVER_FC },
/* Solaris+SunATM */
{ DLT_SUNATM, LINKTYPE_SUNATM },
/* RapidIO */
{ DLT_RIO, LINKTYPE_RIO },
/* PCI Express */
{ DLT_PCI_EXP, LINKTYPE_PCI_EXP },
/* Xilinx Aurora link layer */
{ DLT_AURORA, LINKTYPE_AURORA },
/* 802.11 plus BSD radio header */
{ DLT_IEEE802_11_RADIO, LINKTYPE_IEEE802_11_RADIO },
/* Tazmen Sniffer Protocol */
{ DLT_TZSP, LINKTYPE_TZSP },
/* Arcnet with Linux-style link-layer headers */
{ DLT_ARCNET_LINUX, LINKTYPE_ARCNET_LINUX },
/* Juniper-internal chassis encapsulation */
{ DLT_JUNIPER_MLPPP, LINKTYPE_JUNIPER_MLPPP },
{ DLT_JUNIPER_MLFR, LINKTYPE_JUNIPER_MLFR },
{ DLT_JUNIPER_ES, LINKTYPE_JUNIPER_ES },
{ DLT_JUNIPER_GGSN, LINKTYPE_JUNIPER_GGSN },
{ DLT_JUNIPER_MFR, LINKTYPE_JUNIPER_MFR },
{ DLT_JUNIPER_ATM2, LINKTYPE_JUNIPER_ATM2 },
{ DLT_JUNIPER_SERVICES, LINKTYPE_JUNIPER_SERVICES },
{ DLT_JUNIPER_ATM1, LINKTYPE_JUNIPER_ATM1 },
/* Apple IP-over-IEEE 1394 cooked header */
{ DLT_APPLE_IP_OVER_IEEE1394, LINKTYPE_APPLE_IP_OVER_IEEE1394 },
/* DOCSIS MAC frames */
{ DLT_DOCSIS, LINKTYPE_DOCSIS },
/* IrDA IrLAP packets + Linux-cooked header */
{ DLT_LINUX_IRDA, LINKTYPE_LINUX_IRDA },
/* IBM SP and Next Federation switches */
{ DLT_IBM_SP, LINKTYPE_IBM_SP },
{ DLT_IBM_SN, LINKTYPE_IBM_SN },
/* 802.11 plus AVS radio header */
{ DLT_IEEE802_11_RADIO_AVS, LINKTYPE_IEEE802_11_RADIO_AVS },
/*
* Any platform that defines additional DLT_* codes should:
*
@ -271,6 +482,10 @@ static struct linktype_map {
* defining DLT_* values that collide with those
* LINKTYPE_* values, either).
*/
/* Juniper-internal chassis encapsulation */
{ DLT_JUNIPER_MONITOR, LINKTYPE_JUNIPER_MONITOR },
{ -1, -1 }
};
@ -341,6 +556,43 @@ swap_hdr(struct pcap_file_header *hp)
hp->linktype = SWAPLONG(hp->linktype);
}
static int
sf_getnonblock(pcap_t *p, char *errbuf)
{
/*
* This is a savefile, not a live capture file, so never say
* it's in non-blocking mode.
*/
return (0);
}
static int
sf_setnonblock(pcap_t *p, int nonblock, char *errbuf)
{
/*
* This is a savefile, not a live capture file, so ignore
* requests to put it in non-blocking mode.
*/
return (0);
}
static int
sf_stats(pcap_t *p, struct pcap_stat *ps)
{
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"Statistics aren't available from savefiles");
return (-1);
}
static void
sf_close(pcap_t *p)
{
if (p->sf.rfile != stdin)
(void)fclose(p->sf.rfile);
if (p->sf.base != NULL)
free(p->sf.base);
}
pcap_t *
pcap_open_offline(const char *fname, char *errbuf)
{
@ -357,15 +609,15 @@ pcap_open_offline(const char *fname, char *errbuf)
}
memset((char *)p, 0, sizeof(*p));
/*
* Set this field so we don't close stdin in pcap_close!
*/
p->fd = -1;
if (fname[0] == '-' && fname[1] == '\0')
fp = stdin;
else {
#ifndef WIN32
fp = fopen(fname, "r");
#else
fp = fopen(fname, "rb");
#endif
if (fp == NULL) {
snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", fname,
pcap_strerror(errno));
@ -406,7 +658,12 @@ pcap_open_offline(const char *fname, char *errbuf)
p->snapshot = hdr.snaplen;
p->linktype = linktype_to_dlt(hdr.linktype);
p->sf.rfile = fp;
#ifndef WIN32
p->bufsize = hdr.snaplen;
#else
/* Allocate the space for pcap_pkthdr as well. It will be used by pcap_read_ex */
p->bufsize = hdr.snaplen+sizeof(struct pcap_pkthdr);
#endif
/* Align link header as required for proper data alignment */
/* XXX should handle all types */
@ -441,8 +698,59 @@ pcap_open_offline(const char *fname, char *errbuf)
pcap_fddipad = 0;
#endif
/*
* We interchanged the caplen and len fields at version 2.3,
* in order to match the bpf header layout. But unfortunately
* some files were written with version 2.3 in their headers
* but without the interchanged fields.
*
* In addition, DG/UX tcpdump writes out files with a version
* number of 543.0, and with the caplen and len fields in the
* pre-2.3 order.
*/
switch (hdr.version_major) {
case 2:
if (hdr.version_minor < 3)
p->sf.lengths_swapped = SWAPPED;
else if (hdr.version_minor == 3)
p->sf.lengths_swapped = MAYBE_SWAPPED;
else
p->sf.lengths_swapped = NOT_SWAPPED;
break;
case 543:
p->sf.lengths_swapped = SWAPPED;
break;
default:
p->sf.lengths_swapped = NOT_SWAPPED;
break;
}
#ifndef WIN32
/*
* You can do "select()" and "poll()" on plain files on most
* platforms, and should be able to do so on pipes.
*
* You can't do "select()" on anything other than sockets in
* Windows, so, on Win32 systems, we don't have "selectable_fd".
*/
p->selectable_fd = fileno(fp);
#endif
p->read_op = pcap_offline_read;
p->setfilter_op = install_bpf_program;
p->set_datalink_op = NULL; /* we don't support munging link-layer headers */
p->getnonblock_op = sf_getnonblock;
p->setnonblock_op = sf_setnonblock;
p->stats_op = sf_stats;
p->close_op = sf_close;
return (p);
bad:
if(fp)
fclose(fp);
free(p);
return (NULL);
}
@ -453,10 +761,12 @@ pcap_open_offline(const char *fname, char *errbuf)
* no more packets, and SFERR_TRUNC if a partial packet was encountered.
*/
static int
sf_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char *buf, int buflen)
sf_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char *buf, u_int buflen)
{
struct pcap_sf_patched_pkthdr sf_hdr;
FILE *fp = p->sf.rfile;
size_t amt_read;
bpf_u_int32 t;
/*
* Read the packet header; the structure we use as a buffer
@ -465,9 +775,23 @@ sf_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char *buf, int buflen)
* unpatched libpcap we only read as many bytes as the regular
* header has.
*/
if (fread(&sf_hdr, p->sf.hdrsize, 1, fp) != 1) {
/* probably an EOF, though could be a truncated packet */
return (1);
amt_read = fread(&sf_hdr, 1, p->sf.hdrsize, fp);
if (amt_read != p->sf.hdrsize) {
if (ferror(fp)) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"error reading dump file: %s",
pcap_strerror(errno));
return (-1);
} else {
if (amt_read != 0) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"truncated dump file; tried to read %d header bytes, only got %lu",
p->sf.hdrsize, (unsigned long)amt_read);
return (-1);
}
/* EOF */
return (1);
}
}
if (p->sf.swapped) {
@ -482,17 +806,27 @@ sf_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char *buf, int buflen)
hdr->ts.tv_sec = sf_hdr.ts.tv_sec;
hdr->ts.tv_usec = sf_hdr.ts.tv_usec;
}
/*
* We interchanged the caplen and len fields at version 2.3,
* in order to match the bpf header layout. But unfortunately
* some files were written with version 2.3 in their headers
* but without the interchanged fields.
*/
if (p->sf.version_minor < 3 ||
(p->sf.version_minor == 3 && hdr->caplen > hdr->len)) {
int t = hdr->caplen;
/* Swap the caplen and len fields, if necessary. */
switch (p->sf.lengths_swapped) {
case NOT_SWAPPED:
break;
case MAYBE_SWAPPED:
if (hdr->caplen <= hdr->len) {
/*
* The captured length is <= the actual length,
* so presumably they weren't swapped.
*/
break;
}
/* FALLTHROUGH */
case SWAPPED:
t = hdr->caplen;
hdr->caplen = hdr->len;
hdr->len = t;
break;
}
if (hdr->caplen > buflen) {
@ -503,7 +837,7 @@ sf_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char *buf, int buflen)
* grossly wrong, try to salvage.
*/
static u_char *tp = NULL;
static int tsize = 0;
static size_t tsize = 0;
if (hdr->caplen > 65535) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
@ -523,9 +857,17 @@ sf_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char *buf, int buflen)
return (-1);
}
}
if (fread((char *)tp, hdr->caplen, 1, fp) != 1) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"truncated dump file");
amt_read = fread((char *)tp, 1, hdr->caplen, fp);
if (amt_read != hdr->caplen) {
if (ferror(fp)) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"error reading dump file: %s",
pcap_strerror(errno));
} else {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"truncated dump file; tried to read %u captured bytes, only got %lu",
hdr->caplen, (unsigned long)amt_read);
}
return (-1);
}
/*
@ -540,10 +882,17 @@ sf_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char *buf, int buflen)
} else {
/* read the packet itself */
if (fread((char *)buf, hdr->caplen, 1, fp) != 1) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"truncated dump file");
amt_read = fread((char *)buf, 1, hdr->caplen, fp);
if (amt_read != hdr->caplen) {
if (ferror(fp)) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"error reading dump file: %s",
pcap_strerror(errno));
} else {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"truncated dump file; tried to read %u captured bytes, only got %lu",
hdr->caplen, (unsigned long)amt_read);
}
return (-1);
}
}
@ -564,6 +913,23 @@ pcap_offline_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
while (status == 0) {
struct pcap_pkthdr h;
/*
* Has "pcap_breakloop()" been called?
* If so, return immediately - if we haven't read any
* packets, clear the flag and return -2 to indicate
* that we were told to break out of the loop, otherwise
* leave the flag set, so that the *next* call will break
* out of the loop without having read any packets, and
* return the number of packets we've processed so far.
*/
if (p->break_loop) {
if (n == 0) {
p->break_loop = 0;
return (-2);
} else
return (n);
}
status = sf_next_packet(p, &h, p->buffer, p->bufsize);
if (status) {
if (status == 1)
@ -618,10 +984,18 @@ pcap_dump_open(pcap_t *p, const char *fname)
return (NULL);
}
if (fname[0] == '-' && fname[1] == '\0')
if (fname[0] == '-' && fname[1] == '\0') {
f = stdout;
else {
#ifdef WIN32
_setmode(_fileno(f), _O_BINARY);
#endif
} else {
#ifndef WIN32
f = fopen(fname, "w");
#else
f = fopen(fname, "wb");
setbuf(f, NULL); /* XXX - why? */
#endif
if (f == NULL) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s",
fname, pcap_strerror(errno));
@ -632,6 +1006,22 @@ pcap_dump_open(pcap_t *p, const char *fname)
return ((pcap_dumper_t *)f);
}
FILE *
pcap_dump_file(pcap_dumper_t *p)
{
return ((FILE *)p);
}
int
pcap_dump_flush(pcap_dumper_t *p)
{
if (fflush((FILE *)p) == EOF)
return (-1);
else
return (0);
}
void
pcap_dump_close(pcap_dumper_t *p)
{

View File

@ -21,33 +21,38 @@
*/
#ifndef lint
static const char rcsid[] =
"@(#) $Header: /tcpdump/master/libpcap/scanner.l,v 1.81 2001/09/14 01:40:57 fenner Exp $ (LBL)";
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/scanner.l,v 1.95.2.3 2004/03/28 21:45:33 fenner Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <sys/types.h>
#include <sys/time.h>
#include <ctype.h>
#include <unistd.h>
#include <string.h>
#include "pcap-int.h"
#include "gencode.h"
#include <pcap-namedb.h>
#ifdef INET6
#include <netdb.h>
#include <sys/socket.h>
#ifdef WIN32
#include <pcap-stdinc.h>
#ifdef __MINGW32__
#include "IP6_misc.h"
#endif
#else /* WIN32 */
#include <sys/socket.h> /* for "struct sockaddr" in "struct addrinfo" */
#include <netdb.h> /* for "struct addrinfo" */
#endif /* WIN32 */
/* Workaround for AIX 4.3 */
#if !defined(AI_NUMERICHOST)
#define AI_NUMERICHOST 0x04
#endif
#endif /*INET6*/
#include <pcap-namedb.h>
#include "tokdefs.h"
#ifdef HAVE_OS_PROTO_H
@ -76,11 +81,11 @@ N ([0-9]+|(0X|0x)[0-9A-Fa-f]+)
B ([0-9A-Fa-f][0-9A-Fa-f]?)
W ([0-9A-Fa-f][0-9A-Fa-f]?[0-9A-Fa-f]?[0-9A-Fa-f]?)
%a 15000
%o 17000
%a 16000
%o 19000
%e 6000
%k 4000
%p 19000
%p 25000
%n 2000
V680 {W}:{W}:{W}:{W}:{W}:{W}:{W}:{W}
@ -166,7 +171,7 @@ dst return DST;
src return SRC;
link|ether|ppp|slip return LINK;
fddi|tr return LINK;
fddi|tr|wlan return LINK;
arp return ARP;
rarp return RARP;
ip return IP;
@ -209,6 +214,14 @@ esis return ESIS;
es-is return ESIS;
isis return ISIS;
is-is return ISIS;
l1 return L1;
l2 return L2;
iih return IIH;
lsp return LSP;
snp return SNP;
csnp return CSNP;
psnp return PSNP;
clnp return CLNP;
stp return STP;
@ -219,7 +232,7 @@ netbeui return NETBEUI;
host return HOST;
net return NET;
mask return MASK;
mask return NETMASK;
port return PORT;
proto return PROTO;
protochain {
@ -234,7 +247,7 @@ gateway return GATEWAY;
less return LESS;
greater return GREATER;
byte return BYTE;
byte return CBYTE;
broadcast return TK_BROADCAST;
multicast return TK_MULTICAST;
@ -248,7 +261,29 @@ outbound return OUTBOUND;
vlan return VLAN;
[ \n\t] ;
lane return LANE;
llc return LLC;
metac return METAC;
bcc return BCC;
oam return OAM;
oamf4 return OAMF4;
oamf4ec return OAMF4EC;
oamf4sc return OAMF4SC;
sc return SC;
ilmic return ILMIC;
vpi return VPI;
vci return VCI;
connectmsg return CONNECTMSG;
metaconnect return METACONNECT;
on|ifname return PF_IFNAME;
rset|ruleset return PF_RSET;
rnr|rulenum return PF_RNR;
srnr|subrulenum return PF_SRNR;
reason return PF_REASON;
action return PF_ACTION;
[ \r\n\t] ;
[+\-*/:\[\]!<>()&|=] return yytext[0];
">=" return GEQ;
"<=" return LEQ;
@ -272,7 +307,7 @@ ${B} { yylval.e = pcap_ether_aton(((char *)yytext)+1);
if (getaddrinfo(yytext, NULL, &hints, &res))
bpf_error("bogus IPv6 address %s", yytext);
else {
yylval.e = sdup((char *)yytext); return HID6;
yylval.s = sdup((char *)yytext); return HID6;
}
#else
bpf_error("IPv6 address %s not supported", yytext);

View File

@ -4,7 +4,7 @@
*
* 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
* to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
* Berkeley Laboratory.
*
* Redistribution and use in source and binary forms, with or without
@ -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.6 2000/12/23 07:50:19 guy Exp $ (LBL)
* @(#) $Header: /tcpdump/master/libpcap/sll.h,v 1.7 2002/06/11 17:04:48 itojun Exp $ (LBL)
*/
/*

632
contrib/libpcap/snprintf.c Normal file
View File

@ -0,0 +1,632 @@
/*
* Copyright (c) 1995-1999 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/* $Id: snprintf.c,v 1.1 2003/12/15 01:35:05 guy Exp $ */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifndef lint
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/snprintf.c,v 1.1 2003/12/15 01:35:05 guy Exp $";
#endif
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <sys/types.h>
#include <pcap-int.h>
enum format_flags {
minus_flag = 1,
plus_flag = 2,
space_flag = 4,
alternate_flag = 8,
zero_flag = 16
};
/*
* Common state
*/
struct state {
unsigned char *str;
unsigned char *s;
unsigned char *theend;
size_t sz;
size_t max_sz;
int (*append_char)(struct state *, unsigned char);
int (*reserve)(struct state *, size_t);
/* XXX - methods */
};
#ifndef HAVE_VSNPRINTF
static int
sn_reserve (struct state *state, size_t n)
{
return state->s + n > state->theend;
}
static int
sn_append_char (struct state *state, unsigned char c)
{
if (sn_reserve (state, 1)) {
return 1;
} else {
*state->s++ = c;
return 0;
}
}
#endif
#if 0
static int
as_reserve (struct state *state, size_t n)
{
if (state->s + n > state->theend) {
int off = state->s - state->str;
unsigned char *tmp;
if (state->max_sz && state->sz >= state->max_sz)
return 1;
state->sz = max(state->sz * 2, state->sz + n);
if (state->max_sz)
state->sz = min(state->sz, state->max_sz);
tmp = realloc (state->str, state->sz);
if (tmp == NULL)
return 1;
state->str = tmp;
state->s = state->str + off;
state->theend = state->str + state->sz - 1;
}
return 0;
}
static int
as_append_char (struct state *state, unsigned char c)
{
if(as_reserve (state, 1))
return 1;
else {
*state->s++ = c;
return 0;
}
}
#endif
static int
append_number(struct state *state,
unsigned long num, unsigned base, char *rep,
int width, int prec, int flags, int minusp)
{
int len = 0;
int i;
/* given precision, ignore zero flag */
if(prec != -1)
flags &= ~zero_flag;
else
prec = 1;
/* zero value with zero precision -> "" */
if(prec == 0 && num == 0)
return 0;
do{
if((*state->append_char)(state, rep[num % base]))
return 1;
len++;
num /= base;
}while(num);
prec -= len;
/* pad with prec zeros */
while(prec-- > 0){
if((*state->append_char)(state, '0'))
return 1;
len++;
}
/* add length of alternate prefix (added later) to len */
if(flags & alternate_flag && (base == 16 || base == 8))
len += base / 8;
/* pad with zeros */
if(flags & zero_flag){
width -= len;
if(minusp || (flags & space_flag) || (flags & plus_flag))
width--;
while(width-- > 0){
if((*state->append_char)(state, '0'))
return 1;
len++;
}
}
/* add alternate prefix */
if(flags & alternate_flag && (base == 16 || base == 8)){
if(base == 16)
if((*state->append_char)(state, rep[10] + 23)) /* XXX */
return 1;
if((*state->append_char)(state, '0'))
return 1;
}
/* add sign */
if(minusp){
if((*state->append_char)(state, '-'))
return 1;
len++;
} else if(flags & plus_flag) {
if((*state->append_char)(state, '+'))
return 1;
len++;
} else if(flags & space_flag) {
if((*state->append_char)(state, ' '))
return 1;
len++;
}
if(flags & minus_flag)
/* swap before padding with spaces */
for(i = 0; i < len / 2; i++){
char c = state->s[-i-1];
state->s[-i-1] = state->s[-len+i];
state->s[-len+i] = c;
}
width -= len;
while(width-- > 0){
if((*state->append_char)(state, ' '))
return 1;
len++;
}
if(!(flags & minus_flag))
/* swap after padding with spaces */
for(i = 0; i < len / 2; i++){
char c = state->s[-i-1];
state->s[-i-1] = state->s[-len+i];
state->s[-len+i] = c;
}
return 0;
}
static int
append_string (struct state *state,
unsigned char *arg,
int width,
int prec,
int flags)
{
if(prec != -1)
width -= prec;
else
width -= strlen((char *)arg);
if(!(flags & minus_flag))
while(width-- > 0)
if((*state->append_char) (state, ' '))
return 1;
if (prec != -1) {
while (*arg && prec--)
if ((*state->append_char) (state, *arg++))
return 1;
} else {
while (*arg)
if ((*state->append_char) (state, *arg++))
return 1;
}
if(flags & minus_flag)
while(width-- > 0)
if((*state->append_char) (state, ' '))
return 1;
return 0;
}
static int
append_char(struct state *state,
unsigned char arg,
int width,
int flags)
{
while(!(flags & minus_flag) && --width > 0)
if((*state->append_char) (state, ' '))
return 1;
if((*state->append_char) (state, arg))
return 1;
while((flags & minus_flag) && --width > 0)
if((*state->append_char) (state, ' '))
return 1;
return 0;
}
/*
* This can't be made into a function...
*/
#define PARSE_INT_FORMAT(res, arg, unsig) \
if (long_flag) \
res = (unsig long)va_arg(arg, unsig long); \
else if (short_flag) \
res = (unsig short)va_arg(arg, unsig int); \
else \
res = (unsig int)va_arg(arg, unsig int)
/*
* zyxprintf - return 0 or -1
*/
static int
xyzprintf (struct state *state, const char *char_format, va_list ap)
{
const unsigned char *format = (const unsigned char *)char_format;
unsigned char c;
while((c = *format++)) {
if (c == '%') {
int flags = 0;
int width = 0;
int prec = -1;
int long_flag = 0;
int short_flag = 0;
/* flags */
while((c = *format++)){
if(c == '-')
flags |= minus_flag;
else if(c == '+')
flags |= plus_flag;
else if(c == ' ')
flags |= space_flag;
else if(c == '#')
flags |= alternate_flag;
else if(c == '0')
flags |= zero_flag;
else
break;
}
if((flags & space_flag) && (flags & plus_flag))
flags ^= space_flag;
if((flags & minus_flag) && (flags & zero_flag))
flags ^= zero_flag;
/* width */
if (isdigit(c))
do {
width = width * 10 + c - '0';
c = *format++;
} while(isdigit(c));
else if(c == '*') {
width = va_arg(ap, int);
c = *format++;
}
/* precision */
if (c == '.') {
prec = 0;
c = *format++;
if (isdigit(c))
do {
prec = prec * 10 + c - '0';
c = *format++;
} while(isdigit(c));
else if (c == '*') {
prec = va_arg(ap, int);
c = *format++;
}
}
/* size */
if (c == 'h') {
short_flag = 1;
c = *format++;
} else if (c == 'l') {
long_flag = 1;
c = *format++;
}
switch (c) {
case 'c' :
if(append_char(state, va_arg(ap, int), width, flags))
return -1;
break;
case 's' :
if (append_string(state,
va_arg(ap, unsigned char*),
width,
prec,
flags))
return -1;
break;
case 'd' :
case 'i' : {
long arg;
unsigned long num;
int minusp = 0;
PARSE_INT_FORMAT(arg, ap, signed);
if (arg < 0) {
minusp = 1;
num = -arg;
} else
num = arg;
if (append_number (state, num, 10, "0123456789",
width, prec, flags, minusp))
return -1;
break;
}
case 'u' : {
unsigned long arg;
PARSE_INT_FORMAT(arg, ap, unsigned);
if (append_number (state, arg, 10, "0123456789",
width, prec, flags, 0))
return -1;
break;
}
case 'o' : {
unsigned long arg;
PARSE_INT_FORMAT(arg, ap, unsigned);
if (append_number (state, arg, 010, "01234567",
width, prec, flags, 0))
return -1;
break;
}
case 'x' : {
unsigned long arg;
PARSE_INT_FORMAT(arg, ap, unsigned);
if (append_number (state, arg, 0x10, "0123456789abcdef",
width, prec, flags, 0))
return -1;
break;
}
case 'X' :{
unsigned long arg;
PARSE_INT_FORMAT(arg, ap, unsigned);
if (append_number (state, arg, 0x10, "0123456789ABCDEF",
width, prec, flags, 0))
return -1;
break;
}
case 'p' : {
unsigned long arg = (unsigned long)va_arg(ap, void*);
if (append_number (state, arg, 0x10, "0123456789ABCDEF",
width, prec, flags, 0))
return -1;
break;
}
case 'n' : {
int *arg = va_arg(ap, int*);
*arg = state->s - state->str;
break;
}
case '\0' :
--format;
/* FALLTHROUGH */
case '%' :
if ((*state->append_char)(state, c))
return -1;
break;
default :
if ( (*state->append_char)(state, '%')
|| (*state->append_char)(state, c))
return -1;
break;
}
} else
if ((*state->append_char) (state, c))
return -1;
}
return 0;
}
#ifndef HAVE_SNPRINTF
int
snprintf (char *str, size_t sz, const char *format, ...)
{
va_list args;
int ret;
va_start(args, format);
ret = vsnprintf (str, sz, format, args);
#ifdef PARANOIA
{
int ret2;
char *tmp;
tmp = malloc (sz);
if (tmp == NULL)
abort ();
ret2 = vsprintf (tmp, format, args);
if (ret != ret2 || strcmp(str, tmp))
abort ();
free (tmp);
}
#endif
va_end(args);
return ret;
}
#endif
#if 0
#ifndef HAVE_ASPRINTF
int
asprintf (char **ret, const char *format, ...)
{
va_list args;
int val;
va_start(args, format);
val = vasprintf (ret, format, args);
#ifdef PARANOIA
{
int ret2;
char *tmp;
tmp = malloc (val + 1);
if (tmp == NULL)
abort ();
ret2 = vsprintf (tmp, format, args);
if (val != ret2 || strcmp(*ret, tmp))
abort ();
free (tmp);
}
#endif
va_end(args);
return val;
}
#endif
#ifndef HAVE_ASNPRINTF
int
asnprintf (char **ret, size_t max_sz, const char *format, ...)
{
va_list args;
int val;
va_start(args, format);
val = vasnprintf (ret, max_sz, format, args);
#ifdef PARANOIA
{
int ret2;
char *tmp;
tmp = malloc (val + 1);
if (tmp == NULL)
abort ();
ret2 = vsprintf (tmp, format, args);
if (val != ret2 || strcmp(*ret, tmp))
abort ();
free (tmp);
}
#endif
va_end(args);
return val;
}
#endif
#ifndef HAVE_VASPRINTF
int
vasprintf (char **ret, const char *format, va_list args)
{
return vasnprintf (ret, 0, format, args);
}
#endif
#ifndef HAVE_VASNPRINTF
int
vasnprintf (char **ret, size_t max_sz, const char *format, va_list args)
{
int st;
size_t len;
struct state state;
state.max_sz = max_sz;
state.sz = 1;
state.str = malloc(state.sz);
if (state.str == NULL) {
*ret = NULL;
return -1;
}
state.s = state.str;
state.theend = state.s + state.sz - 1;
state.append_char = as_append_char;
state.reserve = as_reserve;
st = xyzprintf (&state, format, args);
if (st) {
free (state.str);
*ret = NULL;
return -1;
} else {
char *tmp;
*state.s = '\0';
len = state.s - state.str;
tmp = realloc (state.str, len+1);
if (tmp == NULL) {
free (state.str);
*ret = NULL;
return -1;
}
*ret = tmp;
return len;
}
}
#endif
#endif
#ifndef HAVE_VSNPRINTF
int
vsnprintf (char *str, size_t sz, const char *format, va_list args)
{
struct state state;
int ret;
unsigned char *ustr = (unsigned char *)str;
state.max_sz = 0;
state.sz = sz;
state.str = ustr;
state.s = ustr;
state.theend = ustr + sz - 1;
state.append_char = sn_append_char;
state.reserve = sn_reserve;
ret = xyzprintf (&state, format, args);
*state.s = '\0';
if (ret)
return sz;
else
return state.s - state.str;
}
#endif

View File

@ -0,0 +1,45 @@
/*
* Copyright (c) 1997 Yen Yen Lim and North Dakota State University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Yen Yen Lim and
North Dakota State University
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @(#) $Header: /tcpdump/master/libpcap/sunatmpos.h,v 1.1 2002/07/11 09:06:47 guy Exp $ (LBL)
*/
/* SunATM header for ATM packet */
#define SUNATM_DIR_POS 0
#define SUNATM_VPI_POS 1
#define SUNATM_VCI_POS 2
#define SUNATM_PKT_BEGIN_POS 4 /* Start of ATM packet */
/* Protocol type values in the bottom for bits of the byte at SUNATM_DIR_POS. */
#define PT_LANE 0x01 /* LANE */
#define PT_LLC 0x02 /* LLC encapsulation */
#define PT_ILMI 0x05 /* ILMI */
#define PT_QSAAL 0x06 /* Q.SAAL */