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:
parent
2369c04eb9
commit
d109bf9e4b
27
CHANGES
27
CHANGES
@ -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'.
|
||||
|
2354
CMakeLists.txt
2354
CMakeLists.txt
File diff suppressed because it is too large
Load Diff
29
CONTRIBUTING
Normal file
29
CONTRIBUTING
Normal 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!
|
2
CREDITS
2
CREDITS
@ -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>
|
||||
|
@ -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
|
25
INSTALL.txt
25
INSTALL.txt
@ -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
|
||||
|
265
Makefile.in
265
Makefile.in
@ -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
55
README
@ -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
|
||||
|
@ -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
|
@ -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
|
||||
|
@ -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.
@ -1,8 +0,0 @@
|
||||
/* inline foo */
|
||||
#ifndef __cplusplus
|
||||
#ifdef __GNUC__
|
||||
#define inline __inline
|
||||
#else
|
||||
#define inline
|
||||
#endif
|
||||
#endif
|
@ -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_ */
|
@ -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>
|
||||
|
@ -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
393
aclocal.m4
vendored
@ -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])
|
||||
|
@ -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(" -- ");
|
||||
|
@ -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:
|
158
bpf_image.c
158
bpf_image.c
@ -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",
|
||||
|
@ -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,
|
||||
|
32
cmake/Modules/FindDAG.cmake
Normal file
32
cmake/Modules/FindDAG.cmake
Normal 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})
|
85
cmake/Modules/FindFseeko.cmake
Normal file
85
cmake/Modules/FindFseeko.cmake
Normal 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
153
cmake/Modules/FindLFS.cmake
Normal 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)
|
81
cmake/Modules/FindPacket.cmake
Normal file
81
cmake/Modules/FindPacket.cmake
Normal 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})
|
152
cmake/Modules/FindPthreads-w32.cmake
Normal file
152
cmake/Modules/FindPthreads-w32.cmake
Normal 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)
|
24
cmake/Modules/FindSNF.cmake
Normal file
24
cmake/Modules/FindSNF.cmake
Normal 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})
|
24
cmake/Modules/FindTC.cmake
Normal file
24
cmake/Modules/FindTC.cmake
Normal 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})
|
@ -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
21
cmake_uninstall.cmake.in
Normal 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)
|
229
cmakeconfig.h.in
229
cmakeconfig.h.in
@ -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
|
||||
|
203
config.h.in
203
config.h.in
@ -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
|
||||
|
1442
configure.ac
1442
configure.ac
File diff suppressed because it is too large
Load Diff
215
diag-control.h
Normal file
215
diag-control.h
Normal 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 */
|
18
dlpisubs.c
18
dlpisubs.c
@ -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
|
||||
|
79
etherent.c
79
etherent.c
@ -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);
|
||||
}
|
||||
}
|
||||
|
16
extract.h
16
extract.h
@ -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;
|
||||
|
40
fad-getad.c
40
fad-getad.c
@ -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);
|
||||
}
|
||||
|
89
fad-gifc.c
89
fad-gifc.c
@ -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);
|
||||
}
|
||||
|
73
fad-glifc.c
73
fad-glifc.c
@ -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);
|
||||
}
|
||||
|
884
fad-helpers.c
884
fad-helpers.c
@ -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
131
fmtutils.c
Normal 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
50
fmtutils.h
Normal 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
115
ftmacros.h
Normal 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
|
@ -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"
|
||||
|
@ -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"
|
42
gencode.h
42
gencode.h
@ -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 *);
|
||||
|
63
grammar.y
63
grammar.y
@ -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
403
inet.c
@ -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
18
libpcap.pc.in
Normal 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}
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -35,7 +35,7 @@
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "portability.h"
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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)))
|
||||
|
@ -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
|
||||
|
||||
|
860
msdos/ndis2.c
860
msdos/ndis2.c
@ -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 */
|
||||
|
559
msdos/ndis2.h
559
msdos/ndis2.h
@ -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
|
188
msdos/ndis_0.asm
188
msdos/ndis_0.asm
@ -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
|
421
nametoaddr.c
421
nametoaddr.c
@ -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
6
nomkdep
Normal 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
|
270
optimize.c
270
optimize.c
@ -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
28
optimize.h
Normal 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
|
606
pcap-bpf.c
606
pcap-bpf.c
File diff suppressed because it is too large
Load Diff
@ -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);
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
132
pcap-common.c
132
pcap-common.c
@ -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)) {
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
741
pcap-dag.c
741
pcap-dag.c
File diff suppressed because it is too large
Load Diff
@ -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);
|
||||
|
86
pcap-dbus.c
86
pcap-dbus.c
@ -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;
|
||||
}
|
||||
|
@ -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
36
pcap-dll.rc
Normal 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
|
246
pcap-dlpi.c
246
pcap-dlpi.c
@ -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);
|
||||
}
|
||||
|
70
pcap-dos.c
70
pcap-dos.c
@ -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);
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
|
@ -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.
|
||||
|
156
pcap-int.h
156
pcap-int.h
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
850
pcap-linux.c
850
pcap-linux.c
File diff suppressed because it is too large
Load Diff
@ -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;
|
||||
}
|
||||
|
@ -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
306
pcap-netmap.c
Normal 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
2
pcap-netmap.h
Normal 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
1095
pcap-new.c
File diff suppressed because it is too large
Load Diff
63
pcap-nit.c
63
pcap-nit.c
@ -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
30
pcap-null.c
30
pcap-null.c
@ -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
115
pcap-pf.c
@ -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
436
pcap-rdmasniff.c
Normal 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
Loading…
Reference in New Issue
Block a user