Virgin import of libpcap v0.9.1 (alpha 096) from tcpdump.org

This commit is contained in:
Sam Leffler 2005-05-29 17:46:52 +00:00
parent feb4ecdbac
commit 04fb274578
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/vendor/libpcap/dist/; revision=146768
53 changed files with 7274 additions and 1347 deletions

View File

@ -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

View File

@ -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>

View File

@ -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

View File

@ -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

View File

@ -17,7 +17,7 @@
# WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
#
# @(#) $Header: /tcpdump/master/libpcap/Makefile.in,v 1.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

View File

@ -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.

View File

@ -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-------------------------------------

View 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.

View File

@ -1 +1 @@
0.8.3
0.9-PRE-CVS

View File

@ -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

View File

@ -40,7 +40,7 @@
#if !(defined(lint) || defined(KERNEL) || defined(_KERNEL))
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/bpf/net/bpf_filter.c,v 1.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

View File

@ -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

View File

@ -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

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
dnl @(#) $Header: /tcpdump/master/libpcap/configure.in,v 1.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

View File

@ -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

View File

@ -18,7 +18,7 @@
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* @(#) $Header: /tcpdump/master/libpcap/ethertype.h,v 1.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

View File

@ -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));
}

View File

@ -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.
*/

View File

@ -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.
*/

View File

@ -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

View File

@ -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);
}

View File

@ -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;

View File

@ -18,7 +18,7 @@
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* @(#) $Header: /tcpdump/master/libpcap/gencode.h,v 1.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);

View File

@ -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; }
;

View File

@ -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 */

View File

@ -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 */

View File

@ -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);

View File

@ -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);
}

View File

@ -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.
*/

View File

@ -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;
}

View File

@ -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

File diff suppressed because it is too large Load Diff

227
contrib/libpcap/pcap-dos.h Normal file
View 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 */

View File

@ -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

View File

@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#) $Header: /tcpdump/master/libpcap/pcap-int.h,v 1.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 *);

View File

@ -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);
}
/*

View File

@ -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.

View File

@ -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;

View File

@ -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

View File

@ -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);
}

View File

@ -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:

View File

@ -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);
}

View File

@ -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)

View File

@ -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() .

View File

@ -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)

View File

@ -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
View 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

View File

@ -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];

View File

@ -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 */

View File

@ -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 *

View 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;