Virgin import of libpcap v0.9.1 (alpha 096) from tcpdump.org
This commit is contained in:
parent
feb4ecdbac
commit
04fb274578
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/vendor/libpcap/dist/; revision=146768
@ -1,4 +1,4 @@
|
||||
@(#) $Header: /tcpdump/master/libpcap/CHANGES,v 1.56.4.3 2004/03/30 14:29:16 mcr Exp $ (LBL)
|
||||
@(#) $Header: /tcpdump/master/libpcap/CHANGES,v 1.59 2004/03/30 14:42:50 mcr Exp $ (LBL)
|
||||
|
||||
Tue. March 30, 2004. mcr@sandelman.ottawa.on.ca. Summary for 3.8.3 release
|
||||
|
||||
|
@ -21,12 +21,16 @@ Additional people who have contributed patches:
|
||||
Brian Ginsbach <ginsbach@cray.com>
|
||||
Charles M. Hannum <mycroft@netbsd.org>
|
||||
Chris G. Demetriou <cgd@netbsd.org>
|
||||
Chris Lightfoot <cwrl@users.sourceforge.net>
|
||||
Chris Pepper <pepper@mail.reppep.com>
|
||||
Darren Reed <darrenr@reed.wattle.id.au>
|
||||
David Kaelbling <drk@sgi.com>
|
||||
David Young <dyoung@ojctech.com>
|
||||
Dean Gaudet <dean@arctic.org>
|
||||
Don Ebright <Don.Ebright@compuware.com>
|
||||
Dug Song <dugsong@monkey.org>
|
||||
Eric Anderson <anderse@hpl.hp.com>
|
||||
Erik de Castro Lopo <erik.de.castro.lopo@sensorynetworks.com>
|
||||
Franz Schaefer <schaefer@mond.at>
|
||||
Gianluca Varenni <varenni@netgroup-serv.polito.it>
|
||||
Gisle Vanem <giva@bgnett.no>
|
||||
@ -54,9 +58,12 @@ Additional people who have contributed patches:
|
||||
Love Hörnquist-Åstrand <lha@stacken.kth.se>
|
||||
Maciej W. Rozycki <macro@ds2.pg.gda.pl>
|
||||
Marcus Felipe Pereira <marcus@task.com.br>
|
||||
Mark Pizzolato <List-tcpdump-workers@subscriptions.pizzolato.net>
|
||||
Martin Husemann <martin@netbsd.org>
|
||||
Matthew Luckie <mjl@luckie.org.nz>
|
||||
Mike Wiacek <mike@iroot.net>
|
||||
Monroe Williams <monroe@pobox.com>
|
||||
Nicolas Dade <ndade@nsd.dyndns.org>
|
||||
Octavian Cerna <tavy@ylabs.com>
|
||||
Olaf Kirch <okir@caldera.de>
|
||||
Onno van der Linden <onno@simplex.nl>
|
||||
|
@ -1,4 +1,6 @@
|
||||
CHANGES
|
||||
ChmodBPF/ChmodBPF
|
||||
ChmodBPF/StartupParameters.plist
|
||||
CREDITS
|
||||
FILES
|
||||
INSTALL.txt
|
||||
@ -9,6 +11,7 @@ README.aix
|
||||
README.dag
|
||||
README.hpux
|
||||
README.linux
|
||||
README.macosx
|
||||
README.tru64
|
||||
README.Win32
|
||||
SUNOS4/nit_if.o.sparc
|
||||
@ -48,16 +51,33 @@ lbl/os-solaris2.h
|
||||
lbl/os-sunos4.h
|
||||
lbl/os-ultrix4.h
|
||||
llc.h
|
||||
missing/snprintf.c
|
||||
mkdep
|
||||
msdos/bin2c.c
|
||||
msdos/common.dj
|
||||
msdos/makefile
|
||||
msdos/makefile.dj
|
||||
msdos/makefile.wc
|
||||
msdos/ndis2.c
|
||||
msdos/ndis2.h
|
||||
msdos/ndis_0.asm
|
||||
msdos/pkt_rx0.asm
|
||||
msdos/pkt_rx1.s
|
||||
msdos/pktdrvr.c
|
||||
msdos/pktdrvr.h
|
||||
msdos/readme.dos
|
||||
nametoaddr.c
|
||||
nlpid.h
|
||||
optimize.c
|
||||
packaging/pcap.spec
|
||||
packaging/pcap.spec.in
|
||||
pcap-bpf.c
|
||||
pcap-bpf.h
|
||||
pcap-dag.c
|
||||
pcap-dag.h
|
||||
pcap-dlpi.c
|
||||
pcap-dos.c
|
||||
pcap-dos.h
|
||||
pcap-enet.c
|
||||
pcap-int.h
|
||||
pcap-linux.c
|
||||
@ -80,7 +100,6 @@ rawss7.h
|
||||
savefile.c
|
||||
scanner.l
|
||||
sll.h
|
||||
snprintf.c
|
||||
sunatmpos.h
|
||||
Win32/Include/Gnuc.h
|
||||
Win32/Include/addrinfo.h
|
||||
|
@ -1,4 +1,4 @@
|
||||
@(#) $Header: /tcpdump/master/libpcap/INSTALL.txt,v 1.7.2.2 2003/12/15 02:05:00 guy Exp $ (LBL)
|
||||
@(#) $Header: /tcpdump/master/libpcap/INSTALL.txt,v 1.12 2004/12/18 08:52:08 guy Exp $ (LBL)
|
||||
|
||||
To build libpcap, run "./configure" (a shell script). The configure
|
||||
script will determine your system attributes and generate an
|
||||
@ -295,6 +295,8 @@ timestamp resolution if it finds it's running on a SS-1).
|
||||
FILES
|
||||
-----
|
||||
CHANGES - description of differences between releases
|
||||
ChmodBPF/* - Mac OS X startup item to set ownership and permissions
|
||||
on /dev/bpf*
|
||||
CREDITS - people that have helped libpcap along
|
||||
FILES - list of files exported as part of the distribution
|
||||
INSTALL.txt - this file
|
||||
@ -305,6 +307,7 @@ 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.macosx - notes on using libpcap on Mac OS X
|
||||
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
|
||||
@ -336,7 +339,9 @@ inet.c - network routines
|
||||
install-sh - BSD style install script
|
||||
lbl/os-*.h - OS-dependent defines and prototypes
|
||||
llc.h - 802.2 LLC SAP definitions
|
||||
missing/* - replacements for missing library functions
|
||||
mkdep - construct Makefile dependency list
|
||||
msdos/* - drivers for MS-DOS capture support
|
||||
nametoaddr.c - hostname to address routines
|
||||
nlpid.h - OSI network layer protocol identifier definitions
|
||||
net - symlink to bpf/net
|
||||
@ -347,6 +352,8 @@ 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-dos.c - MS-DOS capture support
|
||||
pcap-dos.h - headers for MS-DOS capture support
|
||||
pcap-enet.c - enet support
|
||||
pcap-int.h - internal libpcap definitions
|
||||
pcap-linux.c - Linux packet socket support
|
||||
@ -369,6 +376,5 @@ 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
|
||||
|
@ -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.96.2.1 2003/12/15 01:42:23 guy Exp $ (LBL)
|
||||
# @(#) $Header: /tcpdump/master/libpcap/Makefile.in,v 1.99 2003/12/15 01:35:03 guy Exp $ (LBL)
|
||||
|
||||
#
|
||||
# Various configurable paths (remember to edit Makefile.in, not Makefile)
|
||||
@ -46,6 +46,7 @@ CCOPT = @V_CCOPT@
|
||||
INCLS = -I. @V_INCLS@
|
||||
DEFS = @DEFS@ @V_DEFS@
|
||||
LIBS = @V_LIBS@
|
||||
DYEXT = @DYEXT@
|
||||
|
||||
# Standard CFLAGS
|
||||
CFLAGS = $(CCOPT) $(INCLS) $(DEFS)
|
||||
@ -103,6 +104,24 @@ libpcap.a: $(OBJ)
|
||||
ar rc $@ $(OBJ) $(LIBS)
|
||||
$(RANLIB) $@
|
||||
|
||||
shared: libpcap.$(DYEXT)
|
||||
|
||||
#
|
||||
# XXX - this works with GNU ld, but won't necessarily work with native
|
||||
# ld on, for example, various SVR4-flavored platforms, or Digital UNIX.
|
||||
#
|
||||
libpcap.so: $(OBJ)
|
||||
@rm -f $@
|
||||
ld -shared -o $@.`cat VERSION` $(OBJ)
|
||||
|
||||
# the following rule succeeds, but the result is untested.
|
||||
libpcap.dylib: $(OBJ)
|
||||
rm -f libpcap*.dylib
|
||||
$(CC) -dynamiclib -undefined error -o libpcap.`cat VERSION`.dylib $(OBJ) \
|
||||
-install_name $(libdir)/libpcap.0.dylib -compatibility_version `cat VERSION` \
|
||||
-current_version `cat VERSION`
|
||||
|
||||
|
||||
scanner.c: $(srcdir)/scanner.l
|
||||
@rm -f $@
|
||||
$(LEX) -t $< > $$$$.$@; mv $$$$.$@ $@
|
||||
@ -151,7 +170,7 @@ bpf_filter.c: $(srcdir)/bpf/net/bpf_filter.c
|
||||
bpf_filter.o: bpf_filter.c
|
||||
$(CC) $(CFLAGS) -c bpf_filter.c
|
||||
|
||||
install:
|
||||
install: libpcap.a
|
||||
[ -d $(DESTDIR)$(libdir) ] || \
|
||||
(mkdir -p $(DESTDIR)$(libdir); chmod 755 $(DESTDIR)$(libdir))
|
||||
$(INSTALL_DATA) libpcap.a $(DESTDIR)$(libdir)/libpcap.a
|
||||
@ -168,6 +187,13 @@ install:
|
||||
$(INSTALL_DATA) $(srcdir)/pcap.3 \
|
||||
$(DESTDIR)$(mandir)/man3/pcap.3
|
||||
|
||||
install-shared: install-shared-$(DYEXT)
|
||||
install-shared-so: libpcap.so
|
||||
$(INSTALL_PROGRAM) libpcap.so.`cat VERSION` $(DESTDIR)$(libdir)/libpcap.so.`cat VERSION`
|
||||
install-shared-dylib: libpcap.dylib
|
||||
$(INSTALL_PROGRAM) libpcap.`cat VERSION`.dylib $(DESTDIR)$(libdir)/libpcap.`cat VERSION`.dylib
|
||||
VER=`cat VERSION`; cd $(DESTDIR)$(libdir) && ln -sf libpcap.$$VER.dylib libpcap.0.dylib; ln -sf libpcap.0.dylib libpcap.dylib
|
||||
|
||||
uninstall:
|
||||
rm -f $(DESTDIR)$(libdir)/libpcap.a
|
||||
rm -f $(DESTDIR)$(includedir)/pcap.h
|
||||
@ -176,16 +202,21 @@ uninstall:
|
||||
rm -f $(DESTDIR)$(mandir)/man3/pcap.3
|
||||
|
||||
clean:
|
||||
rm -f $(CLEANFILES)
|
||||
rm -f $(CLEANFILES) libpcap*.dylib libpcap.so*
|
||||
|
||||
distclean:
|
||||
rm -f $(CLEANFILES) Makefile config.cache config.log config.status \
|
||||
distclean: clean
|
||||
rm -f Makefile config.cache config.log config.status \
|
||||
config.h gnuc.h os-proto.h bpf_filter.c stamp-h stamp-h.in
|
||||
rm -rf autom4te.cache
|
||||
|
||||
tags: $(TAGFILES)
|
||||
ctags -wtd $(TAGFILES)
|
||||
|
||||
tar:
|
||||
packaging/pcap.spec: packaging/pcap.spec.in VERSION
|
||||
RPMVERSION=`cat VERSION | sed s/-.*//g`; \
|
||||
sed -e s/@VERSION@/$$RPMVERSION/ -e s/@NAME@/libpcap-`cat VERSION`/ $< > $@
|
||||
|
||||
tar: Makefile packaging/pcap.spec
|
||||
@cwd=`pwd` ; dir=`basename $$cwd` ; name=libpcap-`cat VERSION` ; \
|
||||
list="" ; tar="tar chf" ; \
|
||||
for i in `cat FILES` ; do list="$$list $$name/$$i" ; done; \
|
||||
@ -193,11 +224,16 @@ tar:
|
||||
"rm -f ../$$name; ln -s $$dir ../$$name" ; \
|
||||
rm -f ../$$name; ln -s $$dir ../$$name ; \
|
||||
echo \
|
||||
"(cd .. ; $$tar - [lots of files]) | compress > /tmp/$$name.tar.Z" ; \
|
||||
(cd .. ; $$tar - $$list) | compress > /tmp/$$name.tar.Z ; \
|
||||
"(cd .. ; $$tar - [lots of files]) | gzip -c > /tmp/$$name.tar.gz" ; \
|
||||
(cd .. ; $$tar - $$list) | gzip -c > /tmp/$$name.tar.gz ; \
|
||||
echo \
|
||||
"rm -f ../$$name" ; \
|
||||
rm -f ../$$name
|
||||
|
||||
depend: $(GENSRC) $(GENHDR) bpf_filter.c
|
||||
./mkdep -c $(CC) $(DEFS) $(INCLS) $(SRC)
|
||||
|
||||
Makefile: Makefile.in config.status
|
||||
./config.status
|
||||
@echo your Makefile was out of date, now run $(MAKE) again
|
||||
exit 1
|
||||
|
@ -1,6 +1,6 @@
|
||||
@(#) $Header: /tcpdump/master/libpcap/README,v 1.27.2.1 2003/11/15 23:29:19 guy Exp $ (LBL)
|
||||
@(#) $Header: /tcpdump/master/libpcap/README,v 1.30 2004/10/12 02:02:28 guy Exp $ (LBL)
|
||||
|
||||
LIBPCAP 0.8
|
||||
LIBPCAP 0.9
|
||||
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.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
|
||||
Version 0.9 of LIBPCAP can be retrieved with the CVS tag "libpcap_0_9rel1":
|
||||
cvs -d :pserver:tcpdump@cvs.tcpdump.org:/tcpdump/master checkout -r libpcap_0_9rel1 libpcap
|
||||
|
||||
Please send patches against the master copy to patches@tcpdump.org.
|
||||
|
||||
|
@ -1,3 +1,7 @@
|
||||
For HP-UX 11i (11.11) and later, there are no known issues with
|
||||
promiscuous mode under HP-UX. If you are using a earlier version of
|
||||
HP-UX and cannot upgrade, please continue reading.
|
||||
|
||||
HP-UX patches to fix packet capture problems
|
||||
|
||||
Note that packet-capture programs such as tcpdump may, on HP-UX, not be
|
||||
@ -182,6 +186,10 @@ An additional note, from Jost Martin, for HP-UX 10.20:
|
||||
/sbin/rc2.d/S350hack_ip_stack pointing to this script.
|
||||
Now all this is done on every reboot.
|
||||
|
||||
According to Rick Jones, the global promiscuous switch also has to be
|
||||
turned on for HP-UX 11.00, but not for 11i - and, in fact, the switch
|
||||
doesn't even exist on 11i.
|
||||
|
||||
Here's the "hack_ip_stack" script:
|
||||
|
||||
-----------------------------------Cut Here-------------------------------------
|
||||
|
43
contrib/libpcap/README.macosx
Normal file
43
contrib/libpcap/README.macosx
Normal file
@ -0,0 +1,43 @@
|
||||
As with other systems using BPF, Mac OS X allows users with read access
|
||||
to the BPF devices to capture packets with libpcap and allows users with
|
||||
write access to the BPF devices to send packets with libpcap.
|
||||
|
||||
On some systems that use BPF, the BPF devices live on the root file
|
||||
system, and the permissions and/or ownership on those devices can be
|
||||
changed to give users other than root permission to read or write those
|
||||
devices.
|
||||
|
||||
On newer versions of FreeBSD, the BPF devices live on devfs, and devfs
|
||||
can be configured to set the permissions and/or ownership of those
|
||||
devices to give users other than root permission to read or write those
|
||||
devices.
|
||||
|
||||
On Mac OS X, the BPF devices live on devfs, but the OS X version of
|
||||
devfs is based on an older (non-default) FreeBSD devfs, and that version
|
||||
of devfs cannot be configured to set the permissions and/or ownership of
|
||||
those devices.
|
||||
|
||||
Therefore, we supply a "startup item" for OS X that will change the
|
||||
ownership of the BPF devices so that the "admin" group owns them, and
|
||||
will change the permission of the BPF devices to rw-rw----, so that all
|
||||
users in the "admin" group - i.e., all users with "Allow user to
|
||||
administer this computer" turned on - have both read and write access to
|
||||
them.
|
||||
|
||||
The startup item is in the ChmodBPF directory in the source tree. A
|
||||
/Library/StartupItems directory should be created if it doesn't already
|
||||
exist, and the ChmodBPF directory should be copied to the
|
||||
/Library/StartupItems directory (copy the entire directory, so that
|
||||
there's a /Library/StartupItems/ChmodBPF directory, containing all the
|
||||
files in the source tree's ChmodBPF directory; don't copy the individual
|
||||
items in that directory to /Library/StartupItems).
|
||||
|
||||
If you want to give a particular user permission to access the BPF
|
||||
devices, rather than giving all administrative users permission to
|
||||
access them, you can have the ChmodBPF/ChmodBPF script change the
|
||||
ownership of /dev/bpf* without changing the permissions. If you want to
|
||||
give a particular user permission to read and write the BPF devices and
|
||||
give the administrative users permission to read but not write the BPF
|
||||
devices, you can have the script change the owner to that user, the
|
||||
group to "admin", and the permissions to rw-r-----. Other possibilities
|
||||
are left as an exercise for the reader.
|
@ -1 +1 @@
|
||||
0.8.3
|
||||
0.9-PRE-CVS
|
||||
|
37
contrib/libpcap/aclocal.m4
vendored
37
contrib/libpcap/aclocal.m4
vendored
@ -1,4 +1,4 @@
|
||||
dnl @(#) $Header: /tcpdump/master/libpcap/aclocal.m4,v 1.81.2.2 2003/11/16 09:45:51 guy Exp $ (LBL)
|
||||
dnl @(#) $Header: /tcpdump/master/libpcap/aclocal.m4,v 1.85 2005/03/27 03:27:09 guy Exp $ (LBL)
|
||||
dnl
|
||||
dnl Copyright (c) 1995, 1996, 1997, 1998
|
||||
dnl The Regents of the University of California. All rights reserved.
|
||||
@ -166,8 +166,13 @@ AC_DEFUN(AC_LBL_C_INIT,
|
||||
# at least some versions of HP's C compiler can inline that, but can't
|
||||
# inline a function that returns a struct pointer.
|
||||
#
|
||||
# Make sure we use the V_CCOPT flags, because some of those might
|
||||
# disable inlining.
|
||||
#
|
||||
AC_DEFUN(AC_LBL_C_INLINE,
|
||||
[AC_MSG_CHECKING(for inline)
|
||||
save_CFLAGS="$CFLAGS"
|
||||
CFLAGS="$V_CCOPT"
|
||||
AC_CACHE_VAL(ac_cv_lbl_inline, [
|
||||
ac_cv_lbl_inline=""
|
||||
ac_lbl_cc_inline=no
|
||||
@ -195,6 +200,7 @@ AC_DEFUN(AC_LBL_C_INLINE,
|
||||
if test "$ac_lbl_cc_inline" = yes ; then
|
||||
ac_cv_lbl_inline=$ac_lbl_inline
|
||||
fi])
|
||||
CFLAGS="$save_CFLAGS"
|
||||
if test ! -z "$ac_cv_lbl_inline" ; then
|
||||
AC_MSG_RESULT($ac_cv_lbl_inline)
|
||||
else
|
||||
@ -822,23 +828,20 @@ dnl
|
||||
AC_DEFUN(AC_LBL_LIBRARY_NET, [
|
||||
# Most operating systems have gethostbyname() in the default searched
|
||||
# libraries (i.e. libc):
|
||||
AC_CHECK_FUNC(gethostbyname, ,
|
||||
# Some OSes (eg. Solaris) place it in libnsl:
|
||||
AC_LBL_CHECK_LIB(nsl, gethostbyname, ,
|
||||
# Some strange OSes (SINIX) have it in libsocket:
|
||||
AC_LBL_CHECK_LIB(socket, gethostbyname, ,
|
||||
# Unfortunately libsocket sometimes depends on libnsl.
|
||||
# AC_CHECK_LIB's API is essentially broken so the
|
||||
# following ugliness is necessary:
|
||||
AC_LBL_CHECK_LIB(socket, gethostbyname,
|
||||
LIBS="-lsocket -lnsl $LIBS",
|
||||
AC_CHECK_LIB(resolv, gethostbyname),
|
||||
-lnsl))))
|
||||
AC_CHECK_FUNC(socket, , AC_CHECK_LIB(socket, socket, ,
|
||||
AC_LBL_CHECK_LIB(socket, socket, LIBS="-lsocket -lnsl $LIBS", ,
|
||||
-lnsl)))
|
||||
# Some OSes (eg. Solaris) place it in libnsl
|
||||
# Some strange OSes (SINIX) have it in libsocket:
|
||||
AC_SEARCH_LIBS(gethostbyname, nsl socket resolv)
|
||||
# Unfortunately libsocket sometimes depends on libnsl and
|
||||
# AC_SEARCH_LIBS isn't up to the task of handling dependencies like this.
|
||||
if test "$ac_cv_search_gethostbyname" = "no"
|
||||
then
|
||||
AC_CHECK_LIB(socket, gethostbyname,
|
||||
LIBS="-lsocket -lnsl $LIBS", , -lnsl)
|
||||
fi
|
||||
AC_SEARCH_LIBS(socket, socket, ,
|
||||
AC_CHECK_LIB(socket, socket, LIBS="-lsocket -lnsl $LIBS", , -lnsl))
|
||||
# DLPI needs putmsg under HPUX so test for -lstr while we're at it
|
||||
AC_CHECK_LIB(str, putmsg)
|
||||
AC_SEARCH_LIBS(putmsg, str)
|
||||
])
|
||||
|
||||
dnl
|
||||
|
@ -40,7 +40,7 @@
|
||||
|
||||
#if !(defined(lint) || defined(KERNEL) || defined(_KERNEL))
|
||||
static const char rcsid[] _U_ =
|
||||
"@(#) $Header: /tcpdump/master/libpcap/bpf/net/bpf_filter.c,v 1.43.2.1 2003/11/15 23:26:49 guy Exp $ (LBL)";
|
||||
"@(#) $Header: /tcpdump/master/libpcap/bpf/net/bpf_filter.c,v 1.44 2003/11/15 23:24:07 guy Exp $ (LBL)";
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
|
@ -20,7 +20,7 @@
|
||||
*/
|
||||
#ifndef lint
|
||||
static const char rcsid[] _U_ =
|
||||
"@(#) $Header: /tcpdump/master/libpcap/bpf_dump.c,v 1.13.2.1 2003/11/15 23:26:37 guy Exp $ (LBL)";
|
||||
"@(#) $Header: /tcpdump/master/libpcap/bpf_dump.c,v 1.14 2003/11/15 23:23:57 guy Exp $ (LBL)";
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
|
@ -21,7 +21,7 @@
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid[] _U_ =
|
||||
"@(#) $Header: /tcpdump/master/libpcap/bpf_image.c,v 1.25.2.1 2003/11/15 23:26:38 guy Exp $ (LBL)";
|
||||
"@(#) $Header: /tcpdump/master/libpcap/bpf_image.c,v 1.26 2003/11/15 23:23:57 guy Exp $ (LBL)";
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
|
@ -1,8 +1,4 @@
|
||||
/* config.h.in. Generated automatically from configure.in by autoheader. */
|
||||
|
||||
/* Define to empty if the keyword does not work. */
|
||||
#undef const
|
||||
|
||||
/* config.h.in. Generated from configure.in by autoheader. */
|
||||
/* Long story short: aclocal.m4 depends on autoconf 2.13
|
||||
* implementation details wrt "const"; newer versions
|
||||
* have different implementation details so for now we
|
||||
@ -11,114 +7,171 @@
|
||||
*/
|
||||
#undef const
|
||||
|
||||
/* 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
|
||||
|
||||
/* Define if you have the <limits.h> header file. */
|
||||
#undef HAVE_LIMITS_H
|
||||
|
||||
/* Define if you have the <netinet/if_ether.h> header file. */
|
||||
#undef HAVE_NETINET_IF_ETHER_H
|
||||
|
||||
/* Define if you have the <sys/bufmod.h> header file. */
|
||||
#undef HAVE_SYS_BUFMOD_H
|
||||
|
||||
/* Define if you have the <sys/dlpi_ext.h> header file. */
|
||||
#undef HAVE_SYS_DLPI_EXT_H
|
||||
|
||||
/* Define if you have the <sys/ioccom.h> header file. */
|
||||
#undef HAVE_SYS_IOCCOM_H
|
||||
|
||||
/* Define if you have the <sys/sockio.h> header file. */
|
||||
#undef HAVE_SYS_SOCKIO_H
|
||||
|
||||
/* 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__
|
||||
|
||||
/* if we have u_int8_t */
|
||||
#undef u_int8_t
|
||||
|
||||
/* if we have u_int16_t */
|
||||
#undef u_int16_t
|
||||
|
||||
/* if we have u_int32_t */
|
||||
#undef u_int32_t
|
||||
|
||||
/* do not use protochain */
|
||||
#undef NO_PROTOCHAIN
|
||||
|
||||
/* IPv6 */
|
||||
#undef INET6
|
||||
|
||||
/* Enable optimizer debugging */
|
||||
#undef BDEBUG
|
||||
|
||||
/* Enable parser debugging */
|
||||
#undef YYDEBUG
|
||||
/* define if you have the DAG API */
|
||||
#undef HAVE_DAG_API
|
||||
|
||||
/* Define to 1 if you have the declaration of `ether_hostton', and to 0 if you
|
||||
don't. */
|
||||
#undef HAVE_DECL_ETHER_HOSTTON
|
||||
|
||||
/* define if you have a /dev/dlpi */
|
||||
#undef HAVE_DEV_DLPI
|
||||
|
||||
/* /dev/dlpi directory */
|
||||
#undef PCAP_DEV_PREFIX
|
||||
|
||||
/* if if_packet.h has tpacket_stats defined */
|
||||
#undef HAVE_TPACKET_STATS
|
||||
|
||||
/* 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
|
||||
|
||||
/* on HP-UX 9.x */
|
||||
#undef HAVE_HPUX9
|
||||
/* Define to 1 if you have the `ether_hostton' function. */
|
||||
#undef HAVE_ETHER_HOSTTON
|
||||
|
||||
/* on HP-UX 10.20 */
|
||||
#undef HAVE_HPUX10_20
|
||||
|
||||
/* on sinix */
|
||||
#undef sinix
|
||||
/* on HP-UX 9.x */
|
||||
#undef HAVE_HPUX9
|
||||
|
||||
/* On solaris */
|
||||
#undef HAVE_SOLARIS
|
||||
/* if ppa_info_t_dl_module_id exists */
|
||||
#undef HAVE_HP_PPA_INFO_T_DL_MODULE_ID_1
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#undef HAVE_INTTYPES_H
|
||||
|
||||
/* Define to 1 if you have the <limits.h> header file. */
|
||||
#undef HAVE_LIMITS_H
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#undef HAVE_MEMORY_H
|
||||
|
||||
/* Define to 1 if you have the <netinet/ether.h> header file. */
|
||||
#undef HAVE_NETINET_ETHER_H
|
||||
|
||||
/* Define to 1 if you have the <netinet/if_ether.h> header file. */
|
||||
#undef HAVE_NETINET_IF_ETHER_H
|
||||
|
||||
/* if there's an os_proto.h */
|
||||
#undef HAVE_OS_PROTO_H
|
||||
|
||||
/* define if you have a /proc/net/dev */
|
||||
#undef HAVE_PROC_NET_DEV
|
||||
|
||||
/* Define to 1 if you have the `snprintf' function. */
|
||||
#undef HAVE_SNPRINTF
|
||||
|
||||
/* 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
|
||||
/* On solaris */
|
||||
#undef HAVE_SOLARIS
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#undef HAVE_STDINT_H
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#undef HAVE_STDLIB_H
|
||||
|
||||
/* Define to 1 if you have the `strerror' function. */
|
||||
#undef HAVE_STRERROR
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#undef HAVE_STRINGS_H
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#undef HAVE_STRING_H
|
||||
|
||||
/* Define to 1 if you have the `strlcpy' function. */
|
||||
#undef HAVE_STRLCPY
|
||||
|
||||
/* Define to 1 if you have the <sys/bufmod.h> header file. */
|
||||
#undef HAVE_SYS_BUFMOD_H
|
||||
|
||||
/* Define to 1 if you have the <sys/dlpi_ext.h> header file. */
|
||||
#undef HAVE_SYS_DLPI_EXT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/ioccom.h> header file. */
|
||||
#undef HAVE_SYS_IOCCOM_H
|
||||
|
||||
/* Define to 1 if you have the <sys/sockio.h> header file. */
|
||||
#undef HAVE_SYS_SOCKIO_H
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#undef HAVE_SYS_STAT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#undef HAVE_SYS_TYPES_H
|
||||
|
||||
/* if if_packet.h has tpacket_stats defined */
|
||||
#undef HAVE_TPACKET_STATS
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#undef HAVE_UNISTD_H
|
||||
|
||||
/* define if version.h is generated in the build procedure */
|
||||
#undef HAVE_VERSION_H
|
||||
|
||||
/* Define to 1 if you have the `vsnprintf' function. */
|
||||
#undef HAVE_VSNPRINTF
|
||||
|
||||
/* define if your compiler has __attribute__ */
|
||||
#undef HAVE___ATTRIBUTE__
|
||||
|
||||
/* IPv6 */
|
||||
#undef INET6
|
||||
|
||||
/* if unaligned access fails */
|
||||
#undef LBL_ALIGN
|
||||
|
||||
/* Define to 1 if netinet/ether.h declares `ether_hostton' */
|
||||
#undef NETINET_ETHER_H_DECLARES_ETHER_HOSTTON
|
||||
|
||||
/* Define to 1 if netinet/if_ether.h declares `ether_hostton' */
|
||||
#undef NETINET_IF_ETHER_H_DECLARES_ETHER_HOSTTON
|
||||
|
||||
/* do not use protochain */
|
||||
#undef NO_PROTOCHAIN
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#undef PACKAGE_BUGREPORT
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#undef PACKAGE_NAME
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#undef PACKAGE_STRING
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#undef PACKAGE_TARNAME
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#undef PACKAGE_VERSION
|
||||
|
||||
/* /dev/dlpi directory */
|
||||
#undef PCAP_DEV_PREFIX
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#undef STDC_HEADERS
|
||||
|
||||
/* Enable parser debugging */
|
||||
#undef YYDEBUG
|
||||
|
||||
/* needed on HP-UX */
|
||||
#undef _HPUX_SOURCE
|
||||
|
||||
/* define on AIX to get certain functions */
|
||||
#undef _SUN
|
||||
|
||||
/* Define as token for inline if inlining supported */
|
||||
#undef inline
|
||||
|
||||
/* on sinix */
|
||||
#undef sinix
|
||||
|
||||
/* if we have u_int16_t */
|
||||
#undef u_int16_t
|
||||
|
||||
/* if we have u_int32_t */
|
||||
#undef u_int32_t
|
||||
|
||||
/* if we have u_int8_t */
|
||||
#undef u_int8_t
|
||||
|
1508
contrib/libpcap/configure
vendored
1508
contrib/libpcap/configure
vendored
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
||||
dnl @(#) $Header: /tcpdump/master/libpcap/configure.in,v 1.100.2.4 2004/03/28 21:43:34 fenner Exp $ (LBL)
|
||||
dnl @(#) $Header: /tcpdump/master/libpcap/configure.in,v 1.120 2005/03/27 22:26:25 guy Exp $ (LBL)
|
||||
dnl
|
||||
dnl Copyright (c) 1994, 1995, 1996, 1997
|
||||
dnl The Regents of the University of California. All rights reserved.
|
||||
@ -6,7 +6,7 @@ dnl
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
dnl
|
||||
|
||||
AC_REVISION($Revision: 1.100.2.4 $)
|
||||
AC_REVISION($Revision: 1.120 $)
|
||||
AC_PREREQ(2.50)
|
||||
AC_INIT(pcap.c)
|
||||
|
||||
@ -26,13 +26,30 @@ 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)
|
||||
AC_CHECK_HEADERS(sys/ioccom.h sys/sockio.h limits.h)
|
||||
AC_CHECK_HEADERS(netinet/if_ether.h, , , [#include <sys/types.h>
|
||||
#include <sys/socket.h>])
|
||||
if test "$ac_cv_header_netinet_if_ether_h" != yes; then
|
||||
#
|
||||
# The simple test didn't work.
|
||||
# Do we need to include <net/if.h> first?
|
||||
# Unset ac_cv_header_netinet_if_ether_h so we don't
|
||||
# treat the previous failure as a cached value and
|
||||
# suppress the next test.
|
||||
#
|
||||
AC_MSG_NOTICE([Rechecking with some additional includes])
|
||||
unset ac_cv_header_netinet_if_ether_h
|
||||
AC_CHECK_HEADERS(netinet/if_ether.h, , , [#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
struct mbuf;
|
||||
struct rtentry;
|
||||
#include <net/if.h>])
|
||||
fi
|
||||
|
||||
AC_LBL_FIXINCLUDES
|
||||
|
||||
AC_CHECK_FUNCS(ether_hostton strerror strlcpy)
|
||||
AC_CHECK_FUNCS(strerror strlcpy)
|
||||
|
||||
needsnprintf=no
|
||||
AC_CHECK_FUNCS(vsnprintf snprintf,,
|
||||
@ -41,6 +58,75 @@ if test $needsnprintf = yes; then
|
||||
AC_LIBOBJ(snprintf)
|
||||
fi
|
||||
|
||||
#
|
||||
# Do this before checking for ether_hostton(), as it's a
|
||||
# "gethostbyname() -ish function".
|
||||
#
|
||||
AC_LBL_LIBRARY_NET
|
||||
|
||||
#
|
||||
# You are in a twisty little maze of UN*Xes, all different.
|
||||
# Some might not have ether_hostton().
|
||||
# Some might have it, but not declare it in any header file.
|
||||
# Some might have it, but declare it in <netinet/if_ether.h>.
|
||||
# Some might have it, but declare it in <netinet/ether.h>
|
||||
# (And some might have it but document it as something declared in
|
||||
# <netinet/ethernet.h>, although <netinet/if_ether.h> appears to work.)
|
||||
#
|
||||
# Before you is a C compiler.
|
||||
#
|
||||
AC_CHECK_FUNCS(ether_hostton)
|
||||
if test "$ac_cv_func_ether_hostton" = yes; then
|
||||
#
|
||||
# OK, we have ether_hostton(). Do we have <netinet/if_ether.h>?
|
||||
#
|
||||
if test "$ac_cv_header_netinet_if_ether_h" = yes; then
|
||||
#
|
||||
# Yes. Does it declare ether_hostton()?
|
||||
#
|
||||
AC_CHECK_DECLS(ether_hostton,
|
||||
[
|
||||
AC_DEFINE(NETINET_IF_ETHER_H_DECLARES_ETHER_HOSTTON,,
|
||||
[Define to 1 if netinet/if_ether.h declares `ether_hostton'])
|
||||
],,
|
||||
[
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
struct mbuf;
|
||||
struct rtentry;
|
||||
#include <net/if.h>
|
||||
#include <netinet/if_ether.h>
|
||||
])
|
||||
fi
|
||||
#
|
||||
# Did that succeed?
|
||||
#
|
||||
if test "$ac_cv_have_decl_ether_hostton" != yes; then
|
||||
#
|
||||
# No, how about <netinet/ether.h>, as on Linux?
|
||||
#
|
||||
AC_CHECK_HEADERS(netinet/ether.h)
|
||||
if test "$ac_cv_header_netinet_ether_h" = yes; then
|
||||
#
|
||||
# We have it - does it declare ether_hostton()?
|
||||
# Unset ac_cv_have_decl_ether_hostton so we don't
|
||||
# treat the previous failure as a cached value and
|
||||
# suppress the next test.
|
||||
#
|
||||
unset ac_cv_have_decl_ether_hostton
|
||||
AC_CHECK_DECLS(ether_hostton,
|
||||
[
|
||||
AC_DEFINE(NETINET_ETHER_H_DECLARES_ETHER_HOSTTON,,
|
||||
[Define to 1 if netinet/ether.h declares `ether_hostton'])
|
||||
],,
|
||||
[
|
||||
#include <netinet/ether.h>
|
||||
])
|
||||
fi
|
||||
fi
|
||||
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])
|
||||
@ -105,65 +191,88 @@ fi
|
||||
AC_MSG_RESULT($V_PCAP)
|
||||
|
||||
dnl
|
||||
dnl Now figure out how we get a list of interfaces and addresses.
|
||||
dnl Now figure out how we get a list of interfaces and addresses,
|
||||
dnl if we support capturing. Don't bother if we don't support
|
||||
dnl capturing.
|
||||
dnl
|
||||
AC_CHECK_FUNC(getifaddrs,[
|
||||
if test "$V_PCAP" = null
|
||||
then
|
||||
#
|
||||
# We have "getifaddrs()", so we use that to get the list
|
||||
# We can't capture, so we can't open any capture
|
||||
# devices, so we won't return any interfaces.
|
||||
#
|
||||
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
|
||||
V_FINDALLDEVS=null
|
||||
else
|
||||
AC_CHECK_FUNC(getifaddrs,[
|
||||
#
|
||||
# We have "getifaddrs()"; make sure we have <ifaddrs.h>
|
||||
# as well, just in case some platform is really weird.
|
||||
#
|
||||
AC_CHECK_HEADER(ifaddrs.h,[
|
||||
#
|
||||
# We have the header, so we use "getifaddrs()" to
|
||||
# get the list of interfaces.
|
||||
#
|
||||
V_FINDALLDEVS=getad
|
||||
],[
|
||||
#
|
||||
# We don't have the header - give up.
|
||||
# XXX - we could also fall back on some other
|
||||
# mechanism, but, for now, this'll catch this
|
||||
# problem so that we can at least try to figure
|
||||
# out something to do on systems with "getifaddrs()"
|
||||
# but without "ifaddrs.h", if there is something
|
||||
# we can do on those systems.
|
||||
#
|
||||
AC_MSG_ERROR([Your system has getifaddrs() but doesn't have a usable <ifaddrs.h>.])
|
||||
])
|
||||
],[
|
||||
#
|
||||
# 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
|
||||
dlpi)
|
||||
#
|
||||
# This might be Solaris 8 or later, with
|
||||
# SIOCGLIFCONF, or it might be some other OS
|
||||
# or some older version of Solaris, 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
|
||||
;;
|
||||
|
||||
*)
|
||||
#
|
||||
# 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
|
||||
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])
|
||||
;;
|
||||
esac])
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING(if --enable-ipv6 option is specified)
|
||||
AC_ARG_ENABLE(ipv6, [ --enable-ipv6 build IPv6-capable version])
|
||||
@ -249,16 +358,19 @@ 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]],
|
||||
# Check for Endace DAG card support.
|
||||
AC_ARG_WITH([dag], [ --with-dag[[=DIR]] include Endace DAG support ("yes", "no" or DIR; default="yes" on BSD and Linux if present)],
|
||||
[
|
||||
if test "$withval" = no
|
||||
then
|
||||
# User doesn't want DAG support.
|
||||
want_dag=no
|
||||
elif test "$withval" = yes
|
||||
then
|
||||
# User wants DAG support but hasn't specified a directory.
|
||||
want_dag=yes
|
||||
dag_root=
|
||||
else
|
||||
# User wants DAG support and has specified a directory, so use the provided value.
|
||||
want_dag=yes
|
||||
dag_root=$withval
|
||||
fi
|
||||
@ -267,9 +379,22 @@ AC_ARG_WITH(dag, [ --with-dag[=DIR] include DAG support (located in dire
|
||||
# Use DAG API if present, otherwise don't
|
||||
#
|
||||
want_dag=ifpresent
|
||||
dag_root=/root/dag
|
||||
])
|
||||
ac_cv_lbl_dag_api=no
|
||||
|
||||
AC_ARG_WITH([dag-includes], [ --with-dag-includes=DIR Endace DAG include directory],
|
||||
[
|
||||
# User wants DAG support and has specified a header directory, so use the provided value.
|
||||
want_dag=yes
|
||||
dag_include_dir=$withval
|
||||
],[])
|
||||
|
||||
AC_ARG_WITH([dag-libraries], [ --with-dag-libraries=DIR Endace DAG library directory],
|
||||
[
|
||||
# User wants DAG support and has specified a library directory, so use the provided value.
|
||||
want_dag=yes
|
||||
dag_lib_dir=$withval
|
||||
],[])
|
||||
|
||||
case "$V_PCAP" in
|
||||
linux|bpf|dag)
|
||||
#
|
||||
@ -285,60 +410,167 @@ linux|bpf|dag)
|
||||
# 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)
|
||||
AC_MSG_ERROR([DAG support is 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)
|
||||
ac_cv_lbl_dag_api=no
|
||||
if test "$want_dag" != no; then
|
||||
|
||||
AC_MSG_CHECKING([whether we have DAG API headers])
|
||||
|
||||
# If necessary, set default paths for DAG API headers and libraries.
|
||||
if test -z "$dag_root"; then
|
||||
dag_root=$srcdir/../dag
|
||||
dag_root=/usr/local
|
||||
fi
|
||||
|
||||
if test -r "$dag_root/tools" -a -r "$dag_root/include"; then
|
||||
dag_tools_dir="$dag_root/tools"
|
||||
if test -z "$dag_include_dir"; then
|
||||
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"
|
||||
if test -z "$dag_lib_dir"; then
|
||||
dag_lib_dir="$dag_root/lib"
|
||||
fi
|
||||
|
||||
if test -z "$dag_tools_dir"; then
|
||||
dag_tools_dir="$dag_root/tools"
|
||||
fi
|
||||
|
||||
if test -r $dag_include_dir/dagapi.h; then
|
||||
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_MSG_RESULT([$ac_cv_lbl_dag_api ($dag_include_dir)])
|
||||
fi
|
||||
|
||||
if test $ac_cv_lbl_dag_api = yes; then
|
||||
|
||||
AC_MSG_CHECKING([dagapi.o])
|
||||
dagapi_obj=no
|
||||
if test -r $dag_tools_dir/dagapi.o; then
|
||||
|
||||
# 2.4.x.
|
||||
dagapi_obj=$dag_tools_dir/dagapi.o
|
||||
|
||||
elif test -r $dag_lib_dir/dagapi.o; then
|
||||
|
||||
# 2.5.x.
|
||||
dagapi_obj=$dag_lib_dir/dagapi.o
|
||||
|
||||
elif test -r $dag_lib_dir/libdag.a; then
|
||||
|
||||
# 2.5.x.
|
||||
ar x $dag_lib_dir/libdag.a dagapi.o
|
||||
if test -r ./dagapi.o; then
|
||||
dagapi_obj=./dagapi.o
|
||||
fi
|
||||
fi
|
||||
|
||||
if test $dagapi_obj = no; then
|
||||
AC_MSG_RESULT([no (checked $dag_lib_dir $dag_tools_dir $dag_lib_dir/libdag.a)])
|
||||
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])
|
||||
AC_MSG_RESULT([yes ($dagapi_obj)])
|
||||
fi
|
||||
fi
|
||||
|
||||
if test $ac_cv_lbl_dag_api = yes; then
|
||||
|
||||
AC_MSG_CHECKING([dagopts.o])
|
||||
dagopts_obj=no
|
||||
if test -r $dag_tools_dir/dagopts.o; then
|
||||
|
||||
# 2.4.x.
|
||||
dagopts_obj=$dag_tools_dir/dagopts.o
|
||||
|
||||
elif test -r $dag_lib_dir/dagopts.o; then
|
||||
|
||||
# 2.5.x.
|
||||
dagopts_obj=$dag_lib_dir/dagopts.o
|
||||
|
||||
elif test -r $dag_lib_dir/libdag.a; then
|
||||
|
||||
# 2.5.x.
|
||||
ar x $dag_lib_dir/libdag.a dagopts.o
|
||||
if test -r ./dagopts.o; then
|
||||
dagopts_obj=./dagopts.o
|
||||
fi
|
||||
fi
|
||||
|
||||
if test $dagopts_obj = no; then
|
||||
AC_MSG_RESULT([no (checked $dag_lib_dir $dag_tools_dir $dag_lib_dir/libdag.a)])
|
||||
ac_cv_lbl_dag_api=no
|
||||
else
|
||||
AC_MSG_RESULT([yes ($dagopts_obj)])
|
||||
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)
|
||||
if test $ac_cv_lbl_dag_api = yes; then
|
||||
|
||||
# Under 2.5.x only we need to add dagreg.o.
|
||||
if test -r $dag_include_dir/dagreg.h; then
|
||||
|
||||
AC_MSG_CHECKING([dagreg.o])
|
||||
dagreg_obj=no
|
||||
if test -r $dag_lib_dir/dagreg.o; then
|
||||
|
||||
# Object file is ready and waiting.
|
||||
dagreg_obj=$dag_lib_dir/dagreg.o
|
||||
|
||||
elif test -r $dag_lib_dir/libdag.a; then
|
||||
|
||||
# Extract from libdag.a.
|
||||
ar x $dag_lib_dir/libdag.a dagreg.o
|
||||
if test -r ./dagreg.o; then
|
||||
dagreg_obj=./dagreg.o
|
||||
fi
|
||||
fi
|
||||
|
||||
if test $dagreg_obj = no; then
|
||||
AC_MSG_RESULT([no (checked $dag_lib_dir $dag_lib_dir/libdag.a)])
|
||||
ac_cv_lbl_dag_api=no
|
||||
else
|
||||
AC_MSG_RESULT([yes ($dagreg_obj)])
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if test $ac_cv_lbl_dag_api = yes; then
|
||||
|
||||
V_INCLS="$V_INCLS -I$dag_include_dir"
|
||||
V_LIBS="$V_LIBS $dagapi_obj $dagopts_obj $dagreg_obj"
|
||||
if test $V_PCAP != dag ; then
|
||||
SSRC="pcap-dag.c"
|
||||
fi
|
||||
|
||||
# See if we can find a general version string.
|
||||
# Don't need to save and restore LIBS to prevent -ldag being included if there's a found-action (arg 3).
|
||||
saved_ldflags=$LDFLAGS
|
||||
LDFLAGS="-L$dag_lib_dir"
|
||||
AC_CHECK_LIB([dag], [dag_attach_stream], [dag_version="2.5.x"], [dag_version="2.4.x"])
|
||||
LDFLAGS=$saved_ldflags
|
||||
|
||||
# See if we can find a specific version string.
|
||||
AC_MSG_CHECKING([the DAG API version])
|
||||
if test -r "$dag_root/VERSION"; then
|
||||
dag_version="`cat $dag_root/VERSION`"
|
||||
fi
|
||||
AC_MSG_RESULT([$dag_version])
|
||||
AC_DEFINE(HAVE_DAG_API, 1, [define if you have the DAG API])
|
||||
fi
|
||||
|
||||
if test $ac_cv_lbl_dag_api = no; then
|
||||
if test "$want_dag" = yes; then
|
||||
# User wanted DAG support but we couldn't find it.
|
||||
AC_MSG_ERROR([DAG API requested, but not found at $dag_root: use --without-dag])
|
||||
fi
|
||||
|
||||
if test "$V_PCAP" = dag; then
|
||||
# User requested "dag" capture type but the DAG API wasn't found.
|
||||
AC_MSG_ERROR([Specifying the capture type as "dag" requires the DAG API to be present; use the --with-dag options to specify the location. (Try "./configure --help" for more information.)])
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
@ -360,6 +592,7 @@ if test "$V_LEX" = lex ; then
|
||||
fi
|
||||
fi
|
||||
|
||||
DYEXT="so"
|
||||
case "$host_os" in
|
||||
|
||||
aix*)
|
||||
@ -378,7 +611,12 @@ hpux10.1*)
|
||||
;;
|
||||
|
||||
hpux*)
|
||||
dnl HPUX 10.20 and above is similar to HPUX 9...
|
||||
dnl HPUX 10.20 and above is similar to HPUX 9, but
|
||||
dnl not the same....
|
||||
dnl
|
||||
dnl XXX - DYEXT should be set to "sl" if this is building
|
||||
dnl for 32-bit PA-RISC, but should be left as "so" for
|
||||
dnl 64-bit PA-RISC or, I suspect, IA-64.
|
||||
AC_DEFINE(HAVE_HPUX10_20,1,[on HP-UX 10.20])
|
||||
;;
|
||||
|
||||
@ -399,6 +637,11 @@ sinix*)
|
||||
solaris*)
|
||||
AC_DEFINE(HAVE_SOLARIS,1,[On solaris])
|
||||
;;
|
||||
|
||||
darwin*)
|
||||
DYEXT="dylib"
|
||||
V_CCOPT="$V_CCOPT -fno-common"
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_PROG_RANLIB
|
||||
@ -413,6 +656,12 @@ AC_LBL_HP_PPA_INFO_T_DL_MODULE_ID_1
|
||||
|
||||
AC_LBL_UNALIGNED_ACCESS
|
||||
|
||||
#
|
||||
# Makefile.in includes rules to generate version.h, so we assume
|
||||
# that it will be generated if autoconf is used.
|
||||
#
|
||||
AC_DEFINE(HAVE_VERSION_H, 1, [define if version.h is generated in the build procedure])
|
||||
|
||||
rm -f net
|
||||
ln -s ${srcdir}/bpf/net net
|
||||
|
||||
@ -426,6 +675,7 @@ AC_SUBST(V_FINDALLDEVS)
|
||||
AC_SUBST(V_RANLIB)
|
||||
AC_SUBST(V_YACC)
|
||||
AC_SUBST(SSRC)
|
||||
AC_SUBST(DYEXT)
|
||||
|
||||
AC_PROG_INSTALL
|
||||
|
||||
|
@ -21,7 +21,7 @@
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid[] _U_ =
|
||||
"@(#) $Header: /tcpdump/master/libpcap/etherent.c,v 1.21.6.1 2003/11/15 23:26:38 guy Exp $ (LBL)";
|
||||
"@(#) $Header: /tcpdump/master/libpcap/etherent.c,v 1.22 2003/11/15 23:23:57 guy Exp $ (LBL)";
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
|
@ -18,7 +18,7 @@
|
||||
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* @(#) $Header: /tcpdump/master/libpcap/ethertype.h,v 1.12 2001/01/14 21:26:52 guy Exp $ (LBL)
|
||||
* @(#) $Header: /tcpdump/master/libpcap/ethertype.h,v 1.13 2004/06/16 08:20:28 hannes Exp $ (LBL)
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -102,6 +102,12 @@
|
||||
#ifndef ETHERTYPE_IPV6
|
||||
#define ETHERTYPE_IPV6 0x86dd
|
||||
#endif
|
||||
#ifndef ETHERTYPE_MPLS
|
||||
#define ETHERTYPE_MPLS 0x8847
|
||||
#endif
|
||||
#ifndef ETHERTYPE_MPLS_MULTI
|
||||
#define ETHERTYPE_MPLS_MULTI 0x8848
|
||||
#endif
|
||||
#ifndef ETHERTYPE_LOOPBACK
|
||||
#define ETHERTYPE_LOOPBACK 0x9000
|
||||
#endif
|
||||
|
@ -34,7 +34,7 @@
|
||||
|
||||
#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)";
|
||||
"@(#) $Header: /tcpdump/master/libpcap/fad-getad.c,v 1.10 2004/11/04 07:26:04 guy Exp $ (LBL)";
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
@ -58,6 +58,10 @@ static const char rcsid[] _U_ =
|
||||
#include "os-proto.h"
|
||||
#endif
|
||||
|
||||
#ifdef AF_PACKET
|
||||
# include <linux/if_packet.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This is fun.
|
||||
*
|
||||
@ -101,6 +105,11 @@ get_sa_len(struct sockaddr *addr)
|
||||
return (sizeof (struct sockaddr_in6));
|
||||
#endif
|
||||
|
||||
#ifdef AF_PACKET
|
||||
case AF_PACKET:
|
||||
return (sizeof (struct sockaddr_ll));
|
||||
#endif
|
||||
|
||||
default:
|
||||
return (sizeof (struct sockaddr));
|
||||
}
|
||||
|
@ -34,7 +34,7 @@
|
||||
|
||||
#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)";
|
||||
"@(#) $Header: /tcpdump/master/libpcap/fad-gifc.c,v 1.8 2005/01/29 10:34:04 guy Exp $ (LBL)";
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
@ -255,6 +255,9 @@ pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
|
||||
struct ifconf ifc;
|
||||
char *buf = NULL;
|
||||
unsigned buf_size;
|
||||
#ifdef HAVE_SOLARIS
|
||||
char *p, *q;
|
||||
#endif
|
||||
struct ifreq ifrflags, ifrnetmask, ifrbroadaddr, ifrdstaddr;
|
||||
struct sockaddr *netmask, *broadaddr, *dstaddr;
|
||||
size_t netmask_size, broadaddr_size, dstaddr_size;
|
||||
@ -323,6 +326,28 @@ pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
|
||||
else
|
||||
ifnext = (struct ifreq *)((char *)ifrp + n);
|
||||
|
||||
/*
|
||||
* XXX - The 32-bit compatibility layer for Linux on IA-64
|
||||
* is slightly broken. It correctly converts the structures
|
||||
* to and from kernel land from 64 bit to 32 bit but
|
||||
* doesn't update ifc.ifc_len, leaving it larger than the
|
||||
* amount really used. This means we read off the end
|
||||
* of the buffer and encounter an interface with an
|
||||
* "empty" name. Since this is highly unlikely to ever
|
||||
* occur in a valid case we can just finish looking for
|
||||
* interfaces if we see an empty name.
|
||||
*/
|
||||
if (!(*ifrp->ifr_name))
|
||||
break;
|
||||
|
||||
/*
|
||||
* Skip entries that begin with "dummy".
|
||||
* XXX - what are these? Is this Linux-specific?
|
||||
* Are there platforms on which we shouldn't do this?
|
||||
*/
|
||||
if (strncmp(ifrp->ifr_name, "dummy", 5) == 0)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Get the flags for this interface, and skip it if it's
|
||||
* not up.
|
||||
@ -449,6 +474,34 @@ pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
|
||||
dstaddr_size = 0;
|
||||
}
|
||||
|
||||
#ifdef HAVE_SOLARIS
|
||||
/*
|
||||
* If this entry has a colon followed by a number at
|
||||
* the end, it's a logical interface. Those are just
|
||||
* the way you assign multiple IP addresses to a real
|
||||
* interface, so an entry for a logical interface should
|
||||
* be treated like the entry for the real interface;
|
||||
* we do that by stripping off the ":" and the number.
|
||||
*/
|
||||
p = strchr(ifrp->ifr_name, ':');
|
||||
if (p != NULL) {
|
||||
/*
|
||||
* We have a ":"; is it followed by a number?
|
||||
*/
|
||||
q = p + 1;
|
||||
while (isdigit((unsigned char)*q))
|
||||
q++;
|
||||
if (*q == '\0') {
|
||||
/*
|
||||
* All digits after the ":" until the end.
|
||||
* Strip off the ":" and everything after
|
||||
* it.
|
||||
*/
|
||||
*p = '\0';
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Add information for this address to the list.
|
||||
*/
|
||||
|
@ -34,7 +34,7 @@
|
||||
|
||||
#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)";
|
||||
"@(#) $Header: /tcpdump/master/libpcap/fad-glifc.c,v 1.5 2005/01/29 10:34:04 guy Exp $ (LBL)";
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
@ -89,6 +89,9 @@ pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
|
||||
struct lifconf ifc;
|
||||
char *buf = NULL;
|
||||
unsigned buf_size;
|
||||
#ifdef HAVE_SOLARIS
|
||||
char *p, *q;
|
||||
#endif
|
||||
struct lifreq ifrflags, ifrnetmask, ifrbroadaddr, ifrdstaddr;
|
||||
struct sockaddr *netmask, *broadaddr, *dstaddr;
|
||||
int ret = 0;
|
||||
@ -174,6 +177,36 @@ pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
|
||||
else
|
||||
fd = fd4;
|
||||
|
||||
/*
|
||||
* Skip entries that begin with "dummy".
|
||||
* XXX - what are these? Is this Linux-specific?
|
||||
* Are there platforms on which we shouldn't do this?
|
||||
*/
|
||||
if (strncmp(ifrp->lifr_name, "dummy", 5) == 0)
|
||||
continue;
|
||||
|
||||
#ifdef HAVE_SOLARIS
|
||||
/*
|
||||
* Skip entries that have a ":" followed by a number
|
||||
* at the end - those are Solaris virtual interfaces
|
||||
* on which you can't capture.
|
||||
*/
|
||||
p = strchr(ifrp->lifr_name, ':');
|
||||
if (p != NULL) {
|
||||
/*
|
||||
* We have a ":"; is it followed by a number?
|
||||
*/
|
||||
while (isdigit((unsigned char)*p))
|
||||
p++;
|
||||
if (*p == '\0') {
|
||||
/*
|
||||
* All digits after the ":" until the end.
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Get the flags for this interface, and skip it if it's
|
||||
* not up.
|
||||
@ -284,6 +317,34 @@ pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
|
||||
} else
|
||||
dstaddr = NULL;
|
||||
|
||||
#ifdef HAVE_SOLARIS
|
||||
/*
|
||||
* If this entry has a colon followed by a number at
|
||||
* the end, it's a logical interface. Those are just
|
||||
* the way you assign multiple IP addresses to a real
|
||||
* interface, so an entry for a logical interface should
|
||||
* be treated like the entry for the real interface;
|
||||
* we do that by stripping off the ":" and the number.
|
||||
*/
|
||||
p = strchr(ifrp->ifr_name, ':');
|
||||
if (p != NULL) {
|
||||
/*
|
||||
* We have a ":"; is it followed by a number?
|
||||
*/
|
||||
q = p + 1;
|
||||
while (isdigit((unsigned char)*q))
|
||||
q++;
|
||||
if (*q == '\0') {
|
||||
/*
|
||||
* All digits after the ":" until the end.
|
||||
* Strip off the ":" and everything after
|
||||
* it.
|
||||
*/
|
||||
*p = '\0';
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Add information for this address to the list.
|
||||
*/
|
||||
|
@ -34,7 +34,7 @@
|
||||
|
||||
#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)";
|
||||
"@(#) $Header: /tcpdump/master/libpcap/fad-null.c,v 1.2 2003/11/15 23:23:58 guy Exp $ (LBL)";
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
#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)";
|
||||
"@(#) $Header: /tcpdump/master/libpcap/fad-win32.c,v 1.11 2005/01/29 00:52:22 guy Exp $ (LBL)";
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
@ -155,8 +155,7 @@ pcap_add_if_win32(pcap_if_t **devlist, char *name, const char *desc,
|
||||
/*
|
||||
* Add an entry for this interface, with no addresses.
|
||||
*/
|
||||
if (add_or_find_if(&curdev, devlist, (char *)name, 0, (char *)desc,
|
||||
errbuf) == -1) {
|
||||
if (add_or_find_if(&curdev, devlist, name, 0, desc, errbuf) == -1) {
|
||||
/*
|
||||
* Failure.
|
||||
*/
|
||||
@ -221,14 +220,30 @@ 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 *AdaptersName;
|
||||
ULONG NameLength;
|
||||
char *name;
|
||||
|
||||
PacketGetAdapterNames(NULL, &NameLength);
|
||||
|
||||
if (NameLength > 0)
|
||||
AdaptersName = (char*) malloc(NameLength);
|
||||
else
|
||||
{
|
||||
*alldevsp = NULL;
|
||||
return 0;
|
||||
}
|
||||
if (AdaptersName == NULL)
|
||||
{
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE, "Cannot allocate enough memory to list the adapters.");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (!PacketGetAdapterNames(AdaptersName, &NameLength)) {
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"PacketGetAdapterNames: %s",
|
||||
pcap_win32strerror());
|
||||
free(AdaptersName);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
@ -261,14 +276,13 @@ pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
|
||||
*/
|
||||
name = &AdaptersName[0];
|
||||
while (*name != '\0') {
|
||||
/*
|
||||
* Add an entry for this interface.
|
||||
*/
|
||||
if (pcap_add_if_win32(&devlist, name, desc,
|
||||
errbuf) == -1) {
|
||||
/*
|
||||
* Add an entry for this interface.
|
||||
*/
|
||||
if (pcap_add_if_win32(&devlist, name, desc, errbuf) == -1) {
|
||||
/*
|
||||
* Failure.
|
||||
*/
|
||||
* Failure.
|
||||
*/
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
@ -277,15 +291,16 @@ pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
|
||||
}
|
||||
|
||||
if (ret == -1) {
|
||||
/*
|
||||
* We had an error; free the list we've been constructing.
|
||||
*/
|
||||
if (devlist != NULL) {
|
||||
/*
|
||||
* We had an error; free the list we've been constructing.
|
||||
*/
|
||||
if (devlist != NULL) {
|
||||
pcap_freealldevs(devlist);
|
||||
devlist = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
*alldevsp = devlist;
|
||||
free(AdaptersName);
|
||||
return (ret);
|
||||
}
|
||||
|
@ -21,7 +21,7 @@
|
||||
*/
|
||||
#ifndef lint
|
||||
static const char rcsid[] _U_ =
|
||||
"@(#) $Header: /tcpdump/master/libpcap/gencode.c,v 1.193.2.8 2004/03/29 20:53:47 guy Exp $ (LBL)";
|
||||
"@(#) $Header: /tcpdump/master/libpcap/gencode.c,v 1.221 2005/03/27 22:10:23 guy Exp $ (LBL)";
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
@ -33,7 +33,6 @@ static const char rcsid[] _U_ =
|
||||
#else /* WIN32 */
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
#endif /* WIN32 */
|
||||
|
||||
/*
|
||||
@ -59,6 +58,10 @@ static const char rcsid[] _U_ =
|
||||
#include <setjmp.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef MSDOS
|
||||
#include "pcap-dos.h"
|
||||
#endif
|
||||
|
||||
#include "pcap-int.h"
|
||||
|
||||
#include "ethertype.h"
|
||||
@ -97,14 +100,12 @@ static const char rcsid[] _U_ =
|
||||
static jmp_buf top_ctx;
|
||||
static pcap_t *bpf_pcap;
|
||||
|
||||
/* Hack for updating VLAN offsets. */
|
||||
static u_int orig_linktype = -1, orig_nl = -1, orig_nl_nosnap = -1;
|
||||
/* Hack for updating VLAN, MPLS offsets. */
|
||||
static u_int orig_linktype = -1U, orig_nl = -1U, orig_nl_nosnap = -1U;
|
||||
|
||||
/* XXX */
|
||||
#ifdef PCAP_FDDIPAD
|
||||
int pcap_fddipad = PCAP_FDDIPAD;
|
||||
#else
|
||||
int pcap_fddipad;
|
||||
static int pcap_fddipad;
|
||||
#endif
|
||||
|
||||
/* VARARGS */
|
||||
@ -123,7 +124,7 @@ bpf_error(const char *fmt, ...)
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
static void init_linktype(int);
|
||||
static void init_linktype(pcap_t *);
|
||||
|
||||
static int alloc_reg(void);
|
||||
static void free_reg(int);
|
||||
@ -133,8 +134,10 @@ static struct block *root;
|
||||
/*
|
||||
* We divy out chunks of memory rather than call malloc each time so
|
||||
* we don't have to worry about leaking memory. It's probably
|
||||
* not a big deal if all this memory was wasted but it this ever
|
||||
* not a big deal if all this memory was wasted but if this ever
|
||||
* goes into a library that would probably not be a good idea.
|
||||
*
|
||||
* XXX - this *is* in a library....
|
||||
*/
|
||||
#define NCHUNKS 16
|
||||
#define CHUNK0SIZE 1024
|
||||
@ -165,6 +168,7 @@ static struct block *gen_uncond(int);
|
||||
static inline struct block *gen_true(void);
|
||||
static inline struct block *gen_false(void);
|
||||
static struct block *gen_ether_linktype(int);
|
||||
static struct block *gen_linux_sll_linktype(int);
|
||||
static struct block *gen_linktype(int);
|
||||
static struct block *gen_snap(bpf_u_int32, bpf_u_int32, u_int);
|
||||
static struct block *gen_llc(int);
|
||||
@ -340,7 +344,7 @@ pcap_compile(pcap_t *p, struct bpf_program *program,
|
||||
}
|
||||
|
||||
lex_init(buf ? buf : "");
|
||||
init_linktype(pcap_datalink(p));
|
||||
init_linktype(p);
|
||||
(void)pcap_parse();
|
||||
|
||||
if (n_errors)
|
||||
@ -577,15 +581,15 @@ gen_ncmp(datasize, offset, mask, jtype, jvalue, reverse)
|
||||
{
|
||||
struct slist *s;
|
||||
struct block *b;
|
||||
|
||||
|
||||
s = new_stmt(BPF_LD|datasize|BPF_ABS);
|
||||
s->s.k = offset;
|
||||
|
||||
|
||||
if (mask != 0xffffffff) {
|
||||
s->next = new_stmt(BPF_ALU|BPF_AND|BPF_K);
|
||||
s->next->s.k = mask;
|
||||
}
|
||||
|
||||
|
||||
b = new_block(JMP(jtype));
|
||||
b->stmts = s;
|
||||
b->s.k = jvalue;
|
||||
@ -678,10 +682,13 @@ static u_int off_nl_nosnap;
|
||||
static int linktype;
|
||||
|
||||
static void
|
||||
init_linktype(type)
|
||||
int type;
|
||||
init_linktype(p)
|
||||
pcap_t *p;
|
||||
{
|
||||
linktype = type;
|
||||
linktype = pcap_datalink(p);
|
||||
#ifdef PCAP_FDDIPAD
|
||||
pcap_fddipad = p->fddipad;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Assume it's not raw ATM with a pseudo-header, for now.
|
||||
@ -698,7 +705,7 @@ init_linktype(type)
|
||||
orig_nl = -1;
|
||||
orig_nl_nosnap = -1;
|
||||
|
||||
switch (type) {
|
||||
switch (linktype) {
|
||||
|
||||
case DLT_ARCNET:
|
||||
off_linktype = 2;
|
||||
@ -750,6 +757,7 @@ init_linktype(type)
|
||||
return;
|
||||
|
||||
case DLT_PPP:
|
||||
case DLT_PPP_PPPD:
|
||||
case DLT_C_HDLC: /* BSD/OS Cisco HDLC */
|
||||
case DLT_PPP_SERIAL: /* NetBSD sync/async serial PPP */
|
||||
off_linktype = 2;
|
||||
@ -922,7 +930,7 @@ init_linktype(type)
|
||||
off_vpi = SUNATM_VPI_POS;
|
||||
off_vci = SUNATM_VCI_POS;
|
||||
off_proto = PROTO_POS;
|
||||
off_mac = -1; /* LLC-encapsulated, so no MAC-layer header */
|
||||
off_mac = -1; /* LLC-encapsulated, so no MAC-layer header */
|
||||
off_payload = SUNATM_PKT_BEGIN_POS;
|
||||
off_linktype = off_payload;
|
||||
off_nl = off_payload+8; /* 802.2+SNAP */
|
||||
@ -993,6 +1001,21 @@ init_linktype(type)
|
||||
off_nl_nosnap = -1;
|
||||
return;
|
||||
|
||||
case DLT_DOCSIS:
|
||||
/*
|
||||
* Currently, only raw "link[N:M]" filtering is supported.
|
||||
*/
|
||||
off_linktype = -1;
|
||||
off_nl = -1;
|
||||
off_nl_nosnap = -1;
|
||||
return;
|
||||
|
||||
case DLT_SYMANTEC_FIREWALL:
|
||||
off_linktype = 6;
|
||||
off_nl = 44; /* Ethernet II */
|
||||
off_nl_nosnap = 44; /* XXX - what does it do with 802.3 packets? */
|
||||
return;
|
||||
|
||||
case DLT_PFLOG:
|
||||
off_linktype = 0;
|
||||
/* XXX read from header? */
|
||||
@ -1000,6 +1023,25 @@ init_linktype(type)
|
||||
off_nl_nosnap = PFLOG_HDRLEN;
|
||||
return;
|
||||
|
||||
case DLT_JUNIPER_MLFR:
|
||||
case DLT_JUNIPER_MLPPP:
|
||||
off_linktype = 4;
|
||||
off_nl = 4;
|
||||
off_nl_nosnap = -1;
|
||||
return;
|
||||
|
||||
case DLT_JUNIPER_ATM1:
|
||||
off_linktype = 4; /* in reality variable between 4-8 */
|
||||
off_nl = 4;
|
||||
off_nl_nosnap = 14;
|
||||
return;
|
||||
|
||||
case DLT_JUNIPER_ATM2:
|
||||
off_linktype = 8; /* in reality variable between 8-12 */
|
||||
off_nl = 8;
|
||||
off_nl_nosnap = 18;
|
||||
return;
|
||||
|
||||
#ifdef DLT_PFSYNC
|
||||
case DLT_PFSYNC:
|
||||
off_linktype = -1;
|
||||
@ -1231,6 +1273,172 @@ gen_ether_linktype(proto)
|
||||
}
|
||||
}
|
||||
|
||||
static struct block *
|
||||
gen_linux_sll_linktype(proto)
|
||||
register int proto;
|
||||
{
|
||||
struct block *b0, *b1;
|
||||
|
||||
switch (proto) {
|
||||
|
||||
case LLCSAP_IP:
|
||||
b0 = gen_cmp(off_linktype, BPF_H, LINUX_SLL_P_802_2);
|
||||
b1 = gen_cmp(off_linktype + 2, BPF_H, (bpf_int32)
|
||||
((LLCSAP_IP << 8) | LLCSAP_IP));
|
||||
gen_and(b0, b1);
|
||||
return b1;
|
||||
|
||||
case LLCSAP_ISONS:
|
||||
/*
|
||||
* OSI protocols always use 802.2 encapsulation.
|
||||
* XXX - should we check both the DSAP and the
|
||||
* SSAP, like this, or should we check just the
|
||||
* DSAP?
|
||||
*/
|
||||
b0 = gen_cmp(off_linktype, BPF_H, LINUX_SLL_P_802_2);
|
||||
b1 = gen_cmp(off_linktype + 2, BPF_H, (bpf_int32)
|
||||
((LLCSAP_ISONS << 8) | LLCSAP_ISONS));
|
||||
gen_and(b0, b1);
|
||||
return b1;
|
||||
|
||||
case LLCSAP_NETBEUI:
|
||||
/*
|
||||
* NetBEUI always uses 802.2 encapsulation.
|
||||
* XXX - should we check both the DSAP and the
|
||||
* LSAP, like this, or should we check just the
|
||||
* DSAP?
|
||||
*/
|
||||
b0 = gen_cmp(off_linktype, BPF_H, LINUX_SLL_P_802_2);
|
||||
b1 = gen_cmp(off_linktype + 2, BPF_H, (bpf_int32)
|
||||
((LLCSAP_NETBEUI << 8) | LLCSAP_NETBEUI));
|
||||
gen_and(b0, b1);
|
||||
return b1;
|
||||
|
||||
case LLCSAP_IPX:
|
||||
/*
|
||||
* Ethernet_II frames, which are Ethernet
|
||||
* frames with a frame type of ETHERTYPE_IPX;
|
||||
*
|
||||
* Ethernet_802.3 frames, which have a frame
|
||||
* type of LINUX_SLL_P_802_3;
|
||||
*
|
||||
* Ethernet_802.2 frames, which are 802.3
|
||||
* frames with an 802.2 LLC header (i.e, have
|
||||
* a frame type of LINUX_SLL_P_802_2) and
|
||||
* with the IPX LSAP as the DSAP in the LLC
|
||||
* header;
|
||||
*
|
||||
* Ethernet_SNAP frames, which are 802.3
|
||||
* frames with an LLC header and a SNAP
|
||||
* header and with an OUI of 0x000000
|
||||
* (encapsulated Ethernet) and a protocol
|
||||
* ID of ETHERTYPE_IPX in the SNAP header.
|
||||
*
|
||||
* First, do the checks on LINUX_SLL_P_802_2
|
||||
* frames; generate the check for either
|
||||
* Ethernet_802.2 or Ethernet_SNAP frames, and
|
||||
* then put a check for LINUX_SLL_P_802_2 frames
|
||||
* before it.
|
||||
*/
|
||||
b0 = gen_cmp(off_linktype + 2, BPF_B,
|
||||
(bpf_int32)LLCSAP_IPX);
|
||||
b1 = gen_snap(0x000000, ETHERTYPE_IPX,
|
||||
off_linktype + 2);
|
||||
gen_or(b0, b1);
|
||||
b0 = gen_cmp(off_linktype, BPF_H, LINUX_SLL_P_802_2);
|
||||
gen_and(b0, b1);
|
||||
|
||||
/*
|
||||
* Now check for 802.3 frames and OR that with
|
||||
* the previous test.
|
||||
*/
|
||||
b0 = gen_cmp(off_linktype, BPF_H, LINUX_SLL_P_802_3);
|
||||
gen_or(b0, b1);
|
||||
|
||||
/*
|
||||
* Now add the check for Ethernet_II frames, and
|
||||
* do that before checking for the other frame
|
||||
* types.
|
||||
*/
|
||||
b0 = gen_cmp(off_linktype, BPF_H,
|
||||
(bpf_int32)ETHERTYPE_IPX);
|
||||
gen_or(b0, b1);
|
||||
return b1;
|
||||
|
||||
case ETHERTYPE_ATALK:
|
||||
case ETHERTYPE_AARP:
|
||||
/*
|
||||
* EtherTalk (AppleTalk protocols on Ethernet link
|
||||
* layer) may use 802.2 encapsulation.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Check for 802.2 encapsulation (EtherTalk phase 2?);
|
||||
* we check for the 802.2 protocol type in the
|
||||
* "Ethernet type" field.
|
||||
*/
|
||||
b0 = gen_cmp(off_linktype, BPF_H, LINUX_SLL_P_802_2);
|
||||
|
||||
/*
|
||||
* 802.2-encapsulated ETHERTYPE_ATALK packets are
|
||||
* SNAP packets with an organization code of
|
||||
* 0x080007 (Apple, for Appletalk) and a protocol
|
||||
* type of ETHERTYPE_ATALK (Appletalk).
|
||||
*
|
||||
* 802.2-encapsulated ETHERTYPE_AARP packets are
|
||||
* SNAP packets with an organization code of
|
||||
* 0x000000 (encapsulated Ethernet) and a protocol
|
||||
* type of ETHERTYPE_AARP (Appletalk ARP).
|
||||
*/
|
||||
if (proto == ETHERTYPE_ATALK)
|
||||
b1 = gen_snap(0x080007, ETHERTYPE_ATALK,
|
||||
off_linktype + 2);
|
||||
else /* proto == ETHERTYPE_AARP */
|
||||
b1 = gen_snap(0x000000, ETHERTYPE_AARP,
|
||||
off_linktype + 2);
|
||||
gen_and(b0, b1);
|
||||
|
||||
/*
|
||||
* Check for Ethernet encapsulation (Ethertalk
|
||||
* phase 1?); we just check for the Ethernet
|
||||
* protocol type.
|
||||
*/
|
||||
b0 = gen_cmp(off_linktype, BPF_H, (bpf_int32)proto);
|
||||
|
||||
gen_or(b0, b1);
|
||||
return b1;
|
||||
|
||||
default:
|
||||
if (proto <= ETHERMTU) {
|
||||
/*
|
||||
* This is an LLC SAP value, so the frames
|
||||
* that match would be 802.2 frames.
|
||||
* Check for the 802.2 protocol type
|
||||
* in the "Ethernet type" field, and
|
||||
* then check the DSAP.
|
||||
*/
|
||||
b0 = gen_cmp(off_linktype, BPF_H,
|
||||
LINUX_SLL_P_802_2);
|
||||
b1 = gen_cmp(off_linktype + 2, BPF_B,
|
||||
(bpf_int32)proto);
|
||||
gen_and(b0, b1);
|
||||
return b1;
|
||||
} else {
|
||||
/*
|
||||
* This is an Ethernet type, so compare
|
||||
* the length/type field with it (if
|
||||
* the frame is an 802.2 frame, the length
|
||||
* field will be <= ETHERMTU, and, as
|
||||
* "proto" is > ETHERMTU, this test
|
||||
* will fail and the frame won't match,
|
||||
* which is what we want).
|
||||
*/
|
||||
return gen_cmp(off_linktype, BPF_H,
|
||||
(bpf_int32)proto);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static struct block *
|
||||
gen_linktype(proto)
|
||||
register int proto;
|
||||
@ -1241,6 +1449,7 @@ gen_linktype(proto)
|
||||
|
||||
case DLT_EN10MB:
|
||||
return gen_ether_linktype(proto);
|
||||
/*NOTREACHED*/
|
||||
break;
|
||||
|
||||
case DLT_C_HDLC:
|
||||
@ -1252,6 +1461,7 @@ gen_linktype(proto)
|
||||
|
||||
default:
|
||||
return gen_cmp(off_linktype, BPF_H, (bpf_int32)proto);
|
||||
/*NOTREACHED*/
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@ -1265,6 +1475,7 @@ gen_linktype(proto)
|
||||
case DLT_ATM_CLIP:
|
||||
case DLT_IP_OVER_FC:
|
||||
return gen_llc(proto);
|
||||
/*NOTREACHED*/
|
||||
break;
|
||||
|
||||
case DLT_SUNATM:
|
||||
@ -1302,164 +1513,8 @@ gen_linktype(proto)
|
||||
}
|
||||
|
||||
case DLT_LINUX_SLL:
|
||||
switch (proto) {
|
||||
|
||||
case LLCSAP_IP:
|
||||
b0 = gen_cmp(off_linktype, BPF_H, LINUX_SLL_P_802_2);
|
||||
b1 = gen_cmp(off_linktype + 2, BPF_H, (bpf_int32)
|
||||
((LLCSAP_IP << 8) | LLCSAP_IP));
|
||||
gen_and(b0, b1);
|
||||
return b1;
|
||||
|
||||
case LLCSAP_ISONS:
|
||||
/*
|
||||
* OSI protocols always use 802.2 encapsulation.
|
||||
* XXX - should we check both the DSAP and the
|
||||
* LSAP, like this, or should we check just the
|
||||
* DSAP?
|
||||
*/
|
||||
b0 = gen_cmp(off_linktype, BPF_H, LINUX_SLL_P_802_2);
|
||||
b1 = gen_cmp(off_linktype + 2, BPF_H, (bpf_int32)
|
||||
((LLCSAP_ISONS << 8) | LLCSAP_ISONS));
|
||||
gen_and(b0, b1);
|
||||
return b1;
|
||||
|
||||
case LLCSAP_NETBEUI:
|
||||
/*
|
||||
* NetBEUI always uses 802.2 encapsulation.
|
||||
* XXX - should we check both the DSAP and the
|
||||
* LSAP, like this, or should we check just the
|
||||
* DSAP?
|
||||
*/
|
||||
b0 = gen_cmp(off_linktype, BPF_H, LINUX_SLL_P_802_2);
|
||||
b1 = gen_cmp(off_linktype + 2, BPF_H, (bpf_int32)
|
||||
((LLCSAP_NETBEUI << 8) | LLCSAP_NETBEUI));
|
||||
gen_and(b0, b1);
|
||||
return b1;
|
||||
|
||||
case LLCSAP_IPX:
|
||||
/*
|
||||
* Ethernet_II frames, which are Ethernet
|
||||
* frames with a frame type of ETHERTYPE_IPX;
|
||||
*
|
||||
* Ethernet_802.3 frames, which have a frame
|
||||
* type of LINUX_SLL_P_802_3;
|
||||
*
|
||||
* Ethernet_802.2 frames, which are 802.3
|
||||
* frames with an 802.2 LLC header (i.e, have
|
||||
* a frame type of LINUX_SLL_P_802_2) and
|
||||
* with the IPX LSAP as the DSAP in the LLC
|
||||
* header;
|
||||
*
|
||||
* Ethernet_SNAP frames, which are 802.3
|
||||
* frames with an LLC header and a SNAP
|
||||
* header and with an OUI of 0x000000
|
||||
* (encapsulated Ethernet) and a protocol
|
||||
* ID of ETHERTYPE_IPX in the SNAP header.
|
||||
*
|
||||
* First, do the checks on LINUX_SLL_P_802_2
|
||||
* frames; generate the check for either
|
||||
* Ethernet_802.2 or Ethernet_SNAP frames, and
|
||||
* then put a check for LINUX_SLL_P_802_2 frames
|
||||
* before it.
|
||||
*/
|
||||
b0 = gen_cmp(off_linktype + 2, BPF_B,
|
||||
(bpf_int32)LLCSAP_IPX);
|
||||
b1 = gen_snap(0x000000, ETHERTYPE_IPX,
|
||||
off_linktype + 2);
|
||||
gen_or(b0, b1);
|
||||
b0 = gen_cmp(off_linktype, BPF_H, LINUX_SLL_P_802_2);
|
||||
gen_and(b0, b1);
|
||||
|
||||
/*
|
||||
* Now check for 802.3 frames and OR that with
|
||||
* the previous test.
|
||||
*/
|
||||
b0 = gen_cmp(off_linktype, BPF_H, LINUX_SLL_P_802_3);
|
||||
gen_or(b0, b1);
|
||||
|
||||
/*
|
||||
* Now add the check for Ethernet_II frames, and
|
||||
* do that before checking for the other frame
|
||||
* types.
|
||||
*/
|
||||
b0 = gen_cmp(off_linktype, BPF_H,
|
||||
(bpf_int32)ETHERTYPE_IPX);
|
||||
gen_or(b0, b1);
|
||||
return b1;
|
||||
|
||||
case ETHERTYPE_ATALK:
|
||||
case ETHERTYPE_AARP:
|
||||
/*
|
||||
* EtherTalk (AppleTalk protocols on Ethernet link
|
||||
* layer) may use 802.2 encapsulation.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Check for 802.2 encapsulation (EtherTalk phase 2?);
|
||||
* we check for the 802.2 protocol type in the
|
||||
* "Ethernet type" field.
|
||||
*/
|
||||
b0 = gen_cmp(off_linktype, BPF_H, LINUX_SLL_P_802_2);
|
||||
|
||||
/*
|
||||
* 802.2-encapsulated ETHERTYPE_ATALK packets are
|
||||
* SNAP packets with an organization code of
|
||||
* 0x080007 (Apple, for Appletalk) and a protocol
|
||||
* type of ETHERTYPE_ATALK (Appletalk).
|
||||
*
|
||||
* 802.2-encapsulated ETHERTYPE_AARP packets are
|
||||
* SNAP packets with an organization code of
|
||||
* 0x000000 (encapsulated Ethernet) and a protocol
|
||||
* type of ETHERTYPE_AARP (Appletalk ARP).
|
||||
*/
|
||||
if (proto == ETHERTYPE_ATALK)
|
||||
b1 = gen_snap(0x080007, ETHERTYPE_ATALK,
|
||||
off_linktype + 2);
|
||||
else /* proto == ETHERTYPE_AARP */
|
||||
b1 = gen_snap(0x000000, ETHERTYPE_AARP,
|
||||
off_linktype + 2);
|
||||
gen_and(b0, b1);
|
||||
|
||||
/*
|
||||
* Check for Ethernet encapsulation (Ethertalk
|
||||
* phase 1?); we just check for the Ethernet
|
||||
* protocol type.
|
||||
*/
|
||||
b0 = gen_cmp(off_linktype, BPF_H, (bpf_int32)proto);
|
||||
|
||||
gen_or(b0, b1);
|
||||
return b1;
|
||||
|
||||
default:
|
||||
if (proto <= ETHERMTU) {
|
||||
/*
|
||||
* This is an LLC SAP value, so the frames
|
||||
* that match would be 802.2 frames.
|
||||
* Check for the 802.2 protocol type
|
||||
* in the "Ethernet type" field, and
|
||||
* then check the DSAP.
|
||||
*/
|
||||
b0 = gen_cmp(off_linktype, BPF_H,
|
||||
LINUX_SLL_P_802_2);
|
||||
b1 = gen_cmp(off_linktype + 2, BPF_B,
|
||||
(bpf_int32)proto);
|
||||
gen_and(b0, b1);
|
||||
return b1;
|
||||
} else {
|
||||
/*
|
||||
* This is an Ethernet type, so compare
|
||||
* the length/type field with it (if
|
||||
* the frame is an 802.2 frame, the length
|
||||
* field will be <= ETHERMTU, and, as
|
||||
* "proto" is > ETHERMTU, this test
|
||||
* will fail and the frame won't match,
|
||||
* which is what we want).
|
||||
*/
|
||||
return gen_cmp(off_linktype, BPF_H,
|
||||
(bpf_int32)proto);
|
||||
}
|
||||
}
|
||||
return gen_linux_sll_linktype(proto);
|
||||
/*NOTREACHED*/
|
||||
break;
|
||||
|
||||
case DLT_SLIP:
|
||||
@ -1483,9 +1538,11 @@ gen_linktype(proto)
|
||||
default:
|
||||
return gen_false(); /* always false */
|
||||
}
|
||||
/*NOTREACHED*/
|
||||
break;
|
||||
|
||||
case DLT_PPP:
|
||||
case DLT_PPP_PPPD:
|
||||
case DLT_PPP_SERIAL:
|
||||
case DLT_PPP_ETHER:
|
||||
/*
|
||||
@ -1669,6 +1726,7 @@ gen_linktype(proto)
|
||||
#endif /* INET6 */
|
||||
else
|
||||
return gen_false();
|
||||
/*NOTREACHED*/
|
||||
break;
|
||||
|
||||
case DLT_ARCNET:
|
||||
@ -1689,7 +1747,7 @@ gen_linktype(proto)
|
||||
#endif /* INET6 */
|
||||
|
||||
case ETHERTYPE_IP:
|
||||
b0 = gen_cmp(off_linktype, BPF_B,
|
||||
b0 = gen_cmp(off_linktype, BPF_B,
|
||||
(bpf_int32)ARCTYPE_IP);
|
||||
b1 = gen_cmp(off_linktype, BPF_B,
|
||||
(bpf_int32)ARCTYPE_IP_OLD);
|
||||
@ -1699,7 +1757,7 @@ gen_linktype(proto)
|
||||
case ETHERTYPE_ARP:
|
||||
b0 = gen_cmp(off_linktype, BPF_B,
|
||||
(bpf_int32)ARCTYPE_ARP);
|
||||
b1 = gen_cmp(off_linktype, BPF_B,
|
||||
b1 = gen_cmp(off_linktype, BPF_B,
|
||||
(bpf_int32)ARCTYPE_ARP_OLD);
|
||||
gen_or(b0, b1);
|
||||
return (b1);
|
||||
@ -1712,6 +1770,7 @@ gen_linktype(proto)
|
||||
return (gen_cmp(off_linktype, BPF_B,
|
||||
(bpf_int32)ARCTYPE_ATALK));
|
||||
}
|
||||
/*NOTREACHED*/
|
||||
break;
|
||||
|
||||
case DLT_LTALK:
|
||||
@ -1721,6 +1780,7 @@ gen_linktype(proto)
|
||||
default:
|
||||
return gen_false();
|
||||
}
|
||||
/*NOTREACHED*/
|
||||
break;
|
||||
|
||||
case DLT_FRELAY:
|
||||
@ -1766,10 +1826,27 @@ gen_linktype(proto)
|
||||
default:
|
||||
return gen_false();
|
||||
}
|
||||
/*NOTREACHED*/
|
||||
break;
|
||||
|
||||
case DLT_JUNIPER_MLFR:
|
||||
case DLT_JUNIPER_MLPPP:
|
||||
case DLT_JUNIPER_ATM1:
|
||||
case DLT_JUNIPER_ATM2:
|
||||
/* just lets verify the magic number for now -
|
||||
* on ATM we may have up to 6 different encapsulations on the wire
|
||||
* and need a lot of heuristics to figure out that the payload
|
||||
* might be;
|
||||
*
|
||||
* FIXME encapsulation specific BPF_ filters
|
||||
*/
|
||||
return gen_mcmp(0, BPF_W, 0x4d474300, 0xffffff00); /* compare the magic number */
|
||||
|
||||
case DLT_LINUX_IRDA:
|
||||
bpf_error("IrDA link-layer type filtering not implemented");
|
||||
bpf_error("IrDA link-layer type filtering not implemented");
|
||||
|
||||
case DLT_DOCSIS:
|
||||
bpf_error("DOCSIS link-layer type filtering not implemented");
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2504,7 +2581,7 @@ gen_dnhostop(addr, dir, base_off)
|
||||
return b1;
|
||||
|
||||
case Q_ISO:
|
||||
bpf_error("ISO host filtering not implemented");
|
||||
bpf_error("ISO host filtering not implemented");
|
||||
|
||||
default:
|
||||
abort();
|
||||
@ -2978,91 +3055,91 @@ gen_proto_abbrev(proto)
|
||||
break;
|
||||
|
||||
case Q_ISO:
|
||||
b1 = gen_linktype(LLCSAP_ISONS);
|
||||
b1 = gen_linktype(LLCSAP_ISONS);
|
||||
break;
|
||||
|
||||
case Q_ESIS:
|
||||
b1 = gen_proto(ISO9542_ESIS, Q_ISO, Q_DEFAULT);
|
||||
b1 = gen_proto(ISO9542_ESIS, Q_ISO, Q_DEFAULT);
|
||||
break;
|
||||
|
||||
case Q_ISIS:
|
||||
b1 = gen_proto(ISO10589_ISIS, Q_ISO, Q_DEFAULT);
|
||||
b1 = gen_proto(ISO10589_ISIS, Q_ISO, Q_DEFAULT);
|
||||
break;
|
||||
|
||||
case Q_ISIS_L1: /* all IS-IS Level1 PDU-Types */
|
||||
b0 = gen_proto(ISIS_L1_LAN_IIH, Q_ISIS, Q_DEFAULT);
|
||||
b1 = gen_proto(ISIS_PTP_IIH, Q_ISIS, Q_DEFAULT); /* FIXME extract the circuit-type bits */
|
||||
b0 = gen_proto(ISIS_L1_LAN_IIH, Q_ISIS, Q_DEFAULT);
|
||||
b1 = gen_proto(ISIS_PTP_IIH, Q_ISIS, Q_DEFAULT); /* FIXME extract the circuit-type bits */
|
||||
gen_or(b0, b1);
|
||||
b0 = gen_proto(ISIS_L1_LSP, Q_ISIS, Q_DEFAULT);
|
||||
b0 = gen_proto(ISIS_L1_LSP, Q_ISIS, Q_DEFAULT);
|
||||
gen_or(b0, b1);
|
||||
b0 = gen_proto(ISIS_L1_CSNP, Q_ISIS, Q_DEFAULT);
|
||||
b0 = gen_proto(ISIS_L1_CSNP, Q_ISIS, Q_DEFAULT);
|
||||
gen_or(b0, b1);
|
||||
b0 = gen_proto(ISIS_L1_PSNP, Q_ISIS, Q_DEFAULT);
|
||||
b0 = gen_proto(ISIS_L1_PSNP, Q_ISIS, Q_DEFAULT);
|
||||
gen_or(b0, b1);
|
||||
break;
|
||||
|
||||
case Q_ISIS_L2: /* all IS-IS Level2 PDU-Types */
|
||||
b0 = gen_proto(ISIS_L2_LAN_IIH, Q_ISIS, Q_DEFAULT);
|
||||
b1 = gen_proto(ISIS_PTP_IIH, Q_ISIS, Q_DEFAULT); /* FIXME extract the circuit-type bits */
|
||||
b0 = gen_proto(ISIS_L2_LAN_IIH, Q_ISIS, Q_DEFAULT);
|
||||
b1 = gen_proto(ISIS_PTP_IIH, Q_ISIS, Q_DEFAULT); /* FIXME extract the circuit-type bits */
|
||||
gen_or(b0, b1);
|
||||
b0 = gen_proto(ISIS_L2_LSP, Q_ISIS, Q_DEFAULT);
|
||||
b0 = gen_proto(ISIS_L2_LSP, Q_ISIS, Q_DEFAULT);
|
||||
gen_or(b0, b1);
|
||||
b0 = gen_proto(ISIS_L2_CSNP, Q_ISIS, Q_DEFAULT);
|
||||
b0 = gen_proto(ISIS_L2_CSNP, Q_ISIS, Q_DEFAULT);
|
||||
gen_or(b0, b1);
|
||||
b0 = gen_proto(ISIS_L2_PSNP, Q_ISIS, Q_DEFAULT);
|
||||
b0 = gen_proto(ISIS_L2_PSNP, Q_ISIS, Q_DEFAULT);
|
||||
gen_or(b0, b1);
|
||||
break;
|
||||
|
||||
case Q_ISIS_IIH: /* all IS-IS Hello PDU-Types */
|
||||
b0 = gen_proto(ISIS_L1_LAN_IIH, Q_ISIS, Q_DEFAULT);
|
||||
b1 = gen_proto(ISIS_L2_LAN_IIH, Q_ISIS, Q_DEFAULT);
|
||||
b0 = gen_proto(ISIS_L1_LAN_IIH, Q_ISIS, Q_DEFAULT);
|
||||
b1 = gen_proto(ISIS_L2_LAN_IIH, Q_ISIS, Q_DEFAULT);
|
||||
gen_or(b0, b1);
|
||||
b0 = gen_proto(ISIS_PTP_IIH, Q_ISIS, Q_DEFAULT);
|
||||
b0 = gen_proto(ISIS_PTP_IIH, Q_ISIS, Q_DEFAULT);
|
||||
gen_or(b0, b1);
|
||||
break;
|
||||
|
||||
case Q_ISIS_LSP:
|
||||
b0 = gen_proto(ISIS_L1_LSP, Q_ISIS, Q_DEFAULT);
|
||||
b1 = gen_proto(ISIS_L2_LSP, Q_ISIS, Q_DEFAULT);
|
||||
case Q_ISIS_LSP:
|
||||
b0 = gen_proto(ISIS_L1_LSP, Q_ISIS, Q_DEFAULT);
|
||||
b1 = gen_proto(ISIS_L2_LSP, Q_ISIS, Q_DEFAULT);
|
||||
gen_or(b0, b1);
|
||||
break;
|
||||
|
||||
case Q_ISIS_SNP:
|
||||
b0 = gen_proto(ISIS_L1_CSNP, Q_ISIS, Q_DEFAULT);
|
||||
b1 = gen_proto(ISIS_L2_CSNP, Q_ISIS, Q_DEFAULT);
|
||||
b0 = gen_proto(ISIS_L1_CSNP, Q_ISIS, Q_DEFAULT);
|
||||
b1 = gen_proto(ISIS_L2_CSNP, Q_ISIS, Q_DEFAULT);
|
||||
gen_or(b0, b1);
|
||||
b0 = gen_proto(ISIS_L1_PSNP, Q_ISIS, Q_DEFAULT);
|
||||
b0 = gen_proto(ISIS_L1_PSNP, Q_ISIS, Q_DEFAULT);
|
||||
gen_or(b0, b1);
|
||||
b0 = gen_proto(ISIS_L2_PSNP, Q_ISIS, Q_DEFAULT);
|
||||
b0 = gen_proto(ISIS_L2_PSNP, Q_ISIS, Q_DEFAULT);
|
||||
gen_or(b0, b1);
|
||||
break;
|
||||
|
||||
case Q_ISIS_CSNP:
|
||||
b0 = gen_proto(ISIS_L1_CSNP, Q_ISIS, Q_DEFAULT);
|
||||
b1 = gen_proto(ISIS_L2_CSNP, Q_ISIS, Q_DEFAULT);
|
||||
b0 = gen_proto(ISIS_L1_CSNP, Q_ISIS, Q_DEFAULT);
|
||||
b1 = gen_proto(ISIS_L2_CSNP, Q_ISIS, Q_DEFAULT);
|
||||
gen_or(b0, b1);
|
||||
break;
|
||||
|
||||
case Q_ISIS_PSNP:
|
||||
b0 = gen_proto(ISIS_L1_PSNP, Q_ISIS, Q_DEFAULT);
|
||||
b1 = gen_proto(ISIS_L2_PSNP, Q_ISIS, Q_DEFAULT);
|
||||
b0 = gen_proto(ISIS_L1_PSNP, Q_ISIS, Q_DEFAULT);
|
||||
b1 = gen_proto(ISIS_L2_PSNP, Q_ISIS, Q_DEFAULT);
|
||||
gen_or(b0, b1);
|
||||
break;
|
||||
|
||||
case Q_CLNP:
|
||||
b1 = gen_proto(ISO8473_CLNP, Q_ISO, Q_DEFAULT);
|
||||
b1 = gen_proto(ISO8473_CLNP, Q_ISO, Q_DEFAULT);
|
||||
break;
|
||||
|
||||
case Q_STP:
|
||||
b1 = gen_linktype(LLCSAP_8021D);
|
||||
b1 = gen_linktype(LLCSAP_8021D);
|
||||
break;
|
||||
|
||||
case Q_IPX:
|
||||
b1 = gen_linktype(LLCSAP_IPX);
|
||||
b1 = gen_linktype(LLCSAP_IPX);
|
||||
break;
|
||||
|
||||
case Q_NETBEUI:
|
||||
b1 = gen_linktype(LLCSAP_NETBEUI);
|
||||
b1 = gen_linktype(LLCSAP_NETBEUI);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -3303,8 +3380,11 @@ lookup_proto(name, proto)
|
||||
case Q_LINK:
|
||||
/* XXX should look up h/w protocol type based on linktype */
|
||||
v = pcap_nametoeproto(name);
|
||||
if (v == PROTO_UNDEF)
|
||||
bpf_error("unknown ether proto '%s'", name);
|
||||
if (v == PROTO_UNDEF) {
|
||||
v = pcap_nametollc(name);
|
||||
if (v == PROTO_UNDEF)
|
||||
bpf_error("unknown ether proto '%s'", name);
|
||||
}
|
||||
break;
|
||||
|
||||
case Q_ISO:
|
||||
@ -3696,6 +3776,7 @@ gen_proto(v, proto, dir)
|
||||
* XXX - what about SNAP-encapsulated frames?
|
||||
*/
|
||||
return gen_cmp(2, BPF_H, (0x03<<8) | v);
|
||||
/*NOTREACHED*/
|
||||
break;
|
||||
|
||||
case DLT_C_HDLC:
|
||||
@ -4136,6 +4217,7 @@ gen_mcode(s1, s2, masklen, q)
|
||||
bpf_error("Mask syntax for networks only");
|
||||
/* NOTREACHED */
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
struct block *
|
||||
@ -4770,6 +4852,7 @@ gen_broadcast(proto)
|
||||
return b2;
|
||||
}
|
||||
bpf_error("only link-layer/IP broadcast filters supported");
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/*
|
||||
@ -4986,6 +5069,7 @@ gen_multicast(proto)
|
||||
#endif /* INET6 */
|
||||
}
|
||||
bpf_error("link-layer multicast filters supported only on ethernet/FDDI/token ring/ARCNET/802.11/ATM LANE/Fibre Channel");
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/*
|
||||
@ -5036,6 +5120,31 @@ gen_inbound(dir)
|
||||
(bpf_int32)((dir == 0) ? PF_IN : PF_OUT));
|
||||
break;
|
||||
|
||||
case DLT_PPP_PPPD:
|
||||
if (dir) {
|
||||
/* match outgoing packets */
|
||||
b0 = gen_cmp(0, BPF_B, PPP_PPPD_OUT);
|
||||
} else {
|
||||
/* match incoming packets */
|
||||
b0 = gen_cmp(0, BPF_B, PPP_PPPD_IN);
|
||||
}
|
||||
break;
|
||||
|
||||
case DLT_JUNIPER_MLFR:
|
||||
case DLT_JUNIPER_MLPPP:
|
||||
case DLT_JUNIPER_ATM1:
|
||||
case DLT_JUNIPER_ATM2:
|
||||
/* juniper flags (including direction) are stored
|
||||
* the byte after the 3-byte magic number */
|
||||
if (dir) {
|
||||
/* match outgoing packets */
|
||||
b0 = gen_mcmp(3, BPF_B, 0, 0x01);
|
||||
} else {
|
||||
/* match incoming packets */
|
||||
b0 = gen_mcmp(3, BPF_B, 1, 0x01);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
bpf_error("inbound/outbound not supported on linktype %d",
|
||||
linktype);
|
||||
@ -5064,7 +5173,7 @@ gen_pf_ifname(const char *ifname)
|
||||
len-1);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
b0 = gen_bcmp(off, strlen(ifname), ifname);
|
||||
b0 = gen_bcmp(off, strlen(ifname), (const u_char *)ifname);
|
||||
return (b0);
|
||||
}
|
||||
|
||||
@ -5084,7 +5193,7 @@ gen_pf_ruleset(char *ruleset)
|
||||
/* NOTREACHED */
|
||||
}
|
||||
b0 = gen_bcmp(offsetof(struct pfloghdr, ruleset),
|
||||
strlen(ruleset), ruleset);
|
||||
strlen(ruleset), (const u_char *)ruleset);
|
||||
return (b0);
|
||||
}
|
||||
|
||||
@ -5240,7 +5349,80 @@ gen_vlan(vlan_num)
|
||||
if (vlan_num >= 0) {
|
||||
struct block *b1;
|
||||
|
||||
b1 = gen_cmp(orig_nl, BPF_H, (bpf_int32)vlan_num);
|
||||
b1 = gen_mcmp(orig_nl, BPF_H, (bpf_int32)vlan_num, 0x0fff);
|
||||
gen_and(b0, b1);
|
||||
b0 = b1;
|
||||
}
|
||||
|
||||
return (b0);
|
||||
}
|
||||
|
||||
/*
|
||||
* support for MPLS
|
||||
*/
|
||||
struct block *
|
||||
gen_mpls(label_num)
|
||||
int label_num;
|
||||
{
|
||||
struct block *b0;
|
||||
|
||||
/*
|
||||
* Change the offsets to point to the type and data fields within
|
||||
* the MPLS packet. This is somewhat of a kludge.
|
||||
*/
|
||||
if (orig_nl == (u_int)-1) {
|
||||
orig_linktype = off_linktype; /* save original values */
|
||||
orig_nl = off_nl;
|
||||
orig_nl_nosnap = off_nl_nosnap;
|
||||
|
||||
switch (linktype) {
|
||||
|
||||
case DLT_EN10MB:
|
||||
off_linktype = 16;
|
||||
off_nl_nosnap = 18;
|
||||
off_nl = 18;
|
||||
|
||||
b0 = gen_cmp(orig_linktype, BPF_H, (bpf_int32)ETHERTYPE_MPLS);
|
||||
break;
|
||||
|
||||
case DLT_PPP:
|
||||
off_linktype = 6;
|
||||
off_nl_nosnap = 8;
|
||||
off_nl = 8;
|
||||
|
||||
b0 = gen_cmp(orig_linktype, BPF_H, (bpf_int32)PPP_MPLS_UCAST);
|
||||
break;
|
||||
|
||||
case DLT_C_HDLC:
|
||||
off_linktype = 6;
|
||||
off_nl_nosnap = 8;
|
||||
off_nl = 8;
|
||||
|
||||
b0 = gen_cmp(orig_linktype, BPF_H, (bpf_int32)ETHERTYPE_MPLS);
|
||||
break;
|
||||
|
||||
/* FIXME add other DLT_s ...
|
||||
* for Frame-Relay/and ATM this may get messy due to SNAP headers
|
||||
* leave it for now */
|
||||
|
||||
default:
|
||||
bpf_error("no MPLS support for data link type %d",
|
||||
linktype);
|
||||
b0 = NULL;
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
} else {
|
||||
bpf_error("'mpls' can't be combined with 'vlan' or another 'mpls'");
|
||||
b0 = NULL;
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
/* If a specific MPLS label is requested, check it */
|
||||
if (label_num >= 0) {
|
||||
struct block *b1;
|
||||
|
||||
label_num = label_num << 12; /* label is shifted 12 bits on the wire */
|
||||
b1 = gen_mcmp(orig_nl, BPF_W, (bpf_int32)label_num, 0xfffff000); /* only compare the first 20 bits */
|
||||
gen_and(b0, b1);
|
||||
b0 = b1;
|
||||
}
|
||||
@ -5425,15 +5607,15 @@ gen_msg_abbrev(type)
|
||||
break;
|
||||
|
||||
case A_CALLPROCEED:
|
||||
b1 = gen_atmfield_code(A_MSGTYPE, CALL_PROCEED, BPF_JEQ, 0);
|
||||
b1 = gen_atmfield_code(A_MSGTYPE, CALL_PROCEED, BPF_JEQ, 0);
|
||||
break;
|
||||
|
||||
case A_CONNECT:
|
||||
b1 = gen_atmfield_code(A_MSGTYPE, CONNECT, BPF_JEQ, 0);
|
||||
break;
|
||||
break;
|
||||
|
||||
case A_CONNECTACK:
|
||||
b1 = gen_atmfield_code(A_MSGTYPE, CONNECT_ACK, BPF_JEQ, 0);
|
||||
b1 = gen_atmfield_code(A_MSGTYPE, CONNECT_ACK, BPF_JEQ, 0);
|
||||
break;
|
||||
|
||||
case A_RELEASE:
|
||||
@ -5441,7 +5623,7 @@ gen_msg_abbrev(type)
|
||||
break;
|
||||
|
||||
case A_RELEASE_DONE:
|
||||
b1 = gen_atmfield_code(A_MSGTYPE, RELEASE_DONE, BPF_JEQ, 0);
|
||||
b1 = gen_atmfield_code(A_MSGTYPE, RELEASE_DONE, BPF_JEQ, 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -5468,9 +5650,9 @@ gen_atmmulti_abbrev(type)
|
||||
if (!is_atm)
|
||||
bpf_error("'oamf4' supported only on raw ATM");
|
||||
/* OAM F4 type */
|
||||
b0 = gen_atmfield_code(A_VCI, 3, BPF_JEQ, 0);
|
||||
b0 = gen_atmfield_code(A_VCI, 3, BPF_JEQ, 0);
|
||||
b1 = gen_atmfield_code(A_VCI, 4, BPF_JEQ, 0);
|
||||
gen_or(b0, b1);
|
||||
gen_or(b0, b1);
|
||||
b0 = gen_atmfield_code(A_VPI, 0, BPF_JEQ, 0);
|
||||
gen_and(b0, b1);
|
||||
break;
|
||||
|
@ -18,7 +18,7 @@
|
||||
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* @(#) $Header: /tcpdump/master/libpcap/gencode.h,v 1.58.2.1 2004/03/28 21:45:31 fenner Exp $ (LBL)
|
||||
* @(#) $Header: /tcpdump/master/libpcap/gencode.h,v 1.60 2004/06/16 08:20:30 hannes Exp $ (LBL)
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -273,6 +273,7 @@ struct block *gen_multicast(int);
|
||||
struct block *gen_inbound(int);
|
||||
|
||||
struct block *gen_vlan(int);
|
||||
struct block *gen_mpls(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);
|
||||
|
@ -22,7 +22,7 @@
|
||||
*/
|
||||
#ifndef lint
|
||||
static const char rcsid[] _U_ =
|
||||
"@(#) $Header: /tcpdump/master/libpcap/grammar.y,v 1.79.2.3 2004/03/28 21:45:32 fenner Exp $ (LBL)";
|
||||
"@(#) $Header: /tcpdump/master/libpcap/grammar.y,v 1.86 2004/12/18 08:49:23 guy Exp $ (LBL)";
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
@ -33,7 +33,6 @@ static const char rcsid[] _U_ =
|
||||
#include <pcap-stdinc.h>
|
||||
#else /* WIN32 */
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#endif /* WIN32 */
|
||||
|
||||
@ -49,7 +48,6 @@ struct rtentry;
|
||||
#endif /* WIN32 */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <strings.h>
|
||||
|
||||
#include "pcap-int.h"
|
||||
|
||||
@ -128,7 +126,7 @@ pcap_parse()
|
||||
%token LSH RSH
|
||||
%token LEN
|
||||
%token IPV6 ICMPV6 AH ESP
|
||||
%token VLAN
|
||||
%token VLAN MPLS
|
||||
%token ISO ESIS CLNP ISIS L1 L2 IIH LSP SNP CSNP PSNP
|
||||
%token STP
|
||||
%token IPX
|
||||
@ -324,6 +322,8 @@ other: pqual TK_BROADCAST { $$ = gen_broadcast($1); }
|
||||
| OUTBOUND { $$ = gen_inbound(1); }
|
||||
| VLAN pnum { $$ = gen_vlan($2); }
|
||||
| VLAN { $$ = gen_vlan(-1); }
|
||||
| MPLS pnum { $$ = gen_mpls($2); }
|
||||
| MPLS { $$ = gen_mpls(-1); }
|
||||
| pfvar { $$ = $1; }
|
||||
;
|
||||
|
||||
|
@ -34,7 +34,7 @@
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid[] _U_ =
|
||||
"@(#) $Header: /tcpdump/master/libpcap/inet.c,v 1.58.2.1 2003/11/15 23:26:41 guy Exp $ (LBL)";
|
||||
"@(#) $Header: /tcpdump/master/libpcap/inet.c,v 1.66 2005/02/10 19:38:06 guy Exp $ (LBL)";
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
@ -46,13 +46,14 @@ static const char rcsid[] _U_ =
|
||||
#else /* WIN32 */
|
||||
|
||||
#include <sys/param.h>
|
||||
#ifndef MSDOS
|
||||
#include <sys/file.h>
|
||||
#endif
|
||||
#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> */
|
||||
@ -66,17 +67,14 @@ struct rtentry; /* declarations in <net/if.h> */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifndef WIN32
|
||||
#if !defined(WIN32) && !defined(__BORLANDC__)
|
||||
#include <unistd.h>
|
||||
#endif /* WIN32 */
|
||||
#endif /* !WIN32 && !__BORLANDC__ */
|
||||
#ifdef HAVE_LIMITS_H
|
||||
#include <limits.h>
|
||||
#else
|
||||
#define INT_MAX 2147483647
|
||||
#endif
|
||||
#ifdef HAVE_IFADDRS_H
|
||||
#include <ifaddrs.h>
|
||||
#endif
|
||||
|
||||
#include "pcap-int.h"
|
||||
|
||||
@ -132,9 +130,32 @@ 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?
|
||||
*
|
||||
* We do this check so that interfaces that ae supplied
|
||||
* by the interface enumeration mechanism we're using
|
||||
* but that don't support packet capture aren't included
|
||||
* in the list. An example of this is loopback interfaces
|
||||
* on Solaris; we don't just omit loopback interfaces
|
||||
* becaue you *can* capture on loopback interfaces on some
|
||||
* OSes.
|
||||
*/
|
||||
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?
|
||||
*/
|
||||
@ -282,7 +303,7 @@ add_or_find_if(pcap_if_t **curdev_ret, pcap_if_t **alldevs, const char *name,
|
||||
}
|
||||
|
||||
int
|
||||
add_addr_to_iflist(pcap_if_t **alldevs, char *name, u_int flags,
|
||||
add_addr_to_iflist(pcap_if_t **alldevs, const char *name, u_int flags,
|
||||
struct sockaddr *addr, size_t addr_size,
|
||||
struct sockaddr *netmask, size_t netmask_size,
|
||||
struct sockaddr *broadaddr, size_t broadaddr_size,
|
||||
@ -394,7 +415,7 @@ add_addr_to_iflist(pcap_if_t **alldevs, char *name, u_int flags,
|
||||
}
|
||||
|
||||
int
|
||||
pcap_add_if(pcap_if_t **devlist, char *name, u_int flags,
|
||||
pcap_add_if(pcap_if_t **devlist, const char *name, u_int flags,
|
||||
const char *description, char *errbuf)
|
||||
{
|
||||
pcap_if_t *curdev;
|
||||
@ -450,7 +471,7 @@ pcap_freealldevs(pcap_if_t *alldevs)
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
#if !defined(WIN32) && !defined(MSDOS)
|
||||
|
||||
/*
|
||||
* Return the name of a network interface attached to the system, or NULL
|
||||
@ -574,7 +595,7 @@ pcap_lookupnet(device, netp, maskp, errbuf)
|
||||
return (0);
|
||||
}
|
||||
|
||||
#else /* WIN32 */
|
||||
#elif defined(WIN32)
|
||||
|
||||
/*
|
||||
* Return the name of a network interface attached to the system, or NULL
|
||||
@ -597,9 +618,10 @@ pcap_lookupdev(errbuf)
|
||||
ULONG NameLength = 8192;
|
||||
static char AdaptersName[8192];
|
||||
|
||||
PacketGetAdapterNames(AdaptersName,&NameLength);
|
||||
|
||||
return (AdaptersName);
|
||||
if (PacketGetAdapterNames(AdaptersName,&NameLength) )
|
||||
return (AdaptersName);
|
||||
else
|
||||
return NULL;
|
||||
} else {
|
||||
/*
|
||||
* Windows NT (NT 4.0, W2K, WXP). Convert the names to UNICODE for backward compatibility
|
||||
@ -617,7 +639,15 @@ pcap_lookupdev(errbuf)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PacketGetAdapterNames((PTSTR)TAdaptersName,&NameLength);
|
||||
if ( !PacketGetAdapterNames((PTSTR)TAdaptersName,&NameLength) )
|
||||
{
|
||||
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"PacketGetAdapterNames: %s",
|
||||
pcap_win32strerror());
|
||||
free(TAdaptersName);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
tAstr = (char*)TAdaptersName;
|
||||
tUstr = (WCHAR*)AdaptersName;
|
||||
@ -646,6 +676,7 @@ pcap_lookupdev(errbuf)
|
||||
tAstr += strlen(tAstr) + 1;
|
||||
}
|
||||
|
||||
free(TAdaptersName);
|
||||
return (char *)(AdaptersName);
|
||||
}
|
||||
}
|
||||
@ -653,7 +684,7 @@ pcap_lookupdev(errbuf)
|
||||
|
||||
int
|
||||
pcap_lookupnet(device, netp, maskp, errbuf)
|
||||
const register char *device;
|
||||
register const char *device;
|
||||
register bpf_u_int32 *netp, *maskp;
|
||||
register char *errbuf;
|
||||
{
|
||||
@ -690,4 +721,4 @@ pcap_lookupnet(device, netp, maskp, errbuf)
|
||||
return (0);
|
||||
}
|
||||
|
||||
#endif /* WIN32 */
|
||||
#endif /* !WIN32 && !MSDOS */
|
||||
|
@ -24,7 +24,7 @@
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid[] _U_ =
|
||||
"@(#) $Header: /tcpdump/master/libpcap/nametoaddr.c,v 1.68.2.3 2003/11/19 18:13:48 guy Exp $ (LBL)";
|
||||
"@(#) $Header: /tcpdump/master/libpcap/nametoaddr.c,v 1.77 2005/03/27 22:26:25 guy Exp $ (LBL)";
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
@ -53,12 +53,19 @@ static const char rcsid[] _U_ =
|
||||
|
||||
#ifndef WIN32
|
||||
#ifdef HAVE_ETHER_HOSTTON
|
||||
/*
|
||||
* XXX - do we need any of this if <netinet/if_ether.h> doesn't declare
|
||||
* 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 */
|
||||
#ifdef NETINET_ETHER_H_DECLARES_ETHER_HOSTTON
|
||||
#include <netinet/ether.h>
|
||||
#endif /* NETINET_ETHER_H_DECLARES_ETHER_HOSTTON */
|
||||
#endif /* HAVE_ETHER_HOSTTON */
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
@ -124,6 +131,7 @@ pcap_nametoaddrinfo(const char *name)
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = PF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM; /*not really*/
|
||||
hints.ai_protocol = IPPROTO_TCP; /*not really*/
|
||||
error = getaddrinfo(name, NULL, &hints, &res);
|
||||
if (error)
|
||||
return NULL;
|
||||
@ -267,6 +275,30 @@ pcap_nametoeproto(const char *s)
|
||||
return PROTO_UNDEF;
|
||||
}
|
||||
|
||||
#include "llc.h"
|
||||
|
||||
/* Static data base of LLC values. */
|
||||
static struct eproto llc_db[] = {
|
||||
{ "iso", LLCSAP_ISONS },
|
||||
{ "stp", LLCSAP_8021D },
|
||||
{ "ipx", LLCSAP_IPX },
|
||||
{ "netbeui", LLCSAP_NETBEUI },
|
||||
{ (char *)0, 0 }
|
||||
};
|
||||
|
||||
int
|
||||
pcap_nametollc(const char *s)
|
||||
{
|
||||
struct eproto *p = llc_db;
|
||||
|
||||
while (p->s != 0) {
|
||||
if (strcmp(p->s, s) == 0)
|
||||
return p->p;
|
||||
p += 1;
|
||||
}
|
||||
return PROTO_UNDEF;
|
||||
}
|
||||
|
||||
/* Hex digit to integer. */
|
||||
static inline int
|
||||
xdtoi(c)
|
||||
@ -380,18 +412,8 @@ pcap_ether_hostton(const char *name)
|
||||
}
|
||||
#else
|
||||
|
||||
/*
|
||||
* XXX - perhaps this should, instead, be declared in "lbl/os-XXX.h" files,
|
||||
* for those OS versions that don't declare it, rather than being declared
|
||||
* here? That way, for example, we could declare it on FreeBSD 2.x (which
|
||||
* doesn't declare it), but not on FreeBSD 3.x (which declares it like
|
||||
* this) or FreeBSD 4.x (which declares it with its first argument as
|
||||
* "const char *", so no matter how we declare it here, it'll fail to
|
||||
* compile on one of 3.x or 4.x).
|
||||
*/
|
||||
#if !defined(sgi) && !defined(__NetBSD__) && !defined(__FreeBSD__) && \
|
||||
!defined(_UNICOSMP)
|
||||
extern int ether_hostton(char *, struct ether_addr *);
|
||||
#if !defined(HAVE_DECL_ETHER_HOSTTON) || !HAVE_DECL_ETHER_HOSTTON
|
||||
extern int ether_hostton(const char *, struct ether_addr *);
|
||||
#endif
|
||||
|
||||
/* Use the os supplied routines */
|
||||
|
@ -22,7 +22,7 @@
|
||||
*/
|
||||
#ifndef lint
|
||||
static const char rcsid[] _U_ =
|
||||
"@(#) $Header: /tcpdump/master/libpcap/optimize.c,v 1.76.2.3 2003/12/22 00:26:36 guy Exp $ (LBL)";
|
||||
"@(#) $Header: /tcpdump/master/libpcap/optimize.c,v 1.85 2005/04/04 08:42:18 guy Exp $ (LBL)";
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
@ -32,6 +32,7 @@ static const char rcsid[] _U_ =
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
@ -47,11 +48,25 @@ static const char rcsid[] _U_ =
|
||||
extern int dflag;
|
||||
#endif
|
||||
|
||||
#if defined(MSDOS) && !defined(__DJGPP__)
|
||||
extern int _w32_ffs (int mask);
|
||||
#define ffs _w32_ffs
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Represents a deleted instruction.
|
||||
*/
|
||||
#define NOP -1
|
||||
|
||||
/*
|
||||
* Register numbers for use-def values.
|
||||
* 0 through BPF_MEMWORDS-1 represent the corresponding scratch memory
|
||||
* location. A_ATOM is the accumulator and X_ATOM is the index
|
||||
* register.
|
||||
*/
|
||||
#define A_ATOM BPF_MEMWORDS
|
||||
#define X_ATOM (BPF_MEMWORDS+1)
|
||||
|
||||
#define NOP -1
|
||||
|
||||
/*
|
||||
* This define is used to represent *both* the accumulator and
|
||||
* x register in use-def computations.
|
||||
@ -419,6 +434,17 @@ atomdef(s)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute the sets of registers used, defined, and killed by 'b'.
|
||||
*
|
||||
* "Used" means that a statement in 'b' uses the register before any
|
||||
* statement in 'b' defines it, i.e. it uses the value left in
|
||||
* that register by a predecessor block of this block.
|
||||
* "Defined" means that a statement in 'b' defines it.
|
||||
* "Killed" means that a statement in 'b' defines it before any
|
||||
* statement in 'b' uses it, i.e. it kills the value left in that
|
||||
* register by a predecessor block of this block.
|
||||
*/
|
||||
static void
|
||||
compute_local_ud(b)
|
||||
struct block *b;
|
||||
@ -452,8 +478,26 @@ compute_local_ud(b)
|
||||
def |= ATOMMASK(atom);
|
||||
}
|
||||
}
|
||||
if (!ATOMELEM(def, A_ATOM) && BPF_CLASS(b->s.code) == BPF_JMP)
|
||||
use |= ATOMMASK(A_ATOM);
|
||||
if (BPF_CLASS(b->s.code) == BPF_JMP) {
|
||||
/*
|
||||
* XXX - what about RET?
|
||||
*/
|
||||
atom = atomuse(&b->s);
|
||||
if (atom >= 0) {
|
||||
if (atom == AX_ATOM) {
|
||||
if (!ATOMELEM(def, X_ATOM))
|
||||
use |= ATOMMASK(X_ATOM);
|
||||
if (!ATOMELEM(def, A_ATOM))
|
||||
use |= ATOMMASK(A_ATOM);
|
||||
}
|
||||
else if (atom < N_ATOMS) {
|
||||
if (!ATOMELEM(def, atom))
|
||||
use |= ATOMMASK(atom);
|
||||
}
|
||||
else
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
b->def = def;
|
||||
b->kill = kill;
|
||||
@ -664,13 +708,21 @@ opt_peep(b)
|
||||
return;
|
||||
|
||||
last = s;
|
||||
while (1) {
|
||||
for (/*empty*/; /*empty*/; s = next) {
|
||||
/*
|
||||
* Skip over nops.
|
||||
*/
|
||||
s = this_op(s);
|
||||
if (s == 0)
|
||||
break;
|
||||
break; /* nothing left in the block */
|
||||
|
||||
/*
|
||||
* Find the next real instruction after that one
|
||||
* (skipping nops).
|
||||
*/
|
||||
next = this_op(s->next);
|
||||
if (next == 0)
|
||||
break;
|
||||
break; /* no next instruction */
|
||||
last = next;
|
||||
|
||||
/*
|
||||
@ -707,29 +759,38 @@ opt_peep(b)
|
||||
* any local dependencies.
|
||||
*/
|
||||
if (ATOMELEM(b->out_use, X_ATOM))
|
||||
break;
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Check that the instruction following the ldi
|
||||
* is an addx, or it's an ldxms with an addx
|
||||
* following it (with 0 or more nops between the
|
||||
* ldxms and addx).
|
||||
*/
|
||||
if (next->s.code != (BPF_LDX|BPF_MSH|BPF_B))
|
||||
add = next;
|
||||
else
|
||||
add = this_op(next->next);
|
||||
if (add == 0 || add->s.code != (BPF_ALU|BPF_ADD|BPF_X))
|
||||
break;
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Check that a tax follows that (with 0 or more
|
||||
* nops between them).
|
||||
*/
|
||||
tax = this_op(add->next);
|
||||
if (tax == 0 || tax->s.code != (BPF_MISC|BPF_TAX))
|
||||
break;
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Check that an ild follows that (with 0 or more
|
||||
* nops between them).
|
||||
*/
|
||||
ild = this_op(tax->next);
|
||||
if (ild == 0 || BPF_CLASS(ild->s.code) != BPF_LD ||
|
||||
BPF_MODE(ild->s.code) != BPF_IND)
|
||||
break;
|
||||
continue;
|
||||
/*
|
||||
* XXX We need to check that X is not
|
||||
* subsequently used. We know we can eliminate the
|
||||
* accumulator modifications since it is defined
|
||||
* by the last stmt of this sequence.
|
||||
*
|
||||
* We want to turn this sequence:
|
||||
*
|
||||
* (004) ldi #0x2 {s}
|
||||
@ -746,6 +807,16 @@ opt_peep(b)
|
||||
* (007) nop
|
||||
* (008) ild [x+2]
|
||||
*
|
||||
* XXX We need to check that X is not
|
||||
* subsequently used, because we want to change
|
||||
* what'll be in it after this sequence.
|
||||
*
|
||||
* We know we can eliminate the accumulator
|
||||
* modifications earlier in the sequence since
|
||||
* it is defined by the last stmt of this sequence
|
||||
* (i.e., the last statement of the sequence loads
|
||||
* a value into the accumulator, so we can eliminate
|
||||
* earlier operations on the accumulator).
|
||||
*/
|
||||
ild->s.k += s->s.k;
|
||||
s->s.code = NOP;
|
||||
@ -753,19 +824,29 @@ opt_peep(b)
|
||||
tax->s.code = NOP;
|
||||
done = 0;
|
||||
}
|
||||
s = next;
|
||||
}
|
||||
/*
|
||||
* If we have a subtract to do a comparison, and the X register
|
||||
* is a known constant, we can merge this value into the
|
||||
* comparison.
|
||||
* If the comparison at the end of a block is an equality
|
||||
* comparison against a constant, and nobody uses the value
|
||||
* we leave in the A register at the end of a block, and
|
||||
* the operation preceding the comparison is an arithmetic
|
||||
* operation, we can sometime optimize it away.
|
||||
*/
|
||||
if (BPF_OP(b->s.code) == BPF_JEQ) {
|
||||
if (last->s.code == (BPF_ALU|BPF_SUB|BPF_X) &&
|
||||
!ATOMELEM(b->out_use, A_ATOM)) {
|
||||
if (b->s.code == (BPF_JMP|BPF_JEQ|BPF_K) &&
|
||||
!ATOMELEM(b->out_use, A_ATOM)) {
|
||||
/*
|
||||
* We can optimize away certain subtractions of the
|
||||
* X register.
|
||||
*/
|
||||
if (last->s.code == (BPF_ALU|BPF_SUB|BPF_X)) {
|
||||
val = b->val[X_ATOM];
|
||||
if (vmap[val].is_const) {
|
||||
/*
|
||||
* If we have a subtract to do a comparison,
|
||||
* and the X register is a known constant,
|
||||
* we can merge this value into the
|
||||
* comparison:
|
||||
*
|
||||
* sub x -> nop
|
||||
* jeq #y jeq #(x+y)
|
||||
*/
|
||||
@ -774,37 +855,45 @@ opt_peep(b)
|
||||
done = 0;
|
||||
} else if (b->s.k == 0) {
|
||||
/*
|
||||
* sub #x -> nop
|
||||
* jeq #0 jeq #x
|
||||
* If the X register isn't a constant,
|
||||
* and the comparison in the test is
|
||||
* against 0, we can compare with the
|
||||
* X register, instead:
|
||||
*
|
||||
* 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;
|
||||
b->s.code = BPF_JMP|BPF_JEQ|BPF_X;
|
||||
done = 0;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Likewise, a constant subtract can be simplified.
|
||||
* Likewise, a constant subtract can be simplified:
|
||||
*
|
||||
* sub #x -> nop
|
||||
* jeq #y -> jeq #(x+y)
|
||||
*/
|
||||
else if (last->s.code == (BPF_ALU|BPF_SUB|BPF_K) &&
|
||||
!ATOMELEM(b->out_use, A_ATOM)) {
|
||||
|
||||
else if (last->s.code == (BPF_ALU|BPF_SUB|BPF_K)) {
|
||||
last->s.code = NOP;
|
||||
b->s.k += last->s.k;
|
||||
done = 0;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* and #k nop
|
||||
* jeq #0 -> jset #k
|
||||
*/
|
||||
if (last->s.code == (BPF_ALU|BPF_AND|BPF_K) &&
|
||||
!ATOMELEM(b->out_use, A_ATOM) && b->s.k == 0) {
|
||||
b->s.k = last->s.k;
|
||||
b->s.code = BPF_JMP|BPF_K|BPF_JSET;
|
||||
last->s.code = NOP;
|
||||
done = 0;
|
||||
opt_not(b);
|
||||
/*
|
||||
* And, similarly, a constant AND can be simplified
|
||||
* if we're testing against 0, i.e.:
|
||||
*
|
||||
* and #k nop
|
||||
* jeq #0 -> jset #k
|
||||
*/
|
||||
else if (last->s.code == (BPF_ALU|BPF_AND|BPF_K) &&
|
||||
b->s.k == 0) {
|
||||
b->s.k = last->s.k;
|
||||
b->s.code = BPF_JMP|BPF_K|BPF_JSET;
|
||||
last->s.code = NOP;
|
||||
done = 0;
|
||||
opt_not(b);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* jset #0 -> never
|
||||
@ -1102,7 +1191,7 @@ opt_blk(b, do_stmts)
|
||||
struct slist *s;
|
||||
struct edge *p;
|
||||
int i;
|
||||
bpf_int32 aval;
|
||||
bpf_int32 aval, xval;
|
||||
|
||||
#if 0
|
||||
for (s = b->stmts; s && s->next; s = s->next)
|
||||
@ -1114,16 +1203,30 @@ opt_blk(b, do_stmts)
|
||||
|
||||
/*
|
||||
* Initialize the atom values.
|
||||
* If we have no predecessors, everything is undefined.
|
||||
* Otherwise, we inherent our values from our predecessors.
|
||||
* If any register has an ambiguous value (i.e. control paths are
|
||||
* merging) give it the undefined value of 0.
|
||||
*/
|
||||
p = b->in_edges;
|
||||
if (p == 0)
|
||||
if (p == 0) {
|
||||
/*
|
||||
* We have no predecessors, so everything is undefined
|
||||
* upon entry to this block.
|
||||
*/
|
||||
memset((char *)b->val, 0, sizeof(b->val));
|
||||
else {
|
||||
} else {
|
||||
/*
|
||||
* Inherit values from our predecessors.
|
||||
*
|
||||
* First, get the values from the predecessor along the
|
||||
* first edge leading to this node.
|
||||
*/
|
||||
memcpy((char *)b->val, (char *)p->pred->val, sizeof(b->val));
|
||||
/*
|
||||
* Now look at all the other nodes leading to this node.
|
||||
* If, for the predecessor along that edge, a register
|
||||
* has a different value from the one we have (i.e.,
|
||||
* control paths are merging, and the merging paths
|
||||
* assign different values to that register), give the
|
||||
* register the undefined value of 0.
|
||||
*/
|
||||
while ((p = p->next) != NULL) {
|
||||
for (i = 0; i < N_ATOMS; ++i)
|
||||
if (b->val[i] != p->pred->val[i])
|
||||
@ -1131,17 +1234,36 @@ opt_blk(b, do_stmts)
|
||||
}
|
||||
}
|
||||
aval = b->val[A_ATOM];
|
||||
xval = b->val[X_ATOM];
|
||||
for (s = b->stmts; s; s = s->next)
|
||||
opt_stmt(&s->s, b->val, do_stmts);
|
||||
|
||||
/*
|
||||
* This is a special case: if we don't use anything from this
|
||||
* block, and we load the accumulator with value that is
|
||||
* already there, or if this block is a return,
|
||||
* block, and we load the accumulator or index register with a
|
||||
* value that is already there, or if this block is a return,
|
||||
* eliminate all the statements.
|
||||
*
|
||||
* XXX - what if it does a store?
|
||||
*
|
||||
* XXX - why does it matter whether we use anything from this
|
||||
* block? If the accumulator or index register doesn't change
|
||||
* its value, isn't that OK even if we use that value?
|
||||
*
|
||||
* XXX - if we load the accumulator with a different value,
|
||||
* and the block ends with a conditional branch, we obviously
|
||||
* can't eliminate it, as the branch depends on that value.
|
||||
* For the index register, the conditional branch only depends
|
||||
* on the index register value if the test is against the index
|
||||
* register value rather than a constant; if nothing uses the
|
||||
* value we put into the index register, and we're not testing
|
||||
* against the index register's value, and there aren't any
|
||||
* other problems that would keep us from eliminating this
|
||||
* block, can we eliminate it?
|
||||
*/
|
||||
if (do_stmts &&
|
||||
((b->out_use == 0 && aval != 0 &&b->val[A_ATOM] == aval) ||
|
||||
((b->out_use == 0 && aval != 0 && b->val[A_ATOM] == aval &&
|
||||
xval != 0 && b->val[X_ATOM] == xval) ||
|
||||
BPF_CLASS(b->s.code) == BPF_RET)) {
|
||||
if (b->stmts != 0) {
|
||||
b->stmts = 0;
|
||||
@ -1212,9 +1334,9 @@ fold_edge(child, ep)
|
||||
|
||||
if (oval0 == oval1)
|
||||
/*
|
||||
* The operands are identical, so the
|
||||
* result is true if a true branch was
|
||||
* taken to get here, otherwise false.
|
||||
* The operands of the branch instructions are
|
||||
* identical, so the result is true if a true
|
||||
* branch was taken to get here, otherwise false.
|
||||
*/
|
||||
return sense ? JT(child) : JF(child);
|
||||
|
||||
@ -1222,8 +1344,16 @@ fold_edge(child, ep)
|
||||
/*
|
||||
* At this point, we only know the comparison if we
|
||||
* came down the true branch, and it was an equality
|
||||
* comparison with a constant. We rely on the fact that
|
||||
* distinct constants have distinct value numbers.
|
||||
* comparison with a constant.
|
||||
*
|
||||
* I.e., if we came down the true branch, and the branch
|
||||
* was an equality comparison with a constant, we know the
|
||||
* accumulator contains that constant. If we came down
|
||||
* the false branch, or the comparison wasn't with a
|
||||
* constant, we don't know what was in the accumulator.
|
||||
*
|
||||
* We rely on the fact that distinct constants have distinct
|
||||
* value numbers.
|
||||
*/
|
||||
return JF(child);
|
||||
|
||||
|
@ -20,7 +20,7 @@
|
||||
*/
|
||||
#ifndef lint
|
||||
static const char rcsid[] _U_ =
|
||||
"@(#) $Header: /tcpdump/master/libpcap/pcap-bpf.c,v 1.67.2.4 2003/11/22 00:06:28 guy Exp $ (LBL)";
|
||||
"@(#) $Header: /tcpdump/master/libpcap/pcap-bpf.c,v 1.86 2005/02/26 21:58:05 guy Exp $ (LBL)";
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
@ -142,7 +142,11 @@ pcap_read_bpf(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
int cc;
|
||||
int n = 0;
|
||||
register u_char *bp, *ep;
|
||||
u_char *datap;
|
||||
struct bpf_insn *fcode;
|
||||
#ifdef PCAP_FDDIPAD
|
||||
register int pad;
|
||||
#endif
|
||||
|
||||
fcode = p->md.use_bpf ? NULL : p->fcode.bf_insns;
|
||||
again:
|
||||
@ -224,6 +228,9 @@ pcap_read_bpf(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
*/
|
||||
#define bhp ((struct bpf_hdr *)bp)
|
||||
ep = bp + cc;
|
||||
#ifdef PCAP_FDDIPAD
|
||||
pad = p->fddipad;
|
||||
#endif
|
||||
while (bp < ep) {
|
||||
register int caplen, hdrlen;
|
||||
|
||||
@ -249,31 +256,48 @@ pcap_read_bpf(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
|
||||
caplen = bhp->bh_caplen;
|
||||
hdrlen = bhp->bh_hdrlen;
|
||||
datap = bp + hdrlen;
|
||||
/*
|
||||
* Short-circuit evaluation: if using BPF filter
|
||||
* in kernel, no need to do it now.
|
||||
*
|
||||
#ifdef PCAP_FDDIPAD
|
||||
* Note: the filter code was generated assuming
|
||||
* that p->fddipad was the amount of padding
|
||||
* before the header, as that's what's required
|
||||
* in the kernel, so we run the filter before
|
||||
* skipping that padding.
|
||||
#endif
|
||||
*/
|
||||
if (fcode == NULL ||
|
||||
bpf_filter(fcode, bp + hdrlen, bhp->bh_datalen, caplen)) {
|
||||
bpf_filter(fcode, datap, bhp->bh_datalen, caplen)) {
|
||||
struct pcap_pkthdr pkthdr;
|
||||
|
||||
pkthdr.ts.tv_sec = bhp->bh_tstamp.tv_sec;
|
||||
#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;
|
||||
pkthdr.ts.tv_usec = bhp->bh_tstamp.tv_usec/1000;
|
||||
#else
|
||||
pkthdr.ts.tv_usec = bhp->bh_tstamp.tv_usec;
|
||||
#endif
|
||||
/*
|
||||
* XXX A bpf_hdr matches a pcap_pkthdr.
|
||||
*/
|
||||
(*callback)(user, (struct pcap_pkthdr*)bp, bp + hdrlen);
|
||||
#ifdef PCAP_FDDIPAD
|
||||
if (caplen > pad)
|
||||
pkthdr.caplen = caplen - pad;
|
||||
else
|
||||
pkthdr.caplen = 0;
|
||||
if (bhp->bh_datalen > pad)
|
||||
pkthdr.len = bhp->bh_datalen - pad;
|
||||
else
|
||||
pkthdr.len = 0;
|
||||
datap += pad;
|
||||
#else
|
||||
pkthdr.caplen = caplen;
|
||||
pkthdr.len = bhp->bh_datalen;
|
||||
#endif
|
||||
(*callback)(user, &pkthdr, datap);
|
||||
bp += BPF_WORDALIGN(caplen + hdrlen);
|
||||
if (++n >= cnt && cnt > 0) {
|
||||
p->bp = bp;
|
||||
@ -292,6 +316,55 @@ pcap_read_bpf(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
return (n);
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_inject_bpf(pcap_t *p, const void *buf, size_t size)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = write(p->fd, buf, size);
|
||||
#ifdef __APPLE__
|
||||
if (ret == -1 && errno == EAFNOSUPPORT) {
|
||||
/*
|
||||
* In Mac OS X, there's a bug wherein setting the
|
||||
* BIOCSHDRCMPLT flag causes writes to fail; see,
|
||||
* for example:
|
||||
*
|
||||
* http://cerberus.sourcefire.com/~jeff/archives/patches/macosx/BIOCSHDRCMPLT-10.3.3.patch
|
||||
*
|
||||
* So, if, on OS X, we get EAFNOSUPPORT from the write, we
|
||||
* assume it's due to that bug, and turn off that flag
|
||||
* and try again. If we succeed, it either means that
|
||||
* somebody applied the fix from that URL, or other patches
|
||||
* for that bug from
|
||||
*
|
||||
* http://cerberus.sourcefire.com/~jeff/archives/patches/macosx/
|
||||
*
|
||||
* and are running a Darwin kernel with those fixes, or
|
||||
* that Apple fixed the problem in some OS X release.
|
||||
*/
|
||||
u_int spoof_eth_src = 0;
|
||||
|
||||
if (ioctl(p->fd, BIOCSHDRCMPLT, &spoof_eth_src) == -1) {
|
||||
(void)snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"send: can't turn off BIOCSHDRCMPLT: %s",
|
||||
pcap_strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Now try the write again.
|
||||
*/
|
||||
ret = write(p->fd, buf, size);
|
||||
}
|
||||
#endif /* __APPLE__ */
|
||||
if (ret == -1) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
|
||||
pcap_strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
#ifdef _AIX
|
||||
static int
|
||||
bpf_odminit(char *errbuf)
|
||||
@ -467,7 +540,23 @@ bpf_open(pcap_t *p, char *errbuf)
|
||||
*/
|
||||
do {
|
||||
(void)snprintf(device, sizeof(device), "/dev/bpf%d", n++);
|
||||
fd = open(device, O_RDONLY);
|
||||
/*
|
||||
* Initially try a read/write open (to allow the inject
|
||||
* method to work). If that fails due to permission
|
||||
* issues, fall back to read-only. This allows a
|
||||
* non-root user to be granted specific access to pcap
|
||||
* capabilities via file permissions.
|
||||
*
|
||||
* XXX - we should have an API that has a flag that
|
||||
* controls whether to open read-only or read-write,
|
||||
* so that denial of permission to send (or inability
|
||||
* to send, if sending packets isn't supported on
|
||||
* the device in question) can be indicated at open
|
||||
* time.
|
||||
*/
|
||||
fd = open(device, O_RDWR);
|
||||
if (fd == -1 && errno == EACCES)
|
||||
fd = open(device, O_RDONLY);
|
||||
} while (fd < 0 && errno == EBUSY);
|
||||
|
||||
/*
|
||||
@ -480,25 +569,14 @@ 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).
|
||||
* We include the OS's <net/bpf.h>, not our "pcap-bpf.h", so we probably
|
||||
* don't get DLT_DOCSIS defined.
|
||||
*/
|
||||
#ifndef DLT_DOCSIS
|
||||
#define DLT_DOCSIS 143
|
||||
#endif
|
||||
|
||||
pcap_t *
|
||||
pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||
char *ebuf)
|
||||
@ -508,9 +586,14 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||
struct bpf_version bv;
|
||||
#ifdef BIOCGDLTLIST
|
||||
struct bpf_dltlist bdl;
|
||||
#endif
|
||||
#if defined(BIOCGHDRCMPLT) && defined(BIOCSHDRCMPLT)
|
||||
u_int spoof_eth_src = 1;
|
||||
#endif
|
||||
u_int v;
|
||||
pcap_t *p;
|
||||
struct bpf_insn total_insn;
|
||||
struct bpf_program total_prog;
|
||||
struct utsname osinfo;
|
||||
|
||||
#ifdef HAVE_DAG_API
|
||||
@ -643,6 +726,12 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||
v = DLT_CHDLC;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#ifdef PCAP_FDDIPAD
|
||||
if (v == DLT_FDDI)
|
||||
p->fddipad = PCAP_FDDIPAD:
|
||||
else
|
||||
p->fddipad = 0;
|
||||
#endif
|
||||
p->linktype = v;
|
||||
|
||||
@ -653,7 +742,10 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||
* not fatal; we just don't get to use the feature later.
|
||||
*/
|
||||
if (ioctl(fd, BIOCGDLTLIST, (caddr_t)&bdl) == 0) {
|
||||
bdl.bfl_list = (u_int *) malloc(sizeof(u_int) * bdl.bfl_len);
|
||||
u_int i;
|
||||
int is_ethernet;
|
||||
|
||||
bdl.bfl_list = (u_int *) malloc(sizeof(u_int) * bdl.bfl_len + 1);
|
||||
if (bdl.bfl_list == NULL) {
|
||||
(void)snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
|
||||
pcap_strerror(errno));
|
||||
@ -663,9 +755,44 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
* OK, for real Ethernet devices, add DLT_DOCSIS to the
|
||||
* list, so that an application can let you choose it,
|
||||
* in case you're capturing DOCSIS traffic that a Cisco
|
||||
* Cable Modem Termination System is putting out onto
|
||||
* an Ethernet (it doesn't put an Ethernet header onto
|
||||
* the wire, it puts raw DOCSIS frames out on the wire
|
||||
* inside the low-level Ethernet framing).
|
||||
*
|
||||
* A "real Ethernet device" is defined here as a device
|
||||
* that has a link-layer type of DLT_EN10MB and that has
|
||||
* no alternate link-layer types; that's done to exclude
|
||||
* 802.11 interfaces (which might or might not be the
|
||||
* right thing to do, but I suspect it is - Ethernet <->
|
||||
* 802.11 bridges would probably badly mishandle frames
|
||||
* that don't have Ethernet headers).
|
||||
*/
|
||||
if (p->linktype == DLT_EN10MB) {
|
||||
is_ethernet = 1;
|
||||
for (i = 0; i < bdl.bfl_len; i++) {
|
||||
if (bdl.bfl_list[i] != DLT_EN10MB) {
|
||||
is_ethernet = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (is_ethernet) {
|
||||
/*
|
||||
* We reserved one more slot at the end of
|
||||
* the list.
|
||||
*/
|
||||
bdl.bfl_list[bdl.bfl_len] = DLT_DOCSIS;
|
||||
bdl.bfl_len++;
|
||||
}
|
||||
}
|
||||
p->dlt_count = bdl.bfl_len;
|
||||
p->dlt_list = bdl.bfl_list;
|
||||
} else {
|
||||
@ -677,6 +804,42 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If this is an Ethernet device, and we don't have a DLT_ list,
|
||||
* give it a list with DLT_EN10MB and DLT_DOCSIS. (That'd give
|
||||
* 802.11 interfaces DLT_DOCSIS, which isn't the right thing to
|
||||
* do, but there's not much we can do about that without finding
|
||||
* some other way of determining whether it's an Ethernet or 802.11
|
||||
* device.)
|
||||
*/
|
||||
if (p->linktype == DLT_EN10MB && p->dlt_count == 0) {
|
||||
p->dlt_list = (u_int *) malloc(sizeof(u_int) * 2);
|
||||
/*
|
||||
* If that fails, just leave the list empty.
|
||||
*/
|
||||
if (p->dlt_list != NULL) {
|
||||
p->dlt_list[0] = DLT_EN10MB;
|
||||
p->dlt_list[1] = DLT_DOCSIS;
|
||||
p->dlt_count = 2;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(BIOCGHDRCMPLT) && defined(BIOCSHDRCMPLT)
|
||||
/*
|
||||
* Do a BIOCSHDRCMPLT, if defined, to turn that flag on, so
|
||||
* the link-layer source address isn't forcibly overwritten.
|
||||
* (Should we ignore errors? Should we do this only if
|
||||
* we're open for writing?)
|
||||
*
|
||||
* XXX - I seem to remember some packet-sending bug in some
|
||||
* BSDs - check CVS log for "bpf.c"?
|
||||
*/
|
||||
if (ioctl(fd, BIOCSHDRCMPLT, &spoof_eth_src) == -1) {
|
||||
(void)snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
||||
"BIOCSHDRCMPLT: %s", pcap_strerror(errno));
|
||||
goto bad;
|
||||
}
|
||||
#endif
|
||||
/* set timeout */
|
||||
if (to_ms != 0) {
|
||||
/*
|
||||
@ -777,6 +940,28 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||
memset(p->buffer, 0x0, p->bufsize);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If there's no filter program installed, there's
|
||||
* no indication to the kernel of what the snapshot
|
||||
* length should be, so no snapshotting is done.
|
||||
*
|
||||
* Therefore, when we open the device, we install
|
||||
* an "accept everything" filter with the specified
|
||||
* snapshot length.
|
||||
*/
|
||||
total_insn.code = (u_short)(BPF_RET | BPF_K);
|
||||
total_insn.jt = 0;
|
||||
total_insn.jf = 0;
|
||||
total_insn.k = snaplen;
|
||||
|
||||
total_prog.bf_len = 1;
|
||||
total_prog.bf_insns = &total_insn;
|
||||
if (ioctl(p->fd, BIOCSETF, (caddr_t)&total_prog) < 0) {
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCSETF: %s",
|
||||
pcap_strerror(errno));
|
||||
goto bad;
|
||||
}
|
||||
|
||||
/*
|
||||
* On most BPF platforms, either you can do a "select()" or
|
||||
* "poll()" on a BPF file descriptor and it works correctly,
|
||||
@ -818,8 +1003,8 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||
* 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))
|
||||
(strncmp(osinfo.release, "4.3-", 4) == 0 ||
|
||||
strncmp(osinfo.release, "4.4-", 4) == 0))
|
||||
p->selectable_fd = -1;
|
||||
else
|
||||
p->selectable_fd = p->fd;
|
||||
@ -832,20 +1017,19 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||
}
|
||||
|
||||
p->read_op = pcap_read_bpf;
|
||||
p->inject_op = pcap_inject_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;
|
||||
p->close_op = pcap_close_common;
|
||||
|
||||
return (p);
|
||||
bad:
|
||||
(void)close(fd);
|
||||
#ifdef BIOCGDLTLIST
|
||||
if (bdl.bfl_list != NULL)
|
||||
free(bdl.bfl_list);
|
||||
#endif
|
||||
if (p->dlt_list != NULL)
|
||||
free(p->dlt_list);
|
||||
free(p);
|
||||
return (NULL);
|
||||
}
|
||||
@ -893,6 +1077,14 @@ pcap_setfilter_bpf(pcap_t *p, struct bpf_program *fp)
|
||||
return (-1);
|
||||
}
|
||||
p->md.use_bpf = 1; /* filtering in the kernel */
|
||||
|
||||
/*
|
||||
* Discard any previously-received packets, as they might have
|
||||
* passed whatever filter was formerly in effect, but might
|
||||
* not pass this filter (BIOCSETF discards packets buffered
|
||||
* in the kernel, so you can lose packets in any case).
|
||||
*/
|
||||
p->cc = 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,7 @@
|
||||
*
|
||||
* @(#)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)
|
||||
* @(#) $Header: /tcpdump/master/libpcap/pcap-bpf.h,v 1.34 2005/02/08 20:03:15 guy Exp $ (LBL)
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -60,8 +60,13 @@ extern "C" {
|
||||
/* BSD style release date */
|
||||
#define BPF_RELEASE 199606
|
||||
|
||||
#ifdef MSDOS /* must be 32-bit */
|
||||
typedef long bpf_int32;
|
||||
typedef unsigned long bpf_u_int32;
|
||||
#else
|
||||
typedef int bpf_int32;
|
||||
typedef u_int bpf_u_int32;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Alignment macros. BPF_WORDALIGN rounds up to the next
|
||||
@ -121,7 +126,7 @@ struct bpf_version {
|
||||
* 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_NULL 0 /* BSD loopback encapsulation */
|
||||
#define DLT_EN10MB 1 /* Ethernet (10Mb) */
|
||||
#define DLT_EN3MB 2 /* Experimental Ethernet (3Mb) */
|
||||
#define DLT_AX25 3 /* Amateur Radio AX.25 */
|
||||
@ -174,6 +179,12 @@ struct bpf_version {
|
||||
|
||||
#define DLT_ATM_CLIP 19 /* Linux Classical-IP over ATM */
|
||||
|
||||
/*
|
||||
* Apparently Redback uses this for its SmartEdge 400/800. I hope
|
||||
* nobody else decided to use it, too.
|
||||
*/
|
||||
#define DLT_REDBACK_SMARTEDGE 32
|
||||
|
||||
/*
|
||||
* These values are defined by NetBSD; other platforms should refrain from
|
||||
* using them for other purposes, so that NetBSD savefiles with link
|
||||
@ -350,10 +361,11 @@ struct bpf_version {
|
||||
#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.
|
||||
* Header for 802.11 plus a number of bits of link-layer information
|
||||
* including radio information, used by some recent BSD drivers as
|
||||
* well as the madwifi Atheros driver for Linux.
|
||||
*/
|
||||
#define DLT_IEEE802_11_RADIO 127 /* 802.11 plus BSD radio header */
|
||||
#define DLT_IEEE802_11_RADIO 127 /* 802.11 plus radiotap radio header */
|
||||
|
||||
/*
|
||||
* Reserved for the TZSP encapsulation, as per request from
|
||||
@ -415,7 +427,7 @@ struct bpf_version {
|
||||
*/
|
||||
|
||||
/*
|
||||
* Reserved for DOCSIS MAC frames.
|
||||
* DOCSIS MAC frames.
|
||||
*/
|
||||
#define DLT_DOCSIS 143
|
||||
|
||||
@ -491,8 +503,8 @@ struct bpf_version {
|
||||
*
|
||||
* 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.
|
||||
* but it might be used by some non-AVS drivers now or in the
|
||||
* future.
|
||||
*/
|
||||
#define DLT_IEEE802_11_RADIO_AVS 163 /* 802.11 plus AVS radio header */
|
||||
|
||||
@ -504,6 +516,70 @@ struct bpf_version {
|
||||
*/
|
||||
#define DLT_JUNIPER_MONITOR 164
|
||||
|
||||
/*
|
||||
* Reserved for BACnet MS/TP.
|
||||
*/
|
||||
#define DLT_BACNET_MS_TP 165
|
||||
|
||||
/*
|
||||
* Another PPP variant as per request from Karsten Keil <kkeil@suse.de>.
|
||||
*
|
||||
* This is used in some OSes to allow a kernel socket filter to distinguish
|
||||
* between incoming and outgoing packets, on a socket intended to
|
||||
* supply pppd with outgoing packets so it can do dial-on-demand and
|
||||
* hangup-on-lack-of-demand; incoming packets are filtered out so they
|
||||
* don't cause pppd to hold the connection up (you don't want random
|
||||
* input packets such as port scans, packets from old lost connections,
|
||||
* etc. to force the connection to stay up).
|
||||
*
|
||||
* The first byte of the PPP header (0xff03) is modified to accomodate
|
||||
* the direction - 0x00 = IN, 0x01 = OUT.
|
||||
*/
|
||||
#define DLT_PPP_PPPD 166
|
||||
|
||||
/*
|
||||
* Names for backwards compatibility with older versions of some PPP
|
||||
* software; new software should use DLT_PPP_PPPD.
|
||||
*/
|
||||
#define DLT_PPP_WITH_DIRECTION DLT_PPP_PPPD
|
||||
#define DLT_LINUX_PPP_WITHDIRECTION DLT_PPP_PPPD
|
||||
|
||||
/*
|
||||
* Juniper-private data link type, as per request from
|
||||
* Hannes Gredler <hannes@juniper.net>. The DLT_s are used
|
||||
* for passing on chassis-internal metainformation such as
|
||||
* QOS profiles, cookies, etc..
|
||||
*/
|
||||
#define DLT_JUNIPER_PPPOE 167
|
||||
#define DLT_JUNIPER_PPPOE_ATM 168
|
||||
|
||||
#define DLT_GPRS_LLC 169 /* GPRS LLC */
|
||||
#define DLT_GPF_T 170 /* GPF-T (ITU-T G.7041/Y.1303) */
|
||||
#define DLT_GPF_F 171 /* GPF-F (ITU-T G.7041/Y.1303) */
|
||||
|
||||
/*
|
||||
* Requested by Oolan Zimmer <oz@gcom.com> for use in Gcom's T1/E1 line
|
||||
* monitoring equipment.
|
||||
*/
|
||||
#define DLT_GCOM_T1E1 172
|
||||
#define DLT_GCOM_SERIAL 173
|
||||
|
||||
/*
|
||||
* Juniper-private data link type, as per request from
|
||||
* Hannes Gredler <hannes@juniper.net>. The DLT_ is used
|
||||
* for internal communication to Physical Interface Cards (PIC)
|
||||
*/
|
||||
#define DLT_JUNIPER_PIC_PEER 174
|
||||
|
||||
/*
|
||||
* Link types requested by Gregor Maier <gregor@endace.com> of Endace
|
||||
* Measurement Systems. They add an ERF header (see
|
||||
* http://www.endace.com/support/EndaceRecordFormat.pdf) in front of
|
||||
* the link-layer header.
|
||||
*/
|
||||
#define DLT_ERF_ETH 175 /* Ethernet */
|
||||
#define DLT_ERF_POS 176 /* Packet-over-SONET */
|
||||
|
||||
/*
|
||||
* The instruction encodings.
|
||||
*/
|
||||
|
@ -9,27 +9,13 @@
|
||||
* 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.
|
||||
* Authors: Richard Littin, Sean Irvine ({richard,sean}@reeltwo.com)
|
||||
* Modifications: Jesper Peterson, Koryn Grant <support@endace.com>
|
||||
*/
|
||||
|
||||
#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)";
|
||||
"@(#) $Header: /tcpdump/master/libpcap/pcap-dag.c,v 1.21 2005/04/03 23:56:47 guy Exp $ (LBL)";
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
@ -55,17 +41,25 @@ 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>
|
||||
#include "dagnew.h"
|
||||
#include "dagapi.h"
|
||||
|
||||
#define MIN_DAG_SNAPLEN 12
|
||||
#define MAX_DAG_SNAPLEN 2040
|
||||
#define ATM_SNAPLEN 48
|
||||
#define ATM_CELL_SIZE 52
|
||||
#define ATM_HDR_SIZE 4
|
||||
|
||||
/* SunATM pseudo header */
|
||||
struct sunatm_hdr {
|
||||
unsigned char flags; /* destination and traffic type */
|
||||
unsigned char vpi; /* VPI */
|
||||
unsigned short vci; /* VCI */
|
||||
};
|
||||
|
||||
typedef struct pcap_dag_node {
|
||||
struct pcap_dag_node *next;
|
||||
pcap_t *p;
|
||||
pid_t pid;
|
||||
struct pcap_dag_node *next;
|
||||
pcap_t *p;
|
||||
pid_t pid;
|
||||
} pcap_dag_node_t;
|
||||
|
||||
static pcap_dag_node_t *pcap_dags = NULL;
|
||||
@ -103,22 +97,22 @@ 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;
|
||||
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 */
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
if (curr != NULL && curr->p == p) {
|
||||
if (prev != NULL) {
|
||||
prev->next = curr->next;
|
||||
} else {
|
||||
pcap_dags = curr->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -126,58 +120,64 @@ static void delete_pcap_dag(pcap_t *p) {
|
||||
* in the pcap_t structure, and closes the file descriptor for the DAG card.
|
||||
*/
|
||||
|
||||
static void dag_platform_close(pcap_t *p) {
|
||||
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);
|
||||
}
|
||||
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));
|
||||
}
|
||||
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. */
|
||||
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 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;
|
||||
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 ((node = malloc(sizeof(pcap_dag_node_t))) == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!atexit_handler_installed) {
|
||||
atexit(atexit_handler);
|
||||
atexit_handler_installed = 1;
|
||||
}
|
||||
if (!atexit_handler_installed) {
|
||||
atexit(atexit_handler);
|
||||
atexit_handler_installed = 1;
|
||||
}
|
||||
|
||||
node->next = pcap_dags;
|
||||
node->p = p;
|
||||
node->pid = getpid();
|
||||
node->next = pcap_dags;
|
||||
node->p = p;
|
||||
node->pid = getpid();
|
||||
|
||||
pcap_dags = node;
|
||||
pcap_dags = node;
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -185,7 +185,9 @@ static int new_pcap_dag(pcap_t *p) {
|
||||
* 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) {
|
||||
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;
|
||||
@ -209,13 +211,13 @@ static int dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) {
|
||||
}
|
||||
|
||||
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)
|
||||
if (nonblocking && (p->md.dag_mem_top - p->md.dag_mem_bottom < dag_record_size))
|
||||
{
|
||||
/* 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) {
|
||||
|
||||
@ -240,54 +242,59 @@ static int dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (IS_BIGENDIAN())
|
||||
{
|
||||
rlen = header->rlen;
|
||||
}
|
||||
else
|
||||
{
|
||||
rlen = ntohs(header->rlen);
|
||||
if (rlen < dag_record_size)
|
||||
{
|
||||
strncpy(p->errbuf, "dag_read: record too small", PCAP_ERRBUF_SIZE);
|
||||
return -1;
|
||||
}
|
||||
p->md.dag_mem_bottom += rlen;
|
||||
|
||||
switch(header->type) {
|
||||
case TYPE_AAL5:
|
||||
case TYPE_ATM:
|
||||
packet_len = ATM_SNAPLEN;
|
||||
caplen = ATM_SNAPLEN;
|
||||
dp += 4;
|
||||
if (header->type == TYPE_AAL5) {
|
||||
packet_len = ntohs(header->wlen);
|
||||
caplen = rlen - dag_record_size;
|
||||
} else {
|
||||
caplen = packet_len = ATM_CELL_SIZE;
|
||||
}
|
||||
if (p->linktype == DLT_SUNATM) {
|
||||
struct sunatm_hdr *sunatm = (struct sunatm_hdr *)dp;
|
||||
unsigned long rawatm;
|
||||
|
||||
rawatm = ntohl(*((unsigned long *)dp));
|
||||
sunatm->vci = htons((rawatm >> 4) & 0xffff);
|
||||
sunatm->vpi = (rawatm >> 20) & 0x00ff;
|
||||
sunatm->flags = ((header->flags.iface & 1) ? 0x80 : 0x00) |
|
||||
((sunatm->vpi == 0 && sunatm->vci == htons(5)) ? 6 :
|
||||
((sunatm->vpi == 0 && sunatm->vci == htons(16)) ? 5 :
|
||||
((dp[ATM_HDR_SIZE] == 0xaa &&
|
||||
dp[ATM_HDR_SIZE+1] == 0xaa &&
|
||||
dp[ATM_HDR_SIZE+2] == 0x03) ? 2 : 1)));
|
||||
|
||||
} else {
|
||||
packet_len -= ATM_HDR_SIZE;
|
||||
caplen -= ATM_HDR_SIZE;
|
||||
dp += ATM_HDR_SIZE;
|
||||
}
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (caplen > packet_len) {
|
||||
caplen = packet_len;
|
||||
}
|
||||
break;
|
||||
@ -298,10 +305,10 @@ static int dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) {
|
||||
|
||||
/* Count lost packets. */
|
||||
if (header->lctr) {
|
||||
if (p->md.stat.ps_drop > (UINT_MAX - header->lctr)) {
|
||||
if (p->md.stat.ps_drop > (UINT_MAX - ntohs(header->lctr))) {
|
||||
p->md.stat.ps_drop = UINT_MAX;
|
||||
} else {
|
||||
p->md.stat.ps_drop += header->lctr;
|
||||
p->md.stat.ps_drop += ntohs(header->lctr);
|
||||
}
|
||||
}
|
||||
|
||||
@ -311,16 +318,13 @@ static int dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) {
|
||||
/* convert between timestamp formats */
|
||||
register unsigned long long ts;
|
||||
|
||||
if (IS_BIGENDIAN())
|
||||
{
|
||||
if (IS_BIGENDIAN()) {
|
||||
ts = SWAP_TS(header->ts);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ts = header->ts;
|
||||
}
|
||||
|
||||
pcap_header.ts.tv_sec = ts >> 32;
|
||||
pcap_header.ts.tv_sec = ts >> 32;
|
||||
ts = (ts & 0xffffffffULL) * 1000000;
|
||||
ts += 0x80000000; /* rounding */
|
||||
pcap_header.ts.tv_usec = ts >> 32;
|
||||
@ -332,13 +336,13 @@ static int dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) {
|
||||
/* 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)
|
||||
@ -354,10 +358,18 @@ static int dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) {
|
||||
return processed;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return processed;
|
||||
}
|
||||
|
||||
static int
|
||||
dag_inject(pcap_t *p, const void *buf _U_, size_t size _U_)
|
||||
{
|
||||
strlcpy(p->errbuf, "Sending packets isn't supported on DAG cards",
|
||||
PCAP_ERRBUF_SIZE);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
@ -366,152 +378,171 @@ static int dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) {
|
||||
*
|
||||
* 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. */
|
||||
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;
|
||||
daginf_t* daginf;
|
||||
|
||||
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));
|
||||
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 (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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
/* 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);
|
||||
/* 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;
|
||||
}
|
||||
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;
|
||||
/*
|
||||
* 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;
|
||||
handle->md.dag_fcs_bits = 32;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
/* Query the card first for special cases. */
|
||||
daginf = dag_info(handle->fd);
|
||||
if ((0x4200 == daginf->device_code) || (0x4230 == daginf->device_code))
|
||||
{
|
||||
/* DAG 4.2S and 4.23S already strip the FCS. Stripping the final word again truncates the packet. */
|
||||
handle->md.dag_fcs_bits = 0;
|
||||
}
|
||||
|
||||
handle->snapshot = snaplen;
|
||||
/*handle->md.timeout = to_ms; */
|
||||
/* Then allow an environment variable to override. */
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
handle->snapshot = snaplen;
|
||||
/*handle->md.timeout = to_ms; */
|
||||
|
||||
if (new_pcap_dag(handle) < 0) {
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "new_pcap_dag %s: %s\n", device, pcap_strerror(errno));
|
||||
goto fail;
|
||||
}
|
||||
handle->linktype = -1;
|
||||
if (dag_get_datalink(handle) < 0) {
|
||||
strcpy(ebuf, handle->errbuf);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
handle->bufsize = 0;
|
||||
|
||||
/*
|
||||
* "select()" and "poll()" don't (yet) work on DAG device descriptors.
|
||||
*/
|
||||
handle->selectable_fd = -1;
|
||||
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;
|
||||
handle->md.device = (char *)device;
|
||||
#else
|
||||
free((char *)device);
|
||||
device = NULL;
|
||||
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;
|
||||
handle->read_op = dag_read;
|
||||
handle->inject_op = dag_inject;
|
||||
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;
|
||||
return handle;
|
||||
|
||||
fail:
|
||||
if (device != NULL) {
|
||||
free((char *)device);
|
||||
}
|
||||
if (handle != NULL) {
|
||||
free(handle);
|
||||
}
|
||||
if (device != NULL) {
|
||||
free((char *)device);
|
||||
}
|
||||
if (handle != NULL) {
|
||||
/*
|
||||
* Get rid of any link-layer type list we allocated.
|
||||
*/
|
||||
if (handle->dlt_list != NULL) {
|
||||
free(handle->dlt_list);
|
||||
}
|
||||
free(handle);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
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;
|
||||
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;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -527,87 +558,86 @@ static int dag_stats(pcap_t *p, struct pcap_stat *ps) {
|
||||
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;
|
||||
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";
|
||||
/* 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 (i = '0'; ret == 0 && i <= '9'; i++) {
|
||||
dev[3] = i;
|
||||
if (pcap_add_if(devlistp, dev, 0, NULL, errbuf) == -1) {
|
||||
/*
|
||||
* Failure.
|
||||
*/
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
|
||||
for (linenum = 1;
|
||||
fgets(linebuf, sizeof linebuf, proc_dag_f) != NULL; linenum++) {
|
||||
|
||||
/*
|
||||
* Skip the first two lines - they're headers.
|
||||
*/
|
||||
if (linenum <= 2)
|
||||
continue;
|
||||
return (ret);
|
||||
}
|
||||
|
||||
p = &linebuf[0];
|
||||
for (linenum = 1; fgets(linebuf, sizeof linebuf, proc_dag_f) != NULL; linenum++) {
|
||||
|
||||
/*
|
||||
* Skip the first two lines - they're headers.
|
||||
*/
|
||||
if (linenum <= 2)
|
||||
continue;
|
||||
|
||||
if (*p == '\0' || *p == '\n' || *p != 'D')
|
||||
continue; /* not a Dag line */
|
||||
p = &linebuf[0];
|
||||
|
||||
/*
|
||||
* Get the interface name.
|
||||
*/
|
||||
q = &name[0];
|
||||
while (*p != '\0' && *p != ':') {
|
||||
if (*p != ' ')
|
||||
*q++ = tolower(*p++);
|
||||
else
|
||||
p++;
|
||||
}
|
||||
*q = '\0';
|
||||
if (*p == '\0' || *p == '\n' || *p != 'D')
|
||||
continue; /* not a Dag line */
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Get the interface name.
|
||||
*/
|
||||
q = &name[0];
|
||||
while (*p != '\0' && *p != ':') {
|
||||
if (*p != ' ')
|
||||
*q++ = tolower(*p++);
|
||||
else
|
||||
p++;
|
||||
}
|
||||
*q = '\0';
|
||||
|
||||
(void)fclose(proc_dag_f);
|
||||
return (ret);
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -615,31 +645,32 @@ dag_platform_finddevs(pcap_if_t **devlistp, char *errbuf)
|
||||
* 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;
|
||||
}
|
||||
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 */
|
||||
/* 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;
|
||||
}
|
||||
if (install_bpf_program(p, fp) < 0)
|
||||
return -1;
|
||||
|
||||
p->md.use_bpf = 0;
|
||||
p->md.use_bpf = 0;
|
||||
|
||||
return (0);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
dag_set_datalink(pcap_t *p, int dlt)
|
||||
{
|
||||
p->linktype = dlt;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -666,45 +697,66 @@ dag_setnonblock(pcap_t *p, int nonblock, char *errbuf)
|
||||
static int
|
||||
dag_get_datalink(pcap_t *p)
|
||||
{
|
||||
int linktype = -1;
|
||||
int daglinktype;
|
||||
|
||||
/* Check the type through a dagapi call.
|
||||
*/
|
||||
switch(dag_linktype(p->fd)) {
|
||||
case TYPE_HDLC_POS: {
|
||||
dag_record_t *record;
|
||||
if (p->dlt_list == NULL && (p->dlt_list = malloc(2*sizeof(*(p->dlt_list)))) == NULL) {
|
||||
(void)snprintf(p->errbuf, sizeof(p->errbuf), "malloc: %s", pcap_strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* 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);
|
||||
/* Check the type through a dagapi call. */
|
||||
daglinktype = dag_linktype(p->fd);
|
||||
|
||||
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;
|
||||
}
|
||||
switch(daglinktype) {
|
||||
|
||||
return linktype;
|
||||
case TYPE_HDLC_POS:
|
||||
if (p->dlt_list != NULL) {
|
||||
p->dlt_count = 2;
|
||||
p->dlt_list[0] = DLT_CHDLC;
|
||||
p->dlt_list[1] = DLT_PPP_SERIAL;
|
||||
}
|
||||
p->linktype = DLT_CHDLC;
|
||||
break;
|
||||
|
||||
case TYPE_ETH:
|
||||
/*
|
||||
* This is (presumably) a real Ethernet capture; give it a
|
||||
* link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so
|
||||
* that an application can let you choose it, in case you're
|
||||
* capturing DOCSIS traffic that a Cisco Cable Modem
|
||||
* Termination System is putting out onto an Ethernet (it
|
||||
* doesn't put an Ethernet header onto the wire, it puts raw
|
||||
* DOCSIS frames out on the wire inside the low-level
|
||||
* Ethernet framing).
|
||||
*/
|
||||
if (p->dlt_list != NULL) {
|
||||
p->dlt_count = 2;
|
||||
p->dlt_list[0] = DLT_EN10MB;
|
||||
p->dlt_list[1] = DLT_DOCSIS;
|
||||
}
|
||||
p->linktype = DLT_EN10MB;
|
||||
break;
|
||||
|
||||
case TYPE_AAL5:
|
||||
case TYPE_ATM:
|
||||
if (p->dlt_list != NULL) {
|
||||
p->dlt_count = 2;
|
||||
p->dlt_list[0] = DLT_ATM_RFC1483;
|
||||
p->dlt_list[1] = DLT_SUNATM;
|
||||
}
|
||||
p->linktype = DLT_ATM_RFC1483;
|
||||
break;
|
||||
|
||||
|
||||
case TYPE_LEGACY:
|
||||
p->linktype = DLT_NULL;
|
||||
break;
|
||||
|
||||
default:
|
||||
snprintf(p->errbuf, sizeof(p->errbuf), "unknown DAG linktype %d\n", daglinktype);
|
||||
return (-1);
|
||||
|
||||
}
|
||||
|
||||
return p->linktype;
|
||||
}
|
||||
|
@ -19,7 +19,9 @@
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* This code contributed by Atanu Ghosh (atanu@cs.ucl.ac.uk),
|
||||
* University College London.
|
||||
* University College London, and subsequently modified by
|
||||
* Guy Harris (guy@alum.mit.edu) and Mark Pizzolato
|
||||
* <List-tcpdump-workers@subscriptions.pizzolato.net>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -27,18 +29,40 @@
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
* - Apparently the DLIOCRAW ioctl() is specific to SunOS.
|
||||
* - The DLIOCRAW ioctl() is specific to SunOS.
|
||||
*
|
||||
* - There is a bug in bufmod(7) such that setting the snapshot
|
||||
* length results in data being left of the front of the packet.
|
||||
*
|
||||
* - It might be desirable to use pfmod(7) to filter packets in the
|
||||
* kernel when possible.
|
||||
*
|
||||
* - The HP-UX 10.20 DLPI Programmer's Guide used to be available
|
||||
* at
|
||||
*
|
||||
* http://docs.hp.com/hpux/onlinedocs/B2355-90093/B2355-90093.html
|
||||
*
|
||||
* but is no longer available; it can still be found at
|
||||
*
|
||||
* http://h21007.www2.hp.com/dspp/files/unprotected/Drivers/Docs/Refs/B2355-90093.pdf
|
||||
*
|
||||
* in PDF form.
|
||||
*
|
||||
* - The HP-UX 11.00 DLPI Programmer's Guide is available at
|
||||
*
|
||||
* http://docs.hp.com/hpux/onlinedocs/B2355-90139/B2355-90139.html
|
||||
*
|
||||
* and in PDF form at
|
||||
*
|
||||
* http://h21007.www2.hp.com/dspp/files/unprotected/Drivers/Docs/Refs/B2355-90139.pdf
|
||||
*
|
||||
* - Both of the HP documents describe raw-mode services, which are
|
||||
* what we use if DL_HP_RAWDLS is defined.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid[] _U_ =
|
||||
"@(#) $Header: /tcpdump/master/libpcap/pcap-dlpi.c,v 1.91.2.3 2003/11/21 10:20:46 guy Exp $ (LBL)";
|
||||
"@(#) $Header: /tcpdump/master/libpcap/pcap-dlpi.c,v 1.108 2004/10/19 07:06:12 guy Exp $ (LBL)";
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
@ -57,7 +81,7 @@ static const char rcsid[] _U_ =
|
||||
#ifdef HAVE_HPUX9
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef DL_HP_PPA_ACK_OBS
|
||||
#ifdef DL_HP_PPA_REQ
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#include <sys/stream.h>
|
||||
@ -82,6 +106,12 @@ static const char rcsid[] _U_ =
|
||||
#include <stropts.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef HAVE_LIMITS_H
|
||||
#include <limits.h>
|
||||
#else
|
||||
#define INT_MAX 2147483647
|
||||
#endif
|
||||
|
||||
#include "pcap-int.h"
|
||||
|
||||
#ifdef HAVE_OS_PROTO_H
|
||||
@ -127,16 +157,20 @@ static const char rcsid[] _U_ =
|
||||
|
||||
/* Forwards */
|
||||
static char *split_dname(char *, int *, char *);
|
||||
static int dl_doattach(int, int, char *);
|
||||
static int dlattachreq(int, bpf_u_int32, char *);
|
||||
static int dlbindack(int, char *, char *);
|
||||
static int dlbindreq(int, bpf_u_int32, char *);
|
||||
static int dlinfoack(int, char *, char *);
|
||||
static int dlinforeq(int, char *);
|
||||
static int dlbindack(int, char *, char *);
|
||||
static int dlpromisconreq(int, bpf_u_int32, char *);
|
||||
static int dlokack(int, const char *, char *, char *);
|
||||
static int dlinforeq(int, char *);
|
||||
static int dlinfoack(int, char *, char *);
|
||||
#ifdef DL_HP_RAWDLS
|
||||
static int dlrawdatareq(int, const u_char *, int);
|
||||
#endif
|
||||
static int recv_ack(int, int, const char *, char *, char *);
|
||||
static char *dlstrerror(bpf_u_int32);
|
||||
static char *dlprim(bpf_u_int32);
|
||||
static int dlpromisconreq(int, bpf_u_int32, char *);
|
||||
#if defined(HAVE_SOLARIS) && defined(HAVE_SYS_BUFMOD_H)
|
||||
static char *get_release(bpf_u_int32 *, bpf_u_int32 *, bpf_u_int32 *);
|
||||
#endif
|
||||
@ -158,21 +192,32 @@ pcap_stats_dlpi(pcap_t *p, struct pcap_stat *ps)
|
||||
/*
|
||||
* "ps_recv" counts packets handed to the filter, not packets
|
||||
* that passed the filter. As filtering is done in userland,
|
||||
* this does not include packets dropped because we ran out
|
||||
* of buffer space.
|
||||
* this would not include packets dropped because we ran out
|
||||
* of buffer space; in order to make this more like other
|
||||
* platforms (Linux 2.4 and later, BSDs with BPF), where the
|
||||
* "packets received" count includes packets received but dropped
|
||||
* due to running out of buffer space, and to keep from confusing
|
||||
* applications that, for example, compute packet drop percentages,
|
||||
* we also make it count packets dropped by "bufmod" (otherwise we
|
||||
* might run the risk of the packet drop count being bigger than
|
||||
* the received-packet count).
|
||||
*
|
||||
* "ps_drop" counts packets dropped inside the DLPI service
|
||||
* provider device device because of flow control requirements
|
||||
* or resource exhaustion; it doesn't count packets dropped by
|
||||
* the interface driver, or packets dropped upstream. As
|
||||
* filtering is done in userland, it counts packets regardless
|
||||
* of whether they would've passed the filter.
|
||||
* "ps_drop" counts packets dropped by "bufmod" because of
|
||||
* flow control requirements or resource exhaustion; it doesn't
|
||||
* count packets dropped by the interface driver, or packets
|
||||
* dropped upstream. As filtering is done in userland, it counts
|
||||
* packets regardless of whether they would've passed the filter.
|
||||
*
|
||||
* These statistics don't include packets not yet read from
|
||||
* the kernel by libpcap, but they may include packets not
|
||||
* yet read from libpcap by the application.
|
||||
*/
|
||||
*ps = p->md.stat;
|
||||
|
||||
/*
|
||||
* Add in the drop count, as per the above comment.
|
||||
*/
|
||||
ps->ps_recv += ps->ps_drop;
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -220,11 +265,21 @@ pcap_read_dlpi(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
p->break_loop = 0;
|
||||
return (-2);
|
||||
}
|
||||
/*
|
||||
* XXX - check for the DLPI primitive, which
|
||||
* would be DL_HP_RAWDATA_IND on HP-UX
|
||||
* if we're in raw mode?
|
||||
*/
|
||||
if (getmsg(p->fd, &ctl, &data, &flags) < 0) {
|
||||
/* Don't choke when we get ptraced */
|
||||
if (errno == EINTR) {
|
||||
switch (errno) {
|
||||
|
||||
case EINTR:
|
||||
cc = 0;
|
||||
continue;
|
||||
|
||||
case EAGAIN:
|
||||
return (0);
|
||||
}
|
||||
strlcpy(p->errbuf, pcap_strerror(errno),
|
||||
sizeof(p->errbuf));
|
||||
@ -306,6 +361,58 @@ pcap_read_dlpi(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
return (n);
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_inject_dlpi(pcap_t *p, const void *buf, size_t size)
|
||||
{
|
||||
int ret;
|
||||
|
||||
#if defined(DLIOCRAW)
|
||||
ret = write(p->fd, buf, size);
|
||||
if (ret == -1) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
|
||||
pcap_strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
#elif defined(DL_HP_RAWDLS)
|
||||
if (p->send_fd < 0) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"send: Output FD couldn't be opened");
|
||||
return (-1);
|
||||
}
|
||||
ret = dlrawdatareq(p->send_fd, buf, size);
|
||||
if (ret == -1) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
|
||||
pcap_strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
#else /* no raw mode */
|
||||
/*
|
||||
* XXX - this is a pain, because you might have to extract
|
||||
* the address from the packet and use it in a DL_UNITDATA_REQ
|
||||
* request. That would be dependent on the link-layer type.
|
||||
*
|
||||
* I also don't know what SAP you'd have to bind the descriptor
|
||||
* to, or whether you'd need separate "receive" and "send" FDs,
|
||||
* nor do I know whether you'd need different bindings for
|
||||
* D/I/X Ethernet and 802.3, or for {FDDI,Token Ring} plus
|
||||
* 802.2 and {FDDI,Token Ring} plus 802.2 plus SNAP.
|
||||
*
|
||||
* So, for now, we just return a "you can't send" indication,
|
||||
* and leave it up to somebody with a DLPI-based system lacking
|
||||
* both DLIOCRAW and DL_HP_RAWDLS to supply code to implement
|
||||
* packet transmission on that system. If they do, they should
|
||||
* send it to us - but should not send us code that assumes
|
||||
* Ethernet; if the code doesn't work on non-Ethernet interfaces,
|
||||
* it should check "p->linktype" and reject the send request if
|
||||
* it's anything other than DLT_EN10MB.
|
||||
*/
|
||||
strlcpy(p->errbuf, "send: Not supported on this version of this OS",
|
||||
PCAP_ERRBUF_SIZE);
|
||||
ret = -1;
|
||||
#endif /* raw mode */
|
||||
return (ret);
|
||||
}
|
||||
|
||||
#ifndef DL_IPATM
|
||||
#define DL_IPATM 0x12 /* ATM Classical IP interface */
|
||||
#endif
|
||||
@ -325,10 +432,9 @@ pcap_read_dlpi(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
static void
|
||||
pcap_close_dlpi(pcap_t *p)
|
||||
{
|
||||
if (p->buffer != NULL)
|
||||
free(p->buffer);
|
||||
if (p->fd >= 0)
|
||||
close(p->fd);
|
||||
pcap_close_common(p);
|
||||
if (p->send_fd >= 0)
|
||||
close(p->send_fd);
|
||||
}
|
||||
|
||||
pcap_t *
|
||||
@ -362,6 +468,7 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||
}
|
||||
memset(p, 0, sizeof(*p));
|
||||
p->fd = -1; /* indicate that it hasn't been opened yet */
|
||||
p->send_fd = -1;
|
||||
|
||||
#ifdef HAVE_DEV_DLPI
|
||||
/*
|
||||
@ -400,6 +507,22 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||
goto bad;
|
||||
}
|
||||
|
||||
#ifdef DL_HP_RAWDLS
|
||||
/*
|
||||
* XXX - HP-UX 10.20 and 11.xx don't appear to support sending and
|
||||
* receiving packets on the same descriptor - you have to bind the
|
||||
* descriptor on which you receive to a SAP of 22 and bind the
|
||||
* descriptor on which you send to a SAP of 24.
|
||||
*
|
||||
* If the open fails, we just leave -1 in "p->send_fd" and reject
|
||||
* attempts to send packets, just as if, in pcap-bpf.c, we fail
|
||||
* to open the BPF device for reading and writing, we just try
|
||||
* to open it for reading only and, if that succeeds, just let
|
||||
* the send attempts fail.
|
||||
*/
|
||||
p->send_fd = open(cp, O_RDWR);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Get a table of all PPAs for that device, and search that
|
||||
* table for the specified device type name and unit number.
|
||||
@ -445,8 +568,28 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||
|
||||
/* Try again with unit number */
|
||||
if ((p->fd = open(dname2, O_RDWR)) < 0) {
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s: %s", dname2,
|
||||
pcap_strerror(errno));
|
||||
if (errno == ENOENT) {
|
||||
/*
|
||||
* We just report "No DLPI device found"
|
||||
* with the device name, so people don't
|
||||
* get confused and think, for example,
|
||||
* that if they can't capture on "lo0"
|
||||
* on Solaris the fix is to change libpcap
|
||||
* (or the application that uses it) to
|
||||
* look for something other than "/dev/lo0",
|
||||
* as the fix is to look for an operating
|
||||
* system other than Solaris - you just
|
||||
* *can't* capture on a loopback interface
|
||||
* on Solaris, the lack of a DLPI device
|
||||
* for the loopback interface is just a
|
||||
* symptom of that inability.
|
||||
*/
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
||||
"%s: No DLPI device found", device);
|
||||
} else {
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s: %s",
|
||||
dname2, pcap_strerror(errno));
|
||||
}
|
||||
goto bad;
|
||||
}
|
||||
/* XXX Assume unit zero */
|
||||
@ -467,10 +610,17 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||
if (infop->dl_mac_type == DL_IPATM)
|
||||
isatm = 1;
|
||||
#endif
|
||||
if (infop->dl_provider_style == DL_STYLE2 &&
|
||||
(dlattachreq(p->fd, ppa, ebuf) < 0 ||
|
||||
dlokack(p->fd, "attach", (char *)buf, ebuf) < 0))
|
||||
goto bad;
|
||||
if (infop->dl_provider_style == DL_STYLE2) {
|
||||
if (dl_doattach(p->fd, ppa, ebuf) < 0)
|
||||
goto bad;
|
||||
#ifdef DL_HP_RAWDLS
|
||||
if (p->send_fd >= 0) {
|
||||
if (dl_doattach(p->send_fd, ppa, ebuf) < 0)
|
||||
goto bad;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
** Bind (defer if using HP-UX 9 or HP-UX 10.20, totally skip if
|
||||
** using SINIX)
|
||||
@ -495,12 +645,34 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||
*/
|
||||
if ((dlbindreq(p->fd, 1537, ebuf) < 0 &&
|
||||
dlbindreq(p->fd, 2, ebuf) < 0) ||
|
||||
#else
|
||||
dlbindack(p->fd, (char *)buf, ebuf) < 0)
|
||||
goto bad;
|
||||
#elif defined(DL_HP_RAWDLS)
|
||||
/*
|
||||
** This is the descriptor on which we receive packets; we
|
||||
** bind it to 22, as that's INSAP, as per the HP-UX DLPI
|
||||
** Programmer's Guide.
|
||||
*/
|
||||
if (dlbindreq(p->fd, 22, ebuf) < 0 ||
|
||||
dlbindack(p->fd, (char *)buf, ebuf) < 0)
|
||||
goto bad;
|
||||
|
||||
if (p->send_fd >= 0) {
|
||||
/*
|
||||
** This is the descriptor on which we send packets; we
|
||||
** bind it to 24, as that's OUTSAP, as per the HP-UX
|
||||
** DLPI Programmer's Guide.
|
||||
*/
|
||||
if (dlbindreq(p->send_fd, 24, ebuf) < 0 ||
|
||||
dlbindack(p->send_fd, (char *)buf, ebuf) < 0)
|
||||
goto bad;
|
||||
}
|
||||
#else /* neither AIX nor HP-UX */
|
||||
if (dlbindreq(p->fd, 0, ebuf) < 0 ||
|
||||
#endif
|
||||
dlbindack(p->fd, (char *)buf, ebuf) < 0)
|
||||
goto bad;
|
||||
#endif
|
||||
#endif /* SAP to bind to */
|
||||
#endif /* HP-UX 9 or 10.20 or SINIX */
|
||||
|
||||
#ifdef HAVE_SOLARIS
|
||||
if (isatm) {
|
||||
@ -519,7 +691,7 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||
#endif
|
||||
if (promisc) {
|
||||
/*
|
||||
** Enable promiscuous
|
||||
** Enable promiscuous (not necessary on send FD)
|
||||
*/
|
||||
if (dlpromisconreq(p->fd, DL_PROMISC_PHYS, ebuf) < 0 ||
|
||||
dlokack(p->fd, "promisc_phys", (char *)buf, ebuf) < 0)
|
||||
@ -528,7 +700,7 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||
/*
|
||||
** Try to enable multicast (you would have thought
|
||||
** promiscuous would be sufficient). (Skip if using
|
||||
** HP-UX or SINIX)
|
||||
** HP-UX or SINIX) (Not necessary on send FD)
|
||||
*/
|
||||
#if !defined(__hpux) && !defined(sinix)
|
||||
if (dlpromisconreq(p->fd, DL_PROMISC_MULTI, ebuf) < 0 ||
|
||||
@ -540,7 +712,7 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||
/*
|
||||
** Try to enable sap (when not in promiscuous mode when using
|
||||
** using HP-UX, when not doing SunATM on Solaris, and never
|
||||
** under SINIX)
|
||||
** under SINIX) (Not necessary on send FD)
|
||||
*/
|
||||
#ifndef sinix
|
||||
if (
|
||||
@ -573,6 +745,8 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||
|
||||
/*
|
||||
** Determine link type
|
||||
** XXX - get SAP length and address length as well, for use
|
||||
** when sending packets.
|
||||
*/
|
||||
if (dlinforeq(p->fd, ebuf) < 0 ||
|
||||
dlinfoack(p->fd, (char *)buf, ebuf) < 0)
|
||||
@ -585,6 +759,25 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||
case DL_ETHER:
|
||||
p->linktype = DLT_EN10MB;
|
||||
p->offset = 2;
|
||||
/*
|
||||
* This is (presumably) a real Ethernet capture; give it a
|
||||
* link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so
|
||||
* that an application can let you choose it, in case you're
|
||||
* capturing DOCSIS traffic that a Cisco Cable Modem
|
||||
* Termination System is putting out onto an Ethernet (it
|
||||
* doesn't put an Ethernet header onto the wire, it puts raw
|
||||
* DOCSIS frames out on the wire inside the low-level
|
||||
* Ethernet framing).
|
||||
*/
|
||||
p->dlt_list = (u_int *) malloc(sizeof(u_int) * 2);
|
||||
/*
|
||||
* If that fails, just leave the list empty.
|
||||
*/
|
||||
if (p->dlt_list != NULL) {
|
||||
p->dlt_list[0] = DLT_EN10MB;
|
||||
p->dlt_list[1] = DLT_DOCSIS;
|
||||
p->dlt_count = 2;
|
||||
}
|
||||
break;
|
||||
|
||||
case DL_FDDI:
|
||||
@ -593,6 +786,9 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||
break;
|
||||
|
||||
case DL_TPR:
|
||||
/*
|
||||
* XXX - what about DL_TPB? Is that Token Bus?
|
||||
*/
|
||||
p->linktype = DLT_IEEE802;
|
||||
p->offset = 2;
|
||||
break;
|
||||
@ -711,6 +907,7 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||
p->selectable_fd = p->fd;
|
||||
|
||||
p->read_op = pcap_read_dlpi;
|
||||
p->inject_op = pcap_inject_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;
|
||||
@ -722,6 +919,13 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||
bad:
|
||||
if (p->fd >= 0)
|
||||
close(p->fd);
|
||||
if (p->send_fd >= 0)
|
||||
close(p->send_fd);
|
||||
/*
|
||||
* Get rid of any link-layer type list we allocated.
|
||||
*/
|
||||
if (p->dlt_list != NULL)
|
||||
free(p->dlt_list);
|
||||
free(p);
|
||||
return (NULL);
|
||||
}
|
||||
@ -739,7 +943,7 @@ split_dname(char *device, int *unitp, char *ebuf)
|
||||
{
|
||||
char *cp;
|
||||
char *eos;
|
||||
int unit;
|
||||
long unit;
|
||||
|
||||
/*
|
||||
* Look for a number at the end of the device name string.
|
||||
@ -755,15 +959,37 @@ split_dname(char *device, int *unitp, char *ebuf)
|
||||
while (cp-1 >= device && *(cp-1) >= '0' && *(cp-1) <= '9')
|
||||
cp--;
|
||||
|
||||
errno = 0;
|
||||
unit = strtol(cp, &eos, 10);
|
||||
if (*eos != '\0') {
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s bad unit number", device);
|
||||
return (NULL);
|
||||
}
|
||||
*unitp = unit;
|
||||
if (errno == ERANGE || unit > INT_MAX) {
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s unit number too large",
|
||||
device);
|
||||
return (NULL);
|
||||
}
|
||||
if (unit < 0) {
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s unit number is negative",
|
||||
device);
|
||||
return (NULL);
|
||||
}
|
||||
*unitp = (int)unit;
|
||||
return (cp);
|
||||
}
|
||||
|
||||
static int
|
||||
dl_doattach(int fd, int ppa, char *ebuf)
|
||||
{
|
||||
bpf_u_int32 buf[MAXDLBUF];
|
||||
|
||||
if (dlattachreq(fd, ppa, ebuf) < 0 ||
|
||||
dlokack(fd, "attach", (char *)buf, ebuf) < 0)
|
||||
return (-1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
|
||||
{
|
||||
@ -1170,6 +1396,42 @@ dlinfoack(int fd, char *bufp, char *ebuf)
|
||||
return (recv_ack(fd, DL_INFO_ACK_SIZE, "info", bufp, ebuf));
|
||||
}
|
||||
|
||||
#ifdef DL_HP_RAWDLS
|
||||
/*
|
||||
* There's an ack *if* there's an error.
|
||||
*/
|
||||
static int
|
||||
dlrawdatareq(int fd, const u_char *datap, int datalen)
|
||||
{
|
||||
struct strbuf ctl, data;
|
||||
long buf[MAXDLBUF]; /* XXX - char? */
|
||||
union DL_primitives *dlp;
|
||||
int dlen;
|
||||
|
||||
dlp = (union DL_primitives*) buf;
|
||||
|
||||
dlp->dl_primitive = DL_HP_RAWDATA_REQ;
|
||||
dlen = DL_HP_RAWDATA_REQ_SIZE;
|
||||
|
||||
/*
|
||||
* HP's documentation doesn't appear to show us supplying any
|
||||
* address pointed to by the control part of the message.
|
||||
* I think that's what raw mode means - you just send the raw
|
||||
* packet, you don't specify where to send it to, as that's
|
||||
* implied by the destination address.
|
||||
*/
|
||||
ctl.maxlen = 0;
|
||||
ctl.len = dlen;
|
||||
ctl.buf = (void *)buf;
|
||||
|
||||
data.maxlen = 0;
|
||||
data.len = datalen;
|
||||
data.buf = (void *)datap;
|
||||
|
||||
return (putmsg(fd, &ctl, &data, 0));
|
||||
}
|
||||
#endif /* DL_HP_RAWDLS */
|
||||
|
||||
#ifdef HAVE_SYS_BUFMOD_H
|
||||
static int
|
||||
strioctl(int fd, int cmd, int len, char *dp)
|
||||
@ -1216,7 +1478,7 @@ get_release(bpf_u_int32 *majorp, bpf_u_int32 *minorp, bpf_u_int32 *microp)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DL_HP_PPA_ACK_OBS
|
||||
#ifdef DL_HP_PPA_REQ
|
||||
/*
|
||||
* Under HP-UX 10 and HP-UX 11, we can ask for the ppa
|
||||
*/
|
||||
|
1473
contrib/libpcap/pcap-dos.c
Normal file
1473
contrib/libpcap/pcap-dos.c
Normal file
File diff suppressed because it is too large
Load Diff
227
contrib/libpcap/pcap-dos.h
Normal file
227
contrib/libpcap/pcap-dos.h
Normal file
@ -0,0 +1,227 @@
|
||||
/*
|
||||
* Internal details for libpcap on DOS.
|
||||
* 32-bit targets: djgpp, Pharlap or DOS4GW.
|
||||
*
|
||||
* @(#) $Header: /tcpdump/master/libpcap/pcap-dos.h,v 1.1 2004/12/18 08:52:10 guy Exp $ (LBL)
|
||||
*/
|
||||
|
||||
#ifndef __PCAP_DOS_H
|
||||
#define __PCAP_DOS_H
|
||||
|
||||
#ifdef __DJGPP__
|
||||
#include <pc.h> /* simple non-conio kbhit */
|
||||
#else
|
||||
#include <conio.h>
|
||||
#endif
|
||||
|
||||
typedef int BOOL;
|
||||
typedef unsigned char BYTE;
|
||||
typedef unsigned short WORD;
|
||||
typedef unsigned long DWORD;
|
||||
typedef BYTE ETHER[6];
|
||||
|
||||
#define ETH_ALEN sizeof(ETHER) /* Ether address length */
|
||||
#define ETH_HLEN (2*ETH_ALEN+2) /* Ether header length */
|
||||
#define ETH_MTU 1500
|
||||
#define ETH_MIN 60
|
||||
#define ETH_MAX (ETH_MTU+ETH_HLEN)
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#define PHARLAP 1
|
||||
#define DJGPP 2
|
||||
#define DOS4GW 4
|
||||
|
||||
#ifdef __DJGPP__
|
||||
#undef DOSX
|
||||
#define DOSX DJGPP
|
||||
#endif
|
||||
|
||||
#ifdef __WATCOMC__
|
||||
#undef DOSX
|
||||
#define DOSX DOS4GW
|
||||
#endif
|
||||
|
||||
#ifdef __HIGHC__
|
||||
#include <pharlap.h>
|
||||
#undef DOSX
|
||||
#define DOSX PHARLAP
|
||||
#define inline
|
||||
#else
|
||||
typedef unsigned int UINT;
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(__GNUC__) || defined(__HIGHC__)
|
||||
typedef unsigned long long uint64;
|
||||
typedef unsigned long long QWORD;
|
||||
#endif
|
||||
|
||||
#if defined(__WATCOMC__)
|
||||
typedef unsigned __int64 uint64;
|
||||
typedef unsigned __int64 QWORD;
|
||||
#endif
|
||||
|
||||
#define ARGSUSED(x) (void) x
|
||||
|
||||
#if defined (__SMALL__) || defined(__LARGE__)
|
||||
#define DOSX 0
|
||||
|
||||
#elif !defined(DOSX)
|
||||
#error DOSX not defined; 1 = PharLap, 2 = djgpp, 4 = DOS4GW
|
||||
#endif
|
||||
|
||||
#ifdef __HIGHC__
|
||||
#define min(a,b) _min(a,b)
|
||||
#define max(a,b) _max(a,b)
|
||||
#endif
|
||||
|
||||
#ifndef min
|
||||
#define min(a,b) ((a) < (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#ifndef max
|
||||
#define max(a,b) ((a) < (b) ? (b) : (a))
|
||||
#endif
|
||||
|
||||
#if !defined(_U_) && defined(__GNUC__)
|
||||
#define _U_ __attribute__((unused))
|
||||
#endif
|
||||
|
||||
#ifndef _U_
|
||||
#define _U_
|
||||
#endif
|
||||
|
||||
#if defined(USE_32BIT_DRIVERS)
|
||||
#include "msdos/pm_drvr/lock.h"
|
||||
|
||||
#ifndef RECEIVE_QUEUE_SIZE
|
||||
#define RECEIVE_QUEUE_SIZE 60
|
||||
#endif
|
||||
|
||||
#ifndef RECEIVE_BUF_SIZE
|
||||
#define RECEIVE_BUF_SIZE (ETH_MAX+20)
|
||||
#endif
|
||||
|
||||
extern struct device el2_dev LOCKED_VAR; /* 3Com EtherLink II */
|
||||
extern struct device el3_dev LOCKED_VAR; /* EtherLink III */
|
||||
extern struct device tc59_dev LOCKED_VAR; /* 3Com Vortex Card (?) */
|
||||
extern struct device tc515_dev LOCKED_VAR;
|
||||
extern struct device tc90x_dev LOCKED_VAR;
|
||||
extern struct device tc90bcx_dev LOCKED_VAR;
|
||||
extern struct device wd_dev LOCKED_VAR;
|
||||
extern struct device ne_dev LOCKED_VAR;
|
||||
extern struct device acct_dev LOCKED_VAR;
|
||||
extern struct device cs89_dev LOCKED_VAR;
|
||||
extern struct device rtl8139_dev LOCKED_VAR;
|
||||
|
||||
struct rx_ringbuf {
|
||||
volatile int in_index; /* queue index head */
|
||||
int out_index; /* queue index tail */
|
||||
int elem_size; /* size of each element */
|
||||
int num_elem; /* number of elements */
|
||||
char *buf_start; /* start of buffer pool */
|
||||
};
|
||||
|
||||
struct rx_elem {
|
||||
DWORD size; /* size copied to this element */
|
||||
BYTE data[ETH_MAX+10]; /* add some margin. data[0] should be */
|
||||
}; /* dword aligned */
|
||||
|
||||
extern BYTE *get_rxbuf (int len) LOCKED_FUNC;
|
||||
extern int peek_rxbuf (BYTE **buf);
|
||||
extern int release_rxbuf (BYTE *buf);
|
||||
|
||||
#else
|
||||
#define LOCKED_VAR
|
||||
#define LOCKED_FUNC
|
||||
|
||||
struct device {
|
||||
const char *name;
|
||||
const char *long_name;
|
||||
DWORD base_addr; /* device I/O address */
|
||||
int irq; /* device IRQ number */
|
||||
int dma; /* DMA channel */
|
||||
DWORD mem_start; /* shared mem start */
|
||||
DWORD mem_end; /* shared mem end */
|
||||
DWORD rmem_start; /* shmem "recv" start */
|
||||
DWORD rmem_end; /* shared "recv" end */
|
||||
|
||||
struct device *next; /* next device in list */
|
||||
|
||||
/* interface service routines */
|
||||
int (*probe)(struct device *dev);
|
||||
int (*open) (struct device *dev);
|
||||
void (*close)(struct device *dev);
|
||||
int (*xmit) (struct device *dev, const void *buf, int len);
|
||||
void *(*get_stats)(struct device *dev);
|
||||
void (*set_multicast_list)(struct device *dev);
|
||||
|
||||
/* driver-to-pcap receive buffer routines */
|
||||
int (*copy_rx_buf) (BYTE *buf, int max); /* rx-copy (pktdrvr only) */
|
||||
BYTE *(*get_rx_buf) (int len); /* rx-buf fetch/enqueue */
|
||||
int (*peek_rx_buf) (BYTE **buf); /* rx-non-copy at queue */
|
||||
int (*release_rx_buf) (BYTE *buf); /* release after peek */
|
||||
|
||||
WORD flags; /* Low-level status flags. */
|
||||
void *priv; /* private data */
|
||||
};
|
||||
|
||||
/*
|
||||
* Network device statistics
|
||||
*/
|
||||
typedef struct net_device_stats {
|
||||
DWORD rx_packets; /* total packets received */
|
||||
DWORD tx_packets; /* total packets transmitted */
|
||||
DWORD rx_bytes; /* total bytes received */
|
||||
DWORD tx_bytes; /* total bytes transmitted */
|
||||
DWORD rx_errors; /* bad packets received */
|
||||
DWORD tx_errors; /* packet transmit problems */
|
||||
DWORD rx_dropped; /* no space in Rx buffers */
|
||||
DWORD tx_dropped; /* no space available for Tx */
|
||||
DWORD multicast; /* multicast packets received */
|
||||
|
||||
/* detailed rx_errors: */
|
||||
DWORD rx_length_errors;
|
||||
DWORD rx_over_errors; /* recv'r overrun error */
|
||||
DWORD rx_osize_errors; /* recv'r over-size error */
|
||||
DWORD rx_crc_errors; /* recv'd pkt with crc error */
|
||||
DWORD rx_frame_errors; /* recv'd frame alignment error */
|
||||
DWORD rx_fifo_errors; /* recv'r fifo overrun */
|
||||
DWORD rx_missed_errors; /* recv'r missed packet */
|
||||
|
||||
/* detailed tx_errors */
|
||||
DWORD tx_aborted_errors;
|
||||
DWORD tx_carrier_errors;
|
||||
DWORD tx_fifo_errors;
|
||||
DWORD tx_heartbeat_errors;
|
||||
DWORD tx_window_errors;
|
||||
DWORD tx_collisions;
|
||||
DWORD tx_jabbers;
|
||||
} NET_STATS;
|
||||
#endif
|
||||
|
||||
extern struct device *active_dev LOCKED_VAR;
|
||||
extern const struct device *dev_base LOCKED_VAR;
|
||||
extern struct device *probed_dev;
|
||||
|
||||
extern int pcap_pkt_debug;
|
||||
|
||||
extern void _w32_os_yield (void); /* Watt-32's misc.c */
|
||||
|
||||
#ifdef NDEBUG
|
||||
#define PCAP_ASSERT(x) ((void)0)
|
||||
|
||||
#else
|
||||
void pcap_assert (const char *what, const char *file, unsigned line);
|
||||
|
||||
#define PCAP_ASSERT(x) do { \
|
||||
if (!(x)) \
|
||||
pcap_assert (#x, __FILE__, __LINE__); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#endif /* __PCAP_DOS_H */
|
@ -8,7 +8,7 @@
|
||||
*/
|
||||
#ifndef lint
|
||||
static const char rcsid[] _U_ =
|
||||
"@(#) $Header: /tcpdump/master/libpcap/pcap-enet.c,v 1.7.2.1 2003/11/15 23:26:44 guy Exp $";
|
||||
"@(#) $Header: /tcpdump/master/libpcap/pcap-enet.c,v 1.8 2003/11/15 23:24:02 guy Exp $";
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
|
@ -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.55.2.4 2003/12/15 01:42:24 guy Exp $ (LBL)
|
||||
* @(#) $Header: /tcpdump/master/libpcap/pcap-int.h,v 1.68 2004/12/18 08:52:10 guy Exp $ (LBL)
|
||||
*/
|
||||
|
||||
#ifndef pcap_int_h
|
||||
@ -46,6 +46,11 @@ extern "C" {
|
||||
#include <packet32.h>
|
||||
#endif /* WIN32 */
|
||||
|
||||
#ifdef MSDOS
|
||||
#include <fcntl.h>
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Savefile
|
||||
*/
|
||||
@ -74,13 +79,14 @@ struct pcap_md {
|
||||
u_long TotDrops; /* count of dropped packets */
|
||||
long TotMissed; /* missed by i/f during this run */
|
||||
long OrigMissed; /* missed by i/f before this run */
|
||||
char *device; /* device name */
|
||||
#ifdef linux
|
||||
int sock_packet; /* using Linux 2.0 compatible interface */
|
||||
int timeout; /* timeout specified to pcap_open_live */
|
||||
int clear_promisc; /* must clear promiscuous mode when we close */
|
||||
int cooked; /* using SOCK_DGRAM rather than SOCK_RAW */
|
||||
int ifindex; /* interface index of device we're bound to */
|
||||
int lo_ifindex; /* interface index of the loopback device */
|
||||
char *device; /* device name */
|
||||
struct pcap *next; /* list of open promiscuous sock_packet pcaps */
|
||||
#endif
|
||||
|
||||
@ -89,7 +95,7 @@ struct pcap_md {
|
||||
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(). */
|
||||
int dag_offset_flags; /* Flags to pass to dag_offset(). */
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -102,6 +108,7 @@ struct pcap {
|
||||
#else
|
||||
int fd;
|
||||
int selectable_fd;
|
||||
int send_fd;
|
||||
#endif /* WIN32 */
|
||||
int snapshot;
|
||||
int linktype;
|
||||
@ -110,6 +117,15 @@ struct pcap {
|
||||
|
||||
int break_loop; /* flag set to force break from packet-reading loop */
|
||||
|
||||
#ifdef PCAP_FDDIPAD
|
||||
int fddipad;
|
||||
#endif
|
||||
|
||||
#ifdef MSDOS
|
||||
int inter_packet_wait; /* offline: wait between packets */
|
||||
void (*wait_proc)(void); /* call proc while waiting */
|
||||
#endif
|
||||
|
||||
struct pcap_sf sf;
|
||||
struct pcap_md md;
|
||||
|
||||
@ -130,6 +146,7 @@ struct pcap {
|
||||
* Methods.
|
||||
*/
|
||||
int (*read_op)(pcap_t *, int cnt, pcap_handler, u_char *);
|
||||
int (*inject_op)(pcap_t *, const void *, size_t);
|
||||
int (*setfilter_op)(pcap_t *, struct bpf_program *);
|
||||
int (*set_datalink_op)(pcap_t *, int);
|
||||
int (*getnonblock_op)(pcap_t *, char *);
|
||||
@ -144,7 +161,7 @@ struct pcap {
|
||||
|
||||
char errbuf[PCAP_ERRBUF_SIZE + 1];
|
||||
int dlt_count;
|
||||
int *dlt_list;
|
||||
u_int *dlt_list;
|
||||
|
||||
struct pcap_pkthdr pcap_header; /* This is needed for the pcap_next_ex() to work */
|
||||
};
|
||||
@ -252,11 +269,13 @@ extern int vsnprintf (char *, size_t, const char *, va_list ap);
|
||||
/*
|
||||
* Routines that most pcap implementations can use for non-blocking mode.
|
||||
*/
|
||||
#ifndef WIN32
|
||||
#if !defined(WIN32) && !defined(MSDOS)
|
||||
int pcap_getnonblock_fd(pcap_t *, char *);
|
||||
int pcap_setnonblock_fd(pcap_t *p, int, char *);
|
||||
#endif
|
||||
|
||||
void pcap_close_common(pcap_t *);
|
||||
|
||||
/*
|
||||
* Internal interfaces for "pcap_findalldevs()".
|
||||
*
|
||||
@ -267,10 +286,10 @@ int pcap_setnonblock_fd(pcap_t *p, int, char *);
|
||||
* "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 *,
|
||||
int add_addr_to_iflist(pcap_if_t **, const 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 *);
|
||||
int pcap_add_if(pcap_if_t **, const 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 *);
|
||||
@ -279,9 +298,6 @@ int add_or_find_if(pcap_if_t **, pcap_if_t **, const char *, u_int,
|
||||
char *pcap_win32strerror(void);
|
||||
#endif
|
||||
|
||||
/* XXX */
|
||||
extern int pcap_fddipad;
|
||||
|
||||
int install_bpf_program(pcap_t *, struct bpf_program *);
|
||||
|
||||
int pcap_strcasecmp(const char *, const char *);
|
||||
|
@ -27,7 +27,7 @@
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid[] _U_ =
|
||||
"@(#) $Header: /tcpdump/master/libpcap/pcap-linux.c,v 1.98.2.4 2003/11/21 10:20:46 guy Exp $ (LBL)";
|
||||
"@(#) $Header: /tcpdump/master/libpcap/pcap-linux.c,v 1.110 2004/10/19 07:06:12 guy Exp $ (LBL)";
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -188,6 +188,7 @@ static int live_open_old(pcap_t *, const char *, int, int, char *);
|
||||
static int live_open_new(pcap_t *, const char *, int, int, char *);
|
||||
static int pcap_read_linux(pcap_t *, int, pcap_handler, u_char *);
|
||||
static int pcap_read_packet(pcap_t *, pcap_handler, u_char *);
|
||||
static int pcap_inject_linux(pcap_t *, const void *, size_t);
|
||||
static int pcap_stats_linux(pcap_t *, struct pcap_stat *);
|
||||
static int pcap_setfilter_linux(pcap_t *, struct bpf_program *);
|
||||
static void pcap_close_linux(pcap_t *);
|
||||
@ -404,6 +405,7 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||
handle->selectable_fd = handle->fd;
|
||||
|
||||
handle->read_op = pcap_read_linux;
|
||||
handle->inject_op = pcap_inject_linux;
|
||||
handle->setfilter_op = pcap_setfilter_linux;
|
||||
handle->set_datalink_op = NULL; /* can't change data link type */
|
||||
handle->getnonblock_op = pcap_getnonblock_fd;
|
||||
@ -672,6 +674,49 @@ pcap_read_packet(pcap_t *handle, pcap_handler callback, u_char *userdata)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_inject_linux(pcap_t *handle, const void *buf, size_t size)
|
||||
{
|
||||
int ret;
|
||||
|
||||
#ifdef HAVE_PF_PACKET_SOCKETS
|
||||
if (!handle->md.sock_packet) {
|
||||
/* PF_PACKET socket */
|
||||
if (handle->md.ifindex == -1) {
|
||||
/*
|
||||
* We don't support sending on the "any" device.
|
||||
*/
|
||||
strlcpy(handle->errbuf,
|
||||
"Sending packets isn't supported on the \"any\" device",
|
||||
PCAP_ERRBUF_SIZE);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (handle->md.cooked) {
|
||||
/*
|
||||
* We don't support sending on the "any" device.
|
||||
*
|
||||
* XXX - how do you send on a bound cooked-mode
|
||||
* socket?
|
||||
* Is a "sendto()" required there?
|
||||
*/
|
||||
strlcpy(handle->errbuf,
|
||||
"Sending packets isn't supported in cooked mode",
|
||||
PCAP_ERRBUF_SIZE);
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = send(handle->fd, buf, size, 0);
|
||||
if (ret == -1) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
|
||||
pcap_strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the statistics for the given packet capture handle.
|
||||
* Reports the number of dropped packets iff the kernel supports
|
||||
@ -717,9 +762,13 @@ pcap_stats_linux(pcap_t *handle, struct pcap_stat *stats)
|
||||
* platforms, but the best approximation is to return
|
||||
* "tp_packets" as the count of packets and "tp_drops"
|
||||
* as the count of drops.
|
||||
*
|
||||
* Keep a running total because each call to
|
||||
* getsockopt(handle->fd, SOL_PACKET, PACKET_STATISTICS, ....
|
||||
* resets the counters to zero.
|
||||
*/
|
||||
handle->md.stat.ps_recv = kstats.tp_packets;
|
||||
handle->md.stat.ps_drop = kstats.tp_drops;
|
||||
handle->md.stat.ps_recv += kstats.tp_packets;
|
||||
handle->md.stat.ps_drop += kstats.tp_drops;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -948,6 +997,34 @@ static void map_arphrd_to_dlt(pcap_t *handle, int arptype, int cooked_ok)
|
||||
switch (arptype) {
|
||||
|
||||
case ARPHRD_ETHER:
|
||||
/*
|
||||
* This is (presumably) a real Ethernet capture; give it a
|
||||
* link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so
|
||||
* that an application can let you choose it, in case you're
|
||||
* capturing DOCSIS traffic that a Cisco Cable Modem
|
||||
* Termination System is putting out onto an Ethernet (it
|
||||
* doesn't put an Ethernet header onto the wire, it puts raw
|
||||
* DOCSIS frames out on the wire inside the low-level
|
||||
* Ethernet framing).
|
||||
*
|
||||
* XXX - are there any sorts of "fake Ethernet" that have
|
||||
* ARPHRD_ETHER but that *shouldn't offer DLT_DOCSIS as
|
||||
* a Cisco CMTS won't put traffic onto it or get traffic
|
||||
* bridged onto it? ISDN is handled in "live_open_new()",
|
||||
* as we fall back on cooked mode there; are there any
|
||||
* others?
|
||||
*/
|
||||
handle->dlt_list = (u_int *) malloc(sizeof(u_int) * 2);
|
||||
/*
|
||||
* If that fails, just leave the list empty.
|
||||
*/
|
||||
if (handle->dlt_list != NULL) {
|
||||
handle->dlt_list[0] = DLT_EN10MB;
|
||||
handle->dlt_list[1] = DLT_DOCSIS;
|
||||
handle->dlt_count = 2;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case ARPHRD_METRICOM:
|
||||
case ARPHRD_LOOPBACK:
|
||||
handle->linktype = DLT_EN10MB;
|
||||
@ -1163,6 +1240,9 @@ static void map_arphrd_to_dlt(pcap_t *handle, int arptype, int cooked_ok)
|
||||
handle->linktype = DLT_IP_OVER_FC;
|
||||
break;
|
||||
|
||||
#ifndef ARPHRD_IRDA
|
||||
#define ARPHRD_IRDA 783
|
||||
#endif
|
||||
case ARPHRD_IRDA:
|
||||
/* Don't expect IP packet out of this interfaces... */
|
||||
handle->linktype = DLT_LINUX_IRDA;
|
||||
@ -1189,7 +1269,7 @@ live_open_new(pcap_t *handle, const char *device, int promisc,
|
||||
int to_ms, char *ebuf)
|
||||
{
|
||||
#ifdef HAVE_PF_PACKET_SOCKETS
|
||||
int sock_fd = -1, device_id, arptype;
|
||||
int sock_fd = -1, arptype;
|
||||
int err;
|
||||
int fatal_err = 0;
|
||||
struct packet_mreq mr;
|
||||
@ -1278,6 +1358,17 @@ live_open_new(pcap_t *handle, const char *device, int promisc,
|
||||
}
|
||||
handle->md.cooked = 1;
|
||||
|
||||
/*
|
||||
* Get rid of any link-layer type list
|
||||
* we allocated - this only supports cooked
|
||||
* capture.
|
||||
*/
|
||||
if (handle->dlt_list != NULL) {
|
||||
free(handle->dlt_list);
|
||||
handle->dlt_list = NULL;
|
||||
handle->dlt_count = 0;
|
||||
}
|
||||
|
||||
if (handle->linktype == -1) {
|
||||
/*
|
||||
* Warn that we're falling back on
|
||||
@ -1294,15 +1385,16 @@ live_open_new(pcap_t *handle, const char *device, int promisc,
|
||||
}
|
||||
/* IrDA capture is not a real "cooked" capture,
|
||||
* it's IrLAP frames, not IP packets. */
|
||||
if(handle->linktype != DLT_LINUX_IRDA)
|
||||
if (handle->linktype != DLT_LINUX_IRDA)
|
||||
handle->linktype = DLT_LINUX_SLL;
|
||||
}
|
||||
|
||||
device_id = iface_get_id(sock_fd, device, ebuf);
|
||||
if (device_id == -1)
|
||||
handle->md.ifindex = iface_get_id(sock_fd, device, ebuf);
|
||||
if (handle->md.ifindex == -1)
|
||||
break;
|
||||
|
||||
if ((err = iface_bind(sock_fd, device_id, ebuf)) < 0) {
|
||||
if ((err = iface_bind(sock_fd, handle->md.ifindex,
|
||||
ebuf)) < 0) {
|
||||
if (err == -2)
|
||||
fatal_err = 1;
|
||||
break;
|
||||
@ -1315,14 +1407,15 @@ live_open_new(pcap_t *handle, const char *device, int promisc,
|
||||
handle->linktype = DLT_LINUX_SLL;
|
||||
|
||||
/*
|
||||
* XXX - squelch GCC complaints about
|
||||
* uninitialized variables; if we can't
|
||||
* select promiscuous mode on all interfaces,
|
||||
* we should move the code below into the
|
||||
* "if (device)" branch of the "if" and
|
||||
* get rid of the next statement.
|
||||
* We're not bound to a device.
|
||||
* XXX - true? Or true only if we're using
|
||||
* the "any" device?
|
||||
* For now, we're using this as an indication
|
||||
* that we can't transmit; stop doing that only
|
||||
* if we figure out how to transmit in cooked
|
||||
* mode.
|
||||
*/
|
||||
device_id = -1;
|
||||
handle->md.ifindex = -1;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1346,7 +1439,7 @@ live_open_new(pcap_t *handle, const char *device, int promisc,
|
||||
|
||||
if (device && promisc) {
|
||||
memset(&mr, 0, sizeof(mr));
|
||||
mr.mr_ifindex = device_id;
|
||||
mr.mr_ifindex = handle->md.ifindex;
|
||||
mr.mr_type = PACKET_MR_PROMISC;
|
||||
if (setsockopt(sock_fd, SOL_PACKET,
|
||||
PACKET_ADD_MEMBERSHIP, &mr, sizeof(mr)) == -1)
|
||||
@ -1368,9 +1461,14 @@ live_open_new(pcap_t *handle, const char *device, int promisc,
|
||||
if (sock_fd != -1)
|
||||
close(sock_fd);
|
||||
|
||||
if (fatal_err)
|
||||
if (fatal_err) {
|
||||
/*
|
||||
* Get rid of any link-layer type list we allocated.
|
||||
*/
|
||||
if (handle->dlt_list != NULL)
|
||||
free(handle->dlt_list);
|
||||
return -2;
|
||||
else
|
||||
} else
|
||||
return 0;
|
||||
#else
|
||||
strncpy(ebuf,
|
||||
@ -1546,10 +1644,7 @@ static void pcap_close_linux( pcap_t *handle )
|
||||
if (handle->md.device != NULL)
|
||||
free(handle->md.device);
|
||||
handle->md.device = NULL;
|
||||
if (handle->buffer != NULL)
|
||||
free(handle->buffer);
|
||||
if (handle->fd >= 0)
|
||||
close(handle->fd);
|
||||
pcap_close_common(handle);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -30,11 +30,11 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#) $Header: /tcpdump/master/libpcap/pcap-namedb.h,v 1.8 2000/07/29 07:36:43 guy Exp $ (LBL)
|
||||
* @(#) $Header: /tcpdump/master/libpcap/pcap-namedb.h,v 1.10 2005/03/17 07:02:32 guy Exp $ (LBL)
|
||||
*/
|
||||
|
||||
#ifndef lib_pcap_ethers_h
|
||||
#define lib_pcap_ethers_h
|
||||
#ifndef lib_pcap_namedb_h
|
||||
#define lib_pcap_namedb_h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -67,6 +67,7 @@ bpf_u_int32 pcap_nametonetaddr(const char *);
|
||||
int pcap_nametoport(const char *, int *, int *);
|
||||
int pcap_nametoproto(const char *);
|
||||
int pcap_nametoeproto(const char *);
|
||||
int pcap_nametollc(const char *);
|
||||
/*
|
||||
* If a protocol is unknown, PROTO_UNDEF is returned.
|
||||
* Also, pcap_nametoport() returns the protocol along with the port number.
|
||||
|
@ -20,7 +20,7 @@
|
||||
*/
|
||||
#ifndef lint
|
||||
static const char rcsid[] _U_ =
|
||||
"@(#) $Header: /tcpdump/master/libpcap/pcap-nit.c,v 1.50.2.4 2004/03/21 08:33:23 guy Exp $ (LBL)";
|
||||
"@(#) $Header: /tcpdump/master/libpcap/pcap-nit.c,v 1.57 2004/10/19 07:06:13 guy Exp $ (LBL)";
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
@ -192,6 +192,23 @@ pcap_read_nit(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
return (n);
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_inject_nit(pcap_t *p, const void *buf, size_t size)
|
||||
{
|
||||
struct sockaddr sa;
|
||||
int ret;
|
||||
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
strncpy(sa.sa_data, device, sizeof(sa.sa_data));
|
||||
ret = sendto(p->fd, buf, size, 0, &sa, sizeof(sa));
|
||||
if (ret == -1) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
|
||||
pcap_strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static int
|
||||
nit_setflags(int fd, int promisc, int to_ms, char *ebuf)
|
||||
{
|
||||
@ -224,10 +241,9 @@ nit_setflags(int fd, int promisc, int to_ms, char *ebuf)
|
||||
static void
|
||||
pcap_close_nit(pcap_t *p)
|
||||
{
|
||||
if (p->buffer != NULL)
|
||||
free(p->buffer);
|
||||
if (p->fd >= 0)
|
||||
close(p->fd);
|
||||
pcap_close_common(p);
|
||||
if (p->device != NULL)
|
||||
free(p->device);
|
||||
}
|
||||
|
||||
pcap_t *
|
||||
@ -280,12 +296,43 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||
goto bad;
|
||||
}
|
||||
|
||||
/*
|
||||
* We need the device name in order to send packets.
|
||||
*/
|
||||
p->device = strdup(device);
|
||||
if (p->device == NULL) {
|
||||
strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
|
||||
free(p->buffer);
|
||||
goto bad;
|
||||
}
|
||||
|
||||
/*
|
||||
* "p->fd" is a socket, so "select()" should work on it.
|
||||
*/
|
||||
p->selectable_fd = p->fd;
|
||||
|
||||
/*
|
||||
* This is (presumably) a real Ethernet capture; give it a
|
||||
* link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so
|
||||
* that an application can let you choose it, in case you're
|
||||
* capturing DOCSIS traffic that a Cisco Cable Modem
|
||||
* Termination System is putting out onto an Ethernet (it
|
||||
* doesn't put an Ethernet header onto the wire, it puts raw
|
||||
* DOCSIS frames out on the wire inside the low-level
|
||||
* Ethernet framing).
|
||||
*/
|
||||
p->dlt_list = (u_int *) malloc(sizeof(u_int) * 2);
|
||||
/*
|
||||
* If that fails, just leave the list empty.
|
||||
*/
|
||||
if (p->dlt_list != NULL) {
|
||||
p->dlt_list[0] = DLT_EN10MB;
|
||||
p->dlt_list[1] = DLT_DOCSIS;
|
||||
p->dlt_count = 2;
|
||||
}
|
||||
|
||||
p->read_op = pcap_read_nit;
|
||||
p->inject_op = pcap_inject_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;
|
||||
|
@ -20,7 +20,7 @@
|
||||
*/
|
||||
#ifndef lint
|
||||
static const char rcsid[] _U_ =
|
||||
"@(#) $Header: /tcpdump/master/libpcap/pcap-null.c,v 1.20.2.1 2003/11/15 23:26:45 guy Exp $ (LBL)";
|
||||
"@(#) $Header: /tcpdump/master/libpcap/pcap-null.c,v 1.21 2003/11/15 23:24:03 guy Exp $ (LBL)";
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
|
@ -24,7 +24,7 @@
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid[] _U_ =
|
||||
"@(#) $Header: /tcpdump/master/libpcap/pcap-pf.c,v 1.79.2.5 2003/11/22 00:32:55 guy Exp $ (LBL)";
|
||||
"@(#) $Header: /tcpdump/master/libpcap/pcap-pf.c,v 1.91 2005/02/26 21:58:06 guy Exp $ (LBL)";
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
@ -129,10 +129,7 @@ pcap_read_pf(pcap_t *pc, int cnt, pcap_handler callback, u_char *user)
|
||||
*/
|
||||
n = 0;
|
||||
#ifdef PCAP_FDDIPAD
|
||||
if (pc->linktype == DLT_FDDI)
|
||||
pad = pcap_fddipad;
|
||||
else
|
||||
pad = 0;
|
||||
pad = p->fddipad;
|
||||
#endif
|
||||
while (cc > 0) {
|
||||
/*
|
||||
@ -182,10 +179,6 @@ pcap_read_pf(pcap_t *pc, int cnt, pcap_handler callback, u_char *user)
|
||||
inc = ENALIGN(buflen + sp->ens_stamplen);
|
||||
cc -= inc;
|
||||
bp += inc;
|
||||
#ifdef PCAP_FDDIPAD
|
||||
p += pad;
|
||||
buflen -= pad;
|
||||
#endif
|
||||
pc->md.TotPkts++;
|
||||
pc->md.TotDrops += sp->ens_dropped;
|
||||
pc->md.TotMissed = sp->ens_ifoverflows;
|
||||
@ -195,6 +188,14 @@ pcap_read_pf(pcap_t *pc, int cnt, pcap_handler callback, u_char *user)
|
||||
/*
|
||||
* Short-circuit evaluation: if using BPF filter
|
||||
* in kernel, no need to do it now.
|
||||
*
|
||||
#ifdef PCAP_FDDIPAD
|
||||
* Note: the filter code was generated assuming
|
||||
* that p->fddipad was the amount of padding
|
||||
* before the header, as that's what's required
|
||||
* in the kernel, so we run the filter before
|
||||
* skipping that padding.
|
||||
#endif
|
||||
*/
|
||||
if (fcode == NULL ||
|
||||
bpf_filter(fcode, p, sp->ens_count, buflen)) {
|
||||
@ -205,6 +206,10 @@ pcap_read_pf(pcap_t *pc, int cnt, pcap_handler callback, u_char *user)
|
||||
h.len = sp->ens_count - pad;
|
||||
#else
|
||||
h.len = sp->ens_count;
|
||||
#endif
|
||||
#ifdef PCAP_FDDIPAD
|
||||
p += pad;
|
||||
buflen -= pad;
|
||||
#endif
|
||||
h.caplen = buflen;
|
||||
(*callback)(user, &h, p);
|
||||
@ -219,6 +224,20 @@ pcap_read_pf(pcap_t *pc, int cnt, pcap_handler callback, u_char *user)
|
||||
return (n);
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_inject_pf(pcap_t *p, const void *buf, size_t size)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = write(p->fd, buf, size);
|
||||
if (ret == -1) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
|
||||
pcap_strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_stats_pf(pcap_t *p, struct pcap_stat *ps)
|
||||
{
|
||||
@ -265,14 +284,13 @@ pcap_stats_pf(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);
|
||||
}
|
||||
/*
|
||||
* We include the OS's <net/bpf.h>, not our "pcap-bpf.h", so we probably
|
||||
* don't get DLT_DOCSIS defined.
|
||||
*/
|
||||
#ifndef DLT_DOCSIS
|
||||
#define DLT_DOCSIS 143
|
||||
#endif
|
||||
|
||||
pcap_t *
|
||||
pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||
@ -291,14 +309,28 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||
return (0);
|
||||
}
|
||||
memset(p, 0, sizeof(*p));
|
||||
|
||||
/*
|
||||
* Initially try a read/write open (to allow the inject
|
||||
* method to work). If that fails due to permission
|
||||
* issues, fall back to read-only. This allows a
|
||||
* non-root user to be granted specific access to pcap
|
||||
* capabilities via file permissions.
|
||||
*
|
||||
* XXX - we should have an API that has a flag that
|
||||
* controls whether to open read-only or read-write,
|
||||
* so that denial of permission to send (or inability
|
||||
* to send, if sending packets isn't supported on
|
||||
* the device in question) can be indicated at open
|
||||
* time.
|
||||
*
|
||||
* 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);
|
||||
p->fd = pfopen(device, O_RDWR);
|
||||
if (p->fd == -1 && errno == EACCES)
|
||||
p->fd = pfopen(device, O_RDONLY);
|
||||
if (p->fd < 0) {
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "pf open: %s: %s\n\
|
||||
your system may not be properly configured; see the packetfilter(4) man page\n",
|
||||
@ -340,6 +372,25 @@ your system may not be properly configured; see the packetfilter(4) man page\n",
|
||||
case ENDT_10MB:
|
||||
p->linktype = DLT_EN10MB;
|
||||
p->offset = 2;
|
||||
/*
|
||||
* This is (presumably) a real Ethernet capture; give it a
|
||||
* link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so
|
||||
* that an application can let you choose it, in case you're
|
||||
* capturing DOCSIS traffic that a Cisco Cable Modem
|
||||
* Termination System is putting out onto an Ethernet (it
|
||||
* doesn't put an Ethernet header onto the wire, it puts raw
|
||||
* DOCSIS frames out on the wire inside the low-level
|
||||
* Ethernet framing).
|
||||
*/
|
||||
p->dlt_list = (u_int *) malloc(sizeof(u_int) * 2);
|
||||
/*
|
||||
* If that fails, just leave the list empty.
|
||||
*/
|
||||
if (p->dlt_list != NULL) {
|
||||
p->dlt_list[0] = DLT_EN10MB;
|
||||
p->dlt_list[1] = DLT_DOCSIS;
|
||||
p->dlt_count = 2;
|
||||
}
|
||||
break;
|
||||
|
||||
case ENDT_FDDI:
|
||||
@ -396,9 +447,13 @@ your system may not be properly configured; see the packetfilter(4) man page\n",
|
||||
}
|
||||
/* set truncation */
|
||||
#ifdef PCAP_FDDIPAD
|
||||
if (p->linktype == DLT_FDDI)
|
||||
if (p->linktype == DLT_FDDI) {
|
||||
p->fddipad = PCAP_FDDIPAD:
|
||||
|
||||
/* packetfilter includes the padding in the snapshot */
|
||||
snaplen += pcap_fddipad;
|
||||
snaplen += PCAP_FDDIPAD;
|
||||
} else
|
||||
p->fddipad = 0;
|
||||
#endif
|
||||
if (ioctl(p->fd, EIOCTRUNCATE, (caddr_t)&snaplen) < 0) {
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "EIOCTRUNCATE: %s",
|
||||
@ -440,17 +495,23 @@ your system may not be properly configured; see the packetfilter(4) man page\n",
|
||||
p->selectable_fd = p->fd;
|
||||
|
||||
p->read_op = pcap_read_pf;
|
||||
p->inject_op = pcap_inject_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;
|
||||
p->close_op = pcap_close_common;
|
||||
|
||||
return (p);
|
||||
bad:
|
||||
if (p->fd >= 0)
|
||||
close(p->fd);
|
||||
/*
|
||||
* Get rid of any link-layer type list we allocated.
|
||||
*/
|
||||
if (p->dlt_list != NULL)
|
||||
free(p->dlt_list);
|
||||
free(p);
|
||||
return (NULL);
|
||||
}
|
||||
@ -506,6 +567,16 @@ pcap_setfilter_pf(pcap_t *p, struct bpf_program *fp)
|
||||
*/
|
||||
fprintf(stderr, "tcpdump: Using kernel BPF filter\n");
|
||||
p->md.use_bpf = 1;
|
||||
|
||||
/*
|
||||
* Discard any previously-received packets,
|
||||
* as they might have passed whatever filter
|
||||
* was formerly in effect, but might not pass
|
||||
* this filter (BIOCSETF discards packets buffered
|
||||
* in the kernel, so you can lose packets in any
|
||||
* case).
|
||||
*/
|
||||
p->cc = 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid[] _U_ =
|
||||
"@(#) $Header: /tcpdump/master/libpcap/pcap-snit.c,v 1.66.2.3 2003/11/21 10:20:48 guy Exp $ (LBL)";
|
||||
"@(#) $Header: /tcpdump/master/libpcap/pcap-snit.c,v 1.72 2004/10/19 07:06:13 guy Exp $ (LBL)";
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
@ -204,6 +204,29 @@ pcap_read_snit(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
return (n);
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_inject_snit(pcap_t *p, const void *buf, size_t size)
|
||||
{
|
||||
struct strbuf ctl, data;
|
||||
|
||||
/*
|
||||
* XXX - can we just do
|
||||
*
|
||||
ret = write(pd->f, buf, size);
|
||||
*/
|
||||
ctl.len = sizeof(*sa); /* XXX - what was this? */
|
||||
ctl.buf = (char *)sa;
|
||||
data.buf = buf;
|
||||
data.len = size;
|
||||
ret = putmsg(p->fd, &ctl, &data);
|
||||
if (ret == -1) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
|
||||
pcap_strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static int
|
||||
nit_setflags(int fd, int promisc, int to_ms, char *ebuf)
|
||||
{
|
||||
@ -238,15 +261,6 @@ 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(const char *device, int snaplen, int promisc, int to_ms,
|
||||
char *ebuf)
|
||||
@ -271,7 +285,23 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||
snaplen = 96;
|
||||
|
||||
memset(p, 0, sizeof(*p));
|
||||
p->fd = fd = open(dev, O_RDONLY);
|
||||
/*
|
||||
* Initially try a read/write open (to allow the inject
|
||||
* method to work). If that fails due to permission
|
||||
* issues, fall back to read-only. This allows a
|
||||
* non-root user to be granted specific access to pcap
|
||||
* capabilities via file permissions.
|
||||
*
|
||||
* XXX - we should have an API that has a flag that
|
||||
* controls whether to open read-only or read-write,
|
||||
* so that denial of permission to send (or inability
|
||||
* to send, if sending packets isn't supported on
|
||||
* the device in question) can be indicated at open
|
||||
* time.
|
||||
*/
|
||||
p->fd = fd = open(dev, O_RDWR);
|
||||
if (fd < 0 && errno == EACCES)
|
||||
p->fd = fd = open(dev, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s: %s", dev,
|
||||
pcap_strerror(errno));
|
||||
@ -344,13 +374,34 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||
*/
|
||||
p->selectable_fd = p->fd;
|
||||
|
||||
/*
|
||||
* This is (presumably) a real Ethernet capture; give it a
|
||||
* link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so
|
||||
* that an application can let you choose it, in case you're
|
||||
* capturing DOCSIS traffic that a Cisco Cable Modem
|
||||
* Termination System is putting out onto an Ethernet (it
|
||||
* doesn't put an Ethernet header onto the wire, it puts raw
|
||||
* DOCSIS frames out on the wire inside the low-level
|
||||
* Ethernet framing).
|
||||
*/
|
||||
p->dlt_list = (u_int *) malloc(sizeof(u_int) * 2);
|
||||
/*
|
||||
* If that fails, just leave the list empty.
|
||||
*/
|
||||
if (p->dlt_list != NULL) {
|
||||
p->dlt_list[0] = DLT_EN10MB;
|
||||
p->dlt_list[1] = DLT_DOCSIS;
|
||||
p->dlt_count = 2;
|
||||
}
|
||||
|
||||
p->read_op = pcap_read_snit;
|
||||
p->inject_op = pcap_inject_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;
|
||||
p->close_op = pcap_close_common;
|
||||
|
||||
return (p);
|
||||
bad:
|
||||
|
@ -20,7 +20,7 @@
|
||||
*/
|
||||
#ifndef lint
|
||||
static const char rcsid[] _U_ =
|
||||
"@(#) $Header: /tcpdump/master/libpcap/pcap-snoop.c,v 1.45.2.5 2004/03/21 08:33:24 guy Exp $ (LBL)";
|
||||
"@(#) $Header: /tcpdump/master/libpcap/pcap-snoop.c,v 1.54 2004/10/19 07:06:14 guy Exp $ (LBL)";
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
@ -63,8 +63,8 @@ pcap_read_snoop(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
{
|
||||
int cc;
|
||||
register struct snoopheader *sh;
|
||||
register int datalen;
|
||||
register int caplen;
|
||||
register u_int datalen;
|
||||
register u_int caplen;
|
||||
register u_char *cp;
|
||||
|
||||
again:
|
||||
@ -97,6 +97,16 @@ pcap_read_snoop(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
}
|
||||
sh = (struct snoopheader *)p->buffer;
|
||||
datalen = sh->snoop_packetlen;
|
||||
|
||||
/*
|
||||
* XXX - Sigh, snoop_packetlen is a 16 bit quantity. If we
|
||||
* got a short length, but read a full sized snoop pakcet,
|
||||
* assume we overflowed and add back the 64K...
|
||||
*/
|
||||
if (cc == (p->snapshot + sizeof(struct snoopheader)) &&
|
||||
(datalen < p->snapshot))
|
||||
datalen += (64 * 1024);
|
||||
|
||||
caplen = (datalen < p->snapshot) ? datalen : p->snapshot;
|
||||
cp = (u_char *)(sh + 1) + p->offset; /* XXX */
|
||||
|
||||
@ -125,6 +135,24 @@ pcap_read_snoop(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_inject_snoop(pcap_t *p, const void *buf, size_t size)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* XXX - libnet overwrites the source address with what I
|
||||
* presume is the interface's address; is that required?
|
||||
*/
|
||||
ret = write(p->fd, buf, size);
|
||||
if (ret == -1) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
|
||||
pcap_strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_stats_snoop(pcap_t *p, struct pcap_stat *ps)
|
||||
{
|
||||
@ -165,15 +193,6 @@ pcap_stats_snoop(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(const char *device, int snaplen, int promisc, int to_ms,
|
||||
@ -237,6 +256,35 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||
p->linktype = DLT_EN10MB;
|
||||
p->offset = RAW_HDRPAD(sizeof(struct ether_header));
|
||||
ll_hdrlen = sizeof(struct ether_header);
|
||||
/*
|
||||
* This is (presumably) a real Ethernet capture; give it a
|
||||
* link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so
|
||||
* that an application can let you choose it, in case you're
|
||||
* capturing DOCSIS traffic that a Cisco Cable Modem
|
||||
* Termination System is putting out onto an Ethernet (it
|
||||
* doesn't put an Ethernet header onto the wire, it puts raw
|
||||
* DOCSIS frames out on the wire inside the low-level
|
||||
* Ethernet framing).
|
||||
*
|
||||
* XXX - are there any sorts of "fake Ethernet" that have
|
||||
* Ethernet link-layer headers but that *shouldn't offer
|
||||
* DLT_DOCSIS as a Cisco CMTS won't put traffic onto it
|
||||
* or get traffic bridged onto it? "el" is for ATM LANE
|
||||
* Ethernet devices, so that might be the case for them;
|
||||
* the same applies for "qaa" classical IP devices. If
|
||||
* "fa" devices are for FORE SPANS, that'd apply to them
|
||||
* as well; what are "cip" devices - some other ATM
|
||||
* Classical IP devices?
|
||||
*/
|
||||
p->dlt_list = (u_int *) malloc(sizeof(u_int) * 2);
|
||||
/*
|
||||
* If that fails, just leave the list empty.
|
||||
*/
|
||||
if (p->dlt_list != NULL) {
|
||||
p->dlt_list[0] = DLT_EN10MB;
|
||||
p->dlt_list[1] = DLT_DOCSIS;
|
||||
p->dlt_count = 2;
|
||||
}
|
||||
} else if (strncmp("ipg", device, 3) == 0 ||
|
||||
strncmp("rns", device, 3) == 0 || /* O2/200/2000 FDDI */
|
||||
strncmp("xpi", device, 3) == 0) {
|
||||
@ -329,16 +377,22 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||
p->selectable_fd = p->fd;
|
||||
|
||||
p->read_op = pcap_read_snoop;
|
||||
p->inject_op = pcap_inject_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;
|
||||
p->close_op = pcap_close_common;
|
||||
|
||||
return (p);
|
||||
bad:
|
||||
(void)close(fd);
|
||||
/*
|
||||
* Get rid of any link-layer type list we allocated.
|
||||
*/
|
||||
if (p->dlt_list != NULL)
|
||||
free(p->dlt_list);
|
||||
free(p);
|
||||
return (NULL);
|
||||
}
|
||||
|
@ -32,24 +32,32 @@
|
||||
|
||||
#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)";
|
||||
"@(#) $Header: /tcpdump/master/libpcap/pcap-win32.c,v 1.25 2005/02/26 21:58:06 guy Exp $ (LBL)";
|
||||
#endif
|
||||
|
||||
#include <pcap-int.h>
|
||||
#include <packet32.h>
|
||||
#include <Ntddndis.h>
|
||||
#ifdef HAVE_DAG_API
|
||||
#include <dagnew.h>
|
||||
#include <dagapi.h>
|
||||
#endif /* HAVE_DAG_API */
|
||||
#ifdef __MINGW32__
|
||||
int* _errno();
|
||||
#define errno (*_errno())
|
||||
#endif /* __MINGW32__ */
|
||||
|
||||
static int pcap_setfilter_win32(pcap_t *, struct bpf_program *);
|
||||
static int pcap_setfilter_win32_npf(pcap_t *, struct bpf_program *);
|
||||
static int pcap_setfilter_win32_dag(pcap_t *, struct bpf_program *);
|
||||
static int pcap_getnonblock_win32(pcap_t *, char *);
|
||||
static int pcap_setnonblock_win32(pcap_t *, int, char *);
|
||||
|
||||
#define PcapBufSize 256000 /*dimension of the buffer in the pcap_t structure*/
|
||||
#define SIZE_BUF 1000000
|
||||
|
||||
/* Equivalent to ntohs(), but a lot faster under Windows */
|
||||
#define SWAPS(_X) ((_X & 0xff) << 8) | (_X >> 8)
|
||||
|
||||
/*
|
||||
* Header that the WinPcap driver associates to the packets.
|
||||
* Once was in bpf.h
|
||||
@ -92,7 +100,7 @@ pcap_stats_win32(pcap_t *p, struct pcap_stat *ps)
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_read_win32(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
pcap_read_win32_npf(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
{
|
||||
int cc;
|
||||
int n = 0;
|
||||
@ -175,16 +183,209 @@ pcap_read_win32(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
return (n);
|
||||
}
|
||||
|
||||
#ifdef HAVE_DAG_API
|
||||
static int
|
||||
pcap_read_win32_dag(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
{
|
||||
u_char *dp = NULL;
|
||||
int packet_len = 0, caplen = 0;
|
||||
struct pcap_pkthdr pcap_header;
|
||||
u_char *endofbuf;
|
||||
int n = 0;
|
||||
dag_record_t *header;
|
||||
unsigned erf_record_len;
|
||||
ULONGLONG ts;
|
||||
int cc;
|
||||
unsigned swt;
|
||||
unsigned dfp = p->adapter->DagFastProcess;
|
||||
|
||||
cc = p->cc;
|
||||
if (cc == 0) /* Get new packets only if we have processed all the ones of the previous read */
|
||||
{
|
||||
/* Get new packets from the network */
|
||||
if(PacketReceivePacket(p->adapter, p->Packet, TRUE)==FALSE){
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read error: PacketReceivePacket failed");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
cc = p->Packet->ulBytesReceived;
|
||||
if(cc == 0)
|
||||
/* The timeout has expired but we no packets arrived */
|
||||
return 0;
|
||||
header = (dag_record_t*)p->adapter->DagBuffer;
|
||||
}
|
||||
else
|
||||
header = (dag_record_t*)p->bp;
|
||||
|
||||
endofbuf = (char*)header + cc;
|
||||
|
||||
/*
|
||||
* Cycle through the packets
|
||||
*/
|
||||
do
|
||||
{
|
||||
erf_record_len = SWAPS(header->rlen);
|
||||
if((char*)header + erf_record_len > endofbuf)
|
||||
break;
|
||||
|
||||
/* Increase the number of captured packets */
|
||||
p->md.stat.ps_recv++;
|
||||
|
||||
/* Find the beginning of the packet */
|
||||
dp = ((u_char *)header) + dag_record_size;
|
||||
|
||||
/* Determine actual packet len */
|
||||
switch(header->type)
|
||||
{
|
||||
case TYPE_ATM:
|
||||
packet_len = ATM_SNAPLEN;
|
||||
caplen = ATM_SNAPLEN;
|
||||
dp += 4;
|
||||
|
||||
break;
|
||||
|
||||
case TYPE_ETH:
|
||||
swt = SWAPS(header->wlen);
|
||||
packet_len = swt - (p->md.dag_fcs_bits);
|
||||
caplen = erf_record_len - dag_record_size - 2;
|
||||
if (caplen > packet_len)
|
||||
{
|
||||
caplen = packet_len;
|
||||
}
|
||||
dp += 2;
|
||||
|
||||
break;
|
||||
|
||||
case TYPE_HDLC_POS:
|
||||
swt = SWAPS(header->wlen);
|
||||
packet_len = swt - (p->md.dag_fcs_bits);
|
||||
caplen = erf_record_len - dag_record_size;
|
||||
if (caplen > packet_len)
|
||||
{
|
||||
caplen = packet_len;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if(caplen > p->snapshot)
|
||||
caplen = p->snapshot;
|
||||
|
||||
/*
|
||||
* 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 = (char*)header;
|
||||
p->cc = endofbuf - (char*)header;
|
||||
return (n);
|
||||
}
|
||||
}
|
||||
|
||||
if(!dfp)
|
||||
{
|
||||
/* convert between timestamp formats */
|
||||
ts = header->ts;
|
||||
pcap_header.ts.tv_sec = (int)(ts >> 32);
|
||||
ts = (ts & 0xffffffffi64) * 1000000;
|
||||
ts += 0x80000000; /* rounding */
|
||||
pcap_header.ts.tv_usec = (int)(ts >> 32);
|
||||
if (pcap_header.ts.tv_usec >= 1000000) {
|
||||
pcap_header.ts.tv_usec -= 1000000;
|
||||
pcap_header.ts.tv_sec++;
|
||||
}
|
||||
}
|
||||
|
||||
/* No underlaying filtering system. We need to filter on our own */
|
||||
if (p->fcode.bf_insns)
|
||||
{
|
||||
if (bpf_filter(p->fcode.bf_insns, dp, packet_len, caplen) == 0)
|
||||
{
|
||||
/* Move to next packet */
|
||||
header = (dag_record_t*)((char*)header + erf_record_len);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Fill the header for the user suppplied callback function */
|
||||
pcap_header.caplen = caplen;
|
||||
pcap_header.len = packet_len;
|
||||
|
||||
/* Call the callback function */
|
||||
(*callback)(user, &pcap_header, dp);
|
||||
|
||||
/* Move to next packet */
|
||||
header = (dag_record_t*)((char*)header + erf_record_len);
|
||||
|
||||
/* Stop if the number of packets requested by user has been reached*/
|
||||
if (++n >= cnt && cnt > 0)
|
||||
{
|
||||
p->bp = (char*)header;
|
||||
p->cc = endofbuf - (char*)header;
|
||||
return (n);
|
||||
}
|
||||
}
|
||||
while((u_char*)header < endofbuf);
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif /* HAVE_DAG_API */
|
||||
|
||||
/* Send a packet to the network */
|
||||
static int
|
||||
pcap_inject_win32(pcap_t *p, const void *buf, size_t size){
|
||||
LPPACKET PacketToSend;
|
||||
|
||||
PacketToSend=PacketAllocatePacket();
|
||||
|
||||
if (PacketToSend == NULL)
|
||||
{
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send error: PacketAllocatePacket failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
PacketInitPacket(PacketToSend,(PVOID)buf,size);
|
||||
if(PacketSendPacket(p->adapter,PacketToSend,TRUE) == FALSE){
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send error: PacketSendPacket failed");
|
||||
PacketFreePacket(PacketToSend);
|
||||
return -1;
|
||||
}
|
||||
|
||||
PacketFreePacket(PacketToSend);
|
||||
|
||||
/*
|
||||
* We assume it all got sent if "PacketSendPacket()" succeeded.
|
||||
* "pcap_inject()" is expected to return the number of bytes
|
||||
* sent.
|
||||
*/
|
||||
return size;
|
||||
}
|
||||
|
||||
static void
|
||||
pcap_close_win32(pcap_t *p)
|
||||
{
|
||||
if (p->buffer != NULL)
|
||||
free(p->buffer);
|
||||
pcap_close_common(p);
|
||||
if (p->adapter != NULL) {
|
||||
PacketCloseAdapter(p->adapter);
|
||||
p->adapter = NULL;
|
||||
}
|
||||
if (p->Packet) {
|
||||
PacketFreePacket(p->Packet);
|
||||
p->Packet = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
pcap_t *
|
||||
@ -231,6 +432,25 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||
|
||||
case NdisMedium802_3:
|
||||
p->linktype = DLT_EN10MB;
|
||||
/*
|
||||
* This is (presumably) a real Ethernet capture; give it a
|
||||
* link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so
|
||||
* that an application can let you choose it, in case you're
|
||||
* capturing DOCSIS traffic that a Cisco Cable Modem
|
||||
* Termination System is putting out onto an Ethernet (it
|
||||
* doesn't put an Ethernet header onto the wire, it puts raw
|
||||
* DOCSIS frames out on the wire inside the low-level
|
||||
* Ethernet framing).
|
||||
*/
|
||||
p->dlt_list = (u_int *) malloc(sizeof(u_int) * 2);
|
||||
/*
|
||||
* If that fails, just leave the list empty.
|
||||
*/
|
||||
if (p->dlt_list != NULL) {
|
||||
p->dlt_list[0] = DLT_EN10MB;
|
||||
p->dlt_list[1] = DLT_DOCSIS;
|
||||
p->dlt_count = 2;
|
||||
}
|
||||
break;
|
||||
|
||||
case NdisMediumFddi:
|
||||
@ -253,6 +473,18 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||
p->linktype = DLT_ATM_RFC1483;
|
||||
break;
|
||||
|
||||
case NdisMediumCHDLC:
|
||||
p->linktype = DLT_CHDLC;
|
||||
break;
|
||||
|
||||
case NdisMediumPPPSerial:
|
||||
p->linktype = DLT_PPP_SERIAL;
|
||||
break;
|
||||
|
||||
case NdisMediumNull:
|
||||
p->linktype = DLT_NULL;
|
||||
break;
|
||||
|
||||
default:
|
||||
p->linktype = DLT_EN10MB; /*an unknown adapter is assumed to be ethernet*/
|
||||
break;
|
||||
@ -265,15 +497,6 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||
/* 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)
|
||||
{
|
||||
@ -281,26 +504,105 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||
goto bad;
|
||||
}
|
||||
|
||||
PacketInitPacket(p->Packet,(BYTE*)p->buffer,p->bufsize);
|
||||
|
||||
/* allocate the standard buffer in the driver */
|
||||
if(PacketSetBuff( p->adapter, SIZE_BUF)==FALSE)
|
||||
if(!(p->adapter->Flags & INFO_FLAG_DAG_CARD))
|
||||
{
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE,"driver error: not enough memory to allocate the kernel buffer\n");
|
||||
goto bad;
|
||||
/*
|
||||
* Traditional Adapter
|
||||
*/
|
||||
|
||||
p->buffer = (u_char *)malloc(PcapBufSize);
|
||||
if (p->buffer == NULL)
|
||||
{
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
|
||||
goto bad;
|
||||
}
|
||||
|
||||
PacketInitPacket(p->Packet,(BYTE*)p->buffer,p->bufsize);
|
||||
|
||||
p->snapshot = snaplen;
|
||||
|
||||
/* allocate the standard buffer in the driver */
|
||||
if(PacketSetBuff( p->adapter, SIZE_BUF)==FALSE)
|
||||
{
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE,"driver error: not enough memory to allocate the kernel buffer\n");
|
||||
goto bad;
|
||||
}
|
||||
|
||||
/* tell the driver to copy the buffer only if it contains at least 16K */
|
||||
if(PacketSetMinToCopy(p->adapter,16000)==FALSE)
|
||||
{
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE,"Error calling PacketSetMinToCopy: %s\n", pcap_win32strerror());
|
||||
goto bad;
|
||||
}
|
||||
}
|
||||
|
||||
/* tell the driver to copy the buffer only if it contains at least 16K */
|
||||
if(PacketSetMinToCopy(p->adapter,16000)==FALSE)
|
||||
else
|
||||
#ifdef HAVE_DAG_API
|
||||
{
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE,"Error calling PacketSetMinToCopy: %s\n", pcap_win32strerror());
|
||||
goto bad;
|
||||
/*
|
||||
* Dag Card
|
||||
*/
|
||||
LONG status;
|
||||
HKEY dagkey;
|
||||
DWORD lptype;
|
||||
DWORD lpcbdata;
|
||||
int postype = 0;
|
||||
char keyname[512];
|
||||
|
||||
snprintf(keyname, sizeof(keyname), "%s\\CardParams\\%s",
|
||||
"SYSTEM\\CurrentControlSet\\Services\\DAG",
|
||||
strstr(_strlwr((char*)device), "dag"));
|
||||
do
|
||||
{
|
||||
status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyname, 0, KEY_READ, &dagkey);
|
||||
if(status != ERROR_SUCCESS)
|
||||
break;
|
||||
|
||||
status = RegQueryValueEx(dagkey,
|
||||
"PosType",
|
||||
NULL,
|
||||
&lptype,
|
||||
(char*)&postype,
|
||||
&lpcbdata);
|
||||
|
||||
if(status != ERROR_SUCCESS)
|
||||
{
|
||||
postype = 0;
|
||||
}
|
||||
|
||||
RegCloseKey(dagkey);
|
||||
}
|
||||
while(FALSE);
|
||||
|
||||
|
||||
p->snapshot = PacketSetSnapLen(p->adapter, snaplen);
|
||||
|
||||
/* Set the length of the FCS associated to any packet. This value
|
||||
* will be subtracted to the packet length */
|
||||
p->md.dag_fcs_bits = p->adapter->DagFcsLen;
|
||||
}
|
||||
|
||||
#else
|
||||
goto bad;
|
||||
#endif /* HAVE_DAG_API */
|
||||
|
||||
PacketSetReadTimeout(p->adapter, to_ms);
|
||||
|
||||
p->read_op = pcap_read_win32;
|
||||
p->setfilter_op = pcap_setfilter_win32;
|
||||
|
||||
#ifdef HAVE_DAG_API
|
||||
if(p->adapter->Flags & INFO_FLAG_DAG_CARD)
|
||||
{
|
||||
/* install dag specific handlers for read and setfilter */
|
||||
p->read_op = pcap_read_win32_dag;
|
||||
p->setfilter_op = pcap_setfilter_win32_dag;
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif /* HAVE_DAG_API */
|
||||
/* install traditional npf handlers for read and setfilter */
|
||||
p->read_op = pcap_read_win32_npf;
|
||||
p->setfilter_op = pcap_setfilter_win32_npf;
|
||||
#ifdef HAVE_DAG_API
|
||||
}
|
||||
#endif /* HAVE_DAG_API */
|
||||
p->inject_op = pcap_inject_win32;
|
||||
p->set_datalink_op = NULL; /* can't change data link type */
|
||||
p->getnonblock_op = pcap_getnonblock_win32;
|
||||
p->setnonblock_op = pcap_setnonblock_win32;
|
||||
@ -313,22 +615,65 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||
PacketCloseAdapter(p->adapter);
|
||||
if (p->buffer != NULL)
|
||||
free(p->buffer);
|
||||
if(p->Packet)
|
||||
PacketFreePacket(p->Packet);
|
||||
/*
|
||||
* Get rid of any link-layer type list we allocated.
|
||||
*/
|
||||
if (p->dlt_list != NULL)
|
||||
free(p->dlt_list);
|
||||
free(p);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
pcap_setfilter_win32(pcap_t *p, struct bpf_program *fp)
|
||||
pcap_setfilter_win32_npf(pcap_t *p, struct bpf_program *fp)
|
||||
{
|
||||
if(PacketSetBpf(p->adapter,fp)==FALSE){
|
||||
/* kernel filter not installed. */
|
||||
/*
|
||||
* Kernel filter not installed.
|
||||
* XXX - fall back on userland filtering, as is done
|
||||
* on other platforms?
|
||||
*/
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Driver error: cannot set bpf filter: %s", pcap_win32strerror());
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Discard any previously-received packets, as they might have
|
||||
* passed whatever filter was formerly in effect, but might
|
||||
* not pass this filter (BIOCSETF discards packets buffered
|
||||
* in the kernel, so you can lose packets in any case).
|
||||
*/
|
||||
p->cc = 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* We filter at user level, since the kernel driver does't process the packets
|
||||
*/
|
||||
static int
|
||||
pcap_setfilter_win32_dag(pcap_t *p, struct bpf_program *fp) {
|
||||
|
||||
if(!fp)
|
||||
{
|
||||
strncpy(p->errbuf, "setfilter: No filter specified", sizeof(p->errbuf));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Install a user level filter */
|
||||
if (install_bpf_program(p, fp) < 0)
|
||||
{
|
||||
snprintf(p->errbuf, sizeof(p->errbuf),
|
||||
"setfilter, unable to install the filter: %s", pcap_strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
p->md.use_bpf = 0;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_getnonblock_win32(pcap_t *p, char *errbuf)
|
||||
@ -387,28 +732,6 @@ pcap_setmode(pcap_t *p, int mode){
|
||||
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)
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" @(#) $Header: /tcpdump/master/libpcap/pcap.3,v 1.51.2.9 2004/03/28 21:45:32 fenner Exp $
|
||||
.\" @(#) $Header: /tcpdump/master/libpcap/pcap.3,v 1.64 2004/12/17 21:27:54 guy Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1994, 1996, 1997
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
@ -39,7 +39,9 @@ pcap_t *pcap_open_live(const char *device, int snaplen,
|
||||
int promisc, int to_ms, char *errbuf)
|
||||
pcap_t *pcap_open_dead(int linktype, int snaplen)
|
||||
pcap_t *pcap_open_offline(const char *fname, char *errbuf)
|
||||
pcap_t *pcap_fopen_offline(FILE *fp, char *errbuf)
|
||||
pcap_dumper_t *pcap_dump_open(pcap_t *p, const char *fname)
|
||||
pcap_dumper_t *pcap_dump_fopen(pcap_t *p, FILE *fp)
|
||||
.ft
|
||||
.LP
|
||||
.ft B
|
||||
@ -88,6 +90,11 @@ void pcap_breakloop(pcap_t *)
|
||||
.ft
|
||||
.LP
|
||||
.ft B
|
||||
int pcap_inject(pcap_t *p, const void *buf, size_t size)
|
||||
int pcap_sendpacket(pcap_t *p, const u_char *buf, int size)
|
||||
.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);
|
||||
@ -101,7 +108,7 @@ 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)
|
||||
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)
|
||||
@ -128,6 +135,7 @@ in
|
||||
.BR pcap_open_live() ,
|
||||
.BR pcap_open_dead() ,
|
||||
.BR pcap_open_offline() ,
|
||||
.BR pcap_fopen_offline() ,
|
||||
.BR pcap_setnonblock() ,
|
||||
.BR pcap_getnonblock() ,
|
||||
.BR pcap_findalldevs() ,
|
||||
@ -206,9 +214,16 @@ and
|
||||
.BR tcpslice(1) .
|
||||
The name "-" in a synonym for
|
||||
.BR stdin .
|
||||
Alternatively, you may call
|
||||
.B pcap_fopen_offline()
|
||||
to read dumped data from an existing open stream
|
||||
.IR fp .
|
||||
Note that on Windows, that stream should be opened in binary mode.
|
||||
.I errbuf
|
||||
is used to return error text and is only set when
|
||||
.B pcap_open_offline()
|
||||
or
|
||||
.B pcap_fopen_offline()
|
||||
fails and returns
|
||||
.BR NULL .
|
||||
.PP
|
||||
@ -226,13 +241,18 @@ struct as returned by
|
||||
or
|
||||
.BR pcap_open_live() .
|
||||
.I fname
|
||||
specifies the name of the file to open.
|
||||
specifies the name of the file to open. Alternatively, you may call
|
||||
.B pcap_dump_fopen()
|
||||
to write data to an existing open stream
|
||||
.IR fp .
|
||||
Note that on Windows, that stream should be opened in binary mode.
|
||||
If
|
||||
.B NULL
|
||||
is returned,
|
||||
.B pcap_geterr()
|
||||
can be used to get the error text.
|
||||
.PP
|
||||
.PP
|
||||
.B pcap_setnonblock()
|
||||
puts a capture descriptor, opened with
|
||||
.BR pcap_open_live() ,
|
||||
@ -354,6 +374,13 @@ to by
|
||||
may be null if the interface isn't a point-to-point interface
|
||||
.RE
|
||||
.PP
|
||||
Note that not all the addresses in the list of addresses are
|
||||
necessarily IPv4 or IPv6 addresses - you must check the
|
||||
.B sa_family
|
||||
member of the
|
||||
.B "struct sockaddr"
|
||||
before interpreting the contents of the address.
|
||||
.PP
|
||||
.B \-1
|
||||
is returned on failure, in which case
|
||||
.B errbuf
|
||||
@ -628,6 +655,45 @@ 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_inject()
|
||||
sends a raw packet through the network interface;
|
||||
.I buf
|
||||
points to the data of the packet, including the link-layer header, and
|
||||
.I size
|
||||
is the number of bytes in the packet.
|
||||
It returns the number of bytes written on success. A return of \-1
|
||||
indicates an error in which case
|
||||
.B pcap_perror()
|
||||
or
|
||||
.B pcap_geterr()
|
||||
may be used to display the error text.
|
||||
Note that, even if you successfully open the network interface, you
|
||||
might not have permission to send packets on it, or it might not support
|
||||
sending packets; as
|
||||
.I pcap_open_live()
|
||||
doesn't have a flag to indicate whether to open for capturing, sending,
|
||||
or capturing and sending, you cannot request an open that supports
|
||||
sending and be notified at open time whether sending will be possible.
|
||||
Note also that some devices might not support sending packets.
|
||||
.PP
|
||||
Note that, on some platforms, the link-layer header of the packet that's
|
||||
sent might not be the same as the link-layer header of the packet
|
||||
supplied to
|
||||
.BR pcap_inject() ,
|
||||
as the source link-layer address, if the header contains such an
|
||||
address, might be changed to be the address assigned to the interface on
|
||||
which the packet it sent, if the platform doesn't support sending
|
||||
completely raw and unchanged packets.
|
||||
.PP
|
||||
.B pcap_sendpacket()
|
||||
is like
|
||||
.BR pcap_inject() ,
|
||||
but it returns 0 on success and \-1 on failure.
|
||||
.RB ( pcap_inject()
|
||||
comes from OpenBSD;
|
||||
.B pcap_sendpacket()
|
||||
comes from WinPcap. Both are provided for compatibility.)
|
||||
.PP
|
||||
.B pcap_dump()
|
||||
outputs a packet to the ``savefile'' opened with
|
||||
.BR pcap_dump_open() .
|
||||
|
@ -33,7 +33,7 @@
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid[] _U_ =
|
||||
"@(#) $Header: /tcpdump/master/libpcap/pcap.c,v 1.63.2.9 2004/03/25 22:40:52 guy Exp $ (LBL)";
|
||||
"@(#) $Header: /tcpdump/master/libpcap/pcap.c,v 1.88 2005/02/08 20:03:15 guy Exp $ (LBL)";
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
@ -49,7 +49,7 @@ static const char rcsid[] _U_ =
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifndef _MSC_VER
|
||||
#if !defined(_MSC_VER) && !defined(__BORLANDC__)
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
@ -59,6 +59,10 @@ static const char rcsid[] _U_ =
|
||||
#include "os-proto.h"
|
||||
#endif
|
||||
|
||||
#ifdef MSDOS
|
||||
#include "pcap-dos.h"
|
||||
#endif
|
||||
|
||||
#include "pcap-int.h"
|
||||
|
||||
#ifdef HAVE_DAG_API
|
||||
@ -275,6 +279,22 @@ pcap_set_datalink(pcap_t *p, int dlt)
|
||||
break;
|
||||
if (i >= p->dlt_count)
|
||||
goto unsupported;
|
||||
if (p->dlt_count == 2 && p->dlt_list[0] == DLT_EN10MB &&
|
||||
dlt == DLT_DOCSIS) {
|
||||
/*
|
||||
* This is presumably an Ethernet device, as the first
|
||||
* link-layer type it offers is DLT_EN10MB, and the only
|
||||
* other type it offers is DLT_DOCSIS. That means that
|
||||
* we can't tell the driver to supply DOCSIS link-layer
|
||||
* headers - we're just pretending that's what we're
|
||||
* getting, as, presumably, we're capturing on a dedicated
|
||||
* link to a Cisco Cable Modem Termination System, and
|
||||
* it's putting raw DOCSIS frames on the wire inside low-level
|
||||
* Ethernet framing.
|
||||
*/
|
||||
p->linktype = dlt;
|
||||
return (0);
|
||||
}
|
||||
if (p->set_datalink_op(p, dlt) == -1)
|
||||
return (-1);
|
||||
p->linktype = dlt;
|
||||
@ -332,8 +352,23 @@ static struct dlt_choice dlt_choices[] = {
|
||||
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_DOCSIS, "DOCSIS"),
|
||||
DLT_CHOICE(DLT_LINUX_IRDA, "Linux IrDA"),
|
||||
DLT_CHOICE(DLT_IEEE802_11_RADIO_AVS, "802.11 plus AVS radio information header"),
|
||||
DLT_CHOICE(DLT_SYMANTEC_FIREWALL, "Symantec Firewall"),
|
||||
DLT_CHOICE(DLT_JUNIPER_ATM1, "Juniper ATM1 PIC"),
|
||||
DLT_CHOICE(DLT_JUNIPER_ATM2, "Juniper ATM2 PIC"),
|
||||
DLT_CHOICE(DLT_JUNIPER_MLPPP, "Juniper Multi-Link PPP"),
|
||||
DLT_CHOICE(DLT_PPP_PPPD, "PPP for pppd, with direction flag"),
|
||||
DLT_CHOICE(DLT_JUNIPER_PPPOE, "Juniper PPPoE"),
|
||||
DLT_CHOICE(DLT_JUNIPER_PPPOE_ATM, "Juniper PPPoE/ATM"),
|
||||
DLT_CHOICE(DLT_GPRS_LLC, "GPRS LLC"),
|
||||
DLT_CHOICE(DLT_GPF_T, "GPF-T"),
|
||||
DLT_CHOICE(DLT_GPF_F, "GPF-F"),
|
||||
DLT_CHOICE(DLT_JUNIPER_PIC_PEER, "Juniper PIC Peer"),
|
||||
DLT_CHOICE(DLT_JUNIPER_MLFR, "Juniper Multi-Link Frame Relay"),
|
||||
DLT_CHOICE(DLT_ERF_ETH, "Ethernet with Endace ERF header"),
|
||||
DLT_CHOICE(DLT_ERF_POS, "Packet-over-SONET with Endace ERF header"),
|
||||
DLT_CHOICE_SENTINEL
|
||||
};
|
||||
|
||||
@ -502,7 +537,7 @@ pcap_fileno(pcap_t *p)
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
#if !defined(WIN32) && !defined(MSDOS)
|
||||
int
|
||||
pcap_get_selectable_fd(pcap_t *p)
|
||||
{
|
||||
@ -535,7 +570,7 @@ pcap_getnonblock(pcap_t *p, char *errbuf)
|
||||
* We don't look at "p->nonblock", in case somebody tweaked the FD
|
||||
* directly.
|
||||
*/
|
||||
#ifndef WIN32
|
||||
#if !defined(WIN32) && !defined(MSDOS)
|
||||
int
|
||||
pcap_getnonblock_fd(pcap_t *p, char *errbuf)
|
||||
{
|
||||
@ -560,7 +595,7 @@ pcap_setnonblock(pcap_t *p, int nonblock, char *errbuf)
|
||||
return p->setnonblock_op(p, nonblock, errbuf);
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
#if !defined(WIN32) && !defined(MSDOS)
|
||||
/*
|
||||
* Set non-blocking mode, under the assumption that it's just the
|
||||
* standard POSIX non-blocking flag. (This can be called by the
|
||||
@ -603,6 +638,7 @@ pcap_win32strerror(void)
|
||||
DWORD error;
|
||||
static char errbuf[PCAP_ERRBUF_SIZE+1];
|
||||
int errlen;
|
||||
char *p;
|
||||
|
||||
error = GetLastError();
|
||||
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, errbuf,
|
||||
@ -617,6 +653,8 @@ pcap_win32strerror(void)
|
||||
errbuf[errlen - 1] = '\0';
|
||||
errbuf[errlen - 2] = '\0';
|
||||
}
|
||||
p = strchr(errbuf, '\0');
|
||||
snprintf (p, sizeof(errbuf)-(p-errbuf), " (%lu)", error);
|
||||
return (errbuf);
|
||||
}
|
||||
#endif
|
||||
@ -654,15 +692,26 @@ pcap_stats(pcap_t *p, struct pcap_stat *ps)
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_stats_dead(pcap_t *p, struct pcap_stat *ps)
|
||||
pcap_stats_dead(pcap_t *p, struct pcap_stat *ps _U_)
|
||||
{
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Statistics aren't available from a pcap_open_dead pcap_t");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
void
|
||||
pcap_close_common(pcap_t *p)
|
||||
{
|
||||
if (p->buffer != NULL)
|
||||
free(p->buffer);
|
||||
#if !defined(WIN32) && !defined(MSDOS)
|
||||
if (p->fd >= 0)
|
||||
close(p->fd);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
pcap_close_dead(pcap_t *p)
|
||||
pcap_close_dead(pcap_t *p _U_)
|
||||
{
|
||||
/* Nothing to do. */
|
||||
}
|
||||
@ -683,6 +732,30 @@ pcap_open_dead(int linktype, int snaplen)
|
||||
return p;
|
||||
}
|
||||
|
||||
/*
|
||||
* API compatible with WinPcap's "send a packet" routine - returns -1
|
||||
* on error, 0 otherwise.
|
||||
*
|
||||
* XXX - what if we get a short write?
|
||||
*/
|
||||
int
|
||||
pcap_sendpacket(pcap_t *p, const u_char *buf, int size)
|
||||
{
|
||||
if (p->inject_op(p, buf, size) == -1)
|
||||
return (-1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* API compatible with OpenBSD's "send a packet" routine - returns -1 on
|
||||
* error, number of bytes written otherwise.
|
||||
*/
|
||||
int
|
||||
pcap_inject(pcap_t *p, const void *buf, size_t size)
|
||||
{
|
||||
return (p->inject_op(p, buf, size));
|
||||
}
|
||||
|
||||
void
|
||||
pcap_close(pcap_t *p)
|
||||
{
|
||||
@ -705,26 +778,32 @@ pcap_close(pcap_t *p)
|
||||
* was linked, or even weirder things, such as the string being the one
|
||||
* from the library but being truncated).
|
||||
*/
|
||||
#ifdef HAVE_VERSION_H
|
||||
#include "version.h"
|
||||
#else
|
||||
static const char pcap_version_string[] = "libpcap version 0.9[.x]";
|
||||
#endif
|
||||
|
||||
#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 wpcap_version_string[] = "3.1";
|
||||
static const char pcap_version_string_fmt[] =
|
||||
"WinPcap version %s, based on libpcap version 0.8";
|
||||
"WinPcap version %s, based on %s";
|
||||
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;
|
||||
"WinPcap version %s (packet.dll version %s), based on %s";
|
||||
static char *full_pcap_version_string;
|
||||
|
||||
const char *
|
||||
pcap_lib_version(void)
|
||||
{
|
||||
char *packet_version_string;
|
||||
size_t pcap_version_string_len;
|
||||
size_t full_pcap_version_string_len;
|
||||
|
||||
if (pcap_version_string == NULL) {
|
||||
if (full_pcap_version_string == NULL) {
|
||||
/*
|
||||
* Generate the version string.
|
||||
*/
|
||||
@ -735,12 +814,15 @@ pcap_lib_version(void)
|
||||
* 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);
|
||||
full_pcap_version_string_len =
|
||||
(sizeof pcap_version_string_fmt - 4) +
|
||||
strlen(wpcap_version_string) +
|
||||
strlen(pcap_version_string);
|
||||
full_pcap_version_string =
|
||||
malloc(full_pcap_version_string_len);
|
||||
sprintf(full_pcap_version_string,
|
||||
pcap_version_string_fmt, wpcap_version_string,
|
||||
pcap_version_string);
|
||||
} else {
|
||||
/*
|
||||
* WinPcap version string and packet.dll version
|
||||
@ -749,20 +831,48 @@ pcap_lib_version(void)
|
||||
* same version of WinPcap), so we report both
|
||||
* versions.
|
||||
*/
|
||||
pcap_version_string_len =
|
||||
(sizeof pcap_version_string_packet_dll_fmt - 4) +
|
||||
full_pcap_version_string_len =
|
||||
(sizeof pcap_version_string_packet_dll_fmt - 6) +
|
||||
strlen(wpcap_version_string) +
|
||||
strlen(packet_version_string);
|
||||
pcap_version_string = malloc(pcap_version_string_len);
|
||||
sprintf(pcap_version_string,
|
||||
strlen(packet_version_string) +
|
||||
strlen(pcap_version_string);
|
||||
full_pcap_version_string = malloc(full_pcap_version_string_len);
|
||||
|
||||
sprintf(full_pcap_version_string,
|
||||
pcap_version_string_packet_dll_fmt,
|
||||
wpcap_version_string, packet_version_string);
|
||||
wpcap_version_string, packet_version_string,
|
||||
pcap_version_string);
|
||||
}
|
||||
}
|
||||
return (pcap_version_string);
|
||||
return (full_pcap_version_string);
|
||||
}
|
||||
#else
|
||||
#include "version.h"
|
||||
|
||||
#elif defined(MSDOS)
|
||||
|
||||
static char *full_pcap_version_string;
|
||||
|
||||
const char *
|
||||
pcap_lib_version (void)
|
||||
{
|
||||
char *packet_version_string;
|
||||
size_t full_pcap_version_string_len;
|
||||
static char dospfx[] = "DOS-";
|
||||
|
||||
if (full_pcap_version_string == NULL) {
|
||||
/*
|
||||
* Generate the version string.
|
||||
*/
|
||||
full_pcap_version_string_len =
|
||||
sizeof dospfx + strlen(pcap_version_string);
|
||||
full_pcap_version_string =
|
||||
malloc(full_pcap_version_string_len);
|
||||
strcpy(full_pcap_version_string, dospfx);
|
||||
strcat(full_pcap_version_string, pcap_version_string);
|
||||
}
|
||||
return (full_pcap_version_string);
|
||||
}
|
||||
|
||||
#else /* UN*X */
|
||||
|
||||
const char *
|
||||
pcap_lib_version(void)
|
||||
|
@ -31,18 +31,21 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#) $Header: /tcpdump/master/libpcap/pcap.h,v 1.45.2.4 2004/01/27 22:56:20 guy Exp $ (LBL)
|
||||
* @(#) $Header: /tcpdump/master/libpcap/pcap.h,v 1.52 2004/12/18 08:52:11 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 */
|
||||
#if defined(WIN32)
|
||||
#include <pcap-stdinc.h>
|
||||
#elif defined(MSDOS)
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h> /* u_int, u_char etc. */
|
||||
#else /* UN*X */
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#endif /* WIN32/MSDOS/UN*X */
|
||||
|
||||
#ifndef PCAP_DONT_INCLUDE_PCAP_BPF_H
|
||||
#include <pcap-bpf.h>
|
||||
@ -140,6 +143,39 @@ struct pcap_stat {
|
||||
#endif /* WIN32 */
|
||||
};
|
||||
|
||||
#ifdef MSDOS
|
||||
/*
|
||||
* As returned by the pcap_stats_ex()
|
||||
*/
|
||||
struct pcap_stat_ex {
|
||||
u_long rx_packets; /* total packets received */
|
||||
u_long tx_packets; /* total packets transmitted */
|
||||
u_long rx_bytes; /* total bytes received */
|
||||
u_long tx_bytes; /* total bytes transmitted */
|
||||
u_long rx_errors; /* bad packets received */
|
||||
u_long tx_errors; /* packet transmit problems */
|
||||
u_long rx_dropped; /* no space in Rx buffers */
|
||||
u_long tx_dropped; /* no space available for Tx */
|
||||
u_long multicast; /* multicast packets received */
|
||||
u_long collisions;
|
||||
|
||||
/* detailed rx_errors: */
|
||||
u_long rx_length_errors;
|
||||
u_long rx_over_errors; /* receiver ring buff overflow */
|
||||
u_long rx_crc_errors; /* recv'd pkt with crc error */
|
||||
u_long rx_frame_errors; /* recv'd frame alignment error */
|
||||
u_long rx_fifo_errors; /* recv'r fifo overrun */
|
||||
u_long rx_missed_errors; /* recv'r missed packet */
|
||||
|
||||
/* detailed tx_errors */
|
||||
u_long tx_aborted_errors;
|
||||
u_long tx_carrier_errors;
|
||||
u_long tx_fifo_errors;
|
||||
u_long tx_heartbeat_errors;
|
||||
u_long tx_window_errors;
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Item in a list of interfaces.
|
||||
*/
|
||||
@ -172,6 +208,7 @@ int pcap_lookupnet(const char *, bpf_u_int32 *, bpf_u_int32 *, char *);
|
||||
pcap_t *pcap_open_live(const char *, int, int, int, char *);
|
||||
pcap_t *pcap_open_dead(int, int);
|
||||
pcap_t *pcap_open_offline(const char *, char *);
|
||||
pcap_t *pcap_fopen_offline(FILE *, char *);
|
||||
void pcap_close(pcap_t *);
|
||||
int pcap_loop(pcap_t *, int, pcap_handler, u_char *);
|
||||
int pcap_dispatch(pcap_t *, int, pcap_handler, u_char *);
|
||||
@ -184,6 +221,8 @@ int pcap_setfilter(pcap_t *, struct bpf_program *);
|
||||
int pcap_getnonblock(pcap_t *, char *);
|
||||
int pcap_setnonblock(pcap_t *, int, char *);
|
||||
void pcap_perror(pcap_t *, char *);
|
||||
int pcap_inject(pcap_t *, const void *, size_t);
|
||||
int pcap_sendpacket(pcap_t *, const u_char *, int);
|
||||
char *pcap_strerror(int);
|
||||
char *pcap_geterr(pcap_t *);
|
||||
int pcap_compile(pcap_t *, struct bpf_program *, char *, int,
|
||||
@ -207,6 +246,7 @@ FILE *pcap_file(pcap_t *);
|
||||
int pcap_fileno(pcap_t *);
|
||||
|
||||
pcap_dumper_t *pcap_dump_open(pcap_t *, const char *);
|
||||
pcap_dumper_t *pcap_dump_fopen(pcap_t *, FILE *fp);
|
||||
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 *);
|
||||
@ -223,33 +263,44 @@ 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
|
||||
#if defined(WIN32)
|
||||
|
||||
/*
|
||||
* Win32 definitions
|
||||
*/
|
||||
|
||||
int pcap_setbuff(pcap_t *p, int dim);
|
||||
int pcap_setmode(pcap_t *p, int mode);
|
||||
int pcap_sendpacket(pcap_t *p, u_char *buf, int size);
|
||||
int pcap_setmintocopy(pcap_t *p, int size);
|
||||
|
||||
#ifdef WPCAP
|
||||
/* Include file with the wpcap-specific extensions */
|
||||
#include <Win32-Extensions.h>
|
||||
#endif
|
||||
#endif /* WPCAP */
|
||||
|
||||
#define MODE_CAPT 0
|
||||
#define MODE_STAT 1
|
||||
#define MODE_MON 2
|
||||
|
||||
#else
|
||||
#elif defined(MSDOS)
|
||||
|
||||
/*
|
||||
* MS-DOS definitions
|
||||
*/
|
||||
|
||||
int pcap_stats_ex (pcap_t *, struct pcap_stat_ex *);
|
||||
void pcap_set_wait (pcap_t *p, void (*yield)(void), int wait);
|
||||
u_long pcap_mac_packets (void);
|
||||
|
||||
#else /* UN*X */
|
||||
|
||||
/*
|
||||
* UN*X definitions
|
||||
*/
|
||||
|
||||
int pcap_get_selectable_fd(pcap_t *);
|
||||
|
||||
#endif /* WIN32 */
|
||||
#endif /* WIN32/MSDOS/UN*X */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
302
contrib/libpcap/pcap1.h
Normal file
302
contrib/libpcap/pcap1.h
Normal file
@ -0,0 +1,302 @@
|
||||
/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */
|
||||
/*
|
||||
* Copyright (c) 1993, 1994, 1995, 1996, 1997
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the Computer Systems
|
||||
* Engineering Group at Lawrence Berkeley Laboratory.
|
||||
* 4. Neither the name of the University nor of the Laboratory may be used
|
||||
* to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#) $Header: /tcpdump/master/libpcap/pcap1.h,v 1.2 2004/03/30 14:42:50 mcr 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 */
|
||||
|
||||
#ifndef PCAP_DONT_INCLUDE_PCAP_BPF_H
|
||||
#include <pcap-bpf.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define PCAP_VERSION_MAJOR 3
|
||||
#define PCAP_VERSION_MINOR 0
|
||||
|
||||
#define PCAP_ERRBUF_SIZE 256
|
||||
|
||||
/*
|
||||
* Compatibility for systems that have a bpf.h that
|
||||
* predates the bpf typedefs for 64-bit support.
|
||||
*/
|
||||
#if BPF_RELEASE - 0 < 199406
|
||||
typedef int bpf_int32;
|
||||
typedef u_int bpf_u_int32;
|
||||
#endif
|
||||
|
||||
typedef struct pcap pcap_t;
|
||||
typedef struct pcap_dumper pcap_dumper_t;
|
||||
typedef struct pcap_if pcap_if_t;
|
||||
typedef struct pcap_addr pcap_addr_t;
|
||||
|
||||
/*
|
||||
* The first record in the file contains saved values for some
|
||||
* of the flags used in the printout phases of tcpdump.
|
||||
* Many fields here are 32 bit ints so compilers won't insert unwanted
|
||||
* padding; these files need to be interchangeable across architectures.
|
||||
*
|
||||
* Do not change the layout of this structure, in any way (this includes
|
||||
* changes that only affect the length of fields in this structure).
|
||||
*
|
||||
* Also, do not change the interpretation of any of the members of this
|
||||
* structure, in any way (this includes using values other than
|
||||
* LINKTYPE_ values, as defined in "savefile.c", in the "linktype"
|
||||
* field).
|
||||
*
|
||||
* Instead:
|
||||
*
|
||||
* introduce a new structure for the new format, if the layout
|
||||
* of the structure changed;
|
||||
*
|
||||
* send mail to "tcpdump-workers@tcpdump.org", requesting a new
|
||||
* magic number for your new capture file format, and, when
|
||||
* you get the new magic number, put it in "savefile.c";
|
||||
*
|
||||
* use that magic number for save files with the changed file
|
||||
* header;
|
||||
*
|
||||
* make the code in "savefile.c" capable of reading files with
|
||||
* the old file header as well as files with the new file header
|
||||
* (using the magic number to determine the header format).
|
||||
*
|
||||
* Then supply the changes to "patches@tcpdump.org", so that future
|
||||
* versions of libpcap and programs that use it (such as tcpdump) will
|
||||
* be able to read your new capture file format.
|
||||
*/
|
||||
|
||||
enum pcap1_info_types {
|
||||
PCAP_DATACAPTURE,
|
||||
PCAP_TIMESTAMP,
|
||||
PCAP_WALLTIME,
|
||||
PCAP_TIMESKEW,
|
||||
PCAP_PROBEPLACE, /* aka direction */
|
||||
PCAP_COMMENT, /* comment */
|
||||
};
|
||||
|
||||
struct pcap1_info_container {
|
||||
bpf_u_int32 info_len; /* in bytes */
|
||||
bpf_u_int32 info_type; /* enum pcap1_info_types */
|
||||
unsigned char info_data[0];
|
||||
};
|
||||
|
||||
struct pcap1_info_timestamp {
|
||||
struct pcap1_info_container pic;
|
||||
bpf_u_int32 nanoseconds; /* 10^-9 of seconds */
|
||||
bpf_u_int32 seconds; /* seconds since Unix epoch - GMT */
|
||||
bpf_u_int16 macroseconds; /* 16 bits more of MSB of time */
|
||||
bpf_u_int16 sigfigs; /* accuracy of timestamps - LSB bits */
|
||||
};
|
||||
|
||||
struct pcap1_info_packet {
|
||||
struct pcap1_info_container pic;
|
||||
bpf_u_int32 caplen; /* length of portion present */
|
||||
bpf_u_int32 len; /* length this packet (off wire) */
|
||||
bpf_u_int32 linktype; /* data link type (LINKTYPE_*) */
|
||||
bpf_u_int32 ifIndex; /* abstracted interface index */
|
||||
unsigned char packet_data[0];
|
||||
};
|
||||
|
||||
enum pcap1_probe {
|
||||
INBOUND =1,
|
||||
OUTBOUND =2,
|
||||
FORWARD =3,
|
||||
PREENCAP =4,
|
||||
POSTDECAP=5,
|
||||
};
|
||||
|
||||
struct pcap1_info_probe {
|
||||
struct pcap1_info_container pic;
|
||||
bpf_u_int32 probeloc; /* enum pcap1_probe */
|
||||
unsigned char probe_desc[0];
|
||||
};
|
||||
|
||||
struct pcap1_info_comment {
|
||||
struct pcap1_info_container pic;
|
||||
unsigned char comment[0];
|
||||
};
|
||||
|
||||
struct pcap1_packet_header {
|
||||
bpf_u_int32 magic;
|
||||
u_short version_major;
|
||||
u_short version_minor;
|
||||
bpf_u_int32 block_len;
|
||||
struct pcap1_info_container pics[0];
|
||||
};
|
||||
|
||||
/*
|
||||
* Each packet in the dump file is prepended with this generic header.
|
||||
* This gets around the problem of different headers for different
|
||||
* packet interfaces.
|
||||
*/
|
||||
|
||||
/*
|
||||
* As returned by the pcap_stats()
|
||||
*/
|
||||
struct pcap_stat {
|
||||
u_int ps_recv; /* number of packets received */
|
||||
u_int ps_drop; /* number of packets dropped */
|
||||
u_int ps_ifdrop; /* drops by interface XXX not yet supported */
|
||||
#ifdef WIN32
|
||||
u_int bs_capt; /* number of packets that reach the application */
|
||||
#endif /* WIN32 */
|
||||
};
|
||||
|
||||
/*
|
||||
* Item in a list of interfaces.
|
||||
*/
|
||||
struct pcap_if {
|
||||
struct pcap_if *next;
|
||||
char *name; /* name to hand to "pcap_open_live()" */
|
||||
char *description; /* textual description of interface, or NULL */
|
||||
struct pcap_addr *addresses;
|
||||
bpf_u_int32 flags; /* PCAP_IF_ interface flags */
|
||||
};
|
||||
|
||||
#define PCAP_IF_LOOPBACK 0x00000001 /* interface is loopback */
|
||||
|
||||
/*
|
||||
* Representation of an interface address.
|
||||
*/
|
||||
struct pcap_addr {
|
||||
struct pcap_addr *next;
|
||||
struct sockaddr *addr; /* address */
|
||||
struct sockaddr *netmask; /* netmask for that address */
|
||||
struct sockaddr *broadaddr; /* broadcast address for that address */
|
||||
struct sockaddr *dstaddr; /* P2P destination address for that address */
|
||||
};
|
||||
|
||||
typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *,
|
||||
const u_char *);
|
||||
|
||||
char *pcap_lookupdev(char *);
|
||||
int pcap_lookupnet(const char *, bpf_u_int32 *, bpf_u_int32 *, char *);
|
||||
pcap_t *pcap_open_live(const char *, int, int, int, char *);
|
||||
pcap_t *pcap_open_dead(int, int);
|
||||
pcap_t *pcap_open_offline(const char *, char *);
|
||||
void pcap_close(pcap_t *);
|
||||
int pcap_loop(pcap_t *, int, pcap_handler, u_char *);
|
||||
int pcap_dispatch(pcap_t *, int, pcap_handler, u_char *);
|
||||
const u_char*
|
||||
pcap_next(pcap_t *, struct pcap_pkthdr *);
|
||||
int pcap_next_ex(pcap_t *, struct pcap_pkthdr **, const u_char **);
|
||||
void pcap_breakloop(pcap_t *);
|
||||
int pcap_stats(pcap_t *, struct pcap_stat *);
|
||||
int pcap_setfilter(pcap_t *, struct bpf_program *);
|
||||
int pcap_getnonblock(pcap_t *, char *);
|
||||
int pcap_setnonblock(pcap_t *, int, char *);
|
||||
void pcap_perror(pcap_t *, char *);
|
||||
char *pcap_strerror(int);
|
||||
char *pcap_geterr(pcap_t *);
|
||||
int pcap_compile(pcap_t *, struct bpf_program *, char *, int,
|
||||
bpf_u_int32);
|
||||
int pcap_compile_nopcap(int, int, struct bpf_program *,
|
||||
char *, int, bpf_u_int32);
|
||||
void pcap_freecode(struct bpf_program *);
|
||||
int pcap_datalink(pcap_t *);
|
||||
int pcap_list_datalinks(pcap_t *, int **);
|
||||
int pcap_set_datalink(pcap_t *, int);
|
||||
int pcap_datalink_name_to_val(const char *);
|
||||
const char *pcap_datalink_val_to_name(int);
|
||||
const char *pcap_datalink_val_to_description(int);
|
||||
int pcap_snapshot(pcap_t *);
|
||||
int pcap_is_swapped(pcap_t *);
|
||||
int pcap_major_version(pcap_t *);
|
||||
int pcap_minor_version(pcap_t *);
|
||||
|
||||
/* XXX */
|
||||
FILE *pcap_file(pcap_t *);
|
||||
int pcap_fileno(pcap_t *);
|
||||
|
||||
pcap_dumper_t *pcap_dump_open(pcap_t *, const char *);
|
||||
int pcap_dump_flush(pcap_dumper_t *);
|
||||
void pcap_dump_close(pcap_dumper_t *);
|
||||
void pcap_dump(u_char *, const struct pcap_pkthdr *, const u_char *);
|
||||
FILE *pcap_dump_file(pcap_dumper_t *);
|
||||
|
||||
int pcap_findalldevs(pcap_if_t **, char *);
|
||||
void pcap_freealldevs(pcap_if_t *);
|
||||
|
||||
const char *pcap_lib_version(void);
|
||||
|
||||
/* XXX this guy lives in the bpf tree */
|
||||
u_int bpf_filter(struct bpf_insn *, u_char *, u_int, u_int);
|
||||
int bpf_validate(struct bpf_insn *f, int len);
|
||||
char *bpf_image(struct bpf_insn *, int);
|
||||
void bpf_dump(struct bpf_program *, int);
|
||||
|
||||
#ifdef WIN32
|
||||
/*
|
||||
* Win32 definitions
|
||||
*/
|
||||
|
||||
int pcap_setbuff(pcap_t *p, int dim);
|
||||
int pcap_setmode(pcap_t *p, int mode);
|
||||
int pcap_sendpacket(pcap_t *p, u_char *buf, int size);
|
||||
int pcap_setmintocopy(pcap_t *p, int size);
|
||||
|
||||
#ifdef WPCAP
|
||||
/* Include file with the wpcap-specific extensions */
|
||||
#include <Win32-Extensions.h>
|
||||
#endif
|
||||
|
||||
#define MODE_CAPT 0
|
||||
#define MODE_STAT 1
|
||||
|
||||
#else
|
||||
/*
|
||||
* UN*X definitions
|
||||
*/
|
||||
|
||||
int pcap_get_selectable_fd(pcap_t *);
|
||||
|
||||
#endif /* WIN32 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -26,11 +26,11 @@
|
||||
* 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)
|
||||
* @(#) $Header: /tcpdump/master/libpcap/pf.h,v 1.3 2004/04/02 06:33:30 guy Exp $ (LBL)
|
||||
*/
|
||||
|
||||
/* from $OpenBSD: pfvar.h,v 1.170 2003/08/22 21:50:34 david Exp $ */
|
||||
|
||||
|
||||
enum { PF_INOUT=0, PF_IN=1, PF_OUT=2 };
|
||||
enum { PF_PASS=0, PF_DROP=1, PF_SCRUB=2, PF_NAT=3, PF_NONAT=4,
|
||||
PF_BINAT=5, PF_NOBINAT=6, PF_RDR=7, PF_NORDR=8, PF_SYNPROXY_DROP=9 };
|
||||
@ -64,7 +64,7 @@ enum { PF_PASS=0, PF_DROP=1, PF_SCRUB=2, PF_NAT=3, PF_NONAT=4,
|
||||
|
||||
struct pfloghdr {
|
||||
u_int8_t length;
|
||||
sa_family_t af;
|
||||
u_int8_t af;
|
||||
u_int8_t action;
|
||||
u_int8_t reason;
|
||||
char ifname[IFNAMSIZ];
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* @(#) $Header: /tcpdump/master/libpcap/ppp.h,v 1.8 1999/10/19 15:18:31 itojun Exp $ (LBL) */
|
||||
/* @(#) $Header: /tcpdump/master/libpcap/ppp.h,v 1.12 2005/02/08 19:52:19 guy Exp $ (LBL) */
|
||||
/*
|
||||
* Point to Point Protocol (PPP) RFC1331
|
||||
*
|
||||
@ -18,6 +18,9 @@
|
||||
#define PPP_ADDRESS 0xff /* The address byte value */
|
||||
#define PPP_CONTROL 0x03 /* The control byte value */
|
||||
|
||||
#define PPP_PPPD_IN 0x00 /* non-standard for DLT_PPP_PPPD */
|
||||
#define PPP_PPPD_OUT 0x01 /* non-standard for DLT_PPP_PPPD */
|
||||
|
||||
/* Protocol numbers */
|
||||
#define PPP_IP 0x0021 /* Raw IP */
|
||||
#define PPP_OSI 0x0023 /* OSI Network Layer */
|
||||
@ -35,6 +38,8 @@
|
||||
#define PPP_HELLO 0x0201 /* 802.1d Hello Packets */
|
||||
#define PPP_LUXCOM 0x0231 /* Luxcom */
|
||||
#define PPP_SNS 0x0233 /* Sigma Network Systems */
|
||||
#define PPP_MPLS_UCAST 0x0281 /* rfc 3032 */
|
||||
#define PPP_MPLS_MCAST 0x0283 /* rfc 3022 */
|
||||
|
||||
#define PPP_IPCP 0x8021 /* IP Control Protocol */
|
||||
#define PPP_OSICP 0x8023 /* OSI Network Layer Control Protocol */
|
||||
@ -45,6 +50,7 @@
|
||||
#define PPP_STIICP 0x8033 /* Strean Protocol Control Protocol */
|
||||
#define PPP_VINESCP 0x8035 /* Banyan Vines Control Protocol */
|
||||
#define PPP_IPV6CP 0x8057 /* IPv6 Control Protocol */
|
||||
#define PPP_MPLSCP 0x8281 /* rfc 3022 */
|
||||
|
||||
#define PPP_LCP 0xc021 /* Link Control Protocol */
|
||||
#define PPP_PAP 0xc023 /* Password Authentication Protocol */
|
||||
|
@ -30,7 +30,7 @@
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid[] _U_ =
|
||||
"@(#) $Header: /tcpdump/master/libpcap/savefile.c,v 1.92.2.11 2004/03/11 23:46:14 guy Exp $ (LBL)";
|
||||
"@(#) $Header: /tcpdump/master/libpcap/savefile.c,v 1.126 2005/02/08 20:03:16 guy Exp $ (LBL)";
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
@ -49,8 +49,27 @@ static const char rcsid[] _U_ =
|
||||
#include "os-proto.h"
|
||||
#endif
|
||||
|
||||
#define TCPDUMP_MAGIC 0xa1b2c3d4
|
||||
#define PATCHED_TCPDUMP_MAGIC 0xa1b2cd34
|
||||
/*
|
||||
* Standard libpcap format.
|
||||
*/
|
||||
#define TCPDUMP_MAGIC 0xa1b2c3d4
|
||||
|
||||
/*
|
||||
* Alexey Kuznetzov's modified libpcap format.
|
||||
*/
|
||||
#define KUZNETZOV_TCPDUMP_MAGIC 0xa1b2cd34
|
||||
|
||||
/*
|
||||
* Reserved for Francisco Mesquita <francisco.mesquita@radiomovel.pt>
|
||||
* for another modified format.
|
||||
*/
|
||||
#define FMESQUITA_TCPDUMP_MAGIC 0xa1b234cd
|
||||
|
||||
/*
|
||||
* Navtel Communcations' format, with nanosecond timestamps,
|
||||
* as per a request from Dumas Hwang <dumas.hwang@navtelcom.com>.
|
||||
*/
|
||||
#define NAVTEL_TCPDUMP_MAGIC 0xa12b3c4d
|
||||
|
||||
/*
|
||||
* We use the "receiver-makes-right" approach to byte order,
|
||||
@ -75,6 +94,19 @@ static const char rcsid[] _U_ =
|
||||
#define SFERR_BADF 3
|
||||
#define SFERR_EOF 4 /* not really an error, just a status */
|
||||
|
||||
/*
|
||||
* Setting O_BINARY on DOS/Windows is a bit tricky
|
||||
*/
|
||||
#if defined(WIN32)
|
||||
#define SET_BINMODE(f) _setmode(fileno(f), O_BINARY)
|
||||
#elif defined(MSDOS)
|
||||
#if defined(__HIGHC__)
|
||||
#define SET_BINMODE(f) setmode(f, O_BINARY)
|
||||
#else
|
||||
#define SET_BINMODE(f) setmode(fileno(f), O_BINARY)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We don't write DLT_* values to the capture file header, because
|
||||
* they're not the same on all platforms.
|
||||
@ -156,11 +188,6 @@ static const char rcsid[] _U_ =
|
||||
|
||||
#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 */
|
||||
@ -247,11 +274,6 @@ static const char rcsid[] _U_ =
|
||||
#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 */
|
||||
@ -325,6 +347,63 @@ static const char rcsid[] _U_ =
|
||||
*/
|
||||
#define LINKTYPE_JUNIPER_MONITOR 164
|
||||
|
||||
/*
|
||||
* Reserved for BACnet MS/TP.
|
||||
*/
|
||||
#define LINKTYPE_BACNET_MS_TP 165
|
||||
|
||||
/*
|
||||
* Another PPP variant as per request from Karsten Keil <kkeil@suse.de>.
|
||||
*
|
||||
* This is used in some OSes to allow a kernel socket filter to distinguish
|
||||
* between incoming and outgoing packets, on a socket intended to
|
||||
* supply pppd with outgoing packets so it can do dial-on-demand and
|
||||
* hangup-on-lack-of-demand; incoming packets are filtered out so they
|
||||
* don't cause pppd to hold the connection up (you don't want random
|
||||
* input packets such as port scans, packets from old lost connections,
|
||||
* etc. to force the connection to stay up).
|
||||
*
|
||||
* The first byte of the PPP header (0xff03) is modified to accomodate
|
||||
* the direction - 0x00 = IN, 0x01 = OUT.
|
||||
*/
|
||||
#define LINKTYPE_PPP_PPPD 166
|
||||
|
||||
/*
|
||||
* Juniper-private data link type, as per request from
|
||||
* Hannes Gredler <hannes@juniper.net>. The DLT_s are used
|
||||
* for passing on chassis-internal metainformation such as
|
||||
* QOS profiles, cookies, etc..
|
||||
*/
|
||||
#define LINKTYPE_JUNIPER_PPPOE 167
|
||||
#define LINKTYPE_JUNIPER_PPPOE_ATM 168
|
||||
|
||||
#define LINKTYPE_GPRS_LLC 169 /* GPRS LLC */
|
||||
#define LINKTYPE_GPF_T 170 /* GPF-T (ITU-T G.7041/Y.1303) */
|
||||
#define LINKTYPE_GPF_F 171 /* GPF-T (ITU-T G.7041/Y.1303) */
|
||||
|
||||
/*
|
||||
* Requested by Oolan Zimmer <oz@gcom.com> for use in Gcom's T1/E1 line
|
||||
* monitoring equipment.
|
||||
*/
|
||||
#define LINKTYPE_GCOM_T1E1 172
|
||||
#define LINKTYPE_GCOM_SERIAL 173
|
||||
|
||||
/*
|
||||
* Juniper-private data link type, as per request from
|
||||
* Hannes Gredler <hannes@juniper.net>. The DLT_ is used
|
||||
* for internal communication to Physical Interface Cards (PIC)
|
||||
*/
|
||||
#define LINKTYPE_JUNIPER_PIC_PEER 174
|
||||
|
||||
/*
|
||||
* Link types requested by Gregor Maier <gregor@endace.com> of Endace
|
||||
* Measurement Systems. They add an ERF header (see
|
||||
* http://www.endace.com/support/EndaceRecordFormat.pdf) in front of
|
||||
* the link-layer header.
|
||||
*/
|
||||
#define LINKTYPE_ERF_ETH 175 /* Ethernet */
|
||||
#define LINKTYPE_ERF_POS 176 /* Packet-over-SONET */
|
||||
|
||||
static struct linktype_map {
|
||||
int dlt;
|
||||
int linktype;
|
||||
@ -483,8 +562,37 @@ static struct linktype_map {
|
||||
* LINKTYPE_* values, either).
|
||||
*/
|
||||
|
||||
/* Juniper-internal chassis encapsulation */
|
||||
{ DLT_JUNIPER_MONITOR, LINKTYPE_JUNIPER_MONITOR },
|
||||
|
||||
/* BACnet MS/TP */
|
||||
{ DLT_BACNET_MS_TP, LINKTYPE_BACNET_MS_TP },
|
||||
|
||||
/* PPP for pppd, with direction flag in the PPP header */
|
||||
{ DLT_PPP_PPPD, LINKTYPE_PPP_PPPD},
|
||||
|
||||
/* Juniper-internal chassis encapsulation */
|
||||
{ DLT_JUNIPER_PPPOE, LINKTYPE_JUNIPER_PPPOE },
|
||||
{ DLT_JUNIPER_PPPOE_ATM,LINKTYPE_JUNIPER_PPPOE_ATM },
|
||||
|
||||
/* GPRS LLC */
|
||||
{ DLT_GPRS_LLC, LINKTYPE_GPRS_LLC },
|
||||
|
||||
/* Transparent Generic Framing Procedure (ITU-T G.7041/Y.1303) */
|
||||
{ DLT_GPF_T, LINKTYPE_GPF_T },
|
||||
|
||||
/* Framed Generic Framing Procedure (ITU-T G.7041/Y.1303) */
|
||||
{ DLT_GPF_F, LINKTYPE_GPF_F },
|
||||
|
||||
{ DLT_GCOM_T1E1, LINKTYPE_GCOM_T1E1 },
|
||||
{ DLT_GCOM_SERIAL, LINKTYPE_GCOM_SERIAL },
|
||||
|
||||
/* Juniper-internal chassis encapsulation */
|
||||
{ DLT_JUNIPER_MONITOR, LINKTYPE_JUNIPER_MONITOR },
|
||||
{ DLT_JUNIPER_PIC_PEER, LINKTYPE_JUNIPER_PIC_PEER },
|
||||
|
||||
/* Endace types */
|
||||
{ DLT_ERF_ETH, LINKTYPE_ERF_ETH },
|
||||
{ DLT_ERF_POS, LINKTYPE_ERF_POS },
|
||||
|
||||
{ -1, -1 }
|
||||
};
|
||||
@ -584,6 +692,14 @@ sf_stats(pcap_t *p, struct pcap_stat *ps)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static int
|
||||
sf_inject(pcap_t *p, const void *buf _U_, size_t size _U_)
|
||||
{
|
||||
strlcpy(p->errbuf, "Sending packets isn't supported on savefiles",
|
||||
PCAP_ERRBUF_SIZE);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static void
|
||||
sf_close(pcap_t *p)
|
||||
{
|
||||
@ -595,10 +711,38 @@ sf_close(pcap_t *p)
|
||||
|
||||
pcap_t *
|
||||
pcap_open_offline(const char *fname, char *errbuf)
|
||||
{
|
||||
FILE *fp;
|
||||
pcap_t *p;
|
||||
|
||||
if (fname[0] == '-' && fname[1] == '\0')
|
||||
fp = stdin;
|
||||
else {
|
||||
#if !defined(WIN32) && !defined(MSDOS)
|
||||
fp = fopen(fname, "r");
|
||||
#else
|
||||
fp = fopen(fname, "rb");
|
||||
#endif
|
||||
if (fp == NULL) {
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", fname,
|
||||
pcap_strerror(errno));
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
p = pcap_fopen_offline(fp, errbuf);
|
||||
if (p == NULL) {
|
||||
if (fp != stdin)
|
||||
fclose(fp);
|
||||
}
|
||||
return (p);
|
||||
}
|
||||
|
||||
pcap_t *
|
||||
pcap_fopen_offline(FILE *fp, char *errbuf)
|
||||
{
|
||||
register pcap_t *p;
|
||||
register FILE *fp;
|
||||
struct pcap_file_header hdr;
|
||||
size_t amt_read;
|
||||
bpf_u_int32 magic;
|
||||
int linklen;
|
||||
|
||||
@ -610,29 +754,24 @@ pcap_open_offline(const char *fname, char *errbuf)
|
||||
|
||||
memset((char *)p, 0, sizeof(*p));
|
||||
|
||||
if (fname[0] == '-' && fname[1] == '\0')
|
||||
fp = stdin;
|
||||
else {
|
||||
#ifndef WIN32
|
||||
fp = fopen(fname, "r");
|
||||
#else
|
||||
fp = fopen(fname, "rb");
|
||||
#endif
|
||||
if (fp == NULL) {
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", fname,
|
||||
amt_read = fread((char *)&hdr, 1, sizeof(hdr), fp);
|
||||
if (amt_read != sizeof(hdr)) {
|
||||
if (ferror(fp)) {
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"error reading dump file: %s",
|
||||
pcap_strerror(errno));
|
||||
goto bad;
|
||||
} else {
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"truncated dump file; tried to read %lu file header bytes, only got %lu",
|
||||
(unsigned long)sizeof(hdr),
|
||||
(unsigned long)amt_read);
|
||||
}
|
||||
}
|
||||
if (fread((char *)&hdr, sizeof(hdr), 1, fp) != 1) {
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE, "fread: %s",
|
||||
pcap_strerror(errno));
|
||||
goto bad;
|
||||
}
|
||||
magic = hdr.magic;
|
||||
if (magic != TCPDUMP_MAGIC && magic != PATCHED_TCPDUMP_MAGIC) {
|
||||
if (magic != TCPDUMP_MAGIC && magic != KUZNETZOV_TCPDUMP_MAGIC) {
|
||||
magic = SWAPLONG(magic);
|
||||
if (magic != TCPDUMP_MAGIC && magic != PATCHED_TCPDUMP_MAGIC) {
|
||||
if (magic != TCPDUMP_MAGIC && magic != KUZNETZOV_TCPDUMP_MAGIC) {
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"bad dump file format");
|
||||
goto bad;
|
||||
@ -640,12 +779,23 @@ pcap_open_offline(const char *fname, char *errbuf)
|
||||
p->sf.swapped = 1;
|
||||
swap_hdr(&hdr);
|
||||
}
|
||||
if (magic == PATCHED_TCPDUMP_MAGIC) {
|
||||
if (magic == KUZNETZOV_TCPDUMP_MAGIC) {
|
||||
/*
|
||||
* XXX - the patch that's in some versions of libpcap
|
||||
* changes the packet header but not the magic number;
|
||||
* changes the packet header but not the magic number,
|
||||
* and some other versions with this magic number have
|
||||
* some extra debugging information in the packet header;
|
||||
* we'd have to use some hacks^H^H^H^H^Hheuristics to
|
||||
* detect that.
|
||||
* detect those variants.
|
||||
*
|
||||
* Ethereal does that, but it does so by trying to read
|
||||
* the first two packets of the file with each of the
|
||||
* record header formats. That currently means it seeks
|
||||
* backwards and retries the reads, which doesn't work
|
||||
* on pipes. We want to be able to read from a pipe, so
|
||||
* that strategy won't work; we'd have to buffer some
|
||||
* data ourselves and read from that buffer in order to
|
||||
* make that work.
|
||||
*/
|
||||
p->sf.hdrsize = sizeof(struct pcap_sf_patched_pkthdr);
|
||||
} else
|
||||
@ -694,8 +844,8 @@ pcap_open_offline(const char *fname, char *errbuf)
|
||||
p->sf.version_major = hdr.version_major;
|
||||
p->sf.version_minor = hdr.version_minor;
|
||||
#ifdef PCAP_FDDIPAD
|
||||
/* XXX padding only needed for kernel fcode */
|
||||
pcap_fddipad = 0;
|
||||
/* Padding only needed for live capture fcode */
|
||||
p->fddipad = 0;
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -728,7 +878,7 @@ pcap_open_offline(const char *fname, char *errbuf)
|
||||
break;
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
#if !defined(WIN32) && !defined(MSDOS)
|
||||
/*
|
||||
* You can do "select()" and "poll()" on plain files on most
|
||||
* platforms, and should be able to do so on pipes.
|
||||
@ -740,6 +890,7 @@ pcap_open_offline(const char *fname, char *errbuf)
|
||||
#endif
|
||||
|
||||
p->read_op = pcap_offline_read;
|
||||
p->inject_op = sf_inject;
|
||||
p->setfilter_op = install_bpf_program;
|
||||
p->set_datalink_op = NULL; /* we don't support munging link-layer headers */
|
||||
p->getnonblock_op = sf_getnonblock;
|
||||
@ -747,10 +898,17 @@ pcap_open_offline(const char *fname, char *errbuf)
|
||||
p->stats_op = sf_stats;
|
||||
p->close_op = sf_close;
|
||||
|
||||
#if defined(WIN32) || defined(MSDOS)
|
||||
/*
|
||||
* If we're reading from the standard input, put it in binary
|
||||
* mode, as savefiles are binary files.
|
||||
*/
|
||||
if (fp == stdin)
|
||||
SET_BINMODE(fp);
|
||||
#endif
|
||||
|
||||
return (p);
|
||||
bad:
|
||||
if(fp)
|
||||
fclose(fp);
|
||||
free(p);
|
||||
return (NULL);
|
||||
}
|
||||
@ -906,7 +1064,7 @@ sf_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char *buf, u_int buflen)
|
||||
int
|
||||
pcap_offline_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
{
|
||||
struct bpf_insn *fcode = p->fcode.bf_insns;
|
||||
struct bpf_insn *fcode;
|
||||
int status = 0;
|
||||
int n = 0;
|
||||
|
||||
@ -937,7 +1095,7 @@ pcap_offline_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
return (status);
|
||||
}
|
||||
|
||||
if (fcode == NULL ||
|
||||
if ((fcode = p->fcode.bf_insns) == NULL ||
|
||||
bpf_filter(fcode, p->buffer, h.len, h.caplen)) {
|
||||
(*callback)(user, &h, p->buffer);
|
||||
if (++n >= cnt && cnt > 0)
|
||||
@ -967,6 +1125,33 @@ pcap_dump(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
|
||||
(void)fwrite((char *)sp, h->caplen, 1, f);
|
||||
}
|
||||
|
||||
static pcap_dumper_t *
|
||||
pcap_setup_dump(pcap_t *p, int linktype, FILE *f, const char *fname)
|
||||
{
|
||||
|
||||
#if defined(WIN32) || defined(MSDOS)
|
||||
/*
|
||||
* If we're writing to the standard output, put it in binary
|
||||
* mode, as savefiles are binary files.
|
||||
*
|
||||
* Otherwise, we turn off buffering.
|
||||
* XXX - why? And why not on the standard output?
|
||||
*/
|
||||
if (f == stdout)
|
||||
SET_BINMODE(f);
|
||||
else
|
||||
setbuf(f, NULL);
|
||||
#endif
|
||||
if (sf_write_header(f, linktype, p->tzoff, p->snapshot) == -1) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Can't write to %s: %s",
|
||||
fname, pcap_strerror(errno));
|
||||
if (f != stdout)
|
||||
(void)fclose(f);
|
||||
return (NULL);
|
||||
}
|
||||
return ((pcap_dumper_t *)f);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize so that sf_write() will output to the file named 'fname'.
|
||||
*/
|
||||
@ -986,15 +1171,12 @@ pcap_dump_open(pcap_t *p, const char *fname)
|
||||
|
||||
if (fname[0] == '-' && fname[1] == '\0') {
|
||||
f = stdout;
|
||||
#ifdef WIN32
|
||||
_setmode(_fileno(f), _O_BINARY);
|
||||
#endif
|
||||
fname = "standard output";
|
||||
} else {
|
||||
#ifndef WIN32
|
||||
#if !defined(WIN32) && !defined(MSDOS)
|
||||
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",
|
||||
@ -1002,8 +1184,26 @@ pcap_dump_open(pcap_t *p, const char *fname)
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
(void)sf_write_header(f, linktype, p->tzoff, p->snapshot);
|
||||
return ((pcap_dumper_t *)f);
|
||||
return (pcap_setup_dump(p, linktype, f, fname));
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize so that sf_write() will output to the given stream.
|
||||
*/
|
||||
pcap_dumper_t *
|
||||
pcap_dump_fopen(pcap_t *p, FILE *f)
|
||||
{
|
||||
int linktype;
|
||||
|
||||
linktype = dlt_to_linktype(p->linktype);
|
||||
if (linktype == -1) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"stream: link-layer type %d isn't supported in savefiles",
|
||||
linktype);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
return (pcap_setup_dump(p, linktype, f, "stream"));
|
||||
}
|
||||
|
||||
FILE *
|
||||
|
@ -22,7 +22,7 @@
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid[] _U_ =
|
||||
"@(#) $Header: /tcpdump/master/libpcap/scanner.l,v 1.95.2.3 2004/03/28 21:45:33 fenner Exp $ (LBL)";
|
||||
"@(#) $Header: /tcpdump/master/libpcap/scanner.l,v 1.99 2004/06/16 08:20:28 hannes Exp $ (LBL)";
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
@ -260,6 +260,7 @@ inbound return INBOUND;
|
||||
outbound return OUTBOUND;
|
||||
|
||||
vlan return VLAN;
|
||||
mpls return MPLS;
|
||||
|
||||
lane return LANE;
|
||||
llc return LLC;
|
||||
|
Loading…
Reference in New Issue
Block a user