Import vendor revision 77da77c36e5d958f9b8d6729876a33f670de031f from:

https://github.com/the-tcpdump-group/libpcap.git

This among other minor fixes adds support for sniffing RDMA devices.

Sponsored by:	Mellanox Technologies
This commit is contained in:
Hans Petter Selasky 2018-05-18 12:21:19 +00:00
parent 2369c04eb9
commit d109bf9e4b
175 changed files with 21177 additions and 15728 deletions

27
CHANGES
View File

@ -1,3 +1,30 @@
Wednesday, Jan. 25, 2017 guy@alum.mit.edu
Summary for 1.9.0 libpcap release
Man page improvements
Fix Linux cooked mode userspace filtering (GitHub pull request #429)
Fix compilation if IPv6 support not enabled
Fix some Linux memory-mapped capture buffer size issues
Don't fail if kernel filter can't be set on Linux (GitHub issue
#549)
Improve sorting of interfaces for pcap_findalldevs()
Don't list Linux usbmon devices if usbmon module isn't loaded
Report PCAP_ERROR_PERM_DENIED if no permission to open Linux usbmon
devices
Fix DLT_ type for Solaris IPNET devices
Always return an error message for errors finding DAG or Myricom
devices
If possible, don't require that a device be openable when
enumerating them for pcap_findalldevs()
Don't put incompletely-initialized addresses in the address list for
When finding Myricom devices, update description for regular
interfaces that are Myricom devices and handle SNF_FLAGS=0x2(port
aggregation enabled)
Fix compilation error in DAG support
Fix issues with CMake configuration
Add support for stream buffers larger than 2GB on newer DAG cards
Remove support for building against DAG versions without STREAMS
support (before dag-3.0.0 2007)
Tuesday, Oct. 25, 2016 mcr@sandelman.ca
Summary for 1.8.1 libpcap release
Add a target in Makefile.in for Exuberant Ctags use: 'extags'.

File diff suppressed because it is too large Load Diff

29
CONTRIBUTING Normal file
View File

@ -0,0 +1,29 @@
Guidelines for contributing
===========================
To report a security issue (segfault, buffer overflow, infinite loop, arbitrary
code execution etc) please send an e-mail to security@tcpdump.org, do not use
the bug tracker!
To report a non-security problem (failure to compile, failure to capture packets
properly, missing support for a network interface type or DLT) please check
first that it reproduces with the latest stable release of libpcap. If it does,
please check that the problem reproduces with the current git master branch of
libpcap. If it does (and it is not a security-related problem, otherwise see
above), please navigate to https://github.com/the-tcpdump-group/libpcap/issues
and check if the problem has already been reported. If it has not, please open
a new issue and provide the following details:
* libpcap version (e.g. from tcpdump --version)
* operating system name and version and any other details that may be relevant
(uname -a, compiler name and version, CPU type etc.)
* configure flags if any were used
* statement of the problem
* steps to reproduce
Please note that if you know exactly how to solve the problem and the solution
would not be too intrusive, it would be best to contribute some development time
and open a pull request instead.
Still not sure how to do? Feel free to [subscribe](http://www.tcpdump.org/#mailing-lists)
to the mailing list tcpdump-workers@lists.tcpdump.org and ask!

View File

@ -64,7 +64,7 @@ Additional people who have contributed patches:
George Neville-Neil <gnn at freebsd dot org>
Gianluca Varenni <gianluca dot varenni at gmail dot com>
Gilbert Hoyek <gil_hoyek at hotmail dot com>
Gisle Vanem <gvanem at broadpark dot no>
Gisle Vanem <gvanem at yahoo dot no>
Graeme Hewson <ghewson at cix dot compulink dot co dot uk>
Gregor Maier <gregor at net dot in dot tum dot de>
Greg Stark <gsstark at mit dot edu>

View File

@ -1,23 +0,0 @@
REM
REM Automatically generate pcap_version.h based on pcap_version.h.in
REM for Windows
REM The version string comes from VERSION
REM @echo off
REM
setlocal enableextensions disabledelayedexpansion
set "search=%%%%LIBPCAP_VERSION%%%%"
set /p replace=<%1
if exist %3 del %3 2>nul
for /f "delims=" %%i in ('type %2' ) do (
set "line=%%i"
setlocal enabledelayedexpansion
set "line=!line:%search%=%replace%!"
>>%3 echo(!line!
endlocal
)
echo pcap_version.h generated

View File

@ -250,28 +250,13 @@ libpcap program and it dies with:
You must add streams NIT support to your kernel configuration, run
config and boot the new kernel.
If you are running a version of SunOS earlier than 4.1, you will need
to replace the Sun supplied /sys/sun{3,4,4c}/OBJ/nit_if.o with the
appropriate version from this distribution's SUNOS4 subdirectory and
build a new kernel:
nit_if.o.sun3-sunos4 (any flavor of sun3)
nit_if.o.sun4c-sunos4.0.3c (SS1, SS1+, IPC, SLC, etc.)
nit_if.o.sun4-sunos4 (Sun4's not covered by
nit_if.o.sun4c-sunos4.0.3c)
These nit replacements fix a bug that makes nit essentially unusable in
pre-SunOS 4.1. In addition, our sun4c-sunos4.0.3c nit gives you
timestamps to the resolution of the SS-1 clock (1 us) rather than the
lousy 20ms timestamps Sun gives you (tcpdump will print out the full
timestamp resolution if it finds it's running on a SS-1).
FILES
-----
CHANGES - description of differences between releases
ChmodBPF/* - Mac OS X startup item to set ownership and permissions
ChmodBPF/* - macOS startup item to set ownership and permissions
on /dev/bpf*
CMakeLists.txt - CMake file
CONTRIBUTING - guidelines for contributing
CREDITS - people that have helped libpcap along
INSTALL.txt - this file
LICENSE - the license under which tcpdump is distributed
@ -281,12 +266,11 @@ 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.macos - notes on using libpcap on macOS
README.septel - notes on using libpcap to capture on Intel/Septel devices
README.sita - notes on using libpcap to capture on SITA devices
README.tru64 - notes on using libpcap on Digital/Tru64 UNIX
README.Win32 - notes on using libpcap on Win32 systems (with WinPcap)
SUNOS4 - pre-SunOS 4.1 replacement kernel nit modules
VERSION - version of this release
acconfig.h - support for post-2.13 autoconf
aclocal.m4 - autoconf macros
@ -314,7 +298,6 @@ gencode.c - BPF code generation routines
gencode.h - BPF code generation definitions
grammar.y - filter string grammar
ieee80211.h - 802.11 definitions
inet.c - network routines
install-sh - BSD style install script
lbl/os-*.h - OS-dependent defines and prototypes
llc.h - 802.2 LLC SAP definitions
@ -347,6 +330,7 @@ pcap-linux.c - Linux packet socket support
pcap-namedb.h - header for backwards compatibility
pcap-nit.c - SunOS Network Interface Tap support
pcap-nit.h - SunOS Network Interface Tap definitions
pcap-npf.c - WinPcap capture support
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
@ -360,7 +344,6 @@ pcap-snit.c - SunOS 4.x STREAMS-based Network Interface Tap support
pcap-snoop.c - IRIX Snoop network monitoring support
pcap-usb-linux.c - USB capture support for Linux
pcap-usb-linux.h - USB capture support for Linux
pcap-win32.c - WinPcap capture support
pcap.3pcap - manual entry for the library
pcap.c - pcap utility routines
pcap.h - header for backwards compatibility

View File

@ -27,6 +27,8 @@ exec_prefix = @exec_prefix@
datarootdir = @datarootdir@
# Pathname of directory to install the configure program
bindir = @bindir@
# Pathname of directory to install the rpcapd daemon
sbindir = @sbindir@
# Pathname of directory to install the include files
includedir = @includedir@
# Pathname of directory to install the library
@ -48,8 +50,9 @@ AR = @AR@
LN_S = @LN_S@
MKDEP = @MKDEP@
CCOPT = @V_CCOPT@
SHLIB_CCOPT = @V_SHLIB_CCOPT@
INCLS = -I. @V_INCLS@
DEFS = -DBUILDING_PCAP @DEFS@ @V_DEFS@
DEFS = -DBUILDING_PCAP -Dpcap_EXPORTS @DEFS@ @V_DEFS@
ADDLOBJS = @ADDLOBJS@
ADDLARCHIVEOBJS = @ADDLARCHIVEOBJS@
LIBS = @LIBS@
@ -60,9 +63,13 @@ DYEXT = @DYEXT@
V_RPATH_OPT = @V_RPATH_OPT@
DEPENDENCY_CFLAG = @DEPENDENCY_CFLAG@
PROG=libpcap
PTHREAD_LIBS=@PTHREAD_LIBS@
BUILD_RPCAPD=@BUILD_RPCAPD@
INSTALL_RPCAPD=@INSTALL_RPCAPD@
EXTRA_NETWORK_LIBS=@EXTRA_NETWORK_LIBS@
# Standard CFLAGS
FULL_CFLAGS = $(CCOPT) $(INCLS) $(DEFS) $(CFLAGS)
# Standard CFLAGS for building members of a shared library
FULL_CFLAGS = $(CCOPT) $(SHLIB_CCOPT) $(INCLS) $(DEFS) $(CFLAGS)
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
@ -79,13 +86,14 @@ YACC = @YACC@
@rm -f $@
$(CC) $(FULL_CFLAGS) -c $(srcdir)/$*.c
PSRC = pcap-@V_PCAP@.c @USB_SRC@ @BT_SRC@ @BT_MONITOR_SRC@ @NETFILTER_SRC@ @DBUS_SRC@
PSRC = pcap-@V_PCAP@.c @USB_SRC@ @BT_SRC@ @BT_MONITOR_SRC@ @NETFILTER_SRC@ @DBUS_SRC@ @NETMAP_SRC@ @RDMA_SRC@
FSRC = @V_FINDALLDEVS@
SSRC = @SSRC@
CSRC = pcap.c inet.c fad-helpers.c gencode.c optimize.c nametoaddr.c \
etherent.c savefile.c sf-pcap.c sf-pcap-ng.c pcap-common.c \
bpf_image.c bpf_dump.c
GENSRC = scanner.c grammar.c bpf_filter.c version.c
CSRC = pcap.c gencode.c optimize.c nametoaddr.c etherent.c \
fmtutils.c \
savefile.c sf-pcap.c sf-pcapng.c pcap-common.c \
bpf_image.c bpf_filter.c bpf_dump.c
GENSRC = scanner.c grammar.c
LIBOBJS = @LIBOBJS@
SRC = $(PSRC) $(FSRC) $(CSRC) $(SSRC) $(GENSRC)
@ -100,8 +108,10 @@ PUBHDR = \
pcap/bpf.h \
pcap/bluetooth.h \
pcap/can_socketcan.h \
pcap/compiler-tests.h \
pcap/dlt.h \
pcap/export-defs.h \
pcap/funcattrs.h \
pcap/pcap-inttypes.h \
pcap/ipnet.h \
pcap/namedb.h \
pcap/nflog.h \
@ -113,51 +123,38 @@ PUBHDR = \
HDR = $(PUBHDR) \
arcnet.h \
atmuni31.h \
diag-control.h \
ethertype.h \
extract.h \
fmtutils.h \
ftmacros.h \
gencode.h \
ieee80211.h \
llc.h \
nametoaddr.h \
nlpid.h \
optimize.h \
pcap-common.h \
pcap-int.h \
pcap-stdinc.h \
pcap-rpcap.h \
pcap-types.h \
portability.h \
ppp.h \
rpcap-protocol.h \
sf-pcap.h \
sf-pcap-ng.h \
sunatmpos.h
TESTS = \
@VALGRINDTEST@ \
capturetest \
can_set_rfmon_test \
filtertest \
findalldevstest \
opentest \
reactivatetest \
selpolltest
TESTS_SRC = \
tests/valgrindtest.c \
tests/capturetest.c \
tests/can_set_rfmon_test.c \
tests/filtertest.c \
tests/findalldevstest.c \
tests/opentest.c \
tests/reactivatetest.c \
tests/selpolltest.c
sf-pcapng.h \
sunatmpos.h \
varattrs.h
GENHDR = \
scanner.h grammar.h pcap_version.h
scanner.h grammar.h
TAGFILES = \
$(SRC) $(HDR)
CLEANFILES = $(OBJ) libpcap.* $(TESTS) \
CLEANFILES = $(OBJ) libpcap.a libpcap.so.`cat $(srcdir)/VERSION` \
$(PROG)-`cat $(srcdir)/VERSION`.tar.gz $(GENSRC) $(GENHDR) \
lex.yy.c pcap-config
lex.yy.c pcap-config libpcap.pc
MAN1 = pcap-config.1
@ -191,6 +188,7 @@ MAN3PCAP_NOEXPAND = \
pcap_fileno.3pcap \
pcap_findalldevs.3pcap \
pcap_freecode.3pcap \
pcap_get_required_select_timeout.3pcap \
pcap_get_selectable_fd.3pcap \
pcap_geterr.3pcap \
pcap_inject.3pcap \
@ -207,6 +205,7 @@ MAN3PCAP_NOEXPAND = \
pcap_set_datalink.3pcap \
pcap_set_immediate_mode.3pcap \
pcap_set_promisc.3pcap \
pcap_set_protocol.3pcap \
pcap_set_rfmon.3pcap \
pcap_set_snaplen.3pcap \
pcap_set_timeout.3pcap \
@ -231,13 +230,11 @@ MANMISC = \
pcap-tstamp.manmisc.in
EXTRA_DIST = \
$(TESTS_SRC) \
CHANGES \
ChmodBPF/ChmodBPF \
ChmodBPF/StartupParameters.plist \
CREDITS \
CMakeLists.txt \
GenVersion.bat \
INSTALL.txt \
LICENSE \
Makefile.in \
@ -247,22 +244,25 @@ EXTRA_DIST = \
README.dag \
README.hpux \
README.linux \
README.macosx \
README.macos \
README.septel \
README.sita \
README.tru64 \
README.Win32 \
SUNOS4/nit_if.o.sparc \
SUNOS4/nit_if.o.sun3 \
SUNOS4/nit_if.o.sun4c.4.0.3c \
CONTRIBUTING \
TODO \
VERSION \
aclocal.m4 \
bpf/net/bpf_filter.c \
chmod_bpf \
cmake_uninstall.cmake.in \
cmakeconfig.h.in \
cmake/preconfigure.cmake \
config/have_siocglifconf.c \
cmake/Modules/FindDAG.cmake \
cmake/Modules/FindFseeko.cmake \
cmake/Modules/FindLFS.cmake \
cmake/Modules/FindPacket.cmake \
cmake/Modules/FindSNF.cmake \
cmake/Modules/FindTC.cmake \
cmake/have_siocglifconf.c \
config.guess \
config.h.in \
config.sub \
@ -273,9 +273,6 @@ EXTRA_DIST = \
fad-getad.c \
fad-gifc.c \
fad-glifc.c \
fad-helpers.c \
gen_version_c.sh \
gen_version_header.sh \
grammar.y \
install-sh \
lbl/os-aix4.h \
@ -286,6 +283,7 @@ EXTRA_DIST = \
lbl/os-solaris2.h \
lbl/os-sunos4.h \
lbl/os-ultrix4.h \
libpcap.pc.in \
missing/getopt.c \
missing/getopt.h \
missing/snprintf.c \
@ -293,18 +291,15 @@ EXTRA_DIST = \
missing/win_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 \
nomkdep \
org.tcpdump.chmod_bpf.plist \
pcap-bpf.c \
pcap-bt-linux.c \
@ -316,6 +311,7 @@ EXTRA_DIST = \
pcap-dag.h \
pcap-dbus.c \
pcap-dbus.h \
pcap-dll.rc \
pcap-dlpi.c \
pcap-dos.c \
pcap-dos.h \
@ -327,11 +323,16 @@ EXTRA_DIST = \
pcap-new.c \
pcap-netfilter-linux.c \
pcap-netfilter-linux.h \
pcap-netmap.c \
pcap-netmap.h \
pcap-nit.c \
pcap-npf.c \
pcap-null.c \
pcap-pf.c \
pcap-rdmasniff.c \
pcap-rdmasniff.h \
pcap-rpcap.c \
pcap-rpcap.h \
pcap-rpcap-int.h \
pcap-septel.c \
pcap-septel.h \
pcap-sita.h \
@ -345,20 +346,47 @@ EXTRA_DIST = \
pcap-tc.h \
pcap-usb-linux.c \
pcap-usb-linux.h \
pcap-win32.c \
remote-ext.h \
rpcap-protocol.c \
rpcapd/CMakeLists.txt \
rpcapd/Makefile.in \
rpcapd/config_params.h \
rpcapd/daemon.h \
rpcapd/daemon.c \
rpcapd/fileconf.c \
rpcapd/fileconf.h \
rpcapd/log.h \
rpcapd/log-stderr.c \
rpcapd/org.tcpdump.rpcapd.plist \
rpcapd/rpcapd.c \
rpcapd/rpcapd.h \
rpcapd/rpcapd.inetd.conf \
rpcapd/rpcapd.manadmin.in \
rpcapd/rpcapd.rc \
rpcapd/rpcapd.socket \
rpcapd/rpcapd.xinetd.conf \
rpcapd/rpcapd@.service \
rpcapd/win32-svc.h \
sockutils.c \
sockutils.h \
scanner.l \
tests/CMakeLists.txt \
pcap_version.h.in \
Win32/Include/Gnuc.h \
Win32/Include/net/if.h \
testprogs/CMakeLists.txt \
testprogs/Makefile.in \
testprogs/can_set_rfmon_test.c \
testprogs/capturetest.c \
testprogs/filtertest.c \
testprogs/findalldevstest.c \
testprogs/opentest.c \
testprogs/reactivatetest.c \
testprogs/selpolltest.c \
testprogs/threadsignaltest.c \
testprogs/unix.h \
testprogs/valgrindtest.c \
tests/shb-option-too-long.pcapng \
Win32/Prj/wpcap.sln \
Win32/Prj/wpcap.vcxproj \
Win32/Prj/wpcap.vcxproj.filters
all: libpcap.a shared pcap-config
all: libpcap.a shared $(BUILD_RPCAPD) libpcap.pc pcap-config
libpcap.a: $(OBJ)
@rm -f $@
@ -371,20 +399,18 @@ libpcap.so: $(OBJ)
@rm -f $@
VER=`cat $(srcdir)/VERSION`; \
MAJOR_VER=`sed 's/\([0-9][0-9]*\)\..*/\1/' $(srcdir)/VERSION`; \
@V_SHLIB_CMD@ @V_SHLIB_OPT@ @V_SONAME_OPT@$@.$$MAJOR_VER $(LDFLAGS) \
@V_SHLIB_CMD@ $(LDFLAGS) @V_SHLIB_OPT@ @V_SONAME_OPT@$@.$$MAJOR_VER \
-o $@.$$VER $(OBJ) $(ADDLOBJS) $(LIBS)
#
# The following rule succeeds, but the result is untested.
#
# In Mac OS X, the libpcap dylib has the name "libpcap.A.dylib", with
# its full path as the install_name, and with the compatibility and
# current version both set to 1. The compatibility version is set to
# 1 so that programs built with a newer version of the library will run
# against older versions; multi-platform software probably will fail if
# it uses APIs added in the newer version, but Mac OS X-specific software
# will use weak linking and check at run time whether those APIs are
# available.
# In macOS, the libpcap dylib has the name "libpcap.A.dylib", with its
# full path as the install_name, and with the compatibility and current
# version both set to 1. The compatibility version is set to 1 so that
# programs built with a newer version of the library will run against
# older versions if they don't use APIs available in the newer version
# but not in the older version.
#
# We also use "A" as the major version, and 1 as the compatibility version,
# but set the current version to the value in VERSION, with any non-numeric
@ -434,7 +460,7 @@ libpcap.sl: $(OBJ)
#
libpcap.shareda: $(OBJ)
@rm -f $@ shr.o
$(CC) @V_SHLIB_OPT@ -o shr.o $(OBJ) $(ADDLOBJS) $(LDFLAGS) $(LIBS)
$(CC) $(LDFLAGS) @V_SHLIB_OPT@ -o shr.o $(OBJ) $(ADDLOBJS) $(LIBS)
$(AR) rc $@ shr.o
#
@ -455,8 +481,6 @@ scanner.h: scanner.c
scanner.o: scanner.c grammar.h
$(CC) $(FULL_CFLAGS) -c scanner.c
pcap.o: pcap_version.h
grammar.c: $(srcdir)/grammar.y
$(YACC) -p pcap_ -o grammar.c -d $<
grammar.h: grammar.c
@ -466,43 +490,20 @@ grammar.h: grammar.c
$(MAKE) $(MAKEFLAGS) grammar.c; \
fi
grammar.o: grammar.c
grammar.o: grammar.c scanner.h
$(CC) $(FULL_CFLAGS) -c grammar.c
gencode.o: $(srcdir)/gencode.c grammar.h scanner.h
$(CC) $(FULL_CFLAGS) -c $(srcdir)/gencode.c
version.o: version.c
$(CC) $(FULL_CFLAGS) -c version.c
snprintf.o: $(srcdir)/missing/snprintf.c
$(CC) $(FULL_CFLAGS) -o $@ -c $(srcdir)/missing/snprintf.c
strtok_r.o: $(srcdir)/missing/strtok_r.c
$(CC) $(FULL_CFLAGS) -o $@ -c $(srcdir)/missing/strtok_r.c
version.c: $(srcdir)/VERSION $(srcdir)/gen_version_c.sh
#
# Older programs import this if they want to show the
# libpcap version number, rather than calling
# pcap_lib_version(), so we need to export it.
#
@rm -f $@
$(srcdir)/gen_version_c.sh $(srcdir)/VERSION $@
pcap_version.h: $(srcdir)/VERSION $(srcdir)/pcap_version.h.in $(srcdir)/gen_version_header.sh
@rm -f $@
$(srcdir)/gen_version_header.sh $(srcdir)/VERSION $(srcdir)/pcap_version.h.in $@
bpf_filter.c: $(srcdir)/bpf/net/bpf_filter.c
rm -f bpf_filter.c
ln -s $(srcdir)/bpf/net/bpf_filter.c bpf_filter.c
bpf_filter.o: bpf_filter.c
$(CC) $(FULL_CFLAGS) -c bpf_filter.c
#
# Generate the pcap-config script.
# Generate the libpcap.pc file.
#
# Some Makes, e.g. AIX Make and Solaris Make, can't handle "--file=$@.tmp:$<";
# for example, the Solaris 9 make man page says
@ -513,7 +514,16 @@ bpf_filter.o: bpf_filter.c
#
# and this is an explicit target entry.
#
# Therefore, instead of using $<, we explicitly put in $(srcdir)/pcap-config.in.
# Therefore, instead of using $<, we explicitly put in $(srcdir)/libpcap.pc.in.
#
libpcap.pc: $(srcdir)/libpcap.pc.in ./config.status
@rm -f $@ $@.tmp
./config.status --file=$@.tmp:$(srcdir)/libpcap.pc.in
mv $@.tmp $@
chmod a+x $@
#
# Generate the pcap-config script. See above.
#
pcap-config: $(srcdir)/pcap-config.in ./config.status
@rm -f $@ $@.tmp
@ -521,36 +531,21 @@ pcap-config: $(srcdir)/pcap-config.in ./config.status
mv $@.tmp $@
chmod a+x $@
#
# Remote pcap daemon.
#
build-rpcapd: libpcap.a
cd rpcapd; $(MAKE)
#
# Test programs - not built by default, and not installed.
#
tests: $(TESTS)
testprogs: FORCE
cd testprogs; $(MAKE)
capturetest: tests/capturetest.c libpcap.a
$(CC) $(FULL_CFLAGS) -I. -L. -o capturetest $(srcdir)/tests/capturetest.c libpcap.a $(LIBS)
FORCE:
can_set_rfmon_test: tests/can_set_rfmon_test.c libpcap.a
$(CC) $(FULL_CFLAGS) -I. -L. -o can_set_rfmon_test $(srcdir)/tests/can_set_rfmon_test.c libpcap.a $(LIBS)
filtertest: tests/filtertest.c libpcap.a
$(CC) $(FULL_CFLAGS) -I. -L. -o filtertest $(srcdir)/tests/filtertest.c libpcap.a $(LIBS)
findalldevstest: tests/findalldevstest.c libpcap.a
$(CC) $(FULL_CFLAGS) -I. -L. -o findalldevstest $(srcdir)/tests/findalldevstest.c libpcap.a $(LIBS)
opentest: tests/opentest.c libpcap.a
$(CC) $(FULL_CFLAGS) -I. -L. -o opentest $(srcdir)/tests/opentest.c libpcap.a $(LIBS)
reactivatetest: tests/reactivatetest.c libpcap.a
$(CC) $(FULL_CFLAGS) -I. -L. -o reactivatetest $(srcdir)/tests/reactivatetest.c libpcap.a $(LIBS)
selpolltest: tests/selpolltest.c libpcap.a
$(CC) $(FULL_CFLAGS) -I. -L. -o selpolltest $(srcdir)/tests/selpolltest.c libpcap.a $(LIBS)
valgrindtest: tests/valgrindtest.c libpcap.a
$(CC) $(FULL_CFLAGS) -I. -L. -o valgrindtest $(srcdir)/tests/valgrindtest.c libpcap.a $(LIBS)
install: install-shared install-archive pcap-config
install: install-shared install-archive libpcap.pc pcap-config @INSTALL_RPCAPD@
[ -d $(DESTDIR)$(libdir) ] || \
(mkdir -p $(DESTDIR)$(libdir); chmod 755 $(DESTDIR)$(libdir))
[ -d $(DESTDIR)$(includedir) ] || \
@ -571,6 +566,9 @@ install: install-shared install-archive pcap-config
[ -d $(DESTDIR)$(bindir) ] || \
(mkdir -p $(DESTDIR)$(bindir); chmod 755 $(DESTDIR)$(bindir))
$(INSTALL_PROGRAM) pcap-config $(DESTDIR)$(bindir)/pcap-config
[ -d $(DESTDIR)$(libdir)/pkgconfig ] || \
(mkdir -p $(DESTDIR)$(libdir)/pkgconfig; chmod 755 $(DESTDIR)$(libdir)/pkgconfig)
$(INSTALL_DATA) libpcap.pc $(DESTDIR)$(libdir)/pkgconfig/libpcap.pc
for i in $(MAN1); do \
$(INSTALL_DATA) $(srcdir)/$$i \
$(DESTDIR)$(mandir)/man1/$$i; done
@ -671,11 +669,15 @@ install-archive-shareda:
# library on AIX.
#
uninstall: uninstall-shared
install-rpcapd:
cd rpcapd; $(MAKE) DESTDIR=$(DESTDIR) install
uninstall: uninstall-shared uninstall-rpcapd
rm -f $(DESTDIR)$(libdir)/libpcap.a
for i in $(PUBHDR); do \
rm -f $(DESTDIR)$(includedir)/$$i; done
-rmdir $(DESTDIR)$(includedir)/pcap
rm -f $(DESTDIR)/$(libdir)/pkgconfig/libpcap.pc
rm -f $(DESTDIR)/$(bindir)/pcap-config
for i in $(MAN1); do \
rm -f $(DESTDIR)$(mandir)/man1/$$i; done
@ -723,15 +725,22 @@ uninstall-shared-shareda:
rm -f $(DESTDIR)$(libdir)/libpcap.a
uninstall-shared-none:
uninstall-rpcapd:
cd rpcapd; $(MAKE) DESTDIR=$(DESTDIR) uninstall
clean:
rm -f $(CLEANFILES)
cd rpcapd; $(MAKE) clean
cd testprogs; $(MAKE) clean
distclean: clean
rm -f Makefile config.cache config.log config.status \
config.h gnuc.h net os-proto.h bpf_filter.c pcap-config \
stamp-h stamp-h.in
config.h gnuc.h net os-proto.h libpcap.pc \
pcap-config stamp-h stamp-h.in
rm -f $(MAN3PCAP_EXPAND:.in=) $(MANFILE:.in=) $(MANMISC:.in=)
rm -rf autom4te.cache
cd rpcapd; $(MAKE) distclean
cd testprogs; $(MAKE) distclean
extags: $(TAGFILES)
ctags $(TAGFILES)
@ -748,5 +757,7 @@ releasetar:
tar -c -z -f $$name.tar.gz $$name; \
rm -rf $$name
depend: $(GENSRC) $(GENHDR) bpf_filter.c
$(MKDEP) -c $(CC) -m $(CFLAGS) $(DEPENDENCY_CFLAG) $(DEFS) $(INCLS) $(SRC)
depend: $(GENSRC) $(GENHDR)
$(MKDEP) -c "$(CC)" -m "$(DEPENDENCY_CFLAG)" $(CFLAGS) $(DEFS) $(INCLS) $(SRC)
cd rpcapd; $(MAKE) depend
cd testprogs; $(MAKE) depend

55
README
View File

@ -1,19 +1,16 @@
To report a security issue please send an e-mail to security@tcpdump.org.
To report bugs and other problems, contribute patches, request a
feature, provide generic feedback etc please see the file
CONTRIBUTING in the libpcap source tree root.
LIBPCAP 1.x.y
www.tcpdump.org
Please send inquiries/comments/reports to:
tcpdump-workers@lists.tcpdump.org
Now maintained by "The Tcpdump Group"
https://www.tcpdump.org
Anonymous Git is available via:
git clone git://bpf.tcpdump.org/libpcap
Please submit patches by forking the branch on GitHub at
http://github.com/the-tcpdump-group/libpcap/tree/master
and issuing a pull request.
formerly from Lawrence Berkeley National Laboratory
Network Research Group <libpcap@ee.lbl.gov>
ftp://ftp.ee.lbl.gov/old/libpcap-0.4a7.tar.Z
@ -43,15 +40,15 @@ found at
or
http://www.tcpdump.org/papers/bpf-usenix93.ps.Z
https://www.tcpdump.org/papers/bpf-usenix93.ps.Z
and a gzipped version can be found at
http://www.tcpdump.org/papers/bpf-usenix93.ps.gz
https://www.tcpdump.org/papers/bpf-usenix93.ps.gz
A PDF version can be found at
http://www.tcpdump.org/papers/bpf-usenix93.pdf
https://www.tcpdump.org/papers/bpf-usenix93.pdf
Although most packet capture interfaces support in-kernel filtering,
libpcap utilizes in-kernel filtering only for the BPF interface.
@ -62,13 +59,13 @@ would translate BPF filters into a filter program that is compatible
with the underlying kernel subsystem, but this is not yet implemented.
BPF is standard in 4.4BSD, BSD/OS, NetBSD, FreeBSD, OpenBSD, DragonFly
BSD, and Mac OS X; an older, modified and undocumented version is
standard in AIX. {DEC OSF/1, Digital UNIX, Tru64 UNIX} uses the
packetfilter interface but has been extended to accept BPF filters
(which libpcap utilizes). Also, you can add BPF filter support to
Ultrix using the kernel source and/or object patches available in:
BSD, and macOS; an older, modified and undocumented version is standard
in AIX. {DEC OSF/1, Digital UNIX, Tru64 UNIX} uses the packetfilter
interface but has been extended to accept BPF filters (which libpcap
utilizes). Also, you can add BPF filter support to Ultrix using the
kernel source and/or object patches available in:
http://www.tcpdump.org/other/bpfext42.tar.Z
https://www.tcpdump.org/other/bpfext42.tar.Z
Linux, in the 2.2 kernel and later kernels, has a "Socket Filter"
mechanism that accepts BPF filters; see the README.linux file for
@ -87,20 +84,6 @@ We've been maintaining binary compatibility between libpcap releases for
quite a while; there's no reason to tie a binary linked with libpcap to
a particular release of libpcap.
Problems, bugs, questions, desirable enhancements, etc. should be sent
to the address "tcpdump-workers@lists.tcpdump.org". Bugs, support
requests, and feature requests may also be submitted on the GitHub issue
tracker for libpcap at
Current versions can be found at https://www.tcpdump.org.
https://github.com/the-tcpdump-group/libpcap/issues
Source code contributions, etc. should be sent to the email address
above or submitted by forking the branch on GitHub at
http://github.com/the-tcpdump-group/libpcap/tree/master
and issuing a pull request.
Current versions can be found at www.tcpdump.org.
- The TCPdump team
- The TCPdump group

View File

@ -1,5 +1,5 @@
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
As with other systems using BPF, macOS 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
@ -12,16 +12,16 @@ 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
On macOS, the BPF devices live on devfs, but the macOS 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 older versions of Mac OS X;
a "startup item" for older versions of macOS;
a launchd daemon for Tiger and later versions of Mac OS X;
a launchd daemon for Tiger and later versions of macOS;
Both of them will change the ownership of the BPF devices so that the
"admin" group owns them, and will change the permission of the BPF

View File

@ -40,7 +40,7 @@ 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
0x2d for technical reason. So this change in system.txt is crucial 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

View File

@ -1,5 +1,5 @@
The following instructions apply if you have a Linux platform and want
libpcap to support the 'ACN' WAN/LAN router product from from SITA
libpcap to support the 'ACN' WAN/LAN router product from SITA
(http://www.sita.aero)
This might also work on non-Linux Unix-compatible platforms, but that

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1 +1 @@
1.8.1
1.9.0-PRE-GIT

View File

@ -1,8 +0,0 @@
/* inline foo */
#ifndef __cplusplus
#ifdef __GNUC__
#define inline __inline
#else
#define inline
#endif
#endif

View File

@ -1,230 +0,0 @@
/*
* Copyright (c) 1982, 1986, 1989, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)if.h 8.1 (Berkeley) 6/10/93
* $FreeBSD$
*/
#ifndef _NET_IF_H_
#define _NET_IF_H_
/*
* <net/if.h> does not depend on <sys/time.h> on most other systems. This
* helps userland compatability. (struct timeval ifi_lastchange)
*/
#ifndef KERNEL
#include <pcap-stdinc.h>
#endif
/*
* Structure describing information about an interface
* which may be of interest to management entities.
*/
struct if_data {
/* generic interface information */
u_char ifi_type; /* ethernet, tokenring, etc */
u_char ifi_physical; /* e.g., AUI, Thinnet, 10base-T, etc */
u_char ifi_addrlen; /* media address length */
u_char ifi_hdrlen; /* media header length */
u_char ifi_recvquota; /* polling quota for receive intrs */
u_char ifi_xmitquota; /* polling quota for xmit intrs */
u_long ifi_mtu; /* maximum transmission unit */
u_long ifi_metric; /* routing metric (external only) */
u_long ifi_baudrate; /* linespeed */
/* volatile statistics */
u_long ifi_ipackets; /* packets received on interface */
u_long ifi_ierrors; /* input errors on interface */
u_long ifi_opackets; /* packets sent on interface */
u_long ifi_oerrors; /* output errors on interface */
u_long ifi_collisions; /* collisions on csma interfaces */
u_long ifi_ibytes; /* total number of octets received */
u_long ifi_obytes; /* total number of octets sent */
u_long ifi_imcasts; /* packets received via multicast */
u_long ifi_omcasts; /* packets sent via multicast */
u_long ifi_iqdrops; /* dropped on input, this interface */
u_long ifi_noproto; /* destined for unsupported protocol */
u_long ifi_recvtiming; /* usec spent receiving when timing */
u_long ifi_xmittiming; /* usec spent xmitting when timing */
struct timeval ifi_lastchange; /* time of last administrative change */
};
/* ws2tcpip.h has interface flags: IFF_* */
#if 0
#define IFF_UP 0x1 /* interface is up */
#define IFF_BROADCAST 0x2 /* broadcast address valid */
#define IFF_DEBUG 0x4 /* turn on debugging */
#define IFF_LOOPBACK 0x8 /* is a loopback net */
#define IFF_POINTOPOINT 0x10 /* interface is point-to-point link */
/*#define IFF_NOTRAILERS 0x20 * obsolete: avoid use of trailers */
#define IFF_RUNNING 0x40 /* resources allocated */
#define IFF_NOARP 0x80 /* no address resolution protocol */
#define IFF_PROMISC 0x100 /* receive all packets */
#define IFF_ALLMULTI 0x200 /* receive all multicast packets */
#define IFF_OACTIVE 0x400 /* transmission in progress */
#define IFF_SIMPLEX 0x800 /* can't hear own transmissions */
#define IFF_LINK0 0x1000 /* per link layer defined bit */
#define IFF_LINK1 0x2000 /* per link layer defined bit */
#define IFF_LINK2 0x4000 /* per link layer defined bit */
#define IFF_ALTPHYS IFF_LINK2 /* use alternate physical connection */
#define IFF_MULTICAST 0x8000 /* supports multicast */
#endif /* 0 */
/* flags set internally only: */
#define IFF_CANTCHANGE \
(IFF_BROADCAST|IFF_POINTOPOINT|IFF_RUNNING|IFF_OACTIVE|\
IFF_SIMPLEX|IFF_MULTICAST|IFF_ALLMULTI)
#define IFQ_MAXLEN 50
#define IFNET_SLOWHZ 1 /* granularity is 1 second */
/*
* Message format for use in obtaining information about interfaces
* from getkerninfo and the routing socket
*/
struct if_msghdr {
u_short ifm_msglen; /* to skip over non-understood messages */
u_char ifm_version; /* future binary compatability */
u_char ifm_type; /* message type */
int ifm_addrs; /* like rtm_addrs */
int ifm_flags; /* value of if_flags */
u_short ifm_index; /* index for associated ifp */
struct if_data ifm_data;/* statistics and other data about if */
};
/*
* Message format for use in obtaining information about interface addresses
* from getkerninfo and the routing socket
*/
struct ifa_msghdr {
u_short ifam_msglen; /* to skip over non-understood messages */
u_char ifam_version; /* future binary compatability */
u_char ifam_type; /* message type */
int ifam_addrs; /* like rtm_addrs */
int ifam_flags; /* value of ifa_flags */
u_short ifam_index; /* index for associated ifp */
int ifam_metric; /* value of ifa_metric */
};
/*
* Message format for use in obtaining information about multicast addresses
* from the routing socket
*/
struct ifma_msghdr {
u_short ifmam_msglen; /* to skip over non-understood messages */
u_char ifmam_version; /* future binary compatability */
u_char ifmam_type; /* message type */
int ifmam_addrs; /* like rtm_addrs */
int ifmam_flags; /* value of ifa_flags */
u_short ifmam_index; /* index for associated ifp */
};
/*
* Interface request structure used for socket
* ioctl's. All interface ioctl's must have parameter
* definitions which begin with ifr_name. The
* remainder may be interface specific.
*/
struct ifreq {
#define IFNAMSIZ 16
char ifr_name[IFNAMSIZ]; /* if name, e.g. "en0" */
union {
struct sockaddr ifru_addr;
struct sockaddr ifru_dstaddr;
struct sockaddr ifru_broadaddr;
short ifru_flags;
int ifru_metric;
int ifru_mtu;
int ifru_phys;
int ifru_media;
caddr_t ifru_data;
} ifr_ifru;
#define ifr_addr ifr_ifru.ifru_addr /* address */
#define ifr_dstaddr ifr_ifru.ifru_dstaddr /* other end of p-to-p link */
#define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */
#define ifr_flags ifr_ifru.ifru_flags /* flags */
#define ifr_metric ifr_ifru.ifru_metric /* metric */
#define ifr_mtu ifr_ifru.ifru_mtu /* mtu */
#define ifr_phys ifr_ifru.ifru_phys /* physical wire */
#define ifr_media ifr_ifru.ifru_media /* physical media */
#define ifr_data ifr_ifru.ifru_data /* for use by interface */
};
#define _SIZEOF_ADDR_IFREQ(ifr) \
((ifr).ifr_addr.sa_len > sizeof(struct sockaddr) ? \
(sizeof(struct ifreq) - sizeof(struct sockaddr) + \
(ifr).ifr_addr.sa_len) : sizeof(struct ifreq))
struct ifaliasreq {
char ifra_name[IFNAMSIZ]; /* if name, e.g. "en0" */
struct sockaddr ifra_addr;
struct sockaddr ifra_broadaddr;
struct sockaddr ifra_mask;
};
struct ifmediareq {
char ifm_name[IFNAMSIZ]; /* if name, e.g. "en0" */
int ifm_current; /* current media options */
int ifm_mask; /* don't care mask */
int ifm_status; /* media status */
int ifm_active; /* active options */
int ifm_count; /* # entries in ifm_ulist array */
int *ifm_ulist; /* media words */
};
/*
* Structure used in SIOCGIFCONF request.
* Used to retrieve interface configuration
* for machine (useful for programs which
* must know all networks accessible).
*/
struct ifconf {
int ifc_len; /* size of associated buffer */
union {
caddr_t ifcu_buf;
struct ifreq *ifcu_req;
} ifc_ifcu;
#define ifc_buf ifc_ifcu.ifcu_buf /* buffer address */
#define ifc_req ifc_ifcu.ifcu_req /* array of structures returned */
};
#ifdef KERNEL
#ifdef MALLOC_DECLARE
MALLOC_DECLARE(M_IFADDR);
MALLOC_DECLARE(M_IFMADDR);
#endif
#endif
/* XXX - this should go away soon */
#ifdef KERNEL
#include <net/if_var.h>
#endif
#endif /* !_NET_IF_H_ */

View File

@ -100,7 +100,7 @@
<SuppressStartupBanner>true</SuppressStartupBanner>
<WarningLevel>Level3</WarningLevel>
<AdditionalIncludeDirectories>../../;../../lbl/;../../bpf/;../include/;../../../../common;../../../../dag/include;../../../../dag/drv/windows;../../../Win32-Extensions;./;Win32-Extensions;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>HAVE_VERSION_H;__STDC_VERSION__=199901L;HAVE_PACKET_IS_LOOPBACK_ADAPTER;NDEBUG;YY_NEVER_INTERACTIVE;_USRDLL;BUILDING_PCAP;HAVE_STRERROR;__STDC__;INET6;_WINDOWS;HAVE_ADDRINFO;HAVE_REMOTE;WIN32;_U_=;YY_NO_UNISTD_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>HAVE_VERSION_H;__STDC_VERSION__=199901L;HAVE_PACKET_IS_LOOPBACK_ADAPTER;NDEBUG;YY_NEVER_INTERACTIVE;_USRDLL;pcap_EXPORTS;HAVE_STRERROR;__STDC__;INET6;_WINDOWS;ENABLE_REMOTE;WIN32;_U_=;YY_NO_UNISTD_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ResourceCompile>
<Culture>0x0409</Culture>
@ -125,7 +125,7 @@ win_bison -ppcap_ --yacc --output=..\..\grammar.c --defines ..\..\grammar.y</Com
<SuppressStartupBanner>true</SuppressStartupBanner>
<WarningLevel>Level3</WarningLevel>
<AdditionalIncludeDirectories>../../;../../lbl/;../../bpf/;../include/;../../../../common;../../../../dag/include;../../../../dag/drv/windows;../../../Win32-Extensions;./;Win32-Extensions;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>HAVE_VERSION_H;__STDC_VERSION__=199901L;HAVE_PACKET_IS_LOOPBACK_ADAPTER;NDEBUG;YY_NEVER_INTERACTIVE;_USRDLL;BUILDING_PCAP;HAVE_STRERROR;__STDC__;INET6;_WINDOWS;HAVE_ADDRINFO;HAVE_REMOTE;WIN32;_U_=;YY_NO_UNISTD_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>HAVE_VERSION_H;__STDC_VERSION__=199901L;HAVE_PACKET_IS_LOOPBACK_ADAPTER;NDEBUG;YY_NEVER_INTERACTIVE;_USRDLL;pcap_EXPORTS;HAVE_STRERROR;__STDC__;INET6;_WINDOWS;ENABLE_REMOTE;WIN32;_U_=;YY_NO_UNISTD_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ResourceCompile>
<Culture>0x0409</Culture>
@ -151,7 +151,7 @@ win_bison -ppcap_ --yacc --output=..\..\grammar.c --defines ..\..\grammar.y</Com
<MinimalRebuild>true</MinimalRebuild>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<AdditionalIncludeDirectories>../../;../../lbl/;../../bpf/;../include/;../../../../common;../../../../dag/include;../../../../dag/drv/windows;../../../Win32-Extensions;./;Win32-Extensions;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>HAVE_VERSION_H;__STDC_VERSION__=199901L;HAVE_PACKET_IS_LOOPBACK_ADAPTER;_DEBUG;YY_NEVER_INTERACTIVE;_USRDLL;BUILDING_PCAP;HAVE_STRERROR;__STDC__;INET6;_WINDOWS;HAVE_ADDRINFO;HAVE_REMOTE;WIN32;_U_=;YY_NO_UNISTD_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>HAVE_VERSION_H;__STDC_VERSION__=199901L;HAVE_PACKET_IS_LOOPBACK_ADAPTER;_DEBUG;YY_NEVER_INTERACTIVE;_USRDLL;pcap_EXPORTS;HAVE_STRERROR;__STDC__;INET6;_WINDOWS;ENABLE_REMOTE;WIN32;_U_=;YY_NO_UNISTD_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
</ClCompile>
<ResourceCompile>
@ -177,7 +177,7 @@ win_bison -ppcap_ --yacc --output=..\..\grammar.c --defines ..\..\grammar.y</Com
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>../../;../../lbl/;../../bpf/;../include/;../../../../common;../../../../dag/include;../../../../dag/drv/windows;../../../Win32-Extensions;./;Win32-Extensions;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>HAVE_VERSION_H;__STDC_VERSION__=199901L;HAVE_PACKET_IS_LOOPBACK_ADAPTER;_DEBUG;YY_NEVER_INTERACTIVE;_USRDLL;BUILDING_PCAP;HAVE_STRERROR;__STDC__;INET6;_WINDOWS;HAVE_ADDRINFO;HAVE_REMOTE;WIN32;_U_=;YY_NO_UNISTD_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>HAVE_VERSION_H;__STDC_VERSION__=199901L;HAVE_PACKET_IS_LOOPBACK_ADAPTER;_DEBUG;YY_NEVER_INTERACTIVE;_USRDLL;pcap_EXPORTS;HAVE_STRERROR;__STDC__;INET6;_WINDOWS;ENABLE_REMOTE;WIN32;_U_=;YY_NO_UNISTD_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
</ClCompile>
<ResourceCompile>
@ -198,7 +198,6 @@ win_bison -ppcap_ --yacc --output=..\..\grammar.c --defines ..\..\grammar.y</Com
<ClCompile Include="..\..\bpf_dump.c" />
<ClCompile Include="..\..\bpf_image.c" />
<ClCompile Include="..\..\etherent.c" />
<ClCompile Include="..\..\fad-helpers.c" />
<ClCompile Include="..\..\gencode.c" />
<ClCompile Include="..\..\grammar.c" />
<ClCompile Include="..\..\inet.c" />
@ -212,7 +211,7 @@ win_bison -ppcap_ --yacc --output=..\..\grammar.c --defines ..\..\grammar.y</Com
<ClCompile Include="..\..\pcap.c" />
<ClCompile Include="..\..\savefile.c" />
<ClCompile Include="..\..\scanner.c" />
<ClCompile Include="..\..\sf-pcap-ng.c" />
<ClCompile Include="..\..\sf-pcapng.c" />
<ClCompile Include="..\..\sf-pcap.c" />
<ClCompile Include="..\..\sockutils.c" />
</ItemGroup>
@ -231,4 +230,4 @@ win_bison -ppcap_ --yacc --output=..\..\grammar.c --defines ..\..\grammar.y</Com
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>

View File

@ -43,7 +43,7 @@
<ClCompile Include="..\..\sf-pcap.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\sf-pcap-ng.c">
<ClCompile Include="..\..\sf-pcapng.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\pcap-common.c">

393
aclocal.m4 vendored
View File

@ -384,8 +384,7 @@ AC_DEFUN(AC_LBL_CHECK_DEPENDENCY_GENERATION_OPT,
if test ! -z "$ac_lbl_dependency_flag"; then
AC_LANG_CONFTEST(
[AC_LANG_SOURCE([[int main(void) { return 0; }]])])
echo "$CC" $ac_lbl_dependency_flag conftest.c >&5
if "$CC" $ac_lbl_dependency_flag conftest.c >/dev/null 2>&1; then
if AC_RUN_LOG([eval "$CC $ac_lbl_dependency_flag conftest.c >/dev/null 2>&1"]); then
AC_MSG_RESULT([yes, with $ac_lbl_dependency_flag])
DEPENDENCY_CFLAG="$ac_lbl_dependency_flag"
MKDEP='${srcdir}/mkdep'
@ -395,7 +394,7 @@ AC_DEFUN(AC_LBL_CHECK_DEPENDENCY_GENERATION_OPT,
# We can't run mkdep, so have "make depend" do
# nothing.
#
MKDEP=:
MKDEP='${srcdir}/nomkdep'
fi
rm -rf conftest*
else
@ -404,7 +403,7 @@ AC_DEFUN(AC_LBL_CHECK_DEPENDENCY_GENERATION_OPT,
# We can't run mkdep, so have "make depend" do
# nothing.
#
MKDEP=:
MKDEP='${srcdir}/nomkdep'
fi
AC_SUBST(DEPENDENCY_CFLAG)
AC_SUBST(MKDEP)
@ -419,7 +418,7 @@ dnl AC_LBL_SHLIBS_INIT
dnl
dnl results:
dnl
dnl V_CCOPT (modified to build position-independent code)
dnl V_SHLIB_CCOPT (modified to build position-independent code)
dnl V_SHLIB_CMD
dnl V_SHLIB_OPT
dnl V_SONAME_OPT
@ -432,7 +431,7 @@ AC_DEFUN(AC_LBL_SHLIBS_INIT,
# On platforms where we build a shared library:
#
# add options to generate position-independent code,
# if necessary (it's the default in AIX and Darwin/OS X);
# if necessary (it's the default in AIX and Darwin/macOS);
#
# define option to set the soname of the shared library,
# if the OS supports that;
@ -470,13 +469,13 @@ AC_DEFUN(AC_LBL_SHLIBS_INIT,
esac
;;
esac
V_CCOPT="$V_CCOPT $PIC_OPT"
V_SHLIB_CCOPT="$V_SHLIB_CCOPT $PIC_OPT"
V_SONAME_OPT="-Wl,-soname,"
V_RPATH_OPT="-Wl,-rpath,"
;;
hpux*)
V_CCOPT="$V_CCOPT -fpic"
V_SHLIB_CCOPT="$V_SHLIB_CCOPT -fpic"
#
# XXX - this assumes GCC is using the HP linker,
# rather than the GNU linker, and that the "+h"
@ -492,7 +491,7 @@ AC_DEFUN(AC_LBL_SHLIBS_INIT,
;;
solaris*)
V_CCOPT="$V_CCOPT -fpic"
V_SHLIB_CCOPT="$V_SHLIB_CCOPT -fpic"
#
# XXX - this assumes GCC is using the Sun linker,
# rather than the GNU linker.
@ -507,7 +506,7 @@ AC_DEFUN(AC_LBL_SHLIBS_INIT,
# where we build a shared library:
#
# add options to generate position-independent code,
# if necessary (it's the default in Darwin/OS X);
# if necessary (it's the default in Darwin/macOS);
#
# if we generate ".so" shared libraries, define the
# appropriate options for building the shared library;
@ -533,7 +532,7 @@ AC_DEFUN(AC_LBL_SHLIBS_INIT,
#
# "cc" is GCC.
#
V_CCOPT="$V_CCOPT -fpic"
V_SHLIB_CCOPT="$V_SHLIB_CCOPT -fpic"
V_SHLIB_CMD="\$(CC)"
V_SHLIB_OPT="-shared"
V_SONAME_OPT="-Wl,-soname,"
@ -541,7 +540,7 @@ AC_DEFUN(AC_LBL_SHLIBS_INIT,
;;
hpux*)
V_CCOPT="$V_CCOPT +z"
V_SHLIB_CCOPT="$V_SHLIB_CCOPT +z"
V_SHLIB_CMD="\$(LD)"
V_SHLIB_OPT="-b"
V_SONAME_OPT="+h "
@ -564,7 +563,7 @@ AC_DEFUN(AC_LBL_SHLIBS_INIT,
;;
solaris*)
V_CCOPT="$V_CCOPT -Kpic"
V_SHLIB_CCOPT="$V_SHLIB_CCOPT -Kpic"
V_SHLIB_CMD="\$(CC)"
V_SHLIB_OPT="-G"
V_SONAME_OPT="-h "
@ -690,90 +689,6 @@ AC_DEFUN(AC_LBL_UNION_WAIT,
AC_DEFINE(DECLWAITSTATUS,int,[type for wait])
fi])
dnl
dnl Checks to see if the sockaddr struct has the 4.4 BSD sa_len member
dnl
dnl usage:
dnl
dnl AC_LBL_SOCKADDR_SA_LEN
dnl
dnl results:
dnl
dnl HAVE_SOCKADDR_SA_LEN (defined)
dnl
AC_DEFUN(AC_LBL_SOCKADDR_SA_LEN,
[AC_MSG_CHECKING(if sockaddr struct has the sa_len member)
AC_CACHE_VAL(ac_cv_lbl_sockaddr_has_sa_len,
AC_TRY_COMPILE([
# include <sys/types.h>
# include <sys/socket.h>],
[u_int i = sizeof(((struct sockaddr *)0)->sa_len)],
ac_cv_lbl_sockaddr_has_sa_len=yes,
ac_cv_lbl_sockaddr_has_sa_len=no))
AC_MSG_RESULT($ac_cv_lbl_sockaddr_has_sa_len)
if test $ac_cv_lbl_sockaddr_has_sa_len = yes ; then
AC_DEFINE(HAVE_SOCKADDR_SA_LEN,1,[if struct sockaddr has the sa_len member])
fi])
dnl
dnl Checks to see if there's a sockaddr_storage structure
dnl
dnl usage:
dnl
dnl AC_LBL_SOCKADDR_STORAGE
dnl
dnl results:
dnl
dnl HAVE_SOCKADDR_STORAGE (defined)
dnl
AC_DEFUN(AC_LBL_SOCKADDR_STORAGE,
[AC_MSG_CHECKING(if sockaddr_storage struct exists)
AC_CACHE_VAL(ac_cv_lbl_has_sockaddr_storage,
AC_TRY_COMPILE([
# include <sys/types.h>
# include <sys/socket.h>],
[u_int i = sizeof (struct sockaddr_storage)],
ac_cv_lbl_has_sockaddr_storage=yes,
ac_cv_lbl_has_sockaddr_storage=no))
AC_MSG_RESULT($ac_cv_lbl_has_sockaddr_storage)
if test $ac_cv_lbl_has_sockaddr_storage = yes ; then
AC_DEFINE(HAVE_SOCKADDR_STORAGE,1,[if struct sockaddr_storage exists])
fi])
dnl
dnl Checks to see if the dl_hp_ppa_info_t struct has the HP-UX 11.00
dnl dl_module_id_1 member
dnl
dnl usage:
dnl
dnl AC_LBL_HP_PPA_INFO_T_DL_MODULE_ID_1
dnl
dnl results:
dnl
dnl HAVE_HP_PPA_INFO_T_DL_MODULE_ID_1 (defined)
dnl
dnl NOTE: any compile failure means we conclude that it doesn't have
dnl that member, so if we don't have DLPI, don't have a <sys/dlpi_ext.h>
dnl header, or have one that doesn't declare a dl_hp_ppa_info_t type,
dnl we conclude it doesn't have that member (which is OK, as either we
dnl won't be using code that would use that member, or we wouldn't
dnl compile in any case).
dnl
AC_DEFUN(AC_LBL_HP_PPA_INFO_T_DL_MODULE_ID_1,
[AC_MSG_CHECKING(if dl_hp_ppa_info_t struct has dl_module_id_1 member)
AC_CACHE_VAL(ac_cv_lbl_dl_hp_ppa_info_t_has_dl_module_id_1,
AC_TRY_COMPILE([
# include <sys/types.h>
# include <sys/dlpi.h>
# include <sys/dlpi_ext.h>],
[u_int i = sizeof(((dl_hp_ppa_info_t *)0)->dl_module_id_1)],
ac_cv_lbl_dl_hp_ppa_info_t_has_dl_module_id_1=yes,
ac_cv_lbl_dl_hp_ppa_info_t_has_dl_module_id_1=no))
AC_MSG_RESULT($ac_cv_lbl_dl_hp_ppa_info_t_has_dl_module_id_1)
if test $ac_cv_lbl_dl_hp_ppa_info_t_has_dl_module_id_1 = yes ; then
AC_DEFINE(HAVE_HP_PPA_INFO_T_DL_MODULE_ID_1,1,[if ppa_info_t_dl_module_id exists])
fi])
dnl
dnl Checks to see if -R is used
dnl
@ -932,6 +847,16 @@ AC_DEFUN(AC_LBL_DEVEL,
AC_LBL_CHECK_COMPILER_OPT($1, -Wshadow)
AC_LBL_CHECK_COMPILER_OPT($1, -Wdeclaration-after-statement)
AC_LBL_CHECK_COMPILER_OPT($1, -Wused-but-marked-unused)
AC_LBL_CHECK_COMPILER_OPT($1, -Wdocumentation)
AC_LBL_CHECK_COMPILER_OPT($1, -Wcomma)
AC_LBL_CHECK_COMPILER_OPT($1, -Wmissing-noreturn)
# Warns about safeguards added in case the enums are
# extended
# AC_LBL_CHECK_COMPILER_OPT($1, -Wcovered-switch-default)
AC_LBL_CHECK_COMPILER_OPT($1, -Wmissing-variable-declarations)
AC_LBL_CHECK_COMPILER_OPT($1, -Wunused-parameter)
AC_LBL_CHECK_COMPILER_OPT($1, -Wformat-nonliteral)
AC_LBL_CHECK_COMPILER_OPT($1, -Wunreachable-code)
fi
AC_LBL_CHECK_DEPENDENCY_GENERATION_OPT()
#
@ -1020,234 +945,62 @@ fi
dnl
dnl AC_LBL_LIBRARY_NET
dnl
dnl This test is for network applications that need socket() and
dnl gethostbyname() -ish functions. Under Solaris, those applications
dnl need to link with "-lsocket -lnsl". Under IRIX, they need to link
dnl with "-lnsl" but should *not* link with "-lsocket" because
dnl libsocket.a breaks a number of things (for instance:
dnl gethostbyname() under IRIX 5.2, and snoop sockets under most
dnl versions of IRIX).
dnl This test is for network applications that need socket functions and
dnl getaddrinfo()/getnameinfo()-ish functions. We now require
dnl getaddrinfo() and getnameinfo(). We also prefer versions of
dnl recvmsg() that conform to the Single UNIX Specification, so that we
dnl can check whether a datagram received with recvmsg() was truncated
dnl when received due to the buffer being too small.
dnl
dnl Unfortunately, many application developers are not aware of this,
dnl and mistakenly write tests that cause -lsocket to be used under
dnl IRIX. It is also easy to write tests that cause -lnsl to be used
dnl under operating systems where neither are necessary (or useful),
dnl such as SunOS 4.1.4, which uses -lnsl for TLI.
dnl On most operating systems, they're available in the system library.
dnl
dnl This test exists so that every application developer does not test
dnl this in a different, and subtly broken fashion.
dnl It has been argued that this test should be broken up into two
dnl seperate tests, one for the resolver libraries, and one for the
dnl libraries necessary for using Sockets API. Unfortunately, the two
dnl are carefully intertwined and allowing the autoconf user to use
dnl them independantly potentially results in unfortunate ordering
dnl dependancies -- as such, such component macros would have to
dnl carefully use indirection and be aware if the other components were
dnl executed. Since other autoconf macros do not go to this trouble,
dnl and almost no applications use sockets without the resolver, this
dnl complexity has not been implemented.
dnl Under Solaris, we need to link with libsocket and libnsl to get
dnl getaddrinfo() and getnameinfo() and, if we have libxnet, we need to
dnl link with libxnet before libsocket to get a version of recvmsg()
dnl that conforms to the Single UNIX Specification.
dnl
dnl The check for libresolv is in case you are attempting to link
dnl statically and happen to have a libresolv.a lying around (and no
dnl libnsl.a).
dnl We use getaddrinfo() because we want a portable thread-safe way
dnl of getting information for a host name or port; there exist _r
dnl versions of gethostbyname() and getservbyname() on some platforms,
dnl but not on all platforms.
dnl
AC_DEFUN(AC_LBL_LIBRARY_NET, [
# 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:
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))
#
# Most operating systems have getaddrinfo() in the default searched
# libraries (i.e. libc). Check there first.
#
AC_CHECK_FUNC(getaddrinfo,,
[
#
# Not found in the standard system libraries.
# Try libsocket, which requires libnsl.
#
AC_CHECK_LIB(socket, getaddrinfo,
[
#
# OK, we found it in libsocket.
#
LIBS="-lsocket -lnsl $LIBS"
],
[
#
# We didn't find it.
#
AC_MSG_ERROR([getaddrinfo is required, but wasn't found])
], -lnsl)
#
# OK, do we have recvmsg() in libxnet?
# We also link with libsocket and libnsl.
#
AC_CHECK_LIB(xnet, recvmsg,
[
#
# Yes - link with it as well.
#
LIBS="-lxnet $LIBS"
], , -lsocket -lnsl)
])
# DLPI needs putmsg under HPUX so test for -lstr while we're at it
AC_SEARCH_LIBS(putmsg, str)
])
dnl
dnl Test for __attribute__
dnl
AC_DEFUN(AC_C___ATTRIBUTE__, [
AC_MSG_CHECKING(for __attribute__)
AC_CACHE_VAL(ac_cv___attribute__, [
AC_COMPILE_IFELSE([
AC_LANG_SOURCE([[
#include <stdlib.h>
static void foo(void) __attribute__ ((noreturn));
static void
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
AC_DEFINE(HAVE___ATTRIBUTE__, 1, [define if your compiler has __attribute__])
else
#
# We can't use __attribute__, so we can't use __attribute__((unused)),
# so we define _U_ to an empty string.
#
V_DEFS="$V_DEFS -D_U_=\"\""
fi
AC_MSG_RESULT($ac_cv___attribute__)
])
dnl
dnl Test whether __attribute__((unused)) can be used without warnings
dnl
AC_DEFUN(AC_C___ATTRIBUTE___UNUSED, [
AC_MSG_CHECKING([whether __attribute__((unused)) can be used without warnings])
AC_CACHE_VAL(ac_cv___attribute___unused, [
save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $ac_lbl_cc_force_warning_errors"
AC_COMPILE_IFELSE([
AC_LANG_SOURCE([[
#include <stdlib.h>
#include <stdio.h>
int
main(int argc __attribute((unused)), char **argv __attribute((unused)))
{
printf("Hello, world!\n");
return 0;
}
]])],
ac_cv___attribute___unused=yes,
ac_cv___attribute___unused=no)])
CFLAGS="$save_CFLAGS"
if test "$ac_cv___attribute___unused" = "yes"; then
V_DEFS="$V_DEFS -D_U_=\"__attribute__((unused))\""
else
V_DEFS="$V_DEFS -D_U_=\"\""
fi
AC_MSG_RESULT($ac_cv___attribute___unused)
])
dnl
dnl Test whether __attribute__((format)) can be used without warnings
dnl
AC_DEFUN(AC_C___ATTRIBUTE___FORMAT, [
AC_MSG_CHECKING([whether __attribute__((format)) can be used without warnings])
AC_CACHE_VAL(ac_cv___attribute___format, [
save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $ac_lbl_cc_force_warning_errors"
AC_COMPILE_IFELSE([
AC_LANG_SOURCE([[
#include <stdlib.h>
extern int foo(const char *fmt, ...)
__attribute__ ((format (printf, 1, 2)));
int
main(int argc, char **argv)
{
foo("%s", "test");
}
]])],
ac_cv___attribute___format=yes,
ac_cv___attribute___format=no)])
CFLAGS="$save_CFLAGS"
if test "$ac_cv___attribute___format" = "yes"; then
AC_DEFINE(__ATTRIBUTE___FORMAT_OK, 1,
[define if your compiler allows __attribute__((format)) without a warning])
fi
AC_MSG_RESULT($ac_cv___attribute___format)
])
dnl
dnl Checks to see if tpacket_stats is defined in linux/if_packet.h
dnl If so then pcap-linux.c can use this to report proper statistics.
dnl
dnl -Scott Barron
dnl
AC_DEFUN(AC_LBL_TPACKET_STATS,
[AC_MSG_CHECKING(if if_packet.h has tpacket_stats defined)
AC_CACHE_VAL(ac_cv_lbl_tpacket_stats,
AC_TRY_COMPILE([
# include <linux/if_packet.h>],
[struct tpacket_stats stats],
ac_cv_lbl_tpacket_stats=yes,
ac_cv_lbl_tpacket_stats=no))
AC_MSG_RESULT($ac_cv_lbl_tpacket_stats)
if test $ac_cv_lbl_tpacket_stats = yes; then
AC_DEFINE(HAVE_TPACKET_STATS,1,[if if_packet.h has tpacket_stats defined])
fi])
dnl
dnl Checks to see if the tpacket_auxdata struct has a tp_vlan_tci member.
dnl
dnl usage:
dnl
dnl AC_LBL_LINUX_TPACKET_AUXDATA_TP_VLAN_TCI
dnl
dnl results:
dnl
dnl HAVE_LINUX_TPACKET_AUXDATA_TP_VLAN_TCI (defined)
dnl
dnl NOTE: any compile failure means we conclude that it doesn't have
dnl that member, so if we don't have tpacket_auxdata, we conclude it
dnl doesn't have that member (which is OK, as either we won't be using
dnl code that would use that member, or we wouldn't compile in any case).
dnl
AC_DEFUN(AC_LBL_LINUX_TPACKET_AUXDATA_TP_VLAN_TCI,
[AC_MSG_CHECKING(if tpacket_auxdata struct has tp_vlan_tci member)
AC_CACHE_VAL(ac_cv_lbl_linux_tpacket_auxdata_tp_vlan_tci,
AC_TRY_COMPILE([
# include <sys/types.h>
# include <linux/if_packet.h>],
[u_int i = sizeof(((struct tpacket_auxdata *)0)->tp_vlan_tci)],
ac_cv_lbl_linux_tpacket_auxdata_tp_vlan_tci=yes,
ac_cv_lbl_linux_tpacket_auxdata_tp_vlan_tci=no))
AC_MSG_RESULT($ac_cv_lbl_linux_tpacket_auxdata_tp_vlan_tci)
if test $ac_cv_lbl_linux_tpacket_auxdata_tp_vlan_tci = yes ; then
HAVE_LINUX_TPACKET_AUXDATA=tp_vlan_tci
AC_SUBST(HAVE_LINUX_TPACKET_AUXDATA)
AC_DEFINE(HAVE_LINUX_TPACKET_AUXDATA_TP_VLAN_TCI,1,[if tp_vlan_tci exists])
fi])
dnl
dnl Checks to see if Solaris has the dl_passive_req_t struct defined
dnl in <sys/dlpi.h>.
dnl
dnl usage:
dnl
dnl AC_LBL_DL_PASSIVE_REQ_T
dnl
dnl results:
dnl
dnl HAVE_DLPI_PASSIVE (defined)
dnl
AC_DEFUN(AC_LBL_DL_PASSIVE_REQ_T,
[AC_MSG_CHECKING(if dl_passive_req_t struct exists)
AC_CACHE_VAL(ac_cv_lbl_has_dl_passive_req_t,
AC_TRY_COMPILE([
# include <sys/types.h>
# include <sys/dlpi.h>],
[u_int i = sizeof(dl_passive_req_t)],
ac_cv_lbl_has_dl_passive_req_t=yes,
ac_cv_lbl_has_dl_passive_req_t=no))
AC_MSG_RESULT($ac_cv_lbl_has_dl_passive_req_t)
if test $ac_cv_lbl_has_dl_passive_req_t = yes ; then
AC_DEFINE(HAVE_DLPI_PASSIVE,1,[if passive_req_t primitive
exists])
fi])

View File

@ -20,12 +20,14 @@
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#include <config.h>
#endif
#include <pcap.h>
#include <stdio.h>
#include "optimize.h"
void
bpf_dump(const struct bpf_program *p, int option)
{
@ -50,8 +52,7 @@ bpf_dump(const struct bpf_program *p, int option)
}
for (i = 0; i < n; ++insn, ++i) {
#ifdef BDEBUG
extern int bids[];
if (bids[i] > 0)
if (i < NBIDS && bids[i] > 0)
printf("[%02d]", bids[i] - 1);
else
printf(" -- ");

View File

@ -39,47 +39,21 @@
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#include <config.h>
#endif
#ifdef _WIN32
#include <pcap-stdinc.h>
#else /* _WIN32 */
#if HAVE_INTTYPES_H
#include <inttypes.h>
#elif HAVE_STDINT_H
#include <stdint.h>
#endif
#ifdef HAVE_SYS_BITYPES_H
#include <sys/bitypes.h>
#endif
#include <pcap/pcap-inttypes.h>
#include "pcap-types.h"
#ifndef _WIN32
#include <sys/param.h>
#include <sys/types.h>
#include <sys/time.h>
#define SOLARIS (defined(sun) && (defined(__SVR4) || defined(__svr4__)))
#if defined(__hpux) || SOLARIS
# include <sys/sysmacros.h>
# include <sys/stream.h>
# define mbuf msgb
# define m_next b_cont
# define MLEN(m) ((m)->b_wptr - (m)->b_rptr)
# define mtod(m,t) ((t)(m)->b_rptr)
#else /* defined(__hpux) || SOLARIS */
# define MLEN(m) ((m)->m_len)
#endif /* defined(__hpux) || SOLARIS */
#endif /* _WIN32 */
#include <pcap/bpf.h>
#if !defined(KERNEL) && !defined(_KERNEL)
#include <stdlib.h>
#endif
#define int32 bpf_int32
#define u_int32 bpf_u_int32
@ -117,84 +91,6 @@
(u_int32)*((u_char *)p+3)<<0)
#endif
#if defined(KERNEL) || defined(_KERNEL)
# if !defined(__hpux) && !SOLARIS
#include <sys/mbuf.h>
# endif
#define MINDEX(len, _m, _k) \
{ \
len = MLEN(m); \
while ((_k) >= len) { \
(_k) -= len; \
(_m) = (_m)->m_next; \
if ((_m) == 0) \
return 0; \
len = MLEN(m); \
} \
}
static int
m_xword(m, k, err)
register struct mbuf *m;
register int k, *err;
{
register int len;
register u_char *cp, *np;
register struct mbuf *m0;
MINDEX(len, m, k);
cp = mtod(m, u_char *) + k;
if (len - k >= 4) {
*err = 0;
return EXTRACT_LONG(cp);
}
m0 = m->m_next;
if (m0 == 0 || MLEN(m0) + len - k < 4)
goto bad;
*err = 0;
np = mtod(m0, u_char *);
switch (len - k) {
case 1:
return (cp[0] << 24) | (np[0] << 16) | (np[1] << 8) | np[2];
case 2:
return (cp[0] << 24) | (cp[1] << 16) | (np[0] << 8) | np[1];
default:
return (cp[0] << 24) | (cp[1] << 16) | (cp[2] << 8) | np[0];
}
bad:
*err = 1;
return 0;
}
static int
m_xhalf(m, k, err)
register struct mbuf *m;
register int k, *err;
{
register int len;
register u_char *cp;
register struct mbuf *m0;
MINDEX(len, m, k);
cp = mtod(m, u_char *) + k;
if (len - k >= 2) {
*err = 0;
return EXTRACT_SHORT(cp);
}
m0 = m->m_next;
if (m0 == 0)
goto bad;
*err = 0;
return (cp[0] << 8) | mtod(m0, u_char *)[0];
bad:
*err = 1;
return 0;
}
#endif
#ifdef __linux__
#include <linux/types.h>
#include <linux/if_packet.h>
@ -220,27 +116,12 @@ enum {
* Thanks to Ani Sinha <ani@arista.com> for providing initial implementation
*/
u_int
bpf_filter_with_aux_data(pc, p, wirelen, buflen, aux_data)
register const struct bpf_insn *pc;
register const u_char *p;
u_int wirelen;
register u_int buflen;
register const struct bpf_aux_data *aux_data;
bpf_filter_with_aux_data(const struct bpf_insn *pc, const u_char *p,
u_int wirelen, u_int buflen, const struct bpf_aux_data *aux_data)
{
register u_int32 A, X;
register bpf_u_int32 k;
u_int32 mem[BPF_MEMWORDS];
#if defined(KERNEL) || defined(_KERNEL)
struct mbuf *m, *n;
int merr, len;
if (buflen == 0) {
m = (struct mbuf *)p;
p = mtod(m, u_char *);
buflen = MLEN(m);
} else
m = NULL;
#endif
if (pc == 0)
/*
@ -250,16 +131,12 @@ bpf_filter_with_aux_data(pc, p, wirelen, buflen, aux_data)
A = 0;
X = 0;
--pc;
while (1) {
for (;;) {
++pc;
switch (pc->code) {
default:
#if defined(KERNEL) || defined(_KERNEL)
return 0;
#else
abort();
#endif
case BPF_RET|BPF_K:
return (u_int)pc->k;
@ -269,16 +146,7 @@ bpf_filter_with_aux_data(pc, p, wirelen, buflen, aux_data)
case BPF_LD|BPF_W|BPF_ABS:
k = pc->k;
if (k > buflen || sizeof(int32_t) > buflen - k) {
#if defined(KERNEL) || defined(_KERNEL)
if (m == NULL)
return 0;
A = m_xword(m, k, &merr);
if (merr != 0)
return 0;
continue;
#else
return 0;
#endif
}
A = EXTRACT_LONG(&p[k]);
continue;
@ -286,65 +154,37 @@ bpf_filter_with_aux_data(pc, p, wirelen, buflen, aux_data)
case BPF_LD|BPF_H|BPF_ABS:
k = pc->k;
if (k > buflen || sizeof(int16_t) > buflen - k) {
#if defined(KERNEL) || defined(_KERNEL)
if (m == NULL)
return 0;
A = m_xhalf(m, k, &merr);
if (merr != 0)
return 0;
continue;
#else
return 0;
#endif
}
A = EXTRACT_SHORT(&p[k]);
continue;
case BPF_LD|BPF_B|BPF_ABS:
{
#if defined(SKF_AD_VLAN_TAG) && defined(SKF_AD_VLAN_TAG_PRESENT)
int code = BPF_S_ANC_NONE;
#define ANCILLARY(CODE) case SKF_AD_OFF + SKF_AD_##CODE: \
code = BPF_S_ANC_##CODE; \
if (!aux_data) \
return 0; \
break;
switch (pc->k) {
switch (pc->k) {
ANCILLARY(VLAN_TAG);
ANCILLARY(VLAN_TAG_PRESENT);
default :
#endif
k = pc->k;
if (k >= buflen) {
#if defined(KERNEL) || defined(_KERNEL)
if (m == NULL)
return 0;
n = m;
MINDEX(len, n, k);
A = mtod(n, u_char *)[k];
continue;
#else
return 0;
#endif
}
A = p[k];
#if defined(SKF_AD_VLAN_TAG) && defined(SKF_AD_VLAN_TAG_PRESENT)
}
switch (code) {
case BPF_S_ANC_VLAN_TAG:
if (aux_data)
A = aux_data->vlan_tag;
break;
#if defined(SKF_AD_VLAN_TAG_PRESENT)
case SKF_AD_OFF + SKF_AD_VLAN_TAG:
if (!aux_data)
return 0;
A = aux_data->vlan_tag;
break;
case BPF_S_ANC_VLAN_TAG_PRESENT:
if (aux_data)
A = aux_data->vlan_tag_present;
break;
}
case SKF_AD_OFF + SKF_AD_VLAN_TAG_PRESENT:
if (!aux_data)
return 0;
A = aux_data->vlan_tag_present;
break;
#endif
continue;
default:
k = pc->k;
if (k >= buflen) {
return 0;
}
A = p[k];
break;
}
continue;
case BPF_LD|BPF_W|BPF_LEN:
A = wirelen;
continue;
@ -357,16 +197,7 @@ bpf_filter_with_aux_data(pc, p, wirelen, buflen, aux_data)
k = X + pc->k;
if (pc->k > buflen || X > buflen - pc->k ||
sizeof(int32_t) > buflen - k) {
#if defined(KERNEL) || defined(_KERNEL)
if (m == NULL)
return 0;
A = m_xword(m, k, &merr);
if (merr != 0)
return 0;
continue;
#else
return 0;
#endif
}
A = EXTRACT_LONG(&p[k]);
continue;
@ -375,16 +206,7 @@ bpf_filter_with_aux_data(pc, p, wirelen, buflen, aux_data)
k = X + pc->k;
if (X > buflen || pc->k > buflen - X ||
sizeof(int16_t) > buflen - k) {
#if defined(KERNEL) || defined(_KERNEL)
if (m == NULL)
return 0;
A = m_xhalf(m, k, &merr);
if (merr != 0)
return 0;
continue;
#else
return 0;
#endif
}
A = EXTRACT_SHORT(&p[k]);
continue;
@ -392,16 +214,7 @@ bpf_filter_with_aux_data(pc, p, wirelen, buflen, aux_data)
case BPF_LD|BPF_B|BPF_IND:
k = X + pc->k;
if (pc->k >= buflen || X >= buflen - pc->k) {
#if defined(KERNEL) || defined(_KERNEL)
if (m == NULL)
return 0;
n = m;
MINDEX(len, n, k);
A = mtod(n, u_char *)[k];
continue;
#else
return 0;
#endif
}
A = p[k];
continue;
@ -409,16 +222,7 @@ bpf_filter_with_aux_data(pc, p, wirelen, buflen, aux_data)
case BPF_LDX|BPF_MSH|BPF_B:
k = pc->k;
if (k >= buflen) {
#if defined(KERNEL) || defined(_KERNEL)
if (m == NULL)
return 0;
n = m;
MINDEX(len, n, k);
X = (mtod(n, char *)[k] & 0xf) << 2;
continue;
#else
return 0;
#endif
}
X = (p[pc->k] & 0xf) << 2;
continue;
@ -448,18 +252,11 @@ bpf_filter_with_aux_data(pc, p, wirelen, buflen, aux_data)
continue;
case BPF_JMP|BPF_JA:
#if defined(KERNEL) || defined(_KERNEL)
/*
* No backward jumps allowed.
*/
pc += pc->k;
#else
/*
* XXX - we currently implement "ip6 protochain"
* with backward jumps, so sign-extend pc->k.
*/
pc += (bpf_int32)pc->k;
#endif
continue;
case BPF_JMP|BPF_JGT|BPF_K:
@ -599,11 +396,8 @@ bpf_filter_with_aux_data(pc, p, wirelen, buflen, aux_data)
}
u_int
bpf_filter(pc, p, wirelen, buflen)
register const struct bpf_insn *pc;
register const u_char *p;
u_int wirelen;
register u_int buflen;
bpf_filter(const struct bpf_insn *pc, const u_char *p, u_int wirelen,
u_int buflen)
{
return bpf_filter_with_aux_data(pc, p, wirelen, buflen, NULL);
}
@ -621,22 +415,13 @@ bpf_filter(pc, p, wirelen, buflen)
* Otherwise, a bogus program could easily crash the system.
*/
int
bpf_validate(f, len)
const struct bpf_insn *f;
int len;
bpf_validate(const struct bpf_insn *f, int len)
{
u_int i, from;
const struct bpf_insn *p;
if (len < 1)
return 0;
/*
* There's no maximum program length in userland.
*/
#if defined(KERNEL) || defined(_KERNEL)
if (len > BPF_MAXINSNS)
return 0;
#endif
for (i = 0; i < (u_int)len; ++i) {
p = &f[i];
@ -657,14 +442,6 @@ bpf_validate(f, len)
* in userland. The runtime packet length
* check suffices.
*/
#if defined(KERNEL) || defined(_KERNEL)
/*
* More strict check with actual packet length
* is done runtime.
*/
if (p->k >= bpf_maxbufsize)
return 0;
#endif
break;
case BPF_MEM:
if (p->k >= BPF_MEMWORDS)
@ -736,11 +513,7 @@ bpf_validate(f, len)
from = i + 1;
switch (BPF_OP(p->code)) {
case BPF_JA:
#if defined(KERNEL) || defined(_KERNEL)
if (from + p->k < from || from + p->k >= len)
#else
if (from + p->k >= (u_int)len)
#endif
return 0;
break;
case BPF_JEQ:

View File

@ -20,22 +20,10 @@
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#include <config.h>
#endif
#ifdef _WIN32
#include <pcap-stdinc.h>
#else /* _WIN32 */
#if HAVE_INTTYPES_H
#include <inttypes.h>
#elif HAVE_STDINT_H
#include <stdint.h>
#endif
#ifdef HAVE_SYS_BITYPES_H
#include <sys/bitypes.h>
#endif
#include <sys/types.h>
#endif /* _WIN32 */
#include <pcap-types.h>
#include <stdio.h>
#include <string.h>
@ -47,266 +35,290 @@
#endif
char *
bpf_image(p, n)
const struct bpf_insn *p;
int n;
bpf_image(const struct bpf_insn *p, int n)
{
int v;
const char *fmt, *op;
const char *op;
static char image[256];
char operand[64];
char operand_buf[64];
const char *operand;
v = p->k;
switch (p->code) {
default:
op = "unimp";
fmt = "0x%x";
v = p->code;
(void)pcap_snprintf(operand_buf, sizeof operand_buf, "0x%x", p->code);
operand = operand_buf;
break;
case BPF_RET|BPF_K:
op = "ret";
fmt = "#%d";
(void)pcap_snprintf(operand_buf, sizeof operand_buf, "#%d", p->k);
operand = operand_buf;
break;
case BPF_RET|BPF_A:
op = "ret";
fmt = "";
operand = "";
break;
case BPF_LD|BPF_W|BPF_ABS:
op = "ld";
fmt = "[%d]";
(void)pcap_snprintf(operand_buf, sizeof operand_buf, "[%d]", p->k);
operand = operand_buf;
break;
case BPF_LD|BPF_H|BPF_ABS:
op = "ldh";
fmt = "[%d]";
(void)pcap_snprintf(operand_buf, sizeof operand_buf, "[%d]", p->k);
operand = operand_buf;
break;
case BPF_LD|BPF_B|BPF_ABS:
op = "ldb";
fmt = "[%d]";
(void)pcap_snprintf(operand_buf, sizeof operand_buf, "[%d]", p->k);
operand = operand_buf;
break;
case BPF_LD|BPF_W|BPF_LEN:
op = "ld";
fmt = "#pktlen";
operand = "#pktlen";
break;
case BPF_LD|BPF_W|BPF_IND:
op = "ld";
fmt = "[x + %d]";
(void)pcap_snprintf(operand_buf, sizeof operand_buf, "[x + %d]", p->k);
operand = operand_buf;
break;
case BPF_LD|BPF_H|BPF_IND:
op = "ldh";
fmt = "[x + %d]";
(void)pcap_snprintf(operand_buf, sizeof operand_buf, "[x + %d]", p->k);
operand = operand_buf;
break;
case BPF_LD|BPF_B|BPF_IND:
op = "ldb";
fmt = "[x + %d]";
(void)pcap_snprintf(operand_buf, sizeof operand_buf, "[x + %d]", p->k);
operand = operand_buf;
break;
case BPF_LD|BPF_IMM:
op = "ld";
fmt = "#0x%x";
(void)pcap_snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k);
operand = operand_buf;
break;
case BPF_LDX|BPF_IMM:
op = "ldx";
fmt = "#0x%x";
(void)pcap_snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k);
operand = operand_buf;
break;
case BPF_LDX|BPF_MSH|BPF_B:
op = "ldxb";
fmt = "4*([%d]&0xf)";
(void)pcap_snprintf(operand_buf, sizeof operand_buf, "4*([%d]&0xf)", p->k);
operand = operand_buf;
break;
case BPF_LD|BPF_MEM:
op = "ld";
fmt = "M[%d]";
(void)pcap_snprintf(operand_buf, sizeof operand_buf, "M[%d]", p->k);
operand = operand_buf;
break;
case BPF_LDX|BPF_MEM:
op = "ldx";
fmt = "M[%d]";
(void)pcap_snprintf(operand_buf, sizeof operand_buf, "M[%d]", p->k);
operand = operand_buf;
break;
case BPF_ST:
op = "st";
fmt = "M[%d]";
(void)pcap_snprintf(operand_buf, sizeof operand_buf, "M[%d]", p->k);
operand = operand_buf;
break;
case BPF_STX:
op = "stx";
fmt = "M[%d]";
(void)pcap_snprintf(operand_buf, sizeof operand_buf, "M[%d]", p->k);
operand = operand_buf;
break;
case BPF_JMP|BPF_JA:
op = "ja";
fmt = "%d";
v = n + 1 + p->k;
(void)pcap_snprintf(operand_buf, sizeof operand_buf, "%d", n + 1 + p->k);
operand = operand_buf;
break;
case BPF_JMP|BPF_JGT|BPF_K:
op = "jgt";
fmt = "#0x%x";
(void)pcap_snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k);
operand = operand_buf;
break;
case BPF_JMP|BPF_JGE|BPF_K:
op = "jge";
fmt = "#0x%x";
(void)pcap_snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k);
operand = operand_buf;
break;
case BPF_JMP|BPF_JEQ|BPF_K:
op = "jeq";
fmt = "#0x%x";
(void)pcap_snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k);
operand = operand_buf;
break;
case BPF_JMP|BPF_JSET|BPF_K:
op = "jset";
fmt = "#0x%x";
(void)pcap_snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k);
operand = operand_buf;
break;
case BPF_JMP|BPF_JGT|BPF_X:
op = "jgt";
fmt = "x";
operand = "x";
break;
case BPF_JMP|BPF_JGE|BPF_X:
op = "jge";
fmt = "x";
operand = "x";
break;
case BPF_JMP|BPF_JEQ|BPF_X:
op = "jeq";
fmt = "x";
operand = "x";
break;
case BPF_JMP|BPF_JSET|BPF_X:
op = "jset";
fmt = "x";
operand = "x";
break;
case BPF_ALU|BPF_ADD|BPF_X:
op = "add";
fmt = "x";
operand = "x";
break;
case BPF_ALU|BPF_SUB|BPF_X:
op = "sub";
fmt = "x";
operand = "x";
break;
case BPF_ALU|BPF_MUL|BPF_X:
op = "mul";
fmt = "x";
operand = "x";
break;
case BPF_ALU|BPF_DIV|BPF_X:
op = "div";
fmt = "x";
operand = "x";
break;
case BPF_ALU|BPF_MOD|BPF_X:
op = "mod";
fmt = "x";
operand = "x";
break;
case BPF_ALU|BPF_AND|BPF_X:
op = "and";
fmt = "x";
operand = "x";
break;
case BPF_ALU|BPF_OR|BPF_X:
op = "or";
fmt = "x";
operand = "x";
break;
case BPF_ALU|BPF_XOR|BPF_X:
op = "xor";
fmt = "x";
operand = "x";
break;
case BPF_ALU|BPF_LSH|BPF_X:
op = "lsh";
fmt = "x";
operand = "x";
break;
case BPF_ALU|BPF_RSH|BPF_X:
op = "rsh";
fmt = "x";
operand = "x";
break;
case BPF_ALU|BPF_ADD|BPF_K:
op = "add";
fmt = "#%d";
(void)pcap_snprintf(operand_buf, sizeof operand_buf, "#%d", p->k);
operand = operand_buf;
break;
case BPF_ALU|BPF_SUB|BPF_K:
op = "sub";
fmt = "#%d";
(void)pcap_snprintf(operand_buf, sizeof operand_buf, "#%d", p->k);
operand = operand_buf;
break;
case BPF_ALU|BPF_MUL|BPF_K:
op = "mul";
fmt = "#%d";
(void)pcap_snprintf(operand_buf, sizeof operand_buf, "#%d", p->k);
operand = operand_buf;
break;
case BPF_ALU|BPF_DIV|BPF_K:
op = "div";
fmt = "#%d";
(void)pcap_snprintf(operand_buf, sizeof operand_buf, "#%d", p->k);
operand = operand_buf;
break;
case BPF_ALU|BPF_MOD|BPF_K:
op = "mod";
fmt = "#%d";
(void)pcap_snprintf(operand_buf, sizeof operand_buf, "#%d", p->k);
operand = operand_buf;
break;
case BPF_ALU|BPF_AND|BPF_K:
op = "and";
fmt = "#0x%x";
(void)pcap_snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k);
operand = operand_buf;
break;
case BPF_ALU|BPF_OR|BPF_K:
op = "or";
fmt = "#0x%x";
(void)pcap_snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k);
operand = operand_buf;
break;
case BPF_ALU|BPF_XOR|BPF_K:
op = "xor";
fmt = "#0x%x";
(void)pcap_snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k);
operand = operand_buf;
break;
case BPF_ALU|BPF_LSH|BPF_K:
op = "lsh";
fmt = "#%d";
(void)pcap_snprintf(operand_buf, sizeof operand_buf, "#%d", p->k);
operand = operand_buf;
break;
case BPF_ALU|BPF_RSH|BPF_K:
op = "rsh";
fmt = "#%d";
(void)pcap_snprintf(operand_buf, sizeof operand_buf, "#%d", p->k);
operand = operand_buf;
break;
case BPF_ALU|BPF_NEG:
op = "neg";
fmt = "";
operand = "";
break;
case BPF_MISC|BPF_TAX:
op = "tax";
fmt = "";
operand = "";
break;
case BPF_MISC|BPF_TXA:
op = "txa";
fmt = "";
operand = "";
break;
}
(void)pcap_snprintf(operand, sizeof operand, fmt, v);
if (BPF_CLASS(p->code) == BPF_JMP && BPF_OP(p->code) != BPF_JA) {
(void)pcap_snprintf(image, sizeof image,
"(%03d) %-8s %-16s jt %d\tjf %d",

View File

@ -1,7 +1,7 @@
#! /bin/sh
#
# Unfortunately, Mac OS X's devfs is based on the old FreeBSD
# Unfortunately, macOS'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,

View File

@ -0,0 +1,32 @@
#
# Try to find the Endace DAG library.
#
# Try to find the header
find_path(DAG_INCLUDE_DIR dagapi.h)
#
# Try to find the libraries
#
# We assume that if we have libdag we have libdagconf, as they're
# installed at the same time from the same package.
#
find_library(DAG_LIBRARY dag)
find_library(DAGCONF_LIBRARY dagconf)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(DAG
DEFAULT_MSG
DAG_INCLUDE_DIR
DAG_LIBRARY
DAGCONF_LIBRARY
)
mark_as_advanced(
DAG_INCLUDE_DIR
DAG_LIBRARY
DAGCONF_LIBRARY
)
set(DAG_INCLUDE_DIRS ${DAG_INCLUDE_DIR})
set(DAG_LIBRARIES ${DAG_LIBRARY} ${DAGCONF_LIBRARY})

View File

@ -0,0 +1,85 @@
# CMake support for fseeko
#
# Based on FindLFS.cmake by
# Copyright (C) 2016 Julian Andres Klode <jak@debian.org>.
#
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation files
# (the "Software"), to deal in the Software without restriction,
# including without limitation the rights to use, copy, modify, merge,
# publish, distribute, sublicense, and/or sell copies of the Software,
# and to permit persons to whom the Software is furnished to do so,
# subject to the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
# This defines the following variables
#
# FSEEKO_DEFINITIONS - List of definitions to pass to add_definitions()
# FSEEKO_COMPILE_OPTIONS - List of definitions to pass to add_compile_options()
# FSEEKO_LIBRARIES - List of libraries and linker flags
# FSEEKO_FOUND - If there is Large files support
#
include(CheckCSourceCompiles)
include(FindPackageHandleStandardArgs)
include(CMakePushCheckState)
# Check for the availability of fseeko()
# The cases handled are:
#
# * Native fseeko()
# * Preprocessor flag -D_LARGEFILE_SOURCE
#
function(_fseeko_check)
set(_fseeko_cppflags)
cmake_push_check_state()
set(CMAKE_REQUIRED_QUIET 1)
set(CMAKE_REQUIRED_DEFINITIONS ${LFS_DEFINITIONS})
message(STATUS "Looking for native fseeko support")
check_symbol_exists(fseeko stdio.h fseeko_native)
cmake_pop_check_state()
if (fseeko_native)
message(STATUS "Looking for native fseeko support - found")
set(FSEEKO_FOUND TRUE)
else()
message(STATUS "Looking for native fseeko support - not found")
endif()
if (NOT FSEEKO_FOUND)
# See if it's available with _LARGEFILE_SOURCE.
cmake_push_check_state()
set(CMAKE_REQUIRED_QUIET 1)
set(CMAKE_REQUIRED_DEFINITIONS ${LFS_DEFINITIONS} "-D_LARGEFILE_SOURCE")
check_symbol_exists(fseeko stdio.h fseeko_need_largefile_source)
cmake_pop_check_state()
if (fseeko_need_largefile_source)
message(STATUS "Looking for fseeko support with _LARGEFILE_SOURCE - found")
set(FSEEKO_FOUND TRUE)
set(_fseeko_cppflags "-D_LARGEFILE_SOURCE")
else()
message(STATUS "Looking for fseeko support with _LARGEFILE_SOURCE - not found")
endif()
endif()
set(FSEEKO_DEFINITIONS ${_fseeko_cppflags} CACHE STRING "Extra definitions for fseeko support")
set(FSEEKO_COMPILE_OPTIONS "" CACHE STRING "Extra compiler options for fseeko support")
set(FSEEKO_LIBRARIES "" CACHE STRING "Extra definitions for fseeko support")
set(FSEEKO_FOUND ${FSEEKO_FOUND} CACHE INTERNAL "Found fseeko")
endfunction()
if (NOT FSEEKO_FOUND)
_fseeko_check()
endif()
find_package_handle_standard_args(FSEEKO "Could not find fseeko. Set FSEEKO_DEFINITIONS, FSEEKO_COMPILE_OPTIONS, FSEEKO_LIBRARIES." FSEEKO_FOUND)

153
cmake/Modules/FindLFS.cmake Normal file
View File

@ -0,0 +1,153 @@
# CMake support for large files
#
# Copyright (C) 2016 Julian Andres Klode <jak@debian.org>.
#
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation files
# (the "Software"), to deal in the Software without restriction,
# including without limitation the rights to use, copy, modify, merge,
# publish, distribute, sublicense, and/or sell copies of the Software,
# and to permit persons to whom the Software is furnished to do so,
# subject to the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
# This defines the following variables
#
# LFS_DEFINITIONS - List of definitions to pass to add_definitions()
# LFS_COMPILE_OPTIONS - List of definitions to pass to add_compile_options()
# LFS_LIBRARIES - List of libraries and linker flags
# LFS_FOUND - If there is Large files support
#
include(CheckCSourceCompiles)
include(FindPackageHandleStandardArgs)
include(CMakePushCheckState)
# Test program to check for LFS. Requires that off_t has at least 8 byte large
set(_lfs_test_source
"
#include <sys/types.h>
typedef char my_static_assert[sizeof(off_t) >= 8 ? 1 : -1];
int main(void) { return 0; }
"
)
# Check if the given options are needed
#
# This appends to the variables _lfs_cppflags, _lfs_cflags, and _lfs_ldflags,
# it also sets LFS_FOUND to 1 if it works.
function(_lfs_check_compiler_option var options definitions libraries)
cmake_push_check_state()
set(CMAKE_REQUIRED_QUIET 1)
set(CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS} ${options})
set(CMAKE_REQUIRED_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} ${definitions})
set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_DEFINITIONS} ${libraries})
message(STATUS "Looking for LFS support using ${options} ${definitions} ${libraries}")
check_c_source_compiles("${_lfs_test_source}" ${var})
cmake_pop_check_state()
if(${var})
message(STATUS "Looking for LFS support using ${options} ${definitions} ${libraries} - found")
set(_lfs_cppflags ${_lfs_cppflags} ${definitions} PARENT_SCOPE)
set(_lfs_cflags ${_lfs_cflags} ${options} PARENT_SCOPE)
set(_lfs_ldflags ${_lfs_ldflags} ${libraries} PARENT_SCOPE)
set(LFS_FOUND TRUE PARENT_SCOPE)
else()
message(STATUS "Looking for LFS support using ${options} ${definitions} ${libraries} - not found")
endif()
endfunction()
# Check for the availability of LFS.
# The cases handled are:
#
# * Native LFS
# * Output of getconf LFS_CFLAGS; getconf LFS_LIBS; getconf LFS_LDFLAGS
# * Preprocessor flag -D_FILE_OFFSET_BITS=64
# * Preprocessor flag -D_LARGE_FILES
#
function(_lfs_check)
set(_lfs_cflags)
set(_lfs_cppflags)
set(_lfs_ldflags)
set(_lfs_libs)
cmake_push_check_state()
set(CMAKE_REQUIRED_QUIET 1)
message(STATUS "Looking for native LFS support")
check_c_source_compiles("${_lfs_test_source}" lfs_native)
cmake_pop_check_state()
if (lfs_native)
message(STATUS "Looking for native LFS support - found")
set(LFS_FOUND TRUE)
else()
message(STATUS "Looking for native LFS support - not found")
endif()
if (NOT LFS_FOUND)
# Check using getconf. If getconf fails, don't worry, the check in
# _lfs_check_compiler_option will fail as well.
execute_process(COMMAND getconf LFS_CFLAGS
OUTPUT_VARIABLE _lfs_cflags_raw
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET)
execute_process(COMMAND getconf LFS_LIBS
OUTPUT_VARIABLE _lfs_libs_tmp
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET)
execute_process(COMMAND getconf LFS_LDFLAGS
OUTPUT_VARIABLE _lfs_ldflags_tmp
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET)
separate_arguments(_lfs_cflags_raw)
separate_arguments(_lfs_ldflags_tmp)
separate_arguments(_lfs_libs_tmp)
# Move -D flags to the place they are supposed to be
foreach(flag ${_lfs_cflags_raw})
if (flag MATCHES "-D.*")
list(APPEND _lfs_cppflags_tmp ${flag})
else()
list(APPEND _lfs_cflags_tmp ${flag})
endif()
endforeach()
# Check if the flags we received (if any) produce working LFS support
_lfs_check_compiler_option(lfs_getconf_works
"${_lfs_cflags_tmp}"
"${_lfs_cppflags_tmp}"
"${_lfs_libs_tmp};${_lfs_ldflags_tmp}")
endif()
if(NOT LFS_FOUND) # IRIX stuff
_lfs_check_compiler_option(lfs_need_n32 "-n32" "" "")
endif()
if(NOT LFS_FOUND) # Linux and friends
_lfs_check_compiler_option(lfs_need_file_offset_bits "" "-D_FILE_OFFSET_BITS=64" "")
endif()
if(NOT LFS_FOUND) # AIX
_lfs_check_compiler_option(lfs_need_large_files "" "-D_LARGE_FILES=1" "")
endif()
set(LFS_DEFINITIONS ${_lfs_cppflags} CACHE STRING "Extra definitions for large file support")
set(LFS_COMPILE_OPTIONS ${_lfs_cflags} CACHE STRING "Extra definitions for large file support")
set(LFS_LIBRARIES ${_lfs_libs} ${_lfs_ldflags} CACHE STRING "Extra definitions for large file support")
set(LFS_FOUND ${LFS_FOUND} CACHE INTERNAL "Found LFS")
endfunction()
if (NOT LFS_FOUND)
_lfs_check()
endif()
find_package_handle_standard_args(LFS "Could not find LFS. Set LFS_DEFINITIONS, LFS_COMPILE_OPTIONS, LFS_LIBRARIES." LFS_FOUND)

View File

@ -0,0 +1,81 @@
#
# Copyright (C) 2017 Ali Abdulkadir <autostart.ini@gmail.com>.
#
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation files
# (the "Software"), to deal in the Software without restriction,
# including without limitation the rights to use, copy, modify, merge,
# publish, distribute, sub-license, and/or sell copies of the Software,
# and to permit persons to whom the Software is furnished to do so,
# subject to the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
# FindPacket
# ==========
#
# Find the Packet library and include files.
#
# This module defines the following variables:
#
# PACKET_INCLUDE_DIR - absolute path to the directory containing Packet32.h.
#
# PACKET_LIBRARY - relative or absolute path to the Packet library to
# link with. An absolute path is will be used if the
# Packet library is not located in the compiler's
# default search path. See e.g. PACKET_DLL_DIR
# variable below.
# PACKET_FOUND - TRUE if the Packet library *and* header are found.
#
# Hints and Backward Compatibility
# ================================
#
# To tell this module where to look, a user may set the environment variable
# PACKET_DLL_DIR to point cmake to the *root* of a directory with include and
# lib subdirectories for packet.dll (e.g WpdPack/npcap-sdk).
# Alternatively, PACKET_DLL_DIR may also be set from cmake command line or GUI
# (e.g cmake -DPACKET_DLL_DIR=/path/to/packet [...])
#
# The 64-bit Packet.lib is located under /x64
set(64BIT_SUBDIR "")
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(64BIT_SUBDIR "/x64")
endif()
# Find the header
find_path(PACKET_INCLUDE_DIR Packet32.h
HINTS "${PACKET_DLL_DIR}" ENV PACKET_DLL_DIR
PATH_SUFFIXES include Include
)
# Find the library
find_library(PACKET_LIBRARY
NAMES Packet packet
HINTS "${PACKET_DLL_DIR}" ENV PACKET_DLL_DIR
PATH_SUFFIXES Lib${64BIT_SUBDIR} lib${64BIT_SUBDIR}
)
# Set PACKET_FOUND to TRUE if PACKET_INCLUDE_DIR and PACKET_LIBRARY are TRUE.
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(PACKET
DEFAULT_MSG
PACKET_INCLUDE_DIR
PACKET_LIBRARY
)
mark_as_advanced(PACKET_INCLUDE_DIR PACKET_LIBRARY)
set(PACKET_INCLUDE_DIRS ${PACKET_INCLUDE_DIR})
set(PACKET_LIBRARIES ${PACKET_LIBRARY})

View File

@ -0,0 +1,152 @@
# ==============================================================================
# This is a heavily modified version of FindPthreads.cmake for the pcap project.
# It's meant to find Pthreads-w32, an implementation of the
# Threads component of the POSIX 1003.1c 1995 Standard (or later)
# for Microsoft's WIndows.
#
# Apart from this notice, this module "enjoys" the following modifications:
#
# - changed its name to FindPthreads-w32.cmake to not conflict with FindThreads.cmake
#
# - users may be able to use the environment variable PTHREADS_ROOT to point
# cmake to the *root* of their Pthreads-w32 installation.
# Alternatively, PTHREADS_ROOT may also be set from cmake command line or GUI
# (-DPTHREADS_ROOT=/path/to/Pthreads-w32)
# Two other variables that can be defined in a similar fashion are
# PTHREAD_INCLUDE_PATH and PTHREAD_LIBRARY_PATH.
#
# - added some additional status/error messages
#
# - changed formating (uppercase to lowercare + indentation)
#
# - removed some stuff
#
# - when searching for Pthreads-win32 libraries, the directory structure of the
# pre-build binaries folder found in the pthreads-win32 CVS code repository is
# considered (e.i /Pre-built.2/lib/x64 /Pre-built.2/lib/x86)
#
# Send suggestion, patches, gifts and praises to pcap's developers.
# ==============================================================================
#
# Find the Pthreads library
# This module searches for the Pthreads-win32 library (including the
# pthreads-win32 port).
#
# This module defines these variables:
#
# PTHREADS_FOUND - True if the Pthreads library was found
# PTHREADS_LIBRARY - The location of the Pthreads library
# PTHREADS_INCLUDE_DIR - The include directory of the Pthreads library
# PTHREADS_DEFINITIONS - Preprocessor definitions to define (HAVE_PTHREAD_H is a fairly common one)
#
# This module responds to the PTHREADS_EXCEPTION_SCHEME
# variable on Win32 to allow the user to control the
# library linked against. The Pthreads-win32 port
# provides the ability to link against a version of the
# library with exception handling.
# IT IS NOT RECOMMENDED THAT YOU CHANGE PTHREADS_EXCEPTION_SCHEME
# TO ANYTHING OTHER THAN "C" because most POSIX thread implementations
# do not support stack unwinding.
#
# PTHREADS_EXCEPTION_SCHEME
# C = no exceptions (default)
# (NOTE: This is the default scheme on most POSIX thread
# implementations and what you should probably be using)
# CE = C++ Exception Handling
# SE = Structure Exception Handling (MSVC only)
#
#
# Define a default exception scheme to link against
# and validate user choice.
#
#
if(NOT DEFINED PTHREADS_EXCEPTION_SCHEME)
# Assign default if needed
set(PTHREADS_EXCEPTION_SCHEME "C")
else(NOT DEFINED PTHREADS_EXCEPTION_SCHEME)
# Validate
if(NOT PTHREADS_EXCEPTION_SCHEME STREQUAL "C" AND
NOT PTHREADS_EXCEPTION_SCHEME STREQUAL "CE" AND
NOT PTHREADS_EXCEPTION_SCHEME STREQUAL "SE")
message(FATAL_ERROR "See documentation for FindPthreads.cmake, only C, CE, and SE modes are allowed")
endif(NOT PTHREADS_EXCEPTION_SCHEME STREQUAL "C" AND
NOT PTHREADS_EXCEPTION_SCHEME STREQUAL "CE" AND
NOT PTHREADS_EXCEPTION_SCHEME STREQUAL "SE")
if(NOT MSVC AND PTHREADS_EXCEPTION_SCHEME STREQUAL "SE")
message(FATAL_ERROR "Structured Exception Handling is only allowed for MSVC")
endif(NOT MSVC AND PTHREADS_EXCEPTION_SCHEME STREQUAL "SE")
endif(NOT DEFINED PTHREADS_EXCEPTION_SCHEME)
if(PTHREADS_ROOT)
set(PTHREADS_ROOT PATHS ${PTHREADS_ROOT} NO_DEFAULT_PATH)
else()
set(PTHREADS_ROOT $ENV{PTHREADS_ROOT})
endif(PTHREADS_ROOT)
#
# Find the header file
#
find_path(PTHREADS_INCLUDE_DIR
NAMES pthread.h
HINTS
$ENV{PTHREAD_INCLUDE_PATH}
${PTHREADS_ROOT}/include
)
if(PTHREADS_INCLUDE_DIR)
message(STATUS "Found pthread.h: ${PTHREADS_INCLUDE_DIR}")
# else()
# message(FATAL_ERROR "Could not find pthread.h. See README.Win32 for more information.")
endif(PTHREADS_INCLUDE_DIR)
#
# Find the library
#
set(names)
if(MSVC)
set(names
pthreadV${PTHREADS_EXCEPTION_SCHEME}2
libpthread
)
elseif(MINGW)
set(names
pthreadG${PTHREADS_EXCEPTION_SCHEME}2
pthread
)
endif(MSVC)
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
set(SUBDIR "/x86")
elseif(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(SUBDIR "/x64")
endif()
find_library(PTHREADS_LIBRARY NAMES ${names}
DOC "The Portable Threads Library"
HINTS
${CMAKE_SOURCE_DIR}/lib
$ENV{PTHREAD_LIBRARY_PATH}
${PTHREADS_ROOT}
C:/MinGW/lib/
PATH_SUFFIXES lib/${SUBDIR}
)
if(PTHREADS_LIBRARY)
message(STATUS "Found PTHREADS library: ${PTHREADS_LIBRARY} (PTHREADS Exception Scheme: ${PTHREADS_EXCEPTION_SCHEME})")
# else()
# message(FATAL_ERROR "Could not find PTHREADS LIBRARY. See README.Win32 for more information.")
endif(PTHREADS_LIBRARY)
if(PTHREADS_INCLUDE_DIR AND PTHREADS_LIBRARY)
set(PTHREADS_DEFINITIONS -DHAVE_PTHREAD_H)
set(PTHREADS_INCLUDE_DIRS ${PTHREADS_INCLUDE_DIR})
set(PTHREADS_LIBRARIES ${PTHREADS_LIBRARY})
set(PTHREADS_FOUND TRUE)
endif(PTHREADS_INCLUDE_DIR AND PTHREADS_LIBRARY)
mark_as_advanced(PTHREADS_INCLUDE_DIR PTHREADS_LIBRARY)

View File

@ -0,0 +1,24 @@
#
# Try to find the Myricom SNF library.
#
# Try to find the header
find_path(SNF_INCLUDE_DIR snf.h /opt/snf)
# Try to find the library
find_library(SNF_LIBRARY snf /opt/snf)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(SNF
DEFAULT_MSG
SNF_INCLUDE_DIR
SNF_LIBRARY
)
mark_as_advanced(
SNF_INCLUDE_DIR
SNF_LIBRARY
)
set(SNF_INCLUDE_DIRS ${SNF_INCLUDE_DIR})
set(SNF_LIBRARIES ${SNF_LIBRARY})

View File

@ -0,0 +1,24 @@
#
# Try to find the Riverbed TurboCap library.
#
# Try to find the header
find_path(TC_INCLUDE_DIR TcApi.h)
# Try to find the library
find_library(TC_LIBRARY TcApi)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(TC
DEFAULT_MSG
TC_INCLUDE_DIR
TC_LIBRARY
)
mark_as_advanced(
TC_INCLUDE_DIR
TC_LIBRARY
)
set(TC_INCLUDE_DIRS ${TC_INCLUDE_DIR})
set(TC_LIBRARIES ${TC_LIBRARY})

View File

@ -1,55 +0,0 @@
if( NOT LIBPCAP_PRECONFIGURED )
set( LIBPCAP_PRECONFIGURED TRUE )
###################################################################
# Parameters
###################################################################
option (USE_STATIC_RT "Use static Runtime" ON)
######################################
# Project setings
######################################
add_definitions( -DBUILDING_PCAP )
if( MSVC )
add_definitions( -D__STDC__ )
add_definitions( -D_CRT_SECURE_NO_WARNINGS )
add_definitions( "-D_U_=" )
elseif( CMAKE_COMPILER_IS_GNUCXX )
add_definitions( "-D_U_=__attribute__((unused))" )
else(MSVC)
add_definitions( "-D_U_=" )
endif( MSVC )
if (USE_STATIC_RT)
MESSAGE( STATUS "Use STATIC runtime" )
if( MSVC )
set (CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} /MT")
set (CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /MT")
set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")
set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
set (CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL} /MT")
set (CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} /MT")
set (CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /MT")
set (CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /MTd")
endif( MSVC )
else (USE_STATIC_RT)
MESSAGE( STATUS "Use DYNAMIC runtime" )
if( MSVC )
set (CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} /MD")
set (CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /MD")
set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MD")
set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MDd")
set (CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL} /MD")
set (CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} /MD")
set (CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /MD")
set (CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /MDd")
endif( MSVC )
endif (USE_STATIC_RT)
endif( NOT LIBPCAP_PRECONFIGURED )

21
cmake_uninstall.cmake.in Normal file
View File

@ -0,0 +1,21 @@
if(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
message(FATAL_ERROR "Cannot find install manifest: @CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
endif(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files)
string(REGEX REPLACE "\n" ";" files "${files}")
foreach(file ${files})
message(STATUS "Uninstalling $ENV{DESTDIR}${file}")
if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
exec_program(
"@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
OUTPUT_VARIABLE rm_out
RETURN_VALUE rm_retval
)
if(NOT "${rm_retval}" STREQUAL 0)
message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}")
endif(NOT "${rm_retval}" STREQUAL 0)
else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
message(STATUS "File $ENV{DESTDIR}${file} does not exist.")
endif(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
endforeach(file)

View File

@ -1,10 +1,19 @@
/* cmakeconfig.h.in */
/* Define to 1 if arpa/inet.h declares `ether_hostton' */
#cmakedefine ARPA_INET_H_DECLARES_ETHER_HOSTTON 1
/* Enable optimizer debugging */
#cmakedefine BDEBUG 1
/* define if you have a cloning BPF device */
#cmakedefine HAVE_CLONING_BPF 1
/* Define to 1 if remote packet capture is to be supported */
#cmakedefine ENABLE_REMOTE 1
/* define if we have the AIX getnetbyname_r() */
#cmakedefine HAVE_AIX_GETNETBYNAME_R 1
/* define if we have the AIX getprotobyname_r() */
#cmakedefine HAVE_AIX_GETPROTOBYNAME_R 1
/* define if you have the DAG API */
#cmakedefine HAVE_DAG_API 1
@ -15,21 +24,20 @@
/* define if you have dag_get_stream_erf_types() */
#cmakedefine HAVE_DAG_GET_STREAM_ERF_TYPES 1
/* define if you have streams capable DAG API */
#cmakedefine HAVE_DAG_STREAMS_API 1
/* define if you have large streams capable DAG API */
#cmakedefine HAVE_DAG_LARGE_STREAMS_API 1
/* define if you have vdag_set_device_info() */
#cmakedefine HAVE_DAG_VDAG 1
/* Define to 1 if you have the declaration of `ether_hostton', and to 0 if you
don't. */
/* Define to 1 if you have the declaration of `ether_hostton' */
#cmakedefine HAVE_DECL_ETHER_HOSTTON 1
/* define if you have a /dev/dlpi */
#cmakedefine HAVE_DEV_DLPI 1
/* Define to 1 if `dl_module_id_1' is a member of `dl_hp_ppa_info_t'. */
#cmakedefine HAVE_DL_HP_PPA_INFO_T_DL_MODULE_ID_1 1
/* if passive_req_t primitive exists */
#cmakedefine HAVE_DLPI_PASSIVE 1
/* Define to 1 if the system has the type `dl_passive_req_t'. */
#cmakedefine HAVE_DL_PASSIVE_REQ_T 1
/* Define to 1 if you have the `ether_hostton' function. */
#cmakedefine HAVE_ETHER_HOSTTON 1
@ -37,15 +45,15 @@
/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */
#cmakedefine HAVE_FSEEKO 1
/* Define to 1 if you have the `getspnam' function. */
#cmakedefine HAVE_GETSPNAM 1
/* on HP-UX 10.20 or later */
#cmakedefine HAVE_HPUX10_20_OR_LATER 1
/* on HP-UX 9.x */
#cmakedefine HAVE_HPUX9 1
/* if ppa_info_t_dl_module_id exists */
#cmakedefine HAVE_HP_PPA_INFO_T_DL_MODULE_ID_1 1
/* Define to 1 if you have the <inttypes.h> header file. */
#cmakedefine HAVE_INTTYPES_H 1
@ -76,24 +84,24 @@
/* Define to 1 if you have the <linux/ethtool.h> header file. */
#cmakedefine HAVE_LINUX_ETHTOOL_H 1
/* define if we have the Linux getnetbyname_r() */
#cmakedefine HAVE_LINUX_GETNETBYNAME_R 1
/* define if we have the Linux getprotobyname_r() */
#cmakedefine HAVE_LINUX_GETPROTOBYNAME_R 1
/* Define to 1 if you have the <linux/if_bonding.h> header file. */
#cmakedefine HAVE_LINUX_IF_BONDING_H 1
/* Define to 1 if you have the <linux/if_packet.h> header file. */
#cmakedefine HAVE_LINUX_IF_PACKET_H 1
/* Define to 1 if you have the <linux/net_tstamp.h> header file. */
#cmakedefine HAVE_LINUX_NET_TSTAMP_H 1
/* Define to 1 if you have the <linux/socket.h> header file. */
#cmakedefine HAVE_LINUX_SOCKET_H 1
/* Define to 1 if you have the <linux/sockios.h> header file. */
#cmakedefine HAVE_LINUX_SOCKIOS_H 1
/* if tp_vlan_tci exists */
#cmakedefine HAVE_LINUX_TPACKET_AUXDATA_TP_VLAN_TCI 1
/* Define to 1 if you have the <linux/types.h> header file. */
#cmakedefine HAVE_LINUX_TYPES_H 1
/* Define to 1 if you have the <linux/usbdevice_fs.h> header file. */
#cmakedefine HAVE_LINUX_USBDEVICE_FS_H 1
@ -103,32 +111,35 @@
/* Define to 1 if you have the <memory.h> header file. */
#cmakedefine HAVE_MEMORY_H 1
/* Define to 1 if you have the <netinet/ether.h> header file. */
#cmakedefine HAVE_NETINET_ETHER_H 1
/* Define to 1 if you have the <netinet/if_ether.h> header file. */
#cmakedefine HAVE_NETINET_IF_ETHER_H 1
/* Define to 1 if you have the <netpacket/if_packet.h> header file. */
#cmakedefine HAVE_NETPACKET_IF_PACKET_H 1
/* Define to 1 if you have the <netpacket/packet.h> header file. */
#cmakedefine HAVE_NETPACKET_PACKET_H 1
/* Define to 1 if you have the <net/bpf.h> header file. */
#cmakedefine HAVE_NET_BPF_H 1
/* Define to 1 if you have the <net/enet.h> header file. */
#cmakedefine HAVE_NET_ENET_H 1
/* Define to 1 if you have the <net/if_media.h> header file. */
#cmakedefine HAVE_NET_IF_MEDIA_H 1
/* Define to 1 if you have the <net/nit.h> header file. */
#cmakedefine HAVE_NET_NIT_H 1
/* Define to 1 if you have the <net/pfilt.h> header file. */
#cmakedefine HAVE_NET_PFILT_H 1
/* Define to 1 if you have the <net/pfvar.h> header file. */
#cmakedefine HAVE_NET_PFVAR_H 1
/* Define to 1 if you have the <net/raw.h> header file. */
#cmakedefine HAVE_NET_RAW_H 1
/* if there's an os_proto.h for this platform, to use additional prototypes */
#cmakedefine HAVE_OS_PROTO_H 1
/* Define to 1 if remote packet capture is to be supported */
#cmakedefine HAVE_REMOTE 1
/* Define to 1 if you have the <paths.h> header file. */
#cmakedefine HAVE_PATHS_H 1
/* Define to 1 if Packet32 API (WinPcap NPF driver) is available */
#cmakedefine HAVE_PACKET32 1
/* define if net/pfvar.h defines PF_NAT through PF_NORDR */
#cmakedefine HAVE_PF_NAT_THROUGH_PF_NORDR 1
@ -142,18 +153,18 @@
/* Define to 1 if you have the `snprintf' function. */
#cmakedefine HAVE_SNPRINTF 1
/* if struct sockaddr has the sa_len member */
#cmakedefine HAVE_SOCKADDR_SA_LEN 1
/* if struct sockaddr_storage exists */
#cmakedefine HAVE_SOCKADDR_STORAGE 1
/* define if socklen_t is defined */
/* Define to 1 if the system has the type `socklen_t'. */
#cmakedefine HAVE_SOCKLEN_T 1
/* On solaris */
#cmakedefine HAVE_SOLARIS 1
/* define if we have the Solaris/IRIX getnetbyname_r() */
#cmakedefine HAVE_SOLARIS_IRIX_GETNETBYNAME_R 1
/* define if we have the Solaris/IRIX getprotobyname_r() */
#cmakedefine HAVE_SOLARIS_IRIX_GETPROTOBYNAME_R 1
/* Define to 1 if you have the <stdint.h> header file. */
#cmakedefine HAVE_STDINT_H 1
@ -163,17 +174,57 @@
/* Define to 1 if you have the `strerror' function. */
#cmakedefine HAVE_STRERROR 1
/* Define to 1 if you have the `strerror_r' function. */
#cmakedefine HAVE_STRERROR_R 1
/* Define to 1 if you have the `strerror_s' function. */
#cmakedefine HAVE_STRERROR_S 1
/* Define to 1 if you have the <strings.h> header file. */
#cmakedefine HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */
#cmakedefine HAVE_STRING_H 1
/* Define to 1 if you have the `strlcat' function. */
#cmakedefine HAVE_STRLCAT 1
/* Define to 1 if you have the `strlcpy' function. */
#cmakedefine HAVE_STRLCPY 1
/* Define to 1 if you have the `strtok_r' function. */
#cmakedefine HAVE_STRTOK_R 1
/* Define to 1 if the system has the type `struct BPF_TIMEVAL'. */
#cmakedefine HAVE_STRUCT_BPF_TIMEVAL 1
/* Define to 1 if the system has the type `struct ether_addr'. */
#cmakedefine HAVE_STRUCT_ETHER_ADDR 1
/* Define to 1 if you have the <sys/bitypes.h> header file. */
#cmakedefine HAVE_SYS_BITYPES_H 1
/* Define to 1 if `msg_control' is a member of `struct msghdr'. */
#cmakedefine HAVE_STRUCT_MSGHDR_MSG_CONTROL 1
/* Define to 1 if `msg_flags' is a member of `struct msghdr'. */
#cmakedefine HAVE_STRUCT_MSGHDR_MSG_FLAGS 1
/* Define to 1 if `hci_channel' is a member of `struct sockaddr_hci'. */
#cmakedefine HAVE_STRUCT_SOCKADDR_HCI_HCI_CHANNEL 1
/* Define to 1 if `sa_len' is a member of `struct sockaddr'. */
#cmakedefine HAVE_STRUCT_SOCKADDR_SA_LEN 1
/* Define to 1 if the system has the type `struct sockaddr_storage'. */
#cmakedefine HAVE_STRUCT_SOCKADDR_STORAGE 1
/* Define to 1 if `tp_vlan_tci' is a member of `struct tpacket_auxdata'. */
#cmakedefine HAVE_STRUCT_TPACKET_AUXDATA_TP_VLAN_TCI 1
/* Define to 1 if the system has the type `struct tpacket_stats'. */
#cmakedefine HAVE_STRUCT_TPACKET_STATS 1
/* Define to 1 if `bRequestType' is a member of `struct
usbdevfs_ctrltransfer'. */
#cmakedefine HAVE_STRUCT_USBDEVFS_CTRLTRANSFER_BREQUESTTYPE 1
/* Define to 1 if you have the <sys/bufmod.h> header file. */
#cmakedefine HAVE_SYS_BUFMOD_H 1
@ -181,9 +232,15 @@
/* Define to 1 if you have the <sys/dlpi_ext.h> header file. */
#cmakedefine HAVE_SYS_DLPI_EXT_H 1
/* Define to 1 if you have the <sys/dlpi.h> header file. */
#cmakedefine HAVE_SYS_DLPI_H 1
/* Define to 1 if you have the <sys/ioccom.h> header file. */
#cmakedefine HAVE_SYS_IOCCOM_H 1
/* Define to 1 if you have the <sys/net/nit.h> header file. */
#cmakedefine HAVE_SYS_NET_NIT_H 1
/* Define to 1 if you have the <sys/sockio.h> header file. */
#cmakedefine HAVE_SYS_SOCKIO_H 1
@ -196,27 +253,15 @@
/* define if you have the TurboCap API */
#cmakedefine HAVE_TC_API 1
/* if if_packet.h has tpacket_stats defined */
#cmakedefine HAVE_TPACKET_STATS 1
/* Define to 1 if you have the <unistd.h> header file. */
#cmakedefine HAVE_UNISTD_H 1
/* if struct usbdevfs_ctrltransfer has bRequestType */
#cmakedefine HAVE_USBDEVFS_CTRLTRANSFER_BREQUESTTYPE 1
/* Define to 1 if you have the `vsnprintf' function. */
#cmakedefine HAVE_VSNPRINTF 1
/* Define to 1 if you have the `PacketIsLoopbackAdapter' function. */
#cmakedefine HAVE_PACKET_IS_LOOPBACK_ADAPTER 1
/* define if the system supports zerocopy BPF */
#cmakedefine HAVE_ZEROCOPY_BPF 1
/* define if your compiler has __attribute__ */
#cmakedefine HAVE___ATTRIBUTE__ 1
/* IPv6 */
#cmakedefine INET6 1
@ -224,10 +269,7 @@
#cmakedefine LBL_ALIGN 1
/* path for device for USB sniffing */
#cmakedefine LINUX_USB_MON_DEV 1
/* if we need a pcap_parse wrapper around yyparse */
#cmakedefine NEED_YYPARSE_WRAPPER 1
#cmakedefine LINUX_USB_MON_DEV "@LINUX_USB_MON_DEV@"
/* Define to 1 if netinet/ether.h declares `ether_hostton' */
#cmakedefine NETINET_ETHER_H_DECLARES_ETHER_HOSTTON 1
@ -235,17 +277,23 @@
/* Define to 1 if netinet/if_ether.h declares `ether_hostton' */
#cmakedefine NETINET_IF_ETHER_H_DECLARES_ETHER_HOSTTON 1
/* Define to 1 if net/ethernet.h declares `ether_hostton' */
#cmakedefine NET_ETHERNET_H_DECLARES_ETHER_HOSTTON 1
/* do not use protochain */
#cmakedefine NO_PROTOCHAIN 1
/* Define to the address where bug reports for this package should be sent. */
#cmakedefine PACKAGE_BUGREPORT 1
/* Define to the DLL-preferred version string of of this package. */
#cmakedefine PACKAGE_VERSION_DLL @PACKAGE_VERSION_DLL@
/* Define to the full name of this package. */
#cmakedefine PACKAGE_NAME 1
#cmakedefine PACKAGE_NAME "@PACKAGE_NAME@"
/* Define to the full name and version of this package. */
#cmakedefine PACKAGE_STRING 1
#cmakedefine PACKAGE_STRING "@PACKAGE_STRING@"
/* Define to the one symbol short name of this package. */
#cmakedefine PACKAGE_TARNAME 1
@ -254,10 +302,7 @@
#cmakedefine PACKAGE_URL 1
/* Define to the version of this package. */
#cmakedefine PACKAGE_VERSION 1
/* /dev/dlpi directory */
#cmakedefine PCAP_DEV_PREFIX 1
#cmakedefine PACKAGE_VERSION "@PACKAGE_VERSION@"
/* target host supports Bluetooth sniffing */
#cmakedefine PCAP_SUPPORT_BT 1
@ -271,21 +316,30 @@
/* target host supports netfilter sniffing */
#cmakedefine PCAP_SUPPORT_NETFILTER 1
/* use Linux packet ring capture if available */
/* target host supports netmap */
#cmakedefine PCAP_SUPPORT_NETMAP 1
/* use packet ring capture support on Linux if available */
#cmakedefine PCAP_SUPPORT_PACKET_RING 1
/* target host supports RDMA sniffing */
#cmakedefine PCAP_SUPPORT_RDMASNIFF 1
/* target host supports USB sniffing */
#cmakedefine PCAP_SUPPORT_USB 1
/* include ACN support */
#cmakedefine SITA 1
/* if struct sockaddr_hci has hci_channel member */
#cmakedefine SOCKADDR_HCI_HAS_HCI_CHANNEL 1
/* Define to 1 if you have the ANSI C header files. */
#cmakedefine STDC_HEADERS 1
/* Define to 1 if strings.h declares `ffs' */
#cmakedefine STRINGS_H_DECLARES_FFS 1
/* Define to 1 if sys/ethernet.h declares `ether_hostton' */
#cmakedefine SYS_ETHERNET_H_DECLARES_ETHER_HOSTTON 1
/* Enable parser debugging */
#cmakedefine YYDEBUG 1
@ -306,40 +360,7 @@
/* define on AIX to get certain functions */
#cmakedefine _SUN 1
/* define if your compiler allows __attribute__((format)) without a warning */
#cmakedefine __ATTRIBUTE___FORMAT_OK 1
#if 0
/* to handle Ultrix compilers that don't support const in prototypes */
#cmakedefine const 1
/* Define as token for inline if inlining supported */
#cmakedefine inline 1
/* Define to `short' if int16_t not defined. */
#cmakedefine int16_t 1
/* Define to `int' if int32_t not defined. */
#cmakedefine int32_t 1
/* Define to `long long' if int64_t not defined. */
#cmakedefine int64_t 1
/* Define to `signed char' if int8_t not defined. */
#cmakedefine int8_t 1
/* on sinix */
#cmakedefine sinix 1
/* Define to `unsigned short' if u_int16_t not defined. */
#cmakedefine u_int16_t 1
/* Define to `unsigned int' if u_int32_t not defined. */
#cmakedefine u_int32_t 1
/* Define to `unsigned long long' if u_int64_t not defined. */
#cmakedefine u_int64_t 1
/* Define to `unsigned char' if u_int8_t not defined. */
#cmakedefine u_int8_t 1
#endif

View File

@ -1,10 +1,22 @@
/* config.h.in. Generated from configure.ac by autoheader. */
/* Define to 1 if arpa/inet.h declares `ether_hostton' */
#undef ARPA_INET_H_DECLARES_ETHER_HOSTTON
/* Enable optimizer debugging */
#undef BDEBUG
/* define if you have a cloning BPF device */
#undef HAVE_CLONING_BPF
/* Define to 1 if remote packet capture is to be supported */
#undef ENABLE_REMOTE
/* define if we have the AIX getnetbyname_r() */
#undef HAVE_AIX_GETNETBYNAME_R
/* define if we have the AIX getprotobyname_r() */
#undef HAVE_AIX_GETPROTOBYNAME_R
/* Define to 1 if you have the <dagapi.h> header file. */
#undef HAVE_DAGAPI_H
/* define if you have the DAG API */
#undef HAVE_DAG_API
@ -15,40 +27,45 @@
/* define if you have dag_get_stream_erf_types() */
#undef HAVE_DAG_GET_STREAM_ERF_TYPES
/* define if you have streams capable DAG API */
#undef HAVE_DAG_STREAMS_API
/* define if you have large streams capable DAG API */
#undef HAVE_DAG_LARGE_STREAMS_API
/* define if you have vdag_set_device_info() */
#undef HAVE_DAG_VDAG
/* Define to 1 if you have the declaration of `ether_hostton', and to 0 if you
don't. */
/* Define to 1 if you have the declaration of `ether_hostton' */
#undef HAVE_DECL_ETHER_HOSTTON
/* define if you have a /dev/dlpi */
#undef HAVE_DEV_DLPI
/* Define to 1 if `dl_module_id_1' is a member of `dl_hp_ppa_info_t'. */
#undef HAVE_DL_HP_PPA_INFO_T_DL_MODULE_ID_1
/* if passive_req_t primitive exists */
#undef HAVE_DLPI_PASSIVE
/* Define to 1 if the system has the type `dl_passive_req_t'. */
#undef HAVE_DL_PASSIVE_REQ_T
/* Define to 1 if you have the `ether_hostton' function. */
#undef HAVE_ETHER_HOSTTON
/* Define to 1 if you have the `ffs' function. */
#undef HAVE_FFS
/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */
#undef HAVE_FSEEKO
/* Define to 1 if you have the `getspnam' function. */
#undef HAVE_GETSPNAM
/* on HP-UX 10.20 or later */
#undef HAVE_HPUX10_20_OR_LATER
/* on HP-UX 9.x */
#undef HAVE_HPUX9
/* if ppa_info_t_dl_module_id exists */
#undef HAVE_HP_PPA_INFO_T_DL_MODULE_ID_1
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the `dag' library (-ldag). */
#undef HAVE_LIBDAG
/* if libdlpi exists */
#undef HAVE_LIBDLPI
@ -76,24 +93,24 @@
/* Define to 1 if you have the <linux/ethtool.h> header file. */
#undef HAVE_LINUX_ETHTOOL_H
/* define if we have the Linux getnetbyname_r() */
#undef HAVE_LINUX_GETNETBYNAME_R
/* define if we have the Linux getprotobyname_r() */
#undef HAVE_LINUX_GETPROTOBYNAME_R
/* Define to 1 if you have the <linux/if_bonding.h> header file. */
#undef HAVE_LINUX_IF_BONDING_H
/* Define to 1 if you have the <linux/if_packet.h> header file. */
#undef HAVE_LINUX_IF_PACKET_H
/* Define to 1 if you have the <linux/net_tstamp.h> header file. */
#undef HAVE_LINUX_NET_TSTAMP_H
/* Define to 1 if you have the <linux/socket.h> header file. */
#undef HAVE_LINUX_SOCKET_H
/* Define to 1 if you have the <linux/sockios.h> header file. */
#undef HAVE_LINUX_SOCKIOS_H
/* if tp_vlan_tci exists */
#undef HAVE_LINUX_TPACKET_AUXDATA_TP_VLAN_TCI
/* Define to 1 if you have the <linux/types.h> header file. */
#undef HAVE_LINUX_TYPES_H
/* Define to 1 if you have the <linux/usbdevice_fs.h> header file. */
#undef HAVE_LINUX_USBDEVICE_FS_H
@ -103,24 +120,30 @@
/* 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
/* Define to 1 if you have the <netpacket/if_packet.h> header file. */
#undef HAVE_NETPACKET_IF_PACKET_H
/* Define to 1 if you have the <netpacket/packet.h> header file. */
#undef HAVE_NETPACKET_PACKET_H
/* Define to 1 if you have the <net/bpf.h> header file. */
#undef HAVE_NET_BPF_H
/* Define to 1 if you have the <net/enet.h> header file. */
#undef HAVE_NET_ENET_H
/* Define to 1 if you have the <net/if_media.h> header file. */
#undef HAVE_NET_IF_MEDIA_H
/* Define to 1 if you have the <net/nit.h> header file. */
#undef HAVE_NET_NIT_H
/* Define to 1 if you have the <net/pfilt.h> header file. */
#undef HAVE_NET_PFILT_H
/* Define to 1 if you have the <net/pfvar.h> header file. */
#undef HAVE_NET_PFVAR_H
/* Define to 1 if you have the <net/raw.h> header file. */
#undef HAVE_NET_RAW_H
/* if there's an os_proto.h for this platform, to use additional prototypes */
#undef HAVE_OS_PROTO_H
@ -136,18 +159,18 @@
/* Define to 1 if you have the `snprintf' function. */
#undef HAVE_SNPRINTF
/* if struct sockaddr has the sa_len member */
#undef HAVE_SOCKADDR_SA_LEN
/* if struct sockaddr_storage exists */
#undef HAVE_SOCKADDR_STORAGE
/* define if socklen_t is defined */
/* Define to 1 if the system has the type `socklen_t'. */
#undef HAVE_SOCKLEN_T
/* On solaris */
#undef HAVE_SOLARIS
/* define if we have the Solaris/IRIX getnetbyname_r() */
#undef HAVE_SOLARIS_IRIX_GETNETBYNAME_R
/* define if we have the Solaris/IRIX getprotobyname_r() */
#undef HAVE_SOLARIS_IRIX_GETPROTOBYNAME_R
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
@ -157,12 +180,21 @@
/* Define to 1 if you have the `strerror' function. */
#undef HAVE_STRERROR
/* Define to 1 if you have the `strerror_r' function. */
#undef HAVE_STRERROR_R
/* Define to 1 if you have the `strerror_s' function. */
#undef HAVE_STRERROR_S
/* 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 `strlcat' function. */
#undef HAVE_STRLCAT
/* Define to 1 if you have the `strlcpy' function. */
#undef HAVE_STRLCPY
@ -175,8 +207,30 @@
/* 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/bitypes.h> header file. */
#undef HAVE_SYS_BITYPES_H
/* Define to 1 if `msg_control' is a member of `struct msghdr'. */
#undef HAVE_STRUCT_MSGHDR_MSG_CONTROL
/* Define to 1 if `msg_flags' is a member of `struct msghdr'. */
#undef HAVE_STRUCT_MSGHDR_MSG_FLAGS
/* Define to 1 if `hci_channel' is a member of `struct sockaddr_hci'. */
#undef HAVE_STRUCT_SOCKADDR_HCI_HCI_CHANNEL
/* Define to 1 if `sa_len' is a member of `struct sockaddr'. */
#undef HAVE_STRUCT_SOCKADDR_SA_LEN
/* Define to 1 if the system has the type `struct sockaddr_storage'. */
#undef HAVE_STRUCT_SOCKADDR_STORAGE
/* Define to 1 if `tp_vlan_tci' is a member of `struct tpacket_auxdata'. */
#undef HAVE_STRUCT_TPACKET_AUXDATA_TP_VLAN_TCI
/* Define to 1 if the system has the type `struct tpacket_stats'. */
#undef HAVE_STRUCT_TPACKET_STATS
/* Define to 1 if `bRequestType' is a member of `struct
usbdevfs_ctrltransfer'. */
#undef HAVE_STRUCT_USBDEVFS_CTRLTRANSFER_BREQUESTTYPE
/* Define to 1 if you have the <sys/bufmod.h> header file. */
#undef HAVE_SYS_BUFMOD_H
@ -184,11 +238,14 @@
/* 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/dlpi.h> header file. */
#undef HAVE_SYS_DLPI_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/select.h> header file. */
#undef HAVE_SYS_SELECT_H
/* Define to 1 if you have the <sys/net/nit.h> header file. */
#undef HAVE_SYS_NET_NIT_H
/* Define to 1 if you have the <sys/sockio.h> header file. */
#undef HAVE_SYS_SOCKIO_H
@ -202,24 +259,12 @@
/* define if you have the TurboCap API */
#undef HAVE_TC_API
/* 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
/* if struct usbdevfs_ctrltransfer has bRequestType */
#undef HAVE_USBDEVFS_CTRLTRANSFER_BREQUESTTYPE
/* Define to 1 if you have the `vsnprintf' function. */
#undef HAVE_VSNPRINTF
/* define if the system supports zerocopy BPF */
#undef HAVE_ZEROCOPY_BPF
/* define if your compiler has __attribute__ */
#undef HAVE___ATTRIBUTE__
/* IPv6 */
#undef INET6
@ -235,6 +280,9 @@
/* Define to 1 if netinet/if_ether.h declares `ether_hostton' */
#undef NETINET_IF_ETHER_H_DECLARES_ETHER_HOSTTON
/* Define to 1 if net/ethernet.h declares `ether_hostton' */
#undef NET_ETHERNET_H_DECLARES_ETHER_HOSTTON
/* do not use protochain */
#undef NO_PROTOCHAIN
@ -256,9 +304,6 @@
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* /dev/dlpi directory */
#undef PCAP_DEV_PREFIX
/* target host supports Bluetooth sniffing */
#undef PCAP_SUPPORT_BT
@ -271,21 +316,30 @@
/* target host supports netfilter sniffing */
#undef PCAP_SUPPORT_NETFILTER
/* use Linux packet ring capture if available */
/* target host supports netmap */
#undef PCAP_SUPPORT_NETMAP
/* use packet ring capture support on Linux if available */
#undef PCAP_SUPPORT_PACKET_RING
/* target host supports RDMA sniffing */
#undef PCAP_SUPPORT_RDMASNIFF
/* target host supports USB sniffing */
#undef PCAP_SUPPORT_USB
/* include ACN support */
#undef SITA
/* if struct sockaddr_hci has hci_channel member */
#undef SOCKADDR_HCI_HAS_HCI_CHANNEL
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Define to 1 if strings.h declares `ffs' */
#undef STRINGS_H_DECLARES_FFS
/* Define to 1 if sys/ethernet.h declares `ether_hostton' */
#undef SYS_ETHERNET_H_DECLARES_ETHER_HOSTTON
/* Enable parser debugging */
#undef YYDEBUG
@ -310,38 +364,11 @@
/* define on AIX to get certain functions */
#undef _SUN
/* define if your compiler allows __attribute__((format)) without a warning */
#undef __ATTRIBUTE___FORMAT_OK
/* to handle Ultrix compilers that don't support const in prototypes */
#undef const
/* Define as token for inline if inlining supported */
#undef inline
/* Define to `short' if int16_t not defined. */
#undef int16_t
/* Define to `int' if int32_t not defined. */
#undef int32_t
/* Define to `long long' if int64_t not defined. */
#undef int64_t
/* Define to `signed char' if int8_t not defined. */
#undef int8_t
/* on sinix */
#undef sinix
/* Define to `unsigned short' if u_int16_t not defined. */
#undef u_int16_t
/* Define to `unsigned int' if u_int32_t not defined. */
#undef u_int32_t
/* Define to `unsigned long long' if u_int64_t not defined. */
#undef u_int64_t
/* Define to `unsigned char' if u_int8_t not defined. */
#undef u_int8_t

4013
configure vendored

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

215
diag-control.h Normal file
View File

@ -0,0 +1,215 @@
/* -*- 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.
*/
#ifndef _diag_control_h
#define _diag_control_h
#include "pcap/compiler-tests.h"
#ifndef _MSC_VER
/*
* Clang and GCC both support this way of putting pragmas into #defines.
* We don't use it unless we have a compiler that supports it; the
* warning-suppressing pragmas differ between Clang and GCC, so we test
* for both of those separately.
*/
#define PCAP_DO_PRAGMA(x) _Pragma (#x)
#endif
/*
* Suppress Flex warnings.
*/
#if defined(_MSC_VER)
/*
* This is Microsoft Visual Studio; we can use __pragma(warning(disable:XXXX))
* and __pragma(warning(push/pop)).
*
* Suppress signed-vs-unsigned comparison, narrowing, and unreachable
* code warnings.
*/
#define DIAG_OFF_FLEX \
__pragma(warning(push)) \
__pragma(warning(disable:4127)) \
__pragma(warning(disable:4242)) \
__pragma(warning(disable:4244)) \
__pragma(warning(disable:4702))
#define DIAG_ON_FLEX __pragma(warning(pop))
#elif PCAP_IS_AT_LEAST_CLANG_VERSION(2,8)
/*
* This is Clang 2.8 or later; we can use "clang diagnostic
* ignored -Wxxx" and "clang diagnostic push/pop".
*
* Suppress -Wdocumentation warnings; GCC doesn't support -Wdocumentation,
* at least according to the GCC 7.3 documentation. Apparently, Flex
* generates code that upsets at least some versions of Clang's
* -Wdocumentation.
*/
#define DIAG_OFF_FLEX \
PCAP_DO_PRAGMA(clang diagnostic push) \
PCAP_DO_PRAGMA(clang diagnostic ignored "-Wsign-compare") \
PCAP_DO_PRAGMA(clang diagnostic ignored "-Wdocumentation") \
PCAP_DO_PRAGMA(clang diagnostic ignored "-Wmissing-noreturn") \
PCAP_DO_PRAGMA(clang diagnostic ignored "-Wunused-parameter") \
PCAP_DO_PRAGMA(clang diagnostic ignored "-Wunreachable-code")
#define DIAG_ON_FLEX \
PCAP_DO_PRAGMA(clang diagnostic pop)
#elif PCAP_IS_AT_LEAST_GNUC_VERSION(4,6)
/*
* This is GCC 4.6 or later, or a compiler claiming to be that.
* We can use "GCC diagnostic ignored -Wxxx" (introduced in 4.2)
* and "GCC diagnostic push/pop" (introduced in 4.6).
*/
#define DIAG_OFF_FLEX \
PCAP_DO_PRAGMA(GCC diagnostic push) \
PCAP_DO_PRAGMA(GCC diagnostic ignored "-Wsign-compare") \
PCAP_DO_PRAGMA(GCC diagnostic ignored "-Wunused-parameter") \
PCAP_DO_PRAGMA(GCC diagnostic ignored "-Wunreachable-code")
#define DIAG_ON_FLEX \
PCAP_DO_PRAGMA(GCC diagnostic pop)
#else
/*
* Neither Visual Studio, nor Clang 2.8 or later, nor GCC 4.6 or later
* or a compiler claiming to be that; there's nothing we know of that
* we can do.
*/
#define DIAG_OFF_FLEX
#define DIAG_ON_FLEX
#endif
#ifdef YYBYACC
/*
* Berkeley YACC.
*
* It generates a global declaration of yylval, or the appropriately
* prefixed version of yylval, in grammar.h, *even though it's been
* told to generate a pure parser, meaning it doesn't have any global
* variables*. Bison doesn't do this.
*
* That causes a warning due to the local declaration in the parser
* shadowing the global declaration.
*
* So, if the compiler warns about that, we turn off -Wshadow warnings.
*/
#if defined(_MSC_VER)
/*
* This is Microsoft Visual Studio; we can use
* __pragma(warning(disable:XXXX)) and __pragma(warning(push/pop)).
*
* Suppress unreachable code warnings.
*/
#define DIAG_OFF_BISON_BYACC \
__pragma(warning(push)) \
__pragma(warning(disable:4702))
#define DIAG_ON_BISON_BYACC __pragma(warning(pop))
#elif PCAP_IS_AT_LEAST_CLANG_VERSION(2,8)
/*
* This is Clang 2.8 or later; we can use "clang diagnostic
* ignored -Wxxx" and "clang diagnostic push/pop".
*/
#define DIAG_OFF_BISON_BYACC \
PCAP_DO_PRAGMA(clang diagnostic push) \
PCAP_DO_PRAGMA(clang diagnostic ignored "-Wshadow") \
PCAP_DO_PRAGMA(clang diagnostic ignored "-Wunreachable-code")
#define DIAG_ON_BISON_BYACC \
PCAP_DO_PRAGMA(clang diagnostic pop)
#elif PCAP_IS_AT_LEAST_GNUC_VERSION(4,6)
/*
* This is GCC 4.6 or later, or a compiler claiming to be that.
* We can use "GCC diagnostic ignored -Wxxx" (introduced in 4.2)
* and "GCC diagnostic push/pop" (introduced in 4.6).
*/
#define DIAG_OFF_BISON_BYACC \
PCAP_DO_PRAGMA(GCC diagnostic push) \
PCAP_DO_PRAGMA(GCC diagnostic ignored "-Wshadow") \
PCAP_DO_PRAGMA(GCC diagnostic ignored "-Wunreachable-code")
#define DIAG_ON_BISON_BYACC \
PCAP_DO_PRAGMA(GCC diagnostic pop)
#else
/*
* Neither Clang 2.8 or later nor GCC 4.6 or later or a compiler
* claiming to be that; there's nothing we know of that we can do.
*/
#define DIAG_OFF_BISON_BYACC
#define DIAG_ON_BISON_BYACC
#endif
#else
/*
* Bison.
*/
#if defined(_MSC_VER)
/*
* This is Microsoft Visual Studio; we can use
* __pragma(warning(disable:XXXX)) and __pragma(warning(push/pop)).
*
* Suppress some /Wall warnings.
*/
#define DIAG_OFF_BISON_BYACC \
__pragma(warning(push)) \
__pragma(warning(disable:4127)) \
__pragma(warning(disable:4242)) \
__pragma(warning(disable:4244)) \
__pragma(warning(disable:4702))
#define DIAG_ON_BISON_BYACC __pragma(warning(pop))
#elif PCAP_IS_AT_LEAST_CLANG_VERSION(2,8)
/*
* This is Clang 2.8 or later; we can use "clang diagnostic
* ignored -Wxxx" and "clang diagnostic push/pop".
*/
#define DIAG_OFF_BISON_BYACC \
PCAP_DO_PRAGMA(clang diagnostic push) \
PCAP_DO_PRAGMA(clang diagnostic ignored "-Wunreachable-code")
#define DIAG_ON_BISON_BYACC \
PCAP_DO_PRAGMA(clang diagnostic pop)
#elif PCAP_IS_AT_LEAST_GNUC_VERSION(4,6)
/*
* This is GCC 4.6 or later, or a compiler claiming to be that.
* We can use "GCC diagnostic ignored -Wxxx" (introduced in 4.2)
* and "GCC diagnostic push/pop" (introduced in 4.6).
*/
#define DIAG_OFF_BISON_BYACC \
PCAP_DO_PRAGMA(GCC diagnostic push) \
PCAP_DO_PRAGMA(GCC diagnostic ignored "-Wunreachable-code")
#define DIAG_ON_BISON_BYACC \
PCAP_DO_PRAGMA(GCC diagnostic pop)
#else
/*
* Neither Clang 2.8 or later nor GCC 4.6 or later or a compiler
* claiming to be that; there's nothing we know of that we can do.
*/
#define DIAG_OFF_BISON_BYACC
#define DIAG_ON_BISON_BYACC
#endif
#endif
#endif /* _diag_control_h */

View File

@ -12,7 +12,7 @@
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#include <config.h>
#endif
#ifndef DL_IPATM
@ -271,7 +271,16 @@ pcap_process_mactype(pcap_t *p, u_int mactype)
#ifdef DL_IPNET
case DL_IPNET:
p->linktype = DLT_IPNET;
/*
* XXX - DL_IPNET devices default to "raw IP" rather than
* "IPNET header"; see
*
* http://seclists.org/tcpdump/2009/q1/202
*
* We'd have to do DL_IOC_IPNET_INFO to enable getting
* the IPNET header.
*/
p->linktype = DLT_RAW;
p->offset = 0;
break;
#endif
@ -349,7 +358,8 @@ pcap_alloc_databuf(pcap_t *p)
p->bufsize = PKTBUFSIZE;
p->buffer = malloc(p->bufsize + p->offset);
if (p->buffer == NULL) {
strlcpy(p->errbuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
errno, "malloc");
return (-1);
}
@ -383,6 +393,6 @@ strioctl(int fd, int cmd, int len, char *dp)
static void
pcap_stream_err(const char *func, int err, char *errbuf)
{
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", func, pcap_strerror(err));
pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, err, "%s", func);
}
#endif

View File

@ -20,22 +20,10 @@
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#include <config.h>
#endif
#ifdef _WIN32
#include <pcap-stdinc.h>
#else /* _WIN32 */
#if HAVE_INTTYPES_H
#include <inttypes.h>
#elif HAVE_STDINT_H
#include <stdint.h>
#endif
#ifdef HAVE_SYS_BITYPES_H
#include <sys/bitypes.h>
#endif
#include <sys/types.h>
#endif /* _WIN32 */
#include <pcap-types.h>
#include <ctype.h>
#include <memory.h>
@ -50,26 +38,23 @@
#include "os-proto.h"
#endif
static inline int xdtoi(int);
static inline int skip_space(FILE *);
static inline int skip_line(FILE *);
/* Hex digit to integer. */
static inline int
xdtoi(c)
register int c;
static inline u_char
xdtoi(u_char c)
{
if (isdigit(c))
return c - '0';
return (u_char)(c - '0');
else if (islower(c))
return c - 'a' + 10;
return (u_char)(c - 'a' + 10);
else
return c - 'A' + 10;
return (u_char)(c - 'A' + 10);
}
static inline int
skip_space(f)
FILE *f;
skip_space(FILE *f)
{
int c;
@ -81,8 +66,7 @@ skip_space(f)
}
static inline int
skip_line(f)
FILE *f;
skip_line(FILE *f)
{
int c;
@ -96,47 +80,61 @@ skip_line(f)
struct pcap_etherent *
pcap_next_etherent(FILE *fp)
{
register int c, d, i;
register int c, i;
u_char d;
char *bp;
size_t namesize;
static struct pcap_etherent e;
memset((char *)&e, 0, sizeof(e));
do {
for (;;) {
/* Find addr */
c = skip_space(fp);
if (c == EOF)
return (NULL);
if (c == '\n')
continue;
/* If this is a comment, or first thing on line
cannot be etehrnet address, skip the line. */
cannot be Ethernet address, skip the line. */
if (!isxdigit(c)) {
c = skip_line(fp);
if (c == EOF)
return (NULL);
continue;
}
/* must be the start of an address */
for (i = 0; i < 6; i += 1) {
d = xdtoi(c);
d = xdtoi((u_char)c);
c = getc(fp);
if (c == EOF)
return (NULL);
if (isxdigit(c)) {
d <<= 4;
d |= xdtoi(c);
d |= xdtoi((u_char)c);
c = getc(fp);
if (c == EOF)
return (NULL);
}
e.addr[i] = d;
if (c != ':')
break;
c = getc(fp);
if (c == EOF)
return (NULL);
}
if (c == EOF)
break;
/* Must be whitespace */
if (!isspace(c)) {
c = skip_line(fp);
if (c == EOF)
return (NULL);
continue;
}
c = skip_space(fp);
if (c == EOF)
return (NULL);
/* hit end of line... */
if (c == '\n')
@ -144,17 +142,21 @@ pcap_next_etherent(FILE *fp)
if (c == '#') {
c = skip_line(fp);
if (c == EOF)
return (NULL);
continue;
}
/* pick up name */
bp = e.name;
/* Use 'd' to prevent buffer overflow. */
d = sizeof(e.name) - 1;
/* Use 'namesize' to prevent buffer overflow. */
namesize = sizeof(e.name) - 1;
do {
*bp++ = c;
*bp++ = (u_char)c;
c = getc(fp);
} while (!isspace(c) && c != EOF && --d > 0);
if (c == EOF)
return (NULL);
} while (!isspace(c) && --namesize != 0);
*bp = '\0';
/* Eat trailing junk */
@ -162,8 +164,5 @@ pcap_next_etherent(FILE *fp)
(void)skip_line(fp);
return &e;
} while (c != EOF);
return (NULL);
}
}

View File

@ -23,6 +23,9 @@
#include <arpa/inet.h>
#endif
#include <pcap/pcap-inttypes.h>
#include <pcap/compiler-tests.h>
/*
* Macros to extract possibly-unaligned big-endian integral values.
*/
@ -30,15 +33,16 @@
/*
* The processor doesn't natively handle unaligned loads.
*/
#if defined(__GNUC__) && defined(HAVE___ATTRIBUTE__) && \
#if PCAP_IS_AT_LEAST_GNUC_VERSION(2,0) && \
(defined(__alpha) || defined(__alpha__) || \
defined(__mips) || defined(__mips__))
/*
* This is a GCC-compatible compiler and we have __attribute__, which
* we assume that mean we have __attribute__((packed)), and this is
* MIPS or Alpha, which has instructions that can help when doing
* unaligned loads.
* This is MIPS or Alpha, which don't natively handle unaligned loads,
* but which have instructions that can help when doing unaligned
* loads, and this is GCC 2.0 or later or a compiler that claims to
* be GCC 2.0 or later, which we assume that mean we have
* __attribute__((packed)), which we can use to convince the compiler
* to generate those instructions.
*
* Declare packed structures containing a uint16_t and a uint32_t,
* cast the pointer to point to one of those, and fetch through it;

View File

@ -33,7 +33,7 @@
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#include <config.h>
#endif
#include <sys/types.h>
@ -102,10 +102,10 @@
* all those systems we have "struct sockaddr_storage".
*/
#ifndef SA_LEN
#ifdef HAVE_SOCKADDR_SA_LEN
#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
#define SA_LEN(addr) ((addr)->sa_len)
#else /* HAVE_SOCKADDR_SA_LEN */
#ifdef HAVE_SOCKADDR_STORAGE
#else /* HAVE_STRUCT_SOCKADDR_SA_LEN */
#ifdef HAVE_STRUCT_SOCKADDR_STORAGE
static size_t
get_sa_len(struct sockaddr *addr)
{
@ -131,10 +131,10 @@ get_sa_len(struct sockaddr *addr)
}
}
#define SA_LEN(addr) (get_sa_len(addr))
#else /* HAVE_SOCKADDR_STORAGE */
#else /* HAVE_STRUCT_SOCKADDR_STORAGE */
#define SA_LEN(addr) (sizeof (struct sockaddr))
#endif /* HAVE_SOCKADDR_STORAGE */
#endif /* HAVE_SOCKADDR_SA_LEN */
#endif /* HAVE_STRUCT_SOCKADDR_STORAGE */
#endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
#endif /* SA_LEN */
/*
@ -144,10 +144,9 @@ get_sa_len(struct sockaddr *addr)
* could be opened.
*/
int
pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf,
int (*check_usable)(const char *))
pcap_findalldevs_interfaces(pcap_if_list_t *devlistp, char *errbuf,
int (*check_usable)(const char *), get_if_flags_func get_flags_func)
{
pcap_if_t *devlist = NULL;
struct ifaddrs *ifap, *ifa;
struct sockaddr *addr, *netmask, *broadaddr, *dstaddr;
size_t addr_size, broadaddr_size, dstaddr_size;
@ -169,8 +168,8 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf,
* those.
*/
if (getifaddrs(&ifap) != 0) {
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"getifaddrs: %s", pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
errno, "getifaddrs");
return (-1);
}
for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
@ -233,7 +232,7 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf,
/*
* Note that, on some platforms, ifa_broadaddr and
* ifa_dstaddr could be the same field (true on at
* least some versions of *BSD and OS X), so we
* least some versions of *BSD and macOS), so we
* can't just check whether the broadcast address
* is null and add it if so and check whether the
* destination address is null and add it if so.
@ -265,8 +264,8 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf,
/*
* Add information for this address to the list.
*/
if (add_addr_to_iflist(&devlist, ifa->ifa_name,
if_flags_to_pcap_flags(ifa->ifa_name, ifa->ifa_flags),
if (add_addr_to_if(devlistp, ifa->ifa_name, ifa->ifa_flags,
get_flags_func,
addr, addr_size, netmask, addr_size,
broadaddr, broadaddr_size, dstaddr, dstaddr_size,
errbuf) < 0) {
@ -277,16 +276,5 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf,
freeifaddrs(ifap);
if (ret == -1) {
/*
* We had an error; free the list we've been constructing.
*/
if (devlist != NULL) {
pcap_freealldevs(devlist);
devlist = NULL;
}
}
*alldevsp = devlist;
return (ret);
}

View File

@ -33,7 +33,7 @@
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#include <config.h>
#endif
#include <sys/param.h>
@ -57,6 +57,12 @@ struct rtentry; /* declarations in <net/if.h> */
#include <string.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
@ -89,11 +95,11 @@ struct rtentry; /* declarations in <net/if.h> */
* address in an entry returned by SIOCGIFCONF.
*/
#ifndef SA_LEN
#ifdef HAVE_SOCKADDR_SA_LEN
#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
#define SA_LEN(addr) ((addr)->sa_len)
#else /* HAVE_SOCKADDR_SA_LEN */
#else /* HAVE_STRUCT_SOCKADDR_SA_LEN */
#define SA_LEN(addr) (sizeof (struct sockaddr))
#endif /* HAVE_SOCKADDR_SA_LEN */
#endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
#endif /* SA_LEN */
/*
@ -132,10 +138,9 @@ struct rtentry; /* declarations in <net/if.h> */
* we already have that.
*/
int
pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf,
int (*check_usable)(const char *))
pcap_findalldevs_interfaces(pcap_if_list_t *devlistp, char *errbuf,
int (*check_usable)(const char *), get_if_flags_func get_flags_func)
{
pcap_if_t *devlist = NULL;
register int fd;
register struct ifreq *ifrp, *ifend, *ifnext;
size_t n;
@ -155,8 +160,8 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf,
*/
fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd < 0) {
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"socket: %s", pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
errno, "socket");
return (-1);
}
@ -169,10 +174,20 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf,
*/
buf_size = 8192;
for (;;) {
/*
* Don't let the buffer size get bigger than INT_MAX.
*/
if (buf_size > INT_MAX) {
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"interface information requires more than %u bytes",
INT_MAX);
(void)close(fd);
return (-1);
}
buf = malloc(buf_size);
if (buf == NULL) {
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"malloc: %s", pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
errno, "malloc");
(void)close(fd);
return (-1);
}
@ -182,13 +197,13 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf,
memset(buf, 0, buf_size);
if (ioctl(fd, SIOCGIFCONF, (char *)&ifc) < 0
&& errno != EINVAL) {
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"SIOCGIFCONF: %s", pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
errno, "SIOCGIFCONF");
(void)close(fd);
free(buf);
return (-1);
}
if (ifc.ifc_len < buf_size &&
if (ifc.ifc_len < (int)buf_size &&
(buf_size - ifc.ifc_len) > sizeof(ifrp->ifr_name) + MAX_SA_LEN)
break;
free(buf);
@ -255,11 +270,10 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf,
if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifrflags) < 0) {
if (errno == ENXIO)
continue;
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"SIOCGIFFLAGS: %.*s: %s",
pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
errno, "SIOCGIFFLAGS: %.*s",
(int)sizeof(ifrflags.ifr_name),
ifrflags.ifr_name,
pcap_strerror(errno));
ifrflags.ifr_name);
ret = -1;
break;
}
@ -279,11 +293,11 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf,
netmask = NULL;
netmask_size = 0;
} else {
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"SIOCGIFNETMASK: %.*s: %s",
pcap_fmt_errmsg_for_errno(errbuf,
PCAP_ERRBUF_SIZE, errno,
"SIOCGIFNETMASK: %.*s",
(int)sizeof(ifrnetmask.ifr_name),
ifrnetmask.ifr_name,
pcap_strerror(errno));
ifrnetmask.ifr_name);
ret = -1;
break;
}
@ -310,11 +324,11 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf,
broadaddr = NULL;
broadaddr_size = 0;
} else {
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"SIOCGIFBRDADDR: %.*s: %s",
pcap_fmt_errmsg_for_errno(errbuf,
PCAP_ERRBUF_SIZE, errno,
"SIOCGIFBRDADDR: %.*s",
(int)sizeof(ifrbroadaddr.ifr_name),
ifrbroadaddr.ifr_name,
pcap_strerror(errno));
ifrbroadaddr.ifr_name);
ret = -1;
break;
}
@ -349,11 +363,11 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf,
dstaddr = NULL;
dstaddr_size = 0;
} else {
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"SIOCGIFDSTADDR: %.*s: %s",
pcap_fmt_errmsg_for_errno(errbuf,
PCAP_ERRBUF_SIZE, errno,
"SIOCGIFDSTADDR: %.*s",
(int)sizeof(ifrdstaddr.ifr_name),
ifrdstaddr.ifr_name,
pcap_strerror(errno));
ifrdstaddr.ifr_name);
ret = -1;
break;
}
@ -401,8 +415,8 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf,
/*
* Add information for this address to the list.
*/
if (add_addr_to_iflist(&devlist, ifrp->ifr_name,
if_flags_to_pcap_flags(ifrp->ifr_name, ifrflags.ifr_flags),
if (add_addr_to_if(devlistp, ifrp->ifr_name,
ifrflags.ifr_flags, get_flags_func,
&ifrp->ifr_addr, SA_LEN(&ifrp->ifr_addr),
netmask, netmask_size, broadaddr, broadaddr_size,
dstaddr, dstaddr_size, errbuf) < 0) {
@ -413,16 +427,5 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf,
free(buf);
(void)close(fd);
if (ret == -1) {
/*
* We had an error; free the list we've been constructing.
*/
if (devlist != NULL) {
pcap_freealldevs(devlist);
devlist = NULL;
}
}
*alldevsp = devlist;
return (ret);
}

View File

@ -33,7 +33,7 @@
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#include <config.h>
#endif
#include <sys/param.h>
@ -75,10 +75,9 @@ struct rtentry; /* declarations in <net/if.h> */
* SIOCGLIFCONF rather than SIOCGIFCONF in order to get IPv6 addresses.)
*/
int
pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf,
int (*check_usable)(const char *))
pcap_findalldevs_interfaces(pcap_if_list_t *devlistp, char *errbuf,
int (*check_usable)(const char *), get_if_flags_func get_flags_func)
{
pcap_if_t *devlist = NULL;
register int fd4, fd6, fd;
register struct lifreq *ifrp, *ifend;
struct lifnum ifn;
@ -98,8 +97,8 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf,
*/
fd4 = socket(AF_INET, SOCK_DGRAM, 0);
if (fd4 < 0) {
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"socket: %s", pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
errno, "socket: AF_INET");
return (-1);
}
@ -108,8 +107,8 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf,
*/
fd6 = socket(AF_INET6, SOCK_DGRAM, 0);
if (fd6 < 0) {
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"socket: %s", pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
errno, "socket: AF_INET6");
(void)close(fd4);
return (-1);
}
@ -121,8 +120,8 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf,
ifn.lifn_flags = 0;
ifn.lifn_count = 0;
if (ioctl(fd4, SIOCGLIFNUM, (char *)&ifn) < 0) {
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"SIOCGLIFNUM: %s", pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
errno, "SIOCGLIFNUM");
(void)close(fd6);
(void)close(fd4);
return (-1);
@ -134,8 +133,8 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf,
buf_size = ifn.lifn_count * sizeof (struct lifreq);
buf = malloc(buf_size);
if (buf == NULL) {
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"malloc: %s", pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
errno, "malloc");
(void)close(fd6);
(void)close(fd4);
return (-1);
@ -150,8 +149,8 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf,
ifc.lifc_flags = 0;
memset(buf, 0, buf_size);
if (ioctl(fd4, SIOCGLIFCONF, (char *)&ifc) < 0) {
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"SIOCGLIFCONF: %s", pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
errno, "SIOCGLIFCONF");
(void)close(fd6);
(void)close(fd4);
free(buf);
@ -199,11 +198,10 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf,
if (ioctl(fd, SIOCGLIFFLAGS, (char *)&ifrflags) < 0) {
if (errno == ENXIO)
continue;
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"SIOCGLIFFLAGS: %.*s: %s",
pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
errno, "SIOCGLIFFLAGS: %.*s",
(int)sizeof(ifrflags.lifr_name),
ifrflags.lifr_name,
pcap_strerror(errno));
ifrflags.lifr_name);
ret = -1;
break;
}
@ -222,11 +220,11 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf,
*/
netmask = NULL;
} else {
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"SIOCGLIFNETMASK: %.*s: %s",
pcap_fmt_errmsg_for_errno(errbuf,
PCAP_ERRBUF_SIZE, errno,
"SIOCGLIFNETMASK: %.*s",
(int)sizeof(ifrnetmask.lifr_name),
ifrnetmask.lifr_name,
pcap_strerror(errno));
ifrnetmask.lifr_name);
ret = -1;
break;
}
@ -250,11 +248,11 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf,
*/
broadaddr = NULL;
} else {
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"SIOCGLIFBRDADDR: %.*s: %s",
pcap_fmt_errmsg_for_errno(errbuf,
PCAP_ERRBUF_SIZE, errno,
"SIOCGLIFBRDADDR: %.*s",
(int)sizeof(ifrbroadaddr.lifr_name),
ifrbroadaddr.lifr_name,
pcap_strerror(errno));
ifrbroadaddr.lifr_name);
ret = -1;
break;
}
@ -285,11 +283,11 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf,
*/
dstaddr = NULL;
} else {
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"SIOCGLIFDSTADDR: %.*s: %s",
pcap_fmt_errmsg_for_errno(errbuf,
PCAP_ERRBUF_SIZE, errno,
"SIOCGLIFDSTADDR: %.*s",
(int)sizeof(ifrdstaddr.lifr_name),
ifrdstaddr.lifr_name,
pcap_strerror(errno));
ifrdstaddr.lifr_name);
ret = -1;
break;
}
@ -329,8 +327,8 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf,
/*
* Add information for this address to the list.
*/
if (add_addr_to_iflist(&devlist, ifrp->lifr_name,
if_flags_to_pcap_flags(ifrp->lifr_name, ifrflags.lifr_flags),
if (add_addr_to_if(devlistp, ifrp->lifr_name,
ifrflags.lifr_flags, get_flags_func,
(struct sockaddr *)&ifrp->lifr_addr,
sizeof (struct sockaddr_storage),
netmask, sizeof (struct sockaddr_storage),
@ -344,16 +342,5 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf,
(void)close(fd6);
(void)close(fd4);
if (ret == -1) {
/*
* We had an error; free the list we've been constructing.
*/
if (devlist != NULL) {
pcap_freealldevs(devlist);
devlist = NULL;
}
}
*alldevsp = devlist;
return (ret);
}

View File

@ -1,884 +0,0 @@
/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */
/*
* Copyright (c) 1994, 1995, 1996, 1997, 1998
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Computer Systems
* Engineering Group at Lawrence Berkeley Laboratory.
* 4. Neither the name of the University nor of the Laboratory may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef _WIN32
#include <pcap-stdinc.h>
#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
struct mbuf; /* Squelch compiler warnings on some platforms for */
struct rtentry; /* declarations in <net/if.h> */
#include <net/if.h>
#include <netinet/in.h>
#endif /* _WIN32 */
#include <ctype.h>
#include <errno.h>
#include <memory.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if !defined(_WIN32) && !defined(__BORLANDC__)
#include <unistd.h>
#endif /* !_WIN32 && !__BORLANDC__ */
#ifdef HAVE_LIMITS_H
#include <limits.h>
#else
#define INT_MAX 2147483647
#endif
#include "pcap-int.h"
#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
#ifndef _WIN32
/* Not all systems have IFF_LOOPBACK */
#ifdef IFF_LOOPBACK
#define ISLOOPBACK(name, flags) ((flags) & IFF_LOOPBACK)
#else
#define ISLOOPBACK(name, flags) ((name)[0] == 'l' && (name)[1] == 'o' && \
(isdigit((unsigned char)((name)[2])) || (name)[2] == '\0'))
#endif
#ifdef IFF_UP
#define ISUP(flags) ((flags) & IFF_UP)
#else
#define ISUP(flags) 0
#endif
#ifdef IFF_RUNNING
#define ISRUNNING(flags) ((flags) & IFF_RUNNING)
#else
#define ISRUNNING(flags) 0
#endif
/*
* Map UN*X-style interface flags to libpcap flags.
*/
bpf_u_int32
if_flags_to_pcap_flags(const char *name _U_, u_int if_flags)
{
bpf_u_int32 pcap_flags;
pcap_flags = 0;
if (ISLOOPBACK(name, if_flags))
pcap_flags |= PCAP_IF_LOOPBACK;
if (ISUP(if_flags))
pcap_flags |= PCAP_IF_UP;
if (ISRUNNING(if_flags))
pcap_flags |= PCAP_IF_RUNNING;
return (pcap_flags);
}
#endif
static struct sockaddr *
dup_sockaddr(struct sockaddr *sa, size_t sa_length)
{
struct sockaddr *newsa;
if ((newsa = malloc(sa_length)) == NULL)
return (NULL);
return (memcpy(newsa, sa, sa_length));
}
/*
* Construct a "figure of merit" for an interface, for use when sorting
* the list of interfaces, in which interfaces that are up are superior
* to interfaces that aren't up, interfaces that are up and running are
* superior to interfaces that are up but not running, and non-loopback
* interfaces that are up and running are superior to loopback interfaces,
* and interfaces with the same flags have a figure of merit that's higher
* the lower the instance number.
*
* The goal is to try to put the interfaces most likely to be useful for
* capture at the beginning of the list.
*
* The figure of merit, which is lower the "better" the interface is,
* has the uppermost bit set if the interface isn't running, the bit
* below that set if the interface isn't up, the bit below that set
* if the interface is a loopback interface, and the interface index
* in the 29 bits below that. (Yes, we assume u_int is 32 bits.)
*/
static u_int
get_figure_of_merit(pcap_if_t *dev)
{
const char *cp;
u_int n;
if (strcmp(dev->name, "any") == 0) {
/*
* Give the "any" device an artificially high instance
* number, so it shows up after all other non-loopback
* interfaces.
*/
n = 0x1FFFFFFF; /* 29 all-1 bits */
} else {
/*
* A number at the end of the device name string is
* assumed to be a unit number.
*/
cp = dev->name + strlen(dev->name) - 1;
while (cp-1 >= dev->name && *(cp-1) >= '0' && *(cp-1) <= '9')
cp--;
if (*cp >= '0' && *cp <= '9')
n = atoi(cp);
else
n = 0;
}
if (!(dev->flags & PCAP_IF_RUNNING))
n |= 0x80000000;
if (!(dev->flags & PCAP_IF_UP))
n |= 0x40000000;
if (dev->flags & PCAP_IF_LOOPBACK)
n |= 0x20000000;
return (n);
}
/*
* Try to get a description for a given device.
* Returns a mallocated description if it could and NULL if it couldn't.
*
* XXX - on FreeBSDs that support it, should it get the sysctl named
* "dev.{adapter family name}.{adapter unit}.%desc" to get a description
* of the adapter? Note that "dev.an.0.%desc" is "Aironet PC4500/PC4800"
* with my Cisco 350 card, so the name isn't entirely descriptive. The
* "dev.an.0.%pnpinfo" has a better description, although one might argue
* that the problem is really a driver bug - if it can find out that it's
* a Cisco 340 or 350, rather than an old Aironet card, it should use
* that in the description.
*
* Do NetBSD, DragonflyBSD, or OpenBSD support this as well? FreeBSD
* and OpenBSD let you get a description, but it's not generated by the OS,
* it's set with another ioctl that ifconfig supports; we use that to get
* a description in FreeBSD and OpenBSD, but if there is no such
* description available, it still might be nice to get some description
* string based on the device type or something such as that.
*
* In OS X, the System Configuration framework can apparently return
* names in 10.4 and later.
*
* It also appears that freedesktop.org's HAL offers an "info.product"
* string, but the HAL specification says it "should not be used in any
* UI" and "subsystem/capability specific properties" should be used
* instead and, in any case, I think HAL is being deprecated in
* favor of other stuff such as DeviceKit. DeviceKit doesn't appear
* to have any obvious product information for devices, but maybe
* I haven't looked hard enough.
*
* Using the System Configuration framework, or HAL, or DeviceKit, or
* whatever, would require that libpcap applications be linked with
* the frameworks/libraries in question. That shouldn't be a problem
* for programs linking with the shared version of libpcap (unless
* you're running on AIX - which I think is the only UN*X that doesn't
* support linking a shared library with other libraries on which it
* depends, and having an executable linked only with the first shared
* library automatically pick up the other libraries when started -
* and using HAL or whatever). Programs linked with the static
* version of libpcap would have to use pcap-config with the --static
* flag in order to get the right linker flags in order to pick up
* the additional libraries/frameworks; those programs need that anyway
* for libpcap 1.1 and beyond on Linux, as, by default, it requires
* -lnl.
*
* Do any other UN*Xes, or desktop environments support getting a
* description?
*/
static char *
get_if_description(const char *name)
{
#ifdef SIOCGIFDESCR
char *description = NULL;
int s;
struct ifreq ifrdesc;
#ifndef IFDESCRSIZE
size_t descrlen = 64;
#else
size_t descrlen = IFDESCRSIZE;
#endif /* IFDESCRSIZE */
/*
* Get the description for the interface.
*/
memset(&ifrdesc, 0, sizeof ifrdesc);
strlcpy(ifrdesc.ifr_name, name, sizeof ifrdesc.ifr_name);
s = socket(AF_INET, SOCK_DGRAM, 0);
if (s >= 0) {
#ifdef __FreeBSD__
/*
* On FreeBSD, if the buffer isn't big enough for the
* description, the ioctl succeeds, but the description
* isn't copied, ifr_buffer.length is set to the description
* length, and ifr_buffer.buffer is set to NULL.
*/
for (;;) {
free(description);
if ((description = malloc(descrlen)) != NULL) {
ifrdesc.ifr_buffer.buffer = description;
ifrdesc.ifr_buffer.length = descrlen;
if (ioctl(s, SIOCGIFDESCR, &ifrdesc) == 0) {
if (ifrdesc.ifr_buffer.buffer ==
description)
break;
else
descrlen = ifrdesc.ifr_buffer.length;
} else {
/*
* Failed to get interface description.
*/
free(description);
description = NULL;
break;
}
} else
break;
}
#else /* __FreeBSD__ */
/*
* The only other OS that currently supports
* SIOCGIFDESCR is OpenBSD, and it has no way
* to get the description length - it's clamped
* to a maximum of IFDESCRSIZE.
*/
if ((description = malloc(descrlen)) != NULL) {
ifrdesc.ifr_data = (caddr_t)description;
if (ioctl(s, SIOCGIFDESCR, &ifrdesc) != 0) {
/*
* Failed to get interface description.
*/
free(description);
description = NULL;
}
}
#endif /* __FreeBSD__ */
close(s);
if (description != NULL && strlen(description) == 0) {
/*
* Description is empty, so discard it.
*/
free(description);
description = NULL;
}
}
#ifdef __FreeBSD__
/*
* For FreeBSD, if we didn't get a description, and this is
* a device with a name of the form usbusN, label it as a USB
* bus.
*/
if (description == NULL) {
if (strncmp(name, "usbus", 5) == 0) {
/*
* OK, it begins with "usbus".
*/
long busnum;
char *p;
errno = 0;
busnum = strtol(name + 5, &p, 10);
if (errno == 0 && p != name + 5 && *p == '\0' &&
busnum >= 0 && busnum <= INT_MAX) {
/*
* OK, it's a valid number that's not
* bigger than INT_MAX. Construct
* a description from it.
*/
static const char descr_prefix[] = "USB bus number ";
size_t descr_size;
/*
* Allow enough room for a 32-bit bus number.
* sizeof (descr_prefix) includes the
* terminating NUL.
*/
descr_size = sizeof (descr_prefix) + 10;
description = malloc(descr_size);
if (description != NULL) {
pcap_snprintf(description, descr_size,
"%s%ld", descr_prefix, busnum);
}
}
}
}
#endif
return (description);
#else /* SIOCGIFDESCR */
return (NULL);
#endif /* SIOCGIFDESCR */
}
/*
* Look for a given device in the specified list of devices.
*
* If we find it, return 0 and set *curdev_ret to point to it.
*
* If we don't find it, check whether we can open it:
*
* If that fails with PCAP_ERROR_NO_SUCH_DEVICE or
* PCAP_ERROR_IFACE_NOT_UP, don't attempt to add an entry for
* it, as that probably means it exists but doesn't support
* packet capture.
*
* Otherwise, attempt to add an entry for it, with the specified
* ifnet flags and description, and, if that succeeds, return 0
* and set *curdev_ret to point to the new entry, otherwise
* return PCAP_ERROR and set errbuf to an error message. If we
* weren't given a description, try to get one.
*/
int
add_or_find_if(pcap_if_t **curdev_ret, pcap_if_t **alldevs, const char *name,
bpf_u_int32 flags, const char *description, char *errbuf)
{
pcap_t *p;
pcap_if_t *curdev, *prevdev, *nextdev;
u_int this_figure_of_merit, nextdev_figure_of_merit;
char open_errbuf[PCAP_ERRBUF_SIZE];
int ret;
/*
* Is there already an entry in the list for this interface?
*/
for (curdev = *alldevs; curdev != NULL; curdev = curdev->next) {
if (strcmp(name, curdev->name) == 0)
break; /* yes, we found it */
}
if (curdev == NULL) {
/*
* No, we didn't find it.
*
* Can we open this interface for live capture?
*
* We do this check so that interfaces that are
* supplied by the interface enumeration mechanism
* we're using but that don't support packet capture
* aren't included in the list. Loopback interfaces
* on Solaris are an example of this; we don't just
* omit loopback interfaces on all platforms because
* you *can* capture on loopback interfaces on some
* OSes.
*
* On OS X, we don't do this check if the device
* name begins with "wlt"; at least some versions
* of OS X offer monitor mode capturing by having
* a separate "monitor mode" device for each wireless
* adapter, rather than by implementing the ioctls
* that {Free,Net,Open,DragonFly}BSD provide.
* Opening that device puts the adapter into monitor
* mode, which, at least for some adapters, causes
* them to deassociate from the network with which
* they're associated.
*
* Instead, we try to open the corresponding "en"
* device (so that we don't end up with, for users
* without sufficient privilege to open capture
* devices, a list of adapters that only includes
* the wlt devices).
*/
#ifdef __APPLE__
if (strncmp(name, "wlt", 3) == 0) {
char *en_name;
size_t en_name_len;
/*
* Try to allocate a buffer for the "en"
* device's name.
*/
en_name_len = strlen(name) - 1;
en_name = malloc(en_name_len + 1);
if (en_name == NULL) {
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"malloc: %s", pcap_strerror(errno));
return (-1);
}
strcpy(en_name, "en");
strcat(en_name, name + 3);
p = pcap_create(en_name, open_errbuf);
free(en_name);
} else
#endif /* __APPLE */
p = pcap_create(name, open_errbuf);
if (p == NULL) {
/*
* The attempt to create the pcap_t failed;
* that's probably an indication that we're
* out of memory.
*
* Don't bother including this interface,
* but don't treat it as an error.
*/
*curdev_ret = NULL;
return (0);
}
/* Small snaplen, so we don't try to allocate much memory. */
pcap_set_snaplen(p, 68);
ret = pcap_activate(p);
pcap_close(p);
switch (ret) {
case PCAP_ERROR_NO_SUCH_DEVICE:
case PCAP_ERROR_IFACE_NOT_UP:
/*
* We expect these two errors - they're the
* reason we try to open the device.
*
* PCAP_ERROR_NO_SUCH_DEVICE typically means
* "there's no such device *known to the
* OS's capture mechanism*", so, even though
* it might be a valid network interface, you
* can't capture on it (e.g., the loopback
* device in Solaris up to Solaris 10, or
* the vmnet devices in OS X with VMware
* Fusion). We don't include those devices
* in our list of devices, as there's no
* point in doing so - they're not available
* for capture.
*
* PCAP_ERROR_IFACE_NOT_UP means that the
* OS's capture mechanism doesn't work on
* interfaces not marked as up; some capture
* mechanisms *do* support that, so we no
* longer reject those interfaces out of hand,
* but we *do* want to reject them if they
* can't be opened for capture.
*/
*curdev_ret = NULL;
return (0);
}
/*
* Yes, we can open it, or we can't, for some other
* reason.
*
* If we can open it, we want to offer it for
* capture, as you can capture on it. If we can't,
* we want to offer it for capture, so that, if
* the user tries to capture on it, they'll get
* an error and they'll know why they can't
* capture on it (e.g., insufficient permissions)
* or they'll report it as a problem (and then
* have the error message to provide as information).
*
* Allocate a new entry.
*/
curdev = malloc(sizeof(pcap_if_t));
if (curdev == NULL) {
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"malloc: %s", pcap_strerror(errno));
return (-1);
}
/*
* Fill in the entry.
*/
curdev->next = NULL;
curdev->name = strdup(name);
if (curdev->name == NULL) {
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"malloc: %s", pcap_strerror(errno));
free(curdev);
return (-1);
}
if (description == NULL) {
/*
* We weren't handed a description for the
* interface, so see if we can generate one
* ourselves.
*/
curdev->description = get_if_description(name);
} else {
/*
* We were handed a description; make a copy.
*/
curdev->description = strdup(description);
if (curdev->description == NULL) {
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"malloc: %s", pcap_strerror(errno));
free(curdev->name);
free(curdev);
return (-1);
}
}
curdev->addresses = NULL; /* list starts out as empty */
curdev->flags = flags;
/*
* Add it to the list, in the appropriate location.
* First, get the "figure of merit" for this
* interface.
*/
this_figure_of_merit = get_figure_of_merit(curdev);
/*
* Now look for the last interface with an figure of merit
* less than or equal to the new interface's figure of
* merit.
*
* We start with "prevdev" being NULL, meaning we're before
* the first element in the list.
*/
prevdev = NULL;
for (;;) {
/*
* Get the interface after this one.
*/
if (prevdev == NULL) {
/*
* The next element is the first element.
*/
nextdev = *alldevs;
} else
nextdev = prevdev->next;
/*
* Are we at the end of the list?
*/
if (nextdev == NULL) {
/*
* Yes - we have to put the new entry
* after "prevdev".
*/
break;
}
/*
* Is the new interface's figure of merit less
* than the next interface's figure of merit,
* meaning that the new interface is better
* than the next interface?
*/
nextdev_figure_of_merit = get_figure_of_merit(nextdev);
if (this_figure_of_merit < nextdev_figure_of_merit) {
/*
* Yes - we should put the new entry
* before "nextdev", i.e. after "prevdev".
*/
break;
}
prevdev = nextdev;
}
/*
* Insert before "nextdev".
*/
curdev->next = nextdev;
/*
* Insert after "prevdev" - unless "prevdev" is null,
* in which case this is the first interface.
*/
if (prevdev == NULL) {
/*
* This is the first interface. Pass back a
* pointer to it, and put "curdev" before
* "nextdev".
*/
*alldevs = curdev;
} else
prevdev->next = curdev;
}
*curdev_ret = curdev;
return (0);
}
/*
* Try to get a description for a given device, and then look for that
* device in the specified list of devices.
*
* If we find it, then, if the specified address isn't null, add it to
* the list of addresses for the device and return 0.
*
* If we don't find it, check whether we can open it:
*
* If that fails with PCAP_ERROR_NO_SUCH_DEVICE or
* PCAP_ERROR_IFACE_NOT_UP, don't attempt to add an entry for
* it, as that probably means it exists but doesn't support
* packet capture.
*
* Otherwise, attempt to add an entry for it, with the specified
* ifnet flags, and, if that succeeds, add the specified address
* to its list of addresses if that address is non-null, set
* *curdev_ret to point to the new entry, and return 0, otherwise
* return PCAP_ERROR and set errbuf to an error message.
*
* (We can get called with a null address because we might get a list
* of interface name/address combinations from the underlying OS, with
* the address being absent in some cases, rather than a list of
* interfaces with each interface having a list of addresses, so this
* call may be the only call made to add to the list, and we want to
* add interfaces even if they have no addresses.)
*/
int
add_addr_to_iflist(pcap_if_t **alldevs, const char *name, bpf_u_int32 flags,
struct sockaddr *addr, size_t addr_size,
struct sockaddr *netmask, size_t netmask_size,
struct sockaddr *broadaddr, size_t broadaddr_size,
struct sockaddr *dstaddr, size_t dstaddr_size,
char *errbuf)
{
pcap_if_t *curdev;
if (add_or_find_if(&curdev, alldevs, name, flags, NULL, errbuf) == -1) {
/*
* Error - give up.
*/
return (-1);
}
if (curdev == NULL) {
/*
* Device wasn't added because it can't be opened.
* Not a fatal error.
*/
return (0);
}
if (addr == NULL) {
/*
* There's no address to add; this entry just meant
* "here's a new interface".
*/
return (0);
}
/*
* "curdev" is an entry for this interface, and we have an
* address for it; add an entry for that address to the
* interface's list of addresses.
*
* Allocate the new entry and fill it in.
*/
return (add_addr_to_dev(curdev, addr, addr_size, netmask,
netmask_size, broadaddr, broadaddr_size, dstaddr,
dstaddr_size, errbuf));
}
/*
* Add an entry to the list of addresses for an interface.
* "curdev" is the entry for that interface.
* If this is the first IP address added to the interface, move it
* in the list as appropriate.
*/
int
add_addr_to_dev(pcap_if_t *curdev,
struct sockaddr *addr, size_t addr_size,
struct sockaddr *netmask, size_t netmask_size,
struct sockaddr *broadaddr, size_t broadaddr_size,
struct sockaddr *dstaddr, size_t dstaddr_size,
char *errbuf)
{
pcap_addr_t *curaddr, *prevaddr, *nextaddr;
curaddr = malloc(sizeof(pcap_addr_t));
if (curaddr == NULL) {
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"malloc: %s", pcap_strerror(errno));
return (-1);
}
curaddr->next = NULL;
if (addr != NULL) {
curaddr->addr = dup_sockaddr(addr, addr_size);
if (curaddr->addr == NULL) {
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"malloc: %s", pcap_strerror(errno));
free(curaddr);
return (-1);
}
} else
curaddr->addr = NULL;
if (netmask != NULL) {
curaddr->netmask = dup_sockaddr(netmask, netmask_size);
if (curaddr->netmask == NULL) {
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"malloc: %s", pcap_strerror(errno));
if (curaddr->addr != NULL)
free(curaddr->addr);
free(curaddr);
return (-1);
}
} else
curaddr->netmask = NULL;
if (broadaddr != NULL) {
curaddr->broadaddr = dup_sockaddr(broadaddr, broadaddr_size);
if (curaddr->broadaddr == NULL) {
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"malloc: %s", pcap_strerror(errno));
if (curaddr->netmask != NULL)
free(curaddr->netmask);
if (curaddr->addr != NULL)
free(curaddr->addr);
free(curaddr);
return (-1);
}
} else
curaddr->broadaddr = NULL;
if (dstaddr != NULL) {
curaddr->dstaddr = dup_sockaddr(dstaddr, dstaddr_size);
if (curaddr->dstaddr == NULL) {
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"malloc: %s", pcap_strerror(errno));
if (curaddr->broadaddr != NULL)
free(curaddr->broadaddr);
if (curaddr->netmask != NULL)
free(curaddr->netmask);
if (curaddr->addr != NULL)
free(curaddr->addr);
free(curaddr);
return (-1);
}
} else
curaddr->dstaddr = NULL;
/*
* Find the end of the list of addresses.
*/
for (prevaddr = curdev->addresses; prevaddr != NULL; prevaddr = nextaddr) {
nextaddr = prevaddr->next;
if (nextaddr == NULL) {
/*
* This is the end of the list.
*/
break;
}
}
if (prevaddr == NULL) {
/*
* The list was empty; this is the first member.
*/
curdev->addresses = curaddr;
} else {
/*
* "prevaddr" is the last member of the list; append
* this member to it.
*/
prevaddr->next = curaddr;
}
return (0);
}
/*
* Look for a given device in the specified list of devices.
*
* If we find it, return 0.
*
* If we don't find it, check whether we can open it:
*
* If that fails with PCAP_ERROR_NO_SUCH_DEVICE or
* PCAP_ERROR_IFACE_NOT_UP, don't attempt to add an entry for
* it, as that probably means it exists but doesn't support
* packet capture.
*
* Otherwise, attempt to add an entry for it, with the specified
* ifnet flags and description, and, if that succeeds, return 0
* and set *curdev_ret to point to the new entry, otherwise
* return PCAP_ERROR and set errbuf to an error message.
*/
int
pcap_add_if(pcap_if_t **devlist, const char *name, u_int flags,
const char *description, char *errbuf)
{
pcap_if_t *curdev;
return (add_or_find_if(&curdev, devlist, name, flags, description,
errbuf));
}
/*
* Free a list of interfaces.
*/
void
pcap_freealldevs(pcap_if_t *alldevs)
{
pcap_if_t *curdev, *nextdev;
pcap_addr_t *curaddr, *nextaddr;
for (curdev = alldevs; curdev != NULL; curdev = nextdev) {
nextdev = curdev->next;
/*
* Free all addresses.
*/
for (curaddr = curdev->addresses; curaddr != NULL; curaddr = nextaddr) {
nextaddr = curaddr->next;
if (curaddr->addr)
free(curaddr->addr);
if (curaddr->netmask)
free(curaddr->netmask);
if (curaddr->broadaddr)
free(curaddr->broadaddr);
if (curaddr->dstaddr)
free(curaddr->dstaddr);
free(curaddr);
}
/*
* Free the name string.
*/
free(curdev->name);
/*
* Free the description string, if any.
*/
if (curdev->description != NULL)
free(curdev->description);
/*
* Free the interface.
*/
free(curdev);
}
}

131
fmtutils.c Normal file
View File

@ -0,0 +1,131 @@
/*
* Copyright (c) 1993, 1994, 1995, 1996, 1997, 1998
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Computer Systems
* Engineering Group at Lawrence Berkeley Laboratory.
* 4. Neither the name of the University nor of the Laboratory may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Utilities for message formatting used both by libpcap and rpcapd.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "ftmacros.h"
#include <stddef.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <pcap/pcap.h>
#include "portability.h"
#include "fmtutils.h"
/*
* Generate an error message based on a format, arguments, and an
* errno, with a message for the errno after the formatted output.
*/
void
pcap_fmt_errmsg_for_errno(char *errbuf, size_t errbuflen, int errnum,
const char *fmt, ...)
{
va_list ap;
size_t msglen;
char *p;
size_t errbuflen_remaining;
#if defined(HAVE_STRERROR_S)
errno_t err;
#elif defined(HAVE_STRERROR_R)
int err;
#endif
va_start(ap, fmt);
pcap_vsnprintf(errbuf, errbuflen, fmt, ap);
va_end(ap);
msglen = strlen(errbuf);
/*
* Do we have enough space to append ": "?
* Including the terminating '\0', that's 3 bytes.
*/
if (msglen + 3 > errbuflen) {
/* No - just give them what we've produced. */
return;
}
p = errbuf + msglen;
errbuflen_remaining = errbuflen - msglen;
*p++ = ':';
*p++ = ' ';
*p = '\0';
msglen += 2;
errbuflen_remaining -= 2;
/*
* Now append the string for the error code.
*/
#if defined(HAVE_STRERROR_S)
err = strerror_s(p, errbuflen_remaining, errnum);
if (err != 0) {
/*
* It doesn't appear to be documented anywhere obvious
* what the error returns from strerror_s().
*/
pcap_snprintf(p, errbuflen_remaining, "Error %d", errnum);
}
#elif defined(HAVE_STRERROR_R)
err = strerror_r(errnum, p, errbuflen_remaining);
if (err == EINVAL) {
/*
* UNIX 03 says this isn't guaranteed to produce a
* fallback error message.
*/
pcap_snprintf(p, errbuflen_remaining, "Unknown error: %d",
errnum);
} else if (err == ERANGE) {
/*
* UNIX 03 says this isn't guaranteed to produce a
* fallback error message.
*/
pcap_snprintf(p, errbuflen_remaining,
"Message for error %d is too long", errnum);
}
#else
/*
* We have neither strerror_s() nor strerror_r(), so we're
* stuck with using pcap_strerror().
*/
pcap_snprintf(p, errbuflen_remaining, "%s", pcap_strerror(errnum));
#endif
}

50
fmtutils.h Normal file
View File

@ -0,0 +1,50 @@
/*
* Copyright (c) 1994, 1995, 1996
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Computer Systems
* Engineering Group at Lawrence Berkeley Laboratory.
* 4. Neither the name of the University nor of the Laboratory may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef fmtutils_h
#define fmtutils_h
#include "pcap/funcattrs.h"
#ifdef __cplusplus
extern "C" {
#endif
void pcap_fmt_errmsg_for_errno(char *, size_t, int,
PCAP_FORMAT_STRING(const char *), ...) PCAP_PRINTFLIKE(4, 5);
#ifdef __cplusplus
}
#endif
#endif

115
ftmacros.h Normal file
View File

@ -0,0 +1,115 @@
/*
* Copyright (c) 1994, 1995, 1996
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Computer Systems
* Engineering Group at Lawrence Berkeley Laboratory.
* 4. Neither the name of the University nor of the Laboratory may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef ftmacros_h
#define ftmacros_h
/*
* Define some feature test macros to make sure that everything we want
* to be declared gets declared.
*
* On some UN*Xes we need to force strtok_r() to be declared.
* We do *NOT* want to define _POSIX_C_SOURCE, as that tends
* to make non-POSIX APIs that we use unavailable.
* XXX - is there no portable way to say "please pollute the
* namespace to the maximum extent possible"?
*/
#if defined(sun) || defined(__sun)
#define __EXTENSIONS__
/*
* We also need to define _XPG4_2 in order to get
* the Single UNIX Specification version of
* recvmsg().
*/
#define _XPG4_2
#elif defined(_hpux) || defined(hpux) || defined(__hpux)
#define _REENTRANT
/*
* We need this to get the versions of socket functions that
* use socklen_t. Define it only if it's not already defined,
* so we don't get redefiniton warnings.
*/
#ifndef _XOPEN_SOURCE_EXTENDED
#define _XOPEN_SOURCE_EXTENDED
#endif
/*
* XXX - the list of PA-RISC options for GCC makes it sound as if
* building code that uses a particular vintage of UNIX API/ABI
* is complicated:
*
* https://gcc.gnu.org/onlinedocs/gcc/HPPA-Options.html
*
* See the description of the -munix flag.
*
* We probably want libpcap to work with programs built for any
* UN*X standard. I'm not sure whether that's possible and, if
* it is, what sort of stuff it'd have to do.
*
* It might also be a requirement that we build with a special
* flag to allow the library to be used with threaded code, at
* least with HP's C compiler; hopefully doing so won't make it
* *not* work with *un*-threaded code.
*/
#elif defined(__linux__) || defined(linux) || defined(__linux)
/*
* We can't turn _GNU_SOURCE on because some versions of GNU Libc
* will give the GNU version of strerror_r(), which returns a
* string pointer and doesn't necessarily fill in the buffer,
* rather than the standard version of strerror_r(), which
* returns 0 or an errno and always fills in the buffer. We
* require both of the latter behaviors.
*
* So we try turning everything else on that we can. This includes
* defining _XOPEN_SOURCE as 600, because we want to force crypt()
* to be declared on systems that use GNU libc, such as most Linux
* distributions.
*/
#define _POSIX_C_SOURCE 200809L
#define _XOPEN_SOURCE 600
/*
* We turn on both _DEFAULT_SOURCE and _BSD_SOURCE to try to get
* the BSD u_XXX types, such as u_int and u_short, defined. We
* define _DEFAULT_SOURCE first, so that newer versions of GNU libc
* don't whine about _BSD_SOURCE being deprecated; we still have
* to define _BSD_SOURCE to handle older versions of GNU libc that
* don't support _DEFAULT_SOURCE.
*/
#define _DEFAULT_SOURCE
#define _BSD_SOURCE
#endif
#endif

View File

@ -1,11 +0,0 @@
#! /bin/sh
echo '#include <pcap/export-defs.h>' > "$2"
echo 'PCAP_API_DEF' >> "$2"
if grep GIT "$1" >/dev/null; then
read ver <"$1"
echo $ver | tr -d '\012'
date +_%Y_%m_%d
else
cat "$1"
fi | sed -e 's/.*/char pcap_version[] = "&";/' >> "$2"

View File

@ -1,19 +0,0 @@
#! /bin/sh
print_version_string()
{
if grep GIT "$1" >/dev/null
then
read ver <"$1"
echo $ver | tr -d '\012'
date +_%Y_%m_%d
else
cat "$1"
fi
}
if test $# != 3
then
echo "Usage: gen_version_header.sh <version file> <template> <output file>" 1>&2
exit 1
fi
version_string=`print_version_string "$1"`
sed "s/%%LIBPCAP_VERSION%%/$version_string/" "$2" >"$3"

807
gencode.c

File diff suppressed because it is too large Load Diff

View File

@ -19,6 +19,8 @@
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#include "pcap/funcattrs.h"
/*
* ATM support:
*
@ -53,10 +55,6 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef HAVE___ATTRIBUTE__
#define __attribute__(x)
#endif /* HAVE___ATTRIBUTE__ */
/* Address qualifiers. */
#define Q_HOST 1
@ -268,6 +266,11 @@ struct block {
int val[N_ATOMS];
};
/*
* A value of 0 for val[i] means the value is unknown.
*/
#define VAL_UNKNOWN 0
struct arth {
struct block *b; /* protocol checks */
struct slist *s; /* stmt list */
@ -340,11 +343,29 @@ struct block *gen_mtp2type_abbrev(compiler_state_t *, int type);
struct block *gen_mtp3field_code(compiler_state_t *, int, bpf_u_int32,
bpf_u_int32, int);
#ifndef HAVE_NET_PFVAR_H
PCAP_NORETURN
#endif
struct block *gen_pf_ifname(compiler_state_t *, const char *);
#ifndef HAVE_NET_PFVAR_H
PCAP_NORETURN
#endif
struct block *gen_pf_rnr(compiler_state_t *, int);
#ifndef HAVE_NET_PFVAR_H
PCAP_NORETURN
#endif
struct block *gen_pf_srnr(compiler_state_t *, int);
#ifndef HAVE_NET_PFVAR_H
PCAP_NORETURN
#endif
struct block *gen_pf_ruleset(compiler_state_t *, char *);
#ifndef HAVE_NET_PFVAR_H
PCAP_NORETURN
#endif
struct block *gen_pf_reason(compiler_state_t *, int);
#ifndef HAVE_NET_PFVAR_H
PCAP_NORETURN
#endif
struct block *gen_pf_action(compiler_state_t *, int);
struct block *gen_p80211_type(compiler_state_t *, int, int);
@ -366,20 +387,13 @@ struct icode {
};
void bpf_optimize(compiler_state_t *, struct icode *ic);
void bpf_syntax_error(compiler_state_t *, const char *);
void bpf_error(compiler_state_t *, const char *, ...)
__attribute__((noreturn))
#ifdef __ATTRIBUTE___FORMAT_OK
__attribute__((format (printf, 2, 3)))
#endif /* __ATTRIBUTE___FORMAT_OK */
;
void PCAP_NORETURN bpf_syntax_error(compiler_state_t *, const char *);
void PCAP_NORETURN bpf_error(compiler_state_t *, const char *, ...)
PCAP_PRINTFLIKE(2, 3);
void finish_parse(compiler_state_t *, struct block *);
char *sdup(compiler_state_t *, const char *);
struct _opt_state;
typedef struct _opt_state opt_state_t;
struct bpf_insn *icode_to_fcode(compiler_state_t *, struct icode *,
struct block *, u_int *);
void sappend(struct slist *, struct slist *);

View File

@ -21,7 +21,7 @@
/*
* And we need to pass the compiler state to the scanner.
*/
%parse-param {compiler_state_t *cstate}
%parse-param { compiler_state_t *cstate }
%{
/*
@ -47,19 +47,15 @@
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#include <config.h>
#endif
#ifdef _WIN32
#include <pcap-stdinc.h>
#else /* _WIN32 */
#include <sys/types.h>
#include <sys/socket.h>
#endif /* _WIN32 */
#include <stdlib.h>
#ifndef _WIN32
#include <sys/types.h>
#include <sys/socket.h>
#if __STDC__
struct mbuf;
struct rtentry;
@ -71,6 +67,8 @@ struct rtentry;
#include <stdio.h>
#include "diag-control.h"
#include "pcap-int.h"
#include "gencode.h"
@ -90,9 +88,30 @@ struct rtentry;
#include "os-proto.h"
#endif
#define QSET(q, p, d, a) (q).proto = (p),\
(q).dir = (d),\
(q).addr = (a)
#ifdef YYBYACC
/*
* Both Berkeley YACC and Bison define yydebug (under whatever name
* it has) as a global, but Bison does so only if YYDEBUG is defined.
* Berkeley YACC define it even if YYDEBUG isn't defined; declare it
* here to suppress a warning.
*/
#if !defined(YYDEBUG)
extern int yydebug;
#endif
/*
* In Berkeley YACC, yynerrs (under whatever name it has) is global,
* even if it's building a reentrant parser. In Bison, it's local
* in reentrant parsers.
*
* Declare it to squelch a warning.
*/
extern int yynerrs;
#endif
#define QSET(q, p, d, a) (q).proto = (unsigned char)(p),\
(q).dir = (unsigned char)(d),\
(q).addr = (unsigned char)(a)
struct tok {
int v; /* value */
@ -199,8 +218,8 @@ str2tok(const char *str, const struct tok *toks)
static struct qual qerr = { Q_UNDEF, Q_UNDEF, Q_UNDEF, Q_UNDEF };
static void
yyerror(void *yyscanner, compiler_state_t *cstate, const char *msg)
static PCAP_NORETURN_DEF void
yyerror(void *yyscanner _U_, compiler_state_t *cstate, const char *msg)
{
bpf_syntax_error(cstate, msg);
/* NOTREACHED */
@ -246,26 +265,22 @@ pfaction_to_num(compiler_state_t *cstate, const char *action)
}
}
#else /* !HAVE_NET_PFVAR_H */
static int
pfreason_to_num(compiler_state_t *cstate, const char *reason)
static PCAP_NORETURN_DEF int
pfreason_to_num(compiler_state_t *cstate, const char *reason _U_)
{
bpf_error(cstate, "libpcap was compiled on a machine without pf support");
/*NOTREACHED*/
/* this is to make the VC compiler happy */
return -1;
}
static int
pfaction_to_num(compiler_state_t *cstate, const char *action)
static PCAP_NORETURN_DEF int
pfaction_to_num(compiler_state_t *cstate, const char *action _U_)
{
bpf_error(cstate, "libpcap was compiled on a machine without pf support");
/*NOTREACHED*/
/* this is to make the VC compiler happy */
return -1;
}
#endif /* HAVE_NET_PFVAR_H */
DIAG_OFF_BISON_BYACC
%}
%union {

403
inet.c
View File

@ -1,403 +0,0 @@
/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */
/*
* Copyright (c) 1994, 1995, 1996, 1997, 1998
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Computer Systems
* Engineering Group at Lawrence Berkeley Laboratory.
* 4. Neither the name of the University nor of the Laboratory may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef _WIN32
#include <pcap-stdinc.h>
#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
struct mbuf; /* Squelch compiler warnings on some platforms for */
struct rtentry; /* declarations in <net/if.h> */
#include <net/if.h>
#include <netinet/in.h>
#endif /* _WIN32 */
#include <errno.h>
#include <memory.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if !defined(_WIN32) && !defined(__BORLANDC__)
#include <unistd.h>
#endif /* !_WIN32 && !__BORLANDC__ */
#include "pcap-int.h"
#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
#if !defined(_WIN32) && !defined(MSDOS)
/*
* Return the name of a network interface attached to the system, or NULL
* if none can be found. The interface must be configured up; the
* lowest unit number is preferred; loopback is ignored.
*/
char *
pcap_lookupdev(errbuf)
register char *errbuf;
{
pcap_if_t *alldevs;
/* for old BSD systems, including bsdi3 */
#ifndef IF_NAMESIZE
#define IF_NAMESIZE IFNAMSIZ
#endif
static char device[IF_NAMESIZE + 1];
char *ret;
if (pcap_findalldevs(&alldevs, errbuf) == -1)
return (NULL);
if (alldevs == NULL || (alldevs->flags & PCAP_IF_LOOPBACK)) {
/*
* There are no devices on the list, or the first device
* on the list is a loopback device, which means there
* are no non-loopback devices on the list. This means
* we can't return any device.
*
* XXX - why not return a loopback device? If we can't
* capture on it, it won't be on the list, and if it's
* on the list, there aren't any non-loopback devices,
* so why not just supply it as the default device?
*/
(void)strlcpy(errbuf, "no suitable device found",
PCAP_ERRBUF_SIZE);
ret = NULL;
} else {
/*
* Return the name of the first device on the list.
*/
(void)strlcpy(device, alldevs->name, sizeof(device));
ret = device;
}
pcap_freealldevs(alldevs);
return (ret);
}
int
pcap_lookupnet(device, netp, maskp, errbuf)
register const char *device;
register bpf_u_int32 *netp, *maskp;
register char *errbuf;
{
register int fd;
register struct sockaddr_in *sin4;
struct ifreq ifr;
/*
* The pseudo-device "any" listens on all interfaces and therefore
* has the network address and -mask "0.0.0.0" therefore catching
* all traffic. Using NULL for the interface is the same as "any".
*/
if (!device || strcmp(device, "any") == 0
#ifdef HAVE_DAG_API
|| strstr(device, "dag") != NULL
#endif
#ifdef HAVE_SEPTEL_API
|| strstr(device, "septel") != NULL
#endif
#ifdef PCAP_SUPPORT_BT
|| strstr(device, "bluetooth") != NULL
#endif
#ifdef PCAP_SUPPORT_USB
|| strstr(device, "usbmon") != NULL
#endif
#ifdef HAVE_SNF_API
|| strstr(device, "snf") != NULL
#endif
) {
*netp = *maskp = 0;
return 0;
}
fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd < 0) {
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "socket: %s",
pcap_strerror(errno));
return (-1);
}
memset(&ifr, 0, sizeof(ifr));
#ifdef linux
/* XXX Work around Linux kernel bug */
ifr.ifr_addr.sa_family = AF_INET;
#endif
(void)strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
if (ioctl(fd, SIOCGIFADDR, (char *)&ifr) < 0) {
if (errno == EADDRNOTAVAIL) {
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"%s: no IPv4 address assigned", device);
} else {
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"SIOCGIFADDR: %s: %s",
device, pcap_strerror(errno));
}
(void)close(fd);
return (-1);
}
sin4 = (struct sockaddr_in *)&ifr.ifr_addr;
*netp = sin4->sin_addr.s_addr;
memset(&ifr, 0, sizeof(ifr));
#ifdef linux
/* XXX Work around Linux kernel bug */
ifr.ifr_addr.sa_family = AF_INET;
#endif
(void)strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
if (ioctl(fd, SIOCGIFNETMASK, (char *)&ifr) < 0) {
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"SIOCGIFNETMASK: %s: %s", device, pcap_strerror(errno));
(void)close(fd);
return (-1);
}
(void)close(fd);
*maskp = sin4->sin_addr.s_addr;
if (*maskp == 0) {
if (IN_CLASSA(*netp))
*maskp = IN_CLASSA_NET;
else if (IN_CLASSB(*netp))
*maskp = IN_CLASSB_NET;
else if (IN_CLASSC(*netp))
*maskp = IN_CLASSC_NET;
else {
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"inet class for 0x%x unknown", *netp);
return (-1);
}
}
*netp &= *maskp;
return (0);
}
#elif defined(_WIN32)
/*
* Return the name of a network interface attached to the system, or NULL
* if none can be found. The interface must be configured up; the
* lowest unit number is preferred; loopback is ignored.
*
* In the best of all possible worlds, this would be the same as on
* UN*X, but there may be software that expects this to return a
* full list of devices after the first device.
*/
#define ADAPTERSNAME_LEN 8192
char *
pcap_lookupdev(errbuf)
register char *errbuf;
{
DWORD dwVersion;
DWORD dwWindowsMajorVersion;
char our_errbuf[PCAP_ERRBUF_SIZE+1];
#pragma warning (push)
#pragma warning (disable: 4996) /* disable MSVC's GetVersion() deprecated warning here */
dwVersion = GetVersion(); /* get the OS version */
#pragma warning (pop)
dwWindowsMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
if (dwVersion >= 0x80000000 && dwWindowsMajorVersion >= 4) {
/*
* Windows 95, 98, ME.
*/
ULONG NameLength = ADAPTERSNAME_LEN;
static char AdaptersName[ADAPTERSNAME_LEN];
if (PacketGetAdapterNames(AdaptersName,&NameLength) )
return (AdaptersName);
else
return NULL;
} else {
/*
* Windows NT (NT 4.0 and later).
* Convert the names to Unicode for backward compatibility.
*/
ULONG NameLength = ADAPTERSNAME_LEN;
static WCHAR AdaptersName[ADAPTERSNAME_LEN];
size_t BufferSpaceLeft;
char *tAstr;
WCHAR *Unameptr;
char *Adescptr;
size_t namelen, i;
WCHAR *TAdaptersName = (WCHAR*)malloc(ADAPTERSNAME_LEN * sizeof(WCHAR));
int NAdapts = 0;
if(TAdaptersName == NULL)
{
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "memory allocation failure");
return NULL;
}
if ( !PacketGetAdapterNames((PTSTR)TAdaptersName,&NameLength) )
{
pcap_win32_err_to_str(GetLastError(), our_errbuf);
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"PacketGetAdapterNames: %s", our_errbuf);
free(TAdaptersName);
return NULL;
}
BufferSpaceLeft = ADAPTERSNAME_LEN * sizeof(WCHAR);
tAstr = (char*)TAdaptersName;
Unameptr = AdaptersName;
/*
* Convert the device names to Unicode into AdapterName.
*/
do {
/*
* Length of the name, including the terminating
* NUL.
*/
namelen = strlen(tAstr) + 1;
/*
* Do we have room for the name in the Unicode
* buffer?
*/
if (BufferSpaceLeft < namelen * sizeof(WCHAR)) {
/*
* No.
*/
goto quit;
}
BufferSpaceLeft -= namelen * sizeof(WCHAR);
/*
* Copy the name, converting ASCII to Unicode.
* namelen includes the NUL, so we copy it as
* well.
*/
for (i = 0; i < namelen; i++)
*Unameptr++ = *tAstr++;
/*
* Count this adapter.
*/
NAdapts++;
} while (namelen != 1);
/*
* Copy the descriptions, but don't convert them from
* ASCII to Unicode.
*/
Adescptr = (char *)Unameptr;
while(NAdapts--)
{
size_t desclen;
desclen = strlen(tAstr) + 1;
/*
* Do we have room for the name in the Unicode
* buffer?
*/
if (BufferSpaceLeft < desclen) {
/*
* No.
*/
goto quit;
}
/*
* Just copy the ASCII string.
* namelen includes the NUL, so we copy it as
* well.
*/
memcpy(Adescptr, tAstr, desclen);
Adescptr += desclen;
tAstr += desclen;
BufferSpaceLeft -= desclen;
}
quit:
free(TAdaptersName);
return (char *)(AdaptersName);
}
}
int
pcap_lookupnet(device, netp, maskp, errbuf)
register const char *device;
register bpf_u_int32 *netp, *maskp;
register char *errbuf;
{
/*
* We need only the first IPv4 address, so we must scan the array returned by PacketGetNetInfo()
* in order to skip non IPv4 (i.e. IPv6 addresses)
*/
npf_if_addr if_addrs[MAX_NETWORK_ADDRESSES];
LONG if_addr_size = 1;
struct sockaddr_in *t_addr;
unsigned int i;
if (!PacketGetNetInfoEx((void *)device, if_addrs, &if_addr_size)) {
*netp = *maskp = 0;
return (0);
}
for(i=0; i<MAX_NETWORK_ADDRESSES; i++)
{
if(if_addrs[i].IPAddress.ss_family == AF_INET)
{
t_addr = (struct sockaddr_in *) &(if_addrs[i].IPAddress);
*netp = t_addr->sin_addr.S_un.S_addr;
t_addr = (struct sockaddr_in *) &(if_addrs[i].SubnetMask);
*maskp = t_addr->sin_addr.S_un.S_addr;
*netp &= *maskp;
return (0);
}
}
*netp = *maskp = 0;
return (0);
}
#endif /* !_WIN32 && !MSDOS */

18
libpcap.pc.in Normal file
View File

@ -0,0 +1,18 @@
#
# pkg-config file for libpcap.
#
# These variables come from the configure script, so includedir and
# libdir may be defined in terms of prefix and exec_prefix, so the
# latter must be defined as well.
#
prefix="@prefix@"
exec_prefix="@exec_prefix@"
includedir="@includedir@"
libdir="@libdir@"
Name: libpcap
Description: Platform-independent network traffic capture library
Version: @PACKAGE_VERSION@
Libs: -L${libdir} -l@PACKAGE_NAME@
Libs.private: @LIBS@
Cflags: -I${includedir}

View File

@ -56,10 +56,7 @@ char *optarg; /* argument associated with option */
* Parse argc/argv argument vector.
*/
int
getopt(nargc, nargv, ostr)
int nargc;
char * const *nargv;
const char *ostr;
getopt(int nargc, char * const *nargv, const char *ostr)
{
char *cp;
static char *__progname;

View File

@ -2,6 +2,6 @@
* Header for the getopt() we supply if the platform doesn't supply it.
*/
extern char *optarg; /* getopt(3) external variables */
extern int optind, opterr, optopt;
extern int optind, opterr, optreset, optopt;
extern int getopt(int nargc, char * const *nargv, const char *ostr);

View File

@ -35,7 +35,7 @@
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#include <config.h>
#endif
#include "portability.h"

View File

@ -1,86 +0,0 @@
#
# Common defines for libpcap and 16/32-bit network drivers (djgpp)
#
.SUFFIXES: .exe .wlm .dxe .l .y
.PHONY: check_gcclib
default: check_gcclib all
#
# This value is normally not important. Used by 'dxe3gen' in
# msdos/pm_drvr/makefile.dj to make "dynamically loaded modules".
# But this is not finished.
#
#GCC_LIB = $(shell gcc -print-libgcc-file-name)
GCC_LIB = .
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))
OBJ_DIR = djgpp.obj
ifeq ($(wildcard $(GCC_LIB)),)
check_gcclib:
@echo libgcc.a not found. Set \"$(GCC_LIB)\" to \"/djgpp/lib/gcc/djgpp/4.X/libgcc.a\"
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 -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) -o $@ $<
@echo
%.o: %.s
$(CC) -c $(CFLAGS) -x assembler-with-cpp -o $@ $<
@echo

View File

@ -23,7 +23,7 @@ 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 \
savefile.c pcap.c msdos\ndis2.c msdos\pktdrvr.c \
missing\snprintf.c
BORLAND_OBJ = $(SOURCE:.c=.obj) msdos\pkt_rx0.obj msdos\ndis_0.obj
@ -118,8 +118,6 @@ 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
@ -158,8 +156,6 @@ 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

View File

@ -24,7 +24,7 @@ CFLAGS += -Dyylval=pcap_lval # -DBDEBUG -DNDEBUG
SOURCES = grammar.c scanner.c bpf/net/bpf_filter.c bpf_image.c bpf_dump.c \
etherent.c gencode.c nametoaddr.c pcap-common.c pcap-dos.c optimize.c \
savefile.c pcap.c sf-pcap.c sf-pcap-ng.c inet.c \
savefile.c pcap.c sf-pcap.c sf-pcapng.c \
msdos/pktdrvr.c msdos/ndis2.c # missing/snprintf.c
OBJECTS = $(addprefix $(OBJ_DIR)/, $(notdir $(SOURCES:.c=.o)))

View File

@ -28,7 +28,7 @@ OBJS = $(OBJDIR)\grammar.obj $(OBJDIR)\scanner.obj $(OBJDIR)\pcap.obj &
$(OBJDIR)\bpf_filter.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
$(OBJDIR)\savefile.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 &
@ -108,8 +108,6 @@ $(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 &
pcap-namedb.h

View File

@ -1,860 +0,0 @@
/*
* 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 */

View File

@ -1,559 +0,0 @@
/*
* 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

View File

@ -1,188 +0,0 @@
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

View File

@ -23,7 +23,7 @@
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#include <config.h>
#endif
#ifdef DECNETLIB
@ -32,62 +32,99 @@
#endif
#ifdef _WIN32
#include <pcap-stdinc.h>
#ifdef INET6
/*
* To quote the MSDN page for getaddrinfo() at
*
* https://msdn.microsoft.com/en-us/library/windows/desktop/ms738520(v=vs.85).aspx
*
* "Support for getaddrinfo on Windows 2000 and older versions
* The getaddrinfo function was added to the Ws2_32.dll on Windows XP and
* later. To execute an application that uses this function on earlier
* versions of Windows, then you need to include the Ws2tcpip.h and
* Wspiapi.h files. When the Wspiapi.h include file is added, the
* getaddrinfo function is defined to the WspiapiGetAddrInfo inline
* function in the Wspiapi.h file. At runtime, the WspiapiGetAddrInfo
* function is implemented in such a way that if the Ws2_32.dll or the
* Wship6.dll (the file containing getaddrinfo in the IPv6 Technology
* Preview for Windows 2000) does not include getaddrinfo, then a
* version of getaddrinfo is implemented inline based on code in the
* Wspiapi.h header file. This inline code will be used on older Windows
* platforms that do not natively support the getaddrinfo function."
*
* We use getaddrinfo(), so we include Wspiapi.h here. pcap-stdinc.h
* includes Ws2tcpip.h, so we don't need to include it ourselves.
*/
#include <Wspiapi.h>
#endif
#include <winsock2.h>
#include <ws2tcpip.h>
#ifdef INET6
/*
* To quote the MSDN page for getaddrinfo() at
*
* https://msdn.microsoft.com/en-us/library/windows/desktop/ms738520(v=vs.85).aspx
*
* "Support for getaddrinfo on Windows 2000 and older versions
* The getaddrinfo function was added to the Ws2_32.dll on Windows XP and
* later. To execute an application that uses this function on earlier
* versions of Windows, then you need to include the Ws2tcpip.h and
* Wspiapi.h files. When the Wspiapi.h include file is added, the
* getaddrinfo function is defined to the WspiapiGetAddrInfo inline
* function in the Wspiapi.h file. At runtime, the WspiapiGetAddrInfo
* function is implemented in such a way that if the Ws2_32.dll or the
* Wship6.dll (the file containing getaddrinfo in the IPv6 Technology
* Preview for Windows 2000) does not include getaddrinfo, then a
* version of getaddrinfo is implemented inline based on code in the
* Wspiapi.h header file. This inline code will be used on older Windows
* platforms that do not natively support the getaddrinfo function."
*
* We use getaddrinfo(), so we include Wspiapi.h here.
*/
#include <wspiapi.h>
#endif /* INET6 */
#else /* _WIN32 */
#include <sys/param.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/param.h>
#include <sys/types.h> /* concession to AIX */
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <netinet/in.h>
#endif /* _WIN32 */
#ifdef HAVE_ETHER_HOSTTON
#if defined(NET_ETHERNET_H_DECLARES_ETHER_HOSTTON)
/*
* OK, just include <net/ethernet.h>.
*/
#include <net/ethernet.h>
#elif defined(NETINET_ETHER_H_DECLARES_ETHER_HOSTTON)
/*
* OK, just include <netinet/ether.h>
*/
#include <netinet/ether.h>
#elif defined(SYS_ETHERNET_H_DECLARES_ETHER_HOSTTON)
/*
* OK, just include <sys/ethernet.h>
*/
#include <sys/ethernet.h>
#elif defined(ARPA_INET_H_DECLARES_ETHER_HOSTTON)
/*
* OK, just include <arpa/inet.h>
*/
#include <arpa/inet.h>
#elif defined(NETINET_IF_ETHER_H_DECLARES_ETHER_HOSTTON)
/*
* OK, include <netinet/if_ether.h>, after all the other stuff we
* need to include or define for its benefit.
*/
#define NEED_NETINET_IF_ETHER_H
#else
/*
* We'll have to declare it ourselves.
* If <netinet/if_ether.h> defines struct ether_addr, include
* it. Otherwise, define it ourselves.
*/
#ifdef HAVE_STRUCT_ETHER_ADDR
#define NEED_NETINET_IF_ETHER_H
#else /* HAVE_STRUCT_ETHER_ADDR */
struct ether_addr {
unsigned char ether_addr_octet[6];
};
#endif /* HAVE_STRUCT_ETHER_ADDR */
#endif /* what declares ether_hostton() */
#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>
#ifdef NEED_NETINET_IF_ETHER_H
#include <net/if.h> /* Needed on some platforms */
#include <netinet/in.h> /* Needed on some platforms */
#include <netinet/if_ether.h>
#endif /* NEED_NETINET_IF_ETHER_H */
#ifndef HAVE_DECL_ETHER_HOSTTON
/*
* No header declares it, so declare it ourselves.
*/
extern int ether_hostton(const char *, struct ether_addr *);
#endif /* !defined(HAVE_DECL_ETHER_HOSTTON) */
#endif /* HAVE_ETHER_HOSTTON */
#include <arpa/inet.h>
#include <netdb.h>
#endif /* _WIN32 */
#include <ctype.h>
@ -111,11 +148,10 @@ struct rtentry; /* declarations in <net/if.h> */
#define NTOHS(x) (x) = ntohs(x)
#endif
static inline int xdtoi(int);
/*
* Convert host name to internet address.
* Return 0 upon failure.
* XXX - not thread-safe; don't use it inside libpcap.
*/
bpf_u_int32 **
pcap_nametoaddr(const char *name)
@ -141,7 +177,6 @@ pcap_nametoaddr(const char *name)
return 0;
}
#ifdef INET6
struct addrinfo *
pcap_nametoaddrinfo(const char *name)
{
@ -158,23 +193,17 @@ pcap_nametoaddrinfo(const char *name)
else
return res;
}
#endif /*INET6*/
/*
* Convert net name to internet address.
* Return 0 upon failure.
* XXX - not guaranteed to be thread-safe! See below for platforms
* on which it is thread-safe and on which it isn't.
*/
bpf_u_int32
pcap_nametonetaddr(const char *name)
{
#ifndef _WIN32
struct netent *np;
if ((np = getnetbyname(name)) != NULL)
return np->n_net;
else
return 0;
#else
#ifdef _WIN32
/*
* There's no "getnetbyname()" on Windows.
*
@ -188,7 +217,66 @@ pcap_nametonetaddr(const char *name)
* of *UN*X* machines.)
*/
return 0;
#endif
#else
/*
* UN*X.
*/
struct netent *np;
#if defined(HAVE_LINUX_GETNETBYNAME_R)
/*
* We have Linux's reentrant getnetbyname_r().
*/
struct netent result_buf;
char buf[1024]; /* arbitrary size */
int h_errnoval;
int err;
err = getnetbyname_r(name, &result_buf, buf, sizeof buf, &np,
&h_errnoval);
if (err != 0) {
/*
* XXX - dynamically allocate the buffer, and make it
* bigger if we get ERANGE back?
*/
return 0;
}
#elif defined(HAVE_SOLARIS_IRIX_GETNETBYNAME_R)
/*
* We have Solaris's and IRIX's reentrant getnetbyname_r().
*/
struct netent result_buf;
char buf[1024]; /* arbitrary size */
np = getnetbyname_r(name, &result_buf, buf, (int)sizeof buf);
#elif defined(HAVE_AIX_GETNETBYNAME_R)
/*
* We have AIX's reentrant getnetbyname_r().
*/
struct netent result_buf;
struct netent_data net_data;
if (getnetbyname_r(name, &result_buf, &net_data) == -1)
np = NULL;
else
np = &result_buf;
#else
/*
* We don't have any getnetbyname_r(); either we have a
* getnetbyname() that uses thread-specific data, in which
* case we're thread-safe (sufficiently recent FreeBSD,
* sufficiently recent Darwin-based OS, sufficiently recent
* HP-UX, sufficiently recent Tru64 UNIX), or we have the
* traditional getnetbyname() (everything else, including
* current NetBSD and OpenBSD), in which case we're not
* thread-safe.
*/
np = getnetbyname(name);
#endif
if (np != NULL)
return np->n_net;
else
return 0;
#endif /* _WIN32 */
}
/*
@ -199,20 +287,111 @@ pcap_nametonetaddr(const char *name)
int
pcap_nametoport(const char *name, int *port, int *proto)
{
struct servent *sp;
struct addrinfo hints, *res, *ai;
int error;
struct sockaddr_in *in4;
#ifdef INET6
struct sockaddr_in6 *in6;
#endif
int tcp_port = -1;
int udp_port = -1;
/*
* We check for both TCP and UDP in case there are
* ambiguous entries.
*/
memset(&hints, 0, sizeof(hints));
hints.ai_family = PF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
error = getaddrinfo(NULL, name, &hints, &res);
if (error != 0) {
if (error != EAI_NONAME) {
/*
* This is a real error, not just "there's
* no such service name".
* XXX - this doesn't return an error string.
*/
return 0;
}
} else {
/*
* OK, we found it. Did it find anything?
*/
for (ai = res; ai != NULL; ai = ai->ai_next) {
/*
* Does it have an address?
*/
if (ai->ai_addr != NULL) {
/*
* Yes. Get a port number; we're done.
*/
if (ai->ai_addr->sa_family == AF_INET) {
in4 = (struct sockaddr_in *)ai->ai_addr;
tcp_port = ntohs(in4->sin_port);
break;
}
#ifdef INET6
if (ai->ai_addr->sa_family == AF_INET6) {
in6 = (struct sockaddr_in6 *)ai->ai_addr;
tcp_port = ntohs(in6->sin6_port);
break;
}
#endif
}
}
freeaddrinfo(res);
}
memset(&hints, 0, sizeof(hints));
hints.ai_family = PF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_protocol = IPPROTO_UDP;
error = getaddrinfo(NULL, name, &hints, &res);
if (error != 0) {
if (error != EAI_NONAME) {
/*
* This is a real error, not just "there's
* no such service name".
* XXX - this doesn't return an error string.
*/
return 0;
}
} else {
/*
* OK, we found it. Did it find anything?
*/
for (ai = res; ai != NULL; ai = ai->ai_next) {
/*
* Does it have an address?
*/
if (ai->ai_addr != NULL) {
/*
* Yes. Get a port number; we're done.
*/
if (ai->ai_addr->sa_family == AF_INET) {
in4 = (struct sockaddr_in *)ai->ai_addr;
udp_port = ntohs(in4->sin_port);
break;
}
#ifdef INET6
if (ai->ai_addr->sa_family == AF_INET6) {
in6 = (struct sockaddr_in6 *)ai->ai_addr;
udp_port = ntohs(in6->sin6_port);
break;
}
#endif
}
}
freeaddrinfo(res);
}
/*
* We need to check /etc/services for ambiguous entries.
* If we find the ambiguous entry, and it has the
* If we find an ambiguous entry, and it has the
* same port number, change the proto to PROTO_UNDEF
* so both TCP and UDP will be checked.
*/
sp = getservbyname(name, "tcp");
if (sp != NULL) tcp_port = ntohs(sp->s_port);
sp = getservbyname(name, "udp");
if (sp != NULL) udp_port = ntohs(sp->s_port);
if (tcp_port >= 0) {
*port = tcp_port;
*proto = IPPROTO_TCP;
@ -291,12 +470,62 @@ pcap_nametoportrange(const char *name, int *port1, int *port2, int *proto)
return 1;
}
/*
* XXX - not guaranteed to be thread-safe! See below for platforms
* on which it is thread-safe and on which it isn't.
*/
int
pcap_nametoproto(const char *str)
{
struct protoent *p;
#if defined(HAVE_LINUX_GETNETBYNAME_R)
/*
* We have Linux's reentrant getprotobyname_r().
*/
struct protoent result_buf;
char buf[1024]; /* arbitrary size */
int err;
err = getprotobyname_r(str, &result_buf, buf, sizeof buf, &p);
if (err != 0) {
/*
* XXX - dynamically allocate the buffer, and make it
* bigger if we get ERANGE back?
*/
return 0;
}
#elif defined(HAVE_SOLARIS_IRIX_GETNETBYNAME_R)
/*
* We have Solaris's and IRIX's reentrant getprotobyname_r().
*/
struct protoent result_buf;
char buf[1024]; /* arbitrary size */
p = getprotobyname_r(str, &result_buf, buf, (int)sizeof buf);
#elif defined(HAVE_AIX_GETNETBYNAME_R)
/*
* We have AIX's reentrant getprotobyname_r().
*/
struct protoent result_buf;
struct protoent_data proto_data;
if (getprotobyname_r(str, &result_buf, &proto_data) == -1)
p = NULL;
else
p = &result_buf;
#else
/*
* We don't have any getprotobyname_r(); either we have a
* getprotobyname() that uses thread-specific data, in which
* case we're thread-safe (sufficiently recent FreeBSD,
* sufficiently recent Darwin-based OS, sufficiently recent
* HP-UX, sufficiently recent Tru64 UNIX, Windows), or we have
* the traditional getprotobyname() (everything else, including
* current NetBSD and OpenBSD), in which case we're not
* thread-safe.
*/
p = getprotobyname(str);
#endif
if (p != 0)
return p->p_proto;
else
@ -316,7 +545,12 @@ struct eproto {
* Debian, at least, so make it a public symbol, even though we
* don't officially export it by declaring it in a header file.
* (Programs *should* do this themselves, as tcpdump now does.)
*
* We declare it here, right before defining it, to squelch any
* warnings we might get from compilers about the lack of a
* declaration.
*/
PCAP_API struct eproto eproto_db[];
PCAP_API_DEF struct eproto eproto_db[] = {
{ "pup", ETHERTYPE_PUP },
{ "xns", ETHERTYPE_NS },
@ -380,17 +614,16 @@ pcap_nametollc(const char *s)
return PROTO_UNDEF;
}
/* Hex digit to integer. */
static inline int
xdtoi(c)
register int c;
/* Hex digit to 8-bit unsigned integer. */
static inline u_char
xdtoi(u_char c)
{
if (isdigit(c))
return c - '0';
return (u_char)(c - '0');
else if (islower(c))
return c - 'a' + 10;
return (u_char)(c - 'a' + 10);
else
return c - 'A' + 10;
return (u_char)(c - 'A' + 10);
}
int
@ -401,7 +634,7 @@ __pcap_atoin(const char *s, bpf_u_int32 *addr)
*addr = 0;
len = 0;
while (1) {
for (;;) {
n = 0;
while (*s && *s != '.')
n = n * 10 + *s++ - '0';
@ -449,7 +682,7 @@ u_char *
pcap_ether_aton(const char *s)
{
register u_char *ep, *e;
register u_int d;
register u_char d;
e = ep = (u_char *)malloc(6);
if (e == NULL)
@ -470,7 +703,11 @@ pcap_ether_aton(const char *s)
}
#ifndef HAVE_ETHER_HOSTTON
/* Roll our own */
/*
* Roll our own.
* XXX - not thread-safe, because pcap_next_etherent() isn't thread-
* safe! Needs a mutex or a thread-safe pcap_next_etherent().
*/
u_char *
pcap_ether_hostton(const char *name)
{
@ -502,17 +739,10 @@ pcap_ether_hostton(const char *name)
return (NULL);
}
#else
#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 */
/*
* Use the OS-supplied routine.
* This *should* be thread-safe; the API doesn't have a static buffer.
*/
u_char *
pcap_ether_hostton(const char *name)
{
@ -529,10 +759,13 @@ pcap_ether_hostton(const char *name)
}
#endif
/*
* XXX - not guaranteed to be thread-safe!
*/
int
#ifdef DECNETLIB
__pcap_nametodnaddr(const char *name, u_short *res)
{
#ifdef DECNETLIB
struct nodeent *getnodebyname();
struct nodeent *nep;
@ -543,6 +776,8 @@ __pcap_nametodnaddr(const char *name, u_short *res)
memcpy((char *)res, (char *)nep->n_addr, sizeof(unsigned short));
return(1);
#else
__pcap_nametodnaddr(const char *name _U_, u_short *res _U_)
{
return(0);
#endif
}

6
nomkdep Normal file
View File

@ -0,0 +1,6 @@
#!/bin/sh -
#
# Does nothing; used if we don't have a command-line flag to the compiler
# to get it to generate dependencies.
#
exit 0

View File

@ -18,26 +18,14 @@
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* Optimization module for tcpdump intermediate representation.
* Optimization module for BPF code intermediate representation.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#include <config.h>
#endif
#ifdef _WIN32
#include <pcap-stdinc.h>
#else /* _WIN32 */
#if HAVE_INTTYPES_H
#include <inttypes.h>
#elif HAVE_STDINT_H
#include <stdint.h>
#endif
#ifdef HAVE_SYS_BITYPES_H
#include <sys/bitypes.h>
#endif
#include <sys/types.h>
#endif /* _WIN32 */
#include <pcap-types.h>
#include <stdio.h>
#include <stdlib.h>
@ -49,39 +37,149 @@
#include "pcap-int.h"
#include "gencode.h"
#include "optimize.h"
#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
#ifdef BDEBUG
int pcap_optimizer_debug;
#endif
#if defined(MSDOS) && !defined(__DJGPP__)
extern int _w32_ffs (int mask);
#define ffs _w32_ffs
#endif
/*
* So is the check for _MSC_VER done because MinGW has this?
* The internal "debug printout" flag for the filter expression optimizer.
* The code to print that stuff is present only if BDEBUG is defined, so
* the flag, and the routine to set it, are defined only if BDEBUG is
* defined.
*/
#if defined(_WIN32) && defined (_MSC_VER)
static int pcap_optimizer_debug;
/*
* ffs -- vax ffs instruction
* Routine to set that flag.
*
* XXX - with versions of VS that have it, use _BitScanForward()?
* This is intended for libpcap developers, not for general use.
* If you want to set these in a program, you'll have to declare this
* routine yourself, with the appropriate DLL import attribute on Windows;
* it's not declared in any header file, and won't be declared in any
* header file provided by libpcap.
*/
PCAP_API void pcap_set_optimizer_debug(int value);
PCAP_API_DEF void
pcap_set_optimizer_debug(int value)
{
pcap_optimizer_debug = value;
}
/*
* The internal "print dot graph" flag for the filter expression optimizer.
* The code to print that stuff is present only if BDEBUG is defined, so
* the flag, and the routine to set it, are defined only if BDEBUG is
* defined.
*/
static int pcap_print_dot_graph;
/*
* Routine to set that flag.
*
* This is intended for libpcap developers, not for general use.
* If you want to set these in a program, you'll have to declare this
* routine yourself, with the appropriate DLL import attribute on Windows;
* it's not declared in any header file, and won't be declared in any
* header file provided by libpcap.
*/
PCAP_API void pcap_set_print_dot_graph(int value);
PCAP_API_DEF void
pcap_set_print_dot_graph(int value)
{
pcap_print_dot_graph = value;
}
#endif
/*
* lowest_set_bit().
*
* Takes a 32-bit integer as an argument.
*
* If handed a non-zero value, returns the index of the lowest set bit,
* counting upwards fro zero.
*
* If handed zero, the results are platform- and compiler-dependent.
* Keep it out of the light, don't give it any water, don't feed it
* after midnight, and don't pass zero to it.
*
* This is the same as the count of trailing zeroes in the word.
*/
#if PCAP_IS_AT_LEAST_GNUC_VERSION(3,4)
/*
* GCC 3.4 and later; we have __builtin_ctz().
*/
#define lowest_set_bit(mask) __builtin_ctz(mask)
#elif defined(_MSC_VER)
/*
* Visual Studio; we support only 2005 and later, so use
* _BitScanForward().
*/
#include <intrin.h>
#ifndef __clang__
#pragma intrinsic(_BitScanForward)
#endif
static __forceinline int
lowest_set_bit(int mask)
{
unsigned long bit;
/*
* Don't sign-extend mask if long is longer than int.
* (It's currently not, in MSVC, even on 64-bit platforms, but....)
*/
if (_BitScanForward(&bit, (unsigned int)mask) == 0)
return -1; /* mask is zero */
return (int)bit;
}
#elif defined(MSDOS) && defined(__DJGPP__)
/*
* MS-DOS with DJGPP, which declares ffs() in <string.h>, which
* we've already included.
*/
#define lowest_set_bit(mask) (ffs((mask)) - 1)
#elif (defined(MSDOS) && defined(__WATCOMC__)) || defined(STRINGS_H_DECLARES_FFS)
/*
* MS-DOS with Watcom C, which has <strings.h> and declares ffs() there,
* or some other platform (UN*X conforming to a sufficient recent version
* of the Single UNIX Specification).
*/
#include <strings.h>
#define lowest_set_bit(mask) (ffs((mask)) - 1)
#else
/*
* None of the above.
* Use a perfect-hash-function-based function.
*/
static int
ffs(int mask)
lowest_set_bit(int mask)
{
int bit;
unsigned int v = (unsigned int)mask;
if (mask == 0)
return(0);
for (bit = 1; !(mask & 1); bit++)
mask >>= 1;
return(bit);
static const int MultiplyDeBruijnBitPosition[32] = {
0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
};
/*
* We strip off all but the lowermost set bit (v & ~v),
* and perform a minimal perfect hash on it to look up the
* number of low-order zero bits in a table.
*
* See:
*
* http://7ooo.mooo.com/text/ComputingTrailingZerosHOWTO.pdf
*
* http://supertech.csail.mit.edu/papers/debruijn.pdf
*/
return (MultiplyDeBruijnBitPosition[((v & -v) * 0x077CB531U) >> 27]);
}
#endif
@ -127,7 +225,7 @@ struct vmapinfo {
bpf_int32 const_val;
};
struct _opt_state {
typedef struct {
/*
* A flag to indicate that further optimization is needed.
* Iterative passes are continued until a given pass yields no
@ -210,7 +308,7 @@ struct _opt_state {
struct vmapinfo *vmap;
struct valnode *vnode_base;
struct valnode *next_vnode;
};
} opt_state_t;
typedef struct {
/*
@ -290,7 +388,7 @@ find_dom(opt_state_t *opt_state, struct block *root)
x = opt_state->all_dom_sets;
i = opt_state->n_blocks * opt_state->nodewords;
while (--i >= 0)
*x++ = ~0;
*x++ = 0xFFFFFFFFU;
/* Root starts off empty. */
for (i = opt_state->nodewords; --i >= 0;)
root->dom[i] = 0;
@ -330,7 +428,7 @@ find_edom(opt_state_t *opt_state, struct block *root)
x = opt_state->all_edge_sets;
for (i = opt_state->n_edges * opt_state->edgewords; --i >= 0; )
x[i] = ~0;
x[i] = 0xFFFFFFFFU;
/* root->level is the highest level no found. */
memset(root->et.edom, 0, opt_state->edgewords * sizeof(*(uset)0));
@ -590,7 +688,7 @@ F(opt_state_t *opt_state, int code, int v0, int v1)
static inline void
vstore(struct stmt *s, int *valp, int newval, int alter)
{
if (alter && *valp == newval)
if (alter && newval != VAL_UNKNOWN && *valp == newval)
s->code = NOP;
else
*valp = newval;
@ -601,7 +699,7 @@ vstore(struct stmt *s, int *valp, int newval, int alter)
* (Unary operators are handled elsewhere.)
*/
static void
fold_op(compiler_state_t *cstate, struct icode *ic, opt_state_t *opt_state,
fold_op(compiler_state_t *cstate, opt_state_t *opt_state,
struct stmt *s, int v0, int v1)
{
bpf_u_int32 a, b;
@ -943,7 +1041,7 @@ opt_peep(opt_state_t *opt_state, struct block *b)
* evaluation and code transformations weren't folded together.
*/
static void
opt_stmt(compiler_state_t *cstate, struct icode *ic, opt_state_t *opt_state,
opt_stmt(compiler_state_t *cstate, opt_state_t *opt_state,
struct stmt *s, int val[], int alter)
{
int op;
@ -1032,7 +1130,7 @@ opt_stmt(compiler_state_t *cstate, struct icode *ic, opt_state_t *opt_state,
}
}
if (opt_state->vmap[val[A_ATOM]].is_const) {
fold_op(cstate, ic, opt_state, s, val[A_ATOM], K(s->k));
fold_op(cstate, opt_state, s, val[A_ATOM], K(s->k));
val[A_ATOM] = K(s->k);
break;
}
@ -1053,7 +1151,7 @@ opt_stmt(compiler_state_t *cstate, struct icode *ic, opt_state_t *opt_state,
op = BPF_OP(s->code);
if (alter && opt_state->vmap[val[X_ATOM]].is_const) {
if (opt_state->vmap[val[A_ATOM]].is_const) {
fold_op(cstate, ic, opt_state, s, val[A_ATOM], val[X_ATOM]);
fold_op(cstate, opt_state, s, val[A_ATOM], val[X_ATOM]);
val[A_ATOM] = K(s->k);
}
else {
@ -1177,7 +1275,7 @@ opt_deadstores(opt_state_t *opt_state, register struct block *b)
}
static void
opt_blk(compiler_state_t *cstate, struct icode *ic, opt_state_t *opt_state,
opt_blk(compiler_state_t *cstate, opt_state_t *opt_state,
struct block *b, int do_stmts)
{
struct slist *s;
@ -1228,7 +1326,7 @@ opt_blk(compiler_state_t *cstate, struct icode *ic, opt_state_t *opt_state,
aval = b->val[A_ATOM];
xval = b->val[X_ATOM];
for (s = b->stmts; s; s = s->next)
opt_stmt(cstate, ic, opt_state, &s->s, b->val, do_stmts);
opt_stmt(cstate, opt_state, &s->s, b->val, do_stmts);
/*
* This is a special case: if we don't use anything from this
@ -1254,8 +1352,9 @@ opt_blk(compiler_state_t *cstate, struct icode *ic, opt_state_t *opt_state,
* block, can we eliminate it?
*/
if (do_stmts &&
((b->out_use == 0 && aval != 0 && b->val[A_ATOM] == aval &&
xval != 0 && b->val[X_ATOM] == xval) ||
((b->out_use == 0 &&
aval != VAL_UNKNOWN && b->val[A_ATOM] == aval &&
xval != VAL_UNKNOWN && b->val[X_ATOM] == xval) ||
BPF_CLASS(b->s.code) == BPF_RET)) {
if (b->stmts != 0) {
b->stmts = 0;
@ -1380,7 +1479,7 @@ opt_j(opt_state_t *opt_state, struct edge *ep)
register bpf_u_int32 x = ep->edom[i];
while (x != 0) {
k = ffs(x) - 1;
k = lowest_set_bit(x);
x &=~ (1 << k);
k += i * BITS_PER_WORD;
@ -1431,7 +1530,7 @@ or_pullup(opt_state_t *opt_state, struct block *b)
diffp = &JF(b->in_edges->pred);
at_top = 1;
while (1) {
for (;;) {
if (*diffp == 0)
return;
@ -1448,7 +1547,7 @@ or_pullup(opt_state_t *opt_state, struct block *b)
at_top = 0;
}
samep = &JF(*diffp);
while (1) {
for (;;) {
if (*samep == 0)
return;
@ -1522,7 +1621,7 @@ and_pullup(opt_state_t *opt_state, struct block *b)
diffp = &JF(b->in_edges->pred);
at_top = 1;
while (1) {
for (;;) {
if (*diffp == 0)
return;
@ -1539,7 +1638,7 @@ and_pullup(opt_state_t *opt_state, struct block *b)
at_top = 0;
}
samep = &JT(*diffp);
while (1) {
for (;;) {
if (*samep == 0)
return;
@ -1600,7 +1699,7 @@ opt_blks(compiler_state_t *cstate, opt_state_t *opt_state, struct icode *ic,
find_inedges(opt_state, ic->root);
for (i = maxlevel; i >= 0; --i)
for (p = opt_state->levels[i]; p; p = p->link)
opt_blk(cstate, ic, opt_state, p, do_stmts);
opt_blk(cstate, opt_state, p, do_stmts);
if (do_stmts)
/*
@ -1683,7 +1782,7 @@ opt_loop(compiler_state_t *cstate, opt_state_t *opt_state, struct icode *ic,
{
#ifdef BDEBUG
if (pcap_optimizer_debug > 1) {
if (pcap_optimizer_debug > 1 || pcap_print_dot_graph) {
printf("opt_loop(root, %d) begin\n", do_stmts);
opt_dump(cstate, ic);
}
@ -1697,7 +1796,7 @@ opt_loop(compiler_state_t *cstate, opt_state_t *opt_state, struct icode *ic,
find_edom(opt_state, ic->root);
opt_blks(cstate, opt_state, ic, do_stmts);
#ifdef BDEBUG
if (pcap_optimizer_debug > 1) {
if (pcap_optimizer_debug > 1 || pcap_print_dot_graph) {
printf("opt_loop(root, %d) bottom, done=%d\n", do_stmts, opt_state->done);
opt_dump(cstate, ic);
}
@ -1718,14 +1817,14 @@ bpf_optimize(compiler_state_t *cstate, struct icode *ic)
opt_loop(cstate, &opt_state, ic, 1);
intern_blocks(&opt_state, ic);
#ifdef BDEBUG
if (pcap_optimizer_debug > 1) {
if (pcap_optimizer_debug > 1 || pcap_print_dot_graph) {
printf("after intern_blocks()\n");
opt_dump(cstate, ic);
}
#endif
opt_root(&ic->root);
#ifdef BDEBUG
if (pcap_optimizer_debug > 1) {
if (pcap_optimizer_debug > 1 || pcap_print_dot_graph) {
printf("after opt_root()\n");
opt_dump(cstate, ic);
}
@ -1763,7 +1862,7 @@ mark_code(struct icode *ic)
static int
eq_slist(struct slist *x, struct slist *y)
{
while (1) {
for (;;) {
while (x && x->s.code == NOP)
x = x->next;
while (y && y->s.code == NOP)
@ -2013,7 +2112,7 @@ opt_init(compiler_state_t *cstate, opt_state_t *opt_state, struct icode *ic)
* and expect it to provide meaningful information.
*/
#ifdef BDEBUG
int bids[1000];
int bids[NBIDS];
#endif
/*
@ -2030,7 +2129,7 @@ convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state,
struct slist *src;
u_int slen;
u_int off;
int extrajmps; /* number of extra jumps inserted */
u_int extrajmps; /* number of extra jumps inserted */
struct slist **offset = NULL;
if (p == 0 || isMarked(ic, p))
@ -2088,7 +2187,7 @@ convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state,
{
u_int i;
int jt, jf;
const char *ljerr = "%s for block-local relative jump: off=%d";
const char ljerr[] = "%s for block-local relative jump: off=%d";
#if 0
printf("code=%x off=%d %x %x\n", src->s.code,
@ -2108,7 +2207,11 @@ convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state,
/*NOTREACHED*/
}
dst->jt = i - off - 1;
if (i - off - 1 >= 256) {
bpf_error(cstate, ljerr, "out-of-range jump", off);
/*NOTREACHED*/
}
dst->jt = (u_char)(i - off - 1);
jt++;
}
if (offset[i] == src->s.jf) {
@ -2116,7 +2219,11 @@ convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state,
bpf_error(cstate, ljerr, "multiple matches", off);
/*NOTREACHED*/
}
dst->jf = i - off - 1;
if (i - off - 1 >= 256) {
bpf_error(cstate, ljerr, "out-of-range jump", off);
/*NOTREACHED*/
}
dst->jf = (u_char)(i - off - 1);
jf++;
}
}
@ -2133,7 +2240,8 @@ convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state,
free(offset);
#ifdef BDEBUG
bids[dst - conv_state->fstart] = p->id + 1;
if (dst - conv_state->fstart < NBIDS)
bids[dst - conv_state->fstart] = p->id + 1;
#endif
dst->code = (u_short)p->s.code;
dst->k = p->s.k;
@ -2148,13 +2256,17 @@ convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state,
return(0);
}
/* branch if T to following jump */
dst->jt = extrajmps;
if (extrajmps >= 256) {
bpf_error(cstate, "too many extra jumps");
/*NOTREACHED*/
}
dst->jt = (u_char)extrajmps;
extrajmps++;
dst[extrajmps].code = BPF_JMP|BPF_JA;
dst[extrajmps].k = off - extrajmps;
}
else
dst->jt = off;
dst->jt = (u_char)off;
off = JF(p)->offset - (p->offset + slen) - 1;
if (off >= 256) {
/* offset too large for branch, must add a jump */
@ -2165,13 +2277,17 @@ convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state,
}
/* branch if F to following jump */
/* if two jumps are inserted, F goes to second one */
dst->jf = extrajmps;
if (extrajmps >= 256) {
bpf_error(cstate, "too many extra jumps");
/*NOTREACHED*/
}
dst->jf = (u_char)extrajmps;
extrajmps++;
dst[extrajmps].code = BPF_JMP|BPF_JA;
dst[extrajmps].k = off - extrajmps;
}
else
dst->jf = off;
dst->jf = (u_char)off;
}
return (1);
}
@ -2207,7 +2323,7 @@ icode_to_fcode(compiler_state_t *cstate, struct icode *ic,
* Loop doing convert_code_r() until no branches remain
* with too-large offsets.
*/
while (1) {
for (;;) {
unMarkAll(ic);
n = *lenp = count_stmts(ic, root);
@ -2258,8 +2374,8 @@ install_bpf_program(pcap_t *p, struct bpf_program *fp)
p->fcode.bf_len = fp->bf_len;
p->fcode.bf_insns = (struct bpf_insn *)malloc(prog_size);
if (p->fcode.bf_insns == NULL) {
pcap_snprintf(p->errbuf, sizeof(p->errbuf),
"malloc: %s", pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(p->errbuf, sizeof(p->errbuf),
errno, "malloc");
return (-1);
}
memcpy(p->fcode.bf_insns, fp->bf_insns, prog_size);
@ -2287,7 +2403,7 @@ dot_dump_node(struct icode *ic, struct block *block, struct bpf_program *prog,
}
fprintf(out, "\" tooltip=\"");
for (i = 0; i < BPF_MEMWORDS; i++)
if (block->val[i] != 0)
if (block->val[i] != VAL_UNKNOWN)
fprintf(out, "val[%d]=%d ", i, block->val[i]);
fprintf(out, "val[A]=%d ", block->val[A_ATOM]);
fprintf(out, "val[X]=%d", block->val[X_ATOM]);
@ -2346,10 +2462,8 @@ dot_dump(compiler_state_t *cstate, struct icode *ic)
f.bf_insns = icode_to_fcode(cstate, ic, ic->root, &f.bf_len);
fprintf(out, "digraph BPF {\n");
ic->cur_mark = 0;
unMarkAll(ic);
dot_dump_node(ic, ic->root, &f, out);
ic->cur_mark = 0;
unMarkAll(ic);
dot_dump_edge(ic, ic->root, out);
fprintf(out, "}\n");
@ -2372,11 +2486,11 @@ plain_dump(compiler_state_t *cstate, struct icode *ic)
static void
opt_dump(compiler_state_t *cstate, struct icode *ic)
{
/* if optimizer debugging is enabled, output DOT graph
* `pcap_optimizer_debug=4' is equivalent to -dddd to follow -d/-dd/-ddd
* convention in tcpdump command line
/*
* If the CFG, in DOT format, is requested, output it rather than
* the code that would be generated from that graph.
*/
if (pcap_optimizer_debug > 3)
if (pcap_print_dot_graph)
dot_dump(cstate, ic);
else
plain_dump(cstate, ic);

28
optimize.h Normal file
View File

@ -0,0 +1,28 @@
/*
* Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that: (1) source code distributions
* retain the above copyright notice and this paragraph in its entirety, (2)
* distributions including binary code include the above copyright notice and
* this paragraph in its entirety in the documentation or other materials
* provided with the distribution, and (3) all advertising materials mentioning
* features or use of this software display the following acknowledgement:
* ``This product includes software developed by the University of California,
* Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
* the University nor the names of its contributors may be used to endorse
* or promote products derived from this software without specific prior
* written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
/*
* Some stuff for use when debugging the optimizer.
*/
#ifdef BDEBUG
#define NBIDS 1000
extern int bids[NBIDS];
#endif

File diff suppressed because it is too large Load Diff

View File

@ -33,17 +33,13 @@
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#include <config.h>
#endif
#include "pcap-int.h"
#include "pcap-bt-linux.h"
#include "pcap/bluetooth.h"
#ifdef NEED_STRERROR_H
#include "strerror.h"
#endif
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
@ -74,7 +70,7 @@ struct pcap_bt {
};
int
bt_findalldevs(pcap_if_t **alldevsp, char *err_str)
bt_findalldevs(pcap_if_list_t *devlistp, char *err_str)
{
struct hci_dev_list_req *dev_list;
struct hci_dev_req *dev_req;
@ -87,8 +83,8 @@ bt_findalldevs(pcap_if_t **alldevsp, char *err_str)
/* if bluetooth is not supported this this is not fatal*/
if (errno == EAFNOSUPPORT)
return 0;
pcap_snprintf(err_str, PCAP_ERRBUF_SIZE,
"Can't open raw Bluetooth socket: %s", strerror(errno));
pcap_fmt_errmsg_for_errno(err_str, PCAP_ERRBUF_SIZE,
errno, "Can't open raw Bluetooth socket");
return -1;
}
@ -105,9 +101,8 @@ bt_findalldevs(pcap_if_t **alldevsp, char *err_str)
if (ioctl(sock, HCIGETDEVLIST, (void *) dev_list) < 0)
{
pcap_snprintf(err_str, PCAP_ERRBUF_SIZE,
"Can't get Bluetooth device list via ioctl: %s",
strerror(errno));
pcap_fmt_errmsg_for_errno(err_str, PCAP_ERRBUF_SIZE,
errno, "Can't get Bluetooth device list via ioctl");
ret = -1;
goto free;
}
@ -119,13 +114,19 @@ bt_findalldevs(pcap_if_t **alldevsp, char *err_str)
pcap_snprintf(dev_name, 20, BT_IFACE"%d", dev_req->dev_id);
pcap_snprintf(dev_descr, 30, "Bluetooth adapter number %d", i);
if (pcap_add_if(alldevsp, dev_name, 0,
dev_descr, err_str) < 0)
/*
* Bluetooth is a wireless technology.
* XXX - if there's the notion of associating with a
* network, and we can determine whether the interface
* is associated with a network, check that and set
* the status to PCAP_IF_CONNECTION_STATUS_CONNECTED
* or PCAP_IF_CONNECTION_STATUS_DISCONNECTED.
*/
if (add_dev(devlistp, dev_name, PCAP_IF_WIRELESS, dev_descr, err_str) == NULL)
{
ret = -1;
break;
}
}
free:
@ -198,6 +199,17 @@ bt_activate(pcap_t* handle)
return PCAP_ERROR;
}
/*
* Turn a negative snapshot value (invalid), a snapshot value of
* 0 (unspecified), or a value bigger than the normal maximum
* value, into the maximum allowed value.
*
* If some application really *needs* a bigger snapshot
* length, we should just increase MAXIMUM_SNAPLEN.
*/
if (handle->snapshot <= 0 || handle->snapshot > MAXIMUM_SNAPLEN)
handle->snapshot = MAXIMUM_SNAPLEN;
/* Initialize some components of the pcap structure. */
handle->bufsize = BT_CTRL_SIZE+sizeof(pcap_bluetooth_h4_header)+handle->snapshot;
handle->linktype = DLT_BLUETOOTH_HCI_H4_WITH_PHDR;
@ -215,29 +227,29 @@ bt_activate(pcap_t* handle)
/* Create HCI socket */
handle->fd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
if (handle->fd < 0) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't create raw socket: %s", strerror(errno));
pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
errno, "Can't create raw socket");
return PCAP_ERROR;
}
handle->buffer = malloc(handle->bufsize);
if (!handle->buffer) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't allocate dump buffer: %s",
pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
errno, "Can't allocate dump buffer");
goto close_fail;
}
opt = 1;
if (setsockopt(handle->fd, SOL_HCI, HCI_DATA_DIR, &opt, sizeof(opt)) < 0) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't enable data direction info: %s", strerror(errno));
pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
errno, "Can't enable data direction info");
goto close_fail;
}
opt = 1;
if (setsockopt(handle->fd, SOL_HCI, HCI_TIME_STAMP, &opt, sizeof(opt)) < 0) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't enable time stamp: %s", strerror(errno));
pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
errno, "Can't enable time stamp");
goto close_fail;
}
@ -247,8 +259,8 @@ bt_activate(pcap_t* handle)
memset((void *) &flt.type_mask, 0xff, sizeof(flt.type_mask));
memset((void *) &flt.event_mask, 0xff, sizeof(flt.event_mask));
if (setsockopt(handle->fd, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't set filter: %s", strerror(errno));
pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
errno, "Can't set filter");
goto close_fail;
}
@ -256,13 +268,12 @@ bt_activate(pcap_t* handle)
/* Bind socket to the HCI device */
addr.hci_family = AF_BLUETOOTH;
addr.hci_dev = handlep->dev_id;
#ifdef SOCKADDR_HCI_HAS_HCI_CHANNEL
#ifdef HAVE_STRUCT_SOCKADDR_HCI_HCI_CHANNEL
addr.hci_channel = HCI_CHANNEL_RAW;
#endif
if (bind(handle->fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't attach to device %d: %s", handlep->dev_id,
strerror(errno));
pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
errno, "Can't attach to device %d", handlep->dev_id);
goto close_fail;
}
@ -281,8 +292,8 @@ bt_activate(pcap_t* handle)
if (setsockopt(handle->fd, SOL_SOCKET, SO_RCVBUF,
&handle->opt.buffer_size,
sizeof(handle->opt.buffer_size)) == -1) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"SO_RCVBUF: %s", pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(handle->errbuf,
errno, PCAP_ERRBUF_SIZE, "SO_RCVBUF");
goto close_fail;
}
}
@ -296,7 +307,7 @@ bt_activate(pcap_t* handle)
}
static int
bt_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user)
bt_read_linux(pcap_t *handle, int max_packets _U_, pcap_handler callback, u_char *user)
{
struct cmsghdr *cmsg;
struct msghdr msg;
@ -329,8 +340,8 @@ bt_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *us
} while ((ret == -1) && (errno == EINTR));
if (ret < 0) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't receive packet: %s", strerror(errno));
pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
errno, "Can't receive packet");
return -1;
}
@ -366,7 +377,7 @@ bt_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *us
}
static int
bt_inject_linux(pcap_t *handle, const void *buf, size_t size)
bt_inject_linux(pcap_t *handle, const void *buf _U_, size_t size _U_)
{
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "inject not supported on "
"bluetooth devices");
@ -389,8 +400,8 @@ bt_stats_linux(pcap_t *handle, struct pcap_stat *stats)
} while ((ret == -1) && (errno == EINTR));
if (ret < 0) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't get stats via ioctl: %s", strerror(errno));
pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
errno, "Can't get stats via ioctl");
return (-1);
}

View File

@ -34,5 +34,5 @@
/*
* Prototypes for Bluetooth-related functions
*/
int bt_findalldevs(pcap_if_t **alldevsp, char *err_str);
int bt_findalldevs(pcap_if_list_t *devlistp, char *err_str);
pcap_t *bt_create(const char *device, char *ebuf, int *is_ours);

View File

@ -30,7 +30,7 @@
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#include <config.h>
#endif
#include <errno.h>
@ -60,12 +60,21 @@ struct hci_mon_hdr {
} __attribute__((packed));
int
bt_monitor_findalldevs(pcap_if_t **alldevsp, char *err_str)
bt_monitor_findalldevs(pcap_if_list_t *devlistp, char *err_str)
{
int ret = 0;
if (pcap_add_if(alldevsp, INTERFACE_NAME, 0,
"Bluetooth Linux Monitor", err_str) < 0)
/*
* Bluetooth is a wireless technology.
*
* This is a device to monitor all Bluetooth interfaces, so
* there's no notion of "connected" or "disconnected", any
* more than there's a notion of "connected" or "disconnected"
* for the "any" device.
*/
if (add_dev(devlistp, INTERFACE_NAME,
PCAP_IF_WIRELESS|PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE,
"Bluetooth Linux Monitor", err_str) == NULL)
{
ret = -1;
}
@ -110,8 +119,8 @@ bt_monitor_read(pcap_t *handle, int max_packets _U_, pcap_handler callback, u_ch
} while ((ret == -1) && (errno == EINTR));
if (ret < 0) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't receive packet: %s", strerror(errno));
pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
errno, "Can't receive packet");
return -1;
}
@ -173,6 +182,17 @@ bt_monitor_activate(pcap_t* handle)
return PCAP_ERROR_RFMON_NOTSUP;
}
/*
* Turn a negative snapshot value (invalid), a snapshot value of
* 0 (unspecified), or a value bigger than the normal maximum
* value, into the maximum allowed value.
*
* If some application really *needs* a bigger snapshot
* length, we should just increase MAXIMUM_SNAPLEN.
*/
if (handle->snapshot <= 0 || handle->snapshot > MAXIMUM_SNAPLEN)
handle->snapshot = MAXIMUM_SNAPLEN;
handle->bufsize = BT_CONTROL_SIZE + sizeof(pcap_bluetooth_linux_monitor_header) + handle->snapshot;
handle->linktype = DLT_BLUETOOTH_LINUX_MONITOR;
@ -187,15 +207,15 @@ bt_monitor_activate(pcap_t* handle)
handle->fd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
if (handle->fd < 0) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't create raw socket: %s", strerror(errno));
pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
errno, "Can't create raw socket");
return PCAP_ERROR;
}
handle->buffer = malloc(handle->bufsize);
if (!handle->buffer) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't allocate dump buffer: %s",
pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
errno, "Can't allocate dump buffer");
goto close_fail;
}
@ -205,15 +225,15 @@ bt_monitor_activate(pcap_t* handle)
addr.hci_channel = HCI_CHANNEL_MONITOR;
if (bind(handle->fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't attach to interface: %s", strerror(errno));
pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
errno, "Can't attach to interface");
goto close_fail;
}
opt = 1;
if (setsockopt(handle->fd, SOL_SOCKET, SO_TIMESTAMP, &opt, sizeof(opt)) < 0) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't enable time stamp: %s", strerror(errno));
pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
errno, "Can't enable time stamp");
goto close_fail;
}

View File

@ -28,5 +28,5 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
int bt_monitor_findalldevs(pcap_if_t **alldevsp, char *err_str);
int bt_monitor_findalldevs(pcap_if_list_t *devlistp, char *err_str);
pcap_t *bt_monitor_create(const char *device, char *ebuf, int *is_ours);

View File

@ -18,26 +18,14 @@
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* pcap-common.c - common code for pcap and pcap-ng files
* pcap-common.c - common code for pcap and pcapng files
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#include <config.h>
#endif
#ifdef _WIN32
#include <pcap-stdinc.h>
#else /* _WIN32 */
#if HAVE_INTTYPES_H
#include <inttypes.h>
#elif HAVE_STDINT_H
#include <stdint.h>
#endif
#ifdef HAVE_SYS_BITYPES_H
#include <sys/bitypes.h>
#endif
#include <sys/types.h>
#endif /* _WIN32 */
#include <pcap-types.h>
#include "pcap-int.h"
#include "extract.h"
@ -496,9 +484,14 @@
/*
* IEEE 802.15.4, exactly as it appears in the spec (no padding, no
* nothing); requested by Mikko Saarnivala <mikko.saarnivala@sensinode.com>.
* nothing), and with the FCS at the end of the frame; requested by
* Mikko Saarnivala <mikko.saarnivala@sensinode.com>.
*
* This should only be used if the FCS is present at the end of the
* frame; if the frame has no FCS, DLT_IEEE802_15_4_NOFCS should be
* used.
*/
#define LINKTYPE_IEEE802_15_4 195
#define LINKTYPE_IEEE802_15_4_WITHFCS 195
/*
* Various link-layer types, with a pseudo-header, for SITA
@ -703,14 +696,14 @@
* the pseudo-header is:
*
* struct dl_ipnetinfo {
* u_int8_t dli_version;
* u_int8_t dli_family;
* u_int16_t dli_htype;
* u_int32_t dli_pktlen;
* u_int32_t dli_ifindex;
* u_int32_t dli_grifindex;
* u_int32_t dli_zsrc;
* u_int32_t dli_zdst;
* uint8_t dli_version;
* uint8_t dli_family;
* uint16_t dli_htype;
* uint32_t dli_pktlen;
* uint32_t dli_ifindex;
* uint32_t dli_grifindex;
* uint32_t dli_zsrc;
* uint32_t dli_zdst;
* };
*
* dli_version is 2 for the current version of the pseudo-header.
@ -887,7 +880,7 @@
/*
* pfsync output; DLT_PFSYNC is 18, which collides with DLT_CIP in
* SuSE 6.3, on OpenBSD, NetBSD, DragonFly BSD, and Mac OS X, and
* SuSE 6.3, on OpenBSD, NetBSD, DragonFly BSD, and macOS, and
* is 121, which collides with DLT_HHDLC, in FreeBSD. We pick a
* shiny new link-layer header type value that doesn't collide with
* anything, in the hopes that future pfsync savefiles, if any,
@ -984,7 +977,7 @@
* So I'll just give them one; hopefully this will show up in a
* libpcap release in time for them to get this into 10.10 Big Sur
* or whatever Mavericks' successor is called. LINKTYPE_PKTAP
* will be 258 *even on OS X*; that is *intentional*, so that
* will be 258 *even on macOS*; that is *intentional*, so that
* PKTAP files look the same on *all* OSes (different OSes can have
* different numerical values for a given DLT_, but *MUST NOT* have
* different values for what goes in a file, as files can be moved
@ -1028,7 +1021,67 @@
*/
#define LINKTYPE_RDS 265
#define LINKTYPE_MATCHING_MAX 265 /* highest value in the "matching" range */
/*
* USB packets, beginning with a Darwin (macOS, etc.) header.
*/
#define LINKTYPE_USB_DARWIN 266
/*
* OpenBSD DLT_OPENFLOW.
*/
#define LINKTYPE_OPENFLOW 267
/*
* SDLC frames containing SNA PDUs.
*/
#define LINKTYPE_SDLC 268
/*
* per "Selvig, Bjorn" <b.selvig@ti.com> used for
* TI protocol sniffer.
*/
#define LINKTYPE_TI_LLN_SNIFFER 269
/*
* per: Erik de Jong <erikdejong at gmail.com> for
* https://github.com/eriknl/LoRaTap/releases/tag/v0.1
*/
#define LINKTYPE_LORATAP 270
/*
* per: Stefanha at gmail.com for
* http://lists.sandelman.ca/pipermail/tcpdump-workers/2017-May/000772.html
* and: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/vsockmon.h
* for: http://qemu-project.org/Features/VirtioVsock
*/
#define LINKTYPE_VSOCK 271
/*
* Nordic Semiconductor Bluetooth LE sniffer.
*/
#define LINKTYPE_NORDIC_BLE 272
/*
* Excentis DOCSIS 3.1 RF sniffer (XRA-31)
* per: bruno.verstuyft at excentis.com
* http://www.xra31.com/xra-header
*/
#define LINKTYPE_DOCSIS31_XRA31 273
/*
* mPackets, as specified by IEEE 802.3br Figure 99-4, starting
* with the preamble and always ending with a CRC field.
*/
#define LINKTYPE_ETHERNET_MPACKET 274
/*
* DisplayPort AUX channel monitoring data as specified by VESA
* DisplayPort(DP) Standard preceeded by a pseudo-header.
* per dirk.eibach at gdsys.cc
*/
#define LINKTYPE_DISPLAYPORT_AUX 275
#define LINKTYPE_MATCHING_MAX 275 /* highest value in the "matching" range */
static struct linktype_map {
int dlt;
@ -1175,7 +1228,22 @@ linktype_to_dlt(int linktype)
return linktype;
}
#define EXTRACT_
/*
* Return the maximum snapshot length for a given DLT_ value.
*
* For most link-layer types, we use MAXIMUM_SNAPLEN, but for DLT_DBUS,
* the maximum is 134217728, as per
*
* https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-messages
*/
u_int
max_snaplen_for_dlt(int dlt)
{
if (dlt == DLT_DBUS)
return 134217728;
else
return MAXIMUM_SNAPLEN;
}
/*
* DLT_LINUX_SLL packets with a protocol type of LINUX_SLL_P_CAN or
@ -1192,7 +1260,7 @@ swap_linux_sll_header(const struct pcap_pkthdr *hdr, u_char *buf)
u_int caplen = hdr->caplen;
u_int length = hdr->len;
struct sll_header *shdr = (struct sll_header *)buf;
u_int16_t protocol;
uint16_t protocol;
pcap_can_socketcan_hdr *chdr;
if (caplen < (u_int) sizeof(struct sll_header) ||
@ -1338,7 +1406,7 @@ swap_linux_usb_header(const struct pcap_pkthdr *hdr, u_char *buf,
if (uhdr->transfer_type == URB_ISOCHRONOUS) {
/* swap the values in struct linux_usb_isodesc */
usb_isodesc *pisodesc;
u_int32_t i;
uint32_t i;
pisodesc = (usb_isodesc *)(void *)(buf+offset);
for (i = 0; i < uhdr->ndesc; i++) {
@ -1384,7 +1452,7 @@ swap_nflog_header(const struct pcap_pkthdr *hdr, u_char *buf)
nflog_tlv_t *tlv;
u_int caplen = hdr->caplen;
u_int length = hdr->len;
u_int16_t size;
uint16_t size;
if (caplen < (u_int) sizeof(nflog_hdr_t) ||
length < (u_int) sizeof(nflog_hdr_t)) {

View File

@ -1,3 +1,25 @@
/*
* Copyright (c) 1993, 1994, 1995, 1996, 1997
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that: (1) source code distributions
* retain the above copyright notice and this paragraph in its entirety, (2)
* distributions including binary code include the above copyright notice and
* this paragraph in its entirety in the documentation or other materials
* provided with the distribution, and (3) all advertising materials mentioning
* features or use of this software display the following acknowledgement:
* ``This product includes software developed by the University of California,
* Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
* the University nor the names of its contributors may be used to endorse
* or promote products derived from this software without specific prior
* written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* pcap-common.h - common code for pcap and pcapng files
*/
/*
* We use the "receiver-makes-right" approach to byte order,
@ -23,3 +45,5 @@ extern int linktype_to_dlt(int linktype);
extern void swap_pseudo_headers(int linktype, struct pcap_pkthdr *hdr,
u_char *data);
extern u_int max_snaplen_for_dlt(int dlt);

View File

@ -4,12 +4,17 @@
# Script to give the appropriate compiler flags and linker flags
# to use when building code that uses libpcap.
#
# These variables come from the configure script, so includedir and
# libdir may be defined in terms of prefix and exec_prefix, so the
# latter must be defined as well.
#
prefix="@prefix@"
exec_prefix="@exec_prefix@"
includedir="@includedir@"
libdir="@libdir@"
V_RPATH_OPT="@V_RPATH_OPT@"
LIBS="@LIBS@"
PACKAGE_NAME="@PACKAGE_NAME@"
static=0
show_cflags=0
@ -75,7 +80,7 @@ else
#
if [ "$show_cflags" = 1 -a "$show_libs" = 1 ]
then
echo "-I$includedir -L$libdir $RPATH -lpcap"
echo "-I$includedir -L$libdir $RPATH -l$PACKAGE_NAME"
elif [ "$show_cflags" = 1 -a "$show_additional_libs" = 1 ]
then
echo "-I$includedir"
@ -84,6 +89,6 @@ else
echo "-I$includedir"
elif [ "$show_libs" = 1 ]
then
echo "-L$libdir $RPATH -lpcap"
echo "-L$libdir $RPATH -l$PACKAGE_NAME"
fi
fi

File diff suppressed because it is too large Load Diff

View File

@ -9,4 +9,4 @@
*/
pcap_t *dag_create(const char *, char *, int *);
int dag_findalldevs(pcap_if_t **devlistp, char *errbuf);
int dag_findalldevs(pcap_if_list_t *devlistp, char *errbuf);

View File

@ -29,7 +29,7 @@
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#include <config.h>
#endif
#include <string.h>
@ -51,7 +51,7 @@ struct pcap_dbus {
};
static int
dbus_read(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user)
dbus_read(pcap_t *handle, int max_packets _U_, pcap_handler callback, u_char *user)
{
struct pcap_dbus *handlep = handle->priv;
@ -145,6 +145,28 @@ dbus_cleanup(pcap_t *handle)
pcap_cleanup_live_common(handle);
}
/*
* We don't support non-blocking mode. I'm not sure what we'd
* do to support it and, given that we don't support select()/
* poll()/epoll_wait()/kevent() etc., it probably doesn't
* matter.
*/
static int
dbus_getnonblock(pcap_t *p)
{
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"Non-blocking mode isn't supported for capturing on D-Bus");
return (-1);
}
static int
dbus_setnonblock(pcap_t *p, int nonblock _U_)
{
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"Non-blocking mode isn't supported for capturing on D-Bus");
return (-1);
}
static int
dbus_activate(pcap_t *handle)
{
@ -208,11 +230,36 @@ dbus_activate(pcap_t *handle)
handle->setfilter_op = install_bpf_program; /* XXX, later add support for dbus_bus_add_match() */
handle->setdirection_op = NULL;
handle->set_datalink_op = NULL; /* can't change data link type */
handle->getnonblock_op = pcap_getnonblock_fd;
handle->setnonblock_op = pcap_setnonblock_fd;
handle->getnonblock_op = dbus_getnonblock;
handle->setnonblock_op = dbus_setnonblock;
handle->stats_op = dbus_stats;
handle->cleanup_op = dbus_cleanup;
#ifndef _WIN32
/*
* Unfortunately, trying to do a select()/poll()/epoll_wait()/
* kevent()/etc. on a D-Bus connection isn't a simple
* case of "give me an FD on which to wait".
*
* Apparently, you have to register "add watch", "remove watch",
* and "toggle watch" functions with
* dbus_connection_set_watch_functions(),
* keep a *set* of FDs, add to that set in the "add watch"
* function, subtract from it in the "remove watch" function,
* and either add to or subtract from that set in the "toggle
* watch" function, and do the wait on *all* of the FDs in the
* set. (Yes, you need the "toggle watch" function, so that
* the main loop doesn't itself need to check for whether
* a given watch is enabled or disabled - most libpcap programs
* know nothing about D-Bus and shouldn't *have* to know anything
* about D-Bus other than how to decode D-Bus messages.)
*
* Implementing that would require considerable changes in
* the way libpcap exports "selectable FDs" to its client.
* Until that's done, we just say "you can't do that".
*/
handle->selectable_fd = handle->fd = -1;
#endif
if (handle->opt.rfmon) {
/*
@ -222,6 +269,14 @@ dbus_activate(pcap_t *handle)
return PCAP_ERROR_RFMON_NOTSUP;
}
/*
* Turn a negative snapshot value (invalid), a snapshot value of
* 0 (unspecified), or a value bigger than the normal maximum
* value, into the maximum message length for D-Bus (128MB).
*/
if (handle->snapshot <= 0 || handle->snapshot > 134217728)
handle->snapshot = 134217728;
/* dbus_connection_set_max_message_size(handlep->conn, handle->snapshot); */
if (handle->opt.buffer_size != 0)
dbus_connection_set_max_received_size(handlep->conn, handle->opt.buffer_size);
@ -264,15 +319,32 @@ dbus_create(const char *device, char *ebuf, int *is_ours)
return (NULL);
p->activate_op = dbus_activate;
/*
* Set these up front, so that, even if our client tries
* to set non-blocking mode before we're activated, or
* query the state of non-blocking mode, they get an error,
* rather than having the non-blocking mode option set
* for use later.
*/
p->getnonblock_op = dbus_getnonblock;
p->setnonblock_op = dbus_setnonblock;
return (p);
}
int
dbus_findalldevs(pcap_if_t **alldevsp, char *err_str)
dbus_findalldevs(pcap_if_list_t *devlistp, char *err_str)
{
if (pcap_add_if(alldevsp, "dbus-system", 0, "D-Bus system bus", err_str) < 0)
/*
* The notion of "connected" vs. "disconnected" doesn't apply.
* XXX - what about the notions of "up" and "running"?
*/
if (add_dev(devlistp, "dbus-system",
PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE, "D-Bus system bus",
err_str) == NULL)
return -1;
if (pcap_add_if(alldevsp, "dbus-session", 0, "D-Bus session bus", err_str) < 0)
if (add_dev(devlistp, "dbus-session",
PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE, "D-Bus session bus",
err_str) == NULL)
return -1;
return 0;
}

View File

@ -1,2 +1,2 @@
pcap_t *dbus_create(const char *, char *, int *);
int dbus_findalldevs(pcap_if_t **devlistp, char *errbuf);
int dbus_findalldevs(pcap_if_list_t *devlistp, char *errbuf);

36
pcap-dll.rc Normal file
View File

@ -0,0 +1,36 @@
#include "config.h"
#include <winver.h>
VS_VERSION_INFO VERSIONINFO
FILEVERSION PACKAGE_VERSION_DLL
PRODUCTVERSION PACKAGE_VERSION_DLL
FILEFLAGSMASK 0x3fL
FILEOS VOS__WINDOWS32
FILETYPE VFT_DLL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "Comments", "https://github.com/the-tcpdump-group/libpcap/"
VALUE "CompanyName", "The TCPdump Group"
VALUE "FileDescription", "System-Independent Interface for User-Level Packet Capture"
VALUE "FileVersion", "PACKAGE_VERSION_DLL"
VALUE "InternalName", PACKAGE_NAME
VALUE "LegalCopyright", "Copyright (c) The TCPdump Group"
VALUE "LegalTrademarks", ""
VALUE "OriginalFilename", "wpcap.dll"
VALUE "ProductName", PACKAGE_NAME
VALUE "ProductVersion", PACKAGE_VERSION
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x0, 1200
END
END

View File

@ -69,7 +69,7 @@
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#include <config.h>
#endif
#include <sys/types.h>
@ -122,18 +122,29 @@
#include "os-proto.h"
#endif
#ifndef PCAP_DEV_PREFIX
#ifdef _AIX
#define PCAP_DEV_PREFIX "/dev/dlpi"
#else
#define PCAP_DEV_PREFIX "/dev"
#endif
#if defined(__hpux)
/*
* HP-UX has a /dev/dlpi device; you open it and set the PPA of the actual
* network device you want.
*/
#define HAVE_DEV_DLPI
#elif defined(_AIX)
/*
* AIX has a /dev/dlpi directory, with devices named after the interfaces
* underneath it.
*/
#define PCAP_DEV_PREFIX "/dev/dlpi"
#elif defined(HAVE_SOLARIS)
/*
* Solaris has devices named after the interfaces underneath /dev.
*/
#define PCAP_DEV_PREFIX "/dev"
#endif
#define MAXDLBUF 8192
/* Forwards */
static char *split_dname(char *, int *, char *);
static char *split_dname(char *, u_int *, char *);
static int dl_doattach(int, int, char *);
#ifdef DL_HP_RAWDLS
static int dl_dohpuxbind(int, char *);
@ -145,7 +156,7 @@ static int dlokack(int, const char *, char *, char *);
static int dlinforeq(int, char *);
static int dlinfoack(int, char *, char *);
#ifdef HAVE_DLPI_PASSIVE
#ifdef HAVE_DL_PASSIVE_REQ_T
static void dlpassive(int, char *);
#endif
@ -165,7 +176,7 @@ static int send_request(int, char *, int, char *, char *);
static int dlpi_kread(int, off_t, void *, u_int, char *);
#endif
#ifdef HAVE_DEV_DLPI
static int get_dlpi_ppa(int, const char *, int, char *);
static int get_dlpi_ppa(int, const char *, u_int, u_int *, char *);
#endif
/*
@ -227,8 +238,8 @@ pcap_read_dlpi(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
case EAGAIN:
return (0);
}
strlcpy(p->errbuf, pcap_strerror(errno),
sizeof(p->errbuf));
pcap_fmt_errmsg_for_errno(p->errbuf,
sizeof(p->errbuf), errno, "getmsg");
return (-1);
}
cc = data.len;
@ -251,8 +262,8 @@ pcap_inject_dlpi(pcap_t *p, const void *buf, size_t size)
#if defined(DLIOCRAW)
ret = write(p->fd, buf, size);
if (ret == -1) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
errno, "send");
return (-1);
}
#elif defined(DL_HP_RAWDLS)
@ -263,8 +274,8 @@ pcap_inject_dlpi(pcap_t *p, const void *buf, size_t size)
}
ret = dlrawdatareq(pd->send_fd, buf, size);
if (ret == -1) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
errno, "send");
return (-1);
}
/*
@ -334,13 +345,15 @@ pcap_cleanup_dlpi(pcap_t *p)
}
static int
open_dlpi_device(const char *name, int *ppa, char *errbuf)
open_dlpi_device(const char *name, u_int *ppa, char *errbuf)
{
int status;
char dname[100];
char *cp;
int fd;
#ifndef HAVE_DEV_DLPI
#ifdef HAVE_DEV_DLPI
u_int unit;
#else
char dname2[100];
#endif
@ -358,7 +371,7 @@ open_dlpi_device(const char *name, int *ppa, char *errbuf)
* Split the device name into a device type name and a unit number;
* chop off the unit number, so "dname" is just a device type name.
*/
cp = split_dname(dname, ppa, errbuf);
cp = split_dname(dname, &unit, errbuf);
if (cp == NULL)
return (PCAP_ERROR_NO_SUCH_DEVICE);
*cp = '\0';
@ -380,8 +393,8 @@ open_dlpi_device(const char *name, int *ppa, char *errbuf)
status = PCAP_ERROR_PERM_DENIED;
else
status = PCAP_ERROR;
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"%s: %s", cp, pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
errno, "%s", cp);
return (status);
}
@ -389,10 +402,10 @@ open_dlpi_device(const char *name, int *ppa, char *errbuf)
* Get a table of all PPAs for that device, and search that
* table for the specified device type name and unit number.
*/
*ppa = get_dlpi_ppa(fd, dname, *ppa, errbuf);
if (*ppa < 0) {
status = get_dlpi_ppa(fd, dname, unit, ppa, errbuf);
if (status < 0) {
close(fd);
return (*ppa);
return (status);
}
#else
/*
@ -429,8 +442,8 @@ open_dlpi_device(const char *name, int *ppa, char *errbuf)
status = PCAP_ERROR_PERM_DENIED;
else
status = PCAP_ERROR;
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", dname,
pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
errno, "%s", dname);
return (status);
}
@ -469,8 +482,8 @@ open_dlpi_device(const char *name, int *ppa, char *errbuf)
status = PCAP_ERROR_PERM_DENIED;
else
status = PCAP_ERROR;
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s",
dname2, pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(errbuf,
PCAP_ERRBUF_SIZE, errno, "%s", dname2);
}
return (status);
}
@ -489,7 +502,7 @@ pcap_activate_dlpi(pcap_t *p)
#endif
int status = 0;
int retv;
int ppa;
u_int ppa;
#ifdef HAVE_SOLARIS
int isatm = 0;
#endif
@ -563,7 +576,7 @@ pcap_activate_dlpi(pcap_t *p)
goto bad;
}
#ifdef HAVE_DLPI_PASSIVE
#ifdef HAVE_DL_PASSIVE_REQ_T
/*
* Enable Passive mode to be able to capture on aggregated link.
* Not supported in all Solaris versions.
@ -632,6 +645,17 @@ pcap_activate_dlpi(pcap_t *p)
#endif /* AIX vs. HP-UX vs. other */
#endif /* !HP-UX 9 and !HP-UX 10.20 or later and !SINIX */
/*
* Turn a negative snapshot value (invalid), a snapshot value of
* 0 (unspecified), or a value bigger than the normal maximum
* value, into the maximum allowed value.
*
* If some application really *needs* a bigger snapshot
* length, we should just increase MAXIMUM_SNAPLEN.
*/
if (p->snapshot <= 0 || p->snapshot > MAXIMUM_SNAPLEN)
p->snapshot = MAXIMUM_SNAPLEN;
#ifdef HAVE_SOLARIS
if (isatm) {
/*
@ -642,8 +666,8 @@ pcap_activate_dlpi(pcap_t *p)
*/
if (strioctl(p->fd, A_PROMISCON_REQ, 0, NULL) < 0) {
status = PCAP_ERROR;
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"A_PROMISCON_REQ: %s", pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
errno, "A_PROMISCON_REQ");
goto bad;
}
} else
@ -760,8 +784,8 @@ pcap_activate_dlpi(pcap_t *p)
*/
if (strioctl(p->fd, DLIOCRAW, 0, NULL) < 0) {
status = PCAP_ERROR;
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "DLIOCRAW: %s",
pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
errno, "DLIOCRAW");
goto bad;
}
#endif
@ -801,8 +825,8 @@ pcap_activate_dlpi(pcap_t *p)
*/
if (ioctl(p->fd, I_FLUSH, FLUSHR) != 0) {
status = PCAP_ERROR;
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "FLUSHR: %s",
pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
errno, "FLUSHR");
goto bad;
}
@ -845,7 +869,7 @@ pcap_activate_dlpi(pcap_t *p)
* Returns NULL on error, and fills "ebuf" with an error message.
*/
static char *
split_dname(char *device, int *unitp, char *ebuf)
split_dname(char *device, u_int *unitp, char *ebuf)
{
char *cp;
char *eos;
@ -881,7 +905,7 @@ split_dname(char *device, int *unitp, char *ebuf)
device);
return (NULL);
}
*unitp = (int)unit;
*unitp = (u_int)unit;
return (cp);
}
@ -986,7 +1010,7 @@ static int
is_dlpi_interface(const char *name)
{
int fd;
int ppa;
u_int ppa;
char errbuf[PCAP_ERRBUF_SIZE];
fd = open_dlpi_device(name, &ppa, errbuf);
@ -1025,8 +1049,31 @@ is_dlpi_interface(const char *name)
return (1);
}
static int
get_if_flags(const char *name _U_, bpf_u_int32 *flags _U_, char *errbuf _U_)
{
/*
* Nothing we can do other than mark loopback devices as "the
* connected/disconnected status doesn't apply".
*
* XXX - on Solaris, can we do what the dladm command does,
* i.e. get a connected/disconnected indication from a kstat?
* (Note that you can also get the link speed, and possibly
* other information, from a kstat as well.)
*/
if (*flags & PCAP_IF_LOOPBACK) {
/*
* Loopback devices aren't wireless, and "connected"/
* "disconnected" doesn't apply to them.
*/
*flags |= PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE;
return (0);
}
return (0);
}
int
pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
pcap_platform_finddevs(pcap_if_list_t *devlistp, char *errbuf)
{
#ifdef HAVE_SOLARIS
int fd;
@ -1042,7 +1089,8 @@ pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
/*
* Get the list of regular interfaces first.
*/
if (pcap_findalldevs_interfaces(alldevsp, errbuf, is_dlpi_interface) == -1)
if (pcap_findalldevs_interfaces(devlistp, errbuf, is_dlpi_interface,
get_if_flags) == -1)
return (-1); /* failure */
#ifdef HAVE_SOLARIS
@ -1062,13 +1110,18 @@ pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
}
if (strioctl(fd, A_GET_UNITS, sizeof(buf), (char *)&buf) < 0) {
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "A_GET_UNITS: %s",
pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
errno, "A_GET_UNITS");
return (-1);
}
for (i = 0; i < buf.nunits; i++) {
pcap_snprintf(baname, sizeof baname, "ba%u", i);
if (pcap_add_if(alldevsp, baname, 0, NULL, errbuf) < 0)
/*
* XXX - is there a notion of "up" and "running"?
* And is there a way to determine whether the
* interface is plugged into a network?
*/
if (add_dev(devlistp, baname, 0, NULL, errbuf) == NULL)
return (-1);
}
#endif
@ -1088,9 +1141,8 @@ send_request(int fd, char *ptr, int len, char *what, char *ebuf)
flags = 0;
if (putmsg(fd, &ctl, (struct strbuf *) NULL, flags) < 0) {
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
"send_request: putmsg \"%s\": %s",
what, pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
errno, "send_request: putmsg \"%s\"", what);
return (-1);
}
return (0);
@ -1118,8 +1170,8 @@ recv_ack(int fd, int size, const char *what, char *bufp, char *ebuf, int *uerror
flags = 0;
if (getmsg(fd, &ctl, (struct strbuf*)NULL, &flags) < 0) {
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "recv_ack: %s getmsg: %s",
what, pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
errno, "recv_ack: %s getmsg", what);
return (PCAP_ERROR);
}
@ -1141,9 +1193,9 @@ recv_ack(int fd, int size, const char *what, char *bufp, char *ebuf, int *uerror
case DL_SYSERR:
if (uerror != NULL)
*uerror = dlp->error_ack.dl_unix_errno;
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
"recv_ack: %s: UNIX error - %s",
what, pcap_strerror(dlp->error_ack.dl_unix_errno));
pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
dlp->error_ack.dl_unix_errno,
"recv_ack: %s: UNIX error", what);
if (dlp->error_ack.dl_unix_errno == EPERM ||
dlp->error_ack.dl_unix_errno == EACCES)
return (PCAP_ERROR_PERM_DENIED);
@ -1430,7 +1482,7 @@ dlinfoack(int fd, char *bufp, char *ebuf)
return (recv_ack(fd, DL_INFO_ACK_SIZE, "info", bufp, ebuf, NULL));
}
#ifdef HAVE_DLPI_PASSIVE
#ifdef HAVE_DL_PASSIVE_REQ_T
/*
* Enable DLPI passive mode. We do not care if this request fails, as this
* indicates the underlying DLPI device does not support link aggregation.
@ -1552,12 +1604,12 @@ echo 'lanc_outbound_promisc_flag/W1' | /usr/bin/adb -w /stand/vmunix /dev/kmem
* Setting the variable is not necessary on HP-UX 11.x.
*/
static int
get_dlpi_ppa(register int fd, register const char *device, register int unit,
register char *ebuf)
get_dlpi_ppa(register int fd, register const char *device, register u_int unit,
u_int *ppa, register char *ebuf)
{
register dl_hp_ppa_ack_t *ap;
register dl_hp_ppa_info_t *ipstart, *ip;
register int i;
register u_int i;
char dname[100];
register u_long majdev;
struct stat statbuf;
@ -1567,7 +1619,6 @@ get_dlpi_ppa(register int fd, register const char *device, register int unit,
dl_hp_ppa_ack_t *dlp;
struct strbuf ctl;
int flags;
int ppa;
memset((char *)&req, 0, sizeof(req));
req.dl_primitive = DL_HP_PPA_REQ;
@ -1595,8 +1646,13 @@ get_dlpi_ppa(register int fd, register const char *device, register int unit,
*/
/* get the head first */
if (getmsg(fd, &ctl, (struct strbuf *)NULL, &flags) < 0) {
pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
errno, "get_dlpi_ppa: hpppa getmsg");
return (PCAP_ERROR);
}
if (ctl.len == -1) {
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
"get_dlpi_ppa: hpppa getmsg: %s", pcap_strerror(errno));
"get_dlpi_ppa: hpppa getmsg: control buffer has no data");
return (PCAP_ERROR);
}
@ -1608,7 +1664,7 @@ get_dlpi_ppa(register int fd, register const char *device, register int unit,
return (PCAP_ERROR);
}
if (ctl.len < DL_HP_PPA_ACK_SIZE) {
if ((size_t)ctl.len < DL_HP_PPA_ACK_SIZE) {
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
"get_dlpi_ppa: hpppa ack too small (%d < %lu)",
ctl.len, (unsigned long)DL_HP_PPA_ACK_SIZE);
@ -1617,8 +1673,8 @@ get_dlpi_ppa(register int fd, register const char *device, register int unit,
/* allocate buffer */
if ((ppa_data_buf = (char *)malloc(dlp->dl_length)) == NULL) {
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
"get_dlpi_ppa: hpppa malloc: %s", pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
errno, "get_dlpi_ppa: hpppa malloc");
return (PCAP_ERROR);
}
ctl.maxlen = dlp->dl_length;
@ -1626,12 +1682,17 @@ get_dlpi_ppa(register int fd, register const char *device, register int unit,
ctl.buf = (char *)ppa_data_buf;
/* get the data */
if (getmsg(fd, &ctl, (struct strbuf *)NULL, &flags) < 0) {
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
"get_dlpi_ppa: hpppa getmsg: %s", pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
errno, "get_dlpi_ppa: hpppa getmsg");
free(ppa_data_buf);
return (PCAP_ERROR);
}
if (ctl.len < dlp->dl_length) {
if (ctl.len == -1) {
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
"get_dlpi_ppa: hpppa getmsg: control buffer has no data");
return (PCAP_ERROR);
}
if ((u_int)ctl.len < dlp->dl_length) {
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
"get_dlpi_ppa: hpppa ack too small (%d < %lu)",
ctl.len, (unsigned long)dlp->dl_length);
@ -1643,7 +1704,7 @@ get_dlpi_ppa(register int fd, register const char *device, register int unit,
ipstart = (dl_hp_ppa_info_t *)ppa_data_buf;
ip = ipstart;
#ifdef HAVE_HP_PPA_INFO_T_DL_MODULE_ID_1
#ifdef HAVE_DL_HP_PPA_INFO_T_DL_MODULE_ID_1
/*
* The "dl_hp_ppa_info_t" structure has a "dl_module_id_1"
* member that should, in theory, contain the part of the
@ -1689,10 +1750,10 @@ get_dlpi_ppa(register int fd, register const char *device, register int unit,
* device number of a device with the name "/dev/<dev><unit>",
* if such a device exists, as the old code did.
*/
pcap_snprintf(dname, sizeof(dname), "/dev/%s%d", device, unit);
pcap_snprintf(dname, sizeof(dname), "/dev/%s%u", device, unit);
if (stat(dname, &statbuf) < 0) {
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "stat: %s: %s",
dname, pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
errno, "stat: %s", dname);
return (PCAP_ERROR);
}
majdev = major(statbuf.st_rdev);
@ -1709,7 +1770,7 @@ get_dlpi_ppa(register int fd, register const char *device, register int unit,
}
if (i == ap->dl_count) {
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
"can't find /dev/dlpi PPA for %s%d", device, unit);
"can't find /dev/dlpi PPA for %s%u", device, unit);
return (PCAP_ERROR_NO_SUCH_DEVICE);
}
if (ip->dl_hdw_state == HDW_DEAD) {
@ -1718,9 +1779,9 @@ get_dlpi_ppa(register int fd, register const char *device, register int unit,
free(ppa_data_buf);
return (PCAP_ERROR);
}
ppa = ip->dl_ppa;
*ppa = ip->dl_ppa;
free(ppa_data_buf);
return (ppa);
return (0);
}
#endif
@ -1739,8 +1800,8 @@ static char path_vmunix[] = "/hp-ux";
/* Determine ppa number that specifies ifname */
static int
get_dlpi_ppa(register int fd, register const char *ifname, register int unit,
register char *ebuf)
get_dlpi_ppa(register int fd, register const char *ifname, register u_int unit,
u_int *ppa, register char *ebuf)
{
register const char *cp;
register int kd;
@ -1754,24 +1815,24 @@ get_dlpi_ppa(register int fd, register const char *ifname, register int unit,
if (nlist(path_vmunix, &nl) < 0) {
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "nlist %s failed",
path_vmunix);
return (-1);
return (PCAP_ERROR);
}
if (nl[NL_IFNET].n_value == 0) {
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
"could't find %s kernel symbol",
nl[NL_IFNET].n_name);
return (-1);
return (PCAP_ERROR);
}
kd = open("/dev/kmem", O_RDONLY);
if (kd < 0) {
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "kmem open: %s",
pcap_strerror(errno));
return (-1);
pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
errno, "kmem open");
return (PCAP_ERROR);
}
if (dlpi_kread(kd, nl[NL_IFNET].n_value,
&addr, sizeof(addr), ebuf) < 0) {
close(kd);
return (-1);
return (PCAP_ERROR);
}
for (; addr != NULL; addr = ifnet.if_next) {
if (dlpi_kread(kd, (off_t)addr,
@ -1779,15 +1840,17 @@ get_dlpi_ppa(register int fd, register const char *ifname, register int unit,
dlpi_kread(kd, (off_t)ifnet.if_name,
if_name, sizeof(ifnet.if_name), ebuf) < 0) {
(void)close(kd);
return (-1);
return (PCAP_ERROR);
}
if_name[sizeof(ifnet.if_name)] = '\0';
if (strcmp(if_name, ifname) == 0 && ifnet.if_unit == unit)
return (ifnet.if_index);
if (strcmp(if_name, ifname) == 0 && ifnet.if_unit == unit) {
*ppa = ifnet.if_index;
return (0);
}
}
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "Can't find %s", ifname);
return (-1);
return (PCAP_ERROR_NO_SUCH_DEVICE);
}
static int
@ -1797,14 +1860,14 @@ dlpi_kread(register int fd, register off_t addr,
register int cc;
if (lseek(fd, addr, SEEK_SET) < 0) {
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "lseek: %s",
pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
errno, "lseek");
return (-1);
}
cc = read(fd, buf, len);
if (cc < 0) {
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "read: %s",
pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
errno, "read");
return (-1);
} else if (cc != len) {
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "short read (%d != %d)", cc,
@ -1835,3 +1898,12 @@ pcap_create_interface(const char *device _U_, char *ebuf)
p->activate_op = pcap_activate_dlpi;
return (p);
}
/*
* Libpcap version string.
*/
const char *
pcap_lib_version(void)
{
return (PCAP_VERSION_STRING);
}

View File

@ -174,6 +174,17 @@ static int pcap_activate_dos (pcap_t *pcap)
return (PCAP_ERROR_RFMON_NOTSUP);
}
/*
* Turn a negative snapshot value (invalid), a snapshot value of
* 0 (unspecified), or a value bigger than the normal maximum
* value, into the maximum allowed value.
*
* If some application really *needs* a bigger snapshot
* length, we should just increase MAXIMUM_SNAPLEN.
*/
if (pcap->snapshot <= 0 || pcap->snapshot > MAXIMUM_SNAPLEN)
pcap->snapshot = MAXIMUM_SNAPLEN;
if (pcap->snapshot < ETH_MIN+8)
pcap->snapshot = ETH_MIN+8;
@ -197,6 +208,7 @@ static int pcap_activate_dos (pcap_t *pcap)
if (!init_watt32(pcap, pcap->opt.device, pcap->errbuf) ||
!first_init(pcap->opt.device, pcap->errbuf, pcap->opt.promisc))
{
/* XXX - free pcap->buffer? */
return (PCAP_ERROR);
}
atexit (close_driver);
@ -206,6 +218,7 @@ static int pcap_activate_dos (pcap_t *pcap)
pcap_snprintf (pcap->errbuf, PCAP_ERRBUF_SIZE,
"Cannot use different devices simultaneously "
"(`%s' vs. `%s')", active_dev->name, pcap->opt.device);
/* XXX - free pcap->buffer? */
return (PCAP_ERROR);
}
handle_to_device [pcap->fd-1] = active_dev;
@ -467,6 +480,7 @@ static void pcap_cleanup_dos (pcap_t *p)
return;
}
close_driver();
/* XXX - call pcap_cleanup_live_common? */
}
/*
@ -539,17 +553,18 @@ int pcap_lookupnet (const char *device, bpf_u_int32 *localnet,
/*
* Get a list of all interfaces that are present and that we probe okay.
* Returns -1 on error, 0 otherwise.
* The list, as returned through "alldevsp", may be NULL if no interfaces
* were up and could be opened.
* The list may be NULL epty if no interfaces were up and could be opened.
*/
int pcap_platform_finddevs (pcap_if_t **alldevsp, char *errbuf)
int pcap_platform_finddevs (pcap_if_list_t *devlistp, char *errbuf)
{
struct device *dev;
pcap_if_t *curdev;
#if 0 /* Pkt drivers should have no addresses */
struct sockaddr_in sa_ll_1, sa_ll_2;
struct sockaddr *addr, *netmask, *broadaddr, *dstaddr;
pcap_if_t *devlist = NULL;
#endif
int ret = 0;
size_t addr_size = sizeof(*addr);
int found = 0;
for (dev = (struct device*)dev_base; dev; dev = dev->next)
{
@ -562,6 +577,20 @@ int pcap_platform_finddevs (pcap_if_t **alldevsp, char *errbuf)
FLUSHK();
(*dev->close) (dev);
/*
* XXX - find out whether it's up or running? Does that apply here?
* Can we find out if anything's plugged into the adapter, if it's
* a wired device, and set PCAP_IF_CONNECTION_STATUS_CONNECTED
* or PCAP_IF_CONNECTION_STATUS_DISCONNECTED?
*/
if ((curdev = add_dev(devlistp, dev->name, 0,
dev->long_name, errbuf)) == NULL)
{
ret = -1;
break;
}
found = 1;
#if 0 /* Pkt drivers should have no addresses */
memset (&sa_ll_1, 0, sizeof(sa_ll_1));
memset (&sa_ll_2, 0, sizeof(sa_ll_2));
sa_ll_1.sin_family = AF_INET;
@ -573,16 +602,10 @@ int pcap_platform_finddevs (pcap_if_t **alldevsp, char *errbuf)
broadaddr = (struct sockaddr*) &sa_ll_2;
memset (&sa_ll_2.sin_addr, 0xFF, sizeof(sa_ll_2.sin_addr));
if (pcap_add_if(&devlist, dev->name, dev->flags,
dev->long_name, errbuf) < 0)
{
ret = -1;
break;
}
#if 0 /* Pkt drivers should have no addresses */
if (add_addr_to_iflist(&devlist, dev->name, dev->flags, addr, addr_size,
netmask, addr_size, broadaddr, addr_size,
dstaddr, addr_size, errbuf) < 0)
if (add_addr_to_dev(curdev, addr, sizeof(*addr),
netmask, sizeof(*netmask),
broadaddr, sizeof(*broadaddr),
dstaddr, sizeof(*dstaddr), errbuf) < 0)
{
ret = -1;
break;
@ -590,16 +613,9 @@ int pcap_platform_finddevs (pcap_if_t **alldevsp, char *errbuf)
#endif
}
if (devlist && ret < 0)
{
pcap_freealldevs (devlist);
devlist = NULL;
}
else
if (!devlist)
if (ret == 0 && !found)
strcpy (errbuf, "No drivers found");
*alldevsp = devlist;
return (ret);
}
@ -1510,3 +1526,11 @@ static void pktq_clear (struct rx_ringbuf *q)
#endif /* USE_32BIT_DRIVERS */
/*
* Libpcap version string.
*/
const char *
pcap_lib_version(void)
{
return ("DOS-" PCAP_VERSION_STRING);
}

View File

@ -8,7 +8,7 @@
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#include <config.h>
#endif
#include <sys/types.h>

View File

@ -181,9 +181,10 @@ be checked for a match.
.IP "\fBether dst \fIehost\fP"
True if the Ethernet destination address is \fIehost\fP.
\fIEhost\fP
may be either a name from /etc/ethers or a number (see
.IR ethers (3N)
for numeric format).
may be either a name from /etc/ethers or a numerical MAC address of the
form "xx:xx:xx:xx:xx:xx", "xx.xx.xx.xx.xx.xx", "xx-xx-xx-xx-xx-xx",
"xxxx.xxxx.xxxx", "xxxxxxxxxxxx", or various mixes of ':', '.', and '-',
where each "x" is a hex digit (0-9, a-f, or A-F).
.IP "\fBether src \fIehost\fP"
True if the Ethernet source address is \fIehost\fP.
.IP "\fBether host \fIehost\fP"
@ -863,8 +864,9 @@ intervening fragment.
Some offsets and field values may be expressed as names rather than
as numeric values.
The following protocol header field offsets are
available: \fBicmptype\fP (ICMP type field), \fBicmpcode\fP (ICMP
code field), and \fBtcpflags\fP (TCP flags field).
available: \fBicmptype\fP (ICMP type field), \fBicmp6type (ICMP v6 type field)
\fBicmpcode\fP (ICMP code field), \fBicmp6code\fP (ICMP v6 code field), and
\fBtcpflags\fP (TCP flags field).
The following ICMP type field values are available: \fBicmp-echoreply\fP,
\fBicmp-unreach\fP, \fBicmp-sourcequench\fP, \fBicmp-redirect\fP,
@ -873,9 +875,24 @@ The following ICMP type field values are available: \fBicmp-echoreply\fP,
\fBicmp-tstampreply\fP, \fBicmp-ireq\fP, \fBicmp-ireqreply\fP,
\fBicmp-maskreq\fP, \fBicmp-maskreply\fP.
The following ICMPv6 type fields are available: \fBicmp6-echo\fP,
\fBicmp6-echoreply\fP, \fBicmp6-multicastlistenerquery\fP,
\fBicmp6-multicastlistenerreportv1\fP, \fBicmp6-multicastlistenerdone\fP,
\fBicmp6-routersolicit\fP, \fBicmp6-routeradvert\fP,
\fBicmp6-neighborsolicit\fP, \fBicmp6-neighboradvert\fP, \fBicmp6-redirect\fP,
\fBicmp6-routerrenum\fP, \fBicmp6-nodeinformationquery\fP,
\fBicmp6-nodeinformationresponse\fP, \fBicmp6-ineighbordiscoverysolicit\fP,
\fBicmp6-ineighbordiscoveryadvert\fP, \fBicmp6-multicastlistenerreportv2\fP,
\fBicmp6-homeagentdiscoveryrequest\fP, \fBicmp6-homeagentdiscoveryreply\fP,
\fBicmp6-mobileprefixsolicit\fP, \fBicmp6-mobileprefixadvert\fP,
\fBicmp6-certpathsolicit\fP, \fBicmp6-certpathadvert\fP,
\fBicmp6-multicastrouteradvert\fP, \fBicmp6-multicastroutersolicit\fP,
\fBicmp6-multicastrouterterm\fP.
The following TCP flags field values are available: \fBtcp-fin\fP,
\fBtcp-syn\fP, \fBtcp-rst\fP, \fBtcp-push\fP,
\fBtcp-ack\fP, \fBtcp-urg\fP.
\fBtcp-ack\fP, \fBtcp-urg\fP, \fBtcp-ece\fP,
\fBtcp-cwr\fP.
.LP
Primitives may be combined using:
.IP
@ -1010,11 +1027,12 @@ icmp[icmptype] != icmp-echo and icmp[icmptype] != icmp-echoreply
.SH "SEE ALSO"
pcap(3PCAP)
.SH BUGS
Please send problems, bugs, questions, desirable enhancements, etc. to:
To report a security issue please send an e-mail to security@tcpdump.org.
.LP
.RS
tcpdump-workers@lists.tcpdump.org
.RE
To report bugs and other problems, contribute patches, request a
feature, provide generic feedback etc please see the file
.I CONTRIBUTING
in the libpcap source tree root.
.LP
Filter expressions on fields other than those in Token Ring headers will
not correctly handle source-routed Token Ring packets.

View File

@ -34,55 +34,40 @@
#ifndef pcap_int_h
#define pcap_int_h
#include <signal.h>
#include <pcap/pcap.h>
#include "varattrs.h"
#include "fmtutils.h"
/*
* Version string.
* Uses PACKAGE_VERSION from config.h.
*/
#define PCAP_VERSION_STRING "libpcap version " PACKAGE_VERSION
#ifdef __cplusplus
extern "C" {
#endif
#if defined(_WIN32)
/*
* Make sure Packet32.h doesn't define BPF structures that we've
* probably already defined as a result of including <pcap/pcap.h>.
*/
#define BPF_MAJOR_VERSION
#include <Packet32.h>
#elif defined(MSDOS)
#ifdef MSDOS
#include <fcntl.h>
#include <io.h>
#endif
#if (defined(_MSC_VER) && (_MSC_VER <= 1200)) /* we are compiling with Visual Studio 6, that doesn't support the LL suffix*/
/*
* Swap byte ordering of unsigned long long timestamp on a big endian
* machine.
*/
#define SWAPLL(ull) ((ull & 0xff00000000000000) >> 56) | \
((ull & 0x00ff000000000000) >> 40) | \
((ull & 0x0000ff0000000000) >> 24) | \
((ull & 0x000000ff00000000) >> 8) | \
((ull & 0x00000000ff000000) << 8) | \
((ull & 0x0000000000ff0000) << 24) | \
((ull & 0x000000000000ff00) << 40) | \
((ull & 0x00000000000000ff) << 56)
#else /* A recent Visual studio compiler or not VC */
/*
* Swap byte ordering of unsigned long long timestamp on a big endian
* machine.
*/
#define SWAPLL(ull) ((ull & 0xff00000000000000LL) >> 56) | \
((ull & 0x00ff000000000000LL) >> 40) | \
((ull & 0x0000ff0000000000LL) >> 24) | \
((ull & 0x000000ff00000000LL) >> 8) | \
((ull & 0x00000000ff000000LL) << 8) | \
((ull & 0x0000000000ff0000LL) << 24) | \
((ull & 0x000000000000ff00LL) << 40) | \
((ull & 0x00000000000000ffLL) << 56)
#endif /* _MSC_VER */
#define SWAPLL(ull) ((ull & 0xff00000000000000ULL) >> 56) | \
((ull & 0x00ff000000000000ULL) >> 40) | \
((ull & 0x0000ff0000000000ULL) >> 24) | \
((ull & 0x000000ff00000000ULL) >> 8) | \
((ull & 0x00000000ff000000ULL) << 8) | \
((ull & 0x0000000000ff0000ULL) << 24) | \
((ull & 0x000000000000ff00ULL) << 40) | \
((ull & 0x00000000000000ffULL) << 56)
/*
* Maximum snapshot length.
@ -114,19 +99,32 @@ struct pcap_opt {
int promisc;
int rfmon; /* monitor mode */
int immediate; /* immediate mode - deliver packets as soon as they arrive */
int nonblock; /* non-blocking mode - don't wait for packets to be delivered, return "no packets available" */
int tstamp_type;
int tstamp_precision;
/*
* Platform-dependent options.
*/
#ifdef __linux__
int protocol; /* protocol to use when creating PF_PACKET socket */
#endif
#ifdef _WIN32
int nocapture_local;/* disable NPF loopback */
#endif
};
typedef int (*activate_op_t)(pcap_t *);
typedef int (*can_set_rfmon_op_t)(pcap_t *);
typedef int (*read_op_t)(pcap_t *, int cnt, pcap_handler, u_char *);
typedef int (*next_packet_op_t)(pcap_t *, struct pcap_pkthdr *, u_char **);
typedef int (*inject_op_t)(pcap_t *, const void *, size_t);
typedef void (*save_current_filter_op_t)(pcap_t *, const char *);
typedef int (*setfilter_op_t)(pcap_t *, struct bpf_program *);
typedef int (*setdirection_op_t)(pcap_t *, pcap_direction_t);
typedef int (*set_datalink_op_t)(pcap_t *, int);
typedef int (*getnonblock_op_t)(pcap_t *, char *);
typedef int (*setnonblock_op_t)(pcap_t *, int, char *);
typedef int (*getnonblock_op_t)(pcap_t *);
typedef int (*setnonblock_op_t)(pcap_t *, int);
typedef int (*stats_op_t)(pcap_t *, struct pcap_stat *);
#ifdef _WIN32
typedef struct pcap_stat *(*stats_ex_op_t)(pcap_t *, int *);
@ -155,15 +153,14 @@ struct pcap {
read_op_t read_op;
/*
* Method to call to read packets from a savefile.
* Method to call to read the next packet from a savefile.
*/
int (*next_packet_op)(pcap_t *, struct pcap_pkthdr *, u_char **);
next_packet_op_t next_packet_op;
#ifdef _WIN32
ADAPTER *adapter;
HANDLE handle;
#else
int fd;
int selectable_fd;
#endif /* _WIN32 */
/*
@ -174,10 +171,14 @@ struct pcap {
u_char *bp;
int cc;
int break_loop; /* flag set to force break from packet-reading loop */
sig_atomic_t break_loop; /* flag set to force break from packet-reading loop */
void *priv; /* private data for methods */
#ifdef ENABLE_REMOTE
struct pcap_samp rmt_samp; /* parameters related to the sampling process. */
#endif
int swapped;
FILE *rfile; /* null if live capture, non-null if savefile */
u_int fddipad;
@ -208,7 +209,7 @@ struct pcap {
u_char *pkt;
#ifdef _WIN32
struct pcap_stat stat; /* used for pcap_stats_ex() */
struct pcap_stat stat; /* used for pcap_stats_ex() */
#endif
/* We're accepting only packets in this direction/these directions. */
@ -219,6 +220,23 @@ struct pcap {
*/
int bpf_codegen_flags;
#if !defined(_WIN32) && !defined(MSDOS)
int selectable_fd; /* FD on which select()/poll()/epoll_wait()/kevent()/etc. can be done */
/*
* In case there either is no selectable FD, or there is but
* it doesn't necessarily work (e.g., if it doesn't get notified
* if the packet capture timeout expires before the buffer
* fills up), this points to a timeout that should be used
* in select()/poll()/epoll_wait()/kevent() call. The pcap_t should
* be put into non-blocking mode, and, if the timeout expires on
* the call, an attempt should be made to read packets from all
* pcap_t's with a required timeout, and the code must be
* prepared not to see any packets from the attempt.
*/
struct timeval *required_select_timeout;
#endif
/*
* Placeholder for filter code if bpf not in kernel.
*/
@ -240,6 +258,7 @@ struct pcap {
activate_op_t activate_op;
can_set_rfmon_op_t can_set_rfmon_op;
inject_op_t inject_op;
save_current_filter_op_t save_current_filter_op;
setfilter_op_t setfilter_op;
setdirection_op_t setdirection_op;
set_datalink_op_t set_datalink_op;
@ -378,8 +397,8 @@ int pcap_offline_read(pcap_t *, int, pcap_handler, u_char *);
* Routines that most pcap implementations can use for non-blocking mode.
*/
#if !defined(_WIN32) && !defined(MSDOS)
int pcap_getnonblock_fd(pcap_t *, char *);
int pcap_setnonblock_fd(pcap_t *p, int, char *);
int pcap_getnonblock_fd(pcap_t *);
int pcap_setnonblock_fd(pcap_t *p, int);
#endif
/*
@ -404,32 +423,47 @@ int pcap_check_activated(pcap_t *);
/*
* Internal interfaces for "pcap_findalldevs()".
*
* "pcap_platform_finddevs()" is a platform-dependent routine to
* A pcap_if_list_t * is a reference to a list of devices.
*
* A get_if_flags_func is a platform-dependent function called to get
* additional interface flags.
*
* "pcap_platform_finddevs()" is the platform-dependent routine to
* find local network interfaces.
*
* "pcap_findalldevs_interfaces()" is a helper to find those interfaces
* using the "standard" mechanisms (SIOCGIFCONF, "getifaddrs()", etc.).
*
* "pcap_add_if()" adds an interface to the list of interfaces, for
* use by various "find interfaces" routines.
* "add_dev()" adds an entry to a pcap_if_list_t.
*
* "find_dev()" tries to find a device, by name, in a pcap_if_list_t.
*
* "find_or_add_dev()" checks whether a device is already in a pcap_if_list_t
* and, if not, adds an entry for it.
*/
int pcap_platform_finddevs(pcap_if_t **, char *);
struct pcap_if_list;
typedef struct pcap_if_list pcap_if_list_t;
typedef int (*get_if_flags_func)(const char *, bpf_u_int32 *, char *);
int pcap_platform_finddevs(pcap_if_list_t *, char *);
#if !defined(_WIN32) && !defined(MSDOS)
int pcap_findalldevs_interfaces(pcap_if_t **, char *,
int (*)(const char *));
int pcap_findalldevs_interfaces(pcap_if_list_t *, char *,
int (*)(const char *), get_if_flags_func);
#endif
int add_addr_to_iflist(pcap_if_t **, const char *, bpf_u_int32,
struct sockaddr *, size_t, struct sockaddr *, size_t,
struct sockaddr *, size_t, struct sockaddr *, size_t, char *);
pcap_if_t *find_or_add_dev(pcap_if_list_t *, const char *, bpf_u_int32,
get_if_flags_func, const char *, char *);
pcap_if_t *find_dev(pcap_if_list_t *, const char *);
pcap_if_t *add_dev(pcap_if_list_t *, const char *, bpf_u_int32, const char *,
char *);
int add_addr_to_dev(pcap_if_t *, struct sockaddr *, size_t,
struct sockaddr *, size_t, struct sockaddr *, size_t,
struct sockaddr *dstaddr, size_t, char *errbuf);
int pcap_add_if(pcap_if_t **, const char *, bpf_u_int32, const char *,
char *);
int add_or_find_if(pcap_if_t **, pcap_if_t **, const char *, bpf_u_int32,
const char *, char *);
#ifndef _WIN32
bpf_u_int32 if_flags_to_pcap_flags(const char *, u_int);
pcap_if_t *find_or_add_if(pcap_if_list_t *, const char *, bpf_u_int32,
get_if_flags_func, char *);
int add_addr_to_if(pcap_if_list_t *, const char *, bpf_u_int32,
get_if_flags_func,
struct sockaddr *, size_t, struct sockaddr *, size_t,
struct sockaddr *, size_t, struct sockaddr *, size_t, char *);
#endif
/*
@ -462,6 +496,10 @@ int install_bpf_program(pcap_t *, struct bpf_program *);
int pcap_strcasecmp(const char *, const char *);
#ifdef YYDEBUG
extern int pcap_debug;
#endif
#ifdef __cplusplus
}
#endif

View File

@ -25,7 +25,7 @@
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#include <config.h>
#endif
#include <sys/types.h>
@ -137,6 +137,17 @@ pcap_activate_libdlpi(pcap_t *p)
goto bad;
}
/*
* Turn a negative snapshot value (invalid), a snapshot value of
* 0 (unspecified), or a value bigger than the normal maximum
* value, into the maximum allowed value.
*
* If some application really *needs* a bigger snapshot
* length, we should just increase MAXIMUM_SNAPLEN.
*/
if (p->snapshot <= 0 || p->snapshot > MAXIMUM_SNAPLEN)
p->snapshot = MAXIMUM_SNAPLEN;
/* Enable promiscuous mode. */
if (p->opt.promisc) {
retv = dlpromiscon(p, DL_PROMISC_PHYS);
@ -209,8 +220,8 @@ pcap_activate_libdlpi(pcap_t *p)
*/
if (ioctl(p->fd, I_FLUSH, FLUSHR) != 0) {
status = PCAP_ERROR;
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "FLUSHR: %s",
pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
errno, "FLUSHR");
goto bad;
}
@ -276,13 +287,36 @@ is_dlpi_interface(const char *name _U_)
return (1);
}
static int
get_if_flags(const char *name _U_, bpf_u_int32 *flags _U_, char *errbuf _U_)
{
/*
* Nothing we can do other than mark loopback devices as "the
* connected/disconnected status doesn't apply".
*
* XXX - on Solaris, can we do what the dladm command does,
* i.e. get a connected/disconnected indication from a kstat?
* (Note that you can also get the link speed, and possibly
* other information, from a kstat as well.)
*/
if (*flags & PCAP_IF_LOOPBACK) {
/*
* Loopback devices aren't wireless, and "connected"/
* "disconnected" doesn't apply to them.
*/
*flags |= PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE;
return (0);
}
return (0);
}
/*
* In Solaris, the "standard" mechanism" i.e SIOCGLIFCONF will only find
* network links that are plumbed and are up. dlpi_walk(3DLPI) will find
* additional network links present in the system.
*/
int
pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
pcap_platform_finddevs(pcap_if_list_t *devlistp, char *errbuf)
{
int retv = 0;
@ -293,23 +327,36 @@ pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
/*
* Get the list of regular interfaces first.
*/
if (pcap_findalldevs_interfaces(alldevsp, errbuf, is_dlpi_interface) == -1)
if (pcap_findalldevs_interfaces(devlistp, errbuf,
is_dlpi_interface, get_if_flags) == -1)
return (-1); /* failure */
/* dlpi_walk() for loopback will be added here. */
/*
* Find all DLPI devices in the current zone.
*
* XXX - will pcap_findalldevs_interfaces() find any devices
* outside the current zone? If not, the only reason to call
* it would be to get the interface addresses.
*/
dlpi_walk(list_interfaces, &lw, 0);
if (lw.lw_err != 0) {
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"dlpi_walk: %s", pcap_strerror(lw.lw_err));
pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
lw.lw_err, "dlpi_walk");
retv = -1;
goto done;
}
/* Add linkname if it does not exist on the list. */
for (entry = lw.lw_list; entry != NULL; entry = entry->lnl_next) {
if (pcap_add_if(alldevsp, entry->linkname, 0, NULL, errbuf) < 0)
/*
* If it isn't already in the list of devices, try to
* add it.
*/
if (find_or_add_dev(devlistp, entry->linkname, 0, get_if_flags,
NULL, errbuf) == NULL)
retv = -1;
}
done:
@ -437,3 +484,12 @@ pcap_create_interface(const char *device _U_, char *ebuf)
p->activate_op = pcap_activate_libdlpi;
return (p);
}
/*
* Libpcap version string.
*/
const char *
pcap_lib_version(void)
{
return (PCAP_VERSION_STRING);
}

File diff suppressed because it is too large Load Diff

View File

@ -29,7 +29,7 @@
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#include <config.h>
#endif
#include "pcap-int.h"
@ -82,37 +82,90 @@ struct pcap_netfilter {
u_int packets_nobufs; /* ENOBUFS counter */
};
static int nfqueue_send_verdict(const pcap_t *handle, u_int16_t group_id, u_int32_t id, u_int32_t verdict);
static int nfqueue_send_verdict(const pcap_t *handle, uint16_t group_id, u_int32_t id, u_int32_t verdict);
static int
netfilter_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user)
{
struct pcap_netfilter *handlep = handle->priv;
const unsigned char *buf;
register u_char *bp, *ep;
int count = 0;
int len;
/* ignore interrupt system call error */
do {
len = recv(handle->fd, handle->buffer, handle->bufsize, 0);
if (handle->break_loop) {
handle->break_loop = 0;
return -2;
}
if(errno == ENOBUFS) handlep->packets_nobufs++;
} while ((len == -1) && (errno == EINTR || errno == ENOBUFS));
if (len < 0) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't receive packet %d:%s", errno, pcap_strerror(errno));
return -1;
/*
* Has "pcap_breakloop()" been called?
*/
if (handle->break_loop) {
/*
* Yes - clear the flag that indicates that it
* has, and return PCAP_ERROR_BREAK to indicate
* that we were told to break out of the loop.
*/
handle->break_loop = 0;
return PCAP_ERROR_BREAK;
}
len = handle->cc;
if (len == 0) {
/*
* The buffer is empty; refill it.
*
* We ignore EINTR, as that might just be due to a signal
* being delivered - if the signal should interrupt the
* loop, the signal handler should call pcap_breakloop()
* to set handle->break_loop (we ignore it on other
* platforms as well).
*/
do {
len = recv(handle->fd, handle->buffer, handle->bufsize, 0);
if (handle->break_loop) {
handle->break_loop = 0;
return PCAP_ERROR_BREAK;
}
if (errno == ENOBUFS)
handlep->packets_nobufs++;
} while ((len == -1) && (errno == EINTR || errno == ENOBUFS));
buf = (unsigned char *)handle->buffer;
while ((u_int)len >= NLMSG_SPACE(0)) {
const struct nlmsghdr *nlh = (const struct nlmsghdr *) buf;
u_int32_t msg_len;
if (len < 0) {
pcap_fmt_errmsg_for_errno(handle->errbuf,
PCAP_ERRBUF_SIZE, errno, "Can't receive packet");
return PCAP_ERROR;
}
bp = (unsigned char *)handle->buffer;
} else
bp = handle->bp;
ep = bp + len;
while (bp < ep) {
const struct nlmsghdr *nlh = (const struct nlmsghdr *) bp;
uint32_t msg_len;
nftype_t type = OTHER;
/*
* Has "pcap_breakloop()" been called?
* If so, return immediately - if we haven't read any
* packets, clear the flag and return PCAP_ERROR_BREAK
* 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 (handle->break_loop) {
handle->bp = bp;
handle->cc = ep - bp;
if (count == 0) {
handle->break_loop = 0;
return PCAP_ERROR_BREAK;
} else
return count;
}
if (ep - bp < NLMSG_SPACE(0)) {
/*
* There's less than one netlink message left
* in the buffer. Give up.
*/
break;
}
if (nlh->nlmsg_len < sizeof(struct nlmsghdr) || (u_int)len < nlh->nlmsg_len) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Message truncated: (got: %d) (nlmsg_len: %u)", len, nlh->nlmsg_len);
@ -205,12 +258,25 @@ netfilter_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_c
}
msg_len = NLMSG_ALIGN(nlh->nlmsg_len);
if (msg_len > (u_int)len)
msg_len = (u_int)len;
/*
* If the message length would run past the end of the
* buffer, truncate it to the remaining space in the
* buffer.
*/
if (msg_len > ep - bp)
msg_len = ep - bp;
len -= msg_len;
buf += msg_len;
bp += msg_len;
if (count >= max_packets && !PACKET_COUNT_IS_UNLIMITED(max_packets)) {
handle->bp = bp;
handle->cc = ep - bp;
if (handle->cc < 0)
handle->cc = 0;
return count;
}
}
handle->cc = 0;
return count;
}
@ -233,20 +299,20 @@ netfilter_stats_linux(pcap_t *handle, struct pcap_stat *stats)
}
static int
netfilter_inject_linux(pcap_t *handle, const void *buf, size_t size)
netfilter_inject_linux(pcap_t *handle, const void *buf _U_, size_t size _U_)
{
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "inject not supported on netfilter devices");
return (-1);
}
struct my_nfattr {
u_int16_t nfa_len;
u_int16_t nfa_type;
uint16_t nfa_len;
uint16_t nfa_type;
void *data;
};
static int
netfilter_send_config_msg(const pcap_t *handle, u_int16_t msg_type, int ack, u_int8_t family, u_int16_t res_id, const struct my_nfattr *mynfa)
netfilter_send_config_msg(const pcap_t *handle, uint16_t msg_type, int ack, u_int8_t family, u_int16_t res_id, const struct my_nfattr *mynfa)
{
char buf[1024] __attribute__ ((aligned));
@ -310,7 +376,7 @@ netfilter_send_config_msg(const pcap_t *handle, u_int16_t msg_type, int ack, u_i
if (snl.nl_pid != 0 || seq_id != nlh->nlmsg_seq) /* if not from kernel or wrong sequence skip */
continue;
while ((u_int)len >= NLMSG_SPACE(0) && NLMSG_OK(nlh, len)) {
while ((u_int)len >= NLMSG_SPACE(0) && NLMSG_OK(nlh, (u_int)len)) {
if (nlh->nlmsg_type == NLMSG_ERROR || (nlh->nlmsg_type == NLMSG_DONE && nlh->nlmsg_flags & NLM_F_MULTI)) {
if (nlh->nlmsg_len < NLMSG_ALIGN(sizeof(struct nlmsgerr))) {
errno = EBADMSG;
@ -327,13 +393,13 @@ netfilter_send_config_msg(const pcap_t *handle, u_int16_t msg_type, int ack, u_i
}
static int
nflog_send_config_msg(const pcap_t *handle, u_int8_t family, u_int16_t group_id, const struct my_nfattr *mynfa)
nflog_send_config_msg(const pcap_t *handle, uint8_t family, u_int16_t group_id, const struct my_nfattr *mynfa)
{
return netfilter_send_config_msg(handle, (NFNL_SUBSYS_ULOG << 8) | NFULNL_MSG_CONFIG, 1, family, group_id, mynfa);
}
static int
nflog_send_config_cmd(const pcap_t *handle, u_int16_t group_id, u_int8_t cmd, u_int8_t family)
nflog_send_config_cmd(const pcap_t *handle, uint16_t group_id, u_int8_t cmd, u_int8_t family)
{
struct nfulnl_msg_config_cmd msg;
struct my_nfattr nfa;
@ -348,7 +414,7 @@ nflog_send_config_cmd(const pcap_t *handle, u_int16_t group_id, u_int8_t cmd, u_
}
static int
nflog_send_config_mode(const pcap_t *handle, u_int16_t group_id, u_int8_t copy_mode, u_int32_t copy_range)
nflog_send_config_mode(const pcap_t *handle, uint16_t group_id, u_int8_t copy_mode, u_int32_t copy_range)
{
struct nfulnl_msg_config_mode msg;
struct my_nfattr nfa;
@ -364,7 +430,7 @@ nflog_send_config_mode(const pcap_t *handle, u_int16_t group_id, u_int8_t copy_m
}
static int
nfqueue_send_verdict(const pcap_t *handle, u_int16_t group_id, u_int32_t id, u_int32_t verdict)
nfqueue_send_verdict(const pcap_t *handle, uint16_t group_id, u_int32_t id, u_int32_t verdict)
{
struct nfqnl_msg_verdict_hdr msg;
struct my_nfattr nfa;
@ -380,13 +446,13 @@ nfqueue_send_verdict(const pcap_t *handle, u_int16_t group_id, u_int32_t id, u_i
}
static int
nfqueue_send_config_msg(const pcap_t *handle, u_int8_t family, u_int16_t group_id, const struct my_nfattr *mynfa)
nfqueue_send_config_msg(const pcap_t *handle, uint8_t family, u_int16_t group_id, const struct my_nfattr *mynfa)
{
return netfilter_send_config_msg(handle, (NFNL_SUBSYS_QUEUE << 8) | NFQNL_MSG_CONFIG, 1, family, group_id, mynfa);
}
static int
nfqueue_send_config_cmd(const pcap_t *handle, u_int16_t group_id, u_int8_t cmd, u_int16_t pf)
nfqueue_send_config_cmd(const pcap_t *handle, uint16_t group_id, u_int8_t cmd, u_int16_t pf)
{
struct nfqnl_msg_config_cmd msg;
struct my_nfattr nfa;
@ -402,7 +468,7 @@ nfqueue_send_config_cmd(const pcap_t *handle, u_int16_t group_id, u_int8_t cmd,
}
static int
nfqueue_send_config_mode(const pcap_t *handle, u_int16_t group_id, u_int8_t copy_mode, u_int32_t copy_range)
nfqueue_send_config_mode(const pcap_t *handle, uint16_t group_id, u_int8_t copy_mode, u_int32_t copy_range)
{
struct nfqnl_msg_config_params msg;
struct my_nfattr nfa;
@ -479,6 +545,17 @@ netfilter_activate(pcap_t* handle)
group_count = 1;
}
/*
* Turn a negative snapshot value (invalid), a snapshot value of
* 0 (unspecified), or a value bigger than the normal maximum
* value, into the maximum allowed value.
*
* If some application really *needs* a bigger snapshot
* length, we should just increase MAXIMUM_SNAPLEN.
*/
if (handle->snapshot <= 0 || handle->snapshot > MAXIMUM_SNAPLEN)
handle->snapshot = MAXIMUM_SNAPLEN;
/* Initialize some components of the pcap structure. */
handle->bufsize = 128 + handle->snapshot;
handle->offset = 0;
@ -494,7 +571,8 @@ netfilter_activate(pcap_t* handle)
/* Create netlink socket */
handle->fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_NETFILTER);
if (handle->fd < 0) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't create raw socket %d:%s", errno, pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
errno, "Can't create raw socket");
return PCAP_ERROR;
}
@ -512,54 +590,68 @@ netfilter_activate(pcap_t* handle)
handle->buffer = malloc(handle->bufsize);
if (!handle->buffer) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't allocate dump buffer: %s", pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
errno, "Can't allocate dump buffer");
goto close_fail;
}
if (type == NFLOG) {
if (nflog_send_config_cmd(handle, 0, NFULNL_CFG_CMD_PF_UNBIND, AF_INET) < 0) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "NFULNL_CFG_CMD_PF_UNBIND: %s", pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(handle->errbuf,
PCAP_ERRBUF_SIZE, errno,
"NFULNL_CFG_CMD_PF_UNBIND");
goto close_fail;
}
if (nflog_send_config_cmd(handle, 0, NFULNL_CFG_CMD_PF_BIND, AF_INET) < 0) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "NFULNL_CFG_CMD_PF_BIND: %s", pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(handle->errbuf,
PCAP_ERRBUF_SIZE, errno, "NFULNL_CFG_CMD_PF_BIND");
goto close_fail;
}
/* Bind socket to the nflog groups */
for (i = 0; i < group_count; i++) {
if (nflog_send_config_cmd(handle, groups[i], NFULNL_CFG_CMD_BIND, AF_UNSPEC) < 0) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't listen on group group index: %s", pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(handle->errbuf,
PCAP_ERRBUF_SIZE, errno,
"Can't listen on group group index");
goto close_fail;
}
if (nflog_send_config_mode(handle, groups[i], NFULNL_COPY_PACKET, handle->snapshot) < 0) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "NFULNL_COPY_PACKET: %s", pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(handle->errbuf,
PCAP_ERRBUF_SIZE, errno,
"NFULNL_COPY_PACKET");
goto close_fail;
}
}
} else {
if (nfqueue_send_config_cmd(handle, 0, NFQNL_CFG_CMD_PF_UNBIND, AF_INET) < 0) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "NFQNL_CFG_CMD_PF_UNBIND: %s", pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(handle->errbuf,
PCAP_ERRBUF_SIZE, errno, "NFQNL_CFG_CMD_PF_UNBIND");
goto close_fail;
}
if (nfqueue_send_config_cmd(handle, 0, NFQNL_CFG_CMD_PF_BIND, AF_INET) < 0) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "NFQNL_CFG_CMD_PF_BIND: %s", pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(handle->errbuf,
PCAP_ERRBUF_SIZE, errno, "NFQNL_CFG_CMD_PF_BIND");
goto close_fail;
}
/* Bind socket to the nfqueue groups */
for (i = 0; i < group_count; i++) {
if (nfqueue_send_config_cmd(handle, groups[i], NFQNL_CFG_CMD_BIND, AF_UNSPEC) < 0) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't listen on group group index: %s", pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(handle->errbuf,
PCAP_ERRBUF_SIZE, errno,
"Can't listen on group group index");
goto close_fail;
}
if (nfqueue_send_config_mode(handle, groups[i], NFQNL_COPY_PACKET, handle->snapshot) < 0) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "NFQNL_COPY_PACKET: %s", pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(handle->errbuf,
PCAP_ERRBUF_SIZE, errno,
"NFQNL_COPY_PACKET");
goto close_fail;
}
}
@ -578,7 +670,8 @@ netfilter_activate(pcap_t* handle)
* Set the socket buffer size to the specified value.
*/
if (setsockopt(handle->fd, SOL_SOCKET, SO_RCVBUF, &handle->opt.buffer_size, sizeof(handle->opt.buffer_size)) == -1) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "SO_RCVBUF: %s", pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(handle->errbuf,
PCAP_ERRBUF_SIZE, errno, "SO_RCVBUF");
goto close_fail;
}
}
@ -635,7 +728,7 @@ netfilter_create(const char *device, char *ebuf, int *is_ours)
}
int
netfilter_findalldevs(pcap_if_t **alldevsp, char *err_str)
netfilter_findalldevs(pcap_if_list_t *devlistp, char *err_str)
{
int sock;
@ -644,15 +737,23 @@ netfilter_findalldevs(pcap_if_t **alldevsp, char *err_str)
/* if netlink is not supported this is not fatal */
if (errno == EAFNOSUPPORT || errno == EPROTONOSUPPORT)
return 0;
pcap_snprintf(err_str, PCAP_ERRBUF_SIZE, "Can't open netlink socket %d:%s",
errno, pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(err_str, PCAP_ERRBUF_SIZE,
errno, "Can't open netlink socket");
return -1;
}
close(sock);
if (pcap_add_if(alldevsp, NFLOG_IFACE, 0, "Linux netfilter log (NFLOG) interface", err_str) < 0)
/*
* The notion of "connected" vs. "disconnected" doesn't apply.
* XXX - what about "up" and "running"?
*/
if (add_dev(devlistp, NFLOG_IFACE,
PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE,
"Linux netfilter log (NFLOG) interface", err_str) == NULL)
return -1;
if (pcap_add_if(alldevsp, NFQUEUE_IFACE, 0, "Linux netfilter queue (NFQUEUE) interface", err_str) < 0)
if (add_dev(devlistp, NFQUEUE_IFACE,
PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE,
"Linux netfilter queue (NFQUEUE) interface", err_str) == NULL)
return -1;
return 0;
}

View File

@ -31,5 +31,5 @@
/*
* Prototypes for netlink-related functions
*/
int netfilter_findalldevs(pcap_if_t **alldevsp, char *err_str);
int netfilter_findalldevs(pcap_if_list_t *devlistp, char *err_str);
pcap_t *netfilter_create(const char *device, char *ebuf, int *is_ours);

306
pcap-netmap.c Normal file
View File

@ -0,0 +1,306 @@
/*
* Copyright (C) 2014 Luigi Rizzo. 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <poll.h>
#include <ctype.h>
#include <errno.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define NETMAP_WITH_LIBS
#include <net/netmap_user.h>
#include "pcap-int.h"
#include "pcap-netmap.h"
#ifndef __FreeBSD__
/*
* On FreeBSD we use IFF_PPROMISC which is in ifr_flagshigh.
* Remap to IFF_PROMISC on other platforms.
*
* XXX - DragonFly BSD?
*/
#define IFF_PPROMISC IFF_PROMISC
#endif /* __FreeBSD__ */
struct pcap_netmap {
struct nm_desc *d; /* pointer returned by nm_open() */
pcap_handler cb; /* callback and argument */
u_char *cb_arg;
int must_clear_promisc; /* flag */
uint64_t rx_pkts; /* # of pkts received before the filter */
};
static int
pcap_netmap_stats(pcap_t *p, struct pcap_stat *ps)
{
struct pcap_netmap *pn = p->priv;
ps->ps_recv = pn->rx_pkts;
ps->ps_drop = 0;
ps->ps_ifdrop = 0;
return 0;
}
static void
pcap_netmap_filter(u_char *arg, struct pcap_pkthdr *h, const u_char *buf)
{
pcap_t *p = (pcap_t *)arg;
struct pcap_netmap *pn = p->priv;
const struct bpf_insn *pc = p->fcode.bf_insns;
++pn->rx_pkts;
if (pc == NULL || bpf_filter(pc, buf, h->len, h->caplen))
pn->cb(pn->cb_arg, h, buf);
}
static int
pcap_netmap_dispatch(pcap_t *p, int cnt, pcap_handler cb, u_char *user)
{
int ret;
struct pcap_netmap *pn = p->priv;
struct nm_desc *d = pn->d;
struct pollfd pfd = { .fd = p->fd, .events = POLLIN, .revents = 0 };
pn->cb = cb;
pn->cb_arg = user;
for (;;) {
if (p->break_loop) {
p->break_loop = 0;
return PCAP_ERROR_BREAK;
}
/* nm_dispatch won't run forever */
ret = nm_dispatch((void *)d, cnt, (void *)pcap_netmap_filter, (void *)p);
if (ret != 0)
break;
errno = 0;
ret = poll(&pfd, 1, p->opt.timeout);
}
return ret;
}
/* XXX need to check the NIOCTXSYNC/poll */
static int
pcap_netmap_inject(pcap_t *p, const void *buf, size_t size)
{
struct pcap_netmap *pn = p->priv;
struct nm_desc *d = pn->d;
return nm_inject(d, buf, size);
}
static int
pcap_netmap_ioctl(pcap_t *p, u_long what, uint32_t *if_flags)
{
struct pcap_netmap *pn = p->priv;
struct nm_desc *d = pn->d;
struct ifreq ifr;
int error, fd = d->fd;
#ifdef linux
fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd < 0) {
fprintf(stderr, "Error: cannot get device control socket.\n");
return -1;
}
#endif /* linux */
bzero(&ifr, sizeof(ifr));
strncpy(ifr.ifr_name, d->req.nr_name, sizeof(ifr.ifr_name));
switch (what) {
case SIOCSIFFLAGS:
/*
* The flags we pass in are 32-bit and unsigned.
*
* On most if not all UN*Xes, ifr_flags is 16-bit and
* signed, and the result of assigning a longer
* unsigned value to a shorter signed value is
* implementation-defined (even if, in practice, it'll
* do what's intended on all platforms we support
* result of assigning a 32-bit unsigned value).
* So we mask out the upper 16 bits.
*/
ifr.ifr_flags = *if_flags & 0xffff;
#ifdef __FreeBSD__
/*
* In FreeBSD, we need to set the high-order flags,
* as we're using IFF_PPROMISC, which is in those bits.
*
* XXX - DragonFly BSD?
*/
ifr.ifr_flagshigh = *if_flags >> 16;
#endif /* __FreeBSD__ */
break;
}
error = ioctl(fd, what, &ifr);
if (!error) {
switch (what) {
case SIOCGIFFLAGS:
/*
* The flags we return are 32-bit.
*
* On most if not all UN*Xes, ifr_flags is
* 16-bit and signed, and will get sign-
* extended, so that the upper 16 bits of
* those flags will be forced on. So we
* mask out the upper 16 bits of the
* sign-extended value.
*/
*if_flags = ifr.ifr_flags & 0xffff;
#ifdef __FreeBSD__
/*
* In FreeBSD, we need to return the
* high-order flags, as we're using
* IFF_PPROMISC, which is in those bits.
*
* XXX - DragonFly BSD?
*/
*if_flags |= (ifr.ifr_flagshigh << 16);
#endif /* __FreeBSD__ */
}
}
#ifdef linux
close(fd);
#endif /* linux */
return error ? -1 : 0;
}
static void
pcap_netmap_close(pcap_t *p)
{
struct pcap_netmap *pn = p->priv;
struct nm_desc *d = pn->d;
uint32_t if_flags = 0;
if (pn->must_clear_promisc) {
pcap_netmap_ioctl(p, SIOCGIFFLAGS, &if_flags); /* fetch flags */
if (if_flags & IFF_PPROMISC) {
if_flags &= ~IFF_PPROMISC;
pcap_netmap_ioctl(p, SIOCSIFFLAGS, &if_flags);
}
}
nm_close(d);
pcap_cleanup_live_common(p);
}
static int
pcap_netmap_activate(pcap_t *p)
{
struct pcap_netmap *pn = p->priv;
struct nm_desc *d;
uint32_t if_flags = 0;
d = nm_open(p->opt.device, NULL, 0, NULL);
if (d == NULL) {
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
errno, "netmap open: cannot access %s",
p->opt.device);
pcap_cleanup_live_common(p);
return (PCAP_ERROR);
}
#if 0
fprintf(stderr, "%s device %s priv %p fd %d ports %d..%d\n",
__FUNCTION__, p->opt.device, d, d->fd,
d->first_rx_ring, d->last_rx_ring);
#endif
pn->d = d;
p->fd = d->fd;
/*
* Turn a negative snapshot value (invalid), a snapshot value of
* 0 (unspecified), or a value bigger than the normal maximum
* value, into the maximum allowed value.
*
* If some application really *needs* a bigger snapshot
* length, we should just increase MAXIMUM_SNAPLEN.
*/
if (p->snapshot <= 0 || p->snapshot > MAXIMUM_SNAPLEN)
p->snapshot = MAXIMUM_SNAPLEN;
if (p->opt.promisc && !(d->req.nr_ringid & NETMAP_SW_RING)) {
pcap_netmap_ioctl(p, SIOCGIFFLAGS, &if_flags); /* fetch flags */
if (!(if_flags & IFF_PPROMISC)) {
pn->must_clear_promisc = 1;
if_flags |= IFF_PPROMISC;
pcap_netmap_ioctl(p, SIOCSIFFLAGS, &if_flags);
}
}
p->linktype = DLT_EN10MB;
p->selectable_fd = p->fd;
p->read_op = pcap_netmap_dispatch;
p->inject_op = pcap_netmap_inject;
p->setfilter_op = install_bpf_program;
p->setdirection_op = NULL;
p->set_datalink_op = NULL;
p->getnonblock_op = pcap_getnonblock_fd;
p->setnonblock_op = pcap_setnonblock_fd;
p->stats_op = pcap_netmap_stats;
p->cleanup_op = pcap_netmap_close;
return (0);
}
pcap_t *
pcap_netmap_create(const char *device, char *ebuf, int *is_ours)
{
pcap_t *p;
*is_ours = (!strncmp(device, "netmap:", 7) || !strncmp(device, "vale", 4));
if (! *is_ours)
return NULL;
p = pcap_create_common(ebuf, sizeof (struct pcap_netmap));
if (p == NULL)
return (NULL);
p->activate_op = pcap_netmap_activate;
return (p);
}
/*
* The "device name" for netmap devices isn't a name for a device, it's
* an expression that indicates how the device should be set up, so
* there's no way to enumerate them.
*/
int
pcap_netmap_findalldevs(pcap_if_list_t *devlistp _U_, char *err_str _U_)
{
return 0;
}

2
pcap-netmap.h Normal file
View File

@ -0,0 +1,2 @@
pcap_t *pcap_netmap_create(const char *, char *, int *);
int pcap_netmap_findalldevs(pcap_if_list_t *devlistp, char *errbuf);

1095
pcap-new.c

File diff suppressed because it is too large Load Diff

View File

@ -20,7 +20,7 @@
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#include <config.h>
#endif
#include <sys/types.h>
@ -114,8 +114,8 @@ pcap_read_nit(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
if (cc < 0) {
if (errno == EWOULDBLOCK)
return (0);
pcap_snprintf(p->errbuf, sizeof(p->errbuf), "pcap_read: %s",
pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(p->errbuf, sizeof(p->errbuf),
errno, "pcap_read");
return (-1);
}
bp = (u_char *)p->buffer;
@ -206,8 +206,8 @@ pcap_inject_nit(pcap_t *p, const void *buf, size_t size)
strncpy(sa.sa_data, device, sizeof(sa.sa_data));
ret = sendto(p->fd, buf, size, 0, &sa, sizeof(sa));
if (ret == -1) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
errno, "send");
return (-1);
}
return (ret);
@ -249,8 +249,8 @@ nit_setflags(pcap_t *p)
nioc.nioc_flags |= NF_PROMISC;
if (ioctl(p->fd, SIOCSNIT, &nioc) < 0) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "SIOCSNIT: %s",
pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
errno, "SIOCSNIT");
return (-1);
}
return (0);
@ -271,6 +271,17 @@ pcap_activate_nit(pcap_t *p)
return (PCAP_ERROR_RFMON_NOTSUP);
}
/*
* Turn a negative snapshot value (invalid), a snapshot value of
* 0 (unspecified), or a value bigger than the normal maximum
* value, into the maximum allowed value.
*
* If some application really *needs* a bigger snapshot
* length, we should just increase MAXIMUM_SNAPLEN.
*/
if (p->snapshot <= 0 || p->snapshot > MAXIMUM_SNAPLEN)
p->snapshot = MAXIMUM_SNAPLEN;
if (p->snapshot < 96)
/*
* NIT requires a snapshot length of at least 96.
@ -280,8 +291,8 @@ pcap_activate_nit(pcap_t *p)
memset(p, 0, sizeof(*p));
p->fd = fd = socket(AF_NIT, SOCK_RAW, NITPROTO_RAW);
if (fd < 0) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"socket: %s", pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
errno, "socket");
goto bad;
}
snit.snit_family = AF_NIT;
@ -295,8 +306,8 @@ pcap_activate_nit(pcap_t *p)
* they might be the same error, if they both end up
* meaning "NIT doesn't know about that device".
*/
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"bind: %s: %s", snit.snit_ifname, pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
errno, "bind: %s", snit.snit_ifname);
goto bad;
}
if (nit_setflags(p) < 0)
@ -310,7 +321,8 @@ pcap_activate_nit(pcap_t *p)
p->bufsize = BUFSPACE;
p->buffer = malloc(p->bufsize);
if (p->buffer == NULL) {
strlcpy(p->errbuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
errno, "malloc");
goto bad;
}
@ -377,8 +389,29 @@ can_be_bound(const char *name _U_)
return (1);
}
int
pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
static int
get_if_flags(const char *name _U_, bpf_u_int32 *flags _U_, char *errbuf _U_)
{
return (pcap_findalldevs_interfaces(alldevsp, errbuf, can_be_bound));
/*
* Nothing we can do.
* XXX - is there a way to find out whether an adapter has
* something plugged into it?
*/
return (0);
}
int
pcap_platform_finddevs(pcap_if_list_t *devlistp, char *errbuf)
{
return (pcap_findalldevs_interfaces(devlistp, errbuf, can_be_bound,
get_if_flags));
}
/*
* Libpcap version string.
*/
const char *
pcap_lib_version(void)
{
return (PCAP_VERSION_STRING);
}

File diff suppressed because it is too large Load Diff

View File

@ -20,17 +20,11 @@
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#include <config.h>
#endif
#include <sys/param.h> /* optionally get BSD define */
#include <string.h>
#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
#include "pcap-int.h"
static char nosup[] = "live packet capture not supported on this system";
@ -43,11 +37,29 @@ pcap_create_interface(const char *device _U_, char *ebuf)
}
int
pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
pcap_platform_finddevs(pcap_if_list_t *devlistp, char *errbuf)
{
/*
* There are no interfaces on which we can capture.
*/
*alldevsp = NULL;
return (0);
}
#ifdef _WIN32
int
pcap_lookupnet(const char *device _U_, bpf_u_int32 *netp _U_,
bpf_u_int32 *maskp _U_, char *errbuf)
{
(void)strlcpy(errbuf, nosup, PCAP_ERRBUF_SIZE);
return (-1);
}
#endif
/*
* Libpcap version string.
*/
const char *
pcap_lib_version(void)
{
return (PCAP_VERSION_STRING);
}

115
pcap-pf.c
View File

@ -23,7 +23,7 @@
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#include <config.h>
#endif
#include <sys/types.h>
@ -127,8 +127,8 @@ pcap_read_pf(pcap_t *pc, int cnt, pcap_handler callback, u_char *user)
(void)lseek(pc->fd, 0L, SEEK_SET);
goto again;
}
pcap_snprintf(pc->errbuf, sizeof(pc->errbuf), "pf read: %s",
pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(pc->errbuf,
sizeof(pc->errbuf), errno, "pf read");
return (-1);
}
bp = (u_char *)pc->buffer + pc->offset;
@ -232,8 +232,8 @@ pcap_inject_pf(pcap_t *p, const void *buf, size_t size)
ret = write(p->fd, buf, size);
if (ret == -1) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
errno, "send");
return (-1);
}
return (ret);
@ -302,6 +302,7 @@ pcap_activate_pf(pcap_t *p)
int backlog = -1; /* request the most */
struct enfilter Filter;
struct endevp devparams;
int err;
/*
* Initially try a read/write open (to allow the inject
@ -329,11 +330,31 @@ pcap_activate_pf(pcap_t *p)
if (p->fd == -1 && errno == EACCES)
p->fd = pfopen(p->opt.device, O_RDONLY);
if (p->fd < 0) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "pf open: %s: %s\n\
your system may not be properly configured; see the packetfilter(4) man page\n",
p->opt.device, pcap_strerror(errno));
if (errno == EACCES) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"pf open: %s: Permission denied\n"
"your system may not be properly configured; see the packetfilter(4) man page",
p->opt.device);
err = PCAP_ERROR_PERM_DENIED;
} else {
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
errno, "pf open: %s", p->opt.device);
err = PCAP_ERROR;
}
goto bad;
}
/*
* Turn a negative snapshot value (invalid), a snapshot value of
* 0 (unspecified), or a value bigger than the normal maximum
* value, into the maximum allowed value.
*
* If some application really *needs* a bigger snapshot
* length, we should just increase MAXIMUM_SNAPLEN.
*/
if (p->snapshot <= 0 || p->snapshot > MAXIMUM_SNAPLEN)
p->snapshot = MAXIMUM_SNAPLEN;
pf->OrigMissed = -1;
enmode = ENTSTAMP|ENNONEXCL;
if (!p->opt.immediate)
@ -341,8 +362,9 @@ your system may not be properly configured; see the packetfilter(4) man page\n",
if (p->opt.promisc)
enmode |= ENPROMISC;
if (ioctl(p->fd, EIOCMBIS, (caddr_t)&enmode) < 0) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCMBIS: %s",
pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
errno, "EIOCMBIS");
err = PCAP_ERROR;
goto bad;
}
#ifdef ENCOPYALL
@ -352,14 +374,16 @@ your system may not be properly configured; see the packetfilter(4) man page\n",
#endif
/* set the backlog */
if (ioctl(p->fd, EIOCSETW, (caddr_t)&backlog) < 0) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCSETW: %s",
pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
errno, "EIOCSETW");
err = PCAP_ERROR;
goto bad;
}
/* discover interface type */
if (ioctl(p->fd, EIOCDEVP, (caddr_t)&devparams) < 0) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCDEVP: %s",
pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
errno, "EIOCDEVP");
err = PCAP_ERROR;
goto bad;
}
/* HACK: to compile prior to Ultrix 4.2 */
@ -442,6 +466,7 @@ your system may not be properly configured; see the packetfilter(4) man page\n",
*/
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"unknown data-link type %u", devparams.end_dev_type);
err = PCAP_ERROR;
goto bad;
}
/* set truncation */
@ -453,8 +478,9 @@ your system may not be properly configured; see the packetfilter(4) man page\n",
} else
p->fddipad = 0;
if (ioctl(p->fd, EIOCTRUNCATE, (caddr_t)&p->snapshot) < 0) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCTRUNCATE: %s",
pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
errno, "EIOCTRUNCATE");
err = PCAP_ERROR;
goto bad;
}
/* accept all packets */
@ -462,8 +488,9 @@ your system may not be properly configured; see the packetfilter(4) man page\n",
Filter.enf_Priority = 37; /* anything > 2 */
Filter.enf_FilterLen = 0; /* means "always true" */
if (ioctl(p->fd, EIOCSETF, (caddr_t)&Filter) < 0) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCSETF: %s",
pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
errno, "EIOCSETF");
err = PCAP_ERROR;
goto bad;
}
@ -472,8 +499,9 @@ your system may not be properly configured; see the packetfilter(4) man page\n",
timeout.tv_sec = p->opt.timeout / 1000;
timeout.tv_usec = (p->opt.timeout * 1000) % 1000000;
if (ioctl(p->fd, EIOCSRTIMEOUT, (caddr_t)&timeout) < 0) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCSRTIMEOUT: %s",
pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
errno, "EIOCSRTIMEOUT");
err = PCAP_ERROR;
goto bad;
}
}
@ -481,7 +509,9 @@ your system may not be properly configured; see the packetfilter(4) man page\n",
p->bufsize = BUFSPACE;
p->buffer = malloc(p->bufsize + p->offset);
if (p->buffer == NULL) {
strlcpy(p->errbuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
errno, "malloc");
err = PCAP_ERROR;
goto bad;
}
@ -502,7 +532,7 @@ your system may not be properly configured; see the packetfilter(4) man page\n",
return (0);
bad:
pcap_cleanup_live_common(p);
return (PCAP_ERROR);
return (err);
}
pcap_t *
@ -528,10 +558,32 @@ can_be_bound(const char *name _U_)
return (1);
}
int
pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
static int
get_if_flags(const char *name _U_, bpf_u_int32 *flags _U_, char *errbuf _U_)
{
return (pcap_findalldevs_interfaces(alldevsp, errbuf, can_be_bound));
/*
* Nothing we can do other than mark loopback devices as "the
* connected/disconnected status doesn't apply".
*
* XXX - is there a way to find out whether an adapter has
* something plugged into it?
*/
if (*flags & PCAP_IF_LOOPBACK) {
/*
* Loopback devices aren't wireless, and "connected"/
* "disconnected" doesn't apply to them.
*/
*flags |= PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE;
return (0);
}
return (0);
}
int
pcap_platform_finddevs(pcap_if_list_t *devlistp, char *errbuf)
{
return (pcap_findalldevs_interfaces(devlistp, errbuf, can_be_bound,
get_if_flags));
}
static int
@ -560,8 +612,8 @@ pcap_setfilter_pf(pcap_t *p, struct bpf_program *fp)
* Yes. Try to install the filter.
*/
if (ioctl(p->fd, BIOCSETF, (caddr_t)fp) < 0) {
pcap_snprintf(p->errbuf, sizeof(p->errbuf),
"BIOCSETF: %s", pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(p->errbuf,
sizeof(p->errbuf), errno, "BIOCSETF");
return (-1);
}
@ -620,3 +672,12 @@ pcap_setfilter_pf(pcap_t *p, struct bpf_program *fp)
pf->filtering_in_kernel = 0;
return (0);
}
/*
* Libpcap version string.
*/
const char *
pcap_lib_version(void)
{
return (PCAP_VERSION_STRING);
}

436
pcap-rdmasniff.c Normal file
View File

@ -0,0 +1,436 @@
/*
* Copyright (c) 2017 Pure Storage, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "pcap-int.h"
#include "pcap-rdmasniff.h"
#include <infiniband/verbs.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#if !defined(IBV_FLOW_ATTR_SNIFFER)
#define IBV_FLOW_ATTR_SNIFFER 3
#endif
static const int RDMASNIFF_NUM_RECEIVES = 128;
static const int RDMASNIFF_RECEIVE_SIZE = 10000;
struct pcap_rdmasniff {
struct ibv_device * rdma_device;
struct ibv_context * context;
struct ibv_comp_channel * channel;
struct ibv_pd * pd;
struct ibv_cq * cq;
struct ibv_qp * qp;
struct ibv_flow * flow;
struct ibv_mr * mr;
u_char * oneshot_buffer;
unsigned port_num;
int cq_event;
u_int packets_recv;
};
static int
rdmasniff_stats(pcap_t *handle, struct pcap_stat *stat)
{
struct pcap_rdmasniff *priv = handle->priv;
stat->ps_recv = priv->packets_recv;
stat->ps_drop = 0;
stat->ps_ifdrop = 0;
return 0;
}
static void
rdmasniff_cleanup(pcap_t *handle)
{
struct pcap_rdmasniff *priv = handle->priv;
ibv_dereg_mr(priv->mr);
ibv_destroy_flow(priv->flow);
ibv_destroy_qp(priv->qp);
ibv_destroy_cq(priv->cq);
ibv_dealloc_pd(priv->pd);
ibv_destroy_comp_channel(priv->channel);
ibv_close_device(priv->context);
free(priv->oneshot_buffer);
pcap_cleanup_live_common(handle);
}
static void
rdmasniff_post_recv(pcap_t *handle, uint64_t wr_id)
{
struct pcap_rdmasniff *priv = handle->priv;
struct ibv_sge sg_entry;
struct ibv_recv_wr wr, *bad_wr;
sg_entry.length = RDMASNIFF_RECEIVE_SIZE;
sg_entry.addr = (uintptr_t) handle->buffer + RDMASNIFF_RECEIVE_SIZE * wr_id;
sg_entry.lkey = priv->mr->lkey;
wr.wr_id = wr_id;
wr.num_sge = 1;
wr.sg_list = &sg_entry;
wr.next = NULL;
ibv_post_recv(priv->qp, &wr, &bad_wr);
}
static int
rdmasniff_read(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user)
{
struct pcap_rdmasniff *priv = handle->priv;
struct ibv_cq *ev_cq;
void *ev_ctx;
struct ibv_wc wc;
struct pcap_pkthdr pkth;
u_char *pktd;
int count = 0;
if (!priv->cq_event) {
while (ibv_get_cq_event(priv->channel, &ev_cq, &ev_ctx) < 0) {
if (errno != EINTR) {
return PCAP_ERROR;
}
if (handle->break_loop) {
handle->break_loop = 0;
return PCAP_ERROR_BREAK;
}
}
ibv_ack_cq_events(priv->cq, 1);
ibv_req_notify_cq(priv->cq, 0);
priv->cq_event = 1;
}
while (count < max_packets || PACKET_COUNT_IS_UNLIMITED(max_packets)) {
if (ibv_poll_cq(priv->cq, 1, &wc) != 1) {
priv->cq_event = 0;
break;
}
if (wc.status != IBV_WC_SUCCESS) {
fprintf(stderr, "failed WC wr_id %lld status %d/%s\n",
(unsigned long long) wc.wr_id,
wc.status, ibv_wc_status_str(wc.status));
continue;
}
pkth.len = wc.byte_len;
pkth.caplen = min(pkth.len, (u_int)handle->snapshot);
gettimeofday(&pkth.ts, NULL);
pktd = (u_char *) handle->buffer + wc.wr_id * RDMASNIFF_RECEIVE_SIZE;
if (handle->fcode.bf_insns == NULL ||
bpf_filter(handle->fcode.bf_insns, pktd, pkth.len, pkth.caplen)) {
callback(user, &pkth, pktd);
++priv->packets_recv;
++count;
}
rdmasniff_post_recv(handle, wc.wr_id);
if (handle->break_loop) {
handle->break_loop = 0;
return PCAP_ERROR_BREAK;
}
}
return count;
}
static void
rdmasniff_oneshot(u_char *user, const struct pcap_pkthdr *h, const u_char *bytes)
{
struct oneshot_userdata *sp = (struct oneshot_userdata *) user;
pcap_t *handle = sp->pd;
struct pcap_rdmasniff *priv = handle->priv;
*sp->hdr = *h;
memcpy(priv->oneshot_buffer, bytes, h->caplen);
*sp->pkt = priv->oneshot_buffer;
}
static int
rdmasniff_activate(pcap_t *handle)
{
struct pcap_rdmasniff *priv = handle->priv;
struct ibv_qp_init_attr qp_init_attr;
struct ibv_qp_attr qp_attr;
struct ibv_flow_attr flow_attr;
struct ibv_port_attr port_attr;
int i;
priv->context = ibv_open_device(priv->rdma_device);
if (!priv->context) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Failed to open device %s", handle->opt.device);
goto error;
}
priv->pd = ibv_alloc_pd(priv->context);
if (!priv->pd) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Failed to alloc PD for device %s", handle->opt.device);
goto error;
}
priv->channel = ibv_create_comp_channel(priv->context);
if (!priv->channel) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Failed to create comp channel for device %s", handle->opt.device);
goto error;
}
priv->cq = ibv_create_cq(priv->context, RDMASNIFF_NUM_RECEIVES,
NULL, priv->channel, 0);
if (!priv->cq) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Failed to create CQ for device %s", handle->opt.device);
goto error;
}
ibv_req_notify_cq(priv->cq, 0);
memset(&qp_init_attr, 0, sizeof qp_init_attr);
qp_init_attr.send_cq = qp_init_attr.recv_cq = priv->cq;
qp_init_attr.cap.max_recv_wr = RDMASNIFF_NUM_RECEIVES;
qp_init_attr.cap.max_recv_sge = 1;
qp_init_attr.qp_type = IBV_QPT_RAW_PACKET;
priv->qp = ibv_create_qp(priv->pd, &qp_init_attr);
if (!priv->qp) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Failed to create QP for device %s", handle->opt.device);
goto error;
}
memset(&qp_attr, 0, sizeof qp_attr);
qp_attr.qp_state = IBV_QPS_INIT;
qp_attr.port_num = priv->port_num;
if (ibv_modify_qp(priv->qp, &qp_attr, IBV_QP_STATE | IBV_QP_PORT)) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Failed to modify QP to INIT for device %s", handle->opt.device);
goto error;
}
memset(&qp_attr, 0, sizeof qp_attr);
qp_attr.qp_state = IBV_QPS_RTR;
if (ibv_modify_qp(priv->qp, &qp_attr, IBV_QP_STATE)) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Failed to modify QP to RTR for device %s", handle->opt.device);
goto error;
}
memset(&flow_attr, 0, sizeof flow_attr);
flow_attr.type = IBV_FLOW_ATTR_SNIFFER;
flow_attr.size = sizeof flow_attr;
flow_attr.port = priv->port_num;
priv->flow = ibv_create_flow(priv->qp, &flow_attr);
if (!priv->flow) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Failed to create flow for device %s", handle->opt.device);
goto error;
}
handle->bufsize = RDMASNIFF_NUM_RECEIVES * RDMASNIFF_RECEIVE_SIZE;
handle->buffer = malloc(handle->bufsize);
if (!handle->buffer) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Failed to allocate receive buffer for device %s", handle->opt.device);
goto error;
}
priv->oneshot_buffer = malloc(RDMASNIFF_RECEIVE_SIZE);
if (!priv->oneshot_buffer) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Failed to allocate oneshot buffer for device %s", handle->opt.device);
goto error;
}
priv->mr = ibv_reg_mr(priv->pd, handle->buffer, handle->bufsize, IBV_ACCESS_LOCAL_WRITE);
if (!priv->mr) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Failed to register MR for device %s", handle->opt.device);
goto error;
}
for (i = 0; i < RDMASNIFF_NUM_RECEIVES; ++i) {
rdmasniff_post_recv(handle, i);
}
if (!ibv_query_port(priv->context, priv->port_num, &port_attr) &&
port_attr.link_layer == IBV_LINK_LAYER_INFINIBAND) {
handle->linktype = DLT_INFINIBAND;
} else {
handle->linktype = DLT_EN10MB;
}
if (handle->snapshot <= 0 || handle->snapshot > RDMASNIFF_RECEIVE_SIZE)
handle->snapshot = RDMASNIFF_RECEIVE_SIZE;
handle->offset = 0;
handle->read_op = rdmasniff_read;
handle->stats_op = rdmasniff_stats;
handle->cleanup_op = rdmasniff_cleanup;
handle->setfilter_op = install_bpf_program;
handle->setdirection_op = NULL;
handle->set_datalink_op = NULL;
handle->getnonblock_op = pcap_getnonblock_fd;
handle->setnonblock_op = pcap_setnonblock_fd;
handle->oneshot_callback = rdmasniff_oneshot;
handle->selectable_fd = priv->channel->fd;
return 0;
error:
if (priv->mr) {
ibv_dereg_mr(priv->mr);
}
if (priv->flow) {
ibv_destroy_flow(priv->flow);
}
if (priv->qp) {
ibv_destroy_qp(priv->qp);
}
if (priv->cq) {
ibv_destroy_cq(priv->cq);
}
if (priv->channel) {
ibv_destroy_comp_channel(priv->channel);
}
if (priv->pd) {
ibv_dealloc_pd(priv->pd);
}
if (priv->context) {
ibv_close_device(priv->context);
}
if (priv->oneshot_buffer) {
free(priv->oneshot_buffer);
}
return PCAP_ERROR;
}
pcap_t *
rdmasniff_create(const char *device, char *ebuf, int *is_ours)
{
struct pcap_rdmasniff *priv;
struct ibv_device **dev_list;
int numdev;
size_t namelen;
const char *port;
unsigned port_num;
int i;
pcap_t *p = NULL;
*is_ours = 0;
dev_list = ibv_get_device_list(&numdev);
if (!dev_list || !numdev) {
return NULL;
}
namelen = strlen(device);
port = strchr(device, ':');
if (port) {
port_num = strtoul(port + 1, NULL, 10);
if (port_num > 0) {
namelen = port - device;
} else {
port_num = 1;
}
} else {
port_num = 1;
}
for (i = 0; i < numdev; ++i) {
if (strlen(dev_list[i]->name) == namelen &&
!strncmp(device, dev_list[i]->name, namelen)) {
*is_ours = 1;
p = pcap_create_common(ebuf, sizeof (struct pcap_rdmasniff));
if (p) {
p->activate_op = rdmasniff_activate;
priv = p->priv;
priv->rdma_device = dev_list[i];
priv->port_num = port_num;
}
break;
}
}
ibv_free_device_list(dev_list);
return p;
}
int
rdmasniff_findalldevs(pcap_if_list_t *devlistp, char *err_str)
{
struct ibv_device **dev_list;
int numdev;
int i;
int ret = 0;
dev_list = ibv_get_device_list(&numdev);
if (!dev_list || !numdev) {
return 0;
}
for (i = 0; i < numdev; ++i) {
/*
* XXX - do the notions of "up", "running", or
* "connected" apply here?
*/
if (!add_dev(devlistp, dev_list[i]->name, 0, "RDMA sniffer", err_str)) {
ret = -1;
goto out;
}
}
out:
ibv_free_device_list(dev_list);
return ret;
}

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