mirror of
https://github.com/nmap/nmap.git
synced 2026-01-15 02:49:02 +00:00
Updated libpcap from 0.8.3 to 0.9.3
This commit is contained in:
@@ -1,4 +1,13 @@
|
||||
@(#) $Header$ (LBL)
|
||||
@(#) $Header: /tcpdump/master/libpcap/CHANGES,v 1.59.2.3 2005/07/11 20:09:47 mcr Exp $ (LBL)
|
||||
|
||||
Tue. July 5, 2005. ken@xelerance.com. Summary for 0.9.x libpcap
|
||||
|
||||
Fixes for compiling on nearly every platform,
|
||||
including improved 64bit support
|
||||
MSDOS Support
|
||||
Add support for sending packets
|
||||
OpenBSD pf format support
|
||||
IrDA capture (Linux only)
|
||||
|
||||
Tue. March 30, 2004. mcr@sandelman.ottawa.on.ca. Summary for 3.8.3 release
|
||||
|
||||
|
||||
@@ -21,14 +21,19 @@ 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>
|
||||
Gilbert Hoyek <gil_hoyek@hotmail.com>
|
||||
Gisle Vanem <giva@bgnett.no>
|
||||
Graeme Hewson <ghewson@cix.compulink.co.uk>
|
||||
Greg Stark <gsstark@mit.edu>
|
||||
@@ -54,14 +59,20 @@ Additional people who have contributed patches:
|
||||
Love H<>rnquist-<2D>strand <lha@stacken.kth.se>
|
||||
Maciej W. Rozycki <macro@ds2.pg.gda.pl>
|
||||
Marcus Felipe Pereira <marcus@task.com.br>
|
||||
Mark C. Brown <mbrown@hp.com>
|
||||
Mark Pizzolato <List-tcpdump-workers@subscriptions.pizzolato.net>
|
||||
Martin Husemann <martin@netbsd.org>
|
||||
Matthew Luckie <mjl@luckie.org.nz>
|
||||
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>
|
||||
Patrick Marie <mycroft@virgaria.org>
|
||||
Paul Mundt <lethal@linux-sh.org>
|
||||
Pavel Kankovsky <kan@dcit.cz>
|
||||
Pawel Pokrywka <publicpp@gmail.com>
|
||||
Peter Fales <peter@fales-lorenz.net>
|
||||
Peter Jeremy <peter.jeremy@alcatel.com.au>
|
||||
Phil Wood <cpw@lanl.gov>
|
||||
@@ -74,6 +85,7 @@ Additional people who have contributed patches:
|
||||
Solomon Peachy <pizza@shaftnet.org>
|
||||
Stefan Hudson <hudson@mbay.net>
|
||||
Takashi Yamamoto <yamt@mwd.biglobe.ne.jp>
|
||||
Tanaka Shin-ya <zstanaka@archer.livedoor.com>
|
||||
Tony Li <tli@procket.com>
|
||||
Torsten Landschoff <torsten@debian.org>
|
||||
Uns Lider <unslider@miranda.org>
|
||||
|
||||
33
libpcap-possiblymodified/ChmodBPF/ChmodBPF
Normal file
33
libpcap-possiblymodified/ChmodBPF/ChmodBPF
Normal file
@@ -0,0 +1,33 @@
|
||||
#! /bin/sh
|
||||
|
||||
. /etc/rc.common
|
||||
|
||||
StartService ()
|
||||
{
|
||||
#
|
||||
# Unfortunately, Mac OS X's devfs is based on the old FreeBSD
|
||||
# one, not the current one, so there's no way to configure it
|
||||
# to create BPF devices with particular owners or groups.
|
||||
# This startup item will make it owned by the admin group,
|
||||
# with permissions rw-rw----, so that anybody in the admin
|
||||
# group can use programs that capture or send raw packets.
|
||||
#
|
||||
# Change this as appropriate for your site, e.g. to make
|
||||
# it owned by a particular user without changing the permissions,
|
||||
# so only that user and the super-user can capture or send raw
|
||||
# packets, or give it the permissions rw-r-----, so that
|
||||
# only the super-user can send raw packets but anybody in the
|
||||
# admin group can capture packets.
|
||||
#
|
||||
chgrp admin /dev/bpf*
|
||||
chmod g+rw /dev/bpf*
|
||||
}
|
||||
|
||||
StopService ()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
RestartService () { StartService; }
|
||||
|
||||
RunService "$1"
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
Description = "Change BPF permissions";
|
||||
Provides = ("Non-root permission to capture or send raw packets");
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
CHANGES
|
||||
ChmodBPF/ChmodBPF
|
||||
ChmodBPF/StartupParameters.plist
|
||||
CREDITS
|
||||
FILES
|
||||
INSTALL.txt
|
||||
@@ -9,6 +11,8 @@ README.aix
|
||||
README.dag
|
||||
README.hpux
|
||||
README.linux
|
||||
README.macosx
|
||||
README.septel
|
||||
README.tru64
|
||||
README.Win32
|
||||
SUNOS4/nit_if.o.sparc
|
||||
@@ -48,16 +52,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
|
||||
@@ -67,6 +88,8 @@ pcap-nit.h
|
||||
pcap-null.c
|
||||
pcap-pf.c
|
||||
pcap-pf.h
|
||||
pcap-septel.c
|
||||
pcap-septel.h
|
||||
pcap-stdinc.h
|
||||
pcap-snit.c
|
||||
pcap-snoop.c
|
||||
@@ -76,11 +99,9 @@ pcap.c
|
||||
pcap.h
|
||||
pf.h
|
||||
ppp.h
|
||||
rawss7.h
|
||||
savefile.c
|
||||
scanner.l
|
||||
sll.h
|
||||
snprintf.c
|
||||
sunatmpos.h
|
||||
Win32/Include/Gnuc.h
|
||||
Win32/Include/addrinfo.h
|
||||
|
||||
@@ -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,8 @@ 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.septel - notes on using libpcap to capture on Intel/Septel devices
|
||||
README.tru64 - notes on using libpcap on Digital/Tru64 UNIX
|
||||
README.Win32 - notes on using libpcap on Win32 systems (with WinPcap)
|
||||
SUNOS4 - pre-SunOS 4.1 replacement kernel nit modules
|
||||
@@ -336,7 +340,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 +353,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
|
||||
@@ -356,6 +364,8 @@ pcap-nit.h - SunOS Network Interface Tap definitions
|
||||
pcap-null.c - dummy monitor support (allows offline use of libpcap)
|
||||
pcap-pf.c - Ultrix and Digital/Tru64 UNIX Packet Filter support
|
||||
pcap-pf.h - Ultrix and Digital/Tru64 UNIX Packet Filter definitions
|
||||
pcap-septel.c - INTEL/Septel device capture support
|
||||
pcap-septel.h - INTEL/Septel device capture support
|
||||
pcap-stdinc.h - includes and #defines for compiling on Win32 systems
|
||||
pcap-snit.c - SunOS 4.x STREAMS-based Network Interface Tap support
|
||||
pcap-snoop.c - IRIX Snoop network monitoring support
|
||||
@@ -369,6 +379,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
|
||||
|
||||
@@ -46,6 +46,7 @@ CCOPT = @V_CCOPT@
|
||||
INCLS = -I. @V_INCLS@
|
||||
DEFS = @DEFS@ @V_DEFS@
|
||||
LIBS = @V_LIBS@
|
||||
DYEXT = @DYEXT@
|
||||
|
||||
# Standard CFLAGS
|
||||
CFLAGS = $(CCOPT) $(INCLS) $(DEFS)
|
||||
@@ -103,6 +104,24 @@ libpcap.a: $(OBJ)
|
||||
ar rc $@ $(OBJ) $(LIBS)
|
||||
$(RANLIB) $@
|
||||
|
||||
shared: libpcap.$(DYEXT)
|
||||
|
||||
#
|
||||
# XXX - this works with GNU ld, but won't necessarily work with native
|
||||
# ld on, for example, various SVR4-flavored platforms, or Digital UNIX.
|
||||
#
|
||||
libpcap.so: $(OBJ)
|
||||
@rm -f $@
|
||||
ld -shared -o $@.`cat VERSION` $(OBJ)
|
||||
|
||||
# the following rule succeeds, but the result is untested.
|
||||
libpcap.dylib: $(OBJ)
|
||||
rm -f libpcap*.dylib
|
||||
$(CC) -dynamiclib -undefined error -o libpcap.`cat VERSION`.dylib $(OBJ) \
|
||||
-install_name $(libdir)/libpcap.0.dylib -compatibility_version `cat VERSION` \
|
||||
-current_version `cat VERSION`
|
||||
|
||||
|
||||
scanner.c: $(srcdir)/scanner.l
|
||||
@rm -f $@
|
||||
$(LEX) -t $< > $$$$.$@; mv $$$$.$@ $@
|
||||
@@ -151,7 +170,7 @@ bpf_filter.c: $(srcdir)/bpf/net/bpf_filter.c
|
||||
bpf_filter.o: bpf_filter.c
|
||||
$(CC) $(CFLAGS) -c bpf_filter.c
|
||||
|
||||
install:
|
||||
install: libpcap.a
|
||||
[ -d $(DESTDIR)$(libdir) ] || \
|
||||
(mkdir -p $(DESTDIR)$(libdir); chmod 755 $(DESTDIR)$(libdir))
|
||||
$(INSTALL_DATA) libpcap.a $(DESTDIR)$(libdir)/libpcap.a
|
||||
@@ -168,6 +187,13 @@ install:
|
||||
$(INSTALL_DATA) $(srcdir)/pcap.3 \
|
||||
$(DESTDIR)$(mandir)/man3/pcap.3
|
||||
|
||||
install-shared: install-shared-$(DYEXT)
|
||||
install-shared-so: libpcap.so
|
||||
$(INSTALL_PROGRAM) libpcap.so.`cat VERSION` $(DESTDIR)$(libdir)/libpcap.so.`cat VERSION`
|
||||
install-shared-dylib: libpcap.dylib
|
||||
$(INSTALL_PROGRAM) libpcap.`cat VERSION`.dylib $(DESTDIR)$(libdir)/libpcap.`cat VERSION`.dylib
|
||||
VER=`cat VERSION`; cd $(DESTDIR)$(libdir) && ln -sf libpcap.$$VER.dylib libpcap.0.dylib; ln -sf libpcap.0.dylib libpcap.dylib
|
||||
|
||||
uninstall:
|
||||
rm -f $(DESTDIR)$(libdir)/libpcap.a
|
||||
rm -f $(DESTDIR)$(includedir)/pcap.h
|
||||
@@ -176,16 +202,21 @@ uninstall:
|
||||
rm -f $(DESTDIR)$(mandir)/man3/pcap.3
|
||||
|
||||
clean:
|
||||
rm -f $(CLEANFILES)
|
||||
rm -f $(CLEANFILES) libpcap*.dylib libpcap.so*
|
||||
|
||||
distclean:
|
||||
rm -f $(CLEANFILES) Makefile config.cache config.log config.status \
|
||||
distclean: clean
|
||||
rm -f Makefile config.cache config.log config.status \
|
||||
config.h gnuc.h os-proto.h bpf_filter.c stamp-h stamp-h.in
|
||||
rm -rf autom4te.cache
|
||||
|
||||
tags: $(TAGFILES)
|
||||
ctags -wtd $(TAGFILES)
|
||||
|
||||
tar:
|
||||
packaging/pcap.spec: packaging/pcap.spec.in VERSION
|
||||
RPMVERSION=`cat VERSION | sed s/-.*//g`; \
|
||||
sed -e s/@VERSION@/$$RPMVERSION/ -e s/@NAME@/libpcap-`cat VERSION`/ $< > $@
|
||||
|
||||
tar: Makefile packaging/pcap.spec
|
||||
@cwd=`pwd` ; dir=`basename $$cwd` ; name=libpcap-`cat VERSION` ; \
|
||||
list="" ; tar="tar chf" ; \
|
||||
for i in `cat FILES` ; do list="$$list $$name/$$i" ; done; \
|
||||
@@ -193,11 +224,16 @@ tar:
|
||||
"rm -f ../$$name; ln -s $$dir ../$$name" ; \
|
||||
rm -f ../$$name; ln -s $$dir ../$$name ; \
|
||||
echo \
|
||||
"(cd .. ; $$tar - [lots of files]) | compress > /tmp/$$name.tar.Z" ; \
|
||||
(cd .. ; $$tar - $$list) | compress > /tmp/$$name.tar.Z ; \
|
||||
"(cd .. ; $$tar - [lots of files]) | gzip -c > /tmp/$$name.tar.gz" ; \
|
||||
(cd .. ; $$tar - $$list) | gzip -c > /tmp/$$name.tar.gz ; \
|
||||
echo \
|
||||
"rm -f ../$$name" ; \
|
||||
rm -f ../$$name
|
||||
|
||||
depend: $(GENSRC) $(GENHDR) bpf_filter.c
|
||||
./mkdep -c $(CC) $(DEFS) $(INCLS) $(SRC)
|
||||
|
||||
Makefile: Makefile.in config.status
|
||||
./config.status
|
||||
@echo your Makefile was out of date, now run $(MAKE) again
|
||||
exit 1
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
@(#) $Header$ (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.
|
||||
|
||||
|
||||
@@ -37,12 +37,57 @@ cards and will not capture from the native OS packet stream.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Libpcap when built for DAG cards against dag-2.5.1 or later releases:
|
||||
|
||||
Timeouts are supported. pcap_dispatch() will return after to_ms milliseconds
|
||||
regardless of how many packets are received. If to_ms is zero pcap_dispatch()
|
||||
will block waiting for data indefinitely.
|
||||
|
||||
pcap_dispatch() will block on and process a minimum of 64kB of data (before
|
||||
filtering) for efficiency. This can introduce high latencies on quiet
|
||||
interfaces unless a timeout value is set. The timeout expiring will override
|
||||
the 64kB minimum causing pcap_dispatch() to process any available data and
|
||||
return.
|
||||
|
||||
pcap_setnonblock is supported. When nonblock is set, pcap_dispatch() will
|
||||
check once for available data, process any data available up to count, then
|
||||
return immediately.
|
||||
|
||||
pcap_findalldevs() is supported, e.g. dag0, dag1...
|
||||
|
||||
Some DAG cards can provide more than one 'stream' of received data.
|
||||
This can be data from different physical ports, or separated by filtering
|
||||
or load balancing mechanisms. Receive streams have even numbers, e.g.
|
||||
dag0:0, dag0:2 etc. Specifying transmit streams for capture is not supported.
|
||||
|
||||
pcap_setfilter() is supported, BPF programs run in userspace.
|
||||
|
||||
pcap_setdirection() is not supported. Only received traffic is captured.
|
||||
DAG cards normally do not have IP or link layer addresses assigned as
|
||||
they are used to passively monitor links.
|
||||
|
||||
pcap_breakloop() is supported.
|
||||
|
||||
pcap_datalink() and pcap_list_datalinks() are supported. The DAG card does
|
||||
not attempt to set the correct datalink type automatically where more than
|
||||
one type is possible.
|
||||
|
||||
pcap_stats() is supported. ps_drop is the number of packets dropped due to
|
||||
RX stream buffer overflow, this count is before filters are applied (it will
|
||||
include packets that would have been dropped by the filter). The RX stream
|
||||
buffer size is user configurable outside libpcap, typically 16-512MB.
|
||||
|
||||
pcap_get_selectable_fd() is not supported, DAG cards do not support
|
||||
poll/select methods.
|
||||
|
||||
pcap_inject() and pcap_sendpacket() are not supported.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Please submit bug reports via <support@endace.com>.
|
||||
|
||||
Please also visit our Web pages at:
|
||||
Please also visit our Web site at:
|
||||
|
||||
http://www.endace.com/
|
||||
http://dag.cs.waikato.ac.nz/
|
||||
|
||||
For more information about Endace DAG cards contact <sales@endace.com>.
|
||||
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
For HP-UX 11i (11.11) and later, there are no known issues with
|
||||
promiscuous mode under HP-UX. If you are using a earlier version of
|
||||
HP-UX and cannot upgrade, please continue reading.
|
||||
|
||||
HP-UX patches to fix packet capture problems
|
||||
|
||||
Note that packet-capture programs such as tcpdump may, on HP-UX, not be
|
||||
@@ -182,6 +186,10 @@ An additional note, from Jost Martin, for HP-UX 10.20:
|
||||
/sbin/rc2.d/S350hack_ip_stack pointing to this script.
|
||||
Now all this is done on every reboot.
|
||||
|
||||
According to Rick Jones, the global promiscuous switch also has to be
|
||||
turned on for HP-UX 11.00, but not for 11i - and, in fact, the switch
|
||||
doesn't even exist on 11i.
|
||||
|
||||
Here's the "hack_ip_stack" script:
|
||||
|
||||
-----------------------------------Cut Here-------------------------------------
|
||||
|
||||
43
libpcap-possiblymodified/README.macosx
Normal file
43
libpcap-possiblymodified/README.macosx
Normal file
@@ -0,0 +1,43 @@
|
||||
As with other systems using BPF, Mac OS X allows users with read access
|
||||
to the BPF devices to capture packets with libpcap and allows users with
|
||||
write access to the BPF devices to send packets with libpcap.
|
||||
|
||||
On some systems that use BPF, the BPF devices live on the root file
|
||||
system, and the permissions and/or ownership on those devices can be
|
||||
changed to give users other than root permission to read or write those
|
||||
devices.
|
||||
|
||||
On newer versions of FreeBSD, the BPF devices live on devfs, and devfs
|
||||
can be configured to set the permissions and/or ownership of those
|
||||
devices to give users other than root permission to read or write those
|
||||
devices.
|
||||
|
||||
On Mac OS X, the BPF devices live on devfs, but the OS X version of
|
||||
devfs is based on an older (non-default) FreeBSD devfs, and that version
|
||||
of devfs cannot be configured to set the permissions and/or ownership of
|
||||
those devices.
|
||||
|
||||
Therefore, we supply a "startup item" for OS X that will change the
|
||||
ownership of the BPF devices so that the "admin" group owns them, and
|
||||
will change the permission of the BPF devices to rw-rw----, so that all
|
||||
users in the "admin" group - i.e., all users with "Allow user to
|
||||
administer this computer" turned on - have both read and write access to
|
||||
them.
|
||||
|
||||
The startup item is in the ChmodBPF directory in the source tree. A
|
||||
/Library/StartupItems directory should be created if it doesn't already
|
||||
exist, and the ChmodBPF directory should be copied to the
|
||||
/Library/StartupItems directory (copy the entire directory, so that
|
||||
there's a /Library/StartupItems/ChmodBPF directory, containing all the
|
||||
files in the source tree's ChmodBPF directory; don't copy the individual
|
||||
items in that directory to /Library/StartupItems).
|
||||
|
||||
If you want to give a particular user permission to access the BPF
|
||||
devices, rather than giving all administrative users permission to
|
||||
access them, you can have the ChmodBPF/ChmodBPF script change the
|
||||
ownership of /dev/bpf* without changing the permissions. If you want to
|
||||
give a particular user permission to read and write the BPF devices and
|
||||
give the administrative users permission to read but not write the BPF
|
||||
devices, you can have the script change the owner to that user, the
|
||||
group to "admin", and the permissions to rw-r-----. Other possibilities
|
||||
are left as an exercise for the reader.
|
||||
50
libpcap-possiblymodified/README.septel
Normal file
50
libpcap-possiblymodified/README.septel
Normal file
@@ -0,0 +1,50 @@
|
||||
The following instructions apply if you have a Linux platform and want
|
||||
libpcap to support the Septel range of passive network monitoring cards
|
||||
from Intel (http://www.intel.com)
|
||||
|
||||
1) Install and build the Septel software distribution by following the
|
||||
instructions supplied with that package.
|
||||
|
||||
2) Configure libcap. To allow the 'configure' script to locate the Septel
|
||||
software distribution use the '--with-septel' option:
|
||||
|
||||
./configure --with-septel=DIR
|
||||
|
||||
where DIR is the root of the Septel software distribution, for example
|
||||
/var/src/septel.
|
||||
|
||||
By default (if you write only ./configure --with-septel) it takes
|
||||
./../septel as argument for DIR.
|
||||
|
||||
If the Septel software is correctly detected 'configure' will
|
||||
report:
|
||||
|
||||
checking whether we have Septel API... yes
|
||||
|
||||
If 'configure' reports that there is no Septel API, the directory may have been
|
||||
incorrectly specified or the Septel software was not built before configuring
|
||||
libpcap.
|
||||
|
||||
See also the libpcap INSTALL.txt file for further libpcap configuration
|
||||
options.
|
||||
|
||||
Building libpcap at this stage will include support for both the native
|
||||
packet capture stream and for capturing from Septel cards. To build
|
||||
libpcap with only Septel support specify the capture type as 'septel'
|
||||
when configuring libpcap:
|
||||
|
||||
./configure --with-septel=DIR --with-pcap=septel
|
||||
|
||||
Applications built with libpcap configured in this way will only detect Septel
|
||||
cards and will not capture from the native OS packet stream.
|
||||
|
||||
Note: As mentioned in pcap-septel.c we should first edit the system.txt
|
||||
file to change the user part example (UPE) module id to 0xdd instead of
|
||||
0x2d for technical reason. So this change in system.txt is crutial and
|
||||
things will go wrong if it's not done. System.txt along with config.txt
|
||||
are configuration files that are edited by the user before running the
|
||||
gctload program that uses these files for initialising modules and
|
||||
configuring parameters.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
for more information please contact me : gil_hoyek@hotmail.com
|
||||
@@ -1 +1 @@
|
||||
0.8.3
|
||||
0.9.2
|
||||
|
||||
@@ -83,4 +83,53 @@ typedef signed short int32_t;
|
||||
|
||||
#endif /* HAVE_U_INT32_T */
|
||||
|
||||
#ifndef HAVE_U_INT64_T
|
||||
#if SIZEOF_LONG_LONG == 8
|
||||
typedef unsigned long long u_int64_t;
|
||||
#elif defined(_MSC_EXTENSIONS)
|
||||
typedef unsigned _int64 u_int64_t;
|
||||
#elif SIZEOF_INT == 8
|
||||
typedef unsigned int u_int64_t;
|
||||
#elif SIZEOF_LONG == 8
|
||||
typedef unsigned long u_int64_t;
|
||||
#elif SIZEOF_SHORT == 8
|
||||
typedef unsigned short u_int64_t;
|
||||
#else /* XXX */
|
||||
#error "there's no appropriate type for u_int64_t"
|
||||
#endif
|
||||
|
||||
#endif /* HAVE_U_INT64_T */
|
||||
|
||||
#ifndef PRId64
|
||||
#ifdef _MSC_EXTENSIONS
|
||||
#define PRId64 "I64d"
|
||||
#else /* _MSC_EXTENSIONS */
|
||||
#define PRId64 "lld"
|
||||
#endif /* _MSC_EXTENSIONS */
|
||||
#endif /* PRId64 */
|
||||
|
||||
#ifndef PRIo64
|
||||
#ifdef _MSC_EXTENSIONS
|
||||
#define PRIo64 "I64o"
|
||||
#else /* _MSC_EXTENSIONS */
|
||||
#define PRIo64 "llo"
|
||||
#endif /* _MSC_EXTENSIONS */
|
||||
#endif /* PRIo64 */
|
||||
|
||||
#ifndef PRIx64
|
||||
#ifdef _MSC_EXTENSIONS
|
||||
#define PRIx64 "I64x"
|
||||
#else /* _MSC_EXTENSIONS */
|
||||
#define PRIx64 "llx"
|
||||
#endif /* _MSC_EXTENSIONS */
|
||||
#endif /* PRIx64 */
|
||||
|
||||
#ifndef PRIu64
|
||||
#ifdef _MSC_EXTENSIONS
|
||||
#define PRIu64 "I64u"
|
||||
#else /* _MSC_EXTENSIONS */
|
||||
#define PRIu64 "llu"
|
||||
#endif /* _MSC_EXTENSIONS */
|
||||
#endif /* PRIu64 */
|
||||
|
||||
#endif /* _BITTYPES_H */
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
|
||||
#define IN_MULTICAST(a) IN_CLASSD(a)
|
||||
|
||||
#define IN_EXPERIMENTAL(a) ((((u_int32_t) (a)) & 0xe0000000) == 0xe0000000)
|
||||
#define IN_EXPERIMENTAL(a) ((((u_int32_t) (a)) & 0xf0000000) == 0xf0000000)
|
||||
|
||||
#define IN_LOOPBACKNET 127
|
||||
|
||||
@@ -58,8 +58,12 @@ struct in6_addr
|
||||
#endif /* __MINGW32__ */
|
||||
|
||||
|
||||
#ifdef __MINGW32__
|
||||
#if (defined WIN32) || (defined __MINGW32__)
|
||||
typedef unsigned short sa_family_t;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __MINGW32__
|
||||
|
||||
#define __SOCKADDR_COMMON(sa_prefix) \
|
||||
sa_family_t sa_prefix##family
|
||||
|
||||
@@ -41,7 +41,7 @@ RSC=rc.exe
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../" /I "../../lbl/" /I "../../bpf/" /I "../include/" /I "../../../../common" /D "NDEBUG" /D "YY_NEVER_INTERACTIVE" /D yylval=pcap_lval /D "_USRDLL" /D "LIBPCAP_EXPORTS" /D "HAVE_STRERROR" /D "__STDC__" /D "INET6" /D "_WINDOWS" /D "_MBCS" /D SIZEOF_CHAR=1 /D SIZEOF_SHORT=2 /D SIZEOF_INT=4 /D "HAVE_ADDRINFO" /D "WIN32" /D _U_= /D "HAVE_SNPRINTF" /D "HAVE_VSNPRINTF" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../" /I "../../lbl/" /I "../../bpf/" /I "../include/" /I "../../../../common" /I "../../../../dag/include" /I "../../../../dag/drv/windows" /D "NDEBUG" /D "YY_NEVER_INTERACTIVE" /D yylval=pcap_lval /D "_USRDLL" /D "LIBPCAP_EXPORTS" /D "HAVE_STRERROR" /D "__STDC__" /D "INET6" /D "_WINDOWS" /D "_MBCS" /D SIZEOF_CHAR=1 /D SIZEOF_SHORT=2 /D SIZEOF_INT=4 /D "HAVE_ADDRINFO" /D "WIN32" /D _U_= /D "HAVE_SNPRINTF" /D "HAVE_VSNPRINTF" /YX /FD /c
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
@@ -64,7 +64,7 @@ LIB32=link.exe -lib
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../" /I "../../lbl/" /I "../../bpf/" /I "../include/" /I "../../../../common" /D "_DEBUG" /D "YY_NEVER_INTERACTIVE" /D yylval=pcap_lval /D "_USRDLL" /D "LIBPCAP_EXPORTS" /D "HAVE_STRERROR" /D "__STDC__" /D "INET6" /D "_WINDOWS" /D "_MBCS" /D SIZEOF_CHAR=1 /D SIZEOF_SHORT=2 /D SIZEOF_INT=4 /D "HAVE_ADDRINFO" /D "WIN32" /D _U_= /D "HAVE_SNPRINTF" /D "HAVE_VSNPRINTF" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../" /I "../../lbl/" /I "../../bpf/" /I "../include/" /I "../../../../common" /I "../../../../dag/include" /I "../../../../dag/drv/windows" /D "_DEBUG" /D "YY_NEVER_INTERACTIVE" /D yylval=pcap_lval /D "_USRDLL" /D "LIBPCAP_EXPORTS" /D "HAVE_STRERROR" /D "__STDC__" /D "INET6" /D "_WINDOWS" /D "_MBCS" /D SIZEOF_CHAR=1 /D SIZEOF_SHORT=2 /D SIZEOF_INT=4 /D "HAVE_ADDRINFO" /D "WIN32" /D _U_= /D "HAVE_SNPRINTF" /D "HAVE_VSNPRINTF" /YX /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid[] _U_ =
|
||||
"@(#) $Header$";
|
||||
"@(#) $Header: /tcpdump/master/libpcap/Win32/Src/inet_aton.c,v 1.2 2003/11/15 23:24:06 guy Exp $";
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid[] _U_ =
|
||||
"@(#) $Header$";
|
||||
"@(#) $Header: /tcpdump/master/libpcap/Win32/Src/inet_pton.c,v 1.2 2003/11/15 23:24:06 guy Exp $";
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
47
libpcap-possiblymodified/aclocal.m4
vendored
47
libpcap-possiblymodified/aclocal.m4
vendored
@@ -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 OSes (eg. Solaris) place it in libnsl
|
||||
# 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)))
|
||||
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
|
||||
@@ -848,10 +851,10 @@ dnl
|
||||
AC_DEFUN(AC_C___ATTRIBUTE__, [
|
||||
AC_MSG_CHECKING(for __attribute__)
|
||||
AC_CACHE_VAL(ac_cv___attribute__, [
|
||||
AC_TRY_COMPILE([
|
||||
AC_COMPILE_IFELSE(
|
||||
AC_LANG_SOURCE([[
|
||||
#include <stdlib.h>
|
||||
],
|
||||
[
|
||||
|
||||
static void foo(void) __attribute__ ((noreturn));
|
||||
|
||||
static void
|
||||
@@ -859,7 +862,13 @@ foo(void)
|
||||
{
|
||||
exit(1);
|
||||
}
|
||||
],
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
foo();
|
||||
}
|
||||
]]),
|
||||
ac_cv___attribute__=yes,
|
||||
ac_cv___attribute__=no)])
|
||||
if test "$ac_cv___attribute__" = "yes"; then
|
||||
|
||||
1
libpcap-possiblymodified/bpf_filter.c
Symbolic link
1
libpcap-possiblymodified/bpf_filter.c
Symbolic link
@@ -0,0 +1 @@
|
||||
./bpf/net/bpf_filter.c
|
||||
@@ -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,180 @@
|
||||
*/
|
||||
#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 if you have streams capable DAG API */
|
||||
#undef HAVE_DAG_STREAMS_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
|
||||
/* Define to 1 if you have the `ether_hostton' function. */
|
||||
#undef HAVE_ETHER_HOSTTON
|
||||
|
||||
/* 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 10.20 or later */
|
||||
#undef HAVE_HPUX10_20_OR_LATER
|
||||
|
||||
/* on HP-UX 9.x */
|
||||
#undef HAVE_HPUX9
|
||||
|
||||
/* on HP-UX 10.20 */
|
||||
#undef HAVE_HPUX10_20
|
||||
/* if ppa_info_t_dl_module_id exists */
|
||||
#undef HAVE_HP_PPA_INFO_T_DL_MODULE_ID_1
|
||||
|
||||
/* on sinix */
|
||||
#undef sinix
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#undef HAVE_INTTYPES_H
|
||||
|
||||
/* On solaris */
|
||||
#undef HAVE_SOLARIS
|
||||
/* 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 if you have a Septel API */
|
||||
#undef HAVE_SEPTEL_API
|
||||
|
||||
/* 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 the system has the type `struct ether_addr'. */
|
||||
#undef HAVE_STRUCT_ETHER_ADDR
|
||||
|
||||
/* 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
|
||||
|
||||
579
libpcap-possiblymodified/configure
vendored
579
libpcap-possiblymodified/configure
vendored
@@ -2654,6 +2654,8 @@ _ACEOF
|
||||
|
||||
echo "$as_me:$LINENO: checking for inline" >&5
|
||||
echo $ECHO_N "checking for inline... $ECHO_C" >&6
|
||||
save_CFLAGS="$CFLAGS"
|
||||
CFLAGS="$V_CCOPT"
|
||||
if test "${ac_cv_lbl_inline+set}" = set; then
|
||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||
else
|
||||
@@ -2728,6 +2730,7 @@ rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
fi
|
||||
fi
|
||||
|
||||
CFLAGS="$save_CFLAGS"
|
||||
if test ! -z "$ac_cv_lbl_inline" ; then
|
||||
echo "$as_me:$LINENO: result: $ac_cv_lbl_inline" >&5
|
||||
echo "${ECHO_T}$ac_cv_lbl_inline" >&6
|
||||
@@ -2756,10 +2759,6 @@ cat >>conftest.$ac_ext <<_ACEOF
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
|
||||
static void foo(void) __attribute__ ((noreturn));
|
||||
|
||||
static void
|
||||
@@ -2768,9 +2767,12 @@ foo(void)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
;
|
||||
return 0;
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
foo();
|
||||
}
|
||||
|
||||
_ACEOF
|
||||
rm -f conftest.$ac_objext
|
||||
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
|
||||
@@ -3511,8 +3513,7 @@ done
|
||||
|
||||
|
||||
|
||||
|
||||
for ac_header in sys/ioccom.h sys/sockio.h ifaddrs.h limits.h
|
||||
for ac_header in sys/ioccom.h sys/sockio.h limits.h
|
||||
do
|
||||
as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
|
||||
if eval "test \"\${$as_ac_Header+set}\" = set"; then
|
||||
@@ -3723,6 +3724,75 @@ fi
|
||||
|
||||
done
|
||||
|
||||
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.
|
||||
#
|
||||
{ echo "$as_me:$LINENO: Rechecking with some additional includes" >&5
|
||||
echo "$as_me: Rechecking with some additional includes" >&6;}
|
||||
unset ac_cv_header_netinet_if_ether_h
|
||||
|
||||
for ac_header in netinet/if_ether.h
|
||||
do
|
||||
as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
|
||||
echo "$as_me:$LINENO: checking for $ac_header" >&5
|
||||
echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
|
||||
if eval "test \"\${$as_ac_Header+set}\" = set"; then
|
||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||
else
|
||||
cat >conftest.$ac_ext <<_ACEOF
|
||||
#line $LINENO "configure"
|
||||
/* confdefs.h. */
|
||||
_ACEOF
|
||||
cat confdefs.h >>conftest.$ac_ext
|
||||
cat >>conftest.$ac_ext <<_ACEOF
|
||||
/* end confdefs.h. */
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
struct mbuf;
|
||||
struct rtentry;
|
||||
#include <net/if.h>
|
||||
|
||||
#include <$ac_header>
|
||||
_ACEOF
|
||||
rm -f conftest.$ac_objext
|
||||
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
|
||||
(eval $ac_compile) 2>&5
|
||||
ac_status=$?
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } &&
|
||||
{ ac_try='test -s conftest.$ac_objext'
|
||||
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); }; }; then
|
||||
eval "$as_ac_Header=yes"
|
||||
else
|
||||
echo "$as_me: failed program was:" >&5
|
||||
sed 's/^/| /' conftest.$ac_ext >&5
|
||||
|
||||
eval "$as_ac_Header=no"
|
||||
fi
|
||||
rm -f conftest.$ac_objext conftest.$ac_ext
|
||||
fi
|
||||
echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
|
||||
echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
|
||||
if test `eval echo '${'$as_ac_Header'}'` = yes; then
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
fi
|
||||
|
||||
if test "$GCC" = yes ; then
|
||||
echo "$as_me:$LINENO: checking for ANSI ioctl definitions" >&5
|
||||
@@ -3802,8 +3872,7 @@ echo "$as_me: error: see the INSTALL for more info" >&2;}
|
||||
|
||||
|
||||
|
||||
|
||||
for ac_func in ether_hostton strerror strlcpy
|
||||
for ac_func in strerror strlcpy
|
||||
do
|
||||
as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
|
||||
echo "$as_me:$LINENO: checking for $ac_func" >&5
|
||||
@@ -4022,84 +4091,22 @@ esac
|
||||
|
||||
fi
|
||||
|
||||
echo "$as_me:$LINENO: checking if --disable-protochain option is specified" >&5
|
||||
echo $ECHO_N "checking if --disable-protochain option is specified... $ECHO_C" >&6
|
||||
# Check whether --enable-protochain or --disable-protochain was given.
|
||||
if test "${enable_protochain+set}" = set; then
|
||||
enableval="$enable_protochain"
|
||||
|
||||
fi;
|
||||
case "x$enable_protochain" in
|
||||
xyes) enable_protochain=enabled ;;
|
||||
xno) enable_protochain=disabled ;;
|
||||
x) enable_protochain=enabled ;;
|
||||
esac
|
||||
|
||||
if test "$enable_protochain" = "disabled"; then
|
||||
|
||||
cat >>confdefs.h <<\_ACEOF
|
||||
#define NO_PROTOCHAIN 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
echo "$as_me:$LINENO: result: ${enable_protochain}" >&5
|
||||
echo "${ECHO_T}${enable_protochain}" >&6
|
||||
|
||||
if test -z "$with_pcap" && test "$cross_compiling" = yes; then
|
||||
{ { echo "$as_me:$LINENO: error: pcap type not determined when cross-compiling; use --with-pcap=..." >&5
|
||||
echo "$as_me: error: pcap type not determined when cross-compiling; use --with-pcap=..." >&2;}
|
||||
{ (exit 1); exit 1; }; }
|
||||
fi
|
||||
|
||||
# Check whether --with-pcap or --without-pcap was given.
|
||||
if test "${with_pcap+set}" = set; then
|
||||
withval="$with_pcap"
|
||||
|
||||
fi;
|
||||
echo "$as_me:$LINENO: checking packet capture type" >&5
|
||||
echo $ECHO_N "checking packet capture type... $ECHO_C" >&6
|
||||
if test ! -z "$with_pcap" ; then
|
||||
V_PCAP="$withval"
|
||||
elif test -r /dev/bpf0 ; then
|
||||
V_PCAP=bpf
|
||||
elif test -r /usr/include/net/pfilt.h ; then
|
||||
V_PCAP=pf
|
||||
elif test -r /dev/enet ; then
|
||||
V_PCAP=enet
|
||||
elif test -r /dev/nit ; then
|
||||
V_PCAP=snit
|
||||
elif test -r /usr/include/sys/net/nit.h ; then
|
||||
V_PCAP=nit
|
||||
elif test -r /usr/include/linux/socket.h ; then
|
||||
V_PCAP=linux
|
||||
elif test -r /usr/include/net/raw.h ; then
|
||||
V_PCAP=snoop
|
||||
elif test -r /usr/include/odmi.h ; then
|
||||
#
|
||||
# On AIX, the BPF devices might not yet be present - they're
|
||||
# created the first time libpcap runs after booting.
|
||||
# We check for odmi.h instead.
|
||||
# Do this before checking for ether_hostton(), as it's a
|
||||
# "gethostbyname() -ish function".
|
||||
#
|
||||
V_PCAP=bpf
|
||||
elif test -r /usr/include/sys/dlpi.h ; then
|
||||
V_PCAP=dlpi
|
||||
elif test -c /dev/bpf0 ; then # check again in case not readable
|
||||
V_PCAP=bpf
|
||||
elif test -c /dev/enet ; then # check again in case not readable
|
||||
V_PCAP=enet
|
||||
elif test -c /dev/nit ; then # check again in case not readable
|
||||
V_PCAP=snit
|
||||
else
|
||||
V_PCAP=null
|
||||
fi
|
||||
echo "$as_me:$LINENO: result: $V_PCAP" >&5
|
||||
echo "${ECHO_T}$V_PCAP" >&6
|
||||
|
||||
echo "$as_me:$LINENO: checking for getifaddrs" >&5
|
||||
echo $ECHO_N "checking for getifaddrs... $ECHO_C" >&6
|
||||
if test "${ac_cv_func_getifaddrs+set}" = set; then
|
||||
# Most operating systems have gethostbyname() in the default searched
|
||||
# libraries (i.e. libc):
|
||||
# Some OSes (eg. Solaris) place it in libnsl
|
||||
# Some strange OSes (SINIX) have it in libsocket:
|
||||
echo "$as_me:$LINENO: checking for library containing gethostbyname" >&5
|
||||
echo $ECHO_N "checking for library containing gethostbyname... $ECHO_C" >&6
|
||||
if test "${ac_cv_search_gethostbyname+set}" = set; then
|
||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||
else
|
||||
ac_func_search_save_LIBS=$LIBS
|
||||
ac_cv_search_gethostbyname=no
|
||||
cat >conftest.$ac_ext <<_ACEOF
|
||||
/* confdefs.h. */
|
||||
_ACEOF
|
||||
@@ -4293,6 +4300,7 @@ echo "${ECHO_T}$ac_cv_lbl_have_siocglifconf" >&6
|
||||
esac
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
echo "$as_me:$LINENO: checking if --enable-ipv6 option is specified" >&5
|
||||
echo $ECHO_N "checking if --enable-ipv6 option is specified... $ECHO_C" >&6
|
||||
@@ -4629,6 +4637,10 @@ dag)
|
||||
V_DEFS="$V_DEFS -DDAG_ONLY"
|
||||
;;
|
||||
|
||||
septel)
|
||||
V_DEFS="$V_DEFS -DSEPTEL_ONLY"
|
||||
;;
|
||||
|
||||
null)
|
||||
{ echo "$as_me:$LINENO: WARNING: cannot determine packet capture interface" >&5
|
||||
echo "$as_me: WARNING: cannot determine packet capture interface" >&2;}
|
||||
@@ -4655,6 +4667,7 @@ fi
|
||||
echo "$as_me:$LINENO: result: $ac_cv_lbl_proc_net_dev" >&5
|
||||
echo "${ECHO_T}$ac_cv_lbl_proc_net_dev" >&6
|
||||
|
||||
# Check for Endace DAG card support.
|
||||
|
||||
# Check whether --with-dag or --without-dag was given.
|
||||
if test "${with_dag+set}" = set; then
|
||||
@@ -4662,12 +4675,14 @@ if test "${with_dag+set}" = set; then
|
||||
|
||||
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
|
||||
@@ -4678,15 +4693,36 @@ else
|
||||
# Use DAG API if present, otherwise don't
|
||||
#
|
||||
want_dag=ifpresent
|
||||
dag_root=/root/dag
|
||||
|
||||
fi;
|
||||
ac_cv_lbl_dag_api=no
|
||||
|
||||
|
||||
# Check whether --with-dag-includes or --without-dag-includes was given.
|
||||
if test "${with_dag_includes+set}" = set; then
|
||||
withval="$with_dag_includes"
|
||||
|
||||
# User wants DAG support and has specified a header directory, so use the provided value.
|
||||
want_dag=yes
|
||||
dag_include_dir=$withval
|
||||
|
||||
fi;
|
||||
|
||||
|
||||
# Check whether --with-dag-libraries or --without-dag-libraries was given.
|
||||
if test "${with_dag_libraries+set}" = set; then
|
||||
withval="$with_dag_libraries"
|
||||
|
||||
# User wants DAG support and has specified a library directory, so use the provided value.
|
||||
want_dag=yes
|
||||
dag_lib_dir=$withval
|
||||
|
||||
fi;
|
||||
|
||||
case "$V_PCAP" in
|
||||
linux|bpf|dag)
|
||||
#
|
||||
# We support the DAG API on Linux or BSD, or if we're building a
|
||||
# DAG-only libpcap.
|
||||
# We support the DAG API if we're on Linux or BSD, or if we're
|
||||
# building a DAG-only libpcap.
|
||||
#
|
||||
;;
|
||||
*)
|
||||
@@ -4697,8 +4733,8 @@ linux|bpf|dag)
|
||||
# If they expressed no preference, don't include it.
|
||||
#
|
||||
if test $want_dag = yes; then
|
||||
{ { echo "$as_me:$LINENO: error: DAG support only available with 'linux' 'bpf' and 'dag' packet capture types" >&5
|
||||
echo "$as_me: error: DAG support only available with 'linux' 'bpf' and 'dag' packet capture types" >&2;}
|
||||
{ { echo "$as_me:$LINENO: error: DAG support is only available with 'linux' 'bpf' and 'dag' packet capture types" >&5
|
||||
echo "$as_me: error: DAG support is only available with 'linux' 'bpf' and 'dag' packet capture types" >&2;}
|
||||
{ (exit 1); exit 1; }; }
|
||||
elif test $want_dag = yes; then
|
||||
want_dag=no
|
||||
@@ -4706,65 +4742,337 @@ echo "$as_me: error: DAG support only available with 'linux' 'bpf' and 'dag' pac
|
||||
;;
|
||||
esac
|
||||
|
||||
if test "$with_dag" != no; then
|
||||
echo "$as_me:$LINENO: checking whether we have DAG API" >&5
|
||||
echo $ECHO_N "checking whether we have DAG API... $ECHO_C" >&6
|
||||
ac_cv_lbl_dag_api=no
|
||||
if test "$want_dag" != no; then
|
||||
|
||||
echo "$as_me:$LINENO: checking whether we have DAG API headers" >&5
|
||||
echo $ECHO_N "checking whether we have DAG API headers... $ECHO_C" >&6
|
||||
|
||||
# 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
|
||||
echo "$as_me:$LINENO: result: $ac_cv_lbl_dag_api ($dag_include_dir)" >&5
|
||||
echo "${ECHO_T}$ac_cv_lbl_dag_api ($dag_include_dir)" >&6
|
||||
fi
|
||||
|
||||
if test $ac_cv_lbl_dag_api = yes; then
|
||||
|
||||
echo "$as_me:$LINENO: checking dagapi.o" >&5
|
||||
echo $ECHO_N "checking dagapi.o... $ECHO_C" >&6
|
||||
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
|
||||
echo "$as_me:$LINENO: result: no (checked $dag_lib_dir $dag_tools_dir $dag_lib_dir/libdag.a)" >&5
|
||||
echo "${ECHO_T}no (checked $dag_lib_dir $dag_tools_dir $dag_lib_dir/libdag.a)" >&6
|
||||
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
|
||||
echo "$as_me:$LINENO: result: $ac_cv_lbl_dag_api$dag_version" >&5
|
||||
echo "${ECHO_T}$ac_cv_lbl_dag_api$dag_version" >&6
|
||||
if test $ac_cv_lbl_dag_api = no; then
|
||||
if test "$want_dag" = yes; then
|
||||
{ { echo "$as_me:$LINENO: error: DAG API not found under directory $dag_root; use --without-dag" >&5
|
||||
echo "$as_me: error: DAG API not found under directory $dag_root; use --without-dag" >&2;}
|
||||
{ (exit 1); exit 1; }; }
|
||||
fi
|
||||
else
|
||||
echo "$as_me:$LINENO: result: yes ($dagapi_obj)" >&5
|
||||
echo "${ECHO_T}yes ($dagapi_obj)" >&6
|
||||
fi
|
||||
fi
|
||||
|
||||
if test $ac_cv_lbl_dag_api = yes; then
|
||||
|
||||
echo "$as_me:$LINENO: checking dagopts.o" >&5
|
||||
echo $ECHO_N "checking dagopts.o... $ECHO_C" >&6
|
||||
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
|
||||
echo "$as_me:$LINENO: result: no (checked $dag_lib_dir $dag_tools_dir $dag_lib_dir/libdag.a)" >&5
|
||||
echo "${ECHO_T}no (checked $dag_lib_dir $dag_tools_dir $dag_lib_dir/libdag.a)" >&6
|
||||
ac_cv_lbl_dag_api=no
|
||||
else
|
||||
echo "$as_me:$LINENO: result: yes ($dagopts_obj)" >&5
|
||||
echo "${ECHO_T}yes ($dagopts_obj)" >&6
|
||||
fi
|
||||
fi
|
||||
|
||||
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
|
||||
echo "$as_me:$LINENO: checking dagreg.o" >&5
|
||||
echo $ECHO_N "checking dagreg.o... $ECHO_C" >&6
|
||||
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
|
||||
echo "$as_me:$LINENO: result: no (checked $dag_lib_dir $dag_lib_dir/libdag.a)" >&5
|
||||
echo "${ECHO_T}no (checked $dag_lib_dir $dag_lib_dir/libdag.a)" >&6
|
||||
ac_cv_lbl_dag_api=no
|
||||
else
|
||||
echo "$as_me:$LINENO: result: yes ($dagreg_obj)" >&5
|
||||
echo "${ECHO_T}yes ($dagreg_obj)" >&6
|
||||
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"
|
||||
echo "$as_me:$LINENO: checking for dag_attach_stream in -ldag" >&5
|
||||
echo $ECHO_N "checking for dag_attach_stream in -ldag... $ECHO_C" >&6
|
||||
if test "${ac_cv_lib_dag_dag_attach_stream+set}" = set; then
|
||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||
else
|
||||
ac_check_lib_save_LIBS=$LIBS
|
||||
LIBS="-ldag $LIBS"
|
||||
cat >conftest.$ac_ext <<_ACEOF
|
||||
#line $LINENO "configure"
|
||||
/* confdefs.h. */
|
||||
_ACEOF
|
||||
cat confdefs.h >>conftest.$ac_ext
|
||||
cat >>conftest.$ac_ext <<_ACEOF
|
||||
/* end confdefs.h. */
|
||||
|
||||
/* Override any gcc2 internal prototype to avoid an error. */
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
/* We use char because int might match the return type of a gcc2
|
||||
builtin and then its argument prototype would still apply. */
|
||||
char dag_attach_stream ();
|
||||
int
|
||||
main ()
|
||||
{
|
||||
dag_attach_stream ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
rm -f conftest.$ac_objext conftest$ac_exeext
|
||||
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
|
||||
(eval $ac_link) 2>&5
|
||||
ac_status=$?
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } &&
|
||||
{ ac_try='test -s conftest$ac_exeext'
|
||||
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); }; }; then
|
||||
ac_cv_lib_dag_dag_attach_stream=yes
|
||||
else
|
||||
echo "$as_me: failed program was:" >&5
|
||||
sed 's/^/| /' conftest.$ac_ext >&5
|
||||
|
||||
ac_cv_lib_dag_dag_attach_stream=no
|
||||
fi
|
||||
rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
|
||||
LIBS=$ac_check_lib_save_LIBS
|
||||
fi
|
||||
echo "$as_me:$LINENO: result: $ac_cv_lib_dag_dag_attach_stream" >&5
|
||||
echo "${ECHO_T}$ac_cv_lib_dag_dag_attach_stream" >&6
|
||||
if test $ac_cv_lib_dag_dag_attach_stream = yes; then
|
||||
dag_version="2.5.x"
|
||||
else
|
||||
dag_version="2.4.x"
|
||||
fi
|
||||
|
||||
LDFLAGS=$saved_ldflags
|
||||
|
||||
if test "$dag_version" = 2.5.x; then
|
||||
|
||||
cat >>confdefs.h <<\_ACEOF
|
||||
#define HAVE_DAG_STREAMS_API 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
|
||||
# See if we can find a specific version string.
|
||||
echo "$as_me:$LINENO: checking the DAG API version" >&5
|
||||
echo $ECHO_N "checking the DAG API version... $ECHO_C" >&6
|
||||
if test -r "$dag_root/VERSION"; then
|
||||
dag_version="`cat $dag_root/VERSION`"
|
||||
fi
|
||||
echo "$as_me:$LINENO: result: $dag_version" >&5
|
||||
echo "${ECHO_T}$dag_version" >&6
|
||||
|
||||
cat >>confdefs.h <<\_ACEOF
|
||||
#define HAVE_DAG_API 1
|
||||
_ACEOF
|
||||
|
||||
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.
|
||||
{ { echo "$as_me:$LINENO: error: DAG API requested, but not found at $dag_root: use --without-dag" >&5
|
||||
echo "$as_me: error: DAG API requested, but not found at $dag_root: use --without-dag" >&2;}
|
||||
{ (exit 1); exit 1; }; }
|
||||
fi
|
||||
|
||||
if test "$V_PCAP" = dag; then
|
||||
# User requested "dag" capture type but the DAG API wasn't
|
||||
# found.
|
||||
{ { echo "$as_me:$LINENO: 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.)" >&5
|
||||
echo "$as_me: 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.)" >&2;}
|
||||
{ (exit 1); exit 1; }; }
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "$V_PCAP" = dag -a "$ac_cv_lbl_dag_api" = no; then
|
||||
{ { echo "$as_me:$LINENO: error: Specifying the capture type as 'dag' requires the DAG API to be present; use --with-dag=DIR" >&5
|
||||
echo "$as_me: error: Specifying the capture type as 'dag' requires the DAG API to be present; use --with-dag=DIR" >&2;}
|
||||
|
||||
# Check whether --with-septel or --without-septel was given.
|
||||
if test "${with_septel+set}" = set; then
|
||||
withval="$with_septel"
|
||||
|
||||
if test "$withval" = no
|
||||
then
|
||||
want_septel=no
|
||||
elif test "$withval" = yes
|
||||
then
|
||||
want_septel=yes
|
||||
septel_root=
|
||||
else
|
||||
want_septel=yes
|
||||
septel_root=$withval
|
||||
fi
|
||||
|
||||
else
|
||||
|
||||
#
|
||||
# Use Septel API if present, otherwise don't
|
||||
#
|
||||
want_septel=ifpresent
|
||||
septel_root=./../septel
|
||||
|
||||
fi;
|
||||
ac_cv_lbl_septel_api=no
|
||||
case "$V_PCAP" in
|
||||
linux|septel)
|
||||
#
|
||||
# We support the Septel API if we're on Linux, or if we're building
|
||||
# a Septel-only libpcap.
|
||||
#
|
||||
;;
|
||||
*)
|
||||
#
|
||||
# If the user explicitly requested Septel, tell them it's not
|
||||
# supported.
|
||||
#
|
||||
# If they expressed no preference, don't include it.
|
||||
#
|
||||
if test $want_septel = yes; then
|
||||
{ { echo "$as_me:$LINENO: error: Septel support only available with 'linux' and 'septel' packet capture types" >&5
|
||||
echo "$as_me: error: Septel support only available with 'linux' and 'septel' packet capture types" >&2;}
|
||||
{ (exit 1); exit 1; }; }
|
||||
elif test $want_septel = yes; then
|
||||
want_septel=no
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if test "$with_septel" != no; then
|
||||
echo "$as_me:$LINENO: checking whether we have Septel API" >&5
|
||||
echo $ECHO_N "checking whether we have Septel API... $ECHO_C" >&6
|
||||
|
||||
if test -z "$septel_root"; then
|
||||
septel_root=$srcdir/../septel
|
||||
|
||||
fi
|
||||
|
||||
septel_tools_dir="$septel_root"
|
||||
septel_include_dir="$septel_root/INC"
|
||||
DEF="-DHAVE_SEPTEL_API"
|
||||
|
||||
ac_cv_lbl_septel_api=no
|
||||
if test -r "$septel_include_dir/msg.h"; then
|
||||
V_INCLS="$V_INCLS -I$septel_include_dir"
|
||||
V_DEFS="$V_DEFS $DEF"
|
||||
V_LIBS="$V_LIBS $septel_tools_dir/asciibin.o $septel_tools_dir/bit2byte.o $septel_tools_dir/confirm.o $septel_tools_dir/fmtmsg.o $septel_tools_dir/gct_unix.o $septel_tools_dir/hqueue.o $septel_tools_dir/ident.o $septel_tools_dir/mem.o $septel_tools_dir/pack.o $septel_tools_dir/parse.o $septel_tools_dir/pool.o $septel_tools_dir/sdlsig.o $septel_tools_dir/strtonum.o $septel_tools_dir/timer.o $septel_tools_dir/trace.o "
|
||||
|
||||
if test "$V_PCAP" != septel ; then
|
||||
SSRC="pcap-septel.c"
|
||||
|
||||
fi
|
||||
ac_cv_lbl_septel_api=yes
|
||||
fi
|
||||
|
||||
echo "$as_me:$LINENO: result: $ac_cv_lbl_septel_api" >&5
|
||||
echo "${ECHO_T}$ac_cv_lbl_septel_api" >&6
|
||||
if test $ac_cv_lbl_septel_api = no; then
|
||||
if test "$want_septel" = yes; then
|
||||
{ { echo "$as_me:$LINENO: error: Septel API not found under directory $septel_root; use --without-septel" >&5
|
||||
echo "$as_me: error: Septel API not found under directory $septel_root; use --without-septel" >&2;}
|
||||
{ (exit 1); exit 1; }; }
|
||||
fi
|
||||
else
|
||||
|
||||
cat >>confdefs.h <<\_ACEOF
|
||||
#define HAVE_SEPTEL_API 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "$V_PCAP" = septel -a "$ac_cv_lbl_septel_api" = no; then
|
||||
{ { echo "$as_me:$LINENO: error: Specifying the capture type as 'septel' requires the Septel API to be present; use --with-septel=DIR" >&5
|
||||
echo "$as_me: error: Specifying the capture type as 'septel' requires the Septel API to be present; use --with-septel=DIR" >&2;}
|
||||
{ (exit 1); exit 1; }; }
|
||||
fi
|
||||
|
||||
DYEXT="so"
|
||||
case "$host_os" in
|
||||
|
||||
aix*)
|
||||
@@ -4792,7 +5100,7 @@ hpux10.1*)
|
||||
hpux*)
|
||||
|
||||
cat >>confdefs.h <<\_ACEOF
|
||||
#define HAVE_HPUX10_20 1
|
||||
#define HAVE_HPUX10_20_OR_LATER 1
|
||||
_ACEOF
|
||||
|
||||
;;
|
||||
@@ -4868,6 +5176,11 @@ cat >>confdefs.h <<\_ACEOF
|
||||
_ACEOF
|
||||
|
||||
;;
|
||||
|
||||
darwin*)
|
||||
DYEXT="dylib"
|
||||
V_CCOPT="$V_CCOPT -fno-common"
|
||||
;;
|
||||
esac
|
||||
|
||||
if test -n "$ac_tool_prefix"; then
|
||||
@@ -5282,6 +5595,16 @@ _ACEOF
|
||||
|
||||
fi
|
||||
|
||||
#
|
||||
# Makefile.in includes rules to generate version.h, so we assume
|
||||
# that it will be generated if autoconf is used.
|
||||
#
|
||||
|
||||
cat >>confdefs.h <<\_ACEOF
|
||||
#define HAVE_VERSION_H 1
|
||||
_ACEOF
|
||||
|
||||
|
||||
rm -f net
|
||||
ln -s ${srcdir}/bpf/net net
|
||||
|
||||
@@ -5294,6 +5617,7 @@ ln -s ${srcdir}/bpf/net net
|
||||
|
||||
|
||||
|
||||
|
||||
# Find a good install program. We prefer a C program (faster),
|
||||
# so one script is as good as another. But avoid the broken or
|
||||
# incompatible versions:
|
||||
@@ -6022,6 +6346,7 @@ s,@V_PCAP@,$V_PCAP,;t t
|
||||
s,@V_FINDALLDEVS@,$V_FINDALLDEVS,;t t
|
||||
s,@V_RANLIB@,$V_RANLIB,;t t
|
||||
s,@SSRC@,$SSRC,;t t
|
||||
s,@DYEXT@,$DYEXT,;t t
|
||||
s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t
|
||||
s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t
|
||||
s,@INSTALL_DATA@,$INSTALL_DATA,;t t
|
||||
|
||||
@@ -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,103 @@ 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_DECL(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>
|
||||
#include <arpa/inet.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_DECL(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
|
||||
#
|
||||
# Is ether_hostton() declared?
|
||||
#
|
||||
if test "$ac_cv_have_decl_ether_hostton" != yes; then
|
||||
#
|
||||
# No, we'll have to declare it ourselves.
|
||||
# Do we have "struct ether_addr"?
|
||||
#
|
||||
AC_CHECK_TYPES(struct ether_addr,,,
|
||||
[
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
struct mbuf;
|
||||
struct rtentry;
|
||||
#include <net/if.h>
|
||||
#include <netinet/if_ether.h>
|
||||
])
|
||||
AC_DEFINE(HAVE_DECL_ETHER_HOSTTON, 0,
|
||||
[Define to 1 if you have the declaration of `ether_hostton', and to 0 if you
|
||||
don't.])
|
||||
else
|
||||
AC_DEFINE(HAVE_DECL_ETHER_HOSTTON, 1,
|
||||
[Define to 1 if you have the declaration of `ether_hostton', and to 0 if you
|
||||
don't.])
|
||||
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,17 +219,45 @@ 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
|
||||
if test "$V_PCAP" = null
|
||||
then
|
||||
#
|
||||
# We can't capture, so we can't open any capture
|
||||
# devices, so we won't return any interfaces.
|
||||
#
|
||||
V_FINDALLDEVS=null
|
||||
else
|
||||
AC_CHECK_FUNC(getifaddrs,[
|
||||
#
|
||||
# We have "getifaddrs()", so we use that to get the list
|
||||
# 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
|
||||
],[
|
||||
#
|
||||
# Well, we don't have "getifaddrs()", so we have to use some
|
||||
# other mechanism; determine what that mechanism is.
|
||||
# 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.
|
||||
@@ -124,8 +266,10 @@ AC_CHECK_FUNC(getifaddrs,[
|
||||
|
||||
dlpi)
|
||||
#
|
||||
# This might be Solaris 8 or later, with SIOCGLIFCONF,
|
||||
# or it might be some other OS, with just SIOCGIFCONF.
|
||||
# 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,
|
||||
@@ -146,14 +290,6 @@ AC_CHECK_FUNC(getifaddrs,[
|
||||
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.
|
||||
@@ -164,6 +300,7 @@ AC_CHECK_FUNC(getifaddrs,[
|
||||
V_FINDALLDEVS=gifc
|
||||
;;
|
||||
esac])
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING(if --enable-ipv6 option is specified)
|
||||
AC_ARG_ENABLE(ipv6, [ --enable-ipv6 build IPv6-capable version])
|
||||
@@ -231,6 +368,10 @@ dag)
|
||||
V_DEFS="$V_DEFS -DDAG_ONLY"
|
||||
;;
|
||||
|
||||
septel)
|
||||
V_DEFS="$V_DEFS -DSEPTEL_ONLY"
|
||||
;;
|
||||
|
||||
null)
|
||||
AC_MSG_WARN(cannot determine packet capture interface)
|
||||
AC_MSG_WARN((see the INSTALL doc for more info))
|
||||
@@ -249,16 +390,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,14 +411,27 @@ 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)
|
||||
#
|
||||
# We support the DAG API on Linux or BSD, or if we're building a
|
||||
# DAG-only libpcap.
|
||||
# We support the DAG API if we're on Linux or BSD, or if we're
|
||||
# building a DAG-only libpcap.
|
||||
#
|
||||
;;
|
||||
*)
|
||||
@@ -285,62 +442,242 @@ 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_cv_lbl_dag_api=no
|
||||
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
|
||||
dag_version=
|
||||
if test $ac_cv_lbl_dag_api = yes -a -r "$dag_root/VERSION"; then
|
||||
dag_version=" (`cat $dag_root/VERSION`)"
|
||||
|
||||
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
|
||||
else
|
||||
AC_MSG_RESULT([yes ($dagapi_obj)])
|
||||
fi
|
||||
AC_MSG_RESULT($ac_cv_lbl_dag_api$dag_version)
|
||||
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 $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
|
||||
|
||||
if test "$dag_version" = 2.5.x; then
|
||||
AC_DEFINE(HAVE_DAG_STREAMS_API, 1, [define if you have streams capable DAG API])
|
||||
fi
|
||||
|
||||
# See if we can find a specific version string.
|
||||
AC_MSG_CHECKING([the DAG API version])
|
||||
if test -r "$dag_root/VERSION"; then
|
||||
dag_version="`cat $dag_root/VERSION`"
|
||||
fi
|
||||
AC_MSG_RESULT([$dag_version])
|
||||
AC_DEFINE(HAVE_DAG_API, 1, [define if you have the DAG API])
|
||||
fi
|
||||
|
||||
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])
|
||||
# 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
|
||||
|
||||
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)
|
||||
AC_ARG_WITH(septel, [ --with-septel[[=DIR]] include Septel support (located in directory DIR, if supplied). [default=yes, on Linux, if present]],
|
||||
[
|
||||
if test "$withval" = no
|
||||
then
|
||||
want_septel=no
|
||||
elif test "$withval" = yes
|
||||
then
|
||||
want_septel=yes
|
||||
septel_root=
|
||||
else
|
||||
want_septel=yes
|
||||
septel_root=$withval
|
||||
fi
|
||||
],[
|
||||
#
|
||||
# Use Septel API if present, otherwise don't
|
||||
#
|
||||
want_septel=ifpresent
|
||||
septel_root=./../septel
|
||||
])
|
||||
ac_cv_lbl_septel_api=no
|
||||
case "$V_PCAP" in
|
||||
linux|septel)
|
||||
#
|
||||
# We support the Septel API if we're on Linux, or if we're building
|
||||
# a Septel-only libpcap.
|
||||
#
|
||||
;;
|
||||
*)
|
||||
#
|
||||
# If the user explicitly requested Septel, tell them it's not
|
||||
# supported.
|
||||
#
|
||||
# If they expressed no preference, don't include it.
|
||||
#
|
||||
if test $want_septel = yes; then
|
||||
AC_MSG_ERROR(Septel support only available with 'linux' and 'septel' packet capture types)
|
||||
elif test $want_septel = yes; then
|
||||
want_septel=no
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if test "$with_septel" != no; then
|
||||
AC_MSG_CHECKING(whether we have Septel API)
|
||||
|
||||
if test -z "$septel_root"; then
|
||||
septel_root=$srcdir/../septel
|
||||
|
||||
fi
|
||||
|
||||
septel_tools_dir="$septel_root"
|
||||
septel_include_dir="$septel_root/INC"
|
||||
DEF="-DHAVE_SEPTEL_API"
|
||||
|
||||
ac_cv_lbl_septel_api=no
|
||||
if test -r "$septel_include_dir/msg.h"; then
|
||||
V_INCLS="$V_INCLS -I$septel_include_dir"
|
||||
V_DEFS="$V_DEFS $DEF"
|
||||
V_LIBS="$V_LIBS $septel_tools_dir/asciibin.o $septel_tools_dir/bit2byte.o $septel_tools_dir/confirm.o $septel_tools_dir/fmtmsg.o $septel_tools_dir/gct_unix.o $septel_tools_dir/hqueue.o $septel_tools_dir/ident.o $septel_tools_dir/mem.o $septel_tools_dir/pack.o $septel_tools_dir/parse.o $septel_tools_dir/pool.o $septel_tools_dir/sdlsig.o $septel_tools_dir/strtonum.o $septel_tools_dir/timer.o $septel_tools_dir/trace.o "
|
||||
|
||||
if test "$V_PCAP" != septel ; then
|
||||
SSRC="pcap-septel.c"
|
||||
|
||||
fi
|
||||
ac_cv_lbl_septel_api=yes
|
||||
fi
|
||||
|
||||
AC_MSG_RESULT($ac_cv_lbl_septel_api)
|
||||
if test $ac_cv_lbl_septel_api = no; then
|
||||
if test "$want_septel" = yes; then
|
||||
AC_MSG_ERROR(Septel API not found under directory $septel_root; use --without-septel)
|
||||
fi
|
||||
else
|
||||
AC_DEFINE(HAVE_SEPTEL_API, 1, [define if you have a Septel API])
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "$V_PCAP" = septel -a "$ac_cv_lbl_septel_api" = no; then
|
||||
AC_MSG_ERROR(Specifying the capture type as 'septel' requires the Septel API to be present; use --with-septel=DIR)
|
||||
fi
|
||||
|
||||
DYEXT="so"
|
||||
case "$host_os" in
|
||||
|
||||
aix*)
|
||||
@@ -359,8 +696,13 @@ hpux10.1*)
|
||||
;;
|
||||
|
||||
hpux*)
|
||||
dnl HPUX 10.20 and above is similar to HPUX 9...
|
||||
AC_DEFINE(HAVE_HPUX10_20,1,[on HP-UX 10.20])
|
||||
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_OR_LATER,1,[on HP-UX 10.20 or later])
|
||||
;;
|
||||
|
||||
sinix*)
|
||||
@@ -380,6 +722,11 @@ sinix*)
|
||||
solaris*)
|
||||
AC_DEFINE(HAVE_SOLARIS,1,[On solaris])
|
||||
;;
|
||||
|
||||
darwin*)
|
||||
DYEXT="dylib"
|
||||
V_CCOPT="$V_CCOPT -fno-common"
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_PROG_RANLIB
|
||||
@@ -394,6 +741,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
|
||||
|
||||
@@ -405,6 +758,7 @@ AC_SUBST(V_PCAP)
|
||||
AC_SUBST(V_FINDALLDEVS)
|
||||
AC_SUBST(V_RANLIB)
|
||||
AC_SUBST(SSRC)
|
||||
AC_SUBST(DYEXT)
|
||||
|
||||
AC_PROG_INSTALL
|
||||
|
||||
|
||||
997
libpcap-possiblymodified/doc/pcap.html
Normal file
997
libpcap-possiblymodified/doc/pcap.html
Normal file
@@ -0,0 +1,997 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html lang="en"><head><title>PCAP New Generation Dump File Format</title>
|
||||
<meta name="description" content="PCAP New Generation Dump File Format">
|
||||
<meta name="keywords" content="Internet-Draft, Libpcap, dump file format">
|
||||
<meta name="generator" content="xml2rfc v1.22 (http://xml.resource.org/)">
|
||||
<style type='text/css'>
|
||||
<!--
|
||||
body {
|
||||
font-family: verdana, charcoal, helvetica, arial, sans-serif;
|
||||
font-size: small ; color: #000000 ; background-color: #ffffff ; }
|
||||
.title { color: #990000; font-size: x-large ;
|
||||
font-weight: bold; text-align: right;
|
||||
font-family: helvetica, monaco, "MS Sans Serif", arial, sans-serif;
|
||||
background-color: transparent; }
|
||||
.filename { color: #666666; font-size: 18px; line-height: 28px;
|
||||
font-weight: bold; text-align: right;
|
||||
font-family: helvetica, arial, sans-serif;
|
||||
background-color: transparent; }
|
||||
td.rfcbug { background-color: #000000 ; width: 30px ; height: 30px ;
|
||||
text-align: justify; vertical-align: middle ; padding-top: 2px ; }
|
||||
td.rfcbug span.RFC { color: #666666; font-weight: bold; text-decoration: none;
|
||||
background-color: #000000 ;
|
||||
font-family: monaco, charcoal, geneva, "MS Sans Serif", helvetica, verdana, sans-serif;
|
||||
font-size: x-small ; }
|
||||
td.rfcbug span.hotText { color: #ffffff; font-weight: normal; text-decoration: none;
|
||||
text-align: center ;
|
||||
font-family: charcoal, monaco, geneva, "MS Sans Serif", helvetica, verdana, sans-serif;
|
||||
font-size: x-small ; background-color: #000000; }
|
||||
|
||||
A { font-weight: bold; }
|
||||
A:link { color: #990000; background-color: transparent ; }
|
||||
A:visited { color: #333333; background-color: transparent ; }
|
||||
A:active { color: #333333; background-color: transparent ; }
|
||||
|
||||
p { margin-left: 2em; margin-right: 2em; }
|
||||
p.copyright { font-size: x-small ; }
|
||||
p.toc { font-size: small ; font-weight: bold ; margin-left: 3em ;}
|
||||
|
||||
span.emph { font-style: italic; }
|
||||
span.strong { font-weight: bold; }
|
||||
span.verb { font-family: "Courier New", Courier, monospace ; }
|
||||
|
||||
ol.text { margin-left: 2em; margin-right: 2em; }
|
||||
ul.text { margin-left: 2em; margin-right: 2em; }
|
||||
li { margin-left: 3em; }
|
||||
|
||||
pre { margin-left: 3em; color: #333333; background-color: transparent;
|
||||
font-family: "Courier New", Courier, monospace ; font-size: small ;
|
||||
}
|
||||
|
||||
h3 { color: #333333; font-size: medium ;
|
||||
font-family: helvetica, arial, sans-serif ;
|
||||
background-color: transparent; }
|
||||
h4 { font-size: small; font-family: helvetica, arial, sans-serif ; }
|
||||
|
||||
table.bug { width: 30px ; height: 15px ; }
|
||||
td.bug { color: #ffffff ; background-color: #990000 ;
|
||||
text-align: center ; width: 30px ; height: 15px ;
|
||||
}
|
||||
td.bug A.link2 { color: #ffffff ; font-weight: bold;
|
||||
text-decoration: none;
|
||||
font-family: monaco, charcoal, geneva, "MS Sans Serif", helvetica, sans-serif;
|
||||
font-size: x-small ; background-color: transparent }
|
||||
|
||||
td.header { color: #ffffff; font-size: x-small ;
|
||||
font-family: arial, helvetica, sans-serif; vertical-align: top;
|
||||
background-color: #666666 ; width: 33% ; }
|
||||
td.author { font-weight: bold; margin-left: 4em; font-size: x-small ; }
|
||||
td.author-text { font-size: x-small; }
|
||||
table.data { vertical-align: top ; border-collapse: collapse ;
|
||||
border-style: solid solid solid solid ;
|
||||
border-color: black black black black ;
|
||||
font-size: small ; text-align: center ; }
|
||||
table.data th { font-weight: bold ;
|
||||
border-style: solid solid solid solid ;
|
||||
border-color: black black black black ; }
|
||||
table.data td {
|
||||
border-style: solid solid solid solid ;
|
||||
border-color: #333333 #333333 #333333 #333333 ; }
|
||||
|
||||
hr { height: 1px }
|
||||
-->
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<table summary="layout" cellpadding="0" cellspacing="2" class="bug" align="right"><tr><td class="bug"><a href="#toc" class="link2"> TOC </a></td></tr></table>
|
||||
<table summary="layout" width="66%" border="0" cellpadding="0" cellspacing="0"><tr><td><table summary="layout" width="100%" border="0" cellpadding="2" cellspacing="1">
|
||||
<tr><td class="header">Network Working Group</td><td class="header">L. Degioanni</td></tr>
|
||||
<tr><td class="header">Internet-Draft</td><td class="header">F. Risso</td></tr>
|
||||
<tr><td class="header">Expires: August 30, 2004</td><td class="header">Politecnico di Torino</td></tr>
|
||||
<tr><td class="header"> </td><td class="header">March 2004</td></tr>
|
||||
</table></td></tr></table>
|
||||
<div align="right"><span class="title"><br />PCAP New Generation Dump File Format</span></div>
|
||||
<div align="right"><span class="title"><br />pcap</span></div>
|
||||
|
||||
<h3>Status of this Memo</h3>
|
||||
<p>
|
||||
This document is an Internet-Draft and is
|
||||
in full conformance with all provisions of Section 10 of RFC2026.</p>
|
||||
<p>
|
||||
Internet-Drafts are working documents of the Internet Engineering
|
||||
Task Force (IETF), its areas, and its working groups.
|
||||
Note that other groups may also distribute working documents as
|
||||
Internet-Drafts.</p>
|
||||
<p>
|
||||
Internet-Drafts are draft documents valid for a maximum of six months
|
||||
and may be updated, replaced, or obsoleted by other documents at any time.
|
||||
It is inappropriate to use Internet-Drafts as reference material or to cite
|
||||
them other than as "work in progress."</p>
|
||||
<p>
|
||||
The list of current Internet-Drafts can be accessed at
|
||||
<a href='http://www.ietf.org/ietf/1id-abstracts.txt'>http://www.ietf.org/ietf/1id-abstracts.txt</a>.</p>
|
||||
<p>
|
||||
The list of Internet-Draft Shadow Directories can be accessed at
|
||||
<a href='http://www.ietf.org/shadow.html'>http://www.ietf.org/shadow.html</a>.</p>
|
||||
<p>
|
||||
This Internet-Draft will expire on August 30, 2004.</p>
|
||||
|
||||
<h3>Copyright Notice</h3>
|
||||
<p>
|
||||
Copyright (C) The Internet Society (2004). All Rights Reserved.</p>
|
||||
|
||||
<h3>Abstract</h3>
|
||||
|
||||
<p>This document describes a format to dump captured packets on a file. This format is extensible and it is currently proposed for implementation in the libpcap/WinPcap packet capture library.
|
||||
</p><a name="toc"></a><br /><hr />
|
||||
<h3>Table of Contents</h3>
|
||||
<p class="toc">
|
||||
<a href="#anchor1">1.</a>
|
||||
Objectives<br />
|
||||
<a href="#anchor2">2.</a>
|
||||
General File Structure<br />
|
||||
<a href="#sectionblock">2.1</a>
|
||||
General Block Structure<br />
|
||||
<a href="#anchor3">2.2</a>
|
||||
Block Types<br />
|
||||
<a href="#anchor4">2.3</a>
|
||||
Block Hierarchy and Precedence<br />
|
||||
<a href="#anchor5">2.4</a>
|
||||
Data format<br />
|
||||
<a href="#anchor6">3.</a>
|
||||
Block Definition<br />
|
||||
<a href="#sectionshb">3.1</a>
|
||||
Section Header Block (mandatory)<br />
|
||||
<a href="#sectionidb">3.2</a>
|
||||
Interface Description Block (mandatory)<br />
|
||||
<a href="#sectionpb">3.3</a>
|
||||
Packet Block (optional)<br />
|
||||
<a href="#anchor7">3.4</a>
|
||||
Simple Packet Block (optional)<br />
|
||||
<a href="#anchor8">3.5</a>
|
||||
Name Resolution Block (optional)<br />
|
||||
<a href="#anchor9">3.6</a>
|
||||
Interface Statistics Block (optional)<br />
|
||||
<a href="#sectionopt">4.</a>
|
||||
Options<br />
|
||||
<a href="#anchor10">5.</a>
|
||||
Experimental Blocks (deserved to a further investigation)<br />
|
||||
<a href="#anchor11">5.1</a>
|
||||
Other Packet Blocks (experimental)<br />
|
||||
<a href="#anchor12">5.2</a>
|
||||
Compression Block (experimental)<br />
|
||||
<a href="#anchor13">5.3</a>
|
||||
Encryption Block (experimental)<br />
|
||||
<a href="#anchor14">5.4</a>
|
||||
Fixed Length Block (experimental)<br />
|
||||
<a href="#anchor15">5.5</a>
|
||||
Directory Block (experimental)<br />
|
||||
<a href="#anchor16">5.6</a>
|
||||
Traffic Statistics and Monitoring Blocks (experimental)<br />
|
||||
<a href="#anchor17">5.7</a>
|
||||
Event/Security Block (experimental)<br />
|
||||
<a href="#anchor18">6.</a>
|
||||
Conclusions<br />
|
||||
<a href="#anchor19">7.</a>
|
||||
Most important open issues<br />
|
||||
<a href="#rfc.copyright">§</a>
|
||||
Intellectual Property and Copyright Statements<br />
|
||||
</p>
|
||||
<br clear="all" />
|
||||
|
||||
<a name="anchor1"></a><br /><hr />
|
||||
<table summary="layout" cellpadding="0" cellspacing="2" class="bug" align="right"><tr><td class="bug"><a href="#toc" class="link2"> TOC </a></td></tr></table>
|
||||
<a name="rfc.section.1"></a><h3>1. Objectives</h3>
|
||||
|
||||
<p>The problem of exchanging packet traces becomes more and more critical every day; unfortunately, no standard solutions exist for this task right now. One of the most accepted packet interchange formats is the one defined by libpcap, which is rather old and does not fit for some of the nowadays applications especially in terms of extensibility.
|
||||
</p>
|
||||
<p>This document proposes a new format for dumping packet traces. The following goals are being pursued:
|
||||
</p>
|
||||
<ul class="text">
|
||||
<li>Extensibility: aside of some common functionalities, third parties should be able to enrich the information embedded in the file with proprietary extensions, which will be ignored by tools that are not able to understand them.
|
||||
</li>
|
||||
<li>Portability: a capture trace must contain all the information needed to read data independently from network, hardware and operating system of the machine that made the capture.
|
||||
</li>
|
||||
<li>Merge/Append data: it should be possible to add data at the end of a given file, and the resulting file must still be readable.
|
||||
</li>
|
||||
</ul>
|
||||
<a name="anchor2"></a><br /><hr />
|
||||
<table summary="layout" cellpadding="0" cellspacing="2" class="bug" align="right"><tr><td class="bug"><a href="#toc" class="link2"> TOC </a></td></tr></table>
|
||||
<a name="rfc.section.2"></a><h3>2. General File Structure</h3>
|
||||
|
||||
<a name="rfc.section.2.1"></a><h4><a name="sectionblock">2.1</a> General Block Structure</h4>
|
||||
|
||||
<p>A capture file is organized in blocks, that are appended one to another to form the file. All the blocks share a common format, which is shown in <a href="#formatblock">Figure 1</a>.
|
||||
</p><br /><hr />
|
||||
<a name="formatblock"></a>
|
||||
<pre>
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Block Type |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Block Total Length |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
/ Block Body /
|
||||
/ /* variable length, aligned to 32 bits */ /
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Block Total Length |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
</pre>
|
||||
<table border="0" cellpadding="0" cellspacing="2" align="center"><tr><td align="center"><font face="monaco, MS Sans Serif" size="1"><b> Basic block structure. </b></font><br /></td></tr></table><hr size="1" shade="0">
|
||||
|
||||
<p>The fields have the following meaning:
|
||||
</p>
|
||||
<ul class="text">
|
||||
<li>Block Type (32 bits): unique value that identifies the block. Values whose Most Significant Bit (MSB) is equal to 1 are reserved for local use. They allow to save private data to the file and to extend the file format.
|
||||
</li>
|
||||
<li>Block Total Length: total size of this block, in bytes. For instance, a block that does not have a body has a length of 12 bytes.
|
||||
</li>
|
||||
<li>Block Body: content of the block.
|
||||
</li>
|
||||
<li>Block Total Length: total size of this block, in bytes. This field is duplicated for permitting backward file navigation.
|
||||
</li>
|
||||
</ul>
|
||||
<p>This structure, shared among all blocks, makes easy to process a file and to skip unneeded or unknown blocks. Blocks can be nested one inside the others (NOTE: needed?). Some of the blocks are mandatory, i.e. a dump file is not valid if they are not present, other are optional.
|
||||
</p>
|
||||
<p>The structure of the blocks allows to define other blocks if needed. A parser that does non understand them can simply ignore their content.
|
||||
</p>
|
||||
<a name="rfc.section.2.2"></a><h4><a name="anchor3">2.2</a> Block Types</h4>
|
||||
|
||||
<p>The currently defined blocks are the following:
|
||||
</p>
|
||||
<ol class="text">
|
||||
<li>Section Header Block: it defines the most important characteristics of the capture file.
|
||||
</li>
|
||||
<li>Interface Description Block: it defines the most important characteristics of the interface(s) used for capturing traffic.
|
||||
</li>
|
||||
<li>Packet Block: it contains a single captured packet, or a portion of it.
|
||||
</li>
|
||||
<li>Simple Packet Block: it contains a single captured packet, or a portion of it, with only a minimal set of information about it.
|
||||
</li>
|
||||
<li>Name Resolution Block: it defines the mapping from numeric addresses present in the packet dump and the canonical name counterpart.
|
||||
</li>
|
||||
<li>Capture Statistics Block: it defines how to store some statistical data (e.g. packet dropped, etc) which can be useful to undestand the conditions in which the capture has been made.
|
||||
</li>
|
||||
<li>Compression Marker Block: TODO
|
||||
</li>
|
||||
<li>Encryption Marker Block: TODO
|
||||
</li>
|
||||
<li>Fixed Length Marker Block: TODO
|
||||
</li>
|
||||
</ol>
|
||||
<p>The following blocks instead are considered interesting but the authors believe that they deserve more in-depth discussion before being defined:
|
||||
</p>
|
||||
<ol class="text">
|
||||
<li>Further Packet Blocks
|
||||
</li>
|
||||
<li>Directory Block
|
||||
</li>
|
||||
<li>Traffic Statistics and Monitoring Blocks
|
||||
</li>
|
||||
<li>Alert and Security Blocks
|
||||
</li>
|
||||
</ol>
|
||||
<p>TODO Currently standardized Block Type codes are specified in Appendix 1.
|
||||
</p>
|
||||
<a name="rfc.section.2.3"></a><h4><a name="anchor4">2.3</a> Block Hierarchy and Precedence</h4>
|
||||
|
||||
<p>The file must begin with a Section Header Block. However, more than one Section Header Block can be present on the dump, each one covering the data following it till the next one (or the end of file). A Section includes the data delimited by two Section Header Blocks (or by a Section Header Block and the end of the file), including the first Section Header Block.
|
||||
</p>
|
||||
<p>In case an application cannot read a Section because of different version number, it must skip everything until the next Section Header Block. Note that, in order to properly skip the blocks until the next section, all blocks must have the fields Type and Length at the beginning. This is a mandatory requirement that must be maintained in future versions of the block format.
|
||||
</p>
|
||||
<p><a href="#fssample-SHB">Figure 2</a> shows two valid files: the first has a typical configuration, with a single Section Header that covers the whole file. The second one contains three headers, and is normally the result of file concatenation. An application that understands only version 1.0 of the file format skips the intermediate section and restart processing the packets after the third Section Header.
|
||||
</p><br /><hr />
|
||||
<a name="fssample-SHB"></a>
|
||||
<pre>
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| SHB v1.0 | Data |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
Typical configuration with a single Section Header Block
|
||||
|
||||
|
||||
|-- 1st Section --|-- 2nd Section --|-- 3rd Section --|
|
||||
| |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| SHB v1.0 | Data | SHB V1.1 | Data | SHB V1.0 | Data |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
Configuration with three different Section Header Blocks
|
||||
</pre>
|
||||
<table border="0" cellpadding="0" cellspacing="2" align="center"><tr><td align="center"><font face="monaco, MS Sans Serif" size="1"><b> File structure example: the Section Header Block. </b></font><br /></td></tr></table><hr size="1" shade="0">
|
||||
|
||||
<p>NOTE: TO BE COMPLETED with some examples of other blocks
|
||||
</p>
|
||||
<a name="rfc.section.2.4"></a><h4><a name="anchor5">2.4</a> Data format</h4>
|
||||
|
||||
<p>Data contained in each section will always be saved according to the characteristics (little endian / big endian) of the dumping machine. This refers to all fields that are saved as numbers and that span over two or more bytes.
|
||||
</p>
|
||||
<p>The approach of having each section saved in the native format of the generating host is more efficient because it avoids translation of data when reading / writing on the host itself, which is the most common case when generating/processing capture dumps.
|
||||
</p>
|
||||
<p>TODO Probably we have to specify something more here. Is what we're saying enough to avoid any kind of ambiguity?.
|
||||
</p>
|
||||
<a name="anchor6"></a><br /><hr />
|
||||
<table summary="layout" cellpadding="0" cellspacing="2" class="bug" align="right"><tr><td class="bug"><a href="#toc" class="link2"> TOC </a></td></tr></table>
|
||||
<a name="rfc.section.3"></a><h3>3. Block Definition</h3>
|
||||
|
||||
<p>This section details the format of the body of the blocks currently defined.
|
||||
</p>
|
||||
<a name="rfc.section.3.1"></a><h4><a name="sectionshb">3.1</a> Section Header Block (mandatory)</h4>
|
||||
|
||||
<p>The Section Header Block is mandatory. It identifies the beginning of a section of the capture dump file. Its format is shown in <a href="#formatSHB">Figure 3</a>.
|
||||
</p><br /><hr />
|
||||
<a name="formatSHB"></a>
|
||||
<pre>
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Magic |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Major | Minor |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
/ /
|
||||
/ Options (variable) /
|
||||
/ /
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
</pre>
|
||||
<table border="0" cellpadding="0" cellspacing="2" align="center"><tr><td align="center"><font face="monaco, MS Sans Serif" size="1"><b> Section Header Block format. </b></font><br /></td></tr></table><hr size="1" shade="0">
|
||||
|
||||
<p>The meaning of the fields is:
|
||||
</p>
|
||||
<ul class="text">
|
||||
<li>Magic: magic number, whose value is the hexadecimal number 0x1A2B3C4D. This number can be used to distinguish section that have been saved on little-endian machines from the one saved on big-endian machines.
|
||||
</li>
|
||||
<li>Major: number of the current mayor version of the format. Current value is 1.
|
||||
</li>
|
||||
<li>Minor: number of the current minor version of the format. Current value is 0.
|
||||
</li>
|
||||
<li>Options: optionally, a list of options (formatted according to the rules defined in <a href="#sectionopt">Section 4</a>) can be present.
|
||||
</li>
|
||||
</ul>
|
||||
<p>Aside form the options defined in <a href="#sectionopt">Section 4</a>, the following options are valid within this block:
|
||||
</p><a name="InterfaceOptions1"></a>
|
||||
<table class="data" align="center" border="1" cellpadding="2" cellspacing="2">
|
||||
<tr>
|
||||
<th align="left" width="25%">Name</th>
|
||||
<th align="left" width="25%">Code</th>
|
||||
<th align="left" width="25%">Length</th>
|
||||
<th align="left" width="25%">Description</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">Hardware</td>
|
||||
<td align="left">2</td>
|
||||
<td align="left">variable</td>
|
||||
<td align="left">An ascii string containing the description of the hardware used to create this section.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">Operating System</td>
|
||||
<td align="left">3</td>
|
||||
<td align="left">variable</td>
|
||||
<td align="left">An ascii string containing the name of the operating system used to create this section.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">User Application</td>
|
||||
<td align="left">3</td>
|
||||
<td align="left">variable</td>
|
||||
<td align="left">An ascii string containing the name of the application used to create this section.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p>The Section Header Block does not contain data but it rather identifies a list of blocks (interfaces, packets) that are logically correlated. This block does not contain any reference to the size of the section it is currently delimiting, therefore the reader cannot skip a whole section at once. In case a section must be skipped, the user has to repeatedly skip all the blocks contained within it; this makes the parsing of the file slower but it permits to append several capture dumps at the same file.
|
||||
</p>
|
||||
<a name="rfc.section.3.2"></a><h4><a name="sectionidb">3.2</a> Interface Description Block (mandatory)</h4>
|
||||
|
||||
<p>The Interface Description Block is mandatory. This block is needed to specify the characteristics of the network interface on which the capture has been made. In order to properly associate the captured data to the corresponding interface, the Interface Description Block must be defined before any other block that uses it; therefore, this block is usually placed immediately after the Section Header Block.
|
||||
</p>
|
||||
<p>An Interface Description Block is valid only inside the section which it belongs to. The structure of a Interface Description Block is shown in <a href="#formatidb">Figure 4</a>.
|
||||
</p><br /><hr />
|
||||
<a name="formatidb"></a>
|
||||
<pre>
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Interface ID | LinkType |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| SnapLen |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
/ /
|
||||
/ Options (variable) /
|
||||
/ /
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
</pre>
|
||||
<table border="0" cellpadding="0" cellspacing="2" align="center"><tr><td align="center"><font face="monaco, MS Sans Serif" size="1"><b> Interface Description Block format. </b></font><br /></td></tr></table><hr size="1" shade="0">
|
||||
|
||||
<p>The meaning of the fields is:
|
||||
</p>
|
||||
<ul class="text">
|
||||
<li>Interface ID: a progressive number that identifies uniquely any interface inside current section. Two Interface Description Blocks can have the same Interface ID only if they are in different sections of the file. The Interface ID is referenced by the packet blocks.
|
||||
</li>
|
||||
<li>LinkType: a value that defines the link layer type of this interface.
|
||||
</li>
|
||||
<li>SnapLen: maximum number of bytes dumped from each packet. The portion of each packet that exceeds this value will not be stored in the file.
|
||||
</li>
|
||||
<li>Options: optionally, a list of options (formatted according to the rules defined in <a href="#sectionopt">Section 4</a>) can be present.
|
||||
</li>
|
||||
</ul>
|
||||
<p>In addition to the options defined in <a href="#sectionopt">Section 4</a>, the following options are valid within this block:
|
||||
</p><a name="InterfaceOptions2"></a>
|
||||
<table class="data" align="center" border="1" cellpadding="2" cellspacing="2">
|
||||
<tr>
|
||||
<th align="left" width="25%">Name</th>
|
||||
<th align="left" width="25%">Code</th>
|
||||
<th align="left" width="25%">Length</th>
|
||||
<th align="left" width="25%">Description</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">if_name</td>
|
||||
<td align="left">2</td>
|
||||
<td align="left">Variable</td>
|
||||
<td align="left">Name of the device used to capture data.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">if_IPv4addr</td>
|
||||
<td align="left">3</td>
|
||||
<td align="left">8</td>
|
||||
<td align="left">Interface network address and netmask.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">if_IPv6addr</td>
|
||||
<td align="left">4</td>
|
||||
<td align="left">17</td>
|
||||
<td align="left">Interface network address and prefix length (stored in the last byte).</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">if_MACaddr</td>
|
||||
<td align="left">5</td>
|
||||
<td align="left">6</td>
|
||||
<td align="left">Interface Hardware MAC address (48 bits).</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">if_EUIaddr</td>
|
||||
<td align="left">6</td>
|
||||
<td align="left">8</td>
|
||||
<td align="left">Interface Hardware EUI address (64 bits), if available.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">if_speed</td>
|
||||
<td align="left">7</td>
|
||||
<td align="left">8</td>
|
||||
<td align="left">Interface speed (in bps).</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">if_tsaccur</td>
|
||||
<td align="left">8</td>
|
||||
<td align="left">1</td>
|
||||
<td align="left">Precision of timestamps. If the Most Significant Bit is equal to zero, the remaining bits indicates the accuracy as as a negative power of 10 (e.g. 6 means microsecond accuracy). If the Most Significant Bit is equal to zero, the remaining bits indicates the accuracy as as negative power of 2 (e.g. 10 means 1/1024 of second). If this option is not present, a precision of 10^-6 is assumed.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">if_tzone</td>
|
||||
<td align="left">9</td>
|
||||
<td align="left">4</td>
|
||||
<td align="left">Time zone for GMT support (TODO: specify better).</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">if_flags</td>
|
||||
<td align="left">10</td>
|
||||
<td align="left">4</td>
|
||||
<td align="left">Interface flags. (TODO: specify better. Possible flags: promiscuous, inbound/outbound, traffic filtered during capture).</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">if_filter</td>
|
||||
<td align="left">11</td>
|
||||
<td align="left">variable</td>
|
||||
<td align="left">The filter (e.g. "capture only TCP traffic") used to capture traffic. The first byte of the Option Data keeps a code of the filter used (e.g. if this is a libpcap string, or BPF bytecode, and more). More details about this format will be presented in Appendix XXX (TODO).</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">if_opersystem</td>
|
||||
<td align="left">12</td>
|
||||
<td align="left">variable</td>
|
||||
<td align="left">An ascii string containing the name of the operating system of the machine that hosts this interface. This can be different from the same information that can be contained by the Section Header Block (<a href="#sectionshb">Section 3.1</a>) because the capture can have been done on a remote machine.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<a name="rfc.section.3.3"></a><h4><a name="sectionpb">3.3</a> Packet Block (optional)</h4>
|
||||
|
||||
<p>A Packet Block is the standard container for storing the packets coming from the network. The Packet Block is optional because packets can be stored either by means of this block or the Simple Packet Block, which can be used to speed up dump generation. The format of a packet block is shown in <a href="#formatpb">Figure 5</a>.
|
||||
</p><br /><hr />
|
||||
<a name="formatpb"></a>
|
||||
<pre>
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Interface ID | Drops Count |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Timestamp (High) |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Timestamp (Low) |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Captured Len |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Packet Len |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| |
|
||||
| Packet Data |
|
||||
| |
|
||||
| /* variable length, byte-aligned */ |
|
||||
| |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
/ /
|
||||
/ Options (variable) /
|
||||
/ /
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
</pre>
|
||||
<table border="0" cellpadding="0" cellspacing="2" align="center"><tr><td align="center"><font face="monaco, MS Sans Serif" size="1"><b> Packet Block format. </b></font><br /></td></tr></table><hr size="1" shade="0">
|
||||
|
||||
<p>The Packet Block has the following fields:
|
||||
</p>
|
||||
<ul class="text">
|
||||
<li>Interface ID: Specifies the interface this packet comes from, and corresponds to the ID of one of the Interface Description Blocks present in this section of the file (see <a href="#formatidb">Figure 4</a>).
|
||||
</li>
|
||||
<li>Drops Count: a local drop counter. It specified the number of packets lost (by the interface and the operating system) between this packet and the preceding one. The value xFFFF (in hexadecimal) is reserved for those systems in which this information is not available.
|
||||
</li>
|
||||
<li>Timestamp (High): the most significative part of the timestamp. in standard Unix format, i.e. from 1/1/1970.
|
||||
</li>
|
||||
<li>Timestamp (Low): the less significative part of the timestamp. The way to interpret this field is specified by the 'ts_accur' option (see <a href="#formatidb">Figure 4</a>) of the Interface Description block referenced by this packet. If the Interface Description block does not contain a 'ts_accur' option, then this field is expressed in microseconds.
|
||||
</li>
|
||||
<li>Captured Len: number of bytes captured from the packet (i.e. the length of the Packet Data field). It will be the minimum value among the actual Packet Length and the snapshot length (defined in <a href="#formatidb">Figure 4</a>).
|
||||
</li>
|
||||
<li>Packet Len: actual length of the packet when it was transmitted on the network. Can be different from Captured Len if the user wants only a snapshot of the packet.
|
||||
</li>
|
||||
<li>Packet Data: the data coming from the network, including link-layer headers. The length of this field is Captured Len. The format of the link-layer headers depends on the LinkType field specified in the Interface Description Block (see <a href="#sectionidb">Section 3.2</a>) and it is specified in Appendix XXX (TODO).
|
||||
</li>
|
||||
<li>Options: optionally, a list of options (formatted according to the rules defined in <a href="#sectionopt">Section 4</a>) can be present.
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
</p>
|
||||
<a name="rfc.section.3.4"></a><h4><a name="anchor7">3.4</a> Simple Packet Block (optional)</h4>
|
||||
|
||||
<p>The Simple Packet Block is a lightweight container for storing the packets coming from the network. Its presence is optional.
|
||||
</p>
|
||||
<p>A Simple Packet Block is similar to a Packet Block (see <a href="#sectionpb">Section 3.3</a>), but it is smaller, simpler to process and contains only a minimal set of information. This block is preferred to the standard Packet Block when performance or space occupation are critical factors, such as in sustained traffic dump applications. A capture file can contain both Packet Blocks and Simple Packet Blocks: for example, a capture tool could switch from Packet Blocks to Simple Packet Blocks when the hardware resources become critical.
|
||||
</p>
|
||||
<p>The Simple Packet Block does not contain the Interface ID field. Therefore, it must be assumed that all the Simple Packet Blocks have been captured on the interface previously specified in the Interface Description Block.
|
||||
</p>
|
||||
<p><a href="#formatpbs">Figure 6</a> shows the format of the Simple Packet Block.
|
||||
</p><br /><hr />
|
||||
<a name="formatpbs"></a>
|
||||
<pre>
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Packet Len |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| |
|
||||
| Packet Data |
|
||||
| |
|
||||
| /* variable length, byte-aligned */ |
|
||||
| |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
</pre>
|
||||
<table border="0" cellpadding="0" cellspacing="2" align="center"><tr><td align="center"><font face="monaco, MS Sans Serif" size="1"><b> Simple Packet Block format. </b></font><br /></td></tr></table><hr size="1" shade="0">
|
||||
|
||||
<p>The Packet Block has the following fields:
|
||||
</p>
|
||||
<ul class="text">
|
||||
<li>Packet Len: actual length of the packet when it was transmitted on the network. Can be different from captured len if the packet has been truncated.
|
||||
</li>
|
||||
<li>Packet data: the data coming from the network, including link-layers headers. The length of this field can be derived from the field Block Total Length, present in the Block Header.
|
||||
</li>
|
||||
</ul>
|
||||
<p>The Simple Packet Block does not contain the timestamp because this is one of the most costly operations on PCs. Additionally, there are applications that do not require it; e.g. an Intrusion Detection System is interested in packets, not in their timestamp.
|
||||
</p>
|
||||
<p>The Simple Packet Block is very efficient in term of disk space: a snapshot of length 100 bytes requires only 16 bytes of overhead, which corresponds to an efficiency of more than 86%.
|
||||
</p>
|
||||
<a name="rfc.section.3.5"></a><h4><a name="anchor8">3.5</a> Name Resolution Block (optional)</h4>
|
||||
|
||||
<p>The Name Resolution Block is used to support the correlation of numeric addresses (present in the captured packets) and their corresponding canonical names and it is optional. Having the literal names saved in the file, this prevents the need of a name resolution in a delayed time, when the association between names and addresses can be different from the one in use at capture time. Moreover, The Name Resolution Block avoids the need of issuing a lot of DNS requests every time the trace capture is opened, and allows to have name resolution also when reading the capture with a machine not connected to the network.
|
||||
</p>
|
||||
<p>The format of the Name Resolution Block is shown in <a href="#formatnrb">Figure 7</a>.
|
||||
</p><br /><hr />
|
||||
<a name="formatnrb"></a>
|
||||
<pre>
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Record Type | Record Length |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Record Value |
|
||||
| /* variable length, byte-aligned */ |
|
||||
| + + + + + + + + + + + + + + + + + + + + + + + + +
|
||||
| | | | |
|
||||
+-+-+-+-+-+-+-+-+ + + + + + + + + + + + + + + + + + + + + + + + +
|
||||
. . . other records . . .
|
||||
| Record Type == end_of_recs | Record Length == 00 |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
/ /
|
||||
/ Options (variable) /
|
||||
/ /
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
</pre>
|
||||
<table border="0" cellpadding="0" cellspacing="2" align="center"><tr><td align="center"><font face="monaco, MS Sans Serif" size="1"><b> Name Resolution Block format. </b></font><br /></td></tr></table><hr size="1" shade="0">
|
||||
|
||||
<p>A Name Resolution Block is a zero-terminated list of records (in the TLV format), each of which contains an association between a network address and a name. There are three possible types of records:
|
||||
</p><a name="nrrecords"></a>
|
||||
<table class="data" align="center" border="1" cellpadding="2" cellspacing="2">
|
||||
<tr>
|
||||
<th align="left" width="25%">Name</th>
|
||||
<th align="left" width="25%">Code</th>
|
||||
<th align="left" width="25%">Length</th>
|
||||
<th align="left" width="25%">Description</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">end_of_recs</td>
|
||||
<td align="left">0</td>
|
||||
<td align="left">0</td>
|
||||
<td align="left">End of records</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">ip4_rec</td>
|
||||
<td align="left">1</td>
|
||||
<td align="left">Variable</td>
|
||||
<td align="left">Specifies an IPv4 address (contained in the first 4 bytes), followed by one or more zero-terminated strings containing the DNS entries for that address.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">ip6_rec</td>
|
||||
<td align="left">1</td>
|
||||
<td align="left">Variable</td>
|
||||
<td align="left">Specifies an IPv6 address (contained in the first 16 bytes), followed by one or more zero-terminated strings containing the DNS entries for that address.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p>After the list or Name Resolution Records, optionally, a list of options (formatted according to the rules defined in <a href="#sectionopt">Section 4</a>) can be present.
|
||||
</p>
|
||||
<p>A Name Resolution Block is normally placed at the beginning of the file, but no assumptions can be taken about its position. Name Resolution Blocks can be added in a second time by tools that process the file, like network analyzers.
|
||||
</p>
|
||||
<p>In addiction to the options defined in <a href="#sectionopt">Section 4</a>, the following options are valid within this block:
|
||||
</p><table class="data" align="center" border="1" cellpadding="2" cellspacing="2">
|
||||
<tr>
|
||||
<th align="left" width="25%">Name</th>
|
||||
<th align="left" width="25%">Code</th>
|
||||
<th align="left" width="25%">Length</th>
|
||||
<th align="left" width="25%">Description</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">ns_dnsname</td>
|
||||
<td align="left">2</td>
|
||||
<td align="left">Variable</td>
|
||||
<td align="left">An ascii string containing the name of the machine (DNS server) used to perform the name resolution.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<a name="rfc.section.3.6"></a><h4><a name="anchor9">3.6</a> Interface Statistics Block (optional)</h4>
|
||||
|
||||
<p>The Interface Statistics Block contains the capture statistics for a given interface and it is optional. The statistics are referred to the interface defined in the current Section identified by the Interface ID field.
|
||||
</p>
|
||||
<p>The format of the Interface Statistics Block is shown in <a href="#formatisb">Figure 8</a>.
|
||||
</p><br /><hr />
|
||||
<a name="formatisb"></a>
|
||||
<pre>
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| IfRecv |
|
||||
| (high + low) |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| IfDrop |
|
||||
| (high + low) |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| FilterAccept |
|
||||
| (high + low) |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| OSDrop |
|
||||
| (high + low) |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| UsrDelivered |
|
||||
| (high + low) |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Interface ID | Reserved |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
/ /
|
||||
/ Options (variable) /
|
||||
/ /
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
</pre>
|
||||
<table border="0" cellpadding="0" cellspacing="2" align="center"><tr><td align="center"><font face="monaco, MS Sans Serif" size="1"><b> Interface Statistics Block format. </b></font><br /></td></tr></table><hr size="1" shade="0">
|
||||
|
||||
<p>The fields have the following meaning:
|
||||
</p>
|
||||
<ul class="text">
|
||||
<li>IfRecv: number of packets received from the interface during the capture. This number is reported as a 64 bits value, in which the most significat bits are located in the first four bytes of the field.
|
||||
</li>
|
||||
<li>IfDrop: number of packets dropped by the interface during the capture due to lack of resources.
|
||||
</li>
|
||||
<li>FilterAccept: number of packets accepeted by filter during current capture.
|
||||
</li>
|
||||
<li>OSDrop: number of packets dropped by the operating system during the capture.
|
||||
</li>
|
||||
<li>UsrDelivered: number of packets delivered to the user. UsrDelivered can be different from the value 'FilterAccept - OSDropped' because some packets could still lay in the OS buffers when the capture ended.
|
||||
</li>
|
||||
<li>Interface ID: reference to an Interface Description Block.
|
||||
</li>
|
||||
<li>Reserved: Reserved to future use.
|
||||
</li>
|
||||
<li>Options: optionally, a list of options (formatted according to the rules defined in <a href="#sectionopt">Section 4</a>) can be present.
|
||||
</li>
|
||||
</ul>
|
||||
<p>In addiction to the options defined in <a href="#sectionopt">Section 4</a>, the following options are valid within this block:
|
||||
</p><table class="data" align="center" border="1" cellpadding="2" cellspacing="2">
|
||||
<tr>
|
||||
<th align="left" width="25%">Name</th>
|
||||
<th align="left" width="25%">Code</th>
|
||||
<th align="left" width="25%">Length</th>
|
||||
<th align="left" width="25%">Description</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">isb_starttime</td>
|
||||
<td align="left">2</td>
|
||||
<td align="left">8</td>
|
||||
<td align="left">Time in which the capture started; time will be stored in two blocks of four bytes each, containing the timestamp in seconds and nanoseconds.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">isb_endtime</td>
|
||||
<td align="left">3</td>
|
||||
<td align="left">8</td>
|
||||
<td align="left">Time in which the capture started; time will be stored in two blocks of four bytes each, containing the timestamp in seconds and nanoseconds.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<a name="sectionopt"></a><br /><hr />
|
||||
<table summary="layout" cellpadding="0" cellspacing="2" class="bug" align="right"><tr><td class="bug"><a href="#toc" class="link2"> TOC </a></td></tr></table>
|
||||
<a name="rfc.section.4"></a><h3>4. Options</h3>
|
||||
|
||||
<p>Almost all blocks have the possibility to embed optional fields. Optional fields can be used to insert some information that may be useful when reading data, but that it is not really needed for packet processing. Therefore, each tool can be either read the content of the optional fields (if any), or skip them at once.
|
||||
</p>
|
||||
<p>Skipping all the optional fields at once is straightforward because most of the blocks have a fixed length, therefore the field Block Length (present in the General Block Structure, see <a href="#sectionblock">Section 2.1</a>) can be used to skip everything till the next block.
|
||||
</p>
|
||||
<p>Options are a list of Type - Length - Value fields, each one containing a single value:
|
||||
</p>
|
||||
<ul class="text">
|
||||
<li>Option Type (2 bytes): it contains the code that specifies the type of the current TLV record. Option types whose Most Significant Bit is equal to one are reserved for local use; therefore, there is no guarantee that the code used is unique among all capture files (generated by other applications). In case of vendor-specific extensions that have to be identified uniquely, vendors must request an Option Code whose MSB is equal to zero.
|
||||
</li>
|
||||
<li>Option Length (2 bytes): it contains the length of the following 'Option Value' field.
|
||||
</li>
|
||||
<li>Option Value (variable length): it contains the value of the given option. The length of this field as been specified by the Option Length field.
|
||||
</li>
|
||||
</ul>
|
||||
<p>Options may be repeated several times (e.g. an interface that has several IP addresses associated to it). The option list is terminated by a special code which is the 'End of Option'.
|
||||
</p>
|
||||
<p>The format of the optional fields is shown in <a href="#formatopt">Figure 9</a>.
|
||||
</p><br /><hr />
|
||||
<a name="formatopt"></a>
|
||||
<pre>
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Option Code | Option Length |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Option Value |
|
||||
| /* variable length, byte-aligned */ |
|
||||
| + + + + + + + + + + + + + + + + + + + + + + + + +
|
||||
| / / / |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
/ /
|
||||
/ . . . other options . . . /
|
||||
/ /
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Option Code == opt_endofopt | Option Length == 0 |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
</pre>
|
||||
<table border="0" cellpadding="0" cellspacing="2" align="center"><tr><td align="center"><font face="monaco, MS Sans Serif" size="1"><b> Options format. </b></font><br /></td></tr></table><hr size="1" shade="0">
|
||||
|
||||
<p>The following codes can always be present in any optional field:
|
||||
</p><table class="data" align="center" border="1" cellpadding="2" cellspacing="2">
|
||||
<tr>
|
||||
<th align="left" width="25%">Name</th>
|
||||
<th align="left" width="25%">Code</th>
|
||||
<th align="left" width="25%">Length</th>
|
||||
<th align="left" width="25%">Description</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">opt_endofopt</td>
|
||||
<td align="left">0</td>
|
||||
<td align="left">0</td>
|
||||
<td align="left">End of options: it is used to delimit the end of the optional fields. This block cannot be repeated within a given list of options.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">opt_comment</td>
|
||||
<td align="left">1</td>
|
||||
<td align="left">variable</td>
|
||||
<td align="left">Comment: it is an ascii string containing a comment that is associated to the current block.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<a name="anchor10"></a><br /><hr />
|
||||
<table summary="layout" cellpadding="0" cellspacing="2" class="bug" align="right"><tr><td class="bug"><a href="#toc" class="link2"> TOC </a></td></tr></table>
|
||||
<a name="rfc.section.5"></a><h3>5. Experimental Blocks (deserved to a further investigation)</h3>
|
||||
|
||||
<a name="rfc.section.5.1"></a><h4><a name="anchor11">5.1</a> Other Packet Blocks (experimental)</h4>
|
||||
|
||||
<p>Can some other packet blocks (besides the two described in the previous paragraphs) be useful?
|
||||
</p>
|
||||
<a name="rfc.section.5.2"></a><h4><a name="anchor12">5.2</a> Compression Block (experimental)</h4>
|
||||
|
||||
<p>The Compression Block is optional. A file can contain an arbitrary number of these blocks. A Compression Block, as the name says, is used to store compressed data. Its format is shown in <a href="#formatcb">Figure 10</a>.
|
||||
</p><br /><hr />
|
||||
<a name="formatcb"></a>
|
||||
<pre>
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Compr. Type | |
|
||||
+-+-+-+-+-+-+-+-+ |
|
||||
| |
|
||||
| Compressed Data |
|
||||
| |
|
||||
| /* variable length, byte-aligned */ |
|
||||
| |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
</pre>
|
||||
<table border="0" cellpadding="0" cellspacing="2" align="center"><tr><td align="center"><font face="monaco, MS Sans Serif" size="1"><b> Compression Block format. </b></font><br /></td></tr></table><hr size="1" shade="0">
|
||||
|
||||
<p>The fields have the following meaning:
|
||||
</p>
|
||||
<ul class="text">
|
||||
<li>Compression Type: specifies the compression algorithm. Possible values for this field are 0 (uncompressed), 1 (Lempel Ziv), 2 (Gzip), other?? Probably some kind of dumb and fast compression algorithm could be effective with some types of traffic (for example web), but which?
|
||||
</li>
|
||||
<li>Compressed Data: data of this block. Once decompressed, it is made of other blocks.
|
||||
</li>
|
||||
</ul>
|
||||
<a name="rfc.section.5.3"></a><h4><a name="anchor13">5.3</a> Encryption Block (experimental)</h4>
|
||||
|
||||
<p>The Encryption Block is optional. A file can contain an arbitrary number of these blocks. An Encryption Block is used to sotre encrypted data. Its format is shown in <a href="#formateb">Figure 11</a>.
|
||||
</p><br /><hr />
|
||||
<a name="formateb"></a>
|
||||
<pre>
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Encr. Type | |
|
||||
+-+-+-+-+-+-+-+-+ |
|
||||
| |
|
||||
| Compressed Data |
|
||||
| |
|
||||
| /* variable length, byte-aligned */ |
|
||||
| |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
</pre>
|
||||
<table border="0" cellpadding="0" cellspacing="2" align="center"><tr><td align="center"><font face="monaco, MS Sans Serif" size="1"><b> Encryption Block format. </b></font><br /></td></tr></table><hr size="1" shade="0">
|
||||
|
||||
<p>The fields have the following meaning:
|
||||
</p>
|
||||
<ul class="text">
|
||||
<li>Compression Type: specifies the encryption algorithm. Possible values for this field are ??? NOTE: this block should probably contain other fields, depending on the encryption algorithm. To be define precisely.
|
||||
</li>
|
||||
<li>Encrypted Data: data of this block. Once decripted, it consists of other blocks.
|
||||
</li>
|
||||
</ul>
|
||||
<a name="rfc.section.5.4"></a><h4><a name="anchor14">5.4</a> Fixed Length Block (experimental)</h4>
|
||||
|
||||
<p>The Fixed Length Block is optional. A file can contain an arbitrary number of these blocks. A Fixed Length Block can be used to optimize the access to the file. Its format is shown in <a href="#formatflm">Figure 12</a>.
|
||||
A Fixed Length Block stores records with constant size. It contains a set of Blocks (normally Packet Blocks or Simple Packet Blocks), of wihich it specifies the size. Knowing this size a priori helps to scan the file and to load some portions of it without truncating a block, and is particularly useful with cell-based networks like ATM.
|
||||
</p><br /><hr />
|
||||
<a name="formatflm"></a>
|
||||
<pre>
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Cell Size | |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
|
||||
| |
|
||||
| Fixed Size Data |
|
||||
| |
|
||||
| /* variable length, byte-aligned */ |
|
||||
| |
|
||||
| |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
</pre>
|
||||
<table border="0" cellpadding="0" cellspacing="2" align="center"><tr><td align="center"><font face="monaco, MS Sans Serif" size="1"><b> Fixed Length Block format. </b></font><br /></td></tr></table><hr size="1" shade="0">
|
||||
|
||||
<p>The fields have the following meaning:
|
||||
</p>
|
||||
<ul class="text">
|
||||
<li>Cell size: the size of the blocks contained in the data field.
|
||||
</li>
|
||||
<li>Fixed Size Data: data of this block.
|
||||
</li>
|
||||
</ul>
|
||||
<a name="rfc.section.5.5"></a><h4><a name="anchor15">5.5</a> Directory Block (experimental)</h4>
|
||||
|
||||
<p>If present, this block contains the following information:
|
||||
</p>
|
||||
<ul class="text">
|
||||
<li>number of indexed packets (N)
|
||||
</li>
|
||||
<li>table with position and length of any indexed packet (N entries)
|
||||
</li>
|
||||
</ul>
|
||||
<p>A directory block must be followed by at least N packets, otherwise it must be considered invalid. It can be used to efficiently load portions of the file to memory and to support operations on memory mapped files. This block can be added by tools like network analyzers as a consequence of file processing.
|
||||
</p>
|
||||
<a name="rfc.section.5.6"></a><h4><a name="anchor16">5.6</a> Traffic Statistics and Monitoring Blocks (experimental)</h4>
|
||||
|
||||
<p>One or more blocks could be defined to contain network statistics or traffic monitoring information. They could be use to store data collected from RMON or Netflow probes, or from other network monitoring tools.
|
||||
</p>
|
||||
<a name="rfc.section.5.7"></a><h4><a name="anchor17">5.7</a> Event/Security Block (experimental)</h4>
|
||||
|
||||
<p>This block could be used to store events. Events could contain generic information (for example network load over 50%, server down...) or security alerts. An event could be:
|
||||
</p>
|
||||
<ul class="text">
|
||||
<li>skipped, if the application doesn't know how to do with it
|
||||
</li>
|
||||
<li>processed independently by the packets. In other words, the applications skips the packets and processes only the alerts
|
||||
</li>
|
||||
<li>processed in relation to packets: for example, a security tool could load only the packets of the file that are near a security alert; a monitorg tool could skip the packets captured while the server was down.
|
||||
</li>
|
||||
</ul>
|
||||
<a name="anchor18"></a><br /><hr />
|
||||
<table summary="layout" cellpadding="0" cellspacing="2" class="bug" align="right"><tr><td class="bug"><a href="#toc" class="link2"> TOC </a></td></tr></table>
|
||||
<a name="rfc.section.6"></a><h3>6. Conclusions</h3>
|
||||
|
||||
<p>The file format proposed in this document should be very versatile and satisfy a wide range of applications.
|
||||
In the simplest case, it can contain a raw dump of the network data, made of a series of Simple Packet Blocks.
|
||||
In the most complex case, it can be used as a repository for heterogeneous information.
|
||||
In every case, the file remains easy to parse and an application can always skip the data it is not interested in; at the same time, different applications can share the file, and each of them can benfit of the information produced by the others.
|
||||
Two or more files can be concatenated obtaining another valid file.
|
||||
</p>
|
||||
<a name="anchor19"></a><br /><hr />
|
||||
<table summary="layout" cellpadding="0" cellspacing="2" class="bug" align="right"><tr><td class="bug"><a href="#toc" class="link2"> TOC </a></td></tr></table>
|
||||
<a name="rfc.section.7"></a><h3>7. Most important open issues</h3>
|
||||
|
||||
<ul class="text">
|
||||
<li>Data, in the file, must be byte or word aligned? Currently, the structure of this document is not consistent with respect to this point.
|
||||
</li>
|
||||
</ul><a name="rfc.copyright"></a><br /><hr />
|
||||
<table summary="layout" cellpadding="0" cellspacing="2" class="bug" align="right"><tr><td class="bug"><a href="#toc" class="link2"> TOC </a></td></tr></table>
|
||||
<h3>Intellectual Property Statement</h3>
|
||||
<p class='copyright'>
|
||||
The IETF takes no position regarding the validity or scope of
|
||||
any intellectual property or other rights that might be claimed
|
||||
to pertain to the implementation or use of the technology
|
||||
described in this document or the extent to which any license
|
||||
under such rights might or might not be available; neither does
|
||||
it represent that it has made any effort to identify any such
|
||||
rights. Information on the IETF's procedures with respect to
|
||||
rights in standards-track and standards-related documentation
|
||||
can be found in BCP-11. Copies of claims of rights made
|
||||
available for publication and any assurances of licenses to
|
||||
be made available, or the result of an attempt made
|
||||
to obtain a general license or permission for the use of such
|
||||
proprietary rights by implementors or users of this
|
||||
specification can be obtained from the IETF Secretariat.</p>
|
||||
<p class='copyright'>
|
||||
The IETF invites any interested party to bring to its
|
||||
attention any copyrights, patents or patent applications, or
|
||||
other proprietary rights which may cover technology that may be
|
||||
required to practice this standard. Please address the
|
||||
information to the IETF Executive Director.</p>
|
||||
<h3>Full Copyright Statement</h3>
|
||||
<p class='copyright'>
|
||||
Copyright (C) The Internet Society (2004). All Rights Reserved.</p>
|
||||
<p class='copyright'>
|
||||
This document and translations of it may be copied and furnished to
|
||||
others, and derivative works that comment on or otherwise explain it
|
||||
or assist in its implementation may be prepared, copied, published and
|
||||
distributed, in whole or in part, without restriction of any kind,
|
||||
provided that the above copyright notice and this paragraph are
|
||||
included on all such copies and derivative works. However, this
|
||||
document itself may not be modified in any way, such as by removing
|
||||
the copyright notice or references to the Internet Society or other
|
||||
Internet organizations, except as needed for the purpose of
|
||||
developing Internet standards in which case the procedures for
|
||||
copyrights defined in the Internet Standards process must be
|
||||
followed, or as required to translate it into languages other than
|
||||
English.</p>
|
||||
<p class='copyright'>
|
||||
The limited permissions granted above are perpetual and will not be
|
||||
revoked by the Internet Society or its successors or assignees.</p>
|
||||
<p class='copyright'>
|
||||
This document and the information contained herein is provided on an
|
||||
"AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
|
||||
TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
|
||||
BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
|
||||
HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.</p>
|
||||
<h3>Acknowledgment</h3>
|
||||
<p class='copyright'>
|
||||
Funding for the RFC Editor function is currently provided by the
|
||||
Internet Society.</p>
|
||||
</body></html>
|
||||
1680
libpcap-possiblymodified/doc/pcap.txt
Normal file
1680
libpcap-possiblymodified/doc/pcap.txt
Normal file
File diff suppressed because it is too large
Load Diff
746
libpcap-possiblymodified/doc/pcap.xml
Normal file
746
libpcap-possiblymodified/doc/pcap.xml
Normal file
@@ -0,0 +1,746 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml-stylesheet type='text/xsl' href='rfc2629.xslt' ?>
|
||||
|
||||
<!DOCTYPE rfc SYSTEM "rfc2629.dtd">
|
||||
<?rfc toc="yes"?>
|
||||
<rfc ipr="full2026" docname="draft-libpcap-dump-format-00.txt">
|
||||
<front>
|
||||
<title>PCAP New Generation Dump File Format</title>
|
||||
<author initials="L." surname="Degioanni" fullname="Loris Degioanni">
|
||||
<organization>Politecnico di Torino</organization>
|
||||
<address>
|
||||
<postal>
|
||||
<street>Corso Duca degli Abruzzi, 24</street>
|
||||
<city>Torino</city>
|
||||
<code>10129</code>
|
||||
<country>Italy</country>
|
||||
</postal>
|
||||
<phone>+39 011 564 7008</phone>
|
||||
<email>loris.degioanni@polito.it</email>
|
||||
<uri>http://netgroup.polito.it/loris/</uri>
|
||||
</address>
|
||||
</author>
|
||||
<author initials="F." surname="Risso" fullname="Fulvio Risso">
|
||||
<organization>Politecnico di Torino</organization>
|
||||
<address>
|
||||
<postal>
|
||||
<street>Corso Duca degli Abruzzi, 24</street>
|
||||
<city>Torino</city>
|
||||
<code>10129</code>
|
||||
<country>Italy</country>
|
||||
</postal>
|
||||
<phone>+39 011 564 7008</phone>
|
||||
<email>fulvio.risso@polito.it</email>
|
||||
<uri>http://netgroup.polito.it/fulvio.risso/</uri>
|
||||
</address>
|
||||
</author>
|
||||
|
||||
<!-- Other authors go here -->
|
||||
|
||||
<date month="March" year="2004"/>
|
||||
<area>General</area>
|
||||
<!--
|
||||
<workgroup>
|
||||
-->
|
||||
<keyword>Internet-Draft</keyword>
|
||||
<keyword>Libpcap, dump file format</keyword>
|
||||
<abstract>
|
||||
<t>This document describes a format to dump captured packets on a file. This format is extensible and it is currently proposed for implementation in the libpcap/WinPcap packet capture library.</t>
|
||||
</abstract>
|
||||
<!--
|
||||
<note ...>
|
||||
-->
|
||||
</front>
|
||||
<middle>
|
||||
|
||||
<section title="Objectives">
|
||||
<t>The problem of exchanging packet traces becomes more and more critical every day; unfortunately, no standard solutions exist for this task right now. One of the most accepted packet interchange formats is the one defined by libpcap, which is rather old and does not fit for some of the nowadays applications especially in terms of extensibility.</t>
|
||||
<t>This document proposes a new format for dumping packet traces. The following goals are being pursued:</t>
|
||||
<list style="symbols">
|
||||
<t>Extensibility: aside of some common functionalities, third parties should be able to enrich the information embedded in the file with proprietary extensions, which will be ignored by tools that are not able to understand them.</t>
|
||||
<t>Portability: a capture trace must contain all the information needed to read data independently from network, hardware and operating system of the machine that made the capture.</t>
|
||||
<t>Merge/Append data: it should be possible to add data at the end of a given file, and the resulting file must still be readable.</t>
|
||||
</list>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
<section title="General File Structure">
|
||||
|
||||
<section anchor="sectionblock" title="General Block Structure">
|
||||
<t>A capture file is organized in blocks, that are appended one to another to form the file. All the blocks share a common format, which is shown in <xref target="formatblock"/>.</t>
|
||||
|
||||
<figure anchor="formatblock" title="Basic block structure.">
|
||||
<artwork>
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Block Type |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Block Total Length |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
/ Block Body /
|
||||
/ /* variable length, aligned to 32 bits */ /
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Block Total Length |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
</artwork>
|
||||
</figure>
|
||||
|
||||
<t>The fields have the following meaning:</t>
|
||||
|
||||
<list style="symbols">
|
||||
<t>Block Type (32 bits): unique value that identifies the block. Values whose Most Significant Bit (MSB) is equal to 1 are reserved for local use. They allow to save private data to the file and to extend the file format.</t>
|
||||
<t>Block Total Length: total size of this block, in bytes. For instance, a block that does not have a body has a length of 12 bytes.</t>
|
||||
<t>Block Body: content of the block.</t>
|
||||
<t>Block Total Length: total size of this block, in bytes. This field is duplicated for permitting backward file navigation.</t>
|
||||
</list>
|
||||
|
||||
<t>This structure, shared among all blocks, makes easy to process a file and to skip unneeded or unknown blocks. Blocks can be nested one inside the others (NOTE: needed?). Some of the blocks are mandatory, i.e. a dump file is not valid if they are not present, other are optional.</t>
|
||||
<t>The structure of the blocks allows to define other blocks if needed. A parser that does non understand them can simply ignore their content.</t>
|
||||
</section>
|
||||
|
||||
<section title="Block Types">
|
||||
<t>The currently defined blocks are the following:</t>
|
||||
<list style="numbers">
|
||||
<t>Section Header Block: it defines the most important characteristics of the capture file.</t>
|
||||
<t>Interface Description Block: it defines the most important characteristics of the interface(s) used for capturing traffic.</t>
|
||||
<t>Packet Block: it contains a single captured packet, or a portion of it.</t>
|
||||
<t>Simple Packet Block: it contains a single captured packet, or a portion of it, with only a minimal set of information about it.</t>
|
||||
<t>Name Resolution Block: it defines the mapping from numeric addresses present in the packet dump and the canonical name counterpart.</t>
|
||||
<t>Capture Statistics Block: it defines how to store some statistical data (e.g. packet dropped, etc) which can be useful to undestand the conditions in which the capture has been made.</t>
|
||||
<t>Compression Marker Block: TODO</t>
|
||||
<t>Encryption Marker Block: TODO</t>
|
||||
<t>Fixed Length Marker Block: TODO</t>
|
||||
</list>
|
||||
|
||||
<t>The following blocks instead are considered interesting but the authors believe that they deserve more in-depth discussion before being defined:</t>
|
||||
<list style="numbers">
|
||||
<t>Further Packet Blocks</t>
|
||||
<t>Directory Block</t>
|
||||
<t>Traffic Statistics and Monitoring Blocks</t>
|
||||
<t>Alert and Security Blocks</t>
|
||||
</list>
|
||||
|
||||
<t>TODO Currently standardized Block Type codes are specified in Appendix 1.</t>
|
||||
|
||||
</section>
|
||||
|
||||
<section title="Block Hierarchy and Precedence">
|
||||
<t>The file must begin with a Section Header Block. However, more than one Section Header Block can be present on the dump, each one covering the data following it till the next one (or the end of file). A Section includes the data delimited by two Section Header Blocks (or by a Section Header Block and the end of the file), including the first Section Header Block.</t>
|
||||
<t>In case an application cannot read a Section because of different version number, it must skip everything until the next Section Header Block. Note that, in order to properly skip the blocks until the next section, all blocks must have the fields Type and Length at the beginning. This is a mandatory requirement that must be maintained in future versions of the block format.</t>
|
||||
<t><xref target="fssample-SHB"/> shows two valid files: the first has a typical configuration, with a single Section Header that covers the whole file. The second one contains three headers, and is normally the result of file concatenation. An application that understands only version 1.0 of the file format skips the intermediate section and restart processing the packets after the third Section Header.</t>
|
||||
|
||||
<figure anchor="fssample-SHB" title="File structure example: the Section Header Block.">
|
||||
<artwork>
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| SHB v1.0 | Data |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
Typical configuration with a single Section Header Block
|
||||
|
||||
|
||||
|-- 1st Section --|-- 2nd Section --|-- 3rd Section --|
|
||||
| |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| SHB v1.0 | Data | SHB V1.1 | Data | SHB V1.0 | Data |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
Configuration with three different Section Header Blocks
|
||||
</artwork>
|
||||
</figure>
|
||||
|
||||
<t>NOTE: TO BE COMPLETED with some examples of other blocks</t>
|
||||
|
||||
</section>
|
||||
|
||||
<section title="Data format">
|
||||
<t>Data contained in each section will always be saved according to the characteristics (little endian / big endian) of the dumping machine. This refers to all fields that are saved as numbers and that span over two or more bytes.</t>
|
||||
<t>The approach of having each section saved in the native format of the generating host is more efficient because it avoids translation of data when reading / writing on the host itself, which is the most common case when generating/processing capture dumps.</t>
|
||||
<t>TODO Probably we have to specify something more here. Is what we're saying enough to avoid any kind of ambiguity?.</t>
|
||||
</section>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
|
||||
<section title="Block Definition">
|
||||
<t>This section details the format of the body of the blocks currently defined.</t>
|
||||
|
||||
<section anchor="sectionshb" title="Section Header Block (mandatory)">
|
||||
<t>The Section Header Block is mandatory. It identifies the beginning of a section of the capture dump file. Its format is shown in <xref target="formatSHB"/>.</t>
|
||||
<figure anchor="formatSHB" title="Section Header Block format.">
|
||||
<artwork>
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Magic |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Major | Minor |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
/ /
|
||||
/ Options (variable) /
|
||||
/ /
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
</artwork>
|
||||
</figure>
|
||||
|
||||
<t>The meaning of the fields is:</t>
|
||||
<list style="symbols">
|
||||
<t>Magic: magic number, whose value is the hexadecimal number 0x1A2B3C4D. This number can be used to distinguish section that have been saved on little-endian machines from the one saved on big-endian machines.</t>
|
||||
<t>Major: number of the current mayor version of the format. Current value is 1.</t>
|
||||
<t>Minor: number of the current minor version of the format. Current value is 0.</t>
|
||||
<t>Options: optionally, a list of options (formatted according to the rules defined in <xref target="sectionopt"/>) can be present.</t>
|
||||
</list>
|
||||
|
||||
<t>Aside form the options defined in <xref target="sectionopt"/>, the following options are valid within this block:</t>
|
||||
|
||||
<texttable anchor="InterfaceOptions1">
|
||||
<ttcol>Name</ttcol>
|
||||
<ttcol>Code</ttcol>
|
||||
<ttcol>Length</ttcol>
|
||||
<ttcol>Description</ttcol>
|
||||
|
||||
<c>Hardware</c>
|
||||
<c>2</c>
|
||||
<c>variable</c>
|
||||
<c>An ascii string containing the description of the hardware used to create this section.</c>
|
||||
|
||||
<c>Operating System</c>
|
||||
<c>3</c>
|
||||
<c>variable</c>
|
||||
<c>An ascii string containing the name of the operating system used to create this section.</c>
|
||||
|
||||
<c>User Application</c>
|
||||
<c>3</c>
|
||||
<c>variable</c>
|
||||
<c>An ascii string containing the name of the application used to create this section.</c>
|
||||
</texttable>
|
||||
|
||||
|
||||
<t>The Section Header Block does not contain data but it rather identifies a list of blocks (interfaces, packets) that are logically correlated. This block does not contain any reference to the size of the section it is currently delimiting, therefore the reader cannot skip a whole section at once. In case a section must be skipped, the user has to repeatedly skip all the blocks contained within it; this makes the parsing of the file slower but it permits to append several capture dumps at the same file.</t>
|
||||
</section>
|
||||
|
||||
<section anchor="sectionidb" title="Interface Description Block (mandatory)">
|
||||
<t>The Interface Description Block is mandatory. This block is needed to specify the characteristics of the network interface on which the capture has been made. In order to properly associate the captured data to the corresponding interface, the Interface Description Block must be defined before any other block that uses it; therefore, this block is usually placed immediately after the Section Header Block.</t>
|
||||
|
||||
<t>An Interface Description Block is valid only inside the section which it belongs to. The structure of a Interface Description Block is shown in <xref target="formatidb"/>.</t>
|
||||
|
||||
<figure anchor="formatidb" title="Interface Description Block format.">
|
||||
<artwork>
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Interface ID | LinkType |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| SnapLen |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
/ /
|
||||
/ Options (variable) /
|
||||
/ /
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
</artwork>
|
||||
</figure>
|
||||
|
||||
<t>The meaning of the fields is:</t>
|
||||
<list style="symbols">
|
||||
<t>Interface ID: a progressive number that identifies uniquely any interface inside current section. Two Interface Description Blocks can have the same Interface ID only if they are in different sections of the file. The Interface ID is referenced by the packet blocks.</t>
|
||||
<t>LinkType: a value that defines the link layer type of this interface.</t>
|
||||
<t>SnapLen: maximum number of bytes dumped from each packet. The portion of each packet that exceeds this value will not be stored in the file.</t>
|
||||
<t>Options: optionally, a list of options (formatted according to the rules defined in <xref target="sectionopt"/>) can be present.</t>
|
||||
</list>
|
||||
|
||||
<t>In addition to the options defined in <xref target="sectionopt"/>, the following options are valid within this block:</t>
|
||||
|
||||
<texttable anchor="InterfaceOptions2">
|
||||
<ttcol>Name</ttcol>
|
||||
<ttcol>Code</ttcol>
|
||||
<ttcol>Length</ttcol>
|
||||
<ttcol>Description</ttcol>
|
||||
|
||||
<c>if_name</c>
|
||||
<c>2</c>
|
||||
<c>Variable</c>
|
||||
<c>Name of the device used to capture data.</c>
|
||||
|
||||
<c>if_IPv4addr</c>
|
||||
<c>3</c>
|
||||
<c>8</c>
|
||||
<c>Interface network address and netmask.</c>
|
||||
|
||||
<c>if_IPv6addr</c>
|
||||
<c>4</c>
|
||||
<c>17</c>
|
||||
<c>Interface network address and prefix length (stored in the last byte).</c>
|
||||
|
||||
<c>if_MACaddr</c>
|
||||
<c>5</c>
|
||||
<c>6</c>
|
||||
<c>Interface Hardware MAC address (48 bits).</c>
|
||||
|
||||
<c>if_EUIaddr</c>
|
||||
<c>6</c>
|
||||
<c>8</c>
|
||||
<c>Interface Hardware EUI address (64 bits), if available.</c>
|
||||
|
||||
<c>if_speed</c>
|
||||
<c>7</c>
|
||||
<c>8</c>
|
||||
<c>Interface speed (in bps).</c>
|
||||
|
||||
<c>if_tsaccur</c>
|
||||
<c>8</c>
|
||||
<c>1</c>
|
||||
<c>Precision of timestamps. If the Most Significant Bit is equal to zero, the remaining bits indicates the accuracy as as a negative power of 10 (e.g. 6 means microsecond accuracy). If the Most Significant Bit is equal to zero, the remaining bits indicates the accuracy as as negative power of 2 (e.g. 10 means 1/1024 of second). If this option is not present, a precision of 10^-6 is assumed.</c>
|
||||
|
||||
<c>if_tzone</c>
|
||||
<c>9</c>
|
||||
<c>4</c>
|
||||
<c>Time zone for GMT support (TODO: specify better).</c>
|
||||
|
||||
<c>if_flags</c>
|
||||
<c>10</c>
|
||||
<c>4</c>
|
||||
<c>Interface flags. (TODO: specify better. Possible flags: promiscuous, inbound/outbound, traffic filtered during capture).</c>
|
||||
|
||||
<c>if_filter</c>
|
||||
<c>11</c>
|
||||
<c>variable</c>
|
||||
<c>The filter (e.g. "capture only TCP traffic") used to capture traffic. The first byte of the Option Data keeps a code of the filter used (e.g. if this is a libpcap string, or BPF bytecode, and more). More details about this format will be presented in Appendix XXX (TODO).</c>
|
||||
|
||||
<c>if_opersystem</c>
|
||||
<c>12</c>
|
||||
<c>variable</c>
|
||||
<c>An ascii string containing the name of the operating system of the machine that hosts this interface. This can be different from the same information that can be contained by the Section Header Block (<xref target="sectionshb"/>) because the capture can have been done on a remote machine.</c>
|
||||
|
||||
</texttable>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
<section anchor="sectionpb" title="Packet Block (optional)">
|
||||
<t>A Packet Block is the standard container for storing the packets coming from the network. The Packet Block is optional because packets can be stored either by means of this block or the Simple Packet Block, which can be used to speed up dump generation. The format of a packet block is shown in <xref target="formatpb"/>.</t>
|
||||
|
||||
<figure anchor="formatpb" title="Packet Block format.">
|
||||
<artwork>
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Interface ID | Drops Count |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Timestamp (High) |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Timestamp (Low) |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Captured Len |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Packet Len |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| |
|
||||
| Packet Data |
|
||||
| |
|
||||
| /* variable length, byte-aligned */ |
|
||||
| |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
/ /
|
||||
/ Options (variable) /
|
||||
/ /
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
</artwork>
|
||||
</figure>
|
||||
|
||||
<t>The Packet Block has the following fields:</t>
|
||||
|
||||
<list style="symbols">
|
||||
<t>Interface ID: Specifies the interface this packet comes from, and corresponds to the ID of one of the Interface Description Blocks present in this section of the file (see <xref target="formatidb"/>).</t>
|
||||
<t>Drops Count: a local drop counter. It specified the number of packets lost (by the interface and the operating system) between this packet and the preceding one. The value xFFFF (in hexadecimal) is reserved for those systems in which this information is not available.</t>
|
||||
<t>Timestamp (High): the most significative part of the timestamp. in standard Unix format, i.e. from 1/1/1970.</t>
|
||||
<t>Timestamp (Low): the less significative part of the timestamp. The way to interpret this field is specified by the 'ts_accur' option (see <xref target="formatidb"/>) of the Interface Description block referenced by this packet. If the Interface Description block does not contain a 'ts_accur' option, then this field is expressed in microseconds.</t>
|
||||
<t>Captured Len: number of bytes captured from the packet (i.e. the length of the Packet Data field). It will be the minimum value among the actual Packet Length and the snapshot length (defined in <xref target="formatidb"/>).</t>
|
||||
<t>Packet Len: actual length of the packet when it was transmitted on the network. Can be different from Captured Len if the user wants only a snapshot of the packet.</t>
|
||||
<t>Packet Data: the data coming from the network, including link-layer headers. The length of this field is Captured Len. The format of the link-layer headers depends on the LinkType field specified in the Interface Description Block (see <xref target="sectionidb"/>) and it is specified in Appendix XXX (TODO).</t>
|
||||
<t>Options: optionally, a list of options (formatted according to the rules defined in <xref target="sectionopt"/>) can be present.</t>
|
||||
</list>
|
||||
|
||||
<t></t>
|
||||
</section>
|
||||
|
||||
|
||||
<section title="Simple Packet Block (optional)">
|
||||
<t>The Simple Packet Block is a lightweight container for storing the packets coming from the network. Its presence is optional.</t>
|
||||
<t>A Simple Packet Block is similar to a Packet Block (see <xref target="sectionpb"/>), but it is smaller, simpler to process and contains only a minimal set of information. This block is preferred to the standard Packet Block when performance or space occupation are critical factors, such as in sustained traffic dump applications. A capture file can contain both Packet Blocks and Simple Packet Blocks: for example, a capture tool could switch from Packet Blocks to Simple Packet Blocks when the hardware resources become critical.</t>
|
||||
<t>The Simple Packet Block does not contain the Interface ID field. Therefore, it must be assumed that all the Simple Packet Blocks have been captured on the interface previously specified in the Interface Description Block.</t>
|
||||
<t><xref target="formatpbs"/> shows the format of the Simple Packet Block.</t>
|
||||
|
||||
<figure anchor="formatpbs" title="Simple Packet Block format.">
|
||||
<artwork>
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Packet Len |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| |
|
||||
| Packet Data |
|
||||
| |
|
||||
| /* variable length, byte-aligned */ |
|
||||
| |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
</artwork>
|
||||
</figure>
|
||||
|
||||
<t>The Packet Block has the following fields:</t>
|
||||
<list style="symbols">
|
||||
<t>Packet Len: actual length of the packet when it was transmitted on the network. Can be different from captured len if the packet has been truncated.</t>
|
||||
<t>Packet data: the data coming from the network, including link-layers headers. The length of this field can be derived from the field Block Total Length, present in the Block Header.</t>
|
||||
</list>
|
||||
|
||||
<t>The Simple Packet Block does not contain the timestamp because this is one of the most costly operations on PCs. Additionally, there are applications that do not require it; e.g. an Intrusion Detection System is interested in packets, not in their timestamp.</t>
|
||||
|
||||
<t>The Simple Packet Block is very efficient in term of disk space: a snapshot of length 100 bytes requires only 16 bytes of overhead, which corresponds to an efficiency of more than 86%.</t>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
<section title="Name Resolution Block (optional)">
|
||||
<t>The Name Resolution Block is used to support the correlation of numeric addresses (present in the captured packets) and their corresponding canonical names and it is optional. Having the literal names saved in the file, this prevents the need of a name resolution in a delayed time, when the association between names and addresses can be different from the one in use at capture time. Moreover, The Name Resolution Block avoids the need of issuing a lot of DNS requests every time the trace capture is opened, and allows to have name resolution also when reading the capture with a machine not connected to the network.</t>
|
||||
<t>The format of the Name Resolution Block is shown in <xref target="formatnrb"/>.</t>
|
||||
|
||||
<figure anchor="formatnrb" title="Name Resolution Block format.">
|
||||
<artwork>
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Record Type | Record Length |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Record Value |
|
||||
| /* variable length, byte-aligned */ |
|
||||
| + + + + + + + + + + + + + + + + + + + + + + + + +
|
||||
| | | | |
|
||||
+-+-+-+-+-+-+-+-+ + + + + + + + + + + + + + + + + + + + + + + + +
|
||||
. . . other records . . .
|
||||
| Record Type == end_of_recs | Record Length == 00 |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
/ /
|
||||
/ Options (variable) /
|
||||
/ /
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
</artwork>
|
||||
</figure>
|
||||
|
||||
<t>A Name Resolution Block is a zero-terminated list of records (in the TLV format), each of which contains an association between a network address and a name. There are three possible types of records:</t>
|
||||
|
||||
<texttable anchor="nrrecords">
|
||||
<ttcol>Name</ttcol>
|
||||
<ttcol>Code</ttcol>
|
||||
<ttcol>Length</ttcol>
|
||||
<ttcol>Description</ttcol>
|
||||
|
||||
<c>end_of_recs</c>
|
||||
<c>0</c>
|
||||
<c>0</c>
|
||||
<c>End of records</c>
|
||||
|
||||
<c>ip4_rec</c>
|
||||
<c>1</c>
|
||||
<c>Variable</c>
|
||||
<c>Specifies an IPv4 address (contained in the first 4 bytes), followed by one or more zero-terminated strings containing the DNS entries for that address.</c>
|
||||
|
||||
<c>ip6_rec</c>
|
||||
<c>1</c>
|
||||
<c>Variable</c>
|
||||
<c>Specifies an IPv6 address (contained in the first 16 bytes), followed by one or more zero-terminated strings containing the DNS entries for that address.</c>
|
||||
</texttable>
|
||||
|
||||
<t>After the list or Name Resolution Records, optionally, a list of options (formatted according to the rules defined in <xref target="sectionopt"/>) can be present.</t>
|
||||
|
||||
<t>A Name Resolution Block is normally placed at the beginning of the file, but no assumptions can be taken about its position. Name Resolution Blocks can be added in a second time by tools that process the file, like network analyzers.</t>
|
||||
|
||||
<t>In addiction to the options defined in <xref target="sectionopt"/>, the following options are valid within this block:</t>
|
||||
|
||||
<texttable>
|
||||
<ttcol>Name</ttcol>
|
||||
<ttcol>Code</ttcol>
|
||||
<ttcol>Length</ttcol>
|
||||
<ttcol>Description</ttcol>
|
||||
|
||||
<c>ns_dnsname</c>
|
||||
<c>2</c>
|
||||
<c>Variable</c>
|
||||
<c>An ascii string containing the name of the machine (DNS server) used to perform the name resolution.</c>
|
||||
</texttable>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
<section title="Interface Statistics Block (optional)">
|
||||
<t>The Interface Statistics Block contains the capture statistics for a given interface and it is optional. The statistics are referred to the interface defined in the current Section identified by the Interface ID field.</t>
|
||||
<t>The format of the Interface Statistics Block is shown in <xref target="formatisb"/>.</t>
|
||||
|
||||
<figure anchor="formatisb" title="Interface Statistics Block format.">
|
||||
<artwork>
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| IfRecv |
|
||||
| (high + low) |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| IfDrop |
|
||||
| (high + low) |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| FilterAccept |
|
||||
| (high + low) |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| OSDrop |
|
||||
| (high + low) |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| UsrDelivered |
|
||||
| (high + low) |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Interface ID | Reserved |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
/ /
|
||||
/ Options (variable) /
|
||||
/ /
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
</artwork>
|
||||
</figure>
|
||||
|
||||
<t>The fields have the following meaning:</t>
|
||||
|
||||
<list style="symbols">
|
||||
<t>IfRecv: number of packets received from the interface during the capture. This number is reported as a 64 bits value, in which the most significat bits are located in the first four bytes of the field.</t>
|
||||
<t>IfDrop: number of packets dropped by the interface during the capture due to lack of resources.</t>
|
||||
<t>FilterAccept: number of packets accepeted by filter during current capture.</t>
|
||||
<t>OSDrop: number of packets dropped by the operating system during the capture.</t>
|
||||
<t>UsrDelivered: number of packets delivered to the user. UsrDelivered can be different from the value 'FilterAccept - OSDropped' because some packets could still lay in the OS buffers when the capture ended.</t>
|
||||
<t>Interface ID: reference to an Interface Description Block.</t>
|
||||
<t>Reserved: Reserved to future use.</t>
|
||||
<t>Options: optionally, a list of options (formatted according to the rules defined in <xref target="sectionopt"/>) can be present.</t>
|
||||
</list>
|
||||
|
||||
<t>In addiction to the options defined in <xref target="sectionopt"/>, the following options are valid within this block:</t>
|
||||
|
||||
<texttable>
|
||||
<ttcol>Name</ttcol>
|
||||
<ttcol>Code</ttcol>
|
||||
<ttcol>Length</ttcol>
|
||||
<ttcol>Description</ttcol>
|
||||
|
||||
<c>isb_starttime</c>
|
||||
<c>2</c>
|
||||
<c>8</c>
|
||||
<c>Time in which the capture started; time will be stored in two blocks of four bytes each, containing the timestamp in seconds and nanoseconds.</c>
|
||||
|
||||
<c>isb_endtime</c>
|
||||
<c>3</c>
|
||||
<c>8</c>
|
||||
<c>Time in which the capture started; time will be stored in two blocks of four bytes each, containing the timestamp in seconds and nanoseconds.</c>
|
||||
</texttable>
|
||||
|
||||
</section>
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
<section anchor="sectionopt" title="Options">
|
||||
<t>Almost all blocks have the possibility to embed optional fields. Optional fields can be used to insert some information that may be useful when reading data, but that it is not really needed for packet processing. Therefore, each tool can be either read the content of the optional fields (if any), or skip them at once.</t>
|
||||
<t>Skipping all the optional fields at once is straightforward because most of the blocks have a fixed length, therefore the field Block Length (present in the General Block Structure, see <xref target="sectionblock"/>) can be used to skip everything till the next block.</t>
|
||||
|
||||
<t>Options are a list of Type - Length - Value fields, each one containing a single value:</t>
|
||||
|
||||
<list style="symbols">
|
||||
<t>Option Type (2 bytes): it contains the code that specifies the type of the current TLV record. Option types whose Most Significant Bit is equal to one are reserved for local use; therefore, there is no guarantee that the code used is unique among all capture files (generated by other applications). In case of vendor-specific extensions that have to be identified uniquely, vendors must request an Option Code whose MSB is equal to zero.</t>
|
||||
<t>Option Length (2 bytes): it contains the length of the following 'Option Value' field.</t>
|
||||
<t>Option Value (variable length): it contains the value of the given option. The length of this field as been specified by the Option Length field.</t>
|
||||
</list>
|
||||
|
||||
<t>Options may be repeated several times (e.g. an interface that has several IP addresses associated to it). The option list is terminated by a special code which is the 'End of Option'.</t>
|
||||
|
||||
<t>The format of the optional fields is shown in <xref target="formatopt"/>.</t>
|
||||
|
||||
<figure anchor="formatopt" title="Options format.">
|
||||
<artwork>
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Option Code | Option Length |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Option Value |
|
||||
| /* variable length, byte-aligned */ |
|
||||
| + + + + + + + + + + + + + + + + + + + + + + + + +
|
||||
| / / / |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
/ /
|
||||
/ . . . other options . . . /
|
||||
/ /
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Option Code == opt_endofopt | Option Length == 0 |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
</artwork>
|
||||
</figure>
|
||||
|
||||
<t>The following codes can always be present in any optional field:</t>
|
||||
|
||||
<texttable>
|
||||
<ttcol>Name</ttcol>
|
||||
<ttcol>Code</ttcol>
|
||||
<ttcol>Length</ttcol>
|
||||
<ttcol>Description</ttcol>
|
||||
|
||||
<c>opt_endofopt</c>
|
||||
<c>0</c>
|
||||
<c>0</c>
|
||||
<c>End of options: it is used to delimit the end of the optional fields. This block cannot be repeated within a given list of options.</c>
|
||||
|
||||
<c>opt_comment</c>
|
||||
<c>1</c>
|
||||
<c>variable</c>
|
||||
<c>Comment: it is an ascii string containing a comment that is associated to the current block.</c>
|
||||
</texttable>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
|
||||
<section title="Experimental Blocks (deserved to a further investigation)">
|
||||
|
||||
<section title="Other Packet Blocks (experimental)">
|
||||
<t>Can some other packet blocks (besides the two described in the previous paragraphs) be useful?</t>
|
||||
</section>
|
||||
|
||||
<section title="Compression Block (experimental)">
|
||||
<t>The Compression Block is optional. A file can contain an arbitrary number of these blocks. A Compression Block, as the name says, is used to store compressed data. Its format is shown in <xref target="formatcb"/>.</t>
|
||||
|
||||
<figure anchor="formatcb" title="Compression Block format.">
|
||||
<artwork>
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Compr. Type | |
|
||||
+-+-+-+-+-+-+-+-+ |
|
||||
| |
|
||||
| Compressed Data |
|
||||
| |
|
||||
| /* variable length, byte-aligned */ |
|
||||
| |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
</artwork>
|
||||
</figure>
|
||||
|
||||
<t>The fields have the following meaning:</t>
|
||||
|
||||
<list style="symbols">
|
||||
<t>Compression Type: specifies the compression algorithm. Possible values for this field are 0 (uncompressed), 1 (Lempel Ziv), 2 (Gzip), other?? Probably some kind of dumb and fast compression algorithm could be effective with some types of traffic (for example web), but which?</t>
|
||||
<t>Compressed Data: data of this block. Once decompressed, it is made of other blocks.</t>
|
||||
</list>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
<section title="Encryption Block (experimental)">
|
||||
<t>The Encryption Block is optional. A file can contain an arbitrary number of these blocks. An Encryption Block is used to sotre encrypted data. Its format is shown in <xref target="formateb"/>.</t>
|
||||
|
||||
<figure anchor="formateb" title="Encryption Block format.">
|
||||
<artwork>
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Encr. Type | |
|
||||
+-+-+-+-+-+-+-+-+ |
|
||||
| |
|
||||
| Compressed Data |
|
||||
| |
|
||||
| /* variable length, byte-aligned */ |
|
||||
| |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
</artwork>
|
||||
</figure>
|
||||
|
||||
<t>The fields have the following meaning:</t>
|
||||
<list style="symbols">
|
||||
<t>Compression Type: specifies the encryption algorithm. Possible values for this field are ??? NOTE: this block should probably contain other fields, depending on the encryption algorithm. To be define precisely.</t>
|
||||
<t>Encrypted Data: data of this block. Once decripted, it consists of other blocks.</t>
|
||||
</list>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
<section title="Fixed Length Block (experimental)">
|
||||
<t>The Fixed Length Block is optional. A file can contain an arbitrary number of these blocks. A Fixed Length Block can be used to optimize the access to the file. Its format is shown in <xref target="formatflm"/>.
|
||||
A Fixed Length Block stores records with constant size. It contains a set of Blocks (normally Packet Blocks or Simple Packet Blocks), of wihich it specifies the size. Knowing this size a priori helps to scan the file and to load some portions of it without truncating a block, and is particularly useful with cell-based networks like ATM.</t>
|
||||
|
||||
<figure anchor="formatflm" title="Fixed Length Block format.">
|
||||
<artwork>
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Cell Size | |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
|
||||
| |
|
||||
| Fixed Size Data |
|
||||
| |
|
||||
| /* variable length, byte-aligned */ |
|
||||
| |
|
||||
| |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
</artwork>
|
||||
</figure>
|
||||
|
||||
<t>The fields have the following meaning:</t>
|
||||
<list style="symbols">
|
||||
<t>Cell size: the size of the blocks contained in the data field.</t>
|
||||
<t>Fixed Size Data: data of this block.</t>
|
||||
</list>
|
||||
|
||||
</section>
|
||||
|
||||
<section title="Directory Block (experimental)">
|
||||
<t>If present, this block contains the following information:</t>
|
||||
<list style="symbols">
|
||||
<t>number of indexed packets (N)</t>
|
||||
<t>table with position and length of any indexed packet (N entries)</t>
|
||||
</list>
|
||||
|
||||
<t>A directory block must be followed by at least N packets, otherwise it must be considered invalid. It can be used to efficiently load portions of the file to memory and to support operations on memory mapped files. This block can be added by tools like network analyzers as a consequence of file processing.</t>
|
||||
</section>
|
||||
|
||||
<section title="Traffic Statistics and Monitoring Blocks (experimental)">
|
||||
<t>One or more blocks could be defined to contain network statistics or traffic monitoring information. They could be use to store data collected from RMON or Netflow probes, or from other network monitoring tools.</t>
|
||||
</section>
|
||||
|
||||
<section title="Event/Security Block (experimental)">
|
||||
<t>This block could be used to store events. Events could contain generic information (for example network load over 50%, server down...) or security alerts. An event could be:</t>
|
||||
|
||||
<list style="symbols">
|
||||
<t>skipped, if the application doesn't know how to do with it</t>
|
||||
<t>processed independently by the packets. In other words, the applications skips the packets and processes only the alerts</t>
|
||||
<t>processed in relation to packets: for example, a security tool could load only the packets of the file that are near a security alert; a monitorg tool could skip the packets captured while the server was down.</t>
|
||||
</list>
|
||||
|
||||
</section>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
|
||||
<section title="Conclusions">
|
||||
<t>The file format proposed in this document should be very versatile and satisfy a wide range of applications.
|
||||
In the simplest case, it can contain a raw dump of the network data, made of a series of Simple Packet Blocks.
|
||||
In the most complex case, it can be used as a repository for heterogeneous information.
|
||||
In every case, the file remains easy to parse and an application can always skip the data it is not interested in; at the same time, different applications can share the file, and each of them can benfit of the information produced by the others.
|
||||
Two or more files can be concatenated obtaining another valid file.</t>
|
||||
</section>
|
||||
|
||||
|
||||
<section title="Most important open issues">
|
||||
<list style="symbols">
|
||||
<t>Data, in the file, must be byte or word aligned? Currently, the structure of this document is not consistent with respect to this point.</t>
|
||||
</list>
|
||||
</section>
|
||||
|
||||
</middle>
|
||||
|
||||
</rfc>
|
||||
@@ -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
|
||||
|
||||
@@ -47,9 +47,11 @@ static const char rcsid[] _U_ =
|
||||
|
||||
#include <net/if.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ifaddrs.h>
|
||||
|
||||
#include "pcap-int.h"
|
||||
@@ -58,6 +60,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 +107,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));
|
||||
}
|
||||
@@ -128,6 +139,7 @@ pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
|
||||
struct sockaddr *addr, *netmask, *broadaddr, *dstaddr;
|
||||
size_t addr_size, broadaddr_size, dstaddr_size;
|
||||
int ret = 0;
|
||||
char *p, *q;
|
||||
|
||||
/*
|
||||
* Get the list of interface addresses.
|
||||
@@ -205,6 +217,35 @@ pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
|
||||
dstaddr_size = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* If this entry has a colon followed by a number at
|
||||
* the end, we assume it's a logical interface. Those
|
||||
* are just the way you assign multiple IP addresses to
|
||||
* a real interface on Linux, 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.
|
||||
*
|
||||
* XXX - should we do this only on Linux?
|
||||
*/
|
||||
p = strchr(ifa->ifa_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';
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Add information for this address to the list.
|
||||
*/
|
||||
|
||||
@@ -102,6 +102,27 @@ struct rtentry; /* declarations in <net/if.h> */
|
||||
#endif /* HAVE_SOCKADDR_SA_LEN */
|
||||
#endif /* SA_LEN */
|
||||
|
||||
/*
|
||||
* This is also fun.
|
||||
*
|
||||
* There is no ioctl that returns the amount of space required for all
|
||||
* the data that SIOCGIFCONF could return, and if a buffer is supplied
|
||||
* that's not large enough for all the data SIOCGIFCONF could return,
|
||||
* on at least some platforms it just returns the data that'd fit with
|
||||
* no indication that there wasn't enough room for all the data, much
|
||||
* less an indication of how much more room is required.
|
||||
*
|
||||
* The only way to ensure that we got all the data is to pass a buffer
|
||||
* large enough that the amount of space in the buffer *not* filled in
|
||||
* is greater than the largest possible entry.
|
||||
*
|
||||
* We assume that's "sizeof(ifreq.ifr_name)" plus 255, under the assumption
|
||||
* that no address is more than 255 bytes (on systems where the "sa_len"
|
||||
* field in a "struct sockaddr" is 1 byte, e.g. newer BSDs, that's the
|
||||
* case, and addresses are unlikely to be bigger than that in any case).
|
||||
*/
|
||||
#define MAX_SA_LEN 255
|
||||
|
||||
#ifdef HAVE_PROC_NET_DEV
|
||||
/*
|
||||
* Get from "/proc/net/dev" all interfaces listed there; if they're
|
||||
@@ -255,6 +276,9 @@ pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
|
||||
struct ifconf ifc;
|
||||
char *buf = NULL;
|
||||
unsigned buf_size;
|
||||
#if defined (HAVE_SOLARIS) || defined (HAVE_HPUX10_20_OR_LATER)
|
||||
char *p, *q;
|
||||
#endif
|
||||
struct ifreq ifrflags, ifrnetmask, ifrbroadaddr, ifrdstaddr;
|
||||
struct sockaddr *netmask, *broadaddr, *dstaddr;
|
||||
size_t netmask_size, broadaddr_size, dstaddr_size;
|
||||
@@ -272,9 +296,10 @@ pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
|
||||
|
||||
/*
|
||||
* Start with an 8K buffer, and keep growing the buffer until
|
||||
* we get the entire interface list or fail to get it for some
|
||||
* reason other than EINVAL (which is presumed here to mean
|
||||
* "buffer is too small").
|
||||
* we have more than "sizeof(ifrp->ifr_name) + MAX_SA_LEN"
|
||||
* bytes left over in the buffer or we fail to get the
|
||||
* interface list for some reason other than EINVAL (which is
|
||||
* presumed here to mean "buffer is too small").
|
||||
*/
|
||||
buf_size = 8192;
|
||||
for (;;) {
|
||||
@@ -297,7 +322,8 @@ pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
|
||||
free(buf);
|
||||
return (-1);
|
||||
}
|
||||
if (ifc.ifc_len < buf_size)
|
||||
if (ifc.ifc_len < buf_size &&
|
||||
(buf_size - ifc.ifc_len) > sizeof(ifrp->ifr_name) + MAX_SA_LEN)
|
||||
break;
|
||||
free(buf);
|
||||
buf_size *= 2;
|
||||
@@ -323,6 +349,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 +497,34 @@ pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
|
||||
dstaddr_size = 0;
|
||||
}
|
||||
|
||||
#if defined (HAVE_SOLARIS) || defined (HAVE_HPUX10_20_OR_LATER)
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
@@ -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->lifr_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.
|
||||
*/
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -264,8 +279,7 @@ pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
|
||||
/*
|
||||
* Add an entry for this interface.
|
||||
*/
|
||||
if (pcap_add_if_win32(&devlist, name, desc,
|
||||
errbuf) == -1) {
|
||||
if (pcap_add_if_win32(&devlist, name, desc, errbuf) == -1) {
|
||||
/*
|
||||
* Failure.
|
||||
*/
|
||||
@@ -287,5 +301,6 @@ pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
|
||||
}
|
||||
|
||||
*alldevsp = devlist;
|
||||
free(AdaptersName);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -55,6 +55,10 @@
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef HAVE___ATTRIBUTE__
|
||||
#define __attribute__(x)
|
||||
#endif /* HAVE___ATTRIBUTE__ */
|
||||
|
||||
/* Address qualifiers. */
|
||||
|
||||
#define Q_HOST 1
|
||||
@@ -63,6 +67,7 @@
|
||||
#define Q_GATEWAY 4
|
||||
#define Q_PROTO 5
|
||||
#define Q_PROTOCHAIN 6
|
||||
#define Q_PORTRANGE 7
|
||||
|
||||
/* Protocol qualifiers. */
|
||||
|
||||
@@ -119,6 +124,8 @@
|
||||
#define Q_ISIS_PSNP 38
|
||||
#define Q_ISIS_LSP 39
|
||||
|
||||
#define Q_RADIO 40
|
||||
|
||||
/* Directional qualifiers. */
|
||||
|
||||
#define Q_SRC 1
|
||||
@@ -166,6 +173,13 @@
|
||||
end-to-end circuits, ILMI circuits or
|
||||
connection signalling circuit. */
|
||||
|
||||
/*MTP3 field types */
|
||||
#define M_SIO 1
|
||||
#define M_OPC 2
|
||||
#define M_DPC 3
|
||||
#define M_SLS 4
|
||||
|
||||
|
||||
struct slist;
|
||||
|
||||
struct stmt {
|
||||
@@ -273,11 +287,14 @@ 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_atmfield_code(int atmfield, bpf_int32 jvalue, bpf_u_int32 jtype, int reverse);
|
||||
struct block *gen_atmtype_abbrev(int type);
|
||||
struct block *gen_atmmulti_abbrev(int type);
|
||||
|
||||
struct block *gen_mtp3field_code(int mtp3field, bpf_u_int32 jvalue, bpf_u_int32 jtype, int reverse);
|
||||
|
||||
struct block *gen_pf_ifname(const char *);
|
||||
struct block *gen_pf_rnr(int);
|
||||
struct block *gen_pf_srnr(int);
|
||||
@@ -288,10 +305,7 @@ struct block *gen_pf_dir(int);
|
||||
|
||||
void bpf_optimize(struct block **);
|
||||
void bpf_error(const char *, ...)
|
||||
#if HAVE___ATTRIBUTE__
|
||||
__attribute__((noreturn, format (printf, 1, 2)))
|
||||
#endif
|
||||
;
|
||||
__attribute__((noreturn, format (printf, 1, 2)));
|
||||
|
||||
void finish_parse(struct block *);
|
||||
char *sdup(const char *);
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -99,6 +97,7 @@ pcap_parse()
|
||||
struct {
|
||||
struct qual q;
|
||||
int atmfieldtype;
|
||||
int mtp3fieldtype;
|
||||
struct block *b;
|
||||
} blk;
|
||||
struct block *rblk;
|
||||
@@ -114,9 +113,12 @@ pcap_parse()
|
||||
%type <i> atmtype atmmultitype
|
||||
%type <blk> atmfield
|
||||
%type <blk> atmfieldvalue atmvalue atmlistvalue
|
||||
%type <blk> mtp3field
|
||||
%type <blk> mtp3fieldvalue mtp3value mtp3listvalue
|
||||
|
||||
|
||||
%token DST SRC HOST GATEWAY
|
||||
%token NET NETMASK PORT LESS GREATER PROTO PROTOCHAIN CBYTE
|
||||
%token NET NETMASK PORT PORTRANGE LESS GREATER PROTO PROTOCHAIN CBYTE
|
||||
%token ARP RARP IP SCTP TCP UDP ICMP IGMP IGRP PIM VRRP
|
||||
%token ATALK AARP DECNET LAT SCA MOPRC MOPDL
|
||||
%token TK_BROADCAST TK_MULTICAST
|
||||
@@ -128,7 +130,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
|
||||
@@ -136,6 +138,8 @@ pcap_parse()
|
||||
%token LANE LLC METAC BCC SC ILMIC OAMF4EC OAMF4SC
|
||||
%token OAM OAMF4 CONNECTMSG METACONNECT
|
||||
%token VPI VCI
|
||||
%token RADIO
|
||||
%token SIO OPC DPC SLS
|
||||
|
||||
%type <s> ID
|
||||
%type <e> EID
|
||||
@@ -256,6 +260,7 @@ rterm: head id { $$ = $2; }
|
||||
| atmtype { $$.b = gen_atmtype_abbrev($1); $$.q = qerr; }
|
||||
| atmmultitype { $$.b = gen_atmmulti_abbrev($1); $$.q = qerr; }
|
||||
| atmfield atmvalue { $$.b = $2.b; $$.q = qerr; }
|
||||
| mtp3field mtp3value { $$.b = $2.b; $$.q = qerr; }
|
||||
;
|
||||
/* protocol level qualifiers */
|
||||
pqual: pname
|
||||
@@ -273,6 +278,7 @@ dqual: SRC { $$ = Q_SRC; }
|
||||
aqual: HOST { $$ = Q_HOST; }
|
||||
| NET { $$ = Q_NET; }
|
||||
| PORT { $$ = Q_PORT; }
|
||||
| PORTRANGE { $$ = Q_PORTRANGE; }
|
||||
;
|
||||
/* non-directional address type qualifiers */
|
||||
ndaqual: GATEWAY { $$ = Q_GATEWAY; }
|
||||
@@ -314,6 +320,7 @@ pname: LINK { $$ = Q_LINK; }
|
||||
| STP { $$ = Q_STP; }
|
||||
| IPX { $$ = Q_IPX; }
|
||||
| NETBEUI { $$ = Q_NETBEUI; }
|
||||
| RADIO { $$ = Q_RADIO; }
|
||||
;
|
||||
other: pqual TK_BROADCAST { $$ = gen_broadcast($1); }
|
||||
| pqual TK_MULTICAST { $$ = gen_multicast($1); }
|
||||
@@ -324,6 +331,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; }
|
||||
;
|
||||
|
||||
@@ -413,18 +422,41 @@ atmfield: VPI { $$.atmfieldtype = A_VPI; }
|
||||
| VCI { $$.atmfieldtype = A_VCI; }
|
||||
;
|
||||
atmvalue: atmfieldvalue
|
||||
| relop NUM { $$.b = gen_atmfield_code($<blk>0.atmfieldtype, (u_int)$2, (u_int)$1, 0); }
|
||||
| irelop NUM { $$.b = gen_atmfield_code($<blk>0.atmfieldtype, (u_int)$2, (u_int)$1, 1); }
|
||||
| relop NUM { $$.b = gen_atmfield_code($<blk>0.atmfieldtype, (bpf_int32)$2, (bpf_u_int32)$1, 0); }
|
||||
| irelop NUM { $$.b = gen_atmfield_code($<blk>0.atmfieldtype, (bpf_int32)$2, (bpf_u_int32)$1, 1); }
|
||||
| paren atmlistvalue ')' { $$.b = $2.b; $$.q = qerr; }
|
||||
;
|
||||
atmfieldvalue: NUM {
|
||||
$$.atmfieldtype = $<blk>0.atmfieldtype;
|
||||
if ($$.atmfieldtype == A_VPI ||
|
||||
$$.atmfieldtype == A_VCI)
|
||||
$$.b = gen_atmfield_code($$.atmfieldtype, (u_int) $1, BPF_JEQ, 0);
|
||||
$$.b = gen_atmfield_code($$.atmfieldtype, (bpf_int32) $1, BPF_JEQ, 0);
|
||||
}
|
||||
;
|
||||
atmlistvalue: atmfieldvalue
|
||||
| atmlistvalue or atmfieldvalue { gen_or($1.b, $3.b); $$ = $3; }
|
||||
;
|
||||
/* MTP3 field types quantifier */
|
||||
mtp3field: SIO { $$.mtp3fieldtype = M_SIO; }
|
||||
| OPC { $$.mtp3fieldtype = M_OPC; }
|
||||
| DPC { $$.mtp3fieldtype = M_DPC; }
|
||||
| SLS { $$.mtp3fieldtype = M_SLS; }
|
||||
;
|
||||
mtp3value: mtp3fieldvalue
|
||||
| relop NUM { $$.b = gen_mtp3field_code($<blk>0.mtp3fieldtype, (u_int)$2, (u_int)$1, 0); }
|
||||
| irelop NUM { $$.b = gen_mtp3field_code($<blk>0.mtp3fieldtype, (u_int)$2, (u_int)$1, 1); }
|
||||
| paren mtp3listvalue ')' { $$.b = $2.b; $$.q = qerr; }
|
||||
;
|
||||
mtp3fieldvalue: NUM {
|
||||
$$.mtp3fieldtype = $<blk>0.mtp3fieldtype;
|
||||
if ($$.mtp3fieldtype == M_SIO ||
|
||||
$$.mtp3fieldtype == M_OPC ||
|
||||
$$.mtp3fieldtype == M_DPC ||
|
||||
$$.mtp3fieldtype == M_SLS )
|
||||
$$.b = gen_mtp3field_code($$.mtp3fieldtype, (u_int) $1, BPF_JEQ, 0);
|
||||
}
|
||||
;
|
||||
mtp3listvalue: mtp3fieldvalue
|
||||
| mtp3listvalue or mtp3fieldvalue { gen_or($1.b, $3.b); $$ = $3; }
|
||||
;
|
||||
%%
|
||||
|
||||
@@ -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
|
||||
@@ -517,6 +538,9 @@ pcap_lookupnet(device, netp, maskp, errbuf)
|
||||
if (!device || strcmp(device, "any") == 0
|
||||
#ifdef HAVE_DAG_API
|
||||
|| strstr(device, "dag") != NULL
|
||||
#endif
|
||||
#ifdef HAVE_SEPTEL_API
|
||||
|| strstr(device, "septel") != NULL
|
||||
#endif
|
||||
) {
|
||||
*netp = *maskp = 0;
|
||||
@@ -574,7 +598,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 +621,10 @@ pcap_lookupdev(errbuf)
|
||||
ULONG NameLength = 8192;
|
||||
static char AdaptersName[8192];
|
||||
|
||||
PacketGetAdapterNames(AdaptersName,&NameLength);
|
||||
|
||||
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 +642,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 +679,7 @@ pcap_lookupdev(errbuf)
|
||||
tAstr += strlen(tAstr) + 1;
|
||||
}
|
||||
|
||||
free(TAdaptersName);
|
||||
return (char *)(AdaptersName);
|
||||
}
|
||||
}
|
||||
@@ -653,7 +687,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 +724,4 @@ pcap_lookupnet(device, netp, maskp, errbuf)
|
||||
return (0);
|
||||
}
|
||||
|
||||
#endif /* WIN32 */
|
||||
#endif /* !WIN32 && !MSDOS */
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
/* $Id: snprintf.c,v 1.1 2004/04/05 22:43:51 guy Exp $ */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
@@ -39,7 +39,7 @@
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid[] _U_ =
|
||||
"@(#) $Header$";
|
||||
"@(#) $Header: /tcpdump/master/libpcap/missing/snprintf.c,v 1.1 2004/04/05 22:43:51 guy Exp $";
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
43
libpcap-possiblymodified/msdos/bin2c.c
Normal file
43
libpcap-possiblymodified/msdos/bin2c.c
Normal file
@@ -0,0 +1,43 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <time.h>
|
||||
|
||||
static void Abort (char *fmt,...)
|
||||
{
|
||||
va_list args;
|
||||
va_start (args, fmt);
|
||||
vfprintf (stderr, fmt, args);
|
||||
va_end (args);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
FILE *inFile;
|
||||
FILE *outFile = stdout;
|
||||
time_t now = time (NULL);
|
||||
int ch, i;
|
||||
|
||||
if (argc != 2)
|
||||
Abort ("Usage: %s bin-file [> result]", argv[0]);
|
||||
|
||||
if ((inFile = fopen(argv[1],"rb")) == NULL)
|
||||
Abort ("Cannot open %s\n", argv[1]);
|
||||
|
||||
fprintf (outFile,
|
||||
"/* data statements for file %s at %.24s */\n"
|
||||
"/* Generated by BIN2C, G.Vanem 1995 */\n",
|
||||
argv[1], ctime(&now));
|
||||
|
||||
i = 0;
|
||||
while ((ch = fgetc(inFile)) != EOF)
|
||||
{
|
||||
if (i++ % 12 == 0)
|
||||
fputs ("\n ", outFile);
|
||||
fprintf (outFile, "0x%02X,", ch);
|
||||
}
|
||||
fputc ('\n', outFile);
|
||||
fclose (inFile);
|
||||
return (0);
|
||||
}
|
||||
80
libpcap-possiblymodified/msdos/common.dj
Normal file
80
libpcap-possiblymodified/msdos/common.dj
Normal file
@@ -0,0 +1,80 @@
|
||||
#
|
||||
# Common defines for libpcap and 16/32-bit network drivers (djgpp)
|
||||
#
|
||||
# @(#) $Header: /tcpdump/master/libpcap/msdos/common.dj,v 1.2 2004/12/19 19:36:33 guy Exp $ (LBL)
|
||||
|
||||
.SUFFIXES: .exe .wlm .dxe .l .y
|
||||
.PHONY: check_gcclib
|
||||
|
||||
default: check_gcclib all
|
||||
|
||||
GCCLIB = /djgpp/lib/gcc-lib/djgpp/3.31
|
||||
MAKEFILE = Makefile.dj
|
||||
|
||||
#
|
||||
# DLX 2.91+ lib. Change path to suite.
|
||||
# Not used anymore. Uses DXE3 now.
|
||||
#
|
||||
# DLX_LIB = $(DJDIR)/contrib/dlx.291/libdlx.a
|
||||
# DLX_LINK = $(DJDIR)/bin/dlxgen.exe
|
||||
|
||||
WATT32_ROOT = $(subst \,/,$(WATT_ROOT))
|
||||
|
||||
|
||||
ifeq ($(wildcard $(GCCLIB)/libgcc.a),)
|
||||
check_gcclib:
|
||||
@echo libgcc.a not found. Set \"$(GCCLIB)\" to \"/djgpp/lib/gcc-lib/djgpp/3.X\"
|
||||
endif
|
||||
|
||||
|
||||
#
|
||||
# Include 32-bit driver support
|
||||
#
|
||||
USE_32BIT_DRIVERS = 0
|
||||
|
||||
#
|
||||
# Use loadable driver modules instead of statically linking
|
||||
# all drivers.
|
||||
#
|
||||
USE_32BIT_MODULES = 0
|
||||
|
||||
#
|
||||
# Put interrupt sensitive code/data in locked sections
|
||||
# Do `make clean' in all affected directories after changing this.
|
||||
#
|
||||
USE_SECTION_LOCKING = 0
|
||||
|
||||
#
|
||||
# Set to 1 to use exception handler lib (only for me)
|
||||
#
|
||||
USE_EXCEPT = 0
|
||||
|
||||
CC = gcc.exe
|
||||
LD = ld.exe
|
||||
ASM = nasm.exe -fbin -dDEBUG
|
||||
YACC = bison.exe
|
||||
LEX = flex.exe
|
||||
|
||||
CFLAGS = -g -gcoff -O2 -Wall -I. -I$(WATT32_ROOT)/inc
|
||||
|
||||
ifeq ($(USE_EXCEPT),1)
|
||||
CFLAGS += -DUSE_EXCEPT
|
||||
EXC_LIB = d:/prog/mw/except/lib/libexc.a
|
||||
endif
|
||||
|
||||
ifeq ($(USE_SECTION_LOCKING),1)
|
||||
CFLAGS += -DUSE_SECTION_LOCKING
|
||||
endif
|
||||
|
||||
ifeq ($(USE_32BIT_DRIVERS),1)
|
||||
CFLAGS += -DUSE_32BIT_DRIVERS
|
||||
endif
|
||||
|
||||
%.o: %.c
|
||||
$(CC) -c $(CFLAGS) $<
|
||||
@echo
|
||||
|
||||
%.o: %.s
|
||||
$(CC) -c $(CFLAGS) -x assembler-with-cpp -o $@ $<
|
||||
@echo
|
||||
|
||||
184
libpcap-possiblymodified/msdos/makefile
Normal file
184
libpcap-possiblymodified/msdos/makefile
Normal file
@@ -0,0 +1,184 @@
|
||||
#
|
||||
# Makefile for dos-libpcap. NB. This makefile requires a Borland
|
||||
# compatible make tool.
|
||||
#
|
||||
# Targets:
|
||||
# Borland C 4.0+ (DOS large model)
|
||||
# Metaware HighC 3.3+ (PharLap 386|DosX)
|
||||
#
|
||||
|
||||
.AUTODEPEND
|
||||
.SWAP
|
||||
|
||||
!if "$(WATT_ROOT)" == ""
|
||||
!error Environment variable "WATT_ROOT" not set.
|
||||
!endif
|
||||
|
||||
WATT_INC = $(WATT_ROOT)\inc
|
||||
|
||||
DEFS = -DMSDOS -DDEBUG -DNDIS_DEBUG -D_U_= -Dinline= \
|
||||
-DHAVE_STRERROR -DHAVE_LIMITS_H
|
||||
|
||||
ASM = tasm.exe -t -l -mx -m2 -DDEBUG
|
||||
|
||||
SOURCE = grammar.c scanner.c bpf_filt.c bpf_imag.c bpf_dump.c \
|
||||
etherent.c gencode.c nametoad.c pcap-dos.c optimize.c \
|
||||
savefile.c pcap.c inet.c msdos\ndis2.c msdos\pktdrvr.c \
|
||||
missing\snprintf.c
|
||||
|
||||
BORLAND_OBJ = $(SOURCE:.c=.obj) msdos\pkt_rx0.obj msdos\ndis_0.obj
|
||||
|
||||
HIGHC_OBJ = $(SOURCE:.c=.o32) msdos\pkt_rx0.o32
|
||||
|
||||
all:
|
||||
@echo Usage: make pcap_bc.lib or pcap_hc.lib
|
||||
|
||||
|
||||
pcap_bc.lib: bcc.arg $(BORLAND_OBJ) pcap_bc
|
||||
|
||||
|
||||
pcap_hc.lib: hc386.arg $(HIGHC_OBJ)
|
||||
386lib $< @&&|
|
||||
-nowarn -nobackup -twocase -replace $(HIGHC_OBJ)
|
||||
|
|
||||
|
||||
pcap_bc: $(BORLAND_OBJ)
|
||||
@tlib pcap_bc.lib /C @&&|
|
||||
-+$(**:.obj=-+)
|
||||
|
|
||||
|
||||
.c.obj:
|
||||
bcc.exe @bcc.arg -o$*.obj $*.c
|
||||
|
||||
.c.o32:
|
||||
hc386.exe @hc386.arg -o $*.o32 $*.c
|
||||
|
||||
.asm.obj:
|
||||
$(ASM) $*.asm, $*.obj
|
||||
|
||||
.asm.o32:
|
||||
$(ASM) -DDOSX=1 $*.asm, $*.o32
|
||||
|
||||
scanner.c: scanner.l
|
||||
flex -Ppcap_ -7 -oscanner.c scanner.l
|
||||
|
||||
grammar.c tokdefs.h: grammar.y
|
||||
bison --name-prefix=pcap_ --yacc --defines grammar.y
|
||||
- @del grammar.c
|
||||
- @del tokdefs.h
|
||||
ren y_tab.c grammar.c
|
||||
ren y_tab.h tokdefs.h
|
||||
|
||||
bcc.arg: msdos\Makefile
|
||||
@copy &&|
|
||||
$(DEFS) -ml -c -v -3 -O2 -po -RT- -w-
|
||||
-I$(WATT_INC) -I. -I.\msdos\pm_drvr -H=$(TEMP)\bcc.sym
|
||||
| $<
|
||||
|
||||
hc386.arg: msdos\Makefile
|
||||
@copy &&|
|
||||
# -DUSE_32BIT_DRIVERS
|
||||
$(DEFS) -DDOSX=1 -w3 -c -g -O5
|
||||
-I$(WATT_INC) -I. -I.\msdos\pm_drvr
|
||||
-Hsuffix=.o32
|
||||
-Hnocopyr
|
||||
-Hpragma=Offwarn(491,553,572)
|
||||
-Hon=Recognize_library # make memcpy/strlen etc. inline
|
||||
-Hoff=Behaved # turn off some optimiser warnings
|
||||
| $<
|
||||
|
||||
clean:
|
||||
@del *.obj
|
||||
@del *.o32
|
||||
@del *.lst
|
||||
@del *.map
|
||||
@del bcc.arg
|
||||
@del hc386.arg
|
||||
@del grammar.c
|
||||
@del tokdefs.h
|
||||
@del scanner.c
|
||||
@echo Cleaned
|
||||
|
||||
#
|
||||
# dependencies
|
||||
#
|
||||
pkt_rx0.obj: msdos\pkt_rx0.asm
|
||||
|
||||
bpf_filt.obj: bpf_filt.c pcap-int.h pcap.h pcap-bpf.h gnuc.h
|
||||
|
||||
bpf_imag.obj: bpf_imag.c pcap-int.h pcap.h pcap-bpf.h
|
||||
|
||||
bpf_dump.obj: bpf_dump.c pcap.h pcap-bpf.h
|
||||
|
||||
etherent.obj: etherent.c pcap-int.h pcap.h pcap-bpf.h pcap-namedb.h
|
||||
|
||||
optimize.obj: optimize.c pcap-int.h pcap.h pcap-bpf.h gencode.h
|
||||
|
||||
savefile.obj: savefile.c pcap-int.h pcap.h pcap-bpf.h
|
||||
|
||||
pcap.obj: pcap.c pcap-dos.h pcap-int.h pcap.h pcap-bpf.h
|
||||
|
||||
inet.obj: inet.c pcap-int.h pcap.h pcap-bpf.h
|
||||
|
||||
grammar.obj: grammar.c pcap-int.h pcap.h pcap-bpf.h gencode.h \
|
||||
pf.h pcap-namedb.h
|
||||
|
||||
scanner.obj: scanner.c pcap-int.h pcap.h pcap-bpf.h gencode.h \
|
||||
pcap-namedb.h tokdefs.h
|
||||
|
||||
gencode.obj: gencode.c pcap-dos.h pcap-int.h pcap.h pcap-bpf.h \
|
||||
ethertype.h nlpid.h llc.h gencode.h atmuni31.h sunatmpos.h ppp.h sll.h \
|
||||
arcnet.h pf.h pcap-namedb.h
|
||||
|
||||
nametoad.obj: nametoad.c pcap-int.h pcap.h pcap-bpf.h gencode.h \
|
||||
pcap-namedb.h ethertype.h
|
||||
|
||||
pcap-dos.obj: pcap-dos.c pcap.h pcap-bpf.h pcap-dos.h pcap-int.h \
|
||||
msdos\pktdrvr.h
|
||||
|
||||
pktdrvr.obj: msdos\pktdrvr.c gnuc.h pcap-dos.h pcap-int.h \
|
||||
pcap.h pcap-bpf.h msdos\pktdrvr.h msdos\pkt_stub.inc
|
||||
|
||||
ndis2.obj: msdos\ndis2.c pcap-dos.h pcap-int.h pcap.h pcap-bpf.h \
|
||||
msdos\ndis2.h
|
||||
|
||||
pkt_rx0.o32: msdos\pkt_rx0.asm
|
||||
|
||||
bpf_filt.o32: bpf_filt.c pcap-int.h pcap.h pcap-bpf.h gnuc.h
|
||||
|
||||
bpf_imag.o32: bpf_imag.c pcap-int.h pcap.h pcap-bpf.h
|
||||
|
||||
bpf_dump.o32: bpf_dump.c pcap.h pcap-bpf.h
|
||||
|
||||
etherent.o32: etherent.c pcap-int.h pcap.h pcap-bpf.h pcap-namedb.h
|
||||
|
||||
optimize.o32: optimize.c pcap-int.h pcap.h pcap-bpf.h gencode.h
|
||||
|
||||
savefile.o32: savefile.c pcap-int.h pcap.h pcap-bpf.h
|
||||
|
||||
pcap.o32: pcap.c pcap-dos.h pcap-int.h pcap.h pcap-bpf.h
|
||||
|
||||
inet.o32: inet.c pcap-int.h pcap.h pcap-bpf.h
|
||||
|
||||
grammar.o32: grammar.c pcap-int.h pcap.h pcap-bpf.h gencode.h \
|
||||
pf.h pcap-namedb.h
|
||||
|
||||
scanner.o32: scanner.c pcap-int.h pcap.h pcap-bpf.h gencode.h \
|
||||
pcap-namedb.h tokdefs.h
|
||||
|
||||
gencode.o32: gencode.c pcap-dos.h pcap-int.h pcap.h pcap-bpf.h \
|
||||
ethertype.h nlpid.h llc.h gencode.h atmuni31.h sunatmpos.h ppp.h sll.h \
|
||||
arcnet.h pf.h pcap-namedb.h
|
||||
|
||||
nametoad.o32: nametoad.c pcap-int.h pcap.h pcap-bpf.h gencode.h \
|
||||
pcap-namedb.h ethertype.h
|
||||
|
||||
pcap-dos.o32: pcap-dos.c pcap.h pcap-bpf.h pcap-dos.h pcap-int.h \
|
||||
msdos\pktdrvr.h
|
||||
|
||||
pktdrvr.o32: msdos\pktdrvr.c gnuc.h pcap-dos.h pcap-int.h \
|
||||
pcap.h pcap-bpf.h msdos\pktdrvr.h msdos\pkt_stub.inc
|
||||
|
||||
ndis2.o32: msdos\ndis2.c pcap-dos.h pcap-int.h pcap.h pcap-bpf.h \
|
||||
msdos\ndis2.h
|
||||
|
||||
152
libpcap-possiblymodified/msdos/makefile.dj
Normal file
152
libpcap-possiblymodified/msdos/makefile.dj
Normal file
@@ -0,0 +1,152 @@
|
||||
#
|
||||
# GNU Makefile for DOS-libpcap. djgpp version.
|
||||
#
|
||||
# Use this makefile from the libpcap root directory.
|
||||
# E.g. like this:
|
||||
#
|
||||
# c:\net\pcap> make -f msdos/makefile.dj
|
||||
#
|
||||
# @(#) $Header: /tcpdump/master/libpcap/msdos/makefile.dj,v 1.2 2004/12/19 19:41:06 guy Exp $ (LBL)
|
||||
|
||||
VPATH = missing msdos
|
||||
|
||||
PREREQUISITES = scanner.c grammar.c tokdefs.h version.h msdos/pkt_stub.inc
|
||||
|
||||
include msdos/common.dj
|
||||
|
||||
DRIVER_DIR = ./msdos/pm_drvr
|
||||
|
||||
CFLAGS += -DDEBUG -DNDIS_DEBUG -DHAVE_LIMITS_H -DHAVE_STRERROR \
|
||||
-D_U_='__attribute__((unused))' -DHAVE_VERSION_H
|
||||
|
||||
# CFLAGS += -Dyylval=pcap_lval -DBDEBUG -DNDEBUG
|
||||
|
||||
SOURCES = grammar.c scanner.c bpf_filt.c bpf_imag.c bpf_dump.c \
|
||||
etherent.c gencode.c nametoad.c pcap-dos.c optimize.c \
|
||||
savefile.c pcap.c inet.c msdos\pktdrvr.c msdos/ndis2.c \
|
||||
missing/snprintf.c
|
||||
|
||||
OBJECTS = $(notdir $(SOURCES:.c=.o))
|
||||
TEMPBIN = tmp.bin
|
||||
|
||||
ifeq ($(USE_32BIT_DRIVERS),1)
|
||||
PM_OBJECTS = $(addprefix $(DRIVER_DIR)/, \
|
||||
printk.o pci.o pci-scan.o bios32.o dma.o irq.o intwrap.o \
|
||||
lock.o kmalloc.o quirks.o timer.o net_init.o)
|
||||
#
|
||||
# Static link of drivers
|
||||
#
|
||||
ifeq ($(USE_32BIT_MODULES),0)
|
||||
PM_OBJECTS += $(addprefix $(DRIVER_DIR)/, \
|
||||
accton.o 8390.o 3c503.o 3c509.o 3c59x.o 3c515.o \
|
||||
3c575_cb.o 3c90x.o ne.o wd.o cs89x0.o rtl8139.o)
|
||||
endif
|
||||
endif
|
||||
|
||||
all: libpcap.a
|
||||
|
||||
ifeq ($(USE_32BIT_DRIVERS),1)
|
||||
$(PM_OBJECTS):
|
||||
$(MAKE) -f Makefile.dj -C $(DRIVER_DIR) $(notdir $@)
|
||||
endif
|
||||
|
||||
libpcap.a: version.h $(OBJECTS) $(PM_OBJECTS)
|
||||
rm -f $@
|
||||
ar rs $@ $^
|
||||
|
||||
msdos/pkt_stub.inc: msdos/bin2c.exe msdos/pkt_rx1.S
|
||||
$(ASM) -o $(TEMPBIN) -lmsdos/pkt_rx1.lst msdos/pkt_rx1.S
|
||||
./msdos/bin2c $(TEMPBIN) > $@
|
||||
rm -f $(TEMPBIN)
|
||||
|
||||
grammar.c tokdefs.h: grammar.y
|
||||
rm -f grammar.c tokdefs.h
|
||||
$(YACC) --name-prefix=pcap_ --yacc --defines grammar.y
|
||||
mv -f y_tab.c grammar.c
|
||||
mv -f y_tab.h tokdefs.h
|
||||
|
||||
version.h: ./VERSION
|
||||
@echo '/* Generated from VERSION. Do not edit */' > $@
|
||||
sed -e 's/.*/static char pcap_version_string[] = "libpcap (&)";/' ./VERSION >> $@
|
||||
|
||||
scanner.c: scanner.l
|
||||
$(LEX) -Ppcap_ -7 -t $^ > $@
|
||||
@echo
|
||||
|
||||
msdos/bin2c.exe: msdos/bin2c.c
|
||||
$(CC) $*.c -o $*.exe
|
||||
|
||||
clean:
|
||||
$(MAKE) -f Makefile.dj -C $(DRIVER_DIR) clean
|
||||
$(MAKE) -f Makefile.dj -C libcpcap clean
|
||||
rm -f $(OBJECTS) msdos/pkt_rx1.lst Makefile.bak $(PREREQUISITES)
|
||||
|
||||
vclean: clean
|
||||
rm -f libpcap.a msdos/bin2c.exe
|
||||
|
||||
#
|
||||
# Generated dependencies; Due to some hacks in gcc 2.95 and djgpp 2.03
|
||||
# we must prevent "$(DJDIR)/bin/../include/sys/version.h" from beeing
|
||||
# included in dependency output (or else this makefile cannot be used on
|
||||
# another machine). We therefore use a special 'specs' file during
|
||||
# pre-processing.
|
||||
#
|
||||
MM_SPECS = specs.tmp
|
||||
MAKEFILE = msdos/Makefile.dj
|
||||
|
||||
depend: $(PREREQUISITES)
|
||||
@echo Generating dependencies..
|
||||
@cp $(MAKEFILE) Makefile.bak
|
||||
@echo "*cpp: %(cpp_cpu) %{posix:-D_POSIX_SOURCE} -remap" > $(MM_SPECS)
|
||||
sed -e "/^# DO NOT DELETE THIS LINE/,$$d" < Makefile.bak > $(MAKEFILE)
|
||||
echo "# DO NOT DELETE THIS LINE" >> $(MAKEFILE)
|
||||
$(CC) -MM -specs=$(MM_SPECS) $(CFLAGS) $(SOURCES) >> $(MAKEFILE)
|
||||
rm -f $(MM_SPECS)
|
||||
|
||||
#
|
||||
# Manually generated dependencies
|
||||
#
|
||||
msdos/pktdrvr.c: msdos/pkt_stub.inc
|
||||
scanner.c: scanner.l
|
||||
grammar.c tokdefs.h: grammar.y
|
||||
grammar.h: grammar.y
|
||||
scanner.l: pcap-int.h pcap-namedb.h gencode.h grammar.h gnuc.h
|
||||
grammar.y: pcap-int.h gencode.h pcap-namedb.h gnuc.h
|
||||
|
||||
#
|
||||
# Automatically generated dependencies
|
||||
#
|
||||
# DO NOT DELETE THIS LINE
|
||||
grammar.o: grammar.c pcap-int.h pcap.h pcap-bpf.h gencode.h pf.h \
|
||||
pcap-namedb.h
|
||||
scanner.o: scanner.c pcap-int.h pcap.h pcap-bpf.h gencode.h pcap-namedb.h \
|
||||
tokdefs.h
|
||||
bpf_filt.o: bpf_filt.c pcap-int.h pcap.h pcap-bpf.h gnuc.h
|
||||
bpf_imag.o: bpf_imag.c pcap-int.h pcap.h pcap-bpf.h
|
||||
bpf_dump.o: bpf_dump.c pcap.h pcap-bpf.h
|
||||
etherent.o: etherent.c pcap-int.h pcap.h pcap-bpf.h pcap-namedb.h
|
||||
gencode.o: gencode.c pcap-dos.h msdos/pm_drvr/lock.h pcap-int.h pcap.h \
|
||||
pcap-bpf.h ethertype.h nlpid.h llc.h gencode.h atmuni31.h sunatmpos.h \
|
||||
ppp.h sll.h arcnet.h pf.h pcap-namedb.h
|
||||
nametoad.o: nametoad.c pcap-int.h pcap.h pcap-bpf.h gencode.h \
|
||||
pcap-namedb.h ethertype.h
|
||||
pcap-dos.o: pcap-dos.c msdos/pm_drvr/pmdrvr.h msdos/pm_drvr/iface.h \
|
||||
msdos/pm_drvr/lock.h msdos/pm_drvr/ioport.h pcap-dos.h pcap-int.h \
|
||||
pcap.h pcap-bpf.h msdos/pm_drvr/kmalloc.h msdos/pm_drvr/bitops.h \
|
||||
msdos/pm_drvr/timer.h msdos/pm_drvr/dma.h msdos/pm_drvr/irq.h \
|
||||
msdos/pm_drvr/printk.h msdos/pm_drvr/pci.h msdos/pm_drvr/bios32.h \
|
||||
msdos/pm_drvr/module.h msdos/pm_drvr/3c501.h msdos/pm_drvr/3c503.h \
|
||||
msdos/pm_drvr/3c509.h msdos/pm_drvr/3c59x.h msdos/pm_drvr/3c515.h \
|
||||
msdos/pm_drvr/3c90x.h msdos/pm_drvr/3c575_cb.h msdos/pm_drvr/ne.h \
|
||||
msdos/pm_drvr/wd.h msdos/pm_drvr/accton.h msdos/pm_drvr/cs89x0.h \
|
||||
msdos/pm_drvr/rtl8139.h msdos/pm_drvr/ne2k-pci.h msdos/pktdrvr.h
|
||||
optimize.o: optimize.c pcap-int.h pcap.h pcap-bpf.h gencode.h
|
||||
savefile.o: savefile.c pcap-int.h pcap.h pcap-bpf.h
|
||||
pcap.o: pcap.c pcap-dos.h msdos/pm_drvr/lock.h pcap-int.h pcap.h \
|
||||
pcap-bpf.h
|
||||
inet.o: inet.c pcap-int.h pcap.h pcap-bpf.h
|
||||
pktdrvr.o: msdos/pktdrvr.c gnuc.h pcap-dos.h msdos/pm_drvr/lock.h \
|
||||
pcap-int.h pcap.h pcap-bpf.h msdos/pktdrvr.h msdos/pkt_stub.inc
|
||||
ndis2.o: msdos/ndis2.c pcap-dos.h msdos/pm_drvr/lock.h pcap-int.h pcap.h \
|
||||
pcap-bpf.h msdos/ndis2.h
|
||||
snprintf.o: missing/snprintf.c pcap-int.h pcap.h pcap-bpf.h
|
||||
131
libpcap-possiblymodified/msdos/makefile.wc
Normal file
131
libpcap-possiblymodified/msdos/makefile.wc
Normal file
@@ -0,0 +1,131 @@
|
||||
#
|
||||
# Watcom Makefile for dos-libpcap.
|
||||
#
|
||||
# Specify MODEL = `3r' or `3s'
|
||||
# Specify TARGET = `pharlap' or `dos4g'
|
||||
#
|
||||
# Use this makefile from the libpcap root directory.
|
||||
# E.g. like this:
|
||||
#
|
||||
# c:\net\pcap> wmake -f msdos\makefile.wc
|
||||
#
|
||||
|
||||
MODEL = 3s
|
||||
TARGET = dos4g
|
||||
|
||||
OBJDIR = msdos\$(TARGET).w$(MODEL)
|
||||
LIB = $(OBJDIR)\pcap.lib
|
||||
|
||||
.EXTENSIONS: .l .y
|
||||
|
||||
DEFS = -dDEBUG -dNDIS_DEBUG -d_U_= -dHAVE_LIMITS_H -dHAVE_STRERROR &
|
||||
-dHAVE_SNPRINTF -dHAVE_VSNPRINTF
|
||||
|
||||
CC = wcc386.exe
|
||||
ASM = wasm.exe -$(MODEL) $(DEFS) -dDOSX -dDOS4GW -zq -bt=dos -fr=nul -d3 -s
|
||||
|
||||
OBJS = $(OBJDIR)\grammar.obj $(OBJDIR)\scanner.obj $(OBJDIR)\pcap.obj &
|
||||
$(OBJDIR)\bpf_filt.obj $(OBJDIR)\bpf_imag.obj $(OBJDIR)\bpf_dump.obj &
|
||||
$(OBJDIR)\etherent.obj $(OBJDIR)\gencode.obj $(OBJDIR)\nametoad.obj &
|
||||
$(OBJDIR)\pcap-dos.obj $(OBJDIR)\pktdrvr.obj $(OBJDIR)\optimize.obj &
|
||||
$(OBJDIR)\savefile.obj $(OBJDIR)\inet.obj $(OBJDIR)\ndis2.obj
|
||||
|
||||
CFLAGS = $(DEFS) $(YYDEFS) -I. -I$(%watt_root)\inc -I.\msdos\pm_drvr &
|
||||
-$(MODEL) -mf -zff -zgf -zq -bt=dos -fr=nul -w6 -fpi &
|
||||
-oilrtf -zm
|
||||
|
||||
TEMPBIN = tmp.bin
|
||||
|
||||
all: $(OBJDIR) $(OBJDIR)\pcap.lib
|
||||
|
||||
$(OBJDIR):
|
||||
- mkdir $(OBJDIR)
|
||||
|
||||
$(OBJDIR)\pcap.lib: $(OBJS) wlib.arg
|
||||
wlib -q -b -c $(OBJDIR)\pcap.lib @wlib.arg
|
||||
|
||||
wlib.arg: msdos\makefile.wc
|
||||
%create $^@
|
||||
for %f in ($(OBJS)) do %append $^@ +- %f
|
||||
|
||||
$(OBJDIR)\pktdrvr.obj: msdos\pkt_stub.inc msdos\pktdrvr.c gnuc.h &
|
||||
pcap-dos.h pcap-int.h pcap.h msdos\pktdrvr.h
|
||||
*$(CC) $(CFLAGS) msdos\pktdrvr.c -fo=$@
|
||||
|
||||
$(OBJDIR)\ndis2.obj: msdos\ndis2.c
|
||||
*$(CC) $(CFLAGS) msdos\ndis2.c -fo=$@
|
||||
|
||||
.ERASE
|
||||
.c{$(OBJDIR)}.obj:
|
||||
*$(CC) $(CFLAGS) $[@ -fo=$@
|
||||
|
||||
grammar.c tokdefs.h: grammar.y
|
||||
bison --name-prefix=pcap_ --yacc --defines $[@
|
||||
- @del grammar.c
|
||||
- @del tokdefs.h
|
||||
ren y_tab.c grammar.c
|
||||
ren y_tab.h tokdefs.h
|
||||
|
||||
scanner.c: scanner.l
|
||||
flex -Ppcap_ -7 -o$@ $[@
|
||||
|
||||
msdos\pkt_stub.inc: bin2c.exe msdos\pkt_rx1.S
|
||||
nasm -fbin -dDEBUG -o $(TEMPBIN) -lmsdos\pkt_rx1.lst msdos\pkt_rx1.S
|
||||
bin2c.exe $(TEMPBIN) > $@
|
||||
@del $(TEMPBIN)
|
||||
|
||||
bin2c.exe: msdos\bin2c.c
|
||||
wcl $[@
|
||||
|
||||
clean realclean vclean: .SYMBOLIC
|
||||
for %f in (dos4g.w3r dos4g.w3s pharlap.w3r pharlap.w3s) do &
|
||||
@del %f\*.obj
|
||||
@del grammar.c
|
||||
@del tokdefs.h
|
||||
@del scanner.c
|
||||
@del bin2c.exe
|
||||
@del bin2c.obj
|
||||
@del msdos\pkt_stub.inc
|
||||
@echo Cleaned
|
||||
|
||||
#
|
||||
# dependencies
|
||||
#
|
||||
$(OBJDIR)\bpf_filt.obj: bpf_filt.c pcap-int.h pcap.h pcap-bpf.h gnuc.h
|
||||
|
||||
$(OBJDIR)\bpf_imag.obj: bpf_imag.c pcap-int.h pcap.h pcap-bpf.h
|
||||
|
||||
$(OBJDIR)\bpf_dump.obj: bpf_dump.c pcap.h pcap-bpf.h
|
||||
|
||||
$(OBJDIR)\etherent.obj: etherent.c pcap-int.h pcap.h pcap-bpf.h pcap-nam.h
|
||||
|
||||
$(OBJDIR)\optimize.obj: optimize.c pcap-int.h pcap.h pcap-bpf.h gencode.h
|
||||
|
||||
$(OBJDIR)\savefile.obj: savefile.c pcap-int.h pcap.h pcap-bpf.h
|
||||
|
||||
$(OBJDIR)\pcap.obj: pcap.c pcap-dos.h pcap-int.h pcap.h pcap-bpf.h
|
||||
|
||||
$(OBJDIR)\inet.obj: inet.c pcap-int.h pcap.h pcap-bpf.h
|
||||
|
||||
$(OBJDIR)\grammar.obj: grammar.c pcap-int.h pcap.h pcap-bpf.h gencode.h &
|
||||
pf.h pcap-nam.h
|
||||
|
||||
$(OBJDIR)\scanner.obj: scanner.c pcap-int.h pcap.h pcap-bpf.h gencode.h &
|
||||
pcap-nam.h tokdefs.h
|
||||
|
||||
$(OBJDIR)\gencode.obj: gencode.c pcap-dos.h pcap-int.h pcap.h pcap-bpf.h &
|
||||
ethertyp.h nlpid.h llc.h gencode.h atmuni31.h sunatmpo.h ppp.h sll.h &
|
||||
arcnet.h pf.h pcap-nam.h
|
||||
|
||||
$(OBJDIR)\nametoad.obj: nametoad.c pcap-int.h pcap.h pcap-bpf.h gencode.h &
|
||||
pcap-nam.h ethertyp.h
|
||||
|
||||
$(OBJDIR)\pcap-dos.obj: pcap-dos.c pcap.h pcap-bpf.h pcap-dos.h pcap-int.h &
|
||||
msdos\pktdrvr.h
|
||||
|
||||
$(OBJDIR)\pktdrvr.obj: msdos\pktdrvr.c gnuc.h pcap-dos.h pcap-int.h &
|
||||
pcap.h pcap-bpf.h msdos\pktdrvr.h msdos\pkt_stub.inc
|
||||
|
||||
$(OBJDIR)\ndis2.obj: msdos\ndis2.c pcap-dos.h pcap-int.h pcap.h pcap-bpf.h &
|
||||
msdos\ndis2.h
|
||||
|
||||
860
libpcap-possiblymodified/msdos/ndis2.c
Normal file
860
libpcap-possiblymodified/msdos/ndis2.c
Normal file
@@ -0,0 +1,860 @@
|
||||
/*
|
||||
* Copyright (c) 1993,1994
|
||||
* Texas A&M University. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Texas A&M University
|
||||
* and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY 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 UNIVERSITY 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.
|
||||
*
|
||||
* Developers:
|
||||
* David K. Hess, Douglas Lee Schales, David R. Safford
|
||||
*
|
||||
* Heavily modified for Metaware HighC + GNU C 2.8+
|
||||
* Gisle Vanem 1998
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <dos.h>
|
||||
#include <io.h>
|
||||
#include <fcntl.h>
|
||||
#include <malloc.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "pcap-dos.h"
|
||||
#include "pcap-int.h"
|
||||
#include "msdos/ndis2.h"
|
||||
|
||||
#if defined(USE_NDIS2)
|
||||
|
||||
/*
|
||||
* Packet buffer handling
|
||||
*/
|
||||
extern int FreePktBuf (PktBuf *buf);
|
||||
extern int EnquePktBuf (PktBuf *buf);
|
||||
extern PktBuf* AllocPktBuf (void);
|
||||
|
||||
/*
|
||||
* Various defines
|
||||
*/
|
||||
#define MAX_NUM_DEBUG_STRINGS 90
|
||||
#define DEBUG_STRING_LENGTH 80
|
||||
#define STACK_POOL_SIZE 6
|
||||
#define STACK_SIZE 256
|
||||
|
||||
#define MEDIA_FDDI 1
|
||||
#define MEDIA_ETHERNET 2
|
||||
#define MEDIA_TOKEN 3
|
||||
|
||||
static int startDebug = 0;
|
||||
static int stopDebug = 0;
|
||||
|
||||
static DWORD droppedPackets = 0L;
|
||||
static WORD frameSize = 0;
|
||||
static WORD headerSize = 0;
|
||||
static int mediaType = 0;
|
||||
static char *lastErr = NULL;
|
||||
|
||||
static BYTE debugStrings [MAX_NUM_DEBUG_STRINGS][DEBUG_STRING_LENGTH];
|
||||
static BYTE *freeStacks [STACK_POOL_SIZE];
|
||||
static int freeStackPtr = STACK_POOL_SIZE - 1;
|
||||
|
||||
static ProtMan protManEntry = NULL;
|
||||
static WORD protManDS = 0;
|
||||
static volatile int xmitPending;
|
||||
|
||||
static struct _PktBuf *txBufPending;
|
||||
static struct _CardHandle *handle;
|
||||
static struct _CommonChars common;
|
||||
static struct _ProtocolChars protChars;
|
||||
static struct _ProtDispatch lowerTable;
|
||||
|
||||
static struct _FailingModules failingModules;
|
||||
static struct _BindingsList bindings;
|
||||
|
||||
static struct {
|
||||
WORD err_num;
|
||||
char *err_text;
|
||||
} ndis_errlist[] = {
|
||||
|
||||
{ ERR_SUCCESS,
|
||||
"The function completed successfully.\n" },
|
||||
|
||||
{ ERR_WAIT_FOR_RELEASE,
|
||||
"The ReceiveChain completed successfully but the protocol has\n"
|
||||
"retained control of the buffer.\n" },
|
||||
|
||||
{ ERR_REQUEST_QUEUED,
|
||||
"The current request has been queued.\n" },
|
||||
|
||||
{ ERR_FRAME_NOT_RECOGNIZED,
|
||||
"Frame not recognized.\n" },
|
||||
|
||||
{ ERR_FRAME_REJECTED,
|
||||
"Frame was discarded.\n" },
|
||||
|
||||
{ ERR_FORWARD_FRAME,
|
||||
"Protocol wishes to forward frame to another protocol.\n" },
|
||||
|
||||
{ ERR_OUT_OF_RESOURCE,
|
||||
"Out of resource.\n" },
|
||||
|
||||
{ ERR_INVALID_PARAMETER,
|
||||
"Invalid parameter.\n" },
|
||||
|
||||
{ ERR_INVALID_FUNCTION,
|
||||
"Invalid function.\n" },
|
||||
|
||||
{ ERR_NOT_SUPPORTED,
|
||||
"Not supported.\n" },
|
||||
|
||||
{ ERR_HARDWARE_ERROR,
|
||||
"Hardware error.\n" },
|
||||
|
||||
{ ERR_TRANSMIT_ERROR,
|
||||
"The packet was not transmitted due to an error.\n" },
|
||||
|
||||
{ ERR_NO_SUCH_DESTINATION,
|
||||
"Token ring packet was not recognized when transmitted.\n" },
|
||||
|
||||
{ ERR_BUFFER_TOO_SMALL,
|
||||
"Provided buffer was too small.\n" },
|
||||
|
||||
{ ERR_ALREADY_STARTED,
|
||||
"Network drivers already started.\n" },
|
||||
|
||||
{ ERR_INCOMPLETE_BINDING,
|
||||
"Protocol driver could not complete its bindings.\n" },
|
||||
|
||||
{ ERR_DRIVER_NOT_INITIALIZED,
|
||||
"MAC did not initialize properly.\n" },
|
||||
|
||||
{ ERR_HARDWARE_NOT_FOUND,
|
||||
"Hardware not found.\n" },
|
||||
|
||||
{ ERR_HARDWARE_FAILURE,
|
||||
"Hardware failure.\n" },
|
||||
|
||||
{ ERR_CONFIGURATION_FAILURE,
|
||||
"Configuration failure.\n" },
|
||||
|
||||
{ ERR_INTERRUPT_CONFLICT,
|
||||
"Interrupt conflict.\n" },
|
||||
|
||||
{ ERR_INCOMPATIBLE_MAC,
|
||||
"The MAC is not compatible with the protocol.\n" },
|
||||
|
||||
{ ERR_INITIALIZATION_FAILED,
|
||||
"Initialization failed.\n" },
|
||||
|
||||
{ ERR_NO_BINDING,
|
||||
"Binding did not occur.\n" },
|
||||
|
||||
{ ERR_NETWORK_MAY_NOT_BE_CONNECTED,
|
||||
"The network may not be connected to the adapter.\n" },
|
||||
|
||||
{ ERR_INCOMPATIBLE_OS_VERSION,
|
||||
"The version of the operating system is incompatible with the protocol.\n" },
|
||||
|
||||
{ ERR_ALREADY_REGISTERED,
|
||||
"The protocol is already registered.\n" },
|
||||
|
||||
{ ERR_PATH_NOT_FOUND,
|
||||
"PROTMAN.EXE could not be found.\n" },
|
||||
|
||||
{ ERR_INSUFFICIENT_MEMORY,
|
||||
"Insufficient memory.\n" },
|
||||
|
||||
{ ERR_INFO_NOT_FOUND,
|
||||
"Protocol Mananger info structure is lost or corrupted.\n" },
|
||||
|
||||
{ ERR_GENERAL_FAILURE,
|
||||
"General failure.\n" }
|
||||
};
|
||||
|
||||
/*
|
||||
* Some handy macros
|
||||
*/
|
||||
#define PERROR(str) printf("%s (%d): %s\n", __FILE__,__LINE__,str)
|
||||
#define DEBUG_RING() (debugStrings[stopDebug+1 == MAX_NUM_DEBUG_STRINGS ? \
|
||||
stopDebug = 0 : ++stopDebug])
|
||||
|
||||
/*
|
||||
* needs rewrite for DOSX
|
||||
*/
|
||||
#define MAC_DISPATCH(hnd) ((struct _MacUpperDispatch*)(hnd)->common->upperDispatchTable)
|
||||
#define MAC_STATUS(hnd) ((struct _MacStatusTable*) (hnd)->common->serviceStatus)
|
||||
#define MAC_CHAR(hnd) ((struct _MacChars*) (hnd)->common->serviceChars)
|
||||
|
||||
#ifdef NDIS_DEBUG
|
||||
#define DEBUG0(str) printf (str)
|
||||
#define DEBUG1(fmt,a) printf (fmt,a)
|
||||
#define DEBUG2(fmt,a,b) printf (fmt,a,b)
|
||||
#define TRACE0(str) sprintf (DEBUG_RING(),str)
|
||||
#define TRACE1(fmt,a) sprintf (DEBUG_RING(),fmt,a)
|
||||
#else
|
||||
#define DEBUG0(str) ((void)0)
|
||||
#define DEBUG1(fmt,a) ((void)0)
|
||||
#define DEBUG2(fmt,a,b) ((void)0)
|
||||
#define TRACE0(str) ((void)0)
|
||||
#define TRACE1(fmt,a) ((void)0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This routine is called from both threads
|
||||
*/
|
||||
void NdisFreeStack (BYTE *aStack)
|
||||
{
|
||||
GUARD();
|
||||
|
||||
if (freeStackPtr == STACK_POOL_SIZE - 1)
|
||||
PERROR ("tried to free too many stacks");
|
||||
|
||||
freeStacks[++freeStackPtr] = aStack;
|
||||
|
||||
if (freeStackPtr == 0)
|
||||
TRACE0 ("freeStackPtr went positive\n");
|
||||
|
||||
UNGUARD();
|
||||
}
|
||||
|
||||
/*
|
||||
* This routine is called from callbacks to allocate local data
|
||||
*/
|
||||
BYTE *NdisAllocStack (void)
|
||||
{
|
||||
BYTE *stack;
|
||||
|
||||
GUARD();
|
||||
|
||||
if (freeStackPtr < 0)
|
||||
{
|
||||
/* Ran out of stack buffers. Return NULL which will start
|
||||
* dropping packets
|
||||
*/
|
||||
TRACE0 ("freeStackPtr went negative\n");
|
||||
stack = 0;
|
||||
}
|
||||
else
|
||||
stack = freeStacks[freeStackPtr--];
|
||||
|
||||
UNGUARD();
|
||||
return (stack);
|
||||
}
|
||||
|
||||
CALLBACK (NdisSystemRequest (DWORD param1, DWORD param2, WORD param3,
|
||||
WORD opcode, WORD targetDS))
|
||||
{
|
||||
static int bindEntry = 0;
|
||||
struct _CommonChars *macCommon;
|
||||
volatile WORD result;
|
||||
|
||||
switch (opcode)
|
||||
{
|
||||
case REQ_INITIATE_BIND:
|
||||
macCommon = (struct _CommonChars*) param2;
|
||||
if (macCommon == NULL)
|
||||
{
|
||||
printf ("There is an NDIS misconfiguration.\n");
|
||||
result = ERR_GENERAL_FAILURE;
|
||||
break;
|
||||
}
|
||||
DEBUG2 ("module name %s\n"
|
||||
"module type %s\n",
|
||||
macCommon->moduleName,
|
||||
((MacChars*) macCommon->serviceChars)->macName);
|
||||
|
||||
/* Binding to the MAC */
|
||||
result = macCommon->systemRequest ((DWORD)&common, (DWORD)&macCommon,
|
||||
0, REQ_BIND,
|
||||
macCommon->moduleDS);
|
||||
|
||||
if (!strcmp(bindings.moduleName[bindEntry], handle->moduleName))
|
||||
handle->common = macCommon;
|
||||
else PERROR ("unknown module");
|
||||
++bindEntry;
|
||||
break;
|
||||
|
||||
case REQ_INITIATE_UNBIND:
|
||||
macCommon = (struct _CommonChars*) param2;
|
||||
result = macCommon->systemRequest ((DWORD)&common, 0,
|
||||
0, REQ_UNBIND,
|
||||
macCommon->moduleDS);
|
||||
break;
|
||||
|
||||
default:
|
||||
result = ERR_GENERAL_FAILURE;
|
||||
break;
|
||||
}
|
||||
ARGSUSED (param1);
|
||||
ARGSUSED (param3);
|
||||
ARGSUSED (targetDS);
|
||||
return (result);
|
||||
}
|
||||
|
||||
CALLBACK (NdisRequestConfirm (WORD protId, WORD macId, WORD reqHandle,
|
||||
WORD status, WORD request, WORD protDS))
|
||||
{
|
||||
ARGSUSED (protId); ARGSUSED (macId);
|
||||
ARGSUSED (reqHandle); ARGSUSED (status);
|
||||
ARGSUSED (request); ARGSUSED (protDS);
|
||||
return (ERR_SUCCESS);
|
||||
}
|
||||
|
||||
CALLBACK (NdisTransmitConfirm (WORD protId, WORD macId, WORD reqHandle,
|
||||
WORD status, WORD protDS))
|
||||
{
|
||||
xmitPending--;
|
||||
FreePktBuf (txBufPending); /* Add passed ECB back to the free list */
|
||||
|
||||
ARGSUSED (reqHandle);
|
||||
ARGSUSED (status);
|
||||
ARGSUSED (protDS);
|
||||
return (ERR_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The primary function for receiving packets
|
||||
*/
|
||||
CALLBACK (NdisReceiveLookahead (WORD macId, WORD frameSize,
|
||||
WORD bytesAvail, BYTE *buffer,
|
||||
BYTE *indicate, WORD protDS))
|
||||
{
|
||||
int result;
|
||||
PktBuf *pktBuf;
|
||||
WORD bytesCopied;
|
||||
struct _TDBufDescr tDBufDescr;
|
||||
|
||||
#if 0
|
||||
TRACE1 ("lookahead length = %d, ", bytesAvail);
|
||||
TRACE1 ("ecb = %08lX, ", *ecb);
|
||||
TRACE1 ("count = %08lX\n", count);
|
||||
TRACE1 ("offset = %08lX, ", offset);
|
||||
TRACE1 ("timesAllowed = %d, ", timesAllowed);
|
||||
TRACE1 ("packet size = %d\n", look->dataLookAheadLen);
|
||||
#endif
|
||||
|
||||
/* Allocate a buffer for the packet
|
||||
*/
|
||||
if ((pktBuf = AllocPktBuf()) == NULL)
|
||||
{
|
||||
droppedPackets++;
|
||||
return (ERR_FRAME_REJECTED);
|
||||
}
|
||||
|
||||
/*
|
||||
* Now kludge things. Note we will have to undo this later. This will
|
||||
* make the packet contiguous after the MLID has done the requested copy.
|
||||
*/
|
||||
|
||||
tDBufDescr.tDDataCount = 1;
|
||||
tDBufDescr.tDBufDescrRec[0].tDPtrType = NDIS_PTR_PHYSICAL;
|
||||
tDBufDescr.tDBufDescrRec[0].tDDataPtr = pktBuf->buffer;
|
||||
tDBufDescr.tDBufDescrRec[0].tDDataLen = pktBuf->length;
|
||||
tDBufDescr.tDBufDescrRec[0].dummy = 0;
|
||||
|
||||
result = MAC_DISPATCH(handle)->transferData (&bytesCopied, 0, &tDBufDescr,
|
||||
handle->common->moduleDS);
|
||||
pktBuf->packetLength = bytesCopied;
|
||||
|
||||
if (result == ERR_SUCCESS)
|
||||
EnquePktBuf(pktBuf);
|
||||
else FreePktBuf (pktBuf);
|
||||
|
||||
ARGSUSED (frameSize);
|
||||
ARGSUSED (bytesAvail);
|
||||
ARGSUSED (indicate);
|
||||
ARGSUSED (protDS);
|
||||
|
||||
return (ERR_SUCCESS);
|
||||
}
|
||||
|
||||
CALLBACK (NdisIndicationComplete (WORD macId, WORD protDS))
|
||||
{
|
||||
ARGSUSED (macId);
|
||||
ARGSUSED (protDS);
|
||||
|
||||
/* We don't give a hoot about these. Just return
|
||||
*/
|
||||
return (ERR_SUCCESS);
|
||||
}
|
||||
|
||||
/*
|
||||
* This is the OTHER way we may receive packets
|
||||
*/
|
||||
CALLBACK (NdisReceiveChain (WORD macId, WORD frameSize, WORD reqHandle,
|
||||
struct _RxBufDescr *rxBufDescr,
|
||||
BYTE *indicate, WORD protDS))
|
||||
{
|
||||
struct _PktBuf *pktBuf;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* For now we copy the entire packet over to a PktBuf structure. This may be
|
||||
* a performance hit but this routine probably isn't called very much, and
|
||||
* it is a lot of work to do it otherwise. Also if it is a filter protocol
|
||||
* packet we could end up sucking up MAC buffes.
|
||||
*/
|
||||
|
||||
if ((pktBuf = AllocPktBuf()) == NULL)
|
||||
{
|
||||
droppedPackets++;
|
||||
return (ERR_FRAME_REJECTED);
|
||||
}
|
||||
pktBuf->packetLength = 0;
|
||||
|
||||
/* Copy the packet to the buffer
|
||||
*/
|
||||
for (i = 0; i < rxBufDescr->rxDataCount; ++i)
|
||||
{
|
||||
struct _RxBufDescrRec *rxDescr = &rxBufDescr->rxBufDescrRec[i];
|
||||
|
||||
memcpy (pktBuf->buffer + pktBuf->packetLength,
|
||||
rxDescr->rxDataPtr, rxDescr->rxDataLen);
|
||||
pktBuf->packetLength += rxDescr->rxDataLen;
|
||||
}
|
||||
|
||||
EnquePktBuf (pktBuf);
|
||||
|
||||
ARGSUSED (frameSize);
|
||||
ARGSUSED (reqHandle);
|
||||
ARGSUSED (indicate);
|
||||
ARGSUSED (protDS);
|
||||
|
||||
/* This frees up the buffer for the MAC to use
|
||||
*/
|
||||
return (ERR_SUCCESS);
|
||||
}
|
||||
|
||||
CALLBACK (NdisStatusProc (WORD macId, WORD param1, BYTE *indicate,
|
||||
WORD opcode, WORD protDS))
|
||||
{
|
||||
switch (opcode)
|
||||
{
|
||||
case STATUS_RING_STATUS:
|
||||
break;
|
||||
case STATUS_ADAPTER_CHECK:
|
||||
break;
|
||||
case STATUS_START_RESET:
|
||||
break;
|
||||
case STATUS_INTERRUPT:
|
||||
break;
|
||||
case STATUS_END_RESET:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
ARGSUSED (macId);
|
||||
ARGSUSED (param1);
|
||||
ARGSUSED (indicate);
|
||||
ARGSUSED (opcode);
|
||||
ARGSUSED (protDS);
|
||||
|
||||
/* We don't need to do anything about this stuff yet
|
||||
*/
|
||||
return (ERR_SUCCESS);
|
||||
}
|
||||
|
||||
/*
|
||||
* Tell the NDIS driver to start the delivery of the packet
|
||||
*/
|
||||
int NdisSendPacket (struct _PktBuf *pktBuf, int macId)
|
||||
{
|
||||
struct _TxBufDescr txBufDescr;
|
||||
int result;
|
||||
|
||||
xmitPending++;
|
||||
txBufPending = pktBuf; /* we only have 1 pending Tx at a time */
|
||||
|
||||
txBufDescr.txImmedLen = 0;
|
||||
txBufDescr.txImmedPtr = NULL;
|
||||
txBufDescr.txDataCount = 1;
|
||||
txBufDescr.txBufDescrRec[0].txPtrType = NDIS_PTR_PHYSICAL;
|
||||
txBufDescr.txBufDescrRec[0].dummy = 0;
|
||||
txBufDescr.txBufDescrRec[0].txDataLen = pktBuf->packetLength;
|
||||
txBufDescr.txBufDescrRec[0].txDataPtr = pktBuf->buffer;
|
||||
|
||||
result = MAC_DISPATCH(handle)->transmitChain (common.moduleId,
|
||||
pktBuf->handle,
|
||||
&txBufDescr,
|
||||
handle->common->moduleDS);
|
||||
switch (result)
|
||||
{
|
||||
case ERR_OUT_OF_RESOURCE:
|
||||
/* Note that this should not happen but if it does there is not
|
||||
* much we can do about it
|
||||
*/
|
||||
printf ("ERROR: transmit queue overflowed\n");
|
||||
return (0);
|
||||
|
||||
case ERR_SUCCESS:
|
||||
/* Everything was hunky dory and synchronous. Free up the
|
||||
* packet buffer
|
||||
*/
|
||||
xmitPending--;
|
||||
FreePktBuf (pktBuf);
|
||||
return (1);
|
||||
|
||||
case ERR_REQUEST_QUEUED:
|
||||
/* Everything was hunky dory and asynchronous. Do nothing
|
||||
*/
|
||||
return (1);
|
||||
|
||||
default:
|
||||
printf ("Tx fail, code = %04X\n", result);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int ndis_nerr = sizeof(ndis_errlist) / sizeof(ndis_errlist[0]);
|
||||
|
||||
static char *Ndis_strerror (WORD errorCode)
|
||||
{
|
||||
static char buf[30];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ndis_nerr; i++)
|
||||
if (errorCode == ndis_errlist[i].err_num)
|
||||
return (ndis_errlist[i].err_text);
|
||||
|
||||
sprintf (buf,"unknown error %d",errorCode);
|
||||
return (buf);
|
||||
}
|
||||
|
||||
|
||||
char *NdisLastError (void)
|
||||
{
|
||||
char *errStr = lastErr;
|
||||
lastErr = NULL;
|
||||
return (errStr);
|
||||
}
|
||||
|
||||
int NdisOpen (void)
|
||||
{
|
||||
struct _ReqBlock reqBlock;
|
||||
int result;
|
||||
int ndisFd = open (NDIS_PATH, O_RDONLY);
|
||||
|
||||
if (ndisFd < 0)
|
||||
{
|
||||
printf ("Could not open NDIS Protocol Manager device.\n");
|
||||
return (0);
|
||||
}
|
||||
|
||||
memset (&reqBlock, 0, sizeof(ReqBlock));
|
||||
|
||||
reqBlock.opcode = PM_GET_PROTOCOL_MANAGER_LINKAGE;
|
||||
|
||||
result = NdisGetLinkage (ndisFd, (char*)&reqBlock, sizeof(ReqBlock));
|
||||
if (result != 0)
|
||||
{
|
||||
printf ("Could not get Protocol Manager linkage.\n");
|
||||
close (ndisFd);
|
||||
return (0);
|
||||
}
|
||||
|
||||
close (ndisFd);
|
||||
protManEntry = (ProtMan) reqBlock.pointer1;
|
||||
protManDS = reqBlock.word1;
|
||||
|
||||
DEBUG2 ("Entry Point = %04X:%04X\n", FP_SEG(protManEntry),FP_OFF(protManEntry));
|
||||
DEBUG1 ("ProtMan DS = %04X\n", protManDS);
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
||||
int NdisRegisterAndBind (int promis)
|
||||
{
|
||||
struct _ReqBlock reqBlock;
|
||||
WORD result;
|
||||
|
||||
memset (&common,0,sizeof(common));
|
||||
|
||||
common.tableSize = sizeof (common);
|
||||
|
||||
common.majorNdisVersion = 2;
|
||||
common.minorNdisVersion = 0;
|
||||
common.majorModuleVersion = 2;
|
||||
common.minorModuleVersion = 0;
|
||||
|
||||
/* Indicates binding from below and dynamically loaded
|
||||
*/
|
||||
common.moduleFlags = 0x00000006L;
|
||||
|
||||
strcpy (common.moduleName, "PCAP");
|
||||
|
||||
common.protocolLevelUpper = 0xFF;
|
||||
common.protocolLevelLower = 1;
|
||||
common.interfaceLower = 1;
|
||||
#ifdef __DJGPP__
|
||||
common.moduleDS = _dos_ds; /* the callback data segment */
|
||||
#else
|
||||
common.moduleDS = _DS;
|
||||
#endif
|
||||
|
||||
common.systemRequest = (SystemRequest) systemRequestGlue;
|
||||
common.serviceChars = (BYTE*) &protChars;
|
||||
common.serviceStatus = NULL;
|
||||
common.upperDispatchTable = NULL;
|
||||
common.lowerDispatchTable = (BYTE*) &lowerTable;
|
||||
|
||||
protChars.length = sizeof (protChars);
|
||||
protChars.name[0] = 0;
|
||||
protChars.type = 0;
|
||||
|
||||
lowerTable.backPointer = &common;
|
||||
lowerTable.requestConfirm = requestConfirmGlue;
|
||||
lowerTable.transmitConfirm = transmitConfirmGlue;
|
||||
lowerTable.receiveLookahead = receiveLookaheadGlue;
|
||||
lowerTable.indicationComplete = indicationCompleteGlue;
|
||||
lowerTable.receiveChain = receiveChainGlue;
|
||||
lowerTable.status = statusGlue;
|
||||
lowerTable.flags = 3;
|
||||
if (promis)
|
||||
lowerTable.flags |= 4; /* promiscous mode (receive everything) */
|
||||
|
||||
bindings.numBindings = 1;
|
||||
strcpy (bindings.moduleName[0], handle->moduleName);
|
||||
|
||||
/* Register ourselves with NDIS
|
||||
*/
|
||||
reqBlock.opcode = PM_REGISTER_MODULE;
|
||||
reqBlock.pointer1 = (BYTE FAR*) &common;
|
||||
reqBlock.pointer2 = (BYTE FAR*) &bindings;
|
||||
|
||||
result = (*protManEntry) (&reqBlock, protManDS);
|
||||
if (result)
|
||||
{
|
||||
printf ("Protman registering failed: %s\n", Ndis_strerror(result));
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Start the binding process
|
||||
*/
|
||||
reqBlock.opcode = PM_BIND_AND_START;
|
||||
reqBlock.pointer1 = (BYTE FAR*) &failingModules;
|
||||
|
||||
result = (*protManEntry) (&reqBlock, protManDS);
|
||||
if (result)
|
||||
{
|
||||
printf ("Start binding failed: %s\n", Ndis_strerror(result));
|
||||
return (0);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int CheckMacFeatures (CardHandle *card)
|
||||
{
|
||||
DWORD serviceFlags;
|
||||
BYTE _far *mediaString;
|
||||
BYTE _far *mac_addr;
|
||||
|
||||
DEBUG2 ("checking card features\n"
|
||||
"common table address = %08lX, macId = %d\n",
|
||||
card->common, card->common->moduleId);
|
||||
|
||||
serviceFlags = MAC_CHAR (handle)->serviceFlags;
|
||||
|
||||
if ((serviceFlags & SF_PROMISCUOUS) == 0)
|
||||
{
|
||||
printf ("The MAC %s does not support promiscuous mode.\n",
|
||||
card->moduleName);
|
||||
return (0);
|
||||
}
|
||||
|
||||
mediaString = MAC_CHAR (handle)->macName;
|
||||
|
||||
DEBUG1 ("media type = %s\n",mediaString);
|
||||
|
||||
/* Get the media type. And set the header size
|
||||
*/
|
||||
if (!strncmp(mediaString,"802.3",5) ||
|
||||
!strncmp(mediaString,"DIX",3) ||
|
||||
!strncmp(mediaString,"DIX+802.3",9))
|
||||
headerSize = sizeof (EthernetIIHeader);
|
||||
|
||||
else if (!strncmp(mediaString,"FDDI",4))
|
||||
headerSize = sizeof (FddiHeader) +
|
||||
sizeof (Ieee802Dot2SnapHeader);
|
||||
else
|
||||
{
|
||||
printf ("Unsupported MAC type: `%s'\n", mediaString);
|
||||
return (0);
|
||||
}
|
||||
|
||||
frameSize = MAC_CHAR (handle)->maxFrameSize;
|
||||
mac_addr = MAC_CHAR (handle)->currentAddress;
|
||||
|
||||
printf ("Hardware address: %02X:%02X:%02X:%02X:%02X:%02X\n",
|
||||
mac_addr[0], mac_addr[1], mac_addr[2],
|
||||
mac_addr[3], mac_addr[4], mac_addr[5]);
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int NdisStartMac (CardHandle *card)
|
||||
{
|
||||
WORD result;
|
||||
|
||||
/* Set the lookahead length
|
||||
*/
|
||||
result = MAC_DISPATCH(handle)->request (common.moduleId, 0,
|
||||
headerSize, 0,
|
||||
REQ_SET_LOOKAHEAD,
|
||||
card->common->moduleDS);
|
||||
|
||||
/* We assume that if we got INVALID PARAMETER then either this
|
||||
* is not supported or will work anyway. NE2000 does this.
|
||||
*/
|
||||
if (result != ERR_SUCCESS && result != ERR_INVALID_PARAMETER)
|
||||
{
|
||||
DEBUG1 ("Set lookahead failed: %s\n", Ndis_strerror(result));
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Set the packet filter. Note that for some medias and drivers we
|
||||
* must specify all three flags or the card(s) will not operate correctly.
|
||||
*/
|
||||
result = MAC_DISPATCH(handle)->request (common.moduleId, 0,
|
||||
/* all packets */ FILTER_PROMISCUOUS |
|
||||
/* packets to us */ FILTER_DIRECTED |
|
||||
/* broadcasts */ FILTER_BROADCAST,
|
||||
0, REQ_SET_PACKET_FILTER,
|
||||
card->common->moduleDS);
|
||||
if (result != ERR_SUCCESS)
|
||||
{
|
||||
DEBUG1 ("Set packet filter failed: %s\n", Ndis_strerror(result));
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* If OPEN/CLOSE supported then open the adapter
|
||||
*/
|
||||
if (MAC_CHAR(handle)->serviceFlags & SF_OPEN_CLOSE)
|
||||
{
|
||||
result = MAC_DISPATCH(handle)->request (common.moduleId, 0, 0, NULL,
|
||||
REQ_OPEN_ADAPTER,
|
||||
card->common->moduleDS);
|
||||
if (result != ERR_SUCCESS)
|
||||
{
|
||||
DEBUG1 ("Opening the MAC failed: %s\n", Ndis_strerror(result));
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
void NdisShutdown (void)
|
||||
{
|
||||
struct _ReqBlock reqBlock;
|
||||
int result, i;
|
||||
|
||||
if (!handle)
|
||||
return;
|
||||
|
||||
/* If the adapters support open and are open then close them
|
||||
*/
|
||||
if ((MAC_CHAR(handle)->serviceFlags & SF_OPEN_CLOSE) &&
|
||||
(MAC_STATUS(handle)->macStatus & MAC_OPEN))
|
||||
{
|
||||
result = MAC_DISPATCH(handle)->request (common.moduleId, 0, 0, 0,
|
||||
REQ_CLOSE_ADAPTER,
|
||||
handle->common->moduleDS);
|
||||
if (result != ERR_SUCCESS)
|
||||
{
|
||||
printf ("Closing the MAC failed: %s\n", Ndis_strerror(result));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Tell the Protocol Manager to unbind and stop
|
||||
*/
|
||||
reqBlock.opcode = PM_UNBIND_AND_STOP;
|
||||
reqBlock.pointer1 = (BYTE FAR*) &failingModules;
|
||||
reqBlock.pointer2 = NULL;
|
||||
|
||||
result = (*protManEntry) (&reqBlock, protManDS);
|
||||
if (result)
|
||||
printf ("Unbind failed: %s\n", Ndis_strerror(result));
|
||||
|
||||
for (i = 0; i < STACK_POOL_SIZE; ++i)
|
||||
free (freeStacks[i] - STACK_SIZE);
|
||||
|
||||
handle = NULL;
|
||||
}
|
||||
|
||||
int NdisInit (int promis)
|
||||
{
|
||||
int i, result;
|
||||
|
||||
/* Allocate the real mode stacks used for NDIS callbacks
|
||||
*/
|
||||
for (i = 0; i < STACK_POOL_SIZE; ++i)
|
||||
{
|
||||
freeStacks[i] = malloc (STACK_SIZE);
|
||||
if (!freeStacks[i])
|
||||
return (0);
|
||||
freeStacks[i] += STACK_SIZE;
|
||||
}
|
||||
|
||||
if (!NdisOpen())
|
||||
return (0);
|
||||
|
||||
if (!NdisRegisterAndBind(promis))
|
||||
return (0);
|
||||
|
||||
DEBUG1 ("My module id: %d\n", common.moduleId);
|
||||
DEBUG1 ("Handle id; %d\n", handle->common->moduleId);
|
||||
DEBUG1 ("MAC card: %-16s - ", handle->moduleName);
|
||||
|
||||
atexit (NdisShutdown);
|
||||
|
||||
if (!CheckMacFeatures(&handle))
|
||||
return (0);
|
||||
|
||||
switch (mediaType)
|
||||
{
|
||||
case MEDIA_FDDI:
|
||||
DEBUG0 ("Media type: FDDI");
|
||||
break;
|
||||
case MEDIA_ETHERNET:
|
||||
DEBUG0 ("Media type: ETHERNET");
|
||||
break;
|
||||
default:
|
||||
DEBUG0 ("Unsupported media.\n");
|
||||
return (0);
|
||||
}
|
||||
|
||||
DEBUG1 (" - Frame size: %d\n", frameSize);
|
||||
|
||||
if (!NdisStartMac(&handle))
|
||||
return (0);
|
||||
return (1);
|
||||
}
|
||||
#endif /* USE_NDIS2 */
|
||||
|
||||
559
libpcap-possiblymodified/msdos/ndis2.h
Normal file
559
libpcap-possiblymodified/msdos/ndis2.h
Normal file
@@ -0,0 +1,559 @@
|
||||
/*
|
||||
* Copyright (c) 1993,1994
|
||||
* Texas A&M University. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Texas A&M University
|
||||
* and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY 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 UNIVERSITY 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.
|
||||
*
|
||||
* Developers:
|
||||
* David K. Hess, Douglas Lee Schales, David R. Safford
|
||||
*
|
||||
* Heavily modified for Metaware HighC + GNU C 2.8+
|
||||
* Gisle Vanem 1998
|
||||
*/
|
||||
|
||||
#ifndef __PCAP_NDIS_H
|
||||
#define __PCAP_NDIS_H
|
||||
|
||||
#if defined (__HIGHC__)
|
||||
#define pascal _CC(_CALLEE_POPS_STACK & ~_REVERSE_PARMS) /* calling convention */
|
||||
#define CALLBACK(foo) pascal WORD foo
|
||||
#define PAS_PTR(x,arg) typedef FAR WORD pascal (*x) arg
|
||||
#define GUARD() _inline (0x9C,0xFA) /* pushfd, cli */
|
||||
#define UNGUARD() _inline (0x9D) /* popfd */
|
||||
#define FAR _far
|
||||
|
||||
#elif defined(__GNUC__)
|
||||
#define CALLBACK(foo) WORD foo __attribute__((stdcall))
|
||||
#define PAS_PTR(x,arg) typedef WORD (*x) arg __attribute__((stdcall))
|
||||
#define GUARD() __asm__ __volatile__ ("pushfd; cli")
|
||||
#define UNGUARD() __asm__ __volatile__ ("popfd")
|
||||
#define FAR
|
||||
|
||||
#elif defined (__TURBOC__)
|
||||
#define CALLBACK(foo) WORD pascal foo
|
||||
#define PAS_PTR(x,arg) typedef WORD pascal (_far *x) arg
|
||||
#define GUARD() _asm { pushf; cli }
|
||||
#define UNGUARD() _asm { popf }
|
||||
#define FAR _far
|
||||
|
||||
#elif defined (__WATCOMC__)
|
||||
#define CALLBACK(foo) WORD pascal foo
|
||||
#define PAS_PTR(x,arg) typedef WORD pascal (_far *x) arg
|
||||
#define GUARD() _disable()
|
||||
#define UNGUARD() _enable()
|
||||
#define FAR _far
|
||||
|
||||
#else
|
||||
#error Unsupported compiler
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Forwards
|
||||
*/
|
||||
struct _ReqBlock;
|
||||
struct _TxBufDescr;
|
||||
struct _TDBufDescr;
|
||||
|
||||
/*
|
||||
* Protocol Manager API
|
||||
*/
|
||||
PAS_PTR (ProtMan, (struct _ReqBlock FAR*, WORD));
|
||||
|
||||
/*
|
||||
* System request
|
||||
*/
|
||||
PAS_PTR (SystemRequest, (DWORD, DWORD, WORD, WORD, WORD));
|
||||
|
||||
/*
|
||||
* MAC API
|
||||
*/
|
||||
PAS_PTR (TransmitChain, (WORD, WORD, struct _TxBufDescr FAR*, WORD));
|
||||
PAS_PTR (TransferData, (WORD*,WORD, struct _TDBufDescr FAR*, WORD));
|
||||
PAS_PTR (Request, (WORD, WORD, WORD, DWORD, WORD, WORD));
|
||||
PAS_PTR (ReceiveRelease,(WORD, WORD));
|
||||
PAS_PTR (IndicationOn, (WORD));
|
||||
PAS_PTR (IndicationOff, (WORD));
|
||||
|
||||
|
||||
typedef enum {
|
||||
HARDWARE_NOT_INSTALLED = 0,
|
||||
HARDWARE_FAILED_DIAG = 1,
|
||||
HARDWARE_FAILED_CONFIG = 2,
|
||||
HARDWARE_HARD_FAULT = 3,
|
||||
HARDWARE_SOFT_FAULT = 4,
|
||||
HARDWARE_OK = 7,
|
||||
HARDWARE_MASK = 0x0007,
|
||||
MAC_BOUND = 0x0008,
|
||||
MAC_OPEN = 0x0010,
|
||||
DIAG_IN_PROGRESS = 0x0020
|
||||
} NdisMacStatus;
|
||||
|
||||
typedef enum {
|
||||
STATUS_RING_STATUS = 1,
|
||||
STATUS_ADAPTER_CHECK = 2,
|
||||
STATUS_START_RESET = 3,
|
||||
STATUS_INTERRUPT = 4,
|
||||
STATUS_END_RESET = 5
|
||||
} NdisStatus;
|
||||
|
||||
typedef enum {
|
||||
FILTER_DIRECTED = 1,
|
||||
FILTER_BROADCAST = 2,
|
||||
FILTER_PROMISCUOUS = 4,
|
||||
FILTER_SOURCE_ROUTE = 8
|
||||
} NdisPacketFilter;
|
||||
|
||||
typedef enum {
|
||||
REQ_INITIATE_DIAGNOSTICS = 1,
|
||||
REQ_READ_ERROR_LOG = 2,
|
||||
REQ_SET_STATION_ADDRESS = 3,
|
||||
REQ_OPEN_ADAPTER = 4,
|
||||
REQ_CLOSE_ADAPTER = 5,
|
||||
REQ_RESET_MAC = 6,
|
||||
REQ_SET_PACKET_FILTER = 7,
|
||||
REQ_ADD_MULTICAST_ADDRESS = 8,
|
||||
REQ_DELETE_MULTICAST_ADDRESS = 9,
|
||||
REQ_UPDATE_STATISTICS = 10,
|
||||
REQ_CLEAR_STATISTICS = 11,
|
||||
REQ_INTERRUPT_REQUEST = 12,
|
||||
REQ_SET_FUNCTIONAL_ADDRESS = 13,
|
||||
REQ_SET_LOOKAHEAD = 14
|
||||
} NdisGeneralRequest;
|
||||
|
||||
typedef enum {
|
||||
SF_BROADCAST = 0x00000001L,
|
||||
SF_MULTICAST = 0x00000002L,
|
||||
SF_FUNCTIONAL = 0x00000004L,
|
||||
SF_PROMISCUOUS = 0x00000008L,
|
||||
SF_SOFT_ADDRESS = 0x00000010L,
|
||||
SF_STATS_CURRENT = 0x00000020L,
|
||||
SF_INITIATE_DIAGS = 0x00000040L,
|
||||
SF_LOOPBACK = 0x00000080L,
|
||||
SF_RECEIVE_CHAIN = 0x00000100L,
|
||||
SF_SOURCE_ROUTING = 0x00000200L,
|
||||
SF_RESET_MAC = 0x00000400L,
|
||||
SF_OPEN_CLOSE = 0x00000800L,
|
||||
SF_INTERRUPT_REQUEST = 0x00001000L,
|
||||
SF_SOURCE_ROUTING_BRIDGE = 0x00002000L,
|
||||
SF_VIRTUAL_ADDRESSES = 0x00004000L
|
||||
} NdisMacServiceFlags;
|
||||
|
||||
typedef enum {
|
||||
REQ_INITIATE_BIND = 1,
|
||||
REQ_BIND = 2,
|
||||
REQ_INITIATE_PREBIND = 3,
|
||||
REQ_INITIATE_UNBIND = 4,
|
||||
REQ_UNBIND = 5
|
||||
} NdisSysRequest;
|
||||
|
||||
typedef enum {
|
||||
PM_GET_PROTOCOL_MANAGER_INFO = 1,
|
||||
PM_REGISTER_MODULE = 2,
|
||||
PM_BIND_AND_START = 3,
|
||||
PM_GET_PROTOCOL_MANAGER_LINKAGE = 4,
|
||||
PM_GET_PROTOCOL_INI_PATH = 5,
|
||||
PM_REGISTER_PROTOCOL_MANAGER_INFO = 6,
|
||||
PM_INIT_AND_REGISTER = 7,
|
||||
PM_UNBIND_AND_STOP = 8,
|
||||
PM_BIND_STATUS = 9,
|
||||
PM_REGISTER_STATUS = 10
|
||||
} NdisProtManager;
|
||||
|
||||
|
||||
typedef enum {
|
||||
ERR_SUCCESS = 0x00,
|
||||
ERR_WAIT_FOR_RELEASE = 0x01,
|
||||
ERR_REQUEST_QUEUED = 0x02,
|
||||
ERR_FRAME_NOT_RECOGNIZED = 0x03,
|
||||
ERR_FRAME_REJECTED = 0x04,
|
||||
ERR_FORWARD_FRAME = 0x05,
|
||||
ERR_OUT_OF_RESOURCE = 0x06,
|
||||
ERR_INVALID_PARAMETER = 0x07,
|
||||
ERR_INVALID_FUNCTION = 0x08,
|
||||
ERR_NOT_SUPPORTED = 0x09,
|
||||
ERR_HARDWARE_ERROR = 0x0A,
|
||||
ERR_TRANSMIT_ERROR = 0x0B,
|
||||
ERR_NO_SUCH_DESTINATION = 0x0C,
|
||||
ERR_BUFFER_TOO_SMALL = 0x0D,
|
||||
ERR_ALREADY_STARTED = 0x20,
|
||||
ERR_INCOMPLETE_BINDING = 0x21,
|
||||
ERR_DRIVER_NOT_INITIALIZED = 0x22,
|
||||
ERR_HARDWARE_NOT_FOUND = 0x23,
|
||||
ERR_HARDWARE_FAILURE = 0x24,
|
||||
ERR_CONFIGURATION_FAILURE = 0x25,
|
||||
ERR_INTERRUPT_CONFLICT = 0x26,
|
||||
ERR_INCOMPATIBLE_MAC = 0x27,
|
||||
ERR_INITIALIZATION_FAILED = 0x28,
|
||||
ERR_NO_BINDING = 0x29,
|
||||
ERR_NETWORK_MAY_NOT_BE_CONNECTED = 0x2A,
|
||||
ERR_INCOMPATIBLE_OS_VERSION = 0x2B,
|
||||
ERR_ALREADY_REGISTERED = 0x2C,
|
||||
ERR_PATH_NOT_FOUND = 0x2D,
|
||||
ERR_INSUFFICIENT_MEMORY = 0x2E,
|
||||
ERR_INFO_NOT_FOUND = 0x2F,
|
||||
ERR_GENERAL_FAILURE = 0xFF
|
||||
} NdisError;
|
||||
|
||||
#define NDIS_PARAM_INTEGER 0
|
||||
#define NDIS_PARAM_STRING 1
|
||||
|
||||
#define NDIS_TX_BUF_LENGTH 8
|
||||
#define NDIS_TD_BUF_LENGTH 1
|
||||
#define NDIS_RX_BUF_LENGTH 8
|
||||
|
||||
#define NDIS_PTR_PHYSICAL 0
|
||||
#define NDIS_PTR_VIRTUAL 2
|
||||
|
||||
#define NDIS_PATH "PROTMAN$"
|
||||
|
||||
|
||||
typedef struct _CommonChars {
|
||||
WORD tableSize;
|
||||
BYTE majorNdisVersion; /* 2 - Latest version */
|
||||
BYTE minorNdisVersion; /* 0 */
|
||||
WORD reserved1;
|
||||
BYTE majorModuleVersion;
|
||||
BYTE minorModuleVersion;
|
||||
DWORD moduleFlags;
|
||||
/* 0 - Binding at upper boundary supported
|
||||
* 1 - Binding at lower boundary supported
|
||||
* 2 - Dynamically bound.
|
||||
* 3-31 - Reserved, must be zero.
|
||||
*/
|
||||
BYTE moduleName[16];
|
||||
BYTE protocolLevelUpper;
|
||||
/* 1 - MAC
|
||||
* 2 - Data Link
|
||||
* 3 - Network
|
||||
* 4 - Transport
|
||||
* 5 - Session
|
||||
* -1 - Not specified
|
||||
*/
|
||||
BYTE interfaceUpper;
|
||||
BYTE protocolLevelLower;
|
||||
/* 0 - Physical
|
||||
* 1 - MAC
|
||||
* 2 - Data Link
|
||||
* 3 - Network
|
||||
* 4 - Transport
|
||||
* 5 - Session
|
||||
* -1 - Not specified
|
||||
*/
|
||||
BYTE interfaceLower;
|
||||
WORD moduleId;
|
||||
WORD moduleDS;
|
||||
SystemRequest systemRequest;
|
||||
BYTE *serviceChars;
|
||||
BYTE *serviceStatus;
|
||||
BYTE *upperDispatchTable;
|
||||
BYTE *lowerDispatchTable;
|
||||
BYTE *reserved2; /* Must be NULL */
|
||||
BYTE *reserved3; /* Must be NULL */
|
||||
} CommonChars;
|
||||
|
||||
|
||||
typedef struct _MulticastList {
|
||||
WORD maxMulticastAddresses;
|
||||
WORD numberMulticastAddresses;
|
||||
BYTE multicastAddress[16][16];
|
||||
} MulticastList;
|
||||
|
||||
|
||||
typedef struct _MacChars {
|
||||
WORD tableSize;
|
||||
BYTE macName[16];
|
||||
WORD addressLength;
|
||||
BYTE permanentAddress[16];
|
||||
BYTE currentAddress[16];
|
||||
DWORD currentFunctionalAddress;
|
||||
MulticastList *multicastList;
|
||||
DWORD linkSpeed;
|
||||
DWORD serviceFlags;
|
||||
WORD maxFrameSize;
|
||||
DWORD txBufferSize;
|
||||
WORD txBufferAllocSize;
|
||||
DWORD rxBufferSize;
|
||||
WORD rxBufferAllocSize;
|
||||
BYTE ieeeVendor[3];
|
||||
BYTE vendorAdapter;
|
||||
BYTE *vendorAdapterDescription;
|
||||
WORD interruptLevel;
|
||||
WORD txQueueDepth;
|
||||
WORD maxDataBlocks;
|
||||
} MacChars;
|
||||
|
||||
|
||||
typedef struct _ProtocolChars {
|
||||
WORD length;
|
||||
BYTE name[16];
|
||||
WORD type;
|
||||
} ProtocolChars;
|
||||
|
||||
|
||||
typedef struct _MacUpperDispatch {
|
||||
CommonChars *backPointer;
|
||||
Request request;
|
||||
TransmitChain transmitChain;
|
||||
TransferData transferData;
|
||||
ReceiveRelease receiveRelease;
|
||||
IndicationOn indicationOn;
|
||||
IndicationOff indicationOff;
|
||||
} MacUpperDispatch;
|
||||
|
||||
|
||||
typedef struct _MacStatusTable {
|
||||
WORD tableSize;
|
||||
DWORD lastDiag;
|
||||
DWORD macStatus;
|
||||
WORD packetFilter;
|
||||
BYTE *mediaSpecificStats;
|
||||
DWORD lastClear;
|
||||
DWORD totalFramesRx;
|
||||
DWORD totalFramesCrc;
|
||||
DWORD totalBytesRx;
|
||||
DWORD totalDiscardBufSpaceRx;
|
||||
DWORD totalMulticastRx;
|
||||
DWORD totalBroadcastRx;
|
||||
DWORD obsolete1[5];
|
||||
DWORD totalDiscardHwErrorRx;
|
||||
DWORD totalFramesTx;
|
||||
DWORD totalBytesTx;
|
||||
DWORD totalMulticastTx;
|
||||
DWORD totalBroadcastTx;
|
||||
DWORD obsolete2[2];
|
||||
DWORD totalDiscardTimeoutTx;
|
||||
DWORD totalDiscardHwErrorTx;
|
||||
} MacStatusTable;
|
||||
|
||||
|
||||
typedef struct _ProtDispatch {
|
||||
CommonChars *backPointer;
|
||||
DWORD flags;
|
||||
/* 0 - handles non-LLC frames
|
||||
* 1 - handles specific-LSAP LLC frames
|
||||
* 2 - handles specific-LSAP LLC frames
|
||||
* 3-31 - reserved must be 0
|
||||
*/
|
||||
void (*requestConfirm) (void);
|
||||
void (*transmitConfirm) (void);
|
||||
void (*receiveLookahead) (void);
|
||||
void (*indicationComplete) (void);
|
||||
void (*receiveChain) (void);
|
||||
void (*status) (void);
|
||||
} ProtDispatch;
|
||||
|
||||
|
||||
typedef struct _ReqBlock {
|
||||
WORD opcode;
|
||||
WORD status;
|
||||
BYTE FAR *pointer1;
|
||||
BYTE FAR *pointer2;
|
||||
WORD word1;
|
||||
} ReqBlock;
|
||||
|
||||
|
||||
typedef struct _TxBufDescrRec {
|
||||
BYTE txPtrType;
|
||||
BYTE dummy;
|
||||
WORD txDataLen;
|
||||
BYTE *txDataPtr;
|
||||
} TxBufDescrRec;
|
||||
|
||||
|
||||
typedef struct _TxBufDescr {
|
||||
WORD txImmedLen;
|
||||
BYTE *txImmedPtr;
|
||||
WORD txDataCount;
|
||||
TxBufDescrRec txBufDescrRec[NDIS_TX_BUF_LENGTH];
|
||||
} TxBufDescr;
|
||||
|
||||
|
||||
typedef struct _TDBufDescrRec {
|
||||
BYTE tDPtrType;
|
||||
BYTE dummy;
|
||||
WORD tDDataLen;
|
||||
BYTE *tDDataPtr;
|
||||
} TDBufDescrRec;
|
||||
|
||||
|
||||
typedef struct _TDBufDescr {
|
||||
WORD tDDataCount;
|
||||
TDBufDescrRec tDBufDescrRec[NDIS_TD_BUF_LENGTH];
|
||||
} TDBufDescr;
|
||||
|
||||
|
||||
typedef struct _RxBufDescrRec {
|
||||
WORD rxDataLen;
|
||||
BYTE *rxDataPtr;
|
||||
} RxBufDescrRec;
|
||||
|
||||
|
||||
typedef struct _RxBufDescr {
|
||||
WORD rxDataCount;
|
||||
RxBufDescrRec rxBufDescrRec[NDIS_RX_BUF_LENGTH];
|
||||
} RxBufDescr;
|
||||
|
||||
|
||||
typedef struct _PktBuf {
|
||||
struct _PktBuf *nextLink;
|
||||
struct _PktBuf *prevLink;
|
||||
int handle;
|
||||
int length;
|
||||
int packetLength;
|
||||
DWORD sequence;
|
||||
BYTE *buffer;
|
||||
} PktBuf;
|
||||
|
||||
|
||||
typedef struct _CardHandle {
|
||||
BYTE moduleName[16];
|
||||
CommonChars *common;
|
||||
} CardHandle;
|
||||
|
||||
|
||||
typedef struct _BindingsList {
|
||||
WORD numBindings;
|
||||
BYTE moduleName[2][16];
|
||||
} BindingsList;
|
||||
|
||||
|
||||
typedef struct _FailingModules {
|
||||
BYTE upperModuleName[16];
|
||||
BYTE lowerModuleName[16];
|
||||
} FailingModules;
|
||||
|
||||
|
||||
typedef union _HardwareAddress {
|
||||
BYTE bytes[6];
|
||||
WORD words[3];
|
||||
struct {
|
||||
BYTE bytes[6];
|
||||
} addr;
|
||||
} HardwareAddress;
|
||||
|
||||
|
||||
typedef struct _FddiHeader {
|
||||
BYTE frameControl;
|
||||
HardwareAddress etherDestHost;
|
||||
HardwareAddress etherSrcHost;
|
||||
} FddiHeader;
|
||||
|
||||
|
||||
typedef struct _EthernetIIHeader {
|
||||
HardwareAddress etherDestHost;
|
||||
HardwareAddress etherSrcHost;
|
||||
WORD etherType;
|
||||
} EthernetIIHeader;
|
||||
|
||||
|
||||
typedef struct _Ieee802Dot5Header {
|
||||
HardwareAddress etherDestHost;
|
||||
HardwareAddress etherSrcHost;
|
||||
BYTE routeInfo[30];
|
||||
} Ieee802Dot5Header;
|
||||
|
||||
|
||||
typedef struct _Ieee802Dot2SnapHeader {
|
||||
BYTE dsap; /* 0xAA */
|
||||
BYTE ssap; /* 0xAA */
|
||||
BYTE control; /* 3 */
|
||||
BYTE protocolId[5];
|
||||
} Ieee802Dot2SnapHeader;
|
||||
|
||||
|
||||
/*
|
||||
* Prototypes
|
||||
*/
|
||||
extern char *NdisLastError (void);
|
||||
extern int NdisOpen (void);
|
||||
extern int NdisInit (int promis);
|
||||
extern int NdisRegisterAndBind (int promis);
|
||||
extern void NdisShutdown (void);
|
||||
extern void NdisCheckMacFeatures (struct _CardHandle *card);
|
||||
extern int NdisSendPacket (struct _PktBuf *pktBuf, int macId);
|
||||
|
||||
/*
|
||||
* Assembly "glue" functions
|
||||
*/
|
||||
extern int systemRequestGlue();
|
||||
extern int requestConfirmGlue();
|
||||
extern int transmitConfirmGlue();
|
||||
extern int receiveLookaheadGlue();
|
||||
extern int indicationCompleteGlue();
|
||||
extern int receiveChainGlue();
|
||||
extern int statusGlue();
|
||||
|
||||
/*
|
||||
* IOCTL function
|
||||
*/
|
||||
#ifdef __SMALL__
|
||||
extern int _far NdisGetLinkage (int handle, char *data, int size);
|
||||
#else
|
||||
extern int NdisGetLinkage (int handle, char *data, int size);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* NDIS callback handlers
|
||||
*/
|
||||
CALLBACK (NdisSystemRequest (DWORD,DWORD, WORD, WORD, WORD));
|
||||
CALLBACK (NdisRequestConfirm ( WORD, WORD, WORD, WORD, WORD,WORD));
|
||||
CALLBACK (NdisTransmitConfirm ( WORD, WORD, WORD, WORD, WORD));
|
||||
CALLBACK (NdisReceiveLookahead ( WORD, WORD, WORD, BYTE*, BYTE*, WORD));
|
||||
CALLBACK (NdisReceiveChain ( WORD, WORD, WORD, struct _RxBufDescr*, BYTE*, WORD));
|
||||
CALLBACK (NdisStatusProc ( WORD, WORD, BYTE*, WORD,WORD));
|
||||
CALLBACK (NdisIndicationComplete( WORD, WORD));
|
||||
|
||||
BYTE *NdisAllocStack (void);
|
||||
void NdisFreeStack (BYTE*);
|
||||
|
||||
#ifdef __HIGHC__
|
||||
#define RENAME_ASM_SYM(x) pragma Alias(x,"@" #x "") /* prepend `@' */
|
||||
#define RENAME_C_SYM(x) pragma Alias(x,"_" #x "") /* prepend `_' */
|
||||
|
||||
RENAME_ASM_SYM (systemRequestGlue);
|
||||
RENAME_ASM_SYM (requestConfirmGlue);
|
||||
RENAME_ASM_SYM (transmitConfirmGlue);
|
||||
RENAME_ASM_SYM (receiveLookaheadGlue);
|
||||
RENAME_ASM_SYM (indicationCompleteGlue);
|
||||
RENAME_ASM_SYM (receiveChainGlue);
|
||||
RENAME_ASM_SYM (statusGlue);
|
||||
RENAME_ASM_SYM (NdisGetLinkage);
|
||||
RENAME_C_SYM (NdisSystemRequest);
|
||||
RENAME_C_SYM (NdisRequestConfirm);
|
||||
RENAME_C_SYM (NdisTransmitConfirm);
|
||||
RENAME_C_SYM (NdisReceiveLookahead);
|
||||
RENAME_C_SYM (NdisIndicationComplete);
|
||||
RENAME_C_SYM (NdisReceiveChain);
|
||||
RENAME_C_SYM (NdisStatusProc);
|
||||
RENAME_C_SYM (NdisAllocStack);
|
||||
RENAME_C_SYM (NdisFreeStack);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
188
libpcap-possiblymodified/msdos/ndis_0.asm
Normal file
188
libpcap-possiblymodified/msdos/ndis_0.asm
Normal file
@@ -0,0 +1,188 @@
|
||||
PAGE 60,132
|
||||
NAME NDIS_0
|
||||
|
||||
ifdef DOSX
|
||||
.386
|
||||
_TEXT SEGMENT PUBLIC DWORD USE16 'CODE'
|
||||
_TEXT ENDS
|
||||
_DATA SEGMENT PUBLIC DWORD USE16 'CODE'
|
||||
_DATA ENDS
|
||||
_TEXT32 SEGMENT PUBLIC BYTE USE32 'CODE'
|
||||
_TEXT32 ENDS
|
||||
CB_DSEG EQU <CS> ; DOSX is tiny-model
|
||||
D_SEG EQU <_TEXT SEGMENT>
|
||||
D_END EQU <_TEXT ENDS>
|
||||
ASSUME CS:_TEXT,DS:_TEXT
|
||||
|
||||
PUSHREGS equ <pushad>
|
||||
POPREGS equ <popad>
|
||||
|
||||
PUBPROC macro name
|
||||
align 4
|
||||
public @&name
|
||||
@&name label near
|
||||
endm
|
||||
else
|
||||
.286
|
||||
_TEXT SEGMENT PUBLIC DWORD 'CODE'
|
||||
_TEXT ENDS
|
||||
_DATA SEGMENT PUBLIC DWORD 'DATA'
|
||||
_DATA ENDS
|
||||
CB_DSEG EQU <SEG _DATA> ; 16bit is small/large model
|
||||
D_SEG EQU <_DATA SEGMENT>
|
||||
D_END EQU <_DATA ENDS>
|
||||
ASSUME CS:_TEXT,DS:_DATA
|
||||
|
||||
PUSHREGS equ <pusha>
|
||||
POPREGS equ <popa>
|
||||
|
||||
PUBPROC macro name
|
||||
public _&name
|
||||
_&name label far
|
||||
endm
|
||||
endif
|
||||
|
||||
;-------------------------------------------
|
||||
|
||||
D_SEG
|
||||
|
||||
D_END
|
||||
|
||||
|
||||
_TEXT SEGMENT
|
||||
|
||||
EXTRN _NdisSystemRequest : near
|
||||
EXTRN _NdisRequestConfirm : near
|
||||
EXTRN _NdisTransmitConfirm : near
|
||||
EXTRN _NdisReceiveLookahead : near
|
||||
EXTRN _NdisIndicationComplete : near
|
||||
EXTRN _NdisReceiveChain : near
|
||||
EXTRN _NdisStatusProc : near
|
||||
EXTRN _NdisAllocStack : near
|
||||
EXTRN _NdisFreeStack : near
|
||||
|
||||
;
|
||||
; *ALL* interrupt threads come through this macro.
|
||||
;
|
||||
CALLBACK macro callbackProc, argsSize
|
||||
|
||||
pushf
|
||||
PUSHREGS ;; Save the registers
|
||||
|
||||
push es
|
||||
push ds
|
||||
mov ax,CB_DSEG ;; Load DS
|
||||
mov ds,ax
|
||||
call _NdisAllocStack ;; Get and install a stack.
|
||||
|
||||
mov bx,ss ;; Save off the old stack in other regs
|
||||
mov cx,sp
|
||||
mov ss,dx ;; Install the new one
|
||||
mov sp,ax
|
||||
push bx ;; Save the old one on to the new stack
|
||||
push cx
|
||||
sub sp,&argsSize ;; Allocate space for arguments on the stack
|
||||
|
||||
mov ax,ss ;; Set up the destination for the move
|
||||
mov es,ax
|
||||
mov di,sp
|
||||
mov ds,bx ;; Set up the source for the move.
|
||||
mov si,cx
|
||||
add si,4+6+32
|
||||
|
||||
mov cx,&argsSize ;; Move the arguments to the stack.
|
||||
shr cx,1
|
||||
cld
|
||||
rep movsw
|
||||
|
||||
mov ax,CB_DSEG ;; Set my data segment again.
|
||||
mov ds,ax
|
||||
|
||||
call &callbackProc ;; Call the real callback.
|
||||
pop di ;; Pop off the old stack
|
||||
pop si
|
||||
mov bx,ss ;; Save off the current allocated stack.
|
||||
mov cx,sp
|
||||
mov ss,si ;; Restore the old stack
|
||||
mov sp,di
|
||||
push ax ;; Save the return code
|
||||
push bx ;; Free the stack. Push the pointer to it
|
||||
push cx
|
||||
call _NdisFreeStack
|
||||
add sp,4
|
||||
pop ax ;; Get the return code back
|
||||
add di,32 ;; Get a pointer to ax on the stack
|
||||
mov word ptr ss:[di],ax
|
||||
pop ds
|
||||
pop es
|
||||
|
||||
POPREGS
|
||||
popf
|
||||
endm
|
||||
|
||||
;
|
||||
; Define all of the callbacks for the NDIS procs.
|
||||
;
|
||||
|
||||
PUBPROC systemRequestGlue
|
||||
CALLBACK _NdisSystemRequest,14
|
||||
RETF
|
||||
|
||||
PUBPROC requestConfirmGlue
|
||||
CALLBACK _NdisRequestConfirm,12
|
||||
RETF
|
||||
|
||||
PUBPROC transmitConfirmGlue
|
||||
CALLBACK _NdisTransmitConfirm,10
|
||||
RETF
|
||||
|
||||
PUBPROC receiveLookaheadGlue
|
||||
CALLBACK _NdisReceiveLookahead,16
|
||||
RETF
|
||||
|
||||
PUBPROC indicationCompleteGlue
|
||||
CALLBACK _NdisIndicationComplete,4
|
||||
RETF
|
||||
|
||||
PUBPROC receiveChainGlue
|
||||
CALLBACK _NdisReceiveChain,16
|
||||
RETF
|
||||
|
||||
PUBPROC statusGlue
|
||||
CALLBACK _NdisStatusProc,12
|
||||
RETF
|
||||
|
||||
;
|
||||
; int FAR NdisGetLinkage (int handle, char *data, int size);
|
||||
;
|
||||
|
||||
ifdef DOSX
|
||||
PUBPROC NdisGetLinkage
|
||||
push ebx
|
||||
mov ebx, [esp+8] ; device handle
|
||||
mov eax, 4402h ; IOCTRL read function
|
||||
mov edx, [esp+12] ; DS:EDX -> result data
|
||||
mov ecx, [esp+16] ; ECX = length
|
||||
int 21h
|
||||
pop ebx
|
||||
jc @fail
|
||||
xor eax, eax
|
||||
@fail: ret
|
||||
|
||||
else
|
||||
PUBPROC NdisGetLinkage
|
||||
enter 0, 0
|
||||
mov bx, [bp+6]
|
||||
mov ax, 4402h
|
||||
mov dx, [bp+8]
|
||||
mov cx, [bp+12]
|
||||
int 21h
|
||||
jc @fail
|
||||
xor ax, ax
|
||||
@fail: leave
|
||||
retf
|
||||
endif
|
||||
|
||||
ENDS
|
||||
|
||||
END
|
||||
197
libpcap-possiblymodified/msdos/pkt_rx0.asm
Normal file
197
libpcap-possiblymodified/msdos/pkt_rx0.asm
Normal file
@@ -0,0 +1,197 @@
|
||||
PAGE 60,132
|
||||
NAME PKT_RX
|
||||
|
||||
ifdef ??version ; using TASM
|
||||
masm
|
||||
jumps
|
||||
endif
|
||||
|
||||
PUBLIC _pktDrop, _pktRxBuf, _pktTxBuf, _pktTemp
|
||||
PUBLIC _rxOutOfs, _rxInOfs, _PktReceiver, _pktRxEnd
|
||||
|
||||
;
|
||||
; these sizes MUST be equal to the sizes in PKTDRVR.H
|
||||
;
|
||||
|
||||
RX_BUF_SIZE = 1500 ; max message size on Ethernet
|
||||
TX_BUF_SIZE = 1500
|
||||
|
||||
ifdef DOSX
|
||||
.386
|
||||
NUM_RX_BUF = 32 ; # of RX element buffers
|
||||
_TEXT SEGMENT PUBLIC DWORD USE16 'CODE'
|
||||
_TEXT ENDS
|
||||
_DATA SEGMENT PUBLIC DWORD USE16 'CODE'
|
||||
_DATA ENDS
|
||||
D_SEG EQU <_TEXT SEGMENT>
|
||||
D_END EQU <_TEXT ENDS>
|
||||
ASSUME CS:_TEXT,DS:_TEXT
|
||||
else
|
||||
.286
|
||||
NUM_RX_BUF = 10
|
||||
_TEXT SEGMENT PUBLIC DWORD 'CODE'
|
||||
_TEXT ENDS
|
||||
_DATA SEGMENT PUBLIC DWORD 'DATA'
|
||||
_DATA ENDS
|
||||
D_SEG EQU <_DATA SEGMENT>
|
||||
D_END EQU <_DATA ENDS>
|
||||
ASSUME CS:_TEXT,DS:_DATA
|
||||
endif
|
||||
|
||||
;-------------------------------------------
|
||||
|
||||
D_SEG
|
||||
|
||||
RX_ELEMENT STRUC
|
||||
firstCount dw 0 ; # of bytes on 1st call
|
||||
secondCount dw 0 ; # of bytes on 2nd call
|
||||
handle dw 0 ; handle for upcall
|
||||
destinAdr db 6 dup (0) ; packet destination address
|
||||
sourceAdr db 6 dup (0) ; packet source address
|
||||
protocol dw 0 ; packet protocol number
|
||||
rxBuffer db RX_BUF_SIZE dup (0) ; RX buffer
|
||||
ENDS
|
||||
align 4
|
||||
_rxOutOfs dw offset _pktRxBuf ; ring buffer offsets
|
||||
_rxInOfs dw offset _pktRxBuf ; into _pktRxBuf
|
||||
_pktDrop dw 0,0 ; packet drop counter
|
||||
_pktTemp db 20 dup (0) ; temp work area
|
||||
_pktTxBuf db (TX_BUF_SIZE+14) dup (0) ; TX buffer
|
||||
_pktRxBuf RX_ELEMENT NUM_RX_BUF dup (<>) ; RX structures
|
||||
LAST_OFS = offset $
|
||||
|
||||
screenSeg dw 0B800h
|
||||
newInOffset dw 0
|
||||
|
||||
fanChars db '-\|/'
|
||||
fanIndex dw 0
|
||||
|
||||
D_END
|
||||
|
||||
_TEXT SEGMENT
|
||||
|
||||
|
||||
SHOW_RX MACRO
|
||||
push es
|
||||
push bx
|
||||
mov bx, screenSeg
|
||||
mov es, bx ;; r-mode segment of colour screen
|
||||
mov di, 158 ;; upper right corner - 1
|
||||
mov bx, fanIndex
|
||||
mov al, fanChars[bx] ;; get write char
|
||||
mov ah, 15 ;; and white colour
|
||||
stosw ;; write to screen at ES:EDI
|
||||
inc fanIndex ;; update next index
|
||||
and fanIndex, 3
|
||||
pop bx
|
||||
pop es
|
||||
ENDM
|
||||
|
||||
;------------------------------------------------------------------------
|
||||
;
|
||||
; This macro return ES:DI to tail of Rx queue
|
||||
|
||||
ENQUEUE MACRO
|
||||
LOCAL @noWrap
|
||||
mov ax, _rxInOfs ;; DI = current in-offset
|
||||
add ax, SIZE RX_ELEMENT ;; point to next _pktRxBuf buffer
|
||||
cmp ax, LAST_OFS ;; pointing past last ?
|
||||
jb @noWrap ;; no - jump
|
||||
lea ax, _pktRxBuf ;; yes, point to 1st buffer
|
||||
align 4
|
||||
@noWrap: cmp ax, _rxOutOfs ;; in-ofs = out-ofs ?
|
||||
je @dump ;; yes, queue is full
|
||||
mov di, _rxInOfs ;; ES:DI -> buffer at queue input
|
||||
mov newInOffset, ax ;; remember new input offset
|
||||
|
||||
;; NOTE. rxInOfs is updated after the packet has been copied
|
||||
;; to ES:DI (= DS:SI on 2nd call) by the packet driver
|
||||
|
||||
ENDM
|
||||
|
||||
;------------------------------------------------------------------------
|
||||
;
|
||||
; This routine gets called by the packet driver twice:
|
||||
; 1st time (AX=0) it requests an address where to put the packet
|
||||
;
|
||||
; 2nd time (AX=1) the packet has been copied to this location (DS:SI)
|
||||
; BX has client handle (stored in RX_ELEMENT.handle).
|
||||
; CX has # of bytes in packet on both call. They should be equal.
|
||||
;
|
||||
; A test for equality is done by putting CX in _pktRxBuf [n].firstCount
|
||||
; and _pktRxBuf[n].secondCount, and CL on first call in
|
||||
; _pktRxBuf[n].rxBuffer[CX]. These values are checked in "PktReceive"
|
||||
; (PKTDRVR.C)
|
||||
;
|
||||
;---------------------------------------------------------------------
|
||||
|
||||
_PktReceiver:
|
||||
pushf
|
||||
cli ; no distraction wanted !
|
||||
push ds
|
||||
push bx
|
||||
ifdef DOSX
|
||||
mov bx, cs
|
||||
else
|
||||
mov bx, SEG _DATA
|
||||
endif
|
||||
mov ds, bx
|
||||
mov es, bx ; ES = DS = CS or seg _DATA
|
||||
pop bx ; restore handle
|
||||
|
||||
cmp ax, 0 ; first call? (AX=0)
|
||||
jne @post ; AX=1: second call, do post process
|
||||
|
||||
ifdef DEBUG
|
||||
SHOW_RX ; show that a packet is received
|
||||
endif
|
||||
cmp cx, RX_BUF_SIZE+14 ; size OK ?
|
||||
ja @skip ; no, packet to large for us
|
||||
|
||||
ENQUEUE ; ES:DI -> _pktRxBuf[n]
|
||||
|
||||
mov [di].firstCount, cx ; remember the first count.
|
||||
mov [di].handle, bx ; remember the handle.
|
||||
add di, 6 ; ES:DI -> _pktRxBuf[n].destinAdr
|
||||
pop ds
|
||||
popf
|
||||
retf ; far return to driver with ES:DI
|
||||
|
||||
align 4
|
||||
@dump: inc _pktDrop[0] ; discard the packet on 1st call
|
||||
adc _pktDrop[2], 0 ; increment packets lost
|
||||
|
||||
@skip: xor di, di ; return ES:DI = NIL pointer
|
||||
xor ax, ax
|
||||
mov es, ax
|
||||
pop ds
|
||||
popf
|
||||
retf
|
||||
|
||||
align 4
|
||||
@post: or si, si ; DS:SI->_pktRxBuf[n][n].destinAdr
|
||||
jz @discard ; make sure we don't use NULL-pointer
|
||||
|
||||
sub si, 6 ; DS:SI -> _pktRxBuf[n].destinAdr
|
||||
;
|
||||
; push si
|
||||
; push [si].firstCount
|
||||
; call bpf_filter_match ; run the filter here some day?
|
||||
; add sp, 4
|
||||
; cmp ax, 0
|
||||
; je @discard
|
||||
|
||||
mov [si].secondCount, cx
|
||||
mov ax, newInOffset
|
||||
mov _rxInOfs, ax ; update _pktRxBuf input offset
|
||||
|
||||
align 4
|
||||
@discard:pop ds
|
||||
popf
|
||||
retf
|
||||
|
||||
_pktRxEnd db 0 ; marker for end of r-mode code/data
|
||||
|
||||
_TEXT ENDS
|
||||
|
||||
END
|
||||
155
libpcap-possiblymodified/msdos/pkt_rx1.s
Normal file
155
libpcap-possiblymodified/msdos/pkt_rx1.s
Normal file
@@ -0,0 +1,155 @@
|
||||
;
|
||||
; This file requires NASM 0.97+ to assemble
|
||||
;
|
||||
; Currently used only for djgpp + DOS4GW targets
|
||||
;
|
||||
; these sizes MUST be equal to the sizes in PKTDRVR.H
|
||||
;
|
||||
%define ETH_MTU 1500 ; max data size on Ethernet
|
||||
%define ETH_MIN 60 ; min/max total frame size
|
||||
%define ETH_MAX (ETH_MTU+2*6+2)
|
||||
%define NUM_RX_BUF 32 ; # of RX element buffers
|
||||
%define RX_SIZE (ETH_MAX+6) ; sizeof(RX_ELEMENT) = 1514+6
|
||||
%idefine offset
|
||||
|
||||
struc RX_ELEMENT
|
||||
.firstCount resw 1 ; # of bytes on 1st call
|
||||
.secondCount resw 1 ; # of bytes on 2nd call
|
||||
.handle resw 1 ; handle for upcall
|
||||
; .timeStamp resw 4 ; 64-bit RDTSC value
|
||||
.destinAdr resb 6 ; packet destination address
|
||||
.sourceAdr resb 6 ; packet source address
|
||||
.protocol resw 1 ; packet protocol number
|
||||
.rxBuffer resb ETH_MTU ; RX buffer
|
||||
endstruc
|
||||
|
||||
;-------------------------------------------
|
||||
|
||||
[org 0] ; assemble to .bin file
|
||||
|
||||
_rxOutOfs dw offset _pktRxBuf ; ring buffer offsets
|
||||
_rxInOfs dw offset _pktRxBuf ; into _pktRxBuf
|
||||
_pktDrop dw 0,0 ; packet drop counter
|
||||
_pktTemp resb 20 ; temp work area
|
||||
_pktTxBuf resb (ETH_MAX) ; TX buffer
|
||||
_pktRxBuf resb (RX_SIZE*NUM_RX_BUF) ; RX structures
|
||||
LAST_OFS equ $
|
||||
|
||||
screenSeg dw 0B800h
|
||||
newInOffset dw 0
|
||||
|
||||
fanChars db '-\|/'
|
||||
fanIndex dw 0
|
||||
|
||||
%macro SHOW_RX 0
|
||||
push es
|
||||
push bx
|
||||
mov bx, [screenSeg]
|
||||
mov es, bx ;; r-mode segment of colour screen
|
||||
mov di, 158 ;; upper right corner - 1
|
||||
mov bx, [fanIndex]
|
||||
mov al, [fanChars+bx] ;; get write char
|
||||
mov ah, 15 ;; and white colour
|
||||
cld ;; Needed?
|
||||
stosw ;; write to screen at ES:EDI
|
||||
inc word [fanIndex] ;; update next index
|
||||
and word [fanIndex], 3
|
||||
pop bx
|
||||
pop es
|
||||
%endmacro
|
||||
|
||||
;PutTimeStamp
|
||||
; rdtsc
|
||||
; mov [si].timeStamp, eax
|
||||
; mov [si+4].timeStamp, edx
|
||||
; ret
|
||||
|
||||
|
||||
;------------------------------------------------------------------------
|
||||
;
|
||||
; This routine gets called by the packet driver twice:
|
||||
; 1st time (AX=0) it requests an address where to put the packet
|
||||
;
|
||||
; 2nd time (AX=1) the packet has been copied to this location (DS:SI)
|
||||
; BX has client handle (stored in RX_ELEMENT.handle).
|
||||
; CX has # of bytes in packet on both call. They should be equal.
|
||||
; A test for equality is done by putting CX in _pktRxBuf [n].firstCount
|
||||
; and _pktRxBuf[n].secondCount, and CL on first call in
|
||||
; _pktRxBuf[n].rxBuffer[CX]. These values are checked in "PktReceive"
|
||||
; (PKTDRVR.C)
|
||||
;
|
||||
;---------------------------------------------------------------------
|
||||
|
||||
_PktReceiver:
|
||||
pushf
|
||||
cli ; no distraction wanted !
|
||||
push ds
|
||||
push bx
|
||||
mov bx, cs
|
||||
mov ds, bx
|
||||
mov es, bx ; ES = DS = CS or seg _DATA
|
||||
pop bx ; restore handle
|
||||
|
||||
cmp ax, 0 ; first call? (AX=0)
|
||||
jne @post ; AX=1: second call, do post process
|
||||
|
||||
%ifdef DEBUG
|
||||
SHOW_RX ; show that a packet is received
|
||||
%endif
|
||||
|
||||
cmp cx, ETH_MAX ; size OK ?
|
||||
ja @skip ; no, too big
|
||||
|
||||
mov ax, [_rxInOfs]
|
||||
add ax, RX_SIZE
|
||||
cmp ax, LAST_OFS
|
||||
jb @noWrap
|
||||
mov ax, offset _pktRxBuf
|
||||
@noWrap:
|
||||
cmp ax, [_rxOutOfs]
|
||||
je @dump
|
||||
mov di, [_rxInOfs] ; ES:DI -> _pktRxBuf[n]
|
||||
mov [newInOffset], ax
|
||||
|
||||
mov [di], cx ; remember firstCount.
|
||||
mov [di+4], bx ; remember handle.
|
||||
add di, 6 ; ES:DI -> _pktRxBuf[n].destinAdr
|
||||
pop ds
|
||||
popf
|
||||
retf ; far return to driver with ES:DI
|
||||
|
||||
@dump: add word [_pktDrop+0], 1 ; discard the packet on 1st call
|
||||
adc word [_pktDrop+2], 0 ; increment packets lost
|
||||
|
||||
@skip: xor di, di ; return ES:DI = NIL pointer
|
||||
xor ax, ax
|
||||
mov es, ax
|
||||
pop ds
|
||||
popf
|
||||
retf
|
||||
|
||||
@post: or si, si ; DS:SI->_pktRxBuf[n][n].destinAdr
|
||||
jz @discard ; make sure we don't use NULL-pointer
|
||||
|
||||
;
|
||||
; push si
|
||||
; call bpf_filter_match ; run the filter here some day
|
||||
; pop si
|
||||
; cmp ax, 0
|
||||
; je @discard
|
||||
|
||||
mov [si-6+2], cx ; store _pktRxBuf[n].secondCount
|
||||
mov ax, [newInOffset]
|
||||
mov [_rxInOfs], ax ; update _pktRxBuf input offset
|
||||
|
||||
; call PutTimeStamp
|
||||
|
||||
@discard:
|
||||
pop ds
|
||||
popf
|
||||
retf
|
||||
|
||||
_pktRxEnd db 0 ; marker for end of r-mode code/data
|
||||
|
||||
END
|
||||
|
||||
1437
libpcap-possiblymodified/msdos/pktdrvr.c
Normal file
1437
libpcap-possiblymodified/msdos/pktdrvr.c
Normal file
File diff suppressed because it is too large
Load Diff
153
libpcap-possiblymodified/msdos/pktdrvr.h
Normal file
153
libpcap-possiblymodified/msdos/pktdrvr.h
Normal file
@@ -0,0 +1,153 @@
|
||||
#ifndef __PKTDRVR_H
|
||||
#define __PKTDRVR_H
|
||||
|
||||
#define PUBLIC
|
||||
#define LOCAL static
|
||||
|
||||
#define RX_BUF_SIZE ETH_MTU /* buffer size variables. NB !! */
|
||||
#define TX_BUF_SIZE ETH_MTU /* must be same as in pkt_rx*.* */
|
||||
|
||||
#ifdef __HIGHC__
|
||||
#pragma Off(Align_members)
|
||||
#else
|
||||
#pragma pack(1)
|
||||
#endif
|
||||
|
||||
typedef enum { /* Packet-driver classes */
|
||||
PD_ETHER = 1,
|
||||
PD_PRONET10 = 2,
|
||||
PD_IEEE8025 = 3,
|
||||
PD_OMNINET = 4,
|
||||
PD_APPLETALK = 5,
|
||||
PD_SLIP = 6,
|
||||
PD_STARTLAN = 7,
|
||||
PD_ARCNET = 8,
|
||||
PD_AX25 = 9,
|
||||
PD_KISS = 10,
|
||||
PD_IEEE8023_2 = 11,
|
||||
PD_FDDI8022 = 12,
|
||||
PD_X25 = 13,
|
||||
PD_LANstar = 14,
|
||||
PD_PPP = 18
|
||||
} PKT_CLASS;
|
||||
|
||||
typedef enum { /* Packet-driver receive modes */
|
||||
PDRX_OFF = 1, /* turn off receiver */
|
||||
PDRX_DIRECT, /* receive only to this interface */
|
||||
PDRX_BROADCAST, /* DIRECT + broadcast packets */
|
||||
PDRX_MULTICAST1, /* BROADCAST + limited multicast */
|
||||
PDRX_MULTICAST2, /* BROADCAST + all multicast */
|
||||
PDRX_ALL_PACKETS, /* receive all packets on network */
|
||||
} PKT_RX_MODE;
|
||||
|
||||
typedef struct {
|
||||
char type[8];
|
||||
char len;
|
||||
} PKT_FRAME;
|
||||
|
||||
|
||||
typedef struct {
|
||||
BYTE class; /* = 1 for DEC/Interl/Xerox Ethernet */
|
||||
BYTE number; /* = 0 for single LAN adapter */
|
||||
WORD type; /* = 13 for 3C523 */
|
||||
BYTE funcs; /* Basic/Extended/HiPerf functions */
|
||||
WORD intr; /* user interrupt vector number */
|
||||
WORD handle; /* Handle associated with session */
|
||||
BYTE name [15]; /* Name of adapter interface,ie.3C523*/
|
||||
BOOL quiet; /* (don't) print errors to stdout */
|
||||
const char *error; /* address of error string */
|
||||
BYTE majVer; /* Major driver implementation ver. */
|
||||
BYTE minVer; /* Minor driver implementation ver. */
|
||||
BYTE dummyLen; /* length of following data */
|
||||
WORD MAClength; /* HiPerformance data, N/A */
|
||||
WORD MTU; /* HiPerformance data, N/A */
|
||||
WORD multicast; /* HiPerformance data, N/A */
|
||||
WORD rcvrBuffers; /* valid for */
|
||||
WORD UMTbufs; /* High Performance drivers only */
|
||||
WORD postEOIintr; /* Usage ?? */
|
||||
} PKT_INFO;
|
||||
|
||||
#define PKT_PARAM_SIZE 14 /* members majVer - postEOIintr */
|
||||
|
||||
|
||||
typedef struct {
|
||||
DWORD inPackets; /* # of packets received */
|
||||
DWORD outPackets; /* # of packets transmitted */
|
||||
DWORD inBytes; /* # of bytes received */
|
||||
DWORD outBytes; /* # of bytes transmitted */
|
||||
DWORD inErrors; /* # of reception errors */
|
||||
DWORD outErrors; /* # of transmission errors */
|
||||
DWORD lost; /* # of packets lost (RX) */
|
||||
} PKT_STAT;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ETHER destin;
|
||||
ETHER source;
|
||||
WORD proto;
|
||||
BYTE data [TX_BUF_SIZE];
|
||||
} TX_ELEMENT;
|
||||
|
||||
typedef struct {
|
||||
WORD firstCount; /* # of bytes on 1st */
|
||||
WORD secondCount; /* and 2nd upcall */
|
||||
WORD handle; /* instance that upcalled */
|
||||
ETHER destin; /* E-net destination address */
|
||||
ETHER source; /* E-net source address */
|
||||
WORD proto; /* protocol number */
|
||||
BYTE data [RX_BUF_SIZE];
|
||||
} RX_ELEMENT;
|
||||
|
||||
|
||||
#ifdef __HIGHC__
|
||||
#pragma pop(Align_members)
|
||||
#else
|
||||
#pragma pack()
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Prototypes for publics
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern PKT_STAT pktStat; /* statistics for packets */
|
||||
extern PKT_INFO pktInfo; /* packet-driver information */
|
||||
|
||||
extern PKT_RX_MODE receiveMode;
|
||||
extern ETHER myAddress, ethBroadcast;
|
||||
|
||||
extern BOOL PktInitDriver (PKT_RX_MODE mode);
|
||||
extern BOOL PktExitDriver (void);
|
||||
|
||||
extern const char *PktGetErrorStr (int errNum);
|
||||
extern const char *PktGetClassName (WORD class);
|
||||
extern const char *PktRXmodeStr (PKT_RX_MODE mode);
|
||||
extern BOOL PktSearchDriver (void);
|
||||
extern int PktReceive (BYTE *buf, int max);
|
||||
extern BOOL PktTransmit (const void *eth, int len);
|
||||
extern DWORD PktRxDropped (void);
|
||||
extern BOOL PktReleaseHandle (WORD handle);
|
||||
extern BOOL PktTerminHandle (WORD handle);
|
||||
extern BOOL PktResetInterface (WORD handle);
|
||||
extern BOOL PktSetReceiverMode(PKT_RX_MODE mode);
|
||||
extern BOOL PktGetReceiverMode(PKT_RX_MODE *mode);
|
||||
extern BOOL PktGetStatistics (WORD handle);
|
||||
extern BOOL PktSessStatistics (WORD handle);
|
||||
extern BOOL PktResetStatistics(WORD handle);
|
||||
extern BOOL PktGetAddress (ETHER *addr);
|
||||
extern BOOL PktSetAddress (const ETHER *addr);
|
||||
extern BOOL PktGetDriverInfo (void);
|
||||
extern BOOL PktGetDriverParam (void);
|
||||
extern void PktQueueBusy (BOOL busy);
|
||||
extern WORD PktBuffersUsed (void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __PKTDRVR_H */
|
||||
|
||||
162
libpcap-possiblymodified/msdos/readme.dos
Normal file
162
libpcap-possiblymodified/msdos/readme.dos
Normal file
@@ -0,0 +1,162 @@
|
||||
@(#) $Header: /tcpdump/master/libpcap/msdos/readme.dos,v 1.3 2004/12/19 19:47:01 guy Exp $ (LBL)
|
||||
|
||||
libpcap for DOS
|
||||
---------------
|
||||
|
||||
This file contains some notes on building and using libpcap for MS-DOS.
|
||||
Look in `README' and `pcap.man' for usage and details. These targets are
|
||||
supported:
|
||||
|
||||
- Borland C 4.0+ small or large model.
|
||||
- Metaware HighC 3.1+ with PharLap DOS-extender
|
||||
- GNU C 2.7+ with djgpp 2.01+ DOS extender
|
||||
- Watcom C 11.x with DOS4GW extender
|
||||
|
||||
Note: the files in the libpcap.zip contains short trucated filenames.
|
||||
So for djgpp to work with these, disable the use of long file names by
|
||||
setting "LFN=n" in the environment.
|
||||
|
||||
Files specific to DOS are pcap-dos.[ch] and the assembly and C files in
|
||||
the MSDOS sub-directory. Remember to built lipcap libraries from the top
|
||||
install directory. And not from the MSDOS sub-directory.
|
||||
|
||||
Note for djgpp users:
|
||||
If you got the libpcap from the official site www.tcpdump, then that
|
||||
distribution does NOT contain any sources for building 32-bit drivers.
|
||||
Instead get the full version at
|
||||
http://www.bgnett.no/~giva/pcap/libpcap.zip
|
||||
|
||||
and set "USE_32BIT_DRIVERS = 1" in msdos\common.dj.
|
||||
|
||||
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
DOS-libpcap currently only works reliably with a real-mode Ethernet packet-
|
||||
driver. This driver must be installed prior to using any program (e.g.
|
||||
tcpdump) compiled with libpcap. Work is underway to implement protected-
|
||||
mode drivers for 32-bit targets (djgpp only). The 3Com 3c509 driver is
|
||||
working almost perfectly. Due to lack of LAN-cards, I've not had the
|
||||
opportunity to test other drivers. These 32-bit drivers are modified
|
||||
Linux drivers.
|
||||
|
||||
|
||||
Required packages
|
||||
-----------------
|
||||
|
||||
The following packages and tools must be present for all targets.
|
||||
|
||||
1. Watt-32 tcp/ip library. This library is *not* used to send or
|
||||
receive network data. It's mostly used to access the 'hosts'
|
||||
file and other <netdb.h> features. Get 'watt32s*.zip' at:
|
||||
|
||||
http://www.bgnett.no/~giva/
|
||||
|
||||
2. Exception handler and disassember library (libexc.a) is needed if
|
||||
"USE_EXCEPT = 1" in common.dj. Available at:
|
||||
|
||||
http://www.bgnett.no/~giva/misc/exc_dx07.zip
|
||||
|
||||
3. Flex & Bison is used to generate parser for the filter handler
|
||||
pcap_compile:
|
||||
|
||||
ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2gnu/flx254b.zip
|
||||
ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2gnu/bsn128b.zip
|
||||
|
||||
4. NASM assembler v 0.98 or later is required when building djgpp and
|
||||
Watcom targets:
|
||||
|
||||
ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2tk/nasm098p.zip
|
||||
|
||||
5. sed (Stream Editor) is required for doing `make depend'.
|
||||
It's available at
|
||||
ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2gnu/sed*.zip
|
||||
|
||||
A touch tool to update the time-stamp of a file. E.g.
|
||||
ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2gnu/grep*.zip
|
||||
|
||||
6. For djgpp rm.exe and cp.exe are required. These should already be
|
||||
part of your djgpp installation. Also required (experimental at the
|
||||
time) for djgpp is DLX 2.91 or later. This tool is for the generation
|
||||
of dynamically loadable modules.
|
||||
|
||||
|
||||
Compiling libpcap
|
||||
-----------------
|
||||
|
||||
Follow these steps in building libpcap:
|
||||
|
||||
1. Make sure you've installed Watt-32 properly (see it's `INSTALL' file).
|
||||
During that installation a environment variable `WATT_ROOT' is set.
|
||||
This variable is used for building libpcap also (`WATT_INC' is
|
||||
deducted from `WATT_ROOT'). djgpp users should also define environment
|
||||
variables `C_INCLUDE_PATH' and `LIBRARY_PATH' to point to the include
|
||||
directory and library directory respectively. E.g. put this in your
|
||||
AUTOEXEC.BAT:
|
||||
set C_INCLUDE_PATH=c:/net/watt/inc
|
||||
set LIBRARY_PATH=c:/net/watt/lib
|
||||
|
||||
2. Revise the msdos/common.dj file for your djgpp/gcc installation;
|
||||
- change the value of `GCCLIB' to match location of libgcc.a.
|
||||
- set `USE_32BIT_DRIVERS = 1' to build 32-bit driver objects.
|
||||
|
||||
|
||||
3. Build pcap by using appropriate makefile. For djgpp, use:
|
||||
`make -f msdos/makefile.dj' (i.e. GNU `make')
|
||||
|
||||
For a Watcom target say:
|
||||
`wmake -f msdos\makefile.wc'
|
||||
|
||||
For a Borland target say:
|
||||
`maker -f msdos\Makefile pcap_bc.lib' (Borland's `maker.exe')
|
||||
|
||||
And for a HighC/Pharlap target say:
|
||||
`maker -f msdos\Makefile pcap_hc.lib' (Borland's `maker.exe')
|
||||
|
||||
You might like to change some `CFLAGS' -- only `DEBUG' define currently
|
||||
have any effect. It shows a rotating "fan" in upper right corner of
|
||||
screen. Remove `DEBUG' if you don't like it. You could add
|
||||
`-fomit-frame-pointer' to `CFLAGS' to speed up the generated code.
|
||||
But note, this makes debugging and crash-traceback difficult. Only
|
||||
add it if you're fully confident your application is 100% stable.
|
||||
|
||||
Note: Code in `USE_NDIS2' does not work at the moment.
|
||||
|
||||
4. The resulting libraries are put in current directory. There's no
|
||||
test-program for `libpcap'. Linking the library with `tcpdump' is
|
||||
the ultimate test anyway.
|
||||
|
||||
|
||||
|
||||
Extensions to libpcap
|
||||
---------------------
|
||||
|
||||
I've included some extra functions to DOS-libpcap:
|
||||
|
||||
`pcap_config_hook (const char *name, const char *value)'
|
||||
|
||||
Allows an application to set values of internal libpcap variables.
|
||||
`name' is typically a left-side keyword with an associated `value'
|
||||
that is called from application's configure process (see tcpdump's
|
||||
config.c file). libpcap keeps a set of tables that are searched for
|
||||
a name/value match. Currently only used to set debug-levels and
|
||||
parameters for the 32-bit network drivers.
|
||||
|
||||
`pcap_set_wait (pcap_t *, void (*)(void), int)' :
|
||||
|
||||
Only effective when reading offline traffic from dump-files.
|
||||
Function `pcap_offline_read()' will wait (and optionally yield)
|
||||
before printing next packet. This will simulate the pace the packets
|
||||
where actually recorded.
|
||||
|
||||
|
||||
|
||||
Happy sniffing !
|
||||
|
||||
|
||||
Gisle Vanem <giva@bgnett.no>
|
||||
<gvanem@broadpark.no>
|
||||
|
||||
October 1999, 2004
|
||||
|
||||
@@ -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>
|
||||
@@ -67,7 +74,7 @@ struct rtentry; /* declarations in <net/if.h> */
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "pcap-int.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;
|
||||
@@ -208,6 +216,51 @@ pcap_nametoport(const char *name, int *port, int *proto)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert a string in the form PPP-PPP, where correspond to ports, to
|
||||
* a starting and ending port in a port range.
|
||||
* Return 0 on failure.
|
||||
*/
|
||||
int
|
||||
pcap_nametoportrange(const char *name, int *port1, int *port2, int *proto)
|
||||
{
|
||||
u_int p1, p2;
|
||||
char *off, *cpy;
|
||||
int save_proto;
|
||||
|
||||
if (sscanf(name, "%d-%d", &p1, &p2) != 2) {
|
||||
if ((cpy = strdup(name)) == NULL)
|
||||
return 0;
|
||||
|
||||
if ((off = strchr(cpy, '-')) == NULL) {
|
||||
free(cpy);
|
||||
return 0;
|
||||
}
|
||||
|
||||
*off = '\0';
|
||||
|
||||
if (pcap_nametoport(cpy, port1, proto) == 0) {
|
||||
free(cpy);
|
||||
return 0;
|
||||
}
|
||||
save_proto = *proto;
|
||||
|
||||
if (pcap_nametoport(off + 1, port2, proto) == 0) {
|
||||
free(cpy);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (*proto != save_proto)
|
||||
*proto = PROTO_UNDEF;
|
||||
} else {
|
||||
*port1 = p1;
|
||||
*port2 = p2;
|
||||
*proto = PROTO_UNDEF;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
pcap_nametoproto(const char *str)
|
||||
{
|
||||
@@ -267,6 +320,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 +457,13 @@ 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
|
||||
#ifndef HAVE_STRUCT_ETHER_ADDR
|
||||
struct ether_addr {
|
||||
unsigned char ether_addr_octet[6];
|
||||
};
|
||||
#endif
|
||||
extern int ether_hostton(const char *, struct ether_addr *);
|
||||
#endif
|
||||
|
||||
/* Use the os supplied routines */
|
||||
|
||||
1
libpcap-possiblymodified/net
Symbolic link
1
libpcap-possiblymodified/net
Symbolic link
@@ -0,0 +1 @@
|
||||
./bpf/net
|
||||
@@ -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)
|
||||
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) &&
|
||||
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,38 +855,46 @@ 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, similarly, a constant AND can be simplified
|
||||
* if we're testing against 0, i.e.:
|
||||
*
|
||||
* 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) {
|
||||
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
|
||||
* jset #ffffffff -> always
|
||||
@@ -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);
|
||||
|
||||
|
||||
65
libpcap-possiblymodified/packaging/pcap.spec
Normal file
65
libpcap-possiblymodified/packaging/pcap.spec
Normal file
@@ -0,0 +1,65 @@
|
||||
%define prefix /usr
|
||||
%define version 0.9
|
||||
|
||||
Summary: packet capture library
|
||||
Name: libpcap
|
||||
Version: %version
|
||||
Release: 1
|
||||
Group: Development/Libraries
|
||||
Copyright: BSD
|
||||
Source: libpcap-0.9-PRE-CVS.tar.gz
|
||||
BuildRoot: /tmp/%{name}-buildroot
|
||||
URL: http://www.tcpdump.org
|
||||
|
||||
%description
|
||||
Packet-capture library LIBPCAP 0.9
|
||||
Now maintained by "The Tcpdump Group"
|
||||
See http://www.tcpdump.org
|
||||
Please send inquiries/comments/reports to tcpdump-workers@tcpdump.org
|
||||
|
||||
%prep
|
||||
%setup
|
||||
|
||||
%post
|
||||
ldconfig
|
||||
|
||||
%build
|
||||
CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=%prefix
|
||||
make
|
||||
|
||||
%install
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
mkdir -p $RPM_BUILD_ROOT/usr/{lib,include}
|
||||
mkdir -p $RPM_BUILD_ROOT/usr/share/man
|
||||
mkdir -p $RPM_BUILD_ROOT/usr/include/net
|
||||
mkdir -p $RPM_BUILD_ROOT/usr/man/man3
|
||||
make install DESTDIR=$RPM_BUILD_ROOT mandir=/usr/share/man
|
||||
cd $RPM_BUILD_ROOT/usr/lib
|
||||
V1=`echo 0.9 | sed 's/\\.[^\.]*$//g'`
|
||||
V2=`echo 0.9 | sed 's/\\.[^\.]*\.[^\.]*$//g'`
|
||||
ln -sf libpcap.so.0.9 libpcap.so.$V1
|
||||
if test "$V2" -ne "$V1"; then
|
||||
ln -sf libpcap.so.$V1 libpcap.so.$V2
|
||||
ln -sf libpcap.so.$V2 libpcap.so
|
||||
else
|
||||
ln -sf libpcap.so.$V1 libpcap.so
|
||||
fi
|
||||
|
||||
#install -m 755 -o root libpcap.a $RPM_BUILD_ROOT/usr/lib
|
||||
#install -m 644 -o root pcap.3 $RPM_BUILD_ROOT/usr/man/man3
|
||||
#install -m 644 -o root pcap.h $RPM_BUILD_ROOT/usr/include
|
||||
#install -m 644 -o root pcap-bpf.h $RPM_BUILD_ROOT/usr/include/net
|
||||
#install -m 644 -o root pcap-namedb.h $RPM_BUILD_ROOT/usr/include
|
||||
|
||||
%clean
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
%files
|
||||
%defattr(-,root,root)
|
||||
%doc LICENSE CHANGES INSTALL.txt README.linux TODO VERSION CREDITS packaging/pcap.spec
|
||||
/usr/lib/libpcap.a
|
||||
/usr/share/man/man3/*
|
||||
/usr/include/pcap.h
|
||||
/usr/include/pcap-bpf.h
|
||||
/usr/include/pcap-namedb.h
|
||||
/usr/lib/libpcap.so*
|
||||
65
libpcap-possiblymodified/packaging/pcap.spec.in
Normal file
65
libpcap-possiblymodified/packaging/pcap.spec.in
Normal file
@@ -0,0 +1,65 @@
|
||||
%define prefix /usr
|
||||
%define version @VERSION@
|
||||
|
||||
Summary: packet capture library
|
||||
Name: libpcap
|
||||
Version: %version
|
||||
Release: 1
|
||||
Group: Development/Libraries
|
||||
Copyright: BSD
|
||||
Source: @NAME@.tar.gz
|
||||
BuildRoot: /tmp/%{name}-buildroot
|
||||
URL: http://www.tcpdump.org
|
||||
|
||||
%description
|
||||
Packet-capture library LIBPCAP @VERSION@
|
||||
Now maintained by "The Tcpdump Group"
|
||||
See http://www.tcpdump.org
|
||||
Please send inquiries/comments/reports to tcpdump-workers@tcpdump.org
|
||||
|
||||
%prep
|
||||
%setup
|
||||
|
||||
%post
|
||||
ldconfig
|
||||
|
||||
%build
|
||||
CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=%prefix
|
||||
make
|
||||
|
||||
%install
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
mkdir -p $RPM_BUILD_ROOT/usr/{lib,include}
|
||||
mkdir -p $RPM_BUILD_ROOT/usr/share/man
|
||||
mkdir -p $RPM_BUILD_ROOT/usr/include/net
|
||||
mkdir -p $RPM_BUILD_ROOT/usr/man/man3
|
||||
make install DESTDIR=$RPM_BUILD_ROOT mandir=/usr/share/man
|
||||
cd $RPM_BUILD_ROOT/usr/lib
|
||||
V1=`echo @VERSION@ | sed 's/\\.[^\.]*$//g'`
|
||||
V2=`echo @VERSION@ | sed 's/\\.[^\.]*\.[^\.]*$//g'`
|
||||
ln -sf libpcap.so.@VERSION@ libpcap.so.$V1
|
||||
if test "$V2" -ne "$V1"; then
|
||||
ln -sf libpcap.so.$V1 libpcap.so.$V2
|
||||
ln -sf libpcap.so.$V2 libpcap.so
|
||||
else
|
||||
ln -sf libpcap.so.$V1 libpcap.so
|
||||
fi
|
||||
|
||||
#install -m 755 -o root libpcap.a $RPM_BUILD_ROOT/usr/lib
|
||||
#install -m 644 -o root pcap.3 $RPM_BUILD_ROOT/usr/man/man3
|
||||
#install -m 644 -o root pcap.h $RPM_BUILD_ROOT/usr/include
|
||||
#install -m 644 -o root pcap-bpf.h $RPM_BUILD_ROOT/usr/include/net
|
||||
#install -m 644 -o root pcap-namedb.h $RPM_BUILD_ROOT/usr/include
|
||||
|
||||
%clean
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
%files
|
||||
%defattr(-,root,root)
|
||||
%doc LICENSE CHANGES INSTALL.txt README.linux TODO VERSION CREDITS packaging/pcap.spec
|
||||
/usr/lib/libpcap.a
|
||||
/usr/share/man/man3/*
|
||||
/usr/include/pcap.h
|
||||
/usr/include/pcap-bpf.h
|
||||
/usr/include/pcap-namedb.h
|
||||
/usr/lib/libpcap.so*
|
||||
@@ -59,7 +59,7 @@ static const char rcsid[] _U_ =
|
||||
#include <net/if_types.h> /* for IFT_ values */
|
||||
#include <sys/sysconfig.h>
|
||||
#include <sys/device.h>
|
||||
#include <odmi.h>
|
||||
#include <sys/cfgodm.h>
|
||||
#include <cf.h>
|
||||
|
||||
#ifdef __64BIT__
|
||||
@@ -105,6 +105,7 @@ static int odmlockid = 0;
|
||||
#include "gencode.h" /* for "no_optimize" */
|
||||
|
||||
static int pcap_setfilter_bpf(pcap_t *p, struct bpf_program *fp);
|
||||
static int pcap_setdirection_bpf(pcap_t *, pcap_direction_t);
|
||||
static int pcap_set_datalink_bpf(pcap_t *p, int dlt);
|
||||
|
||||
static int
|
||||
@@ -142,7 +143,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 +229,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 +257,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 +317,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,6 +541,22 @@ bpf_open(pcap_t *p, char *errbuf)
|
||||
*/
|
||||
do {
|
||||
(void)snprintf(device, sizeof(device), "/dev/bpf%d", n++);
|
||||
/*
|
||||
* 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 +570,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 +587,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 +727,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 +743,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 +756,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 +805,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 +941,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,
|
||||
@@ -813,39 +999,33 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||
*
|
||||
* XXX - what about AIX?
|
||||
*/
|
||||
p->selectable_fd = p->fd; /* assume select() works until we know otherwise */
|
||||
if (uname(&osinfo) == 0) {
|
||||
/*
|
||||
* We can check what OS this is.
|
||||
*/
|
||||
if (strcmp(osinfo.sysname, "FreeBSD") == 0 &&
|
||||
(strcmp(osinfo.release, "4.3") == 0 ||
|
||||
strcmp(osinfo.release, "4.4") == 0))
|
||||
if (strcmp(osinfo.sysname, "FreeBSD") == 0) {
|
||||
if (strncmp(osinfo.release, "4.3-", 4) == 0 ||
|
||||
strncmp(osinfo.release, "4.4-", 4) == 0)
|
||||
p->selectable_fd = -1;
|
||||
else
|
||||
p->selectable_fd = p->fd;
|
||||
} else {
|
||||
/*
|
||||
* We can't find out what OS this is, so assume we can
|
||||
* do a "select()" or "poll()".
|
||||
*/
|
||||
p->selectable_fd = p->fd;
|
||||
}
|
||||
}
|
||||
|
||||
p->read_op = pcap_read_bpf;
|
||||
p->inject_op = pcap_inject_bpf;
|
||||
p->setfilter_op = pcap_setfilter_bpf;
|
||||
p->setdirection_op = pcap_setdirection_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,9 +1073,53 @@ 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);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set direction flag: Which packets do we accept on a forwarding
|
||||
* single device? IN, OUT or both?
|
||||
*/
|
||||
static int
|
||||
pcap_setdirection_bpf(pcap_t *p, pcap_direction_t d)
|
||||
{
|
||||
#ifdef BIOCSSEESENT
|
||||
u_int seesent;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We don't support PCAP_D_OUT.
|
||||
*/
|
||||
if (d == PCAP_D_OUT) {
|
||||
snprintf(p->errbuf, sizeof(p->errbuf),
|
||||
"Setting direction to PCAP_D_OUT is not supported on BPF");
|
||||
return -1;
|
||||
}
|
||||
#ifdef BIOCSSEESENT
|
||||
seesent = (d == PCAP_D_INOUT);
|
||||
if (ioctl(p->fd, BIOCSSEESENT, &seesent) == -1) {
|
||||
(void) snprintf(p->errbuf, sizeof(p->errbuf),
|
||||
"Cannot set direction to %s: %s",
|
||||
(d == PCAP_D_INOUT) ? "PCAP_D_INOUT" : "PCAP_D_IN",
|
||||
strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
return (0);
|
||||
#else
|
||||
(void) snprintf(p->errbuf, sizeof(p->errbuf),
|
||||
"This system doesn't support BIOCSSEESENT, so the direction can't be set");
|
||||
return (-1);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_set_datalink_bpf(pcap_t *p, int dlt)
|
||||
{
|
||||
|
||||
@@ -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 */
|
||||
@@ -142,7 +147,7 @@ struct bpf_version {
|
||||
* XXX - DLT_ATM_RFC1483 is 13 in BSD/OS, and DLT_RAW is 14 in BSD/OS,
|
||||
* but I don't know what the right #define is for BSD/OS.
|
||||
*/
|
||||
#define DLT_ATM_RFC1483 11 /* LLC/SNAP encapsulated atm */
|
||||
#define DLT_ATM_RFC1483 11 /* LLC-encapsulated ATM */
|
||||
|
||||
#ifdef __OpenBSD__
|
||||
#define DLT_RAW 14 /* raw IP */
|
||||
@@ -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
|
||||
@@ -352,10 +363,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
|
||||
@@ -413,11 +425,16 @@ struct bpf_version {
|
||||
#define DLT_APPLE_IP_OVER_IEEE1394 138
|
||||
|
||||
/*
|
||||
* 139 through 142 are reserved for SS7.
|
||||
* Various SS7 encapsulations, as per a request from Jeff Morriss
|
||||
* <jeff.morriss[AT]ulticom.com> and subsequent discussions.
|
||||
*/
|
||||
#define DLT_MTP2_WITH_PHDR 139 /* pseudo-header with various info, followed by MTP2 */
|
||||
#define DLT_MTP2 140 /* MTP2, without pseudo-header */
|
||||
#define DLT_MTP3 141 /* MTP3, without pseudo-header or MTP2 */
|
||||
#define DLT_SCCP 142 /* SCCP, without pseudo-header or MTP2 or MTP3 */
|
||||
|
||||
/*
|
||||
* Reserved for DOCSIS MAC frames.
|
||||
* DOCSIS MAC frames.
|
||||
*/
|
||||
#define DLT_DOCSIS 143
|
||||
|
||||
@@ -493,8 +510,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 */
|
||||
|
||||
@@ -506,6 +523,78 @@ 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 */
|
||||
|
||||
/*
|
||||
* Requested by Daniele Orlandi <daniele@orlandi.com> for raw LAPD
|
||||
* for vISDN (http://www.orlandi.com/visdn/). Its link-layer header
|
||||
* includes additional information before the LAPD header, so it's
|
||||
* not necessarily a generic LAPD header.
|
||||
*/
|
||||
#define DLT_LINUX_LAPD 177
|
||||
|
||||
/*
|
||||
* The instruction encodings.
|
||||
*/
|
||||
|
||||
@@ -9,22 +9,10 @@
|
||||
* 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 <support@endace.com>
|
||||
* Koryn Grant <support@endace.com>
|
||||
* Stephen Donnelly <support@endace.com>
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
@@ -55,12 +43,20 @@ 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;
|
||||
@@ -103,12 +99,12 @@ 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) {
|
||||
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) {
|
||||
for (prev = NULL, curr = pcap_dags; curr != NULL && curr->p != p; prev = curr, curr = curr->next) {
|
||||
/* empty */
|
||||
}
|
||||
|
||||
@@ -126,30 +122,34 @@ 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));
|
||||
if (p != NULL) {
|
||||
#ifdef HAVE_DAG_STREAMS_API
|
||||
if(dag_stop_stream(p->fd, p->md.dag_stream) < 0)
|
||||
fprintf(stderr,"dag_stop_stream: %s\n", strerror(errno));
|
||||
|
||||
free(p->md.device);
|
||||
}
|
||||
if(dag_detach_stream(p->fd, p->md.dag_stream) < 0)
|
||||
fprintf(stderr,"dag_detach_stream: %s\n", strerror(errno));
|
||||
#else
|
||||
if (p != NULL) {
|
||||
if(dag_stop(p->fd) < 0)
|
||||
fprintf(stderr,"dag_stop: %s\n", strerror(errno));
|
||||
#endif /* HAVE_DAG_STREAMS_API */
|
||||
if(dag_close(p->fd) < 0)
|
||||
fprintf(stderr,"dag_close: %s\n", strerror(errno));
|
||||
}
|
||||
#ifdef linux
|
||||
free(p->md.device);
|
||||
#endif
|
||||
}
|
||||
delete_pcap_dag(p);
|
||||
/* Note: don't need to call close(p->fd) here as dag_close(p->fd) does this. */
|
||||
}
|
||||
|
||||
static void atexit_handler(void) {
|
||||
static void
|
||||
atexit_handler(void)
|
||||
{
|
||||
while (pcap_dags != NULL) {
|
||||
if (pcap_dags->pid == getpid()) {
|
||||
dag_platform_close(pcap_dags->p);
|
||||
@@ -159,7 +159,9 @@ static void atexit_handler(void) {
|
||||
}
|
||||
}
|
||||
|
||||
static int new_pcap_dag(pcap_t *p) {
|
||||
static int
|
||||
new_pcap_dag(pcap_t *p)
|
||||
{
|
||||
pcap_dag_node_t *node = NULL;
|
||||
|
||||
if ((node = malloc(sizeof(pcap_dag_node_t))) == NULL) {
|
||||
@@ -185,13 +187,13 @@ 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;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
/* Get the next bufferful of packets (if necessary). */
|
||||
while (p->md.dag_mem_top - p->md.dag_mem_bottom < dag_record_size) {
|
||||
|
||||
@@ -208,12 +210,38 @@ static int dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
#ifdef HAVE_DAG_STREAMS_API
|
||||
/* dag_advance_stream() will block (unless nonblock is called)
|
||||
* until 64kB of data has accumulated.
|
||||
* If to_ms is set, it will timeout before 64kB has accumulated.
|
||||
* We wait for 64kB because processing a few packets at a time
|
||||
* can cause problems at high packet rates (>200kpps) due
|
||||
* to inefficiencies.
|
||||
* This does mean if to_ms is not specified the capture may 'hang'
|
||||
* for long periods if the data rate is extremely slow (<64kB/sec)
|
||||
* If non-block is specified it will return immediately. The user
|
||||
* is then responsible for efficiency.
|
||||
*/
|
||||
p->md.dag_mem_top = dag_advance_stream(p->fd, p->md.dag_stream, (void**)&(p->md.dag_mem_bottom));
|
||||
#else
|
||||
/* dag_offset does not support timeouts */
|
||||
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)
|
||||
#endif /* HAVE_DAG_STREAMS_API */
|
||||
|
||||
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. */
|
||||
/* Pcap is configured to process only available packets, and there aren't any, return immediately. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(!nonblocking &&
|
||||
p->md.dag_timeout &&
|
||||
(p->md.dag_mem_top - p->md.dag_mem_bottom < dag_record_size))
|
||||
{
|
||||
/* Blocking mode, but timeout set and no data has arrived, return anyway.*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Process the packets. */
|
||||
@@ -223,7 +251,12 @@ static int dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) {
|
||||
int caplen = 0;
|
||||
struct pcap_pkthdr pcap_header;
|
||||
|
||||
#ifdef HAVE_DAG_STREAMS_API
|
||||
dag_record_t *header = (dag_record_t *)(p->md.dag_mem_bottom);
|
||||
#else
|
||||
dag_record_t *header = (dag_record_t *)(p->md.dag_mem_base + p->md.dag_mem_bottom);
|
||||
#endif /* HAVE_DAG_STREAMS_API */
|
||||
|
||||
u_char *dp = ((u_char *)header) + dag_record_size;
|
||||
unsigned short rlen;
|
||||
|
||||
@@ -240,68 +273,117 @@ 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;
|
||||
#ifdef TYPE_MC_ATM
|
||||
case TYPE_MC_ATM:
|
||||
if (header->type == TYPE_MC_ATM) {
|
||||
caplen = packet_len = ATM_CELL_SIZE;
|
||||
dp += 4;
|
||||
}
|
||||
#endif
|
||||
#ifdef TYPE_MC_AAL5
|
||||
case TYPE_MC_AAL5:
|
||||
if (header->type == TYPE_MC_AAL5) {
|
||||
packet_len = ntohs(header->wlen);
|
||||
caplen = rlen - dag_record_size - 4;
|
||||
dp+=4;
|
||||
}
|
||||
#endif
|
||||
if (header->type == TYPE_AAL5) {
|
||||
packet_len = ntohs(header->wlen);
|
||||
caplen = rlen - dag_record_size;
|
||||
} else if(header->type == TYPE_ATM) {
|
||||
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;
|
||||
|
||||
#ifdef TYPE_COLOR_ETH
|
||||
case TYPE_COLOR_ETH:
|
||||
#endif
|
||||
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;
|
||||
|
||||
#ifdef TYPE_COLOR_HDLC_POS
|
||||
case TYPE_COLOR_HDLC_POS:
|
||||
#endif
|
||||
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;
|
||||
#ifdef TYPE_MC_HDLC
|
||||
case TYPE_MC_HDLC:
|
||||
packet_len = ntohs(header->wlen);
|
||||
packet_len -= (p->md.dag_fcs_bits >> 3);
|
||||
caplen = rlen - dag_record_size - 4;
|
||||
if (caplen > packet_len) {
|
||||
caplen = packet_len;
|
||||
}
|
||||
dp += 4;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (caplen > p->snapshot)
|
||||
caplen = p->snapshot;
|
||||
|
||||
/* Count lost packets. */
|
||||
switch(header->type) {
|
||||
#ifdef TYPE_COLOR_HDLC_POS
|
||||
/* in this type the color value overwrites the lctr */
|
||||
case TYPE_COLOR_HDLC_POS:
|
||||
break;
|
||||
#endif
|
||||
#ifdef TYPE_COLOR_ETH
|
||||
/* in this type the color value overwrites the lctr */
|
||||
case TYPE_COLOR_ETH:
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
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,12 +393,9 @@ 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;
|
||||
}
|
||||
|
||||
@@ -349,13 +428,15 @@ static int dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) {
|
||||
}
|
||||
}
|
||||
|
||||
if (nonblocking || processed)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -366,11 +447,20 @@ 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) {
|
||||
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;
|
||||
char * newDev;
|
||||
#ifdef HAVE_DAG_STREAMS_API
|
||||
uint32_t mindata;
|
||||
struct timeval maxwait;
|
||||
struct timeval poll;
|
||||
#endif
|
||||
|
||||
if (device == NULL) {
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "device is NULL: %s", pcap_strerror(errno));
|
||||
@@ -388,8 +478,23 @@ pcap_t *dag_open_live(const char *device, int snaplen, int promisc, int to_ms, c
|
||||
|
||||
memset(handle, 0, sizeof(*handle));
|
||||
|
||||
newDev = (char *)malloc(strlen(device) + 16);
|
||||
|
||||
#ifdef HAVE_DAG_STREAMS_API
|
||||
|
||||
/* Parse input name to get dag device and stream number if provided */
|
||||
if (dag_parse_name(device, newDev, strlen(device) + 16, &handle->md.dag_stream) < 0) {
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "dag_parse_name: %s\n", pcap_strerror(errno));
|
||||
goto fail;
|
||||
}
|
||||
device = newDev;
|
||||
|
||||
if (handle->md.dag_stream%2) {
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "dag_parse_name: tx (even numbered) streams not supported for capture\n");
|
||||
goto fail;
|
||||
}
|
||||
#else
|
||||
if (strstr(device, "/dev") == NULL) {
|
||||
char * newDev = (char *)malloc(strlen(device) + 6);
|
||||
newDev[0] = '\0';
|
||||
strcat(newDev, "/dev/");
|
||||
strcat(newDev,device);
|
||||
@@ -402,6 +507,7 @@ pcap_t *dag_open_live(const char *device, int snaplen, int promisc, int to_ms, c
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "str_dup: %s\n", pcap_strerror(errno));
|
||||
goto fail;
|
||||
}
|
||||
#endif /* HAVE_DAG_STREAMS_API */
|
||||
|
||||
/* setup device parameters */
|
||||
if((handle->fd = dag_open((char *)device)) < 0) {
|
||||
@@ -409,6 +515,48 @@ pcap_t *dag_open_live(const char *device, int snaplen, int promisc, int to_ms, c
|
||||
goto fail;
|
||||
}
|
||||
|
||||
#ifdef HAVE_DAG_STREAMS_API
|
||||
/* Open requested stream. Can fail if already locked or on error */
|
||||
if (dag_attach_stream(handle->fd, handle->md.dag_stream, 0, 0) < 0) {
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "dag_attach_stream: %s\n", pcap_strerror(errno));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Set up default poll parameters for stream
|
||||
* Can be overridden by pcap_set_nonblock()
|
||||
*/
|
||||
if (dag_get_stream_poll(handle->fd, handle->md.dag_stream,
|
||||
&mindata, &maxwait, &poll) < 0) {
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "dag_get_stream_poll: %s\n", pcap_strerror(errno));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Amount of data to collect in Bytes before calling callbacks.
|
||||
* Important for efficiency, but can introduce latency
|
||||
* at low packet rates if to_ms not set!
|
||||
*/
|
||||
mindata = 65536;
|
||||
|
||||
/* Obey to_ms if supplied. This is a good idea!
|
||||
* Recommend 10-100ms. Calls will time out even if no data arrived.
|
||||
*/
|
||||
maxwait.tv_sec = to_ms/1000;
|
||||
maxwait.tv_usec = (to_ms%1000) * 1000;
|
||||
|
||||
if (dag_set_stream_poll(handle->fd, handle->md.dag_stream,
|
||||
mindata, &maxwait, &poll) < 0) {
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "dag_set_stream_poll: %s\n", pcap_strerror(errno));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
#else
|
||||
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;
|
||||
}
|
||||
|
||||
#endif /* HAVE_DAG_STREAMS_API */
|
||||
|
||||
/* set the card snap length to the specified snaplen parameter */
|
||||
if (snaplen == 0 || snaplen > MAX_DAG_SNAPLEN) {
|
||||
snaplen = MAX_DAG_SNAPLEN;
|
||||
@@ -418,21 +566,22 @@ pcap_t *dag_open_live(const char *device, int snaplen, int promisc, int to_ms, c
|
||||
/* 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));
|
||||
#ifdef HAVE_DAG_STREAMS_API
|
||||
if(dag_start_stream(handle->fd, handle->md.dag_stream) < 0) {
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "dag_start_stream %s: %s\n", device, pcap_strerror(errno));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
#else
|
||||
if(dag_start(handle->fd) < 0) {
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "dag_start %s: %s\n", device, pcap_strerror(errno));
|
||||
goto fail;
|
||||
}
|
||||
#endif /* HAVE_DAG_STREAMS_API */
|
||||
|
||||
/*
|
||||
* Important! You have to ensure bottom is properly
|
||||
@@ -441,9 +590,17 @@ pcap_t *dag_open_live(const char *device, int snaplen, int promisc, int to_ms, c
|
||||
*/
|
||||
handle->md.dag_mem_bottom = 0;
|
||||
handle->md.dag_mem_top = 0;
|
||||
|
||||
/* TODO: query the card */
|
||||
handle->md.dag_fcs_bits = 32;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
@@ -455,10 +612,11 @@ pcap_t *dag_open_live(const char *device, int snaplen, int promisc, int to_ms, c
|
||||
}
|
||||
|
||||
handle->snapshot = snaplen;
|
||||
/*handle->md.timeout = to_ms; */
|
||||
handle->md.dag_timeout = to_ms;
|
||||
|
||||
if ((handle->linktype = dag_get_datalink(handle)) < 0) {
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "dag_get_linktype %s: unknown linktype\n", device);
|
||||
handle->linktype = -1;
|
||||
if (dag_get_datalink(handle) < 0) {
|
||||
strcpy(ebuf, handle->errbuf);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@@ -470,19 +628,22 @@ pcap_t *dag_open_live(const char *device, int snaplen, int promisc, int to_ms, c
|
||||
}
|
||||
|
||||
/*
|
||||
* "select()" and "poll()" don't (yet) work on DAG device descriptors.
|
||||
* "select()" and "poll()" don't work on DAG device descriptors.
|
||||
*/
|
||||
handle->selectable_fd = -1;
|
||||
|
||||
#ifdef linux
|
||||
handle->md.device = (char *)device;
|
||||
handle->md.timeout = to_ms;
|
||||
#else
|
||||
free((char *)device);
|
||||
device = NULL;
|
||||
#endif
|
||||
|
||||
handle->read_op = dag_read;
|
||||
handle->inject_op = dag_inject;
|
||||
handle->setfilter_op = dag_setfilter;
|
||||
handle->setdirection_op = NULL; /* Not implemented.*/
|
||||
handle->set_datalink_op = dag_set_datalink;
|
||||
handle->getnonblock_op = pcap_getnonblock_fd;
|
||||
handle->setnonblock_op = dag_setnonblock;
|
||||
@@ -492,17 +653,24 @@ pcap_t *dag_open_live(const char *device, int snaplen, int promisc, int to_ms, c
|
||||
return handle;
|
||||
|
||||
fail:
|
||||
if (device != NULL) {
|
||||
free((char *)device);
|
||||
if (newDev != NULL) {
|
||||
free((char *)newDev);
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
static int dag_stats(pcap_t *p, struct pcap_stat *ps) {
|
||||
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.
|
||||
*/
|
||||
@@ -515,98 +683,42 @@ static int dag_stats(pcap_t *p, struct pcap_stat *ps) {
|
||||
}
|
||||
|
||||
/*
|
||||
* Get from "/proc/dag" all interfaces listed there; if they're
|
||||
* already in the list of interfaces we have, that won't add another
|
||||
* instance, but if they're not, that'll add them.
|
||||
*
|
||||
* We don't bother getting any addresses for them.
|
||||
*
|
||||
* We also don't fail if we couldn't open "/proc/dag"; we just leave
|
||||
* the list of interfaces as is.
|
||||
* Simply submit all possible dag names as candidates.
|
||||
* pcap_add_if() internally tests each candidate with pcap_open_live(),
|
||||
* so any non-existent devices are dropped.
|
||||
* For 2.5 try all rx stream names as well.
|
||||
*/
|
||||
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;
|
||||
char name[12]; /* XXX - pick a size */
|
||||
int ret = 0;
|
||||
int c;
|
||||
|
||||
/* 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) {
|
||||
/* Try all the DAGs 0-9 */
|
||||
for (c = 0; c < 9; c++) {
|
||||
snprintf(name, 12, "dag%d", c);
|
||||
if (pcap_add_if(devlistp, name, 0, NULL, errbuf) == -1) {
|
||||
/*
|
||||
* Failure.
|
||||
*/
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
for (linenum = 1;
|
||||
fgets(linebuf, sizeof linebuf, proc_dag_f) != NULL; linenum++) {
|
||||
|
||||
/*
|
||||
* Skip the first two lines - they're headers.
|
||||
*/
|
||||
if (linenum <= 2)
|
||||
continue;
|
||||
|
||||
p = &linebuf[0];
|
||||
|
||||
if (*p == '\0' || *p == '\n' || *p != 'D')
|
||||
continue; /* not a Dag line */
|
||||
|
||||
/*
|
||||
* Get the interface name.
|
||||
*/
|
||||
q = &name[0];
|
||||
while (*p != '\0' && *p != ':') {
|
||||
if (*p != ' ')
|
||||
*q++ = tolower(*p++);
|
||||
else
|
||||
p++;
|
||||
}
|
||||
*q = '\0';
|
||||
|
||||
/*
|
||||
* Add an entry for this interface, with no addresses.
|
||||
*/
|
||||
p[strlen(p) - 1] = '\0'; /* get rid of \n */
|
||||
if (pcap_add_if(devlistp, name, 0, strdup(p + 2), errbuf) == -1) {
|
||||
#ifdef HAVE_DAG_STREAMS_API
|
||||
{
|
||||
int stream;
|
||||
for(stream=0;stream<16;stream+=2) {
|
||||
snprintf(name, 10, "dag%d:%d", c, stream);
|
||||
if (pcap_add_if(devlistp, name, 0, NULL, errbuf) == -1) {
|
||||
/*
|
||||
* Failure.
|
||||
*/
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ret != -1) {
|
||||
/*
|
||||
* Well, we didn't fail for any other reason; did we
|
||||
* fail due to an error reading the file?
|
||||
*/
|
||||
if (ferror(proc_dag_f)) {
|
||||
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Error reading /proc/dag: %s",
|
||||
pcap_strerror(errno));
|
||||
ret = -1;
|
||||
}
|
||||
#endif /* HAVE_DAG_STREAMS_API */
|
||||
}
|
||||
|
||||
(void)fclose(proc_dag_f);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@@ -615,7 +727,9 @@ 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) {
|
||||
static int
|
||||
dag_setfilter(pcap_t *p, struct bpf_program *fp)
|
||||
{
|
||||
if (!p)
|
||||
return -1;
|
||||
if (!fp) {
|
||||
@@ -626,11 +740,8 @@ static int dag_setfilter(pcap_t *p, struct bpf_program *fp) {
|
||||
|
||||
/* 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));
|
||||
if (install_bpf_program(p, fp) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
p->md.use_bpf = 0;
|
||||
|
||||
@@ -640,6 +751,8 @@ static int dag_setfilter(pcap_t *p, struct bpf_program *fp) {
|
||||
static int
|
||||
dag_set_datalink(pcap_t *p, int dlt)
|
||||
{
|
||||
p->linktype = dlt;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
@@ -654,7 +767,34 @@ dag_setnonblock(pcap_t *p, int nonblock, char *errbuf)
|
||||
*/
|
||||
if (pcap_setnonblock_fd(p, nonblock, errbuf) < 0)
|
||||
return (-1);
|
||||
#ifdef HAVE_DAG_STREAMS_API
|
||||
{
|
||||
uint32_t mindata;
|
||||
struct timeval maxwait;
|
||||
struct timeval poll;
|
||||
|
||||
if (dag_get_stream_poll(p->fd, p->md.dag_stream,
|
||||
&mindata, &maxwait, &poll) < 0) {
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE, "dag_get_stream_poll: %s\n", pcap_strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Amount of data to collect in Bytes before calling callbacks.
|
||||
* Important for efficiency, but can introduce latency
|
||||
* at low packet rates if to_ms not set!
|
||||
*/
|
||||
if(nonblock)
|
||||
mindata = 0;
|
||||
else
|
||||
mindata = 65536;
|
||||
|
||||
if (dag_set_stream_poll(p->fd, p->md.dag_stream,
|
||||
mindata, &maxwait, &poll) < 0) {
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE, "dag_set_stream_poll: %s\n", pcap_strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_DAG_STREAMS_API */
|
||||
if (nonblock) {
|
||||
p->md.dag_offset_flags |= DAGF_NONBLOCK;
|
||||
} else {
|
||||
@@ -666,45 +806,81 @@ 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;
|
||||
|
||||
/* 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);
|
||||
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);
|
||||
}
|
||||
record = (dag_record_t *)(p->md.dag_mem_base + p->md.dag_mem_bottom);
|
||||
|
||||
if ((ntohl(record->rec.pos.hdlc) & 0xffff0000) == 0xff030000) {
|
||||
linktype = DLT_PPP_SERIAL;
|
||||
fprintf(stderr, "Set DAG linktype to %d (DLT_PPP_SERIAL)\n", linktype);
|
||||
} else {
|
||||
linktype = DLT_CHDLC;
|
||||
fprintf(stderr, "Set DAG linktype to %d (DLT_CHDLC)\n", linktype);
|
||||
/* Check the type through a dagapi call. */
|
||||
daglinktype = dag_linktype(p->fd);
|
||||
|
||||
switch(daglinktype) {
|
||||
|
||||
case TYPE_HDLC_POS:
|
||||
case TYPE_COLOR_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->dlt_list[2] = DLT_FRELAY;
|
||||
}
|
||||
p->linktype = DLT_CHDLC;
|
||||
break;
|
||||
}
|
||||
|
||||
case TYPE_ETH:
|
||||
linktype = DLT_EN10MB;
|
||||
fprintf(stderr, "Set DAG linktype to %d (DLT_EN10MB)\n", linktype);
|
||||
case TYPE_COLOR_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:
|
||||
linktype = DLT_ATM_RFC1483;
|
||||
fprintf(stderr, "Set DAG linktype to %d (DLT_ATM_RFC1483)\n", linktype);
|
||||
case TYPE_MC_ATM:
|
||||
case TYPE_MC_AAL5:
|
||||
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_MC_HDLC:
|
||||
if (p->dlt_list != NULL) {
|
||||
p->dlt_count = 4;
|
||||
p->dlt_list[0] = DLT_CHDLC;
|
||||
p->dlt_list[1] = DLT_PPP_SERIAL;
|
||||
p->dlt_list[2] = DLT_FRELAY;
|
||||
p->dlt_list[3] = DLT_MTP2;
|
||||
}
|
||||
p->linktype = DLT_CHDLC;
|
||||
break;
|
||||
|
||||
case TYPE_LEGACY:
|
||||
linktype = DLT_NULL;
|
||||
fprintf(stderr, "Set DAG linktype to %d (DLT_NULL)\n", linktype);
|
||||
p->linktype = DLT_NULL;
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "Unknown DAG linktype %d\n", dag_linktype(p->fd));
|
||||
break;
|
||||
snprintf(p->errbuf, sizeof(p->errbuf), "unknown DAG linktype %d\n", daglinktype);
|
||||
return (-1);
|
||||
|
||||
}
|
||||
|
||||
return linktype;
|
||||
return p->linktype;
|
||||
}
|
||||
|
||||
@@ -11,4 +11,4 @@
|
||||
*/
|
||||
|
||||
pcap_t *dag_open_live(const char *device, int snaplen, int promisc, int to_ms, char *ebuf);
|
||||
|
||||
int dag_platform_finddevs(pcap_if_t **devlistp, char *errbuf);
|
||||
|
||||
@@ -19,7 +19,10 @@
|
||||
* 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), Mark Pizzolato
|
||||
* <List-tcpdump-workers@subscriptions.pizzolato.net>,
|
||||
* and Mark C. Brown (mbrown@hp.com).
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -27,13 +30,42 @@
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* - An older version of the HP-UX DLPI Programmer's Guide, which
|
||||
* I think was advertised as the 10.20 version, 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 10.x, 11.0, and 11i v1.6 version of the HP-UX DLPI
|
||||
* Programmer's Guide, which I think was once advertised as the
|
||||
* 11.00 version is available at
|
||||
*
|
||||
* http://docs.hp.com/en/B2355-90139/index.html
|
||||
*
|
||||
* - The HP-UX 11i v2 version of the HP-UX DLPI Programmer's Guide
|
||||
* is available at
|
||||
*
|
||||
* http://docs.hp.com/en/B2355-90871/index.html
|
||||
*
|
||||
* - All of the HP documents describe raw-mode services, which are
|
||||
* what we use if DL_HP_RAWDLS is defined. XXX - we use __hpux
|
||||
* in some places to test for HP-UX, but use DL_HP_RAWDLS in
|
||||
* other places; do we support any versions of HP-UX without
|
||||
* DL_HP_RAWDLS?
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
@@ -57,7 +89,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 +114,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 +165,23 @@ static const char rcsid[] _U_ =
|
||||
|
||||
/* Forwards */
|
||||
static char *split_dname(char *, int *, char *);
|
||||
static int dl_doattach(int, int, char *);
|
||||
#ifdef DL_HP_RAWDLS
|
||||
static int dl_dohpuxbind(int, char *);
|
||||
#endif
|
||||
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 *, int *);
|
||||
static int dlpromisconreq(int, bpf_u_int32, char *);
|
||||
static int dlokack(int, const char *, char *, char *);
|
||||
static int recv_ack(int, 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 *, int *);
|
||||
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 +203,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 +276,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 +372,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 +443,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 +479,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 +518,21 @@ 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 need separate
|
||||
* descriptors for sending and receiving, bound to different SAPs.
|
||||
*
|
||||
* 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 +578,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,17 +620,26 @@ 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))
|
||||
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)
|
||||
** Bind (defer if using HP-UX 9 or HP-UX 10.20 or later, totally
|
||||
** skip if using SINIX)
|
||||
*/
|
||||
#if !defined(HAVE_HPUX9) && !defined(HAVE_HPUX10_20) && !defined(sinix)
|
||||
#if !defined(HAVE_HPUX9) && !defined(HAVE_HPUX10_20_OR_LATER) && !defined(sinix)
|
||||
#ifdef _AIX
|
||||
/* According to IBM's AIX Support Line, the dl_sap value
|
||||
/*
|
||||
** AIX.
|
||||
** According to IBM's AIX Support Line, the dl_sap value
|
||||
** should not be less than 0x600 (1536) for standard Ethernet.
|
||||
** However, we seem to get DL_BADADDR - "DLSAP addr in improper
|
||||
** format or invalid" - errors if we use 1537 on the "tr0"
|
||||
@@ -495,12 +657,33 @@ 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
|
||||
if (dlbindreq(p->fd, 0, ebuf) < 0 ||
|
||||
#endif
|
||||
dlbindack(p->fd, (char *)buf, ebuf) < 0)
|
||||
dlbindack(p->fd, (char *)buf, ebuf, NULL) < 0)
|
||||
goto bad;
|
||||
#endif
|
||||
#elif defined(DL_HP_RAWDLS)
|
||||
/*
|
||||
** HP-UX 10.0x and 10.1x.
|
||||
*/
|
||||
if (dl_dohpuxbind(p->fd, ebuf) < 0)
|
||||
goto bad;
|
||||
if (p->send_fd >= 0) {
|
||||
/*
|
||||
** XXX - if this fails, just close send_fd and
|
||||
** set it to -1, so that you can't send but can
|
||||
** still receive?
|
||||
*/
|
||||
if (dl_dohpuxbind(p->send_fd, ebuf) < 0)
|
||||
goto bad;
|
||||
}
|
||||
#else /* neither AIX nor HP-UX */
|
||||
/*
|
||||
** Not Sinix, and neither AIX nor HP-UX - Solaris, and any other
|
||||
** OS using DLPI.
|
||||
**/
|
||||
if (dlbindreq(p->fd, 0, ebuf) < 0 ||
|
||||
dlbindack(p->fd, (char *)buf, ebuf, NULL) < 0)
|
||||
goto bad;
|
||||
#endif /* AIX vs. HP-UX vs. other */
|
||||
#endif /* !HP-UX 9 and !HP-UX 10.20 or later and !SINIX */
|
||||
|
||||
#ifdef HAVE_SOLARIS
|
||||
if (isatm) {
|
||||
@@ -519,7 +702,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 +711,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 ||
|
||||
@@ -538,9 +721,9 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||
#endif
|
||||
}
|
||||
/*
|
||||
** Try to enable sap (when not in promiscuous mode when using
|
||||
** using HP-UX, when not doing SunATM on Solaris, and never
|
||||
** under SINIX)
|
||||
** Try to enable SAP promiscuity (when not in promiscuous mode
|
||||
** when using HP-UX, when not doing SunATM on Solaris, and never
|
||||
** under SINIX) (Not necessary on send FD)
|
||||
*/
|
||||
#ifndef sinix
|
||||
if (
|
||||
@@ -559,20 +742,35 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||
else
|
||||
goto bad;
|
||||
}
|
||||
#endif
|
||||
#endif /* sinix */
|
||||
|
||||
/*
|
||||
** HP-UX 9 and HP-UX 10.20 must bind after setting promiscuous
|
||||
** options)
|
||||
** HP-UX 9, and HP-UX 10.20 or later, must bind after setting
|
||||
** promiscuous options.
|
||||
*/
|
||||
#if defined(HAVE_HPUX9) || defined(HAVE_HPUX10_20)
|
||||
if (dlbindreq(p->fd, 0, ebuf) < 0 ||
|
||||
dlbindack(p->fd, (char *)buf, ebuf) < 0)
|
||||
#if defined(HAVE_HPUX9) || defined(HAVE_HPUX10_20_OR_LATER)
|
||||
if (dl_dohpuxbind(p->fd, ebuf) < 0)
|
||||
goto bad;
|
||||
/*
|
||||
** We don't set promiscuous mode on the send FD, but we'll defer
|
||||
** binding it anyway, just to keep the HP-UX 9/10.20 or later
|
||||
** code together.
|
||||
*/
|
||||
if (p->send_fd >= 0) {
|
||||
/*
|
||||
** XXX - if this fails, just close send_fd and
|
||||
** set it to -1, so that you can't send but can
|
||||
** still receive?
|
||||
*/
|
||||
if (dl_dohpuxbind(p->send_fd, ebuf) < 0)
|
||||
goto bad;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
** 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 +783,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 +810,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;
|
||||
@@ -701,7 +921,9 @@ 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->setdirection_op = NULL; /* Not implemented.*/
|
||||
p->set_datalink_op = NULL; /* can't change data link type */
|
||||
p->getnonblock_op = pcap_getnonblock_fd;
|
||||
p->setnonblock_op = pcap_setnonblock_fd;
|
||||
@@ -712,6 +934,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);
|
||||
}
|
||||
@@ -729,7 +958,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.
|
||||
@@ -745,15 +974,78 @@ 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);
|
||||
}
|
||||
|
||||
#ifdef DL_HP_RAWDLS
|
||||
static int
|
||||
dl_dohpuxbind(int fd, char *ebuf)
|
||||
{
|
||||
int hpsap;
|
||||
int uerror;
|
||||
bpf_u_int32 buf[MAXDLBUF];
|
||||
|
||||
/*
|
||||
* XXX - we start at 22 because we used to use only 22, but
|
||||
* that was just because that was the value used in some
|
||||
* sample code from HP. With what value *should* we start?
|
||||
* Does it matter, given that we're enabling SAP promiscuity
|
||||
* on the input FD?
|
||||
*/
|
||||
hpsap = 22;
|
||||
for (;;) {
|
||||
if (dlbindreq(fd, hpsap, ebuf) < 0)
|
||||
return (-1);
|
||||
if (dlbindack(fd, (char *)buf, ebuf, &uerror) >= 0)
|
||||
break;
|
||||
/*
|
||||
* For any error other than a UNIX EBUSY, give up.
|
||||
*/
|
||||
if (uerror != EBUSY)
|
||||
return (-1);
|
||||
|
||||
/*
|
||||
* For EBUSY, try the next SAP value; that means that
|
||||
* somebody else is using that SAP. Clear ebuf so
|
||||
* that application doesn't report the "Device busy"
|
||||
* error as a warning.
|
||||
*/
|
||||
*ebuf = '\0';
|
||||
hpsap++;
|
||||
if (hpsap > 100)
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
|
||||
{
|
||||
@@ -818,7 +1110,7 @@ send_request(int fd, char *ptr, int len, char *what, char *ebuf)
|
||||
}
|
||||
|
||||
static int
|
||||
recv_ack(int fd, int size, const char *what, char *bufp, char *ebuf)
|
||||
recv_ack(int fd, int size, const char *what, char *bufp, char *ebuf, int *uerror)
|
||||
{
|
||||
union DL_primitives *dlp;
|
||||
struct strbuf ctl;
|
||||
@@ -851,12 +1143,16 @@ recv_ack(int fd, int size, const char *what, char *bufp, char *ebuf)
|
||||
switch (dlp->error_ack.dl_errno) {
|
||||
|
||||
case DL_SYSERR:
|
||||
if (uerror != NULL)
|
||||
*uerror = dlp->error_ack.dl_unix_errno;
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
||||
"recv_ack: %s: UNIX error - %s",
|
||||
what, pcap_strerror(dlp->error_ack.dl_unix_errno));
|
||||
break;
|
||||
|
||||
default:
|
||||
if (uerror != NULL)
|
||||
*uerror = 0;
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "recv_ack: %s: %s",
|
||||
what, dlstrerror(dlp->error_ack.dl_errno));
|
||||
break;
|
||||
@@ -864,6 +1160,8 @@ recv_ack(int fd, int size, const char *what, char *bufp, char *ebuf)
|
||||
return (-1);
|
||||
|
||||
default:
|
||||
if (uerror != NULL)
|
||||
*uerror = 0;
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
||||
"recv_ack: %s: Unexpected primitive ack %s",
|
||||
what, dlprim(dlp->dl_primitive));
|
||||
@@ -871,6 +1169,8 @@ recv_ack(int fd, int size, const char *what, char *bufp, char *ebuf)
|
||||
}
|
||||
|
||||
if (ctl.len < size) {
|
||||
if (uerror != NULL)
|
||||
*uerror = 0;
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
||||
"recv_ack: %s: Ack too small (%d < %d)",
|
||||
what, ctl.len, size);
|
||||
@@ -1102,26 +1402,23 @@ dlbindreq(int fd, bpf_u_int32 sap, char *ebuf)
|
||||
|
||||
memset((char *)&req, 0, sizeof(req));
|
||||
req.dl_primitive = DL_BIND_REQ;
|
||||
#ifdef DL_HP_RAWDLS
|
||||
/* XXX - what if neither of these are defined? */
|
||||
#if defined(DL_HP_RAWDLS)
|
||||
req.dl_max_conind = 1; /* XXX magic number */
|
||||
/* 22 is INSAP as per the HP-UX DLPI Programmer's Guide */
|
||||
req.dl_sap = 22;
|
||||
req.dl_service_mode = DL_HP_RAWDLS;
|
||||
#else
|
||||
req.dl_sap = sap;
|
||||
#ifdef DL_CLDLS
|
||||
#elif defined(DL_CLDLS)
|
||||
req.dl_service_mode = DL_CLDLS;
|
||||
#endif
|
||||
#endif
|
||||
req.dl_sap = sap;
|
||||
|
||||
return (send_request(fd, (char *)&req, sizeof(req), "bind", ebuf));
|
||||
}
|
||||
|
||||
static int
|
||||
dlbindack(int fd, char *bufp, char *ebuf)
|
||||
dlbindack(int fd, char *bufp, char *ebuf, int *uerror)
|
||||
{
|
||||
|
||||
return (recv_ack(fd, DL_BIND_ACK_SIZE, "bind", bufp, ebuf));
|
||||
return (recv_ack(fd, DL_BIND_ACK_SIZE, "bind", bufp, ebuf, uerror));
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -1139,7 +1436,7 @@ static int
|
||||
dlokack(int fd, const char *what, char *bufp, char *ebuf)
|
||||
{
|
||||
|
||||
return (recv_ack(fd, DL_OK_ACK_SIZE, what, bufp, ebuf));
|
||||
return (recv_ack(fd, DL_OK_ACK_SIZE, what, bufp, ebuf, NULL));
|
||||
}
|
||||
|
||||
|
||||
@@ -1157,9 +1454,45 @@ static int
|
||||
dlinfoack(int fd, char *bufp, char *ebuf)
|
||||
{
|
||||
|
||||
return (recv_ack(fd, DL_INFO_ACK_SIZE, "info", bufp, ebuf));
|
||||
return (recv_ack(fd, DL_INFO_ACK_SIZE, "info", bufp, ebuf, NULL));
|
||||
}
|
||||
|
||||
#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)
|
||||
@@ -1206,7 +1539,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
|
||||
*/
|
||||
|
||||
1474
libpcap-possiblymodified/pcap-dos.c
Normal file
1474
libpcap-possiblymodified/pcap-dos.c
Normal file
File diff suppressed because it is too large
Load Diff
227
libpcap-possiblymodified/pcap-dos.h
Normal file
227
libpcap-possiblymodified/pcap-dos.h
Normal file
@@ -0,0 +1,227 @@
|
||||
/*
|
||||
* Internal details for libpcap on DOS.
|
||||
* 32-bit targets: djgpp, Pharlap or DOS4GW.
|
||||
*
|
||||
* @(#) $Header: /tcpdump/master/libpcap/pcap-dos.h,v 1.1 2004/12/18 08:52:10 guy Exp $ (LBL)
|
||||
*/
|
||||
|
||||
#ifndef __PCAP_DOS_H
|
||||
#define __PCAP_DOS_H
|
||||
|
||||
#ifdef __DJGPP__
|
||||
#include <pc.h> /* simple non-conio kbhit */
|
||||
#else
|
||||
#include <conio.h>
|
||||
#endif
|
||||
|
||||
typedef int BOOL;
|
||||
typedef unsigned char BYTE;
|
||||
typedef unsigned short WORD;
|
||||
typedef unsigned long DWORD;
|
||||
typedef BYTE ETHER[6];
|
||||
|
||||
#define ETH_ALEN sizeof(ETHER) /* Ether address length */
|
||||
#define ETH_HLEN (2*ETH_ALEN+2) /* Ether header length */
|
||||
#define ETH_MTU 1500
|
||||
#define ETH_MIN 60
|
||||
#define ETH_MAX (ETH_MTU+ETH_HLEN)
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#define PHARLAP 1
|
||||
#define DJGPP 2
|
||||
#define DOS4GW 4
|
||||
|
||||
#ifdef __DJGPP__
|
||||
#undef DOSX
|
||||
#define DOSX DJGPP
|
||||
#endif
|
||||
|
||||
#ifdef __WATCOMC__
|
||||
#undef DOSX
|
||||
#define DOSX DOS4GW
|
||||
#endif
|
||||
|
||||
#ifdef __HIGHC__
|
||||
#include <pharlap.h>
|
||||
#undef DOSX
|
||||
#define DOSX PHARLAP
|
||||
#define inline
|
||||
#else
|
||||
typedef unsigned int UINT;
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(__GNUC__) || defined(__HIGHC__)
|
||||
typedef unsigned long long uint64;
|
||||
typedef unsigned long long QWORD;
|
||||
#endif
|
||||
|
||||
#if defined(__WATCOMC__)
|
||||
typedef unsigned __int64 uint64;
|
||||
typedef unsigned __int64 QWORD;
|
||||
#endif
|
||||
|
||||
#define ARGSUSED(x) (void) x
|
||||
|
||||
#if defined (__SMALL__) || defined(__LARGE__)
|
||||
#define DOSX 0
|
||||
|
||||
#elif !defined(DOSX)
|
||||
#error DOSX not defined; 1 = PharLap, 2 = djgpp, 4 = DOS4GW
|
||||
#endif
|
||||
|
||||
#ifdef __HIGHC__
|
||||
#define min(a,b) _min(a,b)
|
||||
#define max(a,b) _max(a,b)
|
||||
#endif
|
||||
|
||||
#ifndef min
|
||||
#define min(a,b) ((a) < (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#ifndef max
|
||||
#define max(a,b) ((a) < (b) ? (b) : (a))
|
||||
#endif
|
||||
|
||||
#if !defined(_U_) && defined(__GNUC__)
|
||||
#define _U_ __attribute__((unused))
|
||||
#endif
|
||||
|
||||
#ifndef _U_
|
||||
#define _U_
|
||||
#endif
|
||||
|
||||
#if defined(USE_32BIT_DRIVERS)
|
||||
#include "msdos/pm_drvr/lock.h"
|
||||
|
||||
#ifndef RECEIVE_QUEUE_SIZE
|
||||
#define RECEIVE_QUEUE_SIZE 60
|
||||
#endif
|
||||
|
||||
#ifndef RECEIVE_BUF_SIZE
|
||||
#define RECEIVE_BUF_SIZE (ETH_MAX+20)
|
||||
#endif
|
||||
|
||||
extern struct device el2_dev LOCKED_VAR; /* 3Com EtherLink II */
|
||||
extern struct device el3_dev LOCKED_VAR; /* EtherLink III */
|
||||
extern struct device tc59_dev LOCKED_VAR; /* 3Com Vortex Card (?) */
|
||||
extern struct device tc515_dev LOCKED_VAR;
|
||||
extern struct device tc90x_dev LOCKED_VAR;
|
||||
extern struct device tc90bcx_dev LOCKED_VAR;
|
||||
extern struct device wd_dev LOCKED_VAR;
|
||||
extern struct device ne_dev LOCKED_VAR;
|
||||
extern struct device acct_dev LOCKED_VAR;
|
||||
extern struct device cs89_dev LOCKED_VAR;
|
||||
extern struct device rtl8139_dev LOCKED_VAR;
|
||||
|
||||
struct rx_ringbuf {
|
||||
volatile int in_index; /* queue index head */
|
||||
int out_index; /* queue index tail */
|
||||
int elem_size; /* size of each element */
|
||||
int num_elem; /* number of elements */
|
||||
char *buf_start; /* start of buffer pool */
|
||||
};
|
||||
|
||||
struct rx_elem {
|
||||
DWORD size; /* size copied to this element */
|
||||
BYTE data[ETH_MAX+10]; /* add some margin. data[0] should be */
|
||||
}; /* dword aligned */
|
||||
|
||||
extern BYTE *get_rxbuf (int len) LOCKED_FUNC;
|
||||
extern int peek_rxbuf (BYTE **buf);
|
||||
extern int release_rxbuf (BYTE *buf);
|
||||
|
||||
#else
|
||||
#define LOCKED_VAR
|
||||
#define LOCKED_FUNC
|
||||
|
||||
struct device {
|
||||
const char *name;
|
||||
const char *long_name;
|
||||
DWORD base_addr; /* device I/O address */
|
||||
int irq; /* device IRQ number */
|
||||
int dma; /* DMA channel */
|
||||
DWORD mem_start; /* shared mem start */
|
||||
DWORD mem_end; /* shared mem end */
|
||||
DWORD rmem_start; /* shmem "recv" start */
|
||||
DWORD rmem_end; /* shared "recv" end */
|
||||
|
||||
struct device *next; /* next device in list */
|
||||
|
||||
/* interface service routines */
|
||||
int (*probe)(struct device *dev);
|
||||
int (*open) (struct device *dev);
|
||||
void (*close)(struct device *dev);
|
||||
int (*xmit) (struct device *dev, const void *buf, int len);
|
||||
void *(*get_stats)(struct device *dev);
|
||||
void (*set_multicast_list)(struct device *dev);
|
||||
|
||||
/* driver-to-pcap receive buffer routines */
|
||||
int (*copy_rx_buf) (BYTE *buf, int max); /* rx-copy (pktdrvr only) */
|
||||
BYTE *(*get_rx_buf) (int len); /* rx-buf fetch/enqueue */
|
||||
int (*peek_rx_buf) (BYTE **buf); /* rx-non-copy at queue */
|
||||
int (*release_rx_buf) (BYTE *buf); /* release after peek */
|
||||
|
||||
WORD flags; /* Low-level status flags. */
|
||||
void *priv; /* private data */
|
||||
};
|
||||
|
||||
/*
|
||||
* Network device statistics
|
||||
*/
|
||||
typedef struct net_device_stats {
|
||||
DWORD rx_packets; /* total packets received */
|
||||
DWORD tx_packets; /* total packets transmitted */
|
||||
DWORD rx_bytes; /* total bytes received */
|
||||
DWORD tx_bytes; /* total bytes transmitted */
|
||||
DWORD rx_errors; /* bad packets received */
|
||||
DWORD tx_errors; /* packet transmit problems */
|
||||
DWORD rx_dropped; /* no space in Rx buffers */
|
||||
DWORD tx_dropped; /* no space available for Tx */
|
||||
DWORD multicast; /* multicast packets received */
|
||||
|
||||
/* detailed rx_errors: */
|
||||
DWORD rx_length_errors;
|
||||
DWORD rx_over_errors; /* recv'r overrun error */
|
||||
DWORD rx_osize_errors; /* recv'r over-size error */
|
||||
DWORD rx_crc_errors; /* recv'd pkt with crc error */
|
||||
DWORD rx_frame_errors; /* recv'd frame alignment error */
|
||||
DWORD rx_fifo_errors; /* recv'r fifo overrun */
|
||||
DWORD rx_missed_errors; /* recv'r missed packet */
|
||||
|
||||
/* detailed tx_errors */
|
||||
DWORD tx_aborted_errors;
|
||||
DWORD tx_carrier_errors;
|
||||
DWORD tx_fifo_errors;
|
||||
DWORD tx_heartbeat_errors;
|
||||
DWORD tx_window_errors;
|
||||
DWORD tx_collisions;
|
||||
DWORD tx_jabbers;
|
||||
} NET_STATS;
|
||||
#endif
|
||||
|
||||
extern struct device *active_dev LOCKED_VAR;
|
||||
extern const struct device *dev_base LOCKED_VAR;
|
||||
extern struct device *probed_dev;
|
||||
|
||||
extern int pcap_pkt_debug;
|
||||
|
||||
extern void _w32_os_yield (void); /* Watt-32's misc.c */
|
||||
|
||||
#ifdef NDEBUG
|
||||
#define PCAP_ASSERT(x) ((void)0)
|
||||
|
||||
#else
|
||||
void pcap_assert (const char *what, const char *file, unsigned line);
|
||||
|
||||
#define PCAP_ASSERT(x) do { \
|
||||
if (!(x)) \
|
||||
pcap_assert (#x, __FILE__, __LINE__); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#endif /* __PCAP_DOS_H */
|
||||
@@ -46,6 +46,11 @@ extern "C" {
|
||||
#include <packet32.h>
|
||||
#endif /* WIN32 */
|
||||
|
||||
#ifdef MSDOS
|
||||
#include <fcntl.h>
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Savefile
|
||||
*/
|
||||
@@ -74,25 +79,43 @@ 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
|
||||
|
||||
#ifdef HAVE_DAG_API
|
||||
#ifdef HAVE_DAG_STREAMS_API
|
||||
u_char *dag_mem_bottom; /* DAG card current memory bottom pointer */
|
||||
u_char *dag_mem_top; /* DAG card current memory top pointer */
|
||||
#else
|
||||
void *dag_mem_base; /* DAG card memory base address */
|
||||
u_int dag_mem_bottom; /* DAG card current memory bottom pointer */
|
||||
u_int dag_mem_top; /* DAG card current memory top pointer */
|
||||
u_int dag_mem_bottom; /* DAG card current memory bottom offset */
|
||||
u_int dag_mem_top; /* DAG card current memory top offset */
|
||||
#endif /* HAVE_DAG_STREAMS_API */
|
||||
int dag_fcs_bits; /* Number of checksum bits from link layer */
|
||||
int dag_offset_flags; /* Flags to pass to dag_offset(). */
|
||||
#endif
|
||||
int dag_stream; /* DAG stream number */
|
||||
int dag_timeout; /* timeout specified to pcap_open_live.
|
||||
* Same as in linux above, introduce
|
||||
* generally? */
|
||||
#endif /* HAVE_DAG_API */
|
||||
};
|
||||
|
||||
/*
|
||||
* Ultrix, DEC OSF/1^H^H^H^H^H^H^H^H^HDigital UNIX^H^H^H^H^H^H^H^H^H^H^H^H
|
||||
* Tru64 UNIX, and NetBSD pad to make everything line up on a nice boundary.
|
||||
*/
|
||||
#if defined(ultrix) || defined(__osf__) || (defined(__NetBSD__) && __NetBSD_Version__ > 106000000)
|
||||
#define PCAP_FDDIPAD 3
|
||||
#endif
|
||||
|
||||
struct pcap {
|
||||
#ifdef WIN32
|
||||
ADAPTER *adapter;
|
||||
@@ -102,6 +125,7 @@ struct pcap {
|
||||
#else
|
||||
int fd;
|
||||
int selectable_fd;
|
||||
int send_fd;
|
||||
#endif /* WIN32 */
|
||||
int snapshot;
|
||||
int linktype;
|
||||
@@ -110,6 +134,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;
|
||||
|
||||
@@ -126,11 +159,16 @@ struct pcap {
|
||||
*/
|
||||
u_char *pkt;
|
||||
|
||||
/* We're accepting only packets in this direction/these directions. */
|
||||
pcap_direction_t direction;
|
||||
|
||||
/*
|
||||
* Methods.
|
||||
*/
|
||||
int (*read_op)(pcap_t *, int cnt, pcap_handler, u_char *);
|
||||
int (*inject_op)(pcap_t *, const void *, size_t);
|
||||
int (*setfilter_op)(pcap_t *, struct bpf_program *);
|
||||
int (*setdirection_op)(pcap_t *, pcap_direction_t);
|
||||
int (*set_datalink_op)(pcap_t *, int);
|
||||
int (*getnonblock_op)(pcap_t *, char *);
|
||||
int (*setnonblock_op)(pcap_t *, int, char *);
|
||||
@@ -144,7 +182,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 */
|
||||
};
|
||||
@@ -221,15 +259,6 @@ int yylex(void);
|
||||
int pcap_offline_read(pcap_t *, int, pcap_handler, u_char *);
|
||||
int pcap_read(pcap_t *, int cnt, pcap_handler, u_char *);
|
||||
|
||||
|
||||
/*
|
||||
* Ultrix, DEC OSF/1^H^H^H^H^H^H^H^H^HDigital UNIX^H^H^H^H^H^H^H^H^H^H^H^H
|
||||
* Tru64 UNIX, and NetBSD pad to make everything line up on a nice boundary.
|
||||
*/
|
||||
#if defined(ultrix) || defined(__osf__) || defined(__NetBSD__)
|
||||
#define PCAP_FDDIPAD 3
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRLCPY
|
||||
#define strlcpy(x, y, z) \
|
||||
(strncpy((x), (y), (z)), \
|
||||
@@ -252,11 +281,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 +298,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 +310,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 *);
|
||||
|
||||
@@ -84,6 +84,10 @@ static const char rcsid[] _U_ =
|
||||
#include "pcap-dag.h"
|
||||
#endif /* HAVE_DAG_API */
|
||||
|
||||
#ifdef HAVE_SEPTEL_API
|
||||
#include "pcap-septel.h"
|
||||
#endif /* HAVE_SEPTEL_API */
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
@@ -189,8 +193,10 @@ 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 int pcap_setdirection_linux(pcap_t *, pcap_direction_t);
|
||||
static void pcap_close_linux(pcap_t *);
|
||||
|
||||
/*
|
||||
@@ -244,6 +250,12 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||
}
|
||||
#endif /* HAVE_DAG_API */
|
||||
|
||||
#ifdef HAVE_SEPTEL_API
|
||||
if (strstr(device, "septel")) {
|
||||
return septel_open_live(device, snaplen, promisc, to_ms, ebuf);
|
||||
}
|
||||
#endif /* HAVE_SEPTEL_API */
|
||||
|
||||
/* Allocate a handle for this session. */
|
||||
|
||||
handle = malloc(sizeof(*handle));
|
||||
@@ -405,7 +417,9 @@ 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->setdirection_op = pcap_setdirection_linux;
|
||||
handle->set_datalink_op = NULL; /* can't change data link type */
|
||||
handle->getnonblock_op = pcap_getnonblock_fd;
|
||||
handle->setnonblock_op = pcap_setnonblock_fd;
|
||||
@@ -529,19 +543,37 @@ pcap_read_packet(pcap_t *handle, pcap_handler callback, u_char *userdata)
|
||||
}
|
||||
|
||||
#ifdef HAVE_PF_PACKET_SOCKETS
|
||||
if (!handle->md.sock_packet) {
|
||||
/*
|
||||
* Do checks based on packet direction.
|
||||
* We can only do this if we're using PF_PACKET; the
|
||||
* address returned for SOCK_PACKET is a "sockaddr_pkt"
|
||||
* which lacks the relevant packet type information.
|
||||
*/
|
||||
if (from.sll_pkttype == PACKET_OUTGOING) {
|
||||
/*
|
||||
* Outgoing packet.
|
||||
* If this is from the loopback device, reject it;
|
||||
* we'll see the packet as an incoming packet as well,
|
||||
* and we don't want to see it twice.
|
||||
*/
|
||||
if (from.sll_ifindex == handle->md.lo_ifindex)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* If this is from the loopback device, reject outgoing packets;
|
||||
* we'll see the packet as an incoming packet as well, and
|
||||
* we don't want to see it twice.
|
||||
*
|
||||
* We can only do this if we're using PF_PACKET; the address
|
||||
* returned for SOCK_PACKET is a "sockaddr_pkt" which lacks
|
||||
* the relevant packet type information.
|
||||
*/
|
||||
if (!handle->md.sock_packet &&
|
||||
from.sll_ifindex == handle->md.lo_ifindex &&
|
||||
from.sll_pkttype == PACKET_OUTGOING)
|
||||
* If the user only wants incoming packets, reject it.
|
||||
*/
|
||||
if (handle->direction == PCAP_D_IN)
|
||||
return 0;
|
||||
} else {
|
||||
/*
|
||||
* Incoming packet.
|
||||
* If the user only wants outgoing packets, reject it.
|
||||
*/
|
||||
if (handle->direction == PCAP_D_OUT)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_PF_PACKET_SOCKETS
|
||||
@@ -699,6 +731,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
|
||||
@@ -744,9 +819,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
|
||||
{
|
||||
@@ -813,6 +892,11 @@ pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
|
||||
return (-1);
|
||||
#endif /* HAVE_DAG_API */
|
||||
|
||||
#ifdef HAVE_SEPTEL_API
|
||||
if (septel_platform_finddevs(alldevsp, errbuf) < 0)
|
||||
return (-1);
|
||||
#endif /* HAVE_SEPTEL_API */
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
@@ -952,6 +1036,28 @@ pcap_setfilter_linux(pcap_t *handle, struct bpf_program *filter)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set direction flag: Which packets do we accept on a forwarding
|
||||
* single device? IN, OUT or both?
|
||||
*/
|
||||
static int
|
||||
pcap_setdirection_linux(pcap_t *handle, pcap_direction_t d)
|
||||
{
|
||||
#ifdef HAVE_PF_PACKET_SOCKETS
|
||||
if (!handle->md.sock_packet) {
|
||||
handle->direction = d;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* We're not using PF_PACKET sockets, so we can't determine
|
||||
* the direction of the packet.
|
||||
*/
|
||||
snprintf(handle->errbuf, sizeof(handle->errbuf),
|
||||
"Setting direction is not supported on SOCK_PACKET sockets");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Linux uses the ARP hardware type to identify the type of an
|
||||
* interface. pcap uses the DLT_xxx constants for this. This
|
||||
@@ -975,6 +1081,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;
|
||||
@@ -1190,6 +1324,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;
|
||||
@@ -1216,7 +1353,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;
|
||||
@@ -1305,6 +1442,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
|
||||
@@ -1325,11 +1473,12 @@ live_open_new(pcap_t *handle, const char *device, int promisc,
|
||||
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;
|
||||
@@ -1342,14 +1491,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;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1373,7 +1523,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)
|
||||
@@ -1395,9 +1545,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,
|
||||
@@ -1573,10 +1728,7 @@ static void pcap_close_linux( pcap_t *handle )
|
||||
if (handle->md.device != NULL)
|
||||
free(handle->md.device);
|
||||
handle->md.device = NULL;
|
||||
if (handle->buffer != NULL)
|
||||
free(handle->buffer);
|
||||
if (handle->fd >= 0)
|
||||
close(handle->fd);
|
||||
pcap_close_common(handle);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -30,11 +30,11 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#) $Header$ (LBL)
|
||||
* @(#) $Header: /tcpdump/master/libpcap/pcap-namedb.h,v 1.10.2.1 2005/04/19 04:26:08 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" {
|
||||
@@ -65,8 +65,10 @@ struct addrinfo *pcap_nametoaddrinfo(const char *);
|
||||
bpf_u_int32 pcap_nametonetaddr(const char *);
|
||||
|
||||
int pcap_nametoport(const char *, int *, int *);
|
||||
int pcap_nametoportrange(const char *, int *, int *, int *);
|
||||
int pcap_nametoproto(const char *);
|
||||
int pcap_nametoeproto(const char *);
|
||||
int pcap_nametollc(const char *);
|
||||
/*
|
||||
* If a protocol is unknown, PROTO_UNDEF is returned.
|
||||
* Also, pcap_nametoport() returns the protocol along with the port number.
|
||||
|
||||
@@ -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,13 +296,45 @@ 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->setdirection_op = NULL; /* Not implemented. */
|
||||
p->set_datalink_op = NULL; /* can't change data link type */
|
||||
p->getnonblock_op = pcap_getnonblock_fd;
|
||||
p->setnonblock_op = pcap_setnonblock_fd;
|
||||
|
||||
@@ -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 = pc->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 pc->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,13 +309,27 @@ 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_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\
|
||||
@@ -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,24 @@ 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->setdirection_op = NULL; /* Not implemented. */
|
||||
p->set_datalink_op = NULL; /* can't change data link type */
|
||||
p->getnonblock_op = pcap_getnonblock_fd;
|
||||
p->setnonblock_op = pcap_setnonblock_fd;
|
||||
p->stats_op = pcap_stats_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 +568,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);
|
||||
}
|
||||
|
||||
|
||||
307
libpcap-possiblymodified/pcap-septel.c
Normal file
307
libpcap-possiblymodified/pcap-septel.c
Normal file
@@ -0,0 +1,307 @@
|
||||
/*
|
||||
* pcap-septel.c: Packet capture interface for Intel/Septel card.
|
||||
*
|
||||
* The functionality of this code attempts to mimic that of pcap-linux as much
|
||||
* as possible. This code is compiled in several different ways depending on
|
||||
* whether SEPTEL_ONLY and HAVE_SEPTEL_API are defined. If HAVE_SEPTEL_API is
|
||||
* not defined it should not get compiled in, otherwise if SEPTEL_ONLY is
|
||||
* defined then the 'septel_' function calls are renamed to 'pcap_'
|
||||
* equivalents. If SEPTEL_ONLY is not defined then nothing is altered - the
|
||||
* septel_ functions will be called as required from their
|
||||
* pcap-linux/equivalents.
|
||||
*
|
||||
* Authors: Gilbert HOYEK (gil_hoyek@hotmail.com), Elias M. KHOURY
|
||||
* (+961 3 485243)
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid[] _U_ =
|
||||
"@(#) $Header: /tcpdump/master/libpcap/pcap-septel.c,v 1.1.2.2 2005/06/21 01:03:23 guy Exp $";
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "pcap-int.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef HAVE_SEPTEL_API
|
||||
#include <msg.h>
|
||||
#include <ss7_inc.h>
|
||||
#include <sysgct.h>
|
||||
#include <pack.h>
|
||||
#include <system.h>
|
||||
#endif /* HAVE_SEPTEL_API */
|
||||
|
||||
#ifdef SEPTEL_ONLY
|
||||
/* This code is required when compiling for a Septel device only. */
|
||||
#include "pcap-septel.h"
|
||||
|
||||
/* Replace dag function names with pcap equivalent. */
|
||||
#define septel_open_live pcap_open_live
|
||||
#define septel_platform_finddevs pcap_platform_finddevs
|
||||
#endif /* SEPTEL_ONLY */
|
||||
|
||||
static int septel_setfilter(pcap_t *p, struct bpf_program *fp);
|
||||
static int septel_stats(pcap_t *p, struct pcap_stat *ps);
|
||||
static int septel_setnonblock(pcap_t *p, int nonblock, char *errbuf);
|
||||
|
||||
static void septel_platform_close(pcap_t *p) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Read at most max_packets from the capture queue and call the callback
|
||||
* for each of them. Returns the number of packets handled, -1 if an
|
||||
* error occured, or -2 if we were told to break out of the loop.
|
||||
*/
|
||||
static int septel_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) {
|
||||
|
||||
HDR *h;
|
||||
MSG *m;
|
||||
int processed = 0 ;
|
||||
int t = 0 ;
|
||||
|
||||
/* identifier for the message queue of the module(upe) from which we are capturing
|
||||
* packets.These IDs are defined in system.txt . By default it is set to 0x2d
|
||||
* so change it to 0xdd for technical reason and therefore the module id for upe becomes:
|
||||
* LOCAL 0xdd * upe - Example user part task */
|
||||
unsigned int id = 0xdd;
|
||||
|
||||
/* process the packets */
|
||||
do {
|
||||
|
||||
unsigned short packet_len = 0;
|
||||
int caplen = 0;
|
||||
int counter = 0;
|
||||
struct pcap_pkthdr pcap_header;
|
||||
u_char *dp ;
|
||||
|
||||
/*
|
||||
* Has "pcap_breakloop()" been called?
|
||||
*/
|
||||
loop:
|
||||
if (p->break_loop) {
|
||||
/*
|
||||
* Yes - clear the flag that indicates that
|
||||
* it has, and return -2 to indicate that
|
||||
* we were told to break out of the loop.
|
||||
*/
|
||||
p->break_loop = 0;
|
||||
return -2;
|
||||
}
|
||||
|
||||
/*repeat until a packet is read
|
||||
*a NULL message means :
|
||||
* when no packet is in queue or all packets in queue already read */
|
||||
do {
|
||||
/* receive packet in non-blocking mode
|
||||
* GCT_grab is defined in the septel library software */
|
||||
h = GCT_grab(id);
|
||||
|
||||
m = (MSG*)h;
|
||||
/* a couter is added here to avoid an infinite loop
|
||||
* that will cause our capture program GUI to freeze while waiting
|
||||
* for a packet*/
|
||||
counter++ ;
|
||||
|
||||
}
|
||||
while ((m == NULL)&& (counter< 100)) ;
|
||||
|
||||
if (m != NULL) {
|
||||
|
||||
t = h->type ;
|
||||
|
||||
/* catch only messages with type = 0xcf00 or 0x8f01 corrsponding to ss7 messages*/
|
||||
/* XXX = why not use API_MSG_TX_REQ for 0xcf00 and API_MSG_RX_IND
|
||||
* for 0x8f01? */
|
||||
if ((t != 0xcf00) && (t != 0x8f01)) {
|
||||
relm(h);
|
||||
goto loop ;
|
||||
}
|
||||
|
||||
/* XXX - is API_MSG_RX_IND for an MTP2 or MTP3 message? */
|
||||
dp = get_param(m);/* get pointer to MSG parameter area (m->param) */
|
||||
packet_len = m->len;
|
||||
caplen = p->snapshot ;
|
||||
|
||||
|
||||
if (caplen > packet_len) {
|
||||
|
||||
caplen = packet_len;
|
||||
}
|
||||
/* Run the packet filter if there is one. */
|
||||
if ((p->fcode.bf_insns == NULL) || bpf_filter(p->fcode.bf_insns, dp, packet_len, caplen)) {
|
||||
|
||||
|
||||
/* get a time stamp , consisting of :
|
||||
*
|
||||
* pcap_header.ts.tv_sec:
|
||||
* ----------------------
|
||||
* a UNIX format time-in-seconds when he packet was captured,
|
||||
* i.e. the number of seconds since Epoch time (January 1,1970, 00:00:00 GMT)
|
||||
*
|
||||
* pcap_header.ts.tv_usec :
|
||||
* ------------------------
|
||||
* the number of microseconds since that second
|
||||
* when the packet was captured
|
||||
*/
|
||||
|
||||
(void)gettimeofday(&pcap_header.ts, NULL);
|
||||
|
||||
/* 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);
|
||||
|
||||
processed++ ;
|
||||
|
||||
}
|
||||
/* after being processed the packet must be
|
||||
*released in order to receive another one */
|
||||
relm(h);
|
||||
}else
|
||||
processed++;
|
||||
|
||||
}
|
||||
while (processed < cnt) ;
|
||||
|
||||
return processed ;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
septel_inject(pcap_t *handle, const void *buf _U_, size_t size _U_)
|
||||
{
|
||||
strlcpy(handle->errbuf, "Sending packets isn't supported on Septel cards",
|
||||
PCAP_ERRBUF_SIZE);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get a handle for a live capture from the given Septel device. Always pass a NULL device
|
||||
* The promisc flag is ignored because Septel cards have built-in tracing.
|
||||
* The to_ms parameter is also ignored as it is
|
||||
* not supported in hardware.
|
||||
*
|
||||
* See also pcap(3).
|
||||
*/
|
||||
pcap_t *septel_open_live(const char *device, int snaplen, int promisc, int to_ms, char *ebuf) {
|
||||
pcap_t *handle;
|
||||
|
||||
handle = malloc(sizeof(*handle));
|
||||
if (handle == NULL) {
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc %s: %s", device, pcap_strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Initialize some components of the pcap structure. */
|
||||
|
||||
memset(handle, 0, sizeof(*handle));
|
||||
|
||||
handle->snapshot = snaplen;
|
||||
|
||||
handle->linktype = DLT_MTP2;
|
||||
|
||||
handle->bufsize = 0;
|
||||
|
||||
/*
|
||||
* "select()" and "poll()" don't work on Septel queues
|
||||
*/
|
||||
handle->selectable_fd = -1;
|
||||
|
||||
handle->read_op = septel_read;
|
||||
handle->inject_op = septel_inject;
|
||||
handle->setfilter_op = septel_setfilter;
|
||||
handle->set_datalink_op = NULL; /* can't change data link type */
|
||||
handle->getnonblock_op = pcap_getnonblock_fd;
|
||||
handle->setnonblock_op = septel_setnonblock;
|
||||
handle->stats_op = septel_stats;
|
||||
handle->close_op = septel_platform_close;
|
||||
|
||||
return handle;
|
||||
|
||||
fail:
|
||||
if (handle != NULL) {
|
||||
free(handle);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int septel_stats(pcap_t *p, struct pcap_stat *ps) {
|
||||
/*p->md.stat.ps_recv = 0;*/
|
||||
/*p->md.stat.ps_drop = 0;*/
|
||||
|
||||
*ps = p->md.stat;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
septel_platform_finddevs(pcap_if_t **devlistp, char *errbuf)
|
||||
{
|
||||
unsigned char *p;
|
||||
const char description[512]= "Intel/Septel device";
|
||||
char name[512]="septel" ;
|
||||
int ret = 0;
|
||||
pcap_add_if(devlistp,name,0,description,errbuf);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Installs the given bpf filter program in the given pcap structure. There is
|
||||
* no attempt to store the filter in kernel memory as that is not supported
|
||||
* with Septel cards.
|
||||
*/
|
||||
static int septel_setfilter(pcap_t *p, struct bpf_program *fp) {
|
||||
if (!p)
|
||||
return -1;
|
||||
if (!fp) {
|
||||
strncpy(p->errbuf, "setfilter: No filter specified",
|
||||
sizeof(p->errbuf));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Make our private copy of the filter */
|
||||
|
||||
if (install_bpf_program(p, fp) < 0) {
|
||||
snprintf(p->errbuf, sizeof(p->errbuf),
|
||||
"malloc: %s", pcap_strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
p->md.use_bpf = 0;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
septel_setnonblock(pcap_t *p, int nonblock, char *errbuf)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
15
libpcap-possiblymodified/pcap-septel.h
Normal file
15
libpcap-possiblymodified/pcap-septel.h
Normal file
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
* pcap-septel.c: Packet capture interface for Intel Septel card
|
||||
*
|
||||
* The functionality of this code attempts to mimic that of pcap-linux as much
|
||||
* as possible. This code is only needed when compiling in the Intel/Septel
|
||||
* card code at the same time as another type of device.
|
||||
*
|
||||
* Authors: Gilbert HOYEK (gil_hoyek@hotmail.com), Elias M. KHOURY
|
||||
* (+961 3 485343);
|
||||
*
|
||||
* @(#) $Header: /tcpdump/master/libpcap/pcap-septel.h,v 1.1.2.1 2005/06/20 21:30:19 guy Exp $
|
||||
*/
|
||||
|
||||
pcap_t *septel_open_live(const char *device, int snaplen, int promisc, int to_ms, char *ebuf);
|
||||
|
||||
@@ -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,6 +285,22 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||
snaplen = 96;
|
||||
|
||||
memset(p, 0, sizeof(*p));
|
||||
/*
|
||||
* Initially try a read/write open (to allow the inject
|
||||
* method to work). If that fails due to permission
|
||||
* 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,
|
||||
@@ -344,13 +374,35 @@ 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->setdirection_op = NULL; /* Not implemented. */
|
||||
p->set_datalink_op = NULL; /* can't change data link type */
|
||||
p->getnonblock_op = pcap_getnonblock_fd;
|
||||
p->setnonblock_op = pcap_setnonblock_fd;
|
||||
p->stats_op = pcap_stats_snit;
|
||||
p->close_op = pcap_close_snit;
|
||||
p->close_op = pcap_close_common;
|
||||
|
||||
return (p);
|
||||
bad:
|
||||
|
||||
@@ -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 @@ again:
|
||||
}
|
||||
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 @@ again:
|
||||
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,23 @@ 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->setdirection_op = NULL; /* Not implemented. */
|
||||
p->set_datalink_op = NULL; /* can't change data link type */
|
||||
p->getnonblock_op = pcap_getnonblock_fd;
|
||||
p->setnonblock_op = pcap_setnonblock_fd;
|
||||
p->stats_op = pcap_stats_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);
|
||||
}
|
||||
|
||||
@@ -38,18 +38,26 @@ static const char rcsid[] _U_ =
|
||||
#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 *
|
||||
@@ -210,6 +411,7 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||
|
||||
if (p->adapter == NULL)
|
||||
{
|
||||
free(p);
|
||||
/* Adapter detected but we are not able to open it. Return failure. */
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "Error opening adapter: %s", pcap_win32strerror());
|
||||
return NULL;
|
||||
@@ -231,6 +433,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 +474,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,14 +498,8 @@ 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;
|
||||
/* Store the timeout. Used by pcap_setnonblock() */
|
||||
p->timeout= to_ms;
|
||||
|
||||
/* allocate Packet structure used during the capture */
|
||||
if((p->Packet = PacketAllocatePacket())==NULL)
|
||||
@@ -281,8 +508,23 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if(!(p->adapter->Flags & INFO_FLAG_DAG_CARD))
|
||||
{
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
@@ -296,11 +538,77 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE,"Error calling PacketSetMinToCopy: %s\n", pcap_win32strerror());
|
||||
goto bad;
|
||||
}
|
||||
}
|
||||
else
|
||||
#ifdef HAVE_DAG_API
|
||||
{
|
||||
/*
|
||||
* 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->setdirection_op = NULL; /* Not implemented. */
|
||||
/* XXX - can this be implemented on some versions of Windows? */
|
||||
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 +621,65 @@ bad:
|
||||
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 +738,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)
|
||||
|
||||
@@ -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
|
||||
@@ -57,6 +59,10 @@ bpf_u_int32 *maskp, char *errbuf)
|
||||
.ft
|
||||
.LP
|
||||
.ft B
|
||||
typedef void (*pcap_handler)(u_char *user, const struct pcap_pkthdr *h,
|
||||
.ti +8
|
||||
const u_char *bytes);
|
||||
.ft B
|
||||
int pcap_dispatch(pcap_t *p, int cnt,
|
||||
.ti +8
|
||||
pcap_handler callback, u_char *user)
|
||||
@@ -73,7 +79,8 @@ int pcap_compile(pcap_t *p, struct bpf_program *fp,
|
||||
.ti +8
|
||||
char *str, int optimize, bpf_u_int32 netmask)
|
||||
int pcap_setfilter(pcap_t *p, struct bpf_program *fp)
|
||||
void pcap_freecode(struct bpf_program *);
|
||||
void pcap_freecode(struct bpf_program *)
|
||||
int pcap_setdirection(pcap_t *p, pcap_direction_t d)
|
||||
.ft
|
||||
.LP
|
||||
.ft B
|
||||
@@ -88,6 +95,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 +113,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)
|
||||
@@ -111,6 +123,7 @@ const char *pcap_lib_version(void)
|
||||
.ft B
|
||||
void pcap_close(pcap_t *p)
|
||||
int pcap_dump_flush(pcap_dumper_t *p)
|
||||
long pcap_dump_ftell(pcap_dumper_t *p)
|
||||
FILE *pcap_dump_file(pcap_dumper_t *p)
|
||||
void pcap_dump_close(pcap_dumper_t *p)
|
||||
.ft
|
||||
@@ -128,6 +141,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 +220,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 +247,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 +380,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 +661,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() .
|
||||
@@ -707,6 +779,31 @@ when that BPF program is no longer needed, for example after it
|
||||
has been made the filter program for a pcap structure by a call to
|
||||
.BR pcap_setfilter() .
|
||||
.PP
|
||||
.B pcap_setdirection()
|
||||
is used to specify a direction that packets will be captured.
|
||||
.I pcap_direction_t
|
||||
is one of the constants
|
||||
.BR PCAP_D_IN ,
|
||||
.B PCAP_D_OUT
|
||||
or
|
||||
.BR PCAP_D_INOUT .
|
||||
.B PCAP_D_IN
|
||||
will only capture packets received by the device,
|
||||
.B PCAP_D_OUT
|
||||
will only capture packets sent by the device and
|
||||
.B PCAP_D_INOUT
|
||||
will capture packets received by or sent by the device.
|
||||
.B PCAP_D_INOUT
|
||||
is the default setting if this function is not called. This isn't
|
||||
necessarily supported on all platforms; some platforms might return an
|
||||
error, and some other platforms might not support
|
||||
.BR PCAP_D_OUT .
|
||||
This operation is not supported if a ``savefile'' is being read.
|
||||
.B \-1
|
||||
is returned on failure,
|
||||
.B 0
|
||||
is returned on success.
|
||||
.PP
|
||||
.B pcap_datalink()
|
||||
returns the link layer type; link layer types it can return include:
|
||||
.PP
|
||||
@@ -1164,6 +1261,15 @@ but not yet written to the ``savefile'' will be written.
|
||||
.B \-1
|
||||
is returned on error, 0 on success.
|
||||
.PP
|
||||
.B pcap_dump_ftell()
|
||||
returns the current file position for the ``savefile'', representing the
|
||||
number of bytes written by
|
||||
.B pcap_dump_open()
|
||||
and
|
||||
.BR pcap_dump() .
|
||||
.B \-1
|
||||
is returned on error.
|
||||
.PP
|
||||
.B pcap_dump_close()
|
||||
closes the ``savefile.''
|
||||
.PP
|
||||
|
||||
@@ -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;
|
||||
@@ -311,7 +331,7 @@ static struct dlt_choice dlt_choices[] = {
|
||||
DLT_CHOICE(DLT_SLIP, "SLIP"),
|
||||
DLT_CHOICE(DLT_PPP, "PPP"),
|
||||
DLT_CHOICE(DLT_FDDI, "FDDI"),
|
||||
DLT_CHOICE(DLT_ATM_RFC1483, "RFC 1483 IP-over-ATM"),
|
||||
DLT_CHOICE(DLT_ATM_RFC1483, "RFC 1483 LLC-encapsulated ATM"),
|
||||
DLT_CHOICE(DLT_RAW, "Raw IP"),
|
||||
DLT_CHOICE(DLT_SLIP_BSDOS, "BSD/OS SLIP"),
|
||||
DLT_CHOICE(DLT_PPP_BSDOS, "BSD/OS PPP"),
|
||||
@@ -332,8 +352,27 @@ 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(DLT_JUNIPER_GGSN, "Juniper GGSN PIC"),
|
||||
DLT_CHOICE(DLT_JUNIPER_ES, "Juniper Encryption Services PIC"),
|
||||
DLT_CHOICE(DLT_JUNIPER_MONITOR, "Juniper Passive Monitor PIC"),
|
||||
DLT_CHOICE(DLT_JUNIPER_SERVICES, "Juniper Advanced Services PIC"),
|
||||
DLT_CHOICE_SENTINEL
|
||||
};
|
||||
|
||||
@@ -502,7 +541,7 @@ pcap_fileno(pcap_t *p)
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
#if !defined(WIN32) && !defined(MSDOS)
|
||||
int
|
||||
pcap_get_selectable_fd(pcap_t *p)
|
||||
{
|
||||
@@ -535,7 +574,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 +599,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 +642,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 +657,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
|
||||
@@ -647,6 +689,23 @@ pcap_setfilter(pcap_t *p, struct bpf_program *fp)
|
||||
return p->setfilter_op(p, fp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set direction flag, which controls whether we accept only incoming
|
||||
* packets, only outgoing packets, or both.
|
||||
* Note that, depending on the platform, some or all direction arguments
|
||||
* might not be supported.
|
||||
*/
|
||||
int
|
||||
pcap_setdirection(pcap_t *p, pcap_direction_t d)
|
||||
{
|
||||
if (p->setdirection_op == NULL) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Setting direction is not implemented on this platform");
|
||||
return -1;
|
||||
} else
|
||||
return p->setdirection_op(p, d);
|
||||
}
|
||||
|
||||
int
|
||||
pcap_stats(pcap_t *p, struct pcap_stat *ps)
|
||||
{
|
||||
@@ -654,15 +713,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 +753,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 +799,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 +835,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 +852,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)
|
||||
|
||||
@@ -37,12 +37,15 @@
|
||||
#ifndef lib_pcap_h
|
||||
#define lib_pcap_h
|
||||
|
||||
#ifdef WIN32
|
||||
#if defined(WIN32)
|
||||
#include <pcap-stdinc.h>
|
||||
#else /* WIN32 */
|
||||
#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 */
|
||||
#endif /* WIN32/MSDOS/UN*X */
|
||||
|
||||
#ifndef PCAP_DONT_INCLUDE_PCAP_BPF_H
|
||||
#include <pcap-bpf.h>
|
||||
@@ -117,6 +120,12 @@ struct pcap_file_header {
|
||||
bpf_u_int32 linktype; /* data link type (LINKTYPE_*) */
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
PCAP_D_INOUT = 0,
|
||||
PCAP_D_IN,
|
||||
PCAP_D_OUT
|
||||
} pcap_direction_t;
|
||||
|
||||
/*
|
||||
* Each packet in the dump file is prepended with this generic header.
|
||||
* This gets around the problem of different headers for different
|
||||
@@ -140,6 +149,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 +214,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 *);
|
||||
@@ -181,9 +224,12 @@ int pcap_next_ex(pcap_t *, struct pcap_pkthdr **, const u_char **);
|
||||
void pcap_breakloop(pcap_t *);
|
||||
int pcap_stats(pcap_t *, struct pcap_stat *);
|
||||
int pcap_setfilter(pcap_t *, struct bpf_program *);
|
||||
int pcap_setdirection(pcap_t *, pcap_direction_t);
|
||||
int pcap_getnonblock(pcap_t *, char *);
|
||||
int pcap_setnonblock(pcap_t *, int, char *);
|
||||
void pcap_perror(pcap_t *, char *);
|
||||
int pcap_inject(pcap_t *, const void *, size_t);
|
||||
int pcap_sendpacket(pcap_t *, const u_char *, int);
|
||||
char *pcap_strerror(int);
|
||||
char *pcap_geterr(pcap_t *);
|
||||
int pcap_compile(pcap_t *, struct bpf_program *, char *, int,
|
||||
@@ -207,10 +253,12 @@ FILE *pcap_file(pcap_t *);
|
||||
int pcap_fileno(pcap_t *);
|
||||
|
||||
pcap_dumper_t *pcap_dump_open(pcap_t *, const char *);
|
||||
pcap_dumper_t *pcap_dump_fopen(pcap_t *, FILE *fp);
|
||||
FILE *pcap_dump_file(pcap_dumper_t *);
|
||||
long pcap_dump_ftell(pcap_dumper_t *);
|
||||
int pcap_dump_flush(pcap_dumper_t *);
|
||||
void pcap_dump_close(pcap_dumper_t *);
|
||||
void pcap_dump(u_char *, const struct pcap_pkthdr *, const u_char *);
|
||||
FILE *pcap_dump_file(pcap_dumper_t *);
|
||||
|
||||
int pcap_findalldevs(pcap_if_t **, char *);
|
||||
void pcap_freealldevs(pcap_if_t *);
|
||||
@@ -223,33 +271,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
libpcap-possiblymodified/pcap1.h
Normal file
302
libpcap-possiblymodified/pcap1.h
Normal file
@@ -0,0 +1,302 @@
|
||||
/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */
|
||||
/*
|
||||
* Copyright (c) 1993, 1994, 1995, 1996, 1997
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the Computer Systems
|
||||
* Engineering Group at Lawrence Berkeley Laboratory.
|
||||
* 4. Neither the name of the University nor of the Laboratory may be used
|
||||
* to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#) $Header: /tcpdump/master/libpcap/pcap1.h,v 1.2 2004/03/30 14:42:50 mcr Exp $ (LBL)
|
||||
*/
|
||||
|
||||
#ifndef lib_pcap_h
|
||||
#define lib_pcap_h
|
||||
|
||||
#ifdef WIN32
|
||||
#include <pcap-stdinc.h>
|
||||
#else /* WIN32 */
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#endif /* WIN32 */
|
||||
|
||||
#ifndef PCAP_DONT_INCLUDE_PCAP_BPF_H
|
||||
#include <pcap-bpf.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define PCAP_VERSION_MAJOR 3
|
||||
#define PCAP_VERSION_MINOR 0
|
||||
|
||||
#define PCAP_ERRBUF_SIZE 256
|
||||
|
||||
/*
|
||||
* Compatibility for systems that have a bpf.h that
|
||||
* predates the bpf typedefs for 64-bit support.
|
||||
*/
|
||||
#if BPF_RELEASE - 0 < 199406
|
||||
typedef int bpf_int32;
|
||||
typedef u_int bpf_u_int32;
|
||||
#endif
|
||||
|
||||
typedef struct pcap pcap_t;
|
||||
typedef struct pcap_dumper pcap_dumper_t;
|
||||
typedef struct pcap_if pcap_if_t;
|
||||
typedef struct pcap_addr pcap_addr_t;
|
||||
|
||||
/*
|
||||
* The first record in the file contains saved values for some
|
||||
* of the flags used in the printout phases of tcpdump.
|
||||
* Many fields here are 32 bit ints so compilers won't insert unwanted
|
||||
* padding; these files need to be interchangeable across architectures.
|
||||
*
|
||||
* Do not change the layout of this structure, in any way (this includes
|
||||
* changes that only affect the length of fields in this structure).
|
||||
*
|
||||
* Also, do not change the interpretation of any of the members of this
|
||||
* structure, in any way (this includes using values other than
|
||||
* LINKTYPE_ values, as defined in "savefile.c", in the "linktype"
|
||||
* field).
|
||||
*
|
||||
* Instead:
|
||||
*
|
||||
* introduce a new structure for the new format, if the layout
|
||||
* of the structure changed;
|
||||
*
|
||||
* send mail to "tcpdump-workers@tcpdump.org", requesting a new
|
||||
* magic number for your new capture file format, and, when
|
||||
* you get the new magic number, put it in "savefile.c";
|
||||
*
|
||||
* use that magic number for save files with the changed file
|
||||
* header;
|
||||
*
|
||||
* make the code in "savefile.c" capable of reading files with
|
||||
* the old file header as well as files with the new file header
|
||||
* (using the magic number to determine the header format).
|
||||
*
|
||||
* Then supply the changes to "patches@tcpdump.org", so that future
|
||||
* versions of libpcap and programs that use it (such as tcpdump) will
|
||||
* be able to read your new capture file format.
|
||||
*/
|
||||
|
||||
enum pcap1_info_types {
|
||||
PCAP_DATACAPTURE,
|
||||
PCAP_TIMESTAMP,
|
||||
PCAP_WALLTIME,
|
||||
PCAP_TIMESKEW,
|
||||
PCAP_PROBEPLACE, /* aka direction */
|
||||
PCAP_COMMENT, /* comment */
|
||||
};
|
||||
|
||||
struct pcap1_info_container {
|
||||
bpf_u_int32 info_len; /* in bytes */
|
||||
bpf_u_int32 info_type; /* enum pcap1_info_types */
|
||||
unsigned char info_data[0];
|
||||
};
|
||||
|
||||
struct pcap1_info_timestamp {
|
||||
struct pcap1_info_container pic;
|
||||
bpf_u_int32 nanoseconds; /* 10^-9 of seconds */
|
||||
bpf_u_int32 seconds; /* seconds since Unix epoch - GMT */
|
||||
bpf_u_int16 macroseconds; /* 16 bits more of MSB of time */
|
||||
bpf_u_int16 sigfigs; /* accuracy of timestamps - LSB bits */
|
||||
};
|
||||
|
||||
struct pcap1_info_packet {
|
||||
struct pcap1_info_container pic;
|
||||
bpf_u_int32 caplen; /* length of portion present */
|
||||
bpf_u_int32 len; /* length this packet (off wire) */
|
||||
bpf_u_int32 linktype; /* data link type (LINKTYPE_*) */
|
||||
bpf_u_int32 ifIndex; /* abstracted interface index */
|
||||
unsigned char packet_data[0];
|
||||
};
|
||||
|
||||
enum pcap1_probe {
|
||||
INBOUND =1,
|
||||
OUTBOUND =2,
|
||||
FORWARD =3,
|
||||
PREENCAP =4,
|
||||
POSTDECAP=5,
|
||||
};
|
||||
|
||||
struct pcap1_info_probe {
|
||||
struct pcap1_info_container pic;
|
||||
bpf_u_int32 probeloc; /* enum pcap1_probe */
|
||||
unsigned char probe_desc[0];
|
||||
};
|
||||
|
||||
struct pcap1_info_comment {
|
||||
struct pcap1_info_container pic;
|
||||
unsigned char comment[0];
|
||||
};
|
||||
|
||||
struct pcap1_packet_header {
|
||||
bpf_u_int32 magic;
|
||||
u_short version_major;
|
||||
u_short version_minor;
|
||||
bpf_u_int32 block_len;
|
||||
struct pcap1_info_container pics[0];
|
||||
};
|
||||
|
||||
/*
|
||||
* Each packet in the dump file is prepended with this generic header.
|
||||
* This gets around the problem of different headers for different
|
||||
* packet interfaces.
|
||||
*/
|
||||
|
||||
/*
|
||||
* As returned by the pcap_stats()
|
||||
*/
|
||||
struct pcap_stat {
|
||||
u_int ps_recv; /* number of packets received */
|
||||
u_int ps_drop; /* number of packets dropped */
|
||||
u_int ps_ifdrop; /* drops by interface XXX not yet supported */
|
||||
#ifdef WIN32
|
||||
u_int bs_capt; /* number of packets that reach the application */
|
||||
#endif /* WIN32 */
|
||||
};
|
||||
|
||||
/*
|
||||
* Item in a list of interfaces.
|
||||
*/
|
||||
struct pcap_if {
|
||||
struct pcap_if *next;
|
||||
char *name; /* name to hand to "pcap_open_live()" */
|
||||
char *description; /* textual description of interface, or NULL */
|
||||
struct pcap_addr *addresses;
|
||||
bpf_u_int32 flags; /* PCAP_IF_ interface flags */
|
||||
};
|
||||
|
||||
#define PCAP_IF_LOOPBACK 0x00000001 /* interface is loopback */
|
||||
|
||||
/*
|
||||
* Representation of an interface address.
|
||||
*/
|
||||
struct pcap_addr {
|
||||
struct pcap_addr *next;
|
||||
struct sockaddr *addr; /* address */
|
||||
struct sockaddr *netmask; /* netmask for that address */
|
||||
struct sockaddr *broadaddr; /* broadcast address for that address */
|
||||
struct sockaddr *dstaddr; /* P2P destination address for that address */
|
||||
};
|
||||
|
||||
typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *,
|
||||
const u_char *);
|
||||
|
||||
char *pcap_lookupdev(char *);
|
||||
int pcap_lookupnet(const char *, bpf_u_int32 *, bpf_u_int32 *, char *);
|
||||
pcap_t *pcap_open_live(const char *, int, int, int, char *);
|
||||
pcap_t *pcap_open_dead(int, int);
|
||||
pcap_t *pcap_open_offline(const char *, char *);
|
||||
void pcap_close(pcap_t *);
|
||||
int pcap_loop(pcap_t *, int, pcap_handler, u_char *);
|
||||
int pcap_dispatch(pcap_t *, int, pcap_handler, u_char *);
|
||||
const u_char*
|
||||
pcap_next(pcap_t *, struct pcap_pkthdr *);
|
||||
int pcap_next_ex(pcap_t *, struct pcap_pkthdr **, const u_char **);
|
||||
void pcap_breakloop(pcap_t *);
|
||||
int pcap_stats(pcap_t *, struct pcap_stat *);
|
||||
int pcap_setfilter(pcap_t *, struct bpf_program *);
|
||||
int pcap_getnonblock(pcap_t *, char *);
|
||||
int pcap_setnonblock(pcap_t *, int, char *);
|
||||
void pcap_perror(pcap_t *, char *);
|
||||
char *pcap_strerror(int);
|
||||
char *pcap_geterr(pcap_t *);
|
||||
int pcap_compile(pcap_t *, struct bpf_program *, char *, int,
|
||||
bpf_u_int32);
|
||||
int pcap_compile_nopcap(int, int, struct bpf_program *,
|
||||
char *, int, bpf_u_int32);
|
||||
void pcap_freecode(struct bpf_program *);
|
||||
int pcap_datalink(pcap_t *);
|
||||
int pcap_list_datalinks(pcap_t *, int **);
|
||||
int pcap_set_datalink(pcap_t *, int);
|
||||
int pcap_datalink_name_to_val(const char *);
|
||||
const char *pcap_datalink_val_to_name(int);
|
||||
const char *pcap_datalink_val_to_description(int);
|
||||
int pcap_snapshot(pcap_t *);
|
||||
int pcap_is_swapped(pcap_t *);
|
||||
int pcap_major_version(pcap_t *);
|
||||
int pcap_minor_version(pcap_t *);
|
||||
|
||||
/* XXX */
|
||||
FILE *pcap_file(pcap_t *);
|
||||
int pcap_fileno(pcap_t *);
|
||||
|
||||
pcap_dumper_t *pcap_dump_open(pcap_t *, const char *);
|
||||
int pcap_dump_flush(pcap_dumper_t *);
|
||||
void pcap_dump_close(pcap_dumper_t *);
|
||||
void pcap_dump(u_char *, const struct pcap_pkthdr *, const u_char *);
|
||||
FILE *pcap_dump_file(pcap_dumper_t *);
|
||||
|
||||
int pcap_findalldevs(pcap_if_t **, char *);
|
||||
void pcap_freealldevs(pcap_if_t *);
|
||||
|
||||
const char *pcap_lib_version(void);
|
||||
|
||||
/* XXX this guy lives in the bpf tree */
|
||||
u_int bpf_filter(struct bpf_insn *, u_char *, u_int, u_int);
|
||||
int bpf_validate(struct bpf_insn *f, int len);
|
||||
char *bpf_image(struct bpf_insn *, int);
|
||||
void bpf_dump(struct bpf_program *, int);
|
||||
|
||||
#ifdef WIN32
|
||||
/*
|
||||
* Win32 definitions
|
||||
*/
|
||||
|
||||
int pcap_setbuff(pcap_t *p, int dim);
|
||||
int pcap_setmode(pcap_t *p, int mode);
|
||||
int pcap_sendpacket(pcap_t *p, u_char *buf, int size);
|
||||
int pcap_setmintocopy(pcap_t *p, int size);
|
||||
|
||||
#ifdef WPCAP
|
||||
/* Include file with the wpcap-specific extensions */
|
||||
#include <Win32-Extensions.h>
|
||||
#endif
|
||||
|
||||
#define MODE_CAPT 0
|
||||
#define MODE_STAT 1
|
||||
|
||||
#else
|
||||
/*
|
||||
* UN*X definitions
|
||||
*/
|
||||
|
||||
int pcap_get_selectable_fd(pcap_t *);
|
||||
|
||||
#endif /* WIN32 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -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];
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -1,105 +0,0 @@
|
||||
/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */
|
||||
/*
|
||||
* Copyright (c) 2003 - The tcpdump group.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor of the Laboratory may be used
|
||||
* to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#) $Header$ (LBL)
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is never used in libpcap or tcpdump. It is provided as
|
||||
* documentation linktypes 139 through 142 only.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Date: Tue, 09 Sep 2003 09:41:04 -0400
|
||||
* From: Jeff Morriss <jeff.morriss[AT]ulticom.com>
|
||||
* To: tcpdump-workers@tcpdump.org
|
||||
* Subject: [tcpdump-workers] request for LINKTYPE_
|
||||
*
|
||||
* We've had some discussion over on ethereal-dev about a "fake link" or
|
||||
* "raw SS7" dissector that allows dumping an arbitrary protocol into a
|
||||
* file without any (otherwise necessary) lower level protocols. The
|
||||
* common example has been dumping MTP3 into a file without, well, MTP2 or
|
||||
* M2PA.
|
||||
*
|
||||
* We want to store these protocols directly in PCAP file format because
|
||||
* it's well defined and there isn't another (popular) file format for
|
||||
* capturing SS7 messages that we can reverse engineer (and we want to read
|
||||
* these files into Ethereal). Rather than creating a new file format, it's
|
||||
* a lot easier to just allocate a LINKTYPE_.
|
||||
*
|
||||
* Here is the original post thread:
|
||||
*
|
||||
* http://ethereal.com/lists/ethereal-dev/200306/threads.html#00200
|
||||
*
|
||||
* July's thread on the subject:
|
||||
*
|
||||
* http://ethereal.com/lists/ethereal-dev/200307/threads.html#00124
|
||||
*
|
||||
* August's thread:
|
||||
*
|
||||
* http://ethereal.com/lists/ethereal-dev/200308/threads.html#00193
|
||||
*
|
||||
*
|
||||
* and one of the last messages--which is why I'm mailing you today:
|
||||
*
|
||||
* http://ethereal.com/lists/ethereal-dev/200308/msg00193.html
|
||||
*
|
||||
*
|
||||
* Based on the message in the last URL, I'd like to request a new
|
||||
* LINKTYPE_: LINKTYPE_RAWSS7.
|
||||
*
|
||||
* This packets in this file type will contain a header:
|
||||
*/
|
||||
|
||||
typedef struct _rawss7_hdr {
|
||||
/* NOTE: These are in network-byte order. */
|
||||
guint32 type;
|
||||
guint16 length;
|
||||
guint16 spare;
|
||||
} rawss7_hdr;
|
||||
|
||||
/*
|
||||
*
|
||||
* followed by protocol data for whatever protocol 'type' indicates.
|
||||
*
|
||||
* There was some discussion about these protocol 'type's being allocated by
|
||||
* tcpdump-workers as well. In fact it would be handy to have one place to
|
||||
* allocate such numbers, so what do you think about allocating 3 more (for
|
||||
* now) LINKTYPE_'s:
|
||||
*/
|
||||
|
||||
#define LINKTYPE_RAWSS7_MTP2 140
|
||||
#define LINKTYPE_RAWSS7_MTP3 141
|
||||
#define LINKTYPE_RAWSS7_SCCP 142
|
||||
|
||||
/*
|
||||
*
|
||||
* There is no reason this can't be used to store non-SS7 protocols, but
|
||||
* it's what we need to use it for now...
|
||||
*
|
||||
*/
|
||||
@@ -49,8 +49,27 @@ static const char rcsid[] _U_ =
|
||||
#include "os-proto.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Standard libpcap format.
|
||||
*/
|
||||
#define TCPDUMP_MAGIC 0xa1b2c3d4
|
||||
#define PATCHED_TCPDUMP_MAGIC 0xa1b2cd34
|
||||
|
||||
/*
|
||||
* 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 */
|
||||
@@ -242,16 +269,11 @@ static const char rcsid[] _U_ =
|
||||
|
||||
#define LINKTYPE_APPLE_IP_OVER_IEEE1394 138 /* Apple IP-over-IEEE 1394 cooked header */
|
||||
|
||||
#define LINKTYPE_RAWSS7 139 /* see rawss7.h for */
|
||||
#define LINKTYPE_RAWSS7_MTP2 140 /* information on these */
|
||||
#define LINKTYPE_RAWSS7_MTP3 141 /* definitions */
|
||||
#define LINKTYPE_RAWSS7_SCCP 142
|
||||
#define LINKTYPE_MTP2_WITH_PHDR 139
|
||||
#define LINKTYPE_MTP2 140
|
||||
#define LINKTYPE_MTP3 141
|
||||
#define LINKTYPE_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,71 @@ 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 */
|
||||
|
||||
/*
|
||||
* Requested by Daniele Orlandi <daniele@orlandi.com> for raw LAPD
|
||||
* for vISDN (http://www.orlandi.com/visdn/). Its link-layer header
|
||||
* includes additional information before the LAPD header, so it's
|
||||
* not necessarily a generic LAPD header.
|
||||
*/
|
||||
#define LINKTYPE_LINUX_LAPD 177
|
||||
|
||||
static struct linktype_map {
|
||||
int dlt;
|
||||
int linktype;
|
||||
@@ -451,6 +538,12 @@ static struct linktype_map {
|
||||
/* Apple IP-over-IEEE 1394 cooked header */
|
||||
{ DLT_APPLE_IP_OVER_IEEE1394, LINKTYPE_APPLE_IP_OVER_IEEE1394 },
|
||||
|
||||
/* SS7 */
|
||||
{ DLT_MTP2_WITH_PHDR, LINKTYPE_MTP2_WITH_PHDR },
|
||||
{ DLT_MTP2, LINKTYPE_MTP2 },
|
||||
{ DLT_MTP3, LINKTYPE_MTP3 },
|
||||
{ DLT_SCCP, LINKTYPE_SCCP },
|
||||
|
||||
/* DOCSIS MAC frames */
|
||||
{ DLT_DOCSIS, LINKTYPE_DOCSIS },
|
||||
|
||||
@@ -486,6 +579,38 @@ static struct linktype_map {
|
||||
/* 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_PIC_PEER, LINKTYPE_JUNIPER_PIC_PEER },
|
||||
|
||||
/* Endace types */
|
||||
{ DLT_ERF_ETH, LINKTYPE_ERF_ETH },
|
||||
{ DLT_ERF_POS, LINKTYPE_ERF_POS },
|
||||
|
||||
/* viSDN LAPD */
|
||||
{ DLT_LINUX_LAPD, LINKTYPE_LINUX_LAPD },
|
||||
|
||||
{ -1, -1 }
|
||||
};
|
||||
|
||||
@@ -584,6 +709,26 @@ 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);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set direction flag: Which packets do we accept on a forwarding
|
||||
* single device? IN, OUT or both?
|
||||
*/
|
||||
static int
|
||||
sf_setdirection(pcap_t *p, pcap_direction_t d)
|
||||
{
|
||||
snprintf(p->errbuf, sizeof(p->errbuf),
|
||||
"Setting direction is not supported on savefiles");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static void
|
||||
sf_close(pcap_t *p)
|
||||
{
|
||||
@@ -595,10 +740,47 @@ 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;
|
||||
#if defined(WIN32) || defined(MSDOS)
|
||||
/*
|
||||
* We're reading from the standard input, so put it in binary
|
||||
* mode, as savefiles are binary files.
|
||||
*/
|
||||
SET_BINMODE(fp);
|
||||
#endif
|
||||
}
|
||||
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 +792,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 +817,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 +882,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 +916,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,7 +928,9 @@ 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->setdirection_op = sf_setdirection;
|
||||
p->set_datalink_op = NULL; /* we don't support munging link-layer headers */
|
||||
p->getnonblock_op = sf_getnonblock;
|
||||
p->setnonblock_op = sf_setnonblock;
|
||||
@@ -749,8 +939,6 @@ pcap_open_offline(const char *fname, char *errbuf)
|
||||
|
||||
return (p);
|
||||
bad:
|
||||
if(fp)
|
||||
fclose(fp);
|
||||
free(p);
|
||||
return (NULL);
|
||||
}
|
||||
@@ -906,7 +1094,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 +1125,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 +1155,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 +1201,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 +1214,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 *
|
||||
@@ -1012,6 +1242,12 @@ pcap_dump_file(pcap_dumper_t *p)
|
||||
return ((FILE *)p);
|
||||
}
|
||||
|
||||
long
|
||||
pcap_dump_ftell(pcap_dumper_t *p)
|
||||
{
|
||||
return (ftell((FILE *)p));
|
||||
}
|
||||
|
||||
int
|
||||
pcap_dump_flush(pcap_dumper_t *p)
|
||||
{
|
||||
|
||||
@@ -183,6 +183,7 @@ igmp return IGMP;
|
||||
igrp return IGRP;
|
||||
pim return PIM;
|
||||
vrrp return VRRP;
|
||||
radio return RADIO;
|
||||
|
||||
ip6 {
|
||||
#ifdef INET6
|
||||
@@ -234,6 +235,7 @@ host return HOST;
|
||||
net return NET;
|
||||
mask return NETMASK;
|
||||
port return PORT;
|
||||
portrange return PORTRANGE;
|
||||
proto return PROTO;
|
||||
protochain {
|
||||
#ifdef NO_PROTOCHAIN
|
||||
@@ -260,6 +262,7 @@ inbound return INBOUND;
|
||||
outbound return OUTBOUND;
|
||||
|
||||
vlan return VLAN;
|
||||
mpls return MPLS;
|
||||
|
||||
lane return LANE;
|
||||
llc return LLC;
|
||||
@@ -283,6 +286,11 @@ srnr|subrulenum return PF_SRNR;
|
||||
reason return PF_REASON;
|
||||
action return PF_ACTION;
|
||||
|
||||
sio return SIO;
|
||||
opc return OPC;
|
||||
dpc return DPC;
|
||||
sls return SLS;
|
||||
|
||||
[ \r\n\t] ;
|
||||
[+\-*/:\[\]!<>()&|=] return yytext[0];
|
||||
">=" return GEQ;
|
||||
|
||||
1
libpcap-possiblymodified/version.h
Normal file
1
libpcap-possiblymodified/version.h
Normal file
@@ -0,0 +1 @@
|
||||
static const char pcap_version_string[] = "libpcap version 0.8.3";
|
||||
Reference in New Issue
Block a user