MFV r313676: libpcap 1.8.1

MFC after:	1 month
This commit is contained in:
Xin LI 2017-02-13 08:23:39 +00:00
commit ada6f083b9
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=313695
182 changed files with 24368 additions and 11703 deletions

View file

@ -1,5 +1,80 @@
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'.
Rename configure.in to configure.ac: autoconf 2.59
Clean up the name-to-DLT mapping table.
Add some newer DLT_ values: IPMI_HPM_2,ZWAVE_R1_R2,ZWAVE_R3,WATTSTOPPER_DLM,ISO_14443,RDS
Clarify what the return values are for both success and failure.
Many changes to build on windows
Check for the "break the loop" condition in the inner loop for TPACKET_V3.
Fix handling of packet count in the TPACKET_V3 inner loop: GitHub issue #493.
Filter out duplicate looped back CAN frames.
Fix the handling of loopback filters for IPv6 packets.
Add a link-layer header type for RDS (IEC 62106) groups.
Use different intermediate folders for x86 and x64 builds on Windows.
On Linux, handle all CAN captures with pcap-linux.c, in cooked mode.
Removes the need for the "host-endian" link-layer header type.
Compile with '-Wused-but-marked-unused' in devel mode if supported
Have separate DLTs for big-endian and host-endian SocketCAN headers.
Reflect version.h being renamed to pcap_version.h.
Require that version.h be generated: all build procedures we support generate version.h (autoconf, CMake, MSVC)!
Properly check for sock_recv() errors.
Re-impose some of Winsock's limitations on sock_recv().
Replace sprintf() with pcap_snprintf().
Fix signature of pcap_stats_ex_remote().
Initial cmake support for remote packet capture.
Have rpcap_remoteact_getsock() return a SOCKET and supply an "is active" flag.
Clean up {DAG, Septel, Myricom SNF}-only builds.
Do UTF-16-to-ASCII conversion into the right place.
pcap_create_interface() needs the interface name on Linux.
Clean up hardware time stamp support: the "any" device does not support any time stamp types.
Add support for capturing on FreeBSD usbusN interfaces.
Add a LINKTYPE/DLT_ value for FreeBSD USB.
Go back to using PCAP_API on Windows.
CMake support
Add TurboCap support from WinPcap.
Recognize 802.1ad nested VLAN tag in vlan filter.
Thursday Sep. 3, 2015 guy@alum.mit.edu
Summary for 1.7.5 libpcap release
Man page cleanups.
Add some allocation failure checks.
Fix a number of Linux/ucLinux configure/build issues.
Fix some memory leaks.
Recognize 802.1ad nested VLAN tag in vlan filter.
Fix building Bluetooth Linux Monitor support with BlueZ 5.1+
Saturday Jun. 27, 2015 mcr@sandelman.ca
Summary for 1.7.4 libpcap release
Include fix for GitHub issue #424 -- out of tree builds.
Friday Apr. 10, 2015 guy@alum.mit.edu
Summary for 1.7.3 libpcap release
Work around a Linux bonding driver bug.
Thursday Feb. 12, 2015 guy@alum.mit.edu/mcr@sandelman.ca
Summary for 1.7.2 libpcap release
Support for filtering Geneve encapsulated packets.
Generalize encapsulation handling, fixing some bugs.
Don't add null addresses to address lists.
Add pcap_dump_open_append() to open for appending.
Fix the swapping of isochronous descriptors in Linux USB.
Attempt to handle TPACKET_V1 with 32-bit userland and 64-bit kernel.
Wednesday Nov. 12, 2014 guy@alum.mit.edu/mcr@sandelman.ca
Summary for 1.7.0 libpcap release
Fix handling of zones for BPF on Solaris
new DLT for ZWAVE
clarifications for read timeouts.
Use BPF extensions in compiled filters, fixing VLAN filters
some fixes to compilation without stdint.h
EBUSY can now be returned by SNFv3 code.
Fix the range checks in BPF loads
Various DAG fixes.
Various Linux fixes.
Monday Aug. 12, 2014 guy@alum.mit.edu
Summary for 1.6.2 tcpdump release
Summary for 1.6.2 libpcap release
Don't crash on filters testing a non-existent link-layer type
field.
Fix sending in non-blocking mode on Linux with memory-mapped
@ -8,12 +83,12 @@ Monday Aug. 12, 2014 guy@alum.mit.edu
machines.
Saturday Jul. 19, 2014 mcr@sandelman.ca
Summary for 1.6.1 tcpdump release
Summary for 1.6.1 libpcap release
some fixes for the any device
changes for how --enable-XXX works
changes for how --enable-XXX (--enable-sniffing, --enable-can) works
Wednesday Jul. 2, 2014 mcr@sandelman.ca
Summary for 1.6.0 tcpdump release
Summary for 1.6.0 libpcap release
Don't support D-Bus sniffing on OS X
fixes for byte order issues with NFLOG captures
Handle using cooked mode for DLT_NETLINK in activate_new().

View file

@ -2,11 +2,12 @@ This file lists people who have contributed to libpcap:
The current maintainers:
Bill Fenner <fenner at research dot att dot com>
Denis Ovsienko <infrastation at yandex dot ru>
Denis Ovsienko <denis at ovsienko dot info>
Fulvio Risso <risso at polito dot it>
Guy Harris <guy at alum dot mit dot edu>
Hannes Gredler <hannes at juniper dot net>
Michael Richardson <mcr at sandelman dot ottawa dot on dot ca>
Francois-Xavier Le Bail <fx dot lebail at yahoo dot com>
Additional people who have contributed patches:
@ -45,7 +46,7 @@ Additional people who have contributed patches:
David Young <dyoung at ojctech dot com>
Dean Gaudet <dean at arctic dot org>
dhruv <rsrivat at sourceforge dot net>
Don Ebright <Don dot Ebright at compuware dot com>
Don Ebright <Don dot Ebright at compuware dot com>
Dug Song <dugsong at monkey dot org>
Dustin Spicuzza <dustin at virtualroadside dot com>
dzejarczech <dzejarczech at sourceforge dot net>
@ -83,6 +84,7 @@ Additional people who have contributed patches:
Jefferson Ogata <jogata at nodc dot noaa dot gov>
Jesper Dangaard Brouer <hawk at comx dot dk>
Jesper Peterson <jesper at endace dot com>
Jesse Gross <jesse at nicira dot com>
Jiri Slaby <jirislaby at gmail dot com>
Joerg Mayer <jmayer at loplof dot de>
John Bankier <jbankier at rainfinity dot com>
@ -105,6 +107,7 @@ Additional people who have contributed patches:
Mansour Behabadi <mansour at oxplot dot com>
Marcus Felipe Pereira <marcus at task dot com dot br>
Mark C. Brown <mbrown at hp dot com>
Mark Johnston <markjdb at gmail dot com>
Mark Pizzolato <List-tcpdump-workers at subscriptions dot pizzolato dot net>
Markus Mayer <markus_mayer at sourceforge dot net>
Martin Husemann <martin at netbsd dot org>

View file

@ -16,7 +16,7 @@ does support packet capture but libpcap does not support that
particular type. (If you have HP-UX, see below.) If your system uses a
packet capture not supported by libpcap, please send us patches; don't
forget to include an autoconf fragment suitable for use in
configure.in.
configure.ac.
It is possible to override the default packet capture type, although
the circumstance where this works are limited. For example if you have
@ -31,40 +31,22 @@ You will need an ANSI C compiler to build libpcap. The configure script
will abort if your compiler is not ANSI compliant. If this happens, use
the generally available GNU C compiler (GCC).
If you use flex, you must use version 2.4.6 or higher. The configure
script automatically detects the version of flex and will not use it
unless it is new enough. You can use "flex -V" to see what version you
have (unless it's really old). The current version of flex is available
at flex.sourceforge.net and often comes packaged by means of the OS.
As of this writing, the current version is 2.5.37.
You will need either Flex 2.5.31 or later, or a version of Lex
compatible with it (if any exist), to build libpcap. The configure
script will abort if there isn't any such program. If you have an older
version of Flex, or don't have a compatible version of Lex, the current
version of flex is available at flex.sourceforge.net.
If you use bison, you must use flex (and visa versa). The configure
script automatically falls back to lex and yacc if both flex and bison
are not found.
You will need either Bison, Berkeley YACC, or a version of YACC
compatible with them (if any exist), to build libpcap. The configure
script will abort if there isn't any such program. If you don't have
any such program, the current version of Bison can be found at
http://ftp.gnu.org/gnu/bison/ and the current version of Berkeley YACC
can be found at http://invisible-island.net/byacc/.
Sometimes the stock C compiler does not interact well with flex and
bison. The list of problems includes undefined references for alloca.
You can get around this by installing gcc or manually disabling flex
and bison with:
./configure --without-flex --without-bison
If your system only has AT&T lex, this is okay unless your libpcap
program uses other lex/yacc generated code. (Although it's possible to
map the yy* identifiers with a script, we use flex and bison so we
don't feel this is necessary.)
Some systems support the Berkeley Packet Filter natively; for example
out of the box OSF and BSD/OS have bpf. If your system does not support
bpf, you will need to pick up:
ftp://ftp.ee.lbl.gov/bpf-*.tar.Z
Note well: you MUST have kernel source for your operating system in
order to install bpf. An exception is SunOS 4; the bpf distribution
includes replacement kernel objects for some of the standard SunOS 4
network device drivers. See the bpf INSTALL document for more
information.
Sometimes the stock C compiler does not interact well with Flex and
Bison. The list of problems includes undefined references for alloca.
You can get around this by installing GCC.
If you use Solaris, there is a bug with bufmod(7) that is fixed in
Solaris 2.3.2 (aka SunOS 5.3.2). Setting a snapshot length with the
@ -178,14 +160,14 @@ packet timestamps aren't very good. This appears to be due to haphazard
handling of the timestamp in the kernel.
Note well: there is rumoured to be a version of tcpdump floating around
called 3.0.3 that includes libpcap and is supposed to support Linux.
called 3.0.3 that includes libpcap and is supposed to support Linux.
You should be advised that neither the Network Research Group at LBNL
nor the Tcpdump Group ever generated a release with this version number.
nor the Tcpdump Group ever generated a release with this version number.
The LBNL Network Research Group notes with interest that a standard
cracker trick to get people to install trojans is to distribute bogus
packages that have a version number higher than the current release.
packages that have a version number higher than the current release.
They also noted with annoyance that 90% of the Linux related bug reports
they got are due to changes made to unofficial versions of their page.
they got are due to changes made to unofficial versions of their page.
If you are having trouble but aren't using a version that came from
tcpdump.org, please try that before submitting a bug report!
@ -239,11 +221,11 @@ the libpcap 0.6.2 source release, so this release of libpcap might also
build without changes on UnixWare 7.
If linking tcpdump fails with "Undefined: _alloca" when using bison on
a Sun4, your version of bison is broken. In any case version 1.16 or
a Sun4, your version of Bison is broken. In any case version 1.16 or
higher is recommended (1.14 is known to cause problems 1.16 is known to
work). Either pick up a current version from:
ftp://ftp.gnu.org/pub/gnu/bison
http://ftp.gnu.org/gnu/bison/
or hack around it by inserting the lines:
@ -289,6 +271,7 @@ FILES
CHANGES - description of differences between releases
ChmodBPF/* - Mac OS X startup item to set ownership and permissions
on /dev/bpf*
CMakeLists.txt - CMake file
CREDITS - people that have helped libpcap along
INSTALL.txt - this file
LICENSE - the license under which tcpdump is distributed
@ -317,7 +300,7 @@ config.guess - autoconf support
config.h.in - autoconf input
config.sub - autoconf support
configure - configure script (run this first)
configure.in - configure script source
configure.ac - configure script source
dlpisubs.c - DLPI-related functions for pcap-dlpi.c and pcap-libdlpi.c
dlpisubs.h - DLPI-related function declarations
etherent.c - /etc/ethers support routines
@ -325,9 +308,6 @@ ethertype.h - Ethernet protocol types and names definitions
fad-getad.c - pcap_findalldevs() for systems with getifaddrs()
fad-gifc.c - pcap_findalldevs() for systems with only SIOCGIFLIST
fad-glifc.c - pcap_findalldevs() for systems with SIOCGLIFCONF
fad-null.c - pcap_findalldevs() for systems without capture support
fad-sita.c - pcap_findalldevs() for systems with SITA support
fad-win32.c - pcap_findalldevs() for WinPcap
filtertest.c - test program for BPF compiler
findalldevstest.c - test program for pcap_findalldevs()
gencode.c - BPF code generation routines
@ -345,7 +325,6 @@ nametoaddr.c - hostname to address routines
nlpid.h - OSI network layer protocol identifier definitions
net - symlink to bpf/net
optimize.c - BPF optimization routines
packaging - packaging information for building libpcap RPMs
pcap/bluetooth.h - public definition of DLT_BLUETOOTH_HCI_H4_WITH_PHDR header
pcap/bpf.h - BPF definitions
pcap/namedb.h - public libpcap name database definitions
@ -389,7 +368,6 @@ pcap_*.3pcap - manual entries for library functions
pcap-filter.4 - manual entry for filter syntax
pcap-linktype.4 - manual entry for link-layer header types
ppp.h - Point to Point Protocol definitions
runlex.sh - wrapper for Lex/Flex
savefile.c - offline support
scanner.l - filter string scanner
sunatmpos.h - definitions for SunATM capturing

View file

@ -1,9 +1,9 @@
License: BSD
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
@ -13,7 +13,7 @@ are met:
3. The names of the authors may not 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.

View file

@ -2,12 +2,12 @@
# Auto-regenerate configure script or Makefile when things change.
# From autoconf.info . Works best with GNU Make.
#
${srcdir}/configure: configure.in aclocal.m4
${srcdir}/configure: configure.ac aclocal.m4
cd ${srcdir} && autoconf
# autoheader might not change config.h.in, so touch a stamp file.
${srcdir}/config.h.in: ${srcdir}/stamp-h.in
${srcdir}/stamp-h.in: configure.in aclocal.m4
${srcdir}/stamp-h.in: configure.ac aclocal.m4
cd ${srcdir} && autoheader
echo timestamp > ${srcdir}/stamp-h.in

View file

@ -49,12 +49,13 @@ LN_S = @LN_S@
MKDEP = @MKDEP@
CCOPT = @V_CCOPT@
INCLS = -I. @V_INCLS@
DEFS = @DEFS@ @V_DEFS@
DEFS = -DBUILDING_PCAP @DEFS@ @V_DEFS@
ADDLOBJS = @ADDLOBJS@
ADDLARCHIVEOBJS = @ADDLARCHIVEOBJS@
LIBS = @LIBS@
CFLAGS = @CFLAGS@
LDFLAGS = @LDFLAGS@
CROSSFLAGS=
CFLAGS = @CFLAGS@ ${CROSSFLAGS}
LDFLAGS = @LDFLAGS@ ${CROSSFLAGS}
DYEXT = @DYEXT@
V_RPATH_OPT = @V_RPATH_OPT@
DEPENDENCY_CFLAG = @DEPENDENCY_CFLAG@
@ -68,13 +69,8 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
RANLIB = @RANLIB@
#
# Flex and bison allow you to specify the prefixes of the global symbols
# used by the generated parser. This allows programs to use lex/yacc
# and link against libpcap. If you don't have flex or bison, get them.
#
LEX = @V_LEX@
YACC = @V_YACC@
LEX = @LEX@
YACC = @YACC@
# Explicitly define compilation rule since SunOS 4's make doesn't like gcc.
# Also, gcc does not remove the .o before forking 'as', which can be a
@ -83,11 +79,11 @@ YACC = @V_YACC@
@rm -f $@
$(CC) $(FULL_CFLAGS) -c $(srcdir)/$*.c
PSRC = pcap-@V_PCAP@.c @USB_SRC@ @BT_SRC@ @BT_MONITOR_SRC@ @CAN_SRC@ @NETFILTER_SRC@ @CANUSB_SRC@ @DBUS_SRC@
FSRC = fad-@V_FINDALLDEVS@.c
PSRC = pcap-@V_PCAP@.c @USB_SRC@ @BT_SRC@ @BT_MONITOR_SRC@ @NETFILTER_SRC@ @DBUS_SRC@
FSRC = @V_FINDALLDEVS@
SSRC = @SSRC@
CSRC = pcap.c inet.c gencode.c optimize.c nametoaddr.c etherent.c \
savefile.c sf-pcap.c sf-pcap-ng.c pcap-common.c \
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
LIBOBJS = @LIBOBJS@
@ -103,6 +99,9 @@ PUBHDR = \
pcap-namedb.h \
pcap/bpf.h \
pcap/bluetooth.h \
pcap/can_socketcan.h \
pcap/dlt.h \
pcap/export-defs.h \
pcap/ipnet.h \
pcap/namedb.h \
pcap/nflog.h \
@ -115,37 +114,43 @@ HDR = $(PUBHDR) \
arcnet.h \
atmuni31.h \
ethertype.h \
extract.h \
gencode.h \
ieee80211.h \
llc.h \
nametoaddr.h \
nlpid.h \
pcap-common.h \
pcap-int.h \
pcap-stdinc.h \
portability.h \
ppp.h \
sf-pcap.h \
sf-pcap-ng.h \
sunatmpos.h
TESTS = \
@VALGRINDTEST@ \
capturetest \
can_set_rfmon_test \
filtertest \
findalldevstest \
opentest \
selpolltest \
valgrindtest
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 \
tests/valgrindtest.c
tests/selpolltest.c
GENHDR = \
scanner.h tokdefs.h version.h
scanner.h grammar.h pcap_version.h
TAGFILES = \
$(SRC) $(HDR)
@ -231,6 +236,8 @@ EXTRA_DIST = \
ChmodBPF/ChmodBPF \
ChmodBPF/StartupParameters.plist \
CREDITS \
CMakeLists.txt \
GenVersion.bat \
INSTALL.txt \
LICENSE \
Makefile.in \
@ -253,29 +260,37 @@ EXTRA_DIST = \
aclocal.m4 \
bpf/net/bpf_filter.c \
chmod_bpf \
cmakeconfig.h.in \
cmake/preconfigure.cmake \
config/have_siocglifconf.c \
config.guess \
config.h.in \
config.sub \
configure \
configure.in \
configure.ac \
dlpisubs.c \
dlpisubs.h \
fad-getad.c \
fad-gifc.c \
fad-glifc.c \
fad-null.c \
fad-sita.c \
fad-win32.c \
fad-helpers.c \
gen_version_c.sh \
gen_version_header.sh \
grammar.y \
install-sh \
lbl/os-aix4.h \
lbl/os-aix7.h \
lbl/os-hpux11.h \
lbl/os-osf4.h \
lbl/os-osf5.h \
lbl/os-solaris2.h \
lbl/os-sunos4.h \
lbl/os-ultrix4.h \
missing/getopt.c \
missing/getopt.h \
missing/snprintf.c \
missing/strtok_r.c \
missing/win_snprintf.c \
mkdep \
msdos/bin2c.c \
msdos/common.dj \
@ -291,16 +306,11 @@ EXTRA_DIST = \
msdos/pktdrvr.h \
msdos/readme.dos \
org.tcpdump.chmod_bpf.plist \
packaging/pcap.spec.in \
pcap-bpf.c \
pcap-bt-linux.c \
pcap-bt-linux.h \
pcap-bt-monitor-linux.c \
pcap-bt-monitor-linux.h \
pcap-can-linux.c \
pcap-can-linux.h \
pcap-canusb-linux.c \
pcap-canusb-linux.h \
pcap-config.in \
pcap-dag.c \
pcap-dag.h \
@ -314,11 +324,14 @@ EXTRA_DIST = \
pcap-libdlpi.c \
pcap-linux.c \
pcap-namedb.h \
pcap-new.c \
pcap-netfilter-linux.c \
pcap-netfilter-linux.h \
pcap-nit.c \
pcap-null.c \
pcap-pf.c \
pcap-rpcap.c \
pcap-rpcap.h \
pcap-septel.c \
pcap-septel.h \
pcap-sita.h \
@ -328,34 +341,22 @@ EXTRA_DIST = \
pcap-snf.h \
pcap-snit.c \
pcap-snoop.c \
pcap-tc.c \
pcap-tc.h \
pcap-usb-linux.c \
pcap-usb-linux.h \
pcap-win32.c \
runlex.sh \
remote-ext.h \
sockutils.c \
sockutils.h \
scanner.l \
tests/CMakeLists.txt \
pcap_version.h.in \
Win32/Include/Gnuc.h \
Win32/Include/addrinfo.h \
Win32/Include/bittypes.h \
Win32/Include/cdecl_ext.h \
Win32/Include/inetprivate.h \
Win32/Include/ip6_misc.h \
Win32/Include/sockstorage.h \
Win32/Include/arpa/nameser.h \
Win32/Include/net/if.h \
Win32/Include/net/netdb.h \
Win32/Include/net/paths.h \
Win32/Prj/libpcap.dsp \
Win32/Prj/libpcap.dsw \
Win32/Src/ffs.c \
Win32/Src/gai_strerror.c \
Win32/Src/getaddrinfo.c \
Win32/Src/getnetbynm.c \
Win32/Src/getnetent.c \
Win32/Src/getopt.c \
Win32/Src/getservent.c \
Win32/Src/inet_aton.c \
Win32/Src/inet_net.c \
Win32/Src/inet_pton.c
Win32/Prj/wpcap.sln \
Win32/Prj/wpcap.vcxproj \
Win32/Prj/wpcap.vcxproj.filters
all: libpcap.a shared pcap-config
@ -443,24 +444,33 @@ libpcap.shareda: $(OBJ)
libpcap.none:
scanner.c: $(srcdir)/scanner.l
@rm -f $@
$(srcdir)/runlex.sh $(LEX) -o$@ $<
$(LEX) -P pcap_ --header-file=scanner.h --nounput -o scanner.c $<
scanner.h: scanner.c
## Recover from the removal of $@
@if test -f $@; then :; else \
rm -f scanner.c; \
$(MAKE) $(MAKEFLAGS) scanner.c; \
fi
scanner.o: scanner.c tokdefs.h
scanner.o: scanner.c grammar.h
$(CC) $(FULL_CFLAGS) -c scanner.c
pcap.o: version.h
pcap.o: pcap_version.h
tokdefs.h: grammar.c
grammar.c: $(srcdir)/grammar.y
@rm -f grammar.c tokdefs.h
$(YACC) -d $<
mv y.tab.c grammar.c
mv y.tab.h tokdefs.h
$(YACC) -p pcap_ -o grammar.c -d $<
grammar.h: grammar.c
## Recover from the removal of $@
@if test -f $@; then :; else \
rm -f grammar.c; \
$(MAKE) $(MAKEFLAGS) grammar.c; \
fi
grammar.o: grammar.c
@rm -f $@
$(CC) $(FULL_CFLAGS) -Dyylval=pcap_lval -c grammar.c
$(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
@ -468,32 +478,21 @@ version.o: version.c
snprintf.o: $(srcdir)/missing/snprintf.c
$(CC) $(FULL_CFLAGS) -o $@ -c $(srcdir)/missing/snprintf.c
version.c: $(srcdir)/VERSION
@rm -f $@
if grep GIT ${srcdir}/VERSION >/dev/null; then \
read ver <${srcdir}/VERSION; \
echo $$ver | tr -d '\012'; \
date +_%Y_%m_%d; \
else \
cat ${srcdir}/VERSION; \
fi | sed -e 's/.*/char pcap_version[] = "&";/' > $@
strtok_r.o: $(srcdir)/missing/strtok_r.c
$(CC) $(FULL_CFLAGS) -o $@ -c $(srcdir)/missing/strtok_r.c
#
# NOTE: this really is supposed to be static; importing a string
# from a shared library does not work very well on many
# versions of UNIX (Solaris, Linux, and the BSDs, for example),
# so we make the version string static and return it from
# a function, which does work.
#
version.h: $(srcdir)/VERSION
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 $@
if grep GIT ${srcdir}/VERSION >/dev/null; then \
read ver <${srcdir}/VERSION; \
echo $$ver | tr -d '\012'; \
date +_%Y_%m_%d; \
else \
cat ${srcdir}/VERSION; \
fi | sed -e 's/.*/static const char pcap_version_string[] = "libpcap version &";/' > $@
$(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
@ -530,6 +529,9 @@ tests: $(TESTS)
capturetest: tests/capturetest.c libpcap.a
$(CC) $(FULL_CFLAGS) -I. -L. -o capturetest $(srcdir)/tests/capturetest.c libpcap.a $(LIBS)
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)
@ -539,6 +541,9 @@ findalldevstest: tests/findalldevstest.c libpcap.a
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)
@ -728,13 +733,12 @@ distclean: clean
rm -f $(MAN3PCAP_EXPAND:.in=) $(MANFILE:.in=) $(MANMISC:.in=)
rm -rf autom4te.cache
extags: $(TAGFILES)
ctags $(TAGFILES)
tags: $(TAGFILES)
ctags -wtd $(TAGFILES)
packaging/pcap.spec: packaging/pcap.spec.in VERSION
RPMVERSION=`cat VERSION | sed s/-.*//g`; \
sed -e s/@VERSION@/$$RPMVERSION/ -e s/@NAME@/libpcap-`cat VERSION`/ $< > $@
releasetar:
@cwd=`pwd` ; dir=`basename $$cwd` ; name=$(PROG)-`cat VERSION` ; \
mkdir $$name; \

View file

@ -76,15 +76,15 @@ information on configuring that option.
Note to Linux distributions and *BSD systems that include libpcap:
There's now a rule to make a shared library, which should work on Linux
There's now a rule to make a shared library, which should work on Linux
and *BSD, among other platforms.
It sets the soname of the library to "libpcap.so.1"; this is what it
should be, *NOT* libpcap.so.1.x or libpcap.so.1.x.y or something such as
It sets the soname of the library to "libpcap.so.1"; this is what it
should be, *NOT* libpcap.so.1.x or libpcap.so.1.x.y or something such as
that.
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
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

View file

@ -6,11 +6,11 @@ Important stuff (to be done before the next release)
General
- configure should not be in Git. Most open source projects have an
autogen.sh script to run autoconf etc. after checkout. I think we
should stick to the standard.
- configure should not be in Git. Most open source projects have an
autogen.sh script to run autoconf etc. after checkout. I think we
should stick to the standard.
- The source files should be better documented. There is no official
- The source files should be better documented. There is no official
design guideline for what is done where. There should be a common coding
style (okay, you can guess that by looking at the code) and a guide for
what needs to be documented.
@ -18,7 +18,7 @@ General
Less urgent items
-----------------
- Better documentation and cleanup of the interface. I am seeing a few
- Better documentation and cleanup of the interface. I am seeing a few
problems at the first glance which needs fixing:
+ pcap_lookupnet makes little to no sense with protocols != IPv4
+ not very well suited for interactive programs (think ethereal). There

View file

@ -1 +1 @@
1.6.2
1.8.1

View file

@ -42,11 +42,11 @@
#include "config.h"
#endif
#ifdef WIN32
#ifdef _WIN32
#include <pcap-stdinc.h>
#else /* WIN32 */
#else /* _WIN32 */
#if HAVE_INTTYPES_H
#include <inttypes.h>
@ -73,7 +73,7 @@
# define MLEN(m) ((m)->m_len)
#endif /* defined(__hpux) || SOLARIS */
#endif /* WIN32 */
#endif /* _WIN32 */
#include <pcap/bpf.h>
@ -99,7 +99,7 @@
#endif
#ifndef LBL_ALIGN
#ifndef WIN32
#ifndef _WIN32
#include <netinet/in.h>
#endif
@ -195,23 +195,41 @@ m_xhalf(m, k, err)
}
#endif
#ifdef __linux__
#include <linux/types.h>
#include <linux/if_packet.h>
#include <linux/filter.h>
#endif
enum {
BPF_S_ANC_NONE,
BPF_S_ANC_VLAN_TAG,
BPF_S_ANC_VLAN_TAG_PRESENT,
};
/*
* Execute the filter program starting at pc on the packet p
* wirelen is the length of the original packet
* buflen is the amount of data present
* aux_data is auxiliary data, currently used only when interpreting
* filters intended for the Linux kernel in cases where the kernel
* rejects the filter; it contains VLAN tag information
* For the kernel, p is assumed to be a pointer to an mbuf if buflen is 0,
* in all other cases, p is a pointer to a buffer and buflen is its size.
*
* Thanks to Ani Sinha <ani@arista.com> for providing initial implementation
*/
u_int
bpf_filter(pc, p, wirelen, buflen)
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;
{
register u_int32 A, X;
register int k;
int32 mem[BPF_MEMWORDS];
register bpf_u_int32 k;
u_int32 mem[BPF_MEMWORDS];
#if defined(KERNEL) || defined(_KERNEL)
struct mbuf *m, *n;
int merr, len;
@ -250,7 +268,7 @@ bpf_filter(pc, p, wirelen, buflen)
case BPF_LD|BPF_W|BPF_ABS:
k = pc->k;
if (k + sizeof(int32) > buflen) {
if (k > buflen || sizeof(int32_t) > buflen - k) {
#if defined(KERNEL) || defined(_KERNEL)
if (m == NULL)
return 0;
@ -267,7 +285,7 @@ bpf_filter(pc, p, wirelen, buflen)
case BPF_LD|BPF_H|BPF_ABS:
k = pc->k;
if (k + sizeof(short) > buflen) {
if (k > buflen || sizeof(int16_t) > buflen - k) {
#if defined(KERNEL) || defined(_KERNEL)
if (m == NULL)
return 0;
@ -283,22 +301,50 @@ bpf_filter(pc, p, wirelen, buflen)
continue;
case BPF_LD|BPF_B|BPF_ABS:
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];
continue;
{
#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) {
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;
case BPF_S_ANC_VLAN_TAG_PRESENT:
if (aux_data)
A = aux_data->vlan_tag_present;
break;
}
#endif
continue;
}
case BPF_LD|BPF_W|BPF_LEN:
A = wirelen;
continue;
@ -309,7 +355,8 @@ bpf_filter(pc, p, wirelen, buflen)
case BPF_LD|BPF_W|BPF_IND:
k = X + pc->k;
if (k + sizeof(int32) > buflen) {
if (pc->k > buflen || X > buflen - pc->k ||
sizeof(int32_t) > buflen - k) {
#if defined(KERNEL) || defined(_KERNEL)
if (m == NULL)
return 0;
@ -326,7 +373,8 @@ bpf_filter(pc, p, wirelen, buflen)
case BPF_LD|BPF_H|BPF_IND:
k = X + pc->k;
if (k + sizeof(short) > buflen) {
if (X > buflen || pc->k > buflen - X ||
sizeof(int16_t) > buflen - k) {
#if defined(KERNEL) || defined(_KERNEL)
if (m == NULL)
return 0;
@ -343,7 +391,7 @@ bpf_filter(pc, p, wirelen, buflen)
case BPF_LD|BPF_B|BPF_IND:
k = X + pc->k;
if (k >= buflen) {
if (pc->k >= buflen || X >= buflen - pc->k) {
#if defined(KERNEL) || defined(_KERNEL)
if (m == NULL)
return 0;
@ -531,7 +579,12 @@ bpf_filter(pc, p, wirelen, buflen)
continue;
case BPF_ALU|BPF_NEG:
A = -A;
/*
* Most BPF arithmetic is unsigned, but negation
* can't be unsigned; throw some casts to
* specify what we're trying to do.
*/
A = (u_int32)(-(int32)A);
continue;
case BPF_MISC|BPF_TAX:
@ -545,6 +598,17 @@ bpf_filter(pc, p, wirelen, buflen)
}
}
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;
{
return bpf_filter_with_aux_data(pc, p, wirelen, buflen, NULL);
}
/*
* Return true if the 'fcode' is a valid filter program.
* The constraints are that each jump be forward and to a valid
@ -574,7 +638,7 @@ bpf_validate(f, len)
return 0;
#endif
for (i = 0; i < len; ++i) {
for (i = 0; i < (u_int)len; ++i) {
p = &f[i];
switch (BPF_CLASS(p->code)) {
/*
@ -675,7 +739,7 @@ bpf_validate(f, len)
#if defined(KERNEL) || defined(_KERNEL)
if (from + p->k < from || from + p->k >= len)
#else
if (from + p->k >= len)
if (from + p->k >= (u_int)len)
#endif
return 0;
break;
@ -683,7 +747,7 @@ bpf_validate(f, len)
case BPF_JGT:
case BPF_JGE:
case BPF_JSET:
if (from + p->jt >= len || from + p->jf >= len)
if (from + p->jt >= (u_int)len || from + p->jf >= (u_int)len)
return 0;
break;
default:

View file

@ -51,7 +51,10 @@ bpf_dump(const struct bpf_program *p, int option)
for (i = 0; i < n; ++insn, ++i) {
#ifdef BDEBUG
extern int bids[];
printf(bids[i] > 0 ? "[%02d]" : " -- ", bids[i] - 1);
if (bids[i] > 0)
printf("[%02d]", bids[i] - 1);
else
printf(" -- ");
#endif
puts(bpf_image(insn, i));
}

View file

@ -23,9 +23,9 @@
#include "config.h"
#endif
#ifdef WIN32
#ifdef _WIN32
#include <pcap-stdinc.h>
#else /* WIN32 */
#else /* _WIN32 */
#if HAVE_INTTYPES_H
#include <inttypes.h>
#elif HAVE_STDINT_H
@ -35,7 +35,7 @@
#include <sys/bitypes.h>
#endif
#include <sys/types.h>
#endif /* WIN32 */
#endif /* _WIN32 */
#include <stdio.h>
#include <string.h>
@ -306,13 +306,13 @@ bpf_image(p, n)
fmt = "";
break;
}
(void)snprintf(operand, sizeof operand, fmt, v);
(void)pcap_snprintf(operand, sizeof operand, fmt, v);
if (BPF_CLASS(p->code) == BPF_JMP && BPF_OP(p->code) != BPF_JA) {
(void)snprintf(image, sizeof image,
(void)pcap_snprintf(image, sizeof image,
"(%03d) %-8s %-16s jt %d\tjf %d",
n, op, operand, n + 1 + p->jt, n + 1 + p->jf);
} else {
(void)snprintf(image, sizeof image,
(void)pcap_snprintf(image, sizeof image,
"(%03d) %-8s %s",
n, op, operand);
}

View file

@ -1,14 +1,12 @@
#! /bin/sh
# Attempt to guess a canonical system name.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
# 2011, 2012 Free Software Foundation, Inc.
# Copyright 1992-2015 Free Software Foundation, Inc.
timestamp='2012-02-10'
timestamp='2015-02-23'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
@ -22,19 +20,17 @@ timestamp='2012-02-10'
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Originally written by Per Bothner. Please send patches (context
# diff format) to <config-patches@gnu.org> and include a ChangeLog
# entry.
# the same distribution terms that you use for the rest of that
# program. This Exception is an additional permission under section 7
# of the GNU General Public License, version 3 ("GPLv3").
#
# This script attempts to guess a canonical system name similar to
# config.sub. If it succeeds, it prints the system name on stdout, and
# exits with 0. Otherwise, it exits with 1.
# Originally written by Per Bothner; maintained since 2000 by Ben Elliston.
#
# You can get the latest version of this script from:
# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
#
# Please send patches to <config-patches@gnu.org>.
me=`echo "$0" | sed -e 's,.*/,,'`
@ -54,9 +50,7 @@ version="\
GNU config.guess ($timestamp)
Originally written by Per Bothner.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
Free Software Foundation, Inc.
Copyright 1992-2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@ -138,6 +132,27 @@ UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
case "${UNAME_SYSTEM}" in
Linux|GNU|GNU/*)
# If the system lacks a compiler, then just pick glibc.
# We could probably try harder.
LIBC=gnu
eval $set_cc_for_build
cat <<-EOF > $dummy.c
#include <features.h>
#if defined(__UCLIBC__)
LIBC=uclibc
#elif defined(__dietlibc__)
LIBC=dietlibc
#else
LIBC=gnu
#endif
EOF
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
;;
esac
# Note: order is significant - the case branches are not exclusive.
case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
@ -153,20 +168,27 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# Note: NetBSD doesn't particularly care about the vendor
# portion of the name. We always set it to "unknown".
sysctl="sysctl -n hw.machine_arch"
UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
/usr/sbin/$sysctl 2>/dev/null || echo unknown)`
UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \
/sbin/$sysctl 2>/dev/null || \
/usr/sbin/$sysctl 2>/dev/null || \
echo unknown)`
case "${UNAME_MACHINE_ARCH}" in
armeb) machine=armeb-unknown ;;
arm*) machine=arm-unknown ;;
sh3el) machine=shl-unknown ;;
sh3eb) machine=sh-unknown ;;
sh5el) machine=sh5le-unknown ;;
earmv*)
arch=`echo ${UNAME_MACHINE_ARCH} | sed -e 's,^e\(armv[0-9]\).*$,\1,'`
endian=`echo ${UNAME_MACHINE_ARCH} | sed -ne 's,^.*\(eb\)$,\1,p'`
machine=${arch}${endian}-unknown
;;
*) machine=${UNAME_MACHINE_ARCH}-unknown ;;
esac
# The Operating System including object format, if it has switched
# to ELF recently, or will in the future.
case "${UNAME_MACHINE_ARCH}" in
arm*|i386|m68k|ns32k|sh3*|sparc|vax)
arm*|earm*|i386|m68k|ns32k|sh3*|sparc|vax)
eval $set_cc_for_build
if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ELF__
@ -182,6 +204,13 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
os=netbsd
;;
esac
# Determine ABI tags.
case "${UNAME_MACHINE_ARCH}" in
earm*)
expr='s/^earmv[0-9]/-eabi/;s/eb$//'
abi=`echo ${UNAME_MACHINE_ARCH} | sed -e "$expr"`
;;
esac
# The OS release
# Debian GNU/NetBSD machines have a different userland, and
# thus, need a distinct triplet. However, they do not need
@ -198,7 +227,11 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
# contains redundant information, the shorter form:
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
echo "${machine}-${os}${release}"
echo "${machine}-${os}${release}${abi}"
exit ;;
*:Bitrig:*:*)
UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
exit ;;
*:OpenBSD:*:*)
UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
@ -302,7 +335,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
echo arm-acorn-riscix${UNAME_RELEASE}
exit ;;
arm:riscos:*:*|arm:RISCOS:*:*)
arm*:riscos:*:*|arm*:RISCOS:*:*)
echo arm-unknown-riscos
exit ;;
SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
@ -560,8 +593,9 @@ EOF
else
IBM_ARCH=powerpc
fi
if [ -x /usr/bin/oslevel ] ; then
IBM_REV=`/usr/bin/oslevel`
if [ -x /usr/bin/lslpp ] ; then
IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc |
awk -F: '{ print $3 }' | sed s/[0-9]*$/0/`
else
IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
fi
@ -801,10 +835,13 @@ EOF
i*:CYGWIN*:*)
echo ${UNAME_MACHINE}-pc-cygwin
exit ;;
*:MINGW64*:*)
echo ${UNAME_MACHINE}-pc-mingw64
exit ;;
*:MINGW*:*)
echo ${UNAME_MACHINE}-pc-mingw32
exit ;;
i*:MSYS*:*)
*:MSYS*:*)
echo ${UNAME_MACHINE}-pc-msys
exit ;;
i*:windows32*:*)
@ -852,21 +889,21 @@ EOF
exit ;;
*:GNU:*:*)
# the GNU system
echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
exit ;;
*:GNU/*:*:*)
# other systems with GNU libc and userland
echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
exit ;;
i*86:Minix:*:*)
echo ${UNAME_MACHINE}-pc-minix
exit ;;
aarch64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
aarch64_be:Linux:*:*)
UNAME_MACHINE=aarch64_be
echo ${UNAME_MACHINE}-unknown-linux-gnu
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
alpha:Linux:*:*)
case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
@ -879,59 +916,54 @@ EOF
EV68*) UNAME_MACHINE=alphaev68 ;;
esac
objdump --private-headers /bin/sh | grep -q ld.so.1
if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
if test "$?" = 0 ; then LIBC="gnulibc1" ; fi
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
arc:Linux:*:* | arceb:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
arm*:Linux:*:*)
eval $set_cc_for_build
if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ARM_EABI__
then
echo ${UNAME_MACHINE}-unknown-linux-gnu
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
else
if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ARM_PCS_VFP
then
echo ${UNAME_MACHINE}-unknown-linux-gnueabi
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi
else
echo ${UNAME_MACHINE}-unknown-linux-gnueabihf
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf
fi
fi
exit ;;
avr32*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
cris:Linux:*:*)
echo ${UNAME_MACHINE}-axis-linux-gnu
echo ${UNAME_MACHINE}-axis-linux-${LIBC}
exit ;;
crisv32:Linux:*:*)
echo ${UNAME_MACHINE}-axis-linux-gnu
echo ${UNAME_MACHINE}-axis-linux-${LIBC}
exit ;;
frv:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
hexagon:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
i*86:Linux:*:*)
LIBC=gnu
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#ifdef __dietlibc__
LIBC=dietlibc
#endif
EOF
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
echo ${UNAME_MACHINE}-pc-linux-${LIBC}
exit ;;
ia64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
m32r*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
m68*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
mips:Linux:*:* | mips64:Linux:*:*)
eval $set_cc_for_build
@ -950,54 +982,63 @@ EOF
#endif
EOF
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
;;
or32:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
openrisc*:Linux:*:*)
echo or1k-unknown-linux-${LIBC}
exit ;;
or32:Linux:*:* | or1k*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
padre:Linux:*:*)
echo sparc-unknown-linux-gnu
echo sparc-unknown-linux-${LIBC}
exit ;;
parisc64:Linux:*:* | hppa64:Linux:*:*)
echo hppa64-unknown-linux-gnu
echo hppa64-unknown-linux-${LIBC}
exit ;;
parisc:Linux:*:* | hppa:Linux:*:*)
# Look for CPU level
case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
PA7*) echo hppa1.1-unknown-linux-gnu ;;
PA8*) echo hppa2.0-unknown-linux-gnu ;;
*) echo hppa-unknown-linux-gnu ;;
PA7*) echo hppa1.1-unknown-linux-${LIBC} ;;
PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;
*) echo hppa-unknown-linux-${LIBC} ;;
esac
exit ;;
ppc64:Linux:*:*)
echo powerpc64-unknown-linux-gnu
echo powerpc64-unknown-linux-${LIBC}
exit ;;
ppc:Linux:*:*)
echo powerpc-unknown-linux-gnu
echo powerpc-unknown-linux-${LIBC}
exit ;;
ppc64le:Linux:*:*)
echo powerpc64le-unknown-linux-${LIBC}
exit ;;
ppcle:Linux:*:*)
echo powerpcle-unknown-linux-${LIBC}
exit ;;
s390:Linux:*:* | s390x:Linux:*:*)
echo ${UNAME_MACHINE}-ibm-linux
echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
exit ;;
sh64*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
sh*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
sparc:Linux:*:* | sparc64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
tile*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
vax:Linux:*:*)
echo ${UNAME_MACHINE}-dec-linux-gnu
echo ${UNAME_MACHINE}-dec-linux-${LIBC}
exit ;;
x86_64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
xtensa*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
i*86:DYNIX/ptx:4*:*)
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
@ -1201,6 +1242,9 @@ EOF
BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
echo i586-pc-haiku
exit ;;
x86_64:Haiku:*:*)
echo x86_64-unknown-haiku
exit ;;
SX-4:SUPER-UX:*:*)
echo sx4-nec-superux${UNAME_RELEASE}
exit ;;
@ -1227,19 +1271,31 @@ EOF
exit ;;
*:Darwin:*:*)
UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
case $UNAME_PROCESSOR in
i386)
eval $set_cc_for_build
if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
grep IS_64BIT_ARCH >/dev/null
then
UNAME_PROCESSOR="x86_64"
fi
fi ;;
unknown) UNAME_PROCESSOR=powerpc ;;
esac
eval $set_cc_for_build
if test "$UNAME_PROCESSOR" = unknown ; then
UNAME_PROCESSOR=powerpc
fi
if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then
if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
grep IS_64BIT_ARCH >/dev/null
then
case $UNAME_PROCESSOR in
i386) UNAME_PROCESSOR=x86_64 ;;
powerpc) UNAME_PROCESSOR=powerpc64 ;;
esac
fi
fi
elif test "$UNAME_PROCESSOR" = i386 ; then
# Avoid executing cc on OS X 10.9, as it ships with a stub
# that puts up a graphical alert prompting to install
# developer tools. Any system running Mac OS X 10.7 or
# later (Darwin 11 and later) is required to have a 64-bit
# processor. This is not true of the ARM version of Darwin
# that Apple uses in portable devices.
UNAME_PROCESSOR=x86_64
fi
echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
exit ;;
*:procnto*:*:* | *:QNX:[0123456789]*:*)
@ -1256,7 +1312,7 @@ EOF
NEO-?:NONSTOP_KERNEL:*:*)
echo neo-tandem-nsk${UNAME_RELEASE}
exit ;;
NSE-?:NONSTOP_KERNEL:*:*)
NSE-*:NONSTOP_KERNEL:*:*)
echo nse-tandem-nsk${UNAME_RELEASE}
exit ;;
NSR-?:NONSTOP_KERNEL:*:*)
@ -1330,157 +1386,6 @@ EOF
exit ;;
esac
#echo '(No uname command or uname output not recognized.)' 1>&2
#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
eval $set_cc_for_build
cat >$dummy.c <<EOF
#ifdef _SEQUENT_
# include <sys/types.h>
# include <sys/utsname.h>
#endif
main ()
{
#if defined (sony)
#if defined (MIPSEB)
/* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
I don't know.... */
printf ("mips-sony-bsd\n"); exit (0);
#else
#include <sys/param.h>
printf ("m68k-sony-newsos%s\n",
#ifdef NEWSOS4
"4"
#else
""
#endif
); exit (0);
#endif
#endif
#if defined (__arm) && defined (__acorn) && defined (__unix)
printf ("arm-acorn-riscix\n"); exit (0);
#endif
#if defined (hp300) && !defined (hpux)
printf ("m68k-hp-bsd\n"); exit (0);
#endif
#if defined (NeXT)
#if !defined (__ARCHITECTURE__)
#define __ARCHITECTURE__ "m68k"
#endif
int version;
version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
if (version < 4)
printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
else
printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
exit (0);
#endif
#if defined (MULTIMAX) || defined (n16)
#if defined (UMAXV)
printf ("ns32k-encore-sysv\n"); exit (0);
#else
#if defined (CMU)
printf ("ns32k-encore-mach\n"); exit (0);
#else
printf ("ns32k-encore-bsd\n"); exit (0);
#endif
#endif
#endif
#if defined (__386BSD__)
printf ("i386-pc-bsd\n"); exit (0);
#endif
#if defined (sequent)
#if defined (i386)
printf ("i386-sequent-dynix\n"); exit (0);
#endif
#if defined (ns32000)
printf ("ns32k-sequent-dynix\n"); exit (0);
#endif
#endif
#if defined (_SEQUENT_)
struct utsname un;
uname(&un);
if (strncmp(un.version, "V2", 2) == 0) {
printf ("i386-sequent-ptx2\n"); exit (0);
}
if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
printf ("i386-sequent-ptx1\n"); exit (0);
}
printf ("i386-sequent-ptx\n"); exit (0);
#endif
#if defined (vax)
# if !defined (ultrix)
# include <sys/param.h>
# if defined (BSD)
# if BSD == 43
printf ("vax-dec-bsd4.3\n"); exit (0);
# else
# if BSD == 199006
printf ("vax-dec-bsd4.3reno\n"); exit (0);
# else
printf ("vax-dec-bsd\n"); exit (0);
# endif
# endif
# else
printf ("vax-dec-bsd\n"); exit (0);
# endif
# else
printf ("vax-dec-ultrix\n"); exit (0);
# endif
#endif
#if defined (alliant) && defined (i860)
printf ("i860-alliant-bsd\n"); exit (0);
#endif
exit (1);
}
EOF
$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
{ echo "$SYSTEM_NAME"; exit; }
# Apollos put the system type in the environment.
test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
# Convex versions that predate uname can use getsysinfo(1)
if [ -x /usr/convex/getsysinfo ]
then
case `getsysinfo -f cpu_type` in
c1*)
echo c1-convex-bsd
exit ;;
c2*)
if getsysinfo -f scalar_acc
then echo c32-convex-bsd
else echo c2-convex-bsd
fi
exit ;;
c34*)
echo c34-convex-bsd
exit ;;
c38*)
echo c38-convex-bsd
exit ;;
c4*)
echo c4-convex-bsd
exit ;;
esac
fi
cat >&2 <<EOF
$0: unable to guess system type

View file

@ -1,4 +1,4 @@
/* config.h.in. Generated from configure.in by autoheader. */
/* config.h.in. Generated from configure.ac by autoheader. */
/* Enable optimizer debugging */
#undef BDEBUG
@ -76,12 +76,18 @@
/* Define to 1 if you have the <linux/ethtool.h> header file. */
#undef HAVE_LINUX_ETHTOOL_H
/* 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/sockios.h> header file. */
#undef HAVE_LINUX_SOCKIOS_H
/* if tp_vlan_tci exists */
#undef HAVE_LINUX_TPACKET_AUXDATA_TP_VLAN_TCI
@ -118,16 +124,13 @@
/* if there's an os_proto.h for this platform, to use additional prototypes */
#undef HAVE_OS_PROTO_H
/* Define to 1 if you have the <paths.h> header file. */
#undef HAVE_PATHS_H
/* define if net/pfvar.h defines PF_NAT through PF_NORDR */
#undef HAVE_PF_NAT_THROUGH_PF_NORDR
/* define if you have a Septel API */
/* define if you have the Septel API */
#undef HAVE_SEPTEL_API
/* define if you have Myricom SNF API */
/* define if you have the Myricom SNF API */
#undef HAVE_SNF_API
/* Define to 1 if you have the `snprintf' function. */
@ -163,6 +166,9 @@
/* Define to 1 if you have the `strlcpy' function. */
#undef HAVE_STRLCPY
/* Define to 1 if you have the `strtok_r' function. */
#undef HAVE_STRTOK_R
/* Define to 1 if the system has the type `struct BPF_TIMEVAL'. */
#undef HAVE_STRUCT_BPF_TIMEVAL
@ -181,6 +187,9 @@
/* 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/sockio.h> header file. */
#undef HAVE_SYS_SOCKIO_H
@ -190,6 +199,9 @@
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* define if you have the TurboCap API */
#undef HAVE_TC_API
/* if if_packet.h has tpacket_stats defined */
#undef HAVE_TPACKET_STATS
@ -199,9 +211,6 @@
/* if struct usbdevfs_ctrltransfer has bRequestType */
#undef HAVE_USBDEVFS_CTRLTRANSFER_BREQUESTTYPE
/* define if version.h is generated in the build procedure */
#undef HAVE_VERSION_H
/* Define to 1 if you have the `vsnprintf' function. */
#undef HAVE_VSNPRINTF
@ -220,9 +229,6 @@
/* path for device for USB sniffing */
#undef LINUX_USB_MON_DEV
/* if we need a pcap_parse wrapper around yyparse */
#undef NEED_YYPARSE_WRAPPER
/* Define to 1 if netinet/ether.h declares `ether_hostton' */
#undef NETINET_ETHER_H_DECLARES_ETHER_HOSTTON
@ -259,18 +265,15 @@
/* target host supports Bluetooth Monitor */
#undef PCAP_SUPPORT_BT_MONITOR
/* target host supports CAN sniffing */
#undef PCAP_SUPPORT_CAN
/* target host supports canusb */
#undef PCAP_SUPPORT_CANUSB
/* support D-Bus sniffing */
#undef PCAP_SUPPORT_DBUS
/* target host supports netfilter sniffing */
#undef PCAP_SUPPORT_NETFILTER
/* use Linux packet ring capture if available */
#undef PCAP_SUPPORT_PACKET_RING
/* target host supports USB sniffing */
#undef PCAP_SUPPORT_USB
@ -286,6 +289,10 @@
/* Enable parser debugging */
#undef YYDEBUG
/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a
`char[]'. */
#undef YYTEXT_POINTER
/* Enable large inode numbers on Mac OS X 10.5. */
#ifndef _DARWIN_USE_64_BIT_INODE
# define _DARWIN_USE_64_BIT_INODE 1

View file

@ -1,24 +1,18 @@
#! /bin/sh
# Configuration validation subroutine script.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
# 2011, 2012 Free Software Foundation, Inc.
# Copyright 1992-2015 Free Software Foundation, Inc.
timestamp='2012-04-18'
timestamp='2015-02-22'
# This file is (in principle) common to ALL GNU software.
# The presence of a machine in this file suggests that SOME GNU software
# can handle that machine. It does not imply ALL GNU software can.
#
# This file is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <http://www.gnu.org/licenses/>.
@ -26,11 +20,12 @@ timestamp='2012-04-18'
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# the same distribution terms that you use for the rest of that
# program. This Exception is an additional permission under section 7
# of the GNU General Public License, version 3 ("GPLv3").
# Please send patches to <config-patches@gnu.org>. Submit a context
# diff and a properly formatted GNU ChangeLog entry.
# Please send patches to <config-patches@gnu.org>.
#
# Configuration subroutine to validate and canonicalize a configuration type.
# Supply the specified configuration type as an argument.
@ -73,9 +68,7 @@ Report bugs and patches to <config-patches@gnu.org>."
version="\
GNU config.sub ($timestamp)
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
Free Software Foundation, Inc.
Copyright 1992-2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@ -123,8 +116,8 @@ esac
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in
nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
knetbsd*-gnu* | netbsd*-gnu* | \
linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \
kopensolaris*-gnu* | \
storm-chaos* | os2-emx* | rtmk-nova*)
os=-$maybe_os
@ -156,7 +149,7 @@ case $os in
-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
-apple | -axis | -knuth | -cray | -microblaze)
-apple | -axis | -knuth | -cray | -microblaze*)
os=
basic_machine=$1
;;
@ -259,21 +252,24 @@ case $basic_machine in
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
| am33_2.0 \
| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
| be32 | be64 \
| arc | arceb \
| arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
| avr | avr32 \
| be32 | be64 \
| bfin \
| c4x | clipper \
| c4x | c8051 | clipper \
| d10v | d30v | dlx | dsp16xx \
| epiphany \
| fido | fr30 | frv \
| fido | fr30 | frv | ft32 \
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
| hexagon \
| i370 | i860 | i960 | ia64 \
| ip2k | iq2000 \
| k1om \
| le32 | le64 \
| lm32 \
| m32c | m32r | m32rle | m68000 | m68k | m88k \
| maxq | mb | microblaze | mcore | mep | metag \
| maxq | mb | microblaze | microblazeel | mcore | mep | metag \
| mips | mipsbe | mipseb | mipsel | mipsle \
| mips16 \
| mips64 | mips64el \
@ -287,23 +283,26 @@ case $basic_machine in
| mips64vr5900 | mips64vr5900el \
| mipsisa32 | mipsisa32el \
| mipsisa32r2 | mipsisa32r2el \
| mipsisa32r6 | mipsisa32r6el \
| mipsisa64 | mipsisa64el \
| mipsisa64r2 | mipsisa64r2el \
| mipsisa64r6 | mipsisa64r6el \
| mipsisa64sb1 | mipsisa64sb1el \
| mipsisa64sr71k | mipsisa64sr71kel \
| mipsr5900 | mipsr5900el \
| mipstx39 | mipstx39el \
| mn10200 | mn10300 \
| moxie \
| mt \
| msp430 \
| nds32 | nds32le | nds32be \
| nios | nios2 \
| nios | nios2 | nios2eb | nios2el \
| ns16k | ns32k \
| open8 \
| or32 \
| open8 | or1k | or1knd | or32 \
| pdp10 | pdp11 | pj | pjl \
| powerpc | powerpc64 | powerpc64le | powerpcle \
| pyramid \
| riscv32 | riscv64 \
| rl78 | rx \
| score \
| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
@ -314,6 +313,7 @@ case $basic_machine in
| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
| ubicom32 \
| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
| visium \
| we32k \
| x86 | xc16x | xstormy16 | xtensa \
| z8k | z80)
@ -328,7 +328,10 @@ case $basic_machine in
c6x)
basic_machine=tic6x-unknown
;;
m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip)
leon|leon[3-9])
basic_machine=sparc-$basic_machine
;;
m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
basic_machine=$basic_machine-unknown
os=-none
;;
@ -370,13 +373,13 @@ case $basic_machine in
| aarch64-* | aarch64_be-* \
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \
| avr-* | avr32-* \
| be32-* | be64-* \
| bfin-* | bs2000-* \
| c[123]* | c30-* | [cjt]90-* | c4x-* \
| clipper-* | craynv-* | cydra-* \
| c8051-* | clipper-* | craynv-* | cydra-* \
| d10v-* | d30v-* | dlx-* \
| elxsi-* \
| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
@ -385,11 +388,13 @@ case $basic_machine in
| hexagon-* \
| i*86-* | i860-* | i960-* | ia64-* \
| ip2k-* | iq2000-* \
| k1om-* \
| le32-* | le64-* \
| lm32-* \
| m32c-* | m32r-* | m32rle-* \
| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
| m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \
| m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
| microblaze-* | microblazeel-* \
| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
| mips16-* \
| mips64-* | mips64el-* \
@ -403,18 +408,22 @@ case $basic_machine in
| mips64vr5900-* | mips64vr5900el-* \
| mipsisa32-* | mipsisa32el-* \
| mipsisa32r2-* | mipsisa32r2el-* \
| mipsisa32r6-* | mipsisa32r6el-* \
| mipsisa64-* | mipsisa64el-* \
| mipsisa64r2-* | mipsisa64r2el-* \
| mipsisa64r6-* | mipsisa64r6el-* \
| mipsisa64sb1-* | mipsisa64sb1el-* \
| mipsisa64sr71k-* | mipsisa64sr71kel-* \
| mipsr5900-* | mipsr5900el-* \
| mipstx39-* | mipstx39el-* \
| mmix-* \
| mt-* \
| msp430-* \
| nds32-* | nds32le-* | nds32be-* \
| nios-* | nios2-* \
| nios-* | nios2-* | nios2eb-* | nios2el-* \
| none-* | np1-* | ns16k-* | ns32k-* \
| open8-* \
| or1k*-* \
| orion-* \
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
@ -432,6 +441,7 @@ case $basic_machine in
| ubicom32-* \
| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
| vax-* \
| visium-* \
| we32k-* \
| x86-* | x86_64-* | xc16x-* | xps100-* \
| xstormy16-* | xtensa*-* \
@ -769,6 +779,9 @@ case $basic_machine in
basic_machine=m68k-isi
os=-sysv
;;
leon-*|leon[3-9]-*)
basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'`
;;
m68knommu)
basic_machine=m68k-unknown
os=-linux
@ -788,11 +801,15 @@ case $basic_machine in
basic_machine=ns32k-utek
os=-sysv
;;
microblaze)
microblaze*)
basic_machine=microblaze-xilinx
;;
mingw64)
basic_machine=x86_64-pc
os=-mingw64
;;
mingw32)
basic_machine=i386-pc
basic_machine=i686-pc
os=-mingw32
;;
mingw32ce)
@ -820,6 +837,10 @@ case $basic_machine in
basic_machine=powerpc-unknown
os=-morphos
;;
moxiebox)
basic_machine=moxie-unknown
os=-moxiebox
;;
msdos)
basic_machine=i386-pc
os=-msdos
@ -828,7 +849,7 @@ case $basic_machine in
basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
;;
msys)
basic_machine=i386-pc
basic_machine=i686-pc
os=-msys
;;
mvs)
@ -1019,7 +1040,11 @@ case $basic_machine in
basic_machine=i586-unknown
os=-pw32
;;
rdos)
rdos | rdos64)
basic_machine=x86_64-pc
os=-rdos
;;
rdos32)
basic_machine=i386-pc
os=-rdos
;;
@ -1346,29 +1371,29 @@ case $os in
-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
| -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
| -sym* | -kopensolaris* \
| -sym* | -kopensolaris* | -plan9* \
| -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
| -aos* | -aros* \
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
| -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
| -openbsd* | -solidbsd* \
| -bitrig* | -openbsd* | -solidbsd* \
| -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
| -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
| -chorusos* | -chorusrdb* | -cegcc* \
| -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
| -mingw32* | -linux-gnu* | -linux-android* \
| -linux-newlib* | -linux-uclibc* \
| -uxpv* | -beos* | -mpeix* | -udk* \
| -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
| -linux-newlib* | -linux-musl* | -linux-uclibc* \
| -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
| -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
| -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
-qnx*)
@ -1492,9 +1517,6 @@ case $os in
-aros*)
os=-aros
;;
-kaos*)
os=-kaos
;;
-zvmoe)
os=-zvmoe
;;
@ -1543,6 +1565,12 @@ case $basic_machine in
c4x-* | tic4x-*)
os=-coff
;;
c8051-*)
os=-elf
;;
hexagon-*)
os=-elf
;;
tic54x-*)
os=-coff
;;

View file

@ -0,0 +1,6 @@
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/sockio.h>
int main() {
ioctl(0, SIOCGLIFCONF, (char *)0);
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -186,8 +186,8 @@ pcap_process_pkts(pcap_t *p, pcap_handler callback, u_char *user,
pkthdr.len = origlen;
pkthdr.caplen = caplen;
/* Insure caplen does not exceed snapshot */
if (pkthdr.caplen > p->snapshot)
pkthdr.caplen = p->snapshot;
if (pkthdr.caplen > (bpf_u_int32)p->snapshot)
pkthdr.caplen = (bpf_u_int32)p->snapshot;
(*callback)(user, &pkthdr, pk);
if (++n >= count && !PACKET_COUNT_IS_UNLIMITED(count)) {
p->cc = ep - bufp;
@ -255,8 +255,29 @@ pcap_process_mactype(pcap_t *p, u_int mactype)
break;
#endif
#ifdef DL_IPV4
case DL_IPV4:
p->linktype = DLT_IPV4;
p->offset = 0;
break;
#endif
#ifdef DL_IPV6
case DL_IPV6:
p->linktype = DLT_IPV6;
p->offset = 0;
break;
#endif
#ifdef DL_IPNET
case DL_IPNET:
p->linktype = DLT_IPNET;
p->offset = 0;
break;
#endif
default:
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "unknown mactype %u",
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "unknown mactype 0x%x",
mactype);
retv = -1;
}
@ -326,7 +347,7 @@ int
pcap_alloc_databuf(pcap_t *p)
{
p->bufsize = PKTBUFSIZE;
p->buffer = (u_char *)malloc(p->bufsize + p->offset);
p->buffer = malloc(p->bufsize + p->offset);
if (p->buffer == NULL) {
strlcpy(p->errbuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
return (-1);
@ -362,6 +383,6 @@ strioctl(int fd, int cmd, int len, char *dp)
static void
pcap_stream_err(const char *func, int err, char *errbuf)
{
snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", func, pcap_strerror(err));
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", func, pcap_strerror(err));
}
#endif

View file

@ -23,9 +23,9 @@
#include "config.h"
#endif
#ifdef WIN32
#ifdef _WIN32
#include <pcap-stdinc.h>
#else /* WIN32 */
#else /* _WIN32 */
#if HAVE_INTTYPES_H
#include <inttypes.h>
#elif HAVE_STDINT_H
@ -35,7 +35,7 @@
#include <sys/bitypes.h>
#endif
#include <sys/types.h>
#endif /* WIN32 */
#endif /* _WIN32 */
#include <ctype.h>
#include <memory.h>

View file

@ -112,6 +112,9 @@
#ifndef ETHERTYPE_PPPOES
#define ETHERTYPE_PPPOES 0x8864
#endif
#ifndef ETHERTYPE_8021AD
#define ETHERTYPE_8021AD 0x88a8
#endif
#ifndef ETHERTYPE_LOOPBACK
#define ETHERTYPE_LOOPBACK 0x9000
#endif

221
contrib/libpcap/extract.h Normal file
View file

@ -0,0 +1,221 @@
/*
* Copyright (c) 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.
*/
#ifndef _WIN32
#include <arpa/inet.h>
#endif
/*
* Macros to extract possibly-unaligned big-endian integral values.
*/
#ifdef LBL_ALIGN
/*
* The processor doesn't natively handle unaligned loads.
*/
#if defined(__GNUC__) && defined(HAVE___ATTRIBUTE__) && \
(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.
*
* Declare packed structures containing a uint16_t and a uint32_t,
* cast the pointer to point to one of those, and fetch through it;
* the GCC manual doesn't appear to explicitly say that
* __attribute__((packed)) causes the compiler to generate unaligned-safe
* code, but it apppears to do so.
*
* We do this in case the compiler can generate code using those
* instructions to do an unaligned load and pass stuff to "ntohs()" or
* "ntohl()", which might be better than than the code to fetch the
* bytes one at a time and assemble them. (That might not be the
* case on a little-endian platform, such as DEC's MIPS machines and
* Alpha machines, where "ntohs()" and "ntohl()" might not be done
* inline.)
*
* We do this only for specific architectures because, for example,
* at least some versions of GCC, when compiling for 64-bit SPARC,
* generate code that assumes alignment if we do this.
*
* XXX - add other architectures and compilers as possible and
* appropriate.
*
* HP's C compiler, indicated by __HP_cc being defined, supports
* "#pragma unaligned N" in version A.05.50 and later, where "N"
* specifies a number of bytes at which the typedef on the next
* line is aligned, e.g.
*
* #pragma unalign 1
* typedef uint16_t unaligned_uint16_t;
*
* to define unaligned_uint16_t as a 16-bit unaligned data type.
* This could be presumably used, in sufficiently recent versions of
* the compiler, with macros similar to those below. This would be
* useful only if that compiler could generate better code for PA-RISC
* or Itanium than would be generated by a bunch of shifts-and-ORs.
*
* DEC C, indicated by __DECC being defined, has, at least on Alpha,
* an __unaligned qualifier that can be applied to pointers to get the
* compiler to generate code that does unaligned loads and stores when
* dereferencing the pointer in question.
*
* XXX - what if the native C compiler doesn't support
* __attribute__((packed))? How can we get it to generate unaligned
* accesses for *specific* items?
*/
typedef struct {
uint16_t val;
} __attribute__((packed)) unaligned_uint16_t;
typedef struct {
uint32_t val;
} __attribute__((packed)) unaligned_uint32_t;
static inline uint16_t
EXTRACT_16BITS(const void *p)
{
return ((uint16_t)ntohs(((const unaligned_uint16_t *)(p))->val));
}
static inline uint32_t
EXTRACT_32BITS(const void *p)
{
return ((uint32_t)ntohl(((const unaligned_uint32_t *)(p))->val));
}
static inline uint64_t
EXTRACT_64BITS(const void *p)
{
return ((uint64_t)(((uint64_t)ntohl(((const unaligned_uint32_t *)(p) + 0)->val)) << 32 | \
((uint64_t)ntohl(((const unaligned_uint32_t *)(p) + 1)->val)) << 0));
}
#else /* have to do it a byte at a time */
/*
* This isn't a GCC-compatible compiler, we don't have __attribute__,
* or we do but we don't know of any better way with this instruction
* set to do unaligned loads, so do unaligned loads of big-endian
* quantities the hard way - fetch the bytes one at a time and
* assemble them.
*/
#define EXTRACT_16BITS(p) \
((uint16_t)(((uint16_t)(*((const uint8_t *)(p) + 0)) << 8) | \
((uint16_t)(*((const uint8_t *)(p) + 1)) << 0)))
#define EXTRACT_32BITS(p) \
((uint32_t)(((uint32_t)(*((const uint8_t *)(p) + 0)) << 24) | \
((uint32_t)(*((const uint8_t *)(p) + 1)) << 16) | \
((uint32_t)(*((const uint8_t *)(p) + 2)) << 8) | \
((uint32_t)(*((const uint8_t *)(p) + 3)) << 0)))
#define EXTRACT_64BITS(p) \
((uint64_t)(((uint64_t)(*((const uint8_t *)(p) + 0)) << 56) | \
((uint64_t)(*((const uint8_t *)(p) + 1)) << 48) | \
((uint64_t)(*((const uint8_t *)(p) + 2)) << 40) | \
((uint64_t)(*((const uint8_t *)(p) + 3)) << 32) | \
((uint64_t)(*((const uint8_t *)(p) + 4)) << 24) | \
((uint64_t)(*((const uint8_t *)(p) + 5)) << 16) | \
((uint64_t)(*((const uint8_t *)(p) + 6)) << 8) | \
((uint64_t)(*((const uint8_t *)(p) + 7)) << 0)))
#endif /* must special-case unaligned accesses */
#else /* LBL_ALIGN */
/*
* The processor natively handles unaligned loads, so we can just
* cast the pointer and fetch through it.
*/
static inline uint16_t
EXTRACT_16BITS(const void *p)
{
return ((uint16_t)ntohs(*(const uint16_t *)(p)));
}
static inline uint32_t
EXTRACT_32BITS(const void *p)
{
return ((uint32_t)ntohl(*(const uint32_t *)(p)));
}
static inline uint64_t
EXTRACT_64BITS(const void *p)
{
return ((uint64_t)(((uint64_t)ntohl(*((const uint32_t *)(p) + 0))) << 32 | \
((uint64_t)ntohl(*((const uint32_t *)(p) + 1))) << 0));
}
#endif /* LBL_ALIGN */
#define EXTRACT_24BITS(p) \
((uint32_t)(((uint32_t)(*((const uint8_t *)(p) + 0)) << 16) | \
((uint32_t)(*((const uint8_t *)(p) + 1)) << 8) | \
((uint32_t)(*((const uint8_t *)(p) + 2)) << 0)))
#define EXTRACT_40BITS(p) \
((uint64_t)(((uint64_t)(*((const uint8_t *)(p) + 0)) << 32) | \
((uint64_t)(*((const uint8_t *)(p) + 1)) << 24) | \
((uint64_t)(*((const uint8_t *)(p) + 2)) << 16) | \
((uint64_t)(*((const uint8_t *)(p) + 3)) << 8) | \
((uint64_t)(*((const uint8_t *)(p) + 4)) << 0)))
#define EXTRACT_48BITS(p) \
((uint64_t)(((uint64_t)(*((const uint8_t *)(p) + 0)) << 40) | \
((uint64_t)(*((const uint8_t *)(p) + 1)) << 32) | \
((uint64_t)(*((const uint8_t *)(p) + 2)) << 24) | \
((uint64_t)(*((const uint8_t *)(p) + 3)) << 16) | \
((uint64_t)(*((const uint8_t *)(p) + 4)) << 8) | \
((uint64_t)(*((const uint8_t *)(p) + 5)) << 0)))
#define EXTRACT_56BITS(p) \
((uint64_t)(((uint64_t)(*((const uint8_t *)(p) + 0)) << 48) | \
((uint64_t)(*((const uint8_t *)(p) + 1)) << 40) | \
((uint64_t)(*((const uint8_t *)(p) + 2)) << 32) | \
((uint64_t)(*((const uint8_t *)(p) + 3)) << 24) | \
((uint64_t)(*((const uint8_t *)(p) + 4)) << 16) | \
((uint64_t)(*((const uint8_t *)(p) + 5)) << 8) | \
((uint64_t)(*((const uint8_t *)(p) + 6)) << 0)))
/*
* Macros to extract possibly-unaligned little-endian integral values.
* XXX - do loads on little-endian machines that support unaligned loads?
*/
#define EXTRACT_LE_8BITS(p) (*(p))
#define EXTRACT_LE_16BITS(p) \
((uint16_t)(((uint16_t)(*((const uint8_t *)(p) + 1)) << 8) | \
((uint16_t)(*((const uint8_t *)(p) + 0)) << 0)))
#define EXTRACT_LE_32BITS(p) \
((uint32_t)(((uint32_t)(*((const uint8_t *)(p) + 3)) << 24) | \
((uint32_t)(*((const uint8_t *)(p) + 2)) << 16) | \
((uint32_t)(*((const uint8_t *)(p) + 1)) << 8) | \
((uint32_t)(*((const uint8_t *)(p) + 0)) << 0)))
#define EXTRACT_LE_24BITS(p) \
((uint32_t)(((uint32_t)(*((const uint8_t *)(p) + 2)) << 16) | \
((uint32_t)(*((const uint8_t *)(p) + 1)) << 8) | \
((uint32_t)(*((const uint8_t *)(p) + 0)) << 0)))
#define EXTRACT_LE_64BITS(p) \
((uint64_t)(((uint64_t)(*((const uint8_t *)(p) + 7)) << 56) | \
((uint64_t)(*((const uint8_t *)(p) + 6)) << 48) | \
((uint64_t)(*((const uint8_t *)(p) + 5)) << 40) | \
((uint64_t)(*((const uint8_t *)(p) + 4)) << 32) | \
((uint64_t)(*((const uint8_t *)(p) + 3)) << 24) | \
((uint64_t)(*((const uint8_t *)(p) + 2)) << 16) | \
((uint64_t)(*((const uint8_t *)(p) + 1)) << 8) | \
((uint64_t)(*((const uint8_t *)(p) + 0)) << 0)))

View file

@ -144,7 +144,8 @@ get_sa_len(struct sockaddr *addr)
* could be opened.
*/
int
pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf,
int (*check_usable)(const char *))
{
pcap_if_t *devlist = NULL;
struct ifaddrs *ifap, *ifa;
@ -168,11 +169,50 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
* those.
*/
if (getifaddrs(&ifap) != 0) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"getifaddrs: %s", pcap_strerror(errno));
return (-1);
}
for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
/*
* If this entry has a colon followed by a number at
* the end, we assume it's a logical interface. Those
* are just the way you assign multiple IP addresses to
* a real interface on Linux, so an entry for a logical
* interface should be treated like the entry for the
* real interface; we do that by stripping off the ":"
* and the number.
*
* XXX - should we do this only on Linux?
*/
p = strchr(ifa->ifa_name, ':');
if (p != NULL) {
/*
* We have a ":"; is it followed by a number?
*/
q = p + 1;
while (isdigit((unsigned char)*q))
q++;
if (*q == '\0') {
/*
* All digits after the ":" until the end.
* Strip off the ":" and everything after
* it.
*/
*p = '\0';
}
}
/*
* Can we capture on this device?
*/
if (!(*check_usable)(ifa->ifa_name)) {
/*
* No.
*/
continue;
}
/*
* "ifa_addr" was apparently null on at least one
* interface on some system. Therefore, we supply
@ -222,40 +262,12 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
dstaddr_size = 0;
}
/*
* If this entry has a colon followed by a number at
* the end, we assume it's a logical interface. Those
* are just the way you assign multiple IP addresses to
* a real interface on Linux, so an entry for a logical
* interface should be treated like the entry for the
* real interface; we do that by stripping off the ":"
* and the number.
*
* XXX - should we do this only on Linux?
*/
p = strchr(ifa->ifa_name, ':');
if (p != NULL) {
/*
* We have a ":"; is it followed by a number?
*/
q = p + 1;
while (isdigit((unsigned char)*q))
q++;
if (*q == '\0') {
/*
* All digits after the ":" until the end.
* Strip off the ":" and everything after
* it.
*/
*p = '\0';
}
}
/*
* Add information for this address to the list.
*/
if (add_addr_to_iflist(&devlist, ifa->ifa_name,
ifa->ifa_flags, addr, addr_size, netmask, addr_size,
if_flags_to_pcap_flags(ifa->ifa_name, ifa->ifa_flags),
addr, addr_size, netmask, addr_size,
broadaddr, broadaddr_size, dstaddr, dstaddr_size,
errbuf) < 0) {
ret = -1;

View file

@ -132,12 +132,13 @@ struct rtentry; /* declarations in <net/if.h> */
* we already have that.
*/
int
pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf,
int (*check_usable)(const char *))
{
pcap_if_t *devlist = NULL;
register int fd;
register struct ifreq *ifrp, *ifend, *ifnext;
int n;
size_t n;
struct ifconf ifc;
char *buf = NULL;
unsigned buf_size;
@ -154,7 +155,7 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
*/
fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd < 0) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"socket: %s", pcap_strerror(errno));
return (-1);
}
@ -170,7 +171,7 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
for (;;) {
buf = malloc(buf_size);
if (buf == NULL) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"malloc: %s", pcap_strerror(errno));
(void)close(fd);
return (-1);
@ -181,7 +182,7 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
memset(buf, 0, buf_size);
if (ioctl(fd, SIOCGIFCONF, (char *)&ifc) < 0
&& errno != EINVAL) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"SIOCGIFCONF: %s", pcap_strerror(errno));
(void)close(fd);
free(buf);
@ -217,12 +218,12 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
/*
* XXX - The 32-bit compatibility layer for Linux on IA-64
* is slightly broken. It correctly converts the structures
* to and from kernel land from 64 bit to 32 bit but
* doesn't update ifc.ifc_len, leaving it larger than the
* amount really used. This means we read off the end
* of the buffer and encounter an interface with an
* "empty" name. Since this is highly unlikely to ever
* occur in a valid case we can just finish looking for
* to and from kernel land from 64 bit to 32 bit but
* doesn't update ifc.ifc_len, leaving it larger than the
* amount really used. This means we read off the end
* of the buffer and encounter an interface with an
* "empty" name. Since this is highly unlikely to ever
* occur in a valid case we can just finish looking for
* interfaces if we see an empty name.
*/
if (!(*ifrp->ifr_name))
@ -236,6 +237,16 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
if (strncmp(ifrp->ifr_name, "dummy", 5) == 0)
continue;
/*
* Can we capture on this device?
*/
if (!(*check_usable)(ifrp->ifr_name)) {
/*
* No.
*/
continue;
}
/*
* Get the flags for this interface.
*/
@ -244,7 +255,7 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifrflags) < 0) {
if (errno == ENXIO)
continue;
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"SIOCGIFFLAGS: %.*s: %s",
(int)sizeof(ifrflags.ifr_name),
ifrflags.ifr_name,
@ -268,7 +279,7 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
netmask = NULL;
netmask_size = 0;
} else {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"SIOCGIFNETMASK: %.*s: %s",
(int)sizeof(ifrnetmask.ifr_name),
ifrnetmask.ifr_name,
@ -299,7 +310,7 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
broadaddr = NULL;
broadaddr_size = 0;
} else {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"SIOCGIFBRDADDR: %.*s: %s",
(int)sizeof(ifrbroadaddr.ifr_name),
ifrbroadaddr.ifr_name,
@ -338,7 +349,7 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
dstaddr = NULL;
dstaddr_size = 0;
} else {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"SIOCGIFDSTADDR: %.*s: %s",
(int)sizeof(ifrdstaddr.ifr_name),
ifrdstaddr.ifr_name,
@ -391,10 +402,10 @@ 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,
ifrflags.ifr_flags, &ifrp->ifr_addr,
SA_LEN(&ifrp->ifr_addr), netmask, netmask_size,
broadaddr, broadaddr_size, dstaddr, dstaddr_size,
errbuf) < 0) {
if_flags_to_pcap_flags(ifrp->ifr_name, ifrflags.ifr_flags),
&ifrp->ifr_addr, SA_LEN(&ifrp->ifr_addr),
netmask, netmask_size, broadaddr, broadaddr_size,
dstaddr, dstaddr_size, errbuf) < 0) {
ret = -1;
break;
}

View file

@ -75,7 +75,8 @@ 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)
pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf,
int (*check_usable)(const char *))
{
pcap_if_t *devlist = NULL;
register int fd4, fd6, fd;
@ -97,7 +98,7 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
*/
fd4 = socket(AF_INET, SOCK_DGRAM, 0);
if (fd4 < 0) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"socket: %s", pcap_strerror(errno));
return (-1);
}
@ -107,7 +108,7 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
*/
fd6 = socket(AF_INET6, SOCK_DGRAM, 0);
if (fd6 < 0) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"socket: %s", pcap_strerror(errno));
(void)close(fd4);
return (-1);
@ -120,7 +121,7 @@ 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)snprintf(errbuf, PCAP_ERRBUF_SIZE,
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"SIOCGLIFNUM: %s", pcap_strerror(errno));
(void)close(fd6);
(void)close(fd4);
@ -133,7 +134,7 @@ 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)snprintf(errbuf, PCAP_ERRBUF_SIZE,
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"malloc: %s", pcap_strerror(errno));
(void)close(fd6);
(void)close(fd4);
@ -149,7 +150,7 @@ 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)snprintf(errbuf, PCAP_ERRBUF_SIZE,
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"SIOCGLIFCONF: %s", pcap_strerror(errno));
(void)close(fd6);
(void)close(fd4);
@ -164,14 +165,6 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
ifend = (struct lifreq *)(buf + ifc.lifc_len);
for (; ifrp < ifend; ifrp++) {
/*
* IPv6 or not?
*/
if (((struct sockaddr *)&ifrp->lifr_addr)->sa_family == AF_INET6)
fd = fd6;
else
fd = fd4;
/*
* Skip entries that begin with "dummy".
* XXX - what are these? Is this Linux-specific?
@ -180,27 +173,23 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
if (strncmp(ifrp->lifr_name, "dummy", 5) == 0)
continue;
#ifdef HAVE_SOLARIS
/*
* Skip entries that have a ":" followed by a number
* at the end - those are Solaris virtual interfaces
* on which you can't capture.
* Can we capture on this device?
*/
p = strchr(ifrp->lifr_name, ':');
if (p != NULL) {
if (!(*check_usable)(ifrp->lifr_name)) {
/*
* We have a ":"; is it followed by a number?
* No.
*/
while (isdigit((unsigned char)*p))
p++;
if (*p == '\0') {
/*
* All digits after the ":" until the end.
*/
continue;
}
continue;
}
#endif
/*
* IPv6 or not?
*/
if (((struct sockaddr *)&ifrp->lifr_addr)->sa_family == AF_INET6)
fd = fd6;
else
fd = fd4;
/*
* Get the flags for this interface.
@ -210,7 +199,7 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
if (ioctl(fd, SIOCGLIFFLAGS, (char *)&ifrflags) < 0) {
if (errno == ENXIO)
continue;
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"SIOCGLIFFLAGS: %.*s: %s",
(int)sizeof(ifrflags.lifr_name),
ifrflags.lifr_name,
@ -233,7 +222,7 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
*/
netmask = NULL;
} else {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"SIOCGLIFNETMASK: %.*s: %s",
(int)sizeof(ifrnetmask.lifr_name),
ifrnetmask.lifr_name,
@ -261,7 +250,7 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
*/
broadaddr = NULL;
} else {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"SIOCGLIFBRDADDR: %.*s: %s",
(int)sizeof(ifrbroadaddr.lifr_name),
ifrbroadaddr.lifr_name,
@ -296,7 +285,7 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
*/
dstaddr = NULL;
} else {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"SIOCGLIFDSTADDR: %.*s: %s",
(int)sizeof(ifrdstaddr.lifr_name),
ifrdstaddr.lifr_name,
@ -341,7 +330,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,
ifrflags.lifr_flags, (struct sockaddr *)&ifrp->lifr_addr,
if_flags_to_pcap_flags(ifrp->lifr_name, ifrflags.lifr_flags),
(struct sockaddr *)&ifrp->lifr_addr,
sizeof (struct sockaddr_storage),
netmask, sizeof (struct sockaddr_storage),
broadaddr, sizeof (struct sockaddr_storage),

View file

@ -0,0 +1,884 @@
/* -*- 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);
}
}

View file

@ -1,59 +0,0 @@
/*
* fad-sita.c: Packet capture interface additions for SITA ACN devices
*
* Copyright (c) 2007 Fulko Hew, SITA INC Canada, Inc <fulko.hew@sita.aero>
*
* License: BSD
*
* 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 names of the authors may not 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.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <string.h>
#include "pcap-int.h"
#include "pcap-sita.h"
extern pcap_if_t *acn_if_list; /* pcap's list of available interfaces */
int pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf) {
//printf("pcap_findalldevs()\n"); // fulko
*alldevsp = 0; /* initialize the returned variables before we do anything */
strcpy(errbuf, "");
if (acn_parse_hosts_file(errbuf)) /* scan the hosts file for potential IOPs */
{
//printf("pcap_findalldevs() returning BAD after parsehosts\n"); // fulko
return -1;
}
//printf("pcap_findalldevs() got hostlist now finding devs\n"); // fulko
if (acn_findalldevs(errbuf)) /* then ask the IOPs for their monitorable devices */
{
//printf("pcap_findalldevs() returning BAD after findalldevs\n"); // fulko
return -1;
}
*alldevsp = acn_if_list;
acn_if_list = 0; /* then forget our list head, because someone will call pcap_freealldevs() to empty the malloc'ed stuff */
//printf("pcap_findalldevs() returning ZERO OK\n"); // fulko
return 0;
}

View file

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

View file

@ -0,0 +1,19 @@
#! /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"

File diff suppressed because it is too large Load diff

View file

@ -161,7 +161,7 @@
#define A_CONNECTACK 44 /* Connect Ack message */
#define A_RELEASE 45 /* Release message */
#define A_RELEASE_DONE 46 /* Release message */
/* ATM field types */
#define A_VPI 51
#define A_VCI 52
@ -281,83 +281,115 @@ struct qual {
unsigned char pad;
};
struct arth *gen_loadi(int);
struct arth *gen_load(int, struct arth *, int);
struct arth *gen_loadlen(void);
struct arth *gen_neg(struct arth *);
struct arth *gen_arth(int, struct arth *, struct arth *);
struct _compiler_state;
typedef struct _compiler_state compiler_state_t;
struct arth *gen_loadi(compiler_state_t *, int);
struct arth *gen_load(compiler_state_t *, int, struct arth *, int);
struct arth *gen_loadlen(compiler_state_t *);
struct arth *gen_neg(compiler_state_t *, struct arth *);
struct arth *gen_arth(compiler_state_t *, int, struct arth *, struct arth *);
void gen_and(struct block *, struct block *);
void gen_or(struct block *, struct block *);
void gen_not(struct block *);
struct block *gen_scode(const char *, struct qual);
struct block *gen_ecode(const u_char *, struct qual);
struct block *gen_acode(const u_char *, struct qual);
struct block *gen_mcode(const char *, const char *, int, struct qual);
struct block *gen_scode(compiler_state_t *, const char *, struct qual);
struct block *gen_ecode(compiler_state_t *, const u_char *, struct qual);
struct block *gen_acode(compiler_state_t *, const u_char *, struct qual);
struct block *gen_mcode(compiler_state_t *, const char *, const char *,
unsigned int, struct qual);
#ifdef INET6
struct block *gen_mcode6(const char *, const char *, int, struct qual);
struct block *gen_mcode6(compiler_state_t *, const char *, const char *,
unsigned int, struct qual);
#endif
struct block *gen_ncode(const char *, bpf_u_int32, struct qual);
struct block *gen_proto_abbrev(int);
struct block *gen_relation(int, struct arth *, struct arth *, int);
struct block *gen_less(int);
struct block *gen_greater(int);
struct block *gen_byteop(int, int, int);
struct block *gen_broadcast(int);
struct block *gen_multicast(int);
struct block *gen_inbound(int);
struct block *gen_ncode(compiler_state_t *, const char *, bpf_u_int32,
struct qual);
struct block *gen_proto_abbrev(compiler_state_t *, int);
struct block *gen_relation(compiler_state_t *, int, struct arth *,
struct arth *, int);
struct block *gen_less(compiler_state_t *, int);
struct block *gen_greater(compiler_state_t *, int);
struct block *gen_byteop(compiler_state_t *, int, int, int);
struct block *gen_broadcast(compiler_state_t *, int);
struct block *gen_multicast(compiler_state_t *, int);
struct block *gen_inbound(compiler_state_t *, int);
struct block *gen_llc(void);
struct block *gen_llc_i(void);
struct block *gen_llc_s(void);
struct block *gen_llc_u(void);
struct block *gen_llc_s_subtype(bpf_u_int32);
struct block *gen_llc_u_subtype(bpf_u_int32);
struct block *gen_llc(compiler_state_t *);
struct block *gen_llc_i(compiler_state_t *);
struct block *gen_llc_s(compiler_state_t *);
struct block *gen_llc_u(compiler_state_t *);
struct block *gen_llc_s_subtype(compiler_state_t *, bpf_u_int32);
struct block *gen_llc_u_subtype(compiler_state_t *, bpf_u_int32);
struct block *gen_vlan(int);
struct block *gen_mpls(int);
struct block *gen_vlan(compiler_state_t *, int);
struct block *gen_mpls(compiler_state_t *, int);
struct block *gen_pppoed(void);
struct block *gen_pppoes(int);
struct block *gen_pppoed(compiler_state_t *);
struct block *gen_pppoes(compiler_state_t *, int);
struct block *gen_atmfield_code(int atmfield, bpf_int32 jvalue, bpf_u_int32 jtype, int reverse);
struct block *gen_atmtype_abbrev(int type);
struct block *gen_atmmulti_abbrev(int type);
struct block *gen_geneve(compiler_state_t *, int);
struct block *gen_mtp2type_abbrev(int type);
struct block *gen_mtp3field_code(int mtp3field, bpf_u_int32 jvalue, bpf_u_int32 jtype, int reverse);
struct block *gen_atmfield_code(compiler_state_t *, int, bpf_int32,
bpf_u_int32, int);
struct block *gen_atmtype_abbrev(compiler_state_t *, int type);
struct block *gen_atmmulti_abbrev(compiler_state_t *, int type);
struct block *gen_pf_ifname(const char *);
struct block *gen_pf_rnr(int);
struct block *gen_pf_srnr(int);
struct block *gen_pf_ruleset(char *);
struct block *gen_pf_reason(int);
struct block *gen_pf_action(int);
struct block *gen_pf_dir(int);
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);
struct block *gen_p80211_type(int, int);
struct block *gen_p80211_fcdir(int);
struct block *gen_pf_ifname(compiler_state_t *, const char *);
struct block *gen_pf_rnr(compiler_state_t *, int);
struct block *gen_pf_srnr(compiler_state_t *, int);
struct block *gen_pf_ruleset(compiler_state_t *, char *);
struct block *gen_pf_reason(compiler_state_t *, int);
struct block *gen_pf_action(compiler_state_t *, int);
void bpf_optimize(struct block **);
void bpf_error(const char *, ...)
struct block *gen_p80211_type(compiler_state_t *, int, int);
struct block *gen_p80211_fcdir(compiler_state_t *, int);
/*
* Representation of a program as a tree of blocks, plus current mark.
* A block is marked if only if its mark equals the current mark.
* Rather than traverse the code array, marking each item, 'cur_mark'
* is incremented. This automatically makes each element unmarked.
*/
#define isMarked(icp, p) ((p)->mark == (icp)->cur_mark)
#define unMarkAll(icp) (icp)->cur_mark += 1
#define Mark(icp, p) ((p)->mark = (icp)->cur_mark)
struct icode {
struct block *root;
int cur_mark;
};
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, 1, 2)))
__attribute__((format (printf, 2, 3)))
#endif /* __ATTRIBUTE___FORMAT_OK */
;
void finish_parse(struct block *);
char *sdup(const char *);
void finish_parse(compiler_state_t *, struct block *);
char *sdup(compiler_state_t *, const char *);
struct bpf_insn *icode_to_fcode(struct block *, u_int *);
int pcap_parse(void);
void lex_init(const char *);
void lex_cleanup(void);
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 *);
/*
* Older versions of Bison don't put this declaration in
* grammar.h.
*/
int pcap_parse(void *, compiler_state_t *);
/* XXX */
#define JT(b) ((b)->et.succ)
#define JF(b) ((b)->ef.succ)
extern int no_optimize;

View file

@ -1,3 +1,28 @@
/*
* We want a reentrant parser.
*/
%pure-parser
/*
* We also want a reentrant scanner, so we have to pass the
* handle for the reentrant scanner to the parser, and the
* parser has to pass it to the lexical analyzer.
*
* We use void * rather than yyscan_t because, at least with some
* versions of Flex and Bison, if you use yyscan_t in %parse-param and
* %lex-param, you have to include scanner.h before grammar.h to get
* yyscan_t declared, and you have to include grammar.h before scanner.h
* to get YYSTYPE declared. Using void * breaks the cycle; the Flex
* documentation says yyscan_t is just a void *.
*/
%parse-param {void *yyscanner}
%lex-param {void *yyscanner}
/*
* And we need to pass the compiler state to the scanner.
*/
%parse-param {compiler_state_t *cstate}
%{
/*
* Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
@ -26,16 +51,16 @@
#include "config.h"
#endif
#ifdef WIN32
#ifdef _WIN32
#include <pcap-stdinc.h>
#else /* WIN32 */
#else /* _WIN32 */
#include <sys/types.h>
#include <sys/socket.h>
#endif /* WIN32 */
#endif /* _WIN32 */
#include <stdlib.h>
#ifndef WIN32
#ifndef _WIN32
#if __STDC__
struct mbuf;
struct rtentry;
@ -43,13 +68,16 @@ struct rtentry;
#include <netinet/in.h>
#include <arpa/inet.h>
#endif /* WIN32 */
#endif /* _WIN32 */
#include <stdio.h>
#include "pcap-int.h"
#include "gencode.h"
#include "grammar.h"
#include "scanner.h"
#ifdef HAVE_NET_PFVAR_H
#include <net/if.h>
#include <netpfil/pf/pf.h>
@ -170,31 +198,18 @@ str2tok(const char *str, const struct tok *toks)
return (-1);
}
int n_errors = 0;
static struct qual qerr = { Q_UNDEF, Q_UNDEF, Q_UNDEF, Q_UNDEF };
static void
yyerror(const char *msg)
yyerror(void *yyscanner, compiler_state_t *cstate, const char *msg)
{
++n_errors;
bpf_error("%s", msg);
bpf_syntax_error(cstate, msg);
/* NOTREACHED */
}
#ifdef NEED_YYPARSE_WRAPPER
int yyparse(void);
int
pcap_parse()
{
return (yyparse());
}
#endif
#ifdef HAVE_NET_PFVAR_H
static int
pfreason_to_num(const char *reason)
pfreason_to_num(compiler_state_t *cstate, const char *reason)
{
const char *reasons[] = PFRES_NAMES;
int i;
@ -203,12 +218,12 @@ pfreason_to_num(const char *reason)
if (pcap_strcasecmp(reason, reasons[i]) == 0)
return (i);
}
bpf_error("unknown PF reason");
bpf_error(cstate, "unknown PF reason");
/*NOTREACHED*/
}
static int
pfaction_to_num(const char *action)
pfaction_to_num(compiler_state_t *cstate, const char *action)
{
if (pcap_strcasecmp(action, "pass") == 0 ||
pcap_strcasecmp(action, "accept") == 0)
@ -227,15 +242,15 @@ pfaction_to_num(const char *action)
return (PF_NORDR);
#endif
else {
bpf_error("unknown PF action");
bpf_error(cstate, "unknown PF action");
/*NOTREACHED*/
}
}
#else /* !HAVE_NET_PFVAR_H */
static int
pfreason_to_num(const char *reason)
pfreason_to_num(compiler_state_t *cstate, const char *reason)
{
bpf_error("libpcap was compiled on a machine without pf support");
bpf_error(cstate, "libpcap was compiled on a machine without pf support");
/*NOTREACHED*/
/* this is to make the VC compiler happy */
@ -243,9 +258,9 @@ pfreason_to_num(const char *reason)
}
static int
pfaction_to_num(const char *action)
pfaction_to_num(compiler_state_t *cstate, const char *action)
{
bpf_error("libpcap was compiled on a machine without pf support");
bpf_error(cstate, "libpcap was compiled on a machine without pf support");
/*NOTREACHED*/
/* this is to make the VC compiler happy */
@ -300,8 +315,8 @@ pfaction_to_num(const char *action)
%token LEN
%token IPV6 ICMPV6 AH ESP
%token VLAN MPLS
%token PPPOED PPPOES
%token ISO ESIS CLNP ISIS L1 L2 IIH LSP SNP CSNP PSNP
%token PPPOED PPPOES GENEVE
%token ISO ESIS CLNP ISIS L1 L2 IIH LSP SNP CSNP PSNP
%token STP
%token IPX
%token NETBEUI
@ -311,7 +326,7 @@ pfaction_to_num(const char *action)
%token RADIO
%token FISU LSSU MSU HFISU HLSSU HMSU
%token SIO OPC DPC SLS HSIO HOPC HDPC HSLS
%type <s> ID
%type <e> EID
@ -330,7 +345,7 @@ pfaction_to_num(const char *action)
%%
prog: null expr
{
finish_parse($2.b);
finish_parse(cstate, $2.b);
}
| null
;
@ -347,48 +362,48 @@ and: AND { $$ = $<blk>0; }
or: OR { $$ = $<blk>0; }
;
id: nid
| pnum { $$.b = gen_ncode(NULL, (bpf_u_int32)$1,
| pnum { $$.b = gen_ncode(cstate, NULL, (bpf_u_int32)$1,
$$.q = $<blk>0.q); }
| paren pid ')' { $$ = $2; }
;
nid: ID { $$.b = gen_scode($1, $$.q = $<blk>0.q); }
| HID '/' NUM { $$.b = gen_mcode($1, NULL, $3,
nid: ID { $$.b = gen_scode(cstate, $1, $$.q = $<blk>0.q); }
| HID '/' NUM { $$.b = gen_mcode(cstate, $1, NULL, $3,
$$.q = $<blk>0.q); }
| HID NETMASK HID { $$.b = gen_mcode($1, $3, 0,
| HID NETMASK HID { $$.b = gen_mcode(cstate, $1, $3, 0,
$$.q = $<blk>0.q); }
| HID {
/* Decide how to parse HID based on proto */
$$.q = $<blk>0.q;
if ($$.q.addr == Q_PORT)
bpf_error("'port' modifier applied to ip host");
bpf_error(cstate, "'port' modifier applied to ip host");
else if ($$.q.addr == Q_PORTRANGE)
bpf_error("'portrange' modifier applied to ip host");
bpf_error(cstate, "'portrange' modifier applied to ip host");
else if ($$.q.addr == Q_PROTO)
bpf_error("'proto' modifier applied to ip host");
bpf_error(cstate, "'proto' modifier applied to ip host");
else if ($$.q.addr == Q_PROTOCHAIN)
bpf_error("'protochain' modifier applied to ip host");
$$.b = gen_ncode($1, 0, $$.q);
bpf_error(cstate, "'protochain' modifier applied to ip host");
$$.b = gen_ncode(cstate, $1, 0, $$.q);
}
| HID6 '/' NUM {
#ifdef INET6
$$.b = gen_mcode6($1, NULL, $3,
$$.b = gen_mcode6(cstate, $1, NULL, $3,
$$.q = $<blk>0.q);
#else
bpf_error("'ip6addr/prefixlen' not supported "
bpf_error(cstate, "'ip6addr/prefixlen' not supported "
"in this configuration");
#endif /*INET6*/
}
| HID6 {
#ifdef INET6
$$.b = gen_mcode6($1, 0, 128,
$$.b = gen_mcode6(cstate, $1, 0, 128,
$$.q = $<blk>0.q);
#else
bpf_error("'ip6addr' not supported "
bpf_error(cstate, "'ip6addr' not supported "
"in this configuration");
#endif /*INET6*/
}
| EID {
$$.b = gen_ecode($1, $$.q = $<blk>0.q);
| EID {
$$.b = gen_ecode(cstate, $1, $$.q = $<blk>0.q);
/*
* $1 was allocated by "pcap_ether_aton()",
* so we must free it now that we're done
@ -397,7 +412,7 @@ nid: ID { $$.b = gen_scode($1, $$.q = $<blk>0.q); }
free($1);
}
| AID {
$$.b = gen_acode($1, $$.q = $<blk>0.q);
$$.b = gen_acode(cstate, $1, $$.q = $<blk>0.q);
/*
* $1 was allocated by "pcap_ether_aton()",
* so we must free it now that we're done
@ -415,7 +430,7 @@ pid: nid
| qid and id { gen_and($1.b, $3.b); $$ = $3; }
| qid or id { gen_or($1.b, $3.b); $$ = $3; }
;
qid: pnum { $$.b = gen_ncode(NULL, (bpf_u_int32)$1,
qid: pnum { $$.b = gen_ncode(cstate, NULL, (bpf_u_int32)$1,
$$.q = $<blk>0.q); }
| pid
;
@ -431,16 +446,16 @@ head: pqual dqual aqual { QSET($$.q, $1, $2, $3); }
;
rterm: head id { $$ = $2; }
| paren expr ')' { $$.b = $2.b; $$.q = $1.q; }
| pname { $$.b = gen_proto_abbrev($1); $$.q = qerr; }
| arth relop arth { $$.b = gen_relation($2, $1, $3, 0);
| pname { $$.b = gen_proto_abbrev(cstate, $1); $$.q = qerr; }
| arth relop arth { $$.b = gen_relation(cstate, $2, $1, $3, 0);
$$.q = qerr; }
| arth irelop arth { $$.b = gen_relation($2, $1, $3, 1);
| arth irelop arth { $$.b = gen_relation(cstate, $2, $1, $3, 1);
$$.q = qerr; }
| other { $$.b = $1; $$.q = qerr; }
| atmtype { $$.b = gen_atmtype_abbrev($1); $$.q = qerr; }
| atmmultitype { $$.b = gen_atmmulti_abbrev($1); $$.q = qerr; }
| atmtype { $$.b = gen_atmtype_abbrev(cstate, $1); $$.q = qerr; }
| atmmultitype { $$.b = gen_atmmulti_abbrev(cstate, $1); $$.q = qerr; }
| atmfield atmvalue { $$.b = $2.b; $$.q = qerr; }
| mtp2type { $$.b = gen_mtp2type_abbrev($1); $$.q = qerr; }
| mtp2type { $$.b = gen_mtp2type_abbrev(cstate, $1); $$.q = qerr; }
| mtp3field mtp3value { $$.b = $2.b; $$.q = qerr; }
;
/* protocol level qualifiers */
@ -510,52 +525,54 @@ pname: LINK { $$ = Q_LINK; }
| NETBEUI { $$ = Q_NETBEUI; }
| RADIO { $$ = Q_RADIO; }
;
other: pqual TK_BROADCAST { $$ = gen_broadcast($1); }
| pqual TK_MULTICAST { $$ = gen_multicast($1); }
| LESS NUM { $$ = gen_less($2); }
| GREATER NUM { $$ = gen_greater($2); }
| CBYTE NUM byteop NUM { $$ = gen_byteop($3, $2, $4); }
| INBOUND { $$ = gen_inbound(0); }
| OUTBOUND { $$ = gen_inbound(1); }
| VLAN pnum { $$ = gen_vlan($2); }
| VLAN { $$ = gen_vlan(-1); }
| MPLS pnum { $$ = gen_mpls($2); }
| MPLS { $$ = gen_mpls(-1); }
| PPPOED { $$ = gen_pppoed(); }
| PPPOES pnum { $$ = gen_pppoes($2); }
| PPPOES { $$ = gen_pppoes(-1); }
other: pqual TK_BROADCAST { $$ = gen_broadcast(cstate, $1); }
| pqual TK_MULTICAST { $$ = gen_multicast(cstate, $1); }
| LESS NUM { $$ = gen_less(cstate, $2); }
| GREATER NUM { $$ = gen_greater(cstate, $2); }
| CBYTE NUM byteop NUM { $$ = gen_byteop(cstate, $3, $2, $4); }
| INBOUND { $$ = gen_inbound(cstate, 0); }
| OUTBOUND { $$ = gen_inbound(cstate, 1); }
| VLAN pnum { $$ = gen_vlan(cstate, $2); }
| VLAN { $$ = gen_vlan(cstate, -1); }
| MPLS pnum { $$ = gen_mpls(cstate, $2); }
| MPLS { $$ = gen_mpls(cstate, -1); }
| PPPOED { $$ = gen_pppoed(cstate); }
| PPPOES pnum { $$ = gen_pppoes(cstate, $2); }
| PPPOES { $$ = gen_pppoes(cstate, -1); }
| GENEVE pnum { $$ = gen_geneve(cstate, $2); }
| GENEVE { $$ = gen_geneve(cstate, -1); }
| pfvar { $$ = $1; }
| pqual p80211 { $$ = $2; }
| pllc { $$ = $1; }
;
pfvar: PF_IFNAME ID { $$ = gen_pf_ifname($2); }
| PF_RSET ID { $$ = gen_pf_ruleset($2); }
| PF_RNR NUM { $$ = gen_pf_rnr($2); }
| PF_SRNR NUM { $$ = gen_pf_srnr($2); }
| PF_REASON reason { $$ = gen_pf_reason($2); }
| PF_ACTION action { $$ = gen_pf_action($2); }
pfvar: PF_IFNAME ID { $$ = gen_pf_ifname(cstate, $2); }
| PF_RSET ID { $$ = gen_pf_ruleset(cstate, $2); }
| PF_RNR NUM { $$ = gen_pf_rnr(cstate, $2); }
| PF_SRNR NUM { $$ = gen_pf_srnr(cstate, $2); }
| PF_REASON reason { $$ = gen_pf_reason(cstate, $2); }
| PF_ACTION action { $$ = gen_pf_action(cstate, $2); }
;
p80211: TYPE type SUBTYPE subtype
{ $$ = gen_p80211_type($2 | $4,
{ $$ = gen_p80211_type(cstate, $2 | $4,
IEEE80211_FC0_TYPE_MASK |
IEEE80211_FC0_SUBTYPE_MASK);
}
| TYPE type { $$ = gen_p80211_type($2,
| TYPE type { $$ = gen_p80211_type(cstate, $2,
IEEE80211_FC0_TYPE_MASK);
}
| SUBTYPE type_subtype { $$ = gen_p80211_type($2,
| SUBTYPE type_subtype { $$ = gen_p80211_type(cstate, $2,
IEEE80211_FC0_TYPE_MASK |
IEEE80211_FC0_SUBTYPE_MASK);
}
| DIR dir { $$ = gen_p80211_fcdir($2); }
| DIR dir { $$ = gen_p80211_fcdir(cstate, $2); }
;
type: NUM
| ID { $$ = str2tok($1, ieee80211_types);
if ($$ == -1)
bpf_error("unknown 802.11 type name");
bpf_error(cstate, "unknown 802.11 type name");
}
;
@ -565,7 +582,7 @@ subtype: NUM
for (i = 0;; i++) {
if (ieee80211_type_subtypes[i].tok == NULL) {
/* Ran out of types */
bpf_error("unknown 802.11 type");
bpf_error(cstate, "unknown 802.11 type");
break;
}
if ($<i>-1 == ieee80211_type_subtypes[i].type) {
@ -576,7 +593,7 @@ subtype: NUM
$$ = str2tok($1, types);
if ($$ == -1)
bpf_error("unknown 802.11 subtype name");
bpf_error(cstate, "unknown 802.11 subtype name");
}
;
@ -584,7 +601,7 @@ type_subtype: ID { int i;
for (i = 0;; i++) {
if (ieee80211_type_subtypes[i].tok == NULL) {
/* Ran out of types */
bpf_error("unknown 802.11 type name");
bpf_error(cstate, "unknown 802.11 type name");
break;
}
$$ = str2tok($1, ieee80211_type_subtypes[i].tok);
@ -596,29 +613,29 @@ type_subtype: ID { int i;
}
;
pllc: LLC { $$ = gen_llc(); }
pllc: LLC { $$ = gen_llc(cstate); }
| LLC ID { if (pcap_strcasecmp($2, "i") == 0)
$$ = gen_llc_i();
$$ = gen_llc_i(cstate);
else if (pcap_strcasecmp($2, "s") == 0)
$$ = gen_llc_s();
$$ = gen_llc_s(cstate);
else if (pcap_strcasecmp($2, "u") == 0)
$$ = gen_llc_u();
$$ = gen_llc_u(cstate);
else {
u_int subtype;
int subtype;
subtype = str2tok($2, llc_s_subtypes);
if (subtype != -1)
$$ = gen_llc_s_subtype(subtype);
$$ = gen_llc_s_subtype(cstate, subtype);
else {
subtype = str2tok($2, llc_u_subtypes);
if (subtype == -1)
bpf_error("unknown LLC type name \"%s\"", $2);
$$ = gen_llc_u_subtype(subtype);
bpf_error(cstate, "unknown LLC type name \"%s\"", $2);
$$ = gen_llc_u_subtype(cstate, subtype);
}
}
}
/* sigh, "rnr" is already a keyword for PF */
| LLC PF_RNR { $$ = gen_llc_s_subtype(LLC_RNR); }
| LLC PF_RNR { $$ = gen_llc_s_subtype(cstate, LLC_RNR); }
;
dir: NUM
@ -631,15 +648,15 @@ dir: NUM
else if (pcap_strcasecmp($1, "dstods") == 0)
$$ = IEEE80211_FC1_DIR_DSTODS;
else
bpf_error("unknown 802.11 direction");
bpf_error(cstate, "unknown 802.11 direction");
}
;
reason: NUM { $$ = $1; }
| ID { $$ = pfreason_to_num($1); }
| ID { $$ = pfreason_to_num(cstate, $1); }
;
action: ID { $$ = pfaction_to_num($1); }
action: ID { $$ = pfaction_to_num(cstate, $1); }
;
relop: '>' { $$ = BPF_JGT; }
@ -650,24 +667,24 @@ irelop: LEQ { $$ = BPF_JGT; }
| '<' { $$ = BPF_JGE; }
| NEQ { $$ = BPF_JEQ; }
;
arth: pnum { $$ = gen_loadi($1); }
arth: pnum { $$ = gen_loadi(cstate, $1); }
| narth
;
narth: pname '[' arth ']' { $$ = gen_load($1, $3, 1); }
| pname '[' arth ':' NUM ']' { $$ = gen_load($1, $3, $5); }
| arth '+' arth { $$ = gen_arth(BPF_ADD, $1, $3); }
| arth '-' arth { $$ = gen_arth(BPF_SUB, $1, $3); }
| arth '*' arth { $$ = gen_arth(BPF_MUL, $1, $3); }
| arth '/' arth { $$ = gen_arth(BPF_DIV, $1, $3); }
| arth '%' arth { $$ = gen_arth(BPF_MOD, $1, $3); }
| arth '&' arth { $$ = gen_arth(BPF_AND, $1, $3); }
| arth '|' arth { $$ = gen_arth(BPF_OR, $1, $3); }
| arth '^' arth { $$ = gen_arth(BPF_XOR, $1, $3); }
| arth LSH arth { $$ = gen_arth(BPF_LSH, $1, $3); }
| arth RSH arth { $$ = gen_arth(BPF_RSH, $1, $3); }
| '-' arth %prec UMINUS { $$ = gen_neg($2); }
narth: pname '[' arth ']' { $$ = gen_load(cstate, $1, $3, 1); }
| pname '[' arth ':' NUM ']' { $$ = gen_load(cstate, $1, $3, $5); }
| arth '+' arth { $$ = gen_arth(cstate, BPF_ADD, $1, $3); }
| arth '-' arth { $$ = gen_arth(cstate, BPF_SUB, $1, $3); }
| arth '*' arth { $$ = gen_arth(cstate, BPF_MUL, $1, $3); }
| arth '/' arth { $$ = gen_arth(cstate, BPF_DIV, $1, $3); }
| arth '%' arth { $$ = gen_arth(cstate, BPF_MOD, $1, $3); }
| arth '&' arth { $$ = gen_arth(cstate, BPF_AND, $1, $3); }
| arth '|' arth { $$ = gen_arth(cstate, BPF_OR, $1, $3); }
| arth '^' arth { $$ = gen_arth(cstate, BPF_XOR, $1, $3); }
| arth LSH arth { $$ = gen_arth(cstate, BPF_LSH, $1, $3); }
| arth RSH arth { $$ = gen_arth(cstate, BPF_RSH, $1, $3); }
| '-' arth %prec UMINUS { $$ = gen_neg(cstate, $2); }
| paren narth ')' { $$ = $2; }
| LEN { $$ = gen_loadlen(); }
| LEN { $$ = gen_loadlen(cstate); }
;
byteop: '&' { $$ = '&'; }
| '|' { $$ = '|'; }
@ -696,15 +713,15 @@ atmfield: VPI { $$.atmfieldtype = A_VPI; }
| VCI { $$.atmfieldtype = A_VCI; }
;
atmvalue: atmfieldvalue
| relop NUM { $$.b = gen_atmfield_code($<blk>0.atmfieldtype, (bpf_int32)$2, (bpf_u_int32)$1, 0); }
| irelop NUM { $$.b = gen_atmfield_code($<blk>0.atmfieldtype, (bpf_int32)$2, (bpf_u_int32)$1, 1); }
| relop NUM { $$.b = gen_atmfield_code(cstate, $<blk>0.atmfieldtype, (bpf_int32)$2, (bpf_u_int32)$1, 0); }
| irelop NUM { $$.b = gen_atmfield_code(cstate, $<blk>0.atmfieldtype, (bpf_int32)$2, (bpf_u_int32)$1, 1); }
| paren atmlistvalue ')' { $$.b = $2.b; $$.q = qerr; }
;
atmfieldvalue: NUM {
$$.atmfieldtype = $<blk>0.atmfieldtype;
if ($$.atmfieldtype == A_VPI ||
$$.atmfieldtype == A_VCI)
$$.b = gen_atmfield_code($$.atmfieldtype, (bpf_int32) $1, BPF_JEQ, 0);
$$.b = gen_atmfield_code(cstate, $$.atmfieldtype, (bpf_int32) $1, BPF_JEQ, 0);
}
;
atmlistvalue: atmfieldvalue
@ -729,8 +746,8 @@ mtp3field: SIO { $$.mtp3fieldtype = M_SIO; }
| HSLS { $$.mtp3fieldtype = MH_SLS; }
;
mtp3value: mtp3fieldvalue
| relop NUM { $$.b = gen_mtp3field_code($<blk>0.mtp3fieldtype, (u_int)$2, (u_int)$1, 0); }
| irelop NUM { $$.b = gen_mtp3field_code($<blk>0.mtp3fieldtype, (u_int)$2, (u_int)$1, 1); }
| relop NUM { $$.b = gen_mtp3field_code(cstate, $<blk>0.mtp3fieldtype, (u_int)$2, (u_int)$1, 0); }
| irelop NUM { $$.b = gen_mtp3field_code(cstate, $<blk>0.mtp3fieldtype, (u_int)$2, (u_int)$1, 1); }
| paren mtp3listvalue ')' { $$.b = $2.b; $$.q = qerr; }
;
mtp3fieldvalue: NUM {
@ -743,7 +760,7 @@ mtp3fieldvalue: NUM {
$$.mtp3fieldtype == MH_OPC ||
$$.mtp3fieldtype == MH_DPC ||
$$.mtp3fieldtype == MH_SLS)
$$.b = gen_mtp3field_code($$.mtp3fieldtype, (u_int) $1, BPF_JEQ, 0);
$$.b = gen_mtp3field_code(cstate, $$.mtp3fieldtype, (u_int) $1, BPF_JEQ, 0);
}
;
mtp3listvalue: mtp3fieldvalue

File diff suppressed because it is too large Load diff

View file

@ -115,7 +115,7 @@ fi
if [ x"$dir_arg" != x ]; then
dst=$src
src=""
if [ -d $dst ]; then
instcmd=:
else
@ -124,7 +124,7 @@ if [ x"$dir_arg" != x ]; then
else
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if [ -f $src -o -d $src ]
@ -134,7 +134,7 @@ else
echo "install: $src does not exist"
exit 1
fi
if [ x"$dst" = x ]
then
echo "install: no destination specified"
@ -201,17 +201,17 @@ else
# If we're going to rename the final executable, determine the name now.
if [ x"$transformarg" = x ]
if [ x"$transformarg" = x ]
then
dstfile=`basename $dst`
else
dstfile=`basename $dst $transformbasename |
dstfile=`basename $dst $transformbasename |
sed $transformarg`$transformbasename
fi
# don't allow the sed command to completely eliminate the filename
if [ x"$dstfile" = x ]
if [ x"$dstfile" = x ]
then
dstfile=`basename $dst`
else
@ -242,7 +242,7 @@ else
# Now rename the file to the real destination.
$doit $rmcmd -f $dstdir/$dstfile &&
$doit $mvcmd $dsttmp $dstdir/$dstfile
$doit $mvcmd $dsttmp $dstdir/$dstfile
fi &&

View file

@ -0,0 +1,23 @@
/*
* 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.
*/
/* Prototypes missing in AIX 7.x */
int ffs(int i);

View file

@ -20,7 +20,7 @@
*/
/* Prototypes missing in Digital UNIX 4.x */
int snprintf(char *, size_t, const char *, ...);
int vsnprintf(char *, size_t, const char *, va_list);
int pcap_snprintf(char *, size_t, const char *, ...);
int pcap_vsnprintf(char *, size_t, const char *, va_list);
int pfopen(char *, int);

View file

@ -21,10 +21,10 @@
/*
* Prototypes missing in Tru64 UNIX 5.x
* XXX - "snprintf()" and "vsnprintf()" aren't missing, but you have to
* XXX - "pcap_snprintf()" and "pcap_vsnprintf()" aren't missing, but you have to
* #define the right value to get them defined by <stdio.h>.
*/
int snprintf(char *, size_t, const char *, ...);
int vsnprintf(char *, size_t, const char *, va_list);
int pcap_snprintf(char *, size_t, const char *, ...);
int pcap_vsnprintf(char *, size_t, const char *, va_list);
int pfopen(char *, int);

View file

@ -21,4 +21,4 @@
/* Prototypes missing in SunOS 5 */
char *strerror(int);
int snprintf(char *, size_t, const char *, ...);
int pcap_snprintf(char *, size_t, const char *, ...);

View file

@ -65,7 +65,6 @@ int fchmod(int, int);
int fchown(int, int, int);
void endgrent(void);
void endpwent(void);
void endservent(void);
#ifdef __STDC__
struct ether_addr;
#endif
@ -146,7 +145,6 @@ int select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
int setpgrp(int, int);
void setpwent(void);
int setrlimit(int, struct rlimit *);
void setservent(int);
int setsockopt(int, int, int, char *, int);
int shutdown(int, int);
int sigblock(int);
@ -157,7 +155,7 @@ int sigsetmask(int);
struct sigvec;
#endif
int sigvec(int, struct sigvec *, struct sigvec*);
int snprintf(char *, size_t, const char *, ...);
int pcap_snprintf(char *, size_t, const char *, ...);
int socket(int, int, int);
int socketpair(int, int, int, int *);
int symlink(const char *, const char *);

View file

@ -23,7 +23,6 @@
int bcmp(const char *, const char *, u_int);
void bcopy(const void *, void *, u_int);
void bzero(void *, u_int);
void endservent(void);
int getopt(int, char * const *, const char *);
#ifdef __STDC__
struct timeval;

View file

@ -0,0 +1,126 @@
/*
* Copyright (c) 1987, 1993, 1994
* 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 defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)getopt.c 8.3 (Berkeley) 4/27/95";
#endif /* LIBC_SCCS and not lint */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "getopt.h"
int opterr = 1, /* if error message should be printed */
optind = 1, /* index into parent argv vector */
optopt, /* character checked for validity */
optreset; /* reset getopt */
char *optarg; /* argument associated with option */
#define BADCH (int)'?'
#define BADARG (int)':'
#define EMSG ""
/*
* getopt --
* Parse argc/argv argument vector.
*/
int
getopt(nargc, nargv, ostr)
int nargc;
char * const *nargv;
const char *ostr;
{
char *cp;
static char *__progname;
static char *place = EMSG; /* option letter processing */
char *oli; /* option letter list index */
if (__progname == NULL) {
if ((cp = strrchr(nargv[0], '/')) != NULL)
__progname = cp + 1;
else
__progname = nargv[0];
}
if (optreset || !*place) { /* update scanning pointer */
optreset = 0;
if (optind >= nargc || *(place = nargv[optind]) != '-') {
place = EMSG;
return (-1);
}
if (place[1] && *++place == '-') { /* found "--" */
++optind;
place = EMSG;
return (-1);
}
} /* option letter okay? */
if ((optopt = (int)*place++) == (int)':' ||
!(oli = strchr(ostr, optopt))) {
/*
* if the user didn't specify '-' as an option,
* assume it means -1.
*/
if (optopt == (int)'-')
return (-1);
if (!*place)
++optind;
if (opterr && *ostr != ':')
(void)fprintf(stderr,
"%s: illegal option -- %c\n", __progname, optopt);
return (BADCH);
}
if (*++oli != ':') { /* don't need argument */
optarg = NULL;
if (!*place)
++optind;
}
else { /* need an argument */
if (*place) /* no white space */
optarg = place;
else if (nargc <= ++optind) { /* no arg */
place = EMSG;
if (*ostr == ':')
return (BADARG);
if (opterr)
(void)fprintf(stderr,
"%s: option requires an argument -- %c\n",
__progname, optopt);
return (BADCH);
}
else /* white space */
optarg = nargv[optind];
place = EMSG;
++optind;
}
return (optopt); /* dump back option letter */
}

View file

@ -0,0 +1,7 @@
/*
* 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 getopt(int nargc, char * const *nargv, const char *ostr);

View file

@ -456,13 +456,13 @@ xyzprintf (struct state *state, const char *char_format, va_list ap)
#ifndef HAVE_SNPRINTF
int
snprintf (char *str, size_t sz, const char *format, ...)
pcap_snprintf (char *str, size_t sz, const char *format, ...)
{
va_list args;
int ret;
va_start(args, format);
ret = vsnprintf (str, sz, format, args);
ret = pcap_vsnprintf (str, sz, format, args);
#ifdef PARANOIA
{
@ -473,7 +473,7 @@ snprintf (char *str, size_t sz, const char *format, ...)
if (tmp == NULL)
abort ();
ret2 = vsprintf (tmp, format, args);
ret2 = pcap_vsprintf (tmp, format, args);
if (ret != ret2 || strcmp(str, tmp))
abort ();
free (tmp);
@ -518,13 +518,13 @@ asprintf (char **ret, const char *format, ...)
#ifndef HAVE_ASNPRINTF
int
asnprintf (char **ret, size_t max_sz, const char *format, ...)
pcap_asnprintf (char **ret, size_t max_sz, const char *format, ...)
{
va_list args;
int val;
va_start(args, format);
val = vasnprintf (ret, max_sz, format, args);
val = pcap_vasnprintf (ret, max_sz, format, args);
#ifdef PARANOIA
{
@ -534,7 +534,7 @@ asnprintf (char **ret, size_t max_sz, const char *format, ...)
if (tmp == NULL)
abort ();
ret2 = vsprintf (tmp, format, args);
ret2 = pcap_vsprintf (tmp, format, args);
if (val != ret2 || strcmp(*ret, tmp))
abort ();
free (tmp);
@ -548,16 +548,16 @@ asnprintf (char **ret, size_t max_sz, const char *format, ...)
#ifndef HAVE_VASPRINTF
int
vasprintf (char **ret, const char *format, va_list args)
pcap_vasprintf (char **ret, const char *format, va_list args)
{
return vasnprintf (ret, 0, format, args);
return pcap_vasnprintf (ret, 0, format, args);
}
#endif
#ifndef HAVE_VASNPRINTF
int
vasnprintf (char **ret, size_t max_sz, const char *format, va_list args)
pcap_vasnprintf (char **ret, size_t max_sz, const char *format, va_list args)
{
int st;
size_t len;
@ -600,7 +600,7 @@ vasnprintf (char **ret, size_t max_sz, const char *format, va_list args)
#ifndef HAVE_VSNPRINTF
int
vsnprintf (char *str, size_t sz, const char *format, va_list args)
pcap_vsnprintf (char *str, size_t sz, const char *format, va_list args)
{
struct state state;
int ret;

View file

@ -0,0 +1,87 @@
/*-
* Copyright (c) 1998 Softweyr LLC. All rights reserved.
*
* strtok_r, from Berkeley strtok
* Oct 13, 1998 by Wes Peters <wes@softweyr.com>
*
* Copyright (c) 1988, 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
* notices, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notices, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor 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 SOFTWEYR LLC, 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 SOFTWEYR LLC, 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.
*
* From: @(#)strtok.c 8.1 (Berkeley) 6/4/93
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "portability.h"
char *
pcap_strtok_r(char *s, const char *delim, char **last)
{
char *spanp, *tok;
int c, sc;
if (s == NULL && (s = *last) == NULL)
return (NULL);
/*
* Skip (span) leading delimiters (s += strspn(s, delim), sort of).
*/
cont:
c = *s++;
for (spanp = (char *)delim; (sc = *spanp++) != 0;) {
if (c == sc)
goto cont;
}
if (c == 0) { /* no non-delimiter characters */
*last = NULL;
return (NULL);
}
tok = s - 1;
/*
* Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
* Note that delim must have one NUL; we stop if we see that, too.
*/
for (;;) {
c = *s++;
spanp = (char *)delim;
do {
if ((sc = *spanp++) == c) {
if (c == 0)
s = NULL;
else
s[-1] = '\0';
*last = s;
return (tok);
}
} while (sc != 0);
}
/* NOTREACHED */
}

View file

@ -0,0 +1,31 @@
#include <stdio.h>
#include <stdarg.h>
int
pcap_vsnprintf(char *str, size_t str_size, const char *format, va_list args)
{
int ret;
ret = _vsnprintf_s(str, str_size, _TRUNCATE, format, args);
/*
* XXX - _vsnprintf() and _snprintf() do *not* guarantee
* that str is null-terminated, but C99's vsnprintf()
* and snprintf() do, and we want to offer C99 behavior,
* so forcibly null-terminate the string.
*/
str[str_size - 1] = '\0';
return (ret);
}
int
pcap_snprintf(char *str, size_t str_size, const char *format, ...)
{
va_list args;
int ret;
va_start(args, format);
ret = pcap_vsnprintf(str, str_size, format, args);
va_end(args);
return (ret);
}

View file

@ -13,9 +13,6 @@
# @(#)mkdep.sh 5.11 (Berkeley) 5/5/88
#
PATH=/bin:/usr/bin:/usr/ucb:/usr/local:/usr/local/bin:/usr/sfw/bin
export PATH
MAKE=Makefile # default makefile name is "Makefile"
CC=cc # default C compiler is "cc"
DEPENDENCY_CFLAG=-M # default dependency-generation flag is -M

View file

@ -33,10 +33,36 @@
#include <netdnet/dnetdb.h>
#endif
#ifdef WIN32
#ifdef _WIN32
#include <pcap-stdinc.h>
#else /* WIN32 */
#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
#else /* _WIN32 */
#include <sys/param.h>
#include <sys/types.h> /* concession to AIX */
@ -44,9 +70,9 @@
#include <sys/time.h>
#include <netinet/in.h>
#endif /* WIN32 */
#endif /* _WIN32 */
#ifndef WIN32
#ifndef _WIN32
#ifdef HAVE_ETHER_HOSTTON
/*
* XXX - do we need any of this if <netinet/if_ether.h> doesn't declare
@ -64,7 +90,7 @@ struct rtentry; /* declarations in <net/if.h> */
#endif /* HAVE_ETHER_HOSTTON */
#include <arpa/inet.h>
#include <netdb.h>
#endif /* WIN32 */
#endif /* _WIN32 */
#include <ctype.h>
#include <errno.h>
@ -76,6 +102,7 @@ struct rtentry; /* declarations in <net/if.h> */
#include "gencode.h"
#include <pcap/namedb.h>
#include "nametoaddr.h"
#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
@ -142,7 +169,7 @@ pcap_nametoaddrinfo(const char *name)
bpf_u_int32
pcap_nametonetaddr(const char *name)
{
#ifndef WIN32
#ifndef _WIN32
struct netent *np;
if ((np = getnetbyname(name)) != NULL)
@ -152,6 +179,15 @@ pcap_nametonetaddr(const char *name)
#else
/*
* There's no "getnetbyname()" on Windows.
*
* XXX - I guess we could use the BSD code to read
* C:\Windows\System32\drivers\etc/networks, assuming
* that's its home on all the versions of Windows
* we use, but that file probably just has the loopback
* network on 127/24 on 99 44/100% of Windows machines.
*
* (Heck, these days it probably just has that on 99 44/100%
* of *UN*X* machines.)
*/
return 0;
#endif
@ -276,8 +312,14 @@ struct eproto {
u_short p;
};
/* Static data base of ether protocol types. */
struct eproto eproto_db[] = {
/*
* Static data base of ether protocol types.
* tcpdump used to import this, and it's declared as an export on
* 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.)
*/
PCAP_API_DEF struct eproto eproto_db[] = {
#if 0
/* The FreeBSD elf linker generates a request to copy this array
* (including its size) when you link with -lpcap. In order to
@ -394,7 +436,7 @@ __pcap_atodn(const char *s, bpf_u_int32 *addr)
u_int node, area;
if (sscanf(s, "%d.%d", &area, &node) != 2)
bpf_error("malformed decnet address '%s'", s);
return(0);
*addr = (area << AREASHIFT) & AREAMASK;
*addr |= (node & NODEMASK);
@ -498,23 +540,20 @@ pcap_ether_hostton(const char *name)
}
#endif
u_short
__pcap_nametodnaddr(const char *name)
int
__pcap_nametodnaddr(const char *name, u_short *res)
{
#ifdef DECNETLIB
struct nodeent *getnodebyname();
struct nodeent *nep;
unsigned short res;
nep = getnodebyname(name);
if (nep == ((struct nodeent *)0))
bpf_error("unknown decnet host name '%s'\n", name);
return(0);
memcpy((char *)&res, (char *)nep->n_addr, sizeof(unsigned short));
return(res);
memcpy((char *)res, (char *)nep->n_addr, sizeof(unsigned short));
return(1);
#else
bpf_error("decnet name support not included, '%s' cannot be translated\n",
name);
return(0);
#endif
}

View file

@ -0,0 +1,48 @@
/*
* Copyright (c) 1994, 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.
*/
#ifdef __cplusplus
extern "C" {
#endif
/*
* Routines used for name-or-address-string-to-address resolution
* that are *not* exported to code using libpcap.
*/
int __pcap_atodn(const char *, bpf_u_int32 *);
int __pcap_atoin(const char *, bpf_u_int32 *);
int __pcap_nametodnaddr(const char *, u_short *);
#ifdef __cplusplus
}
#endif

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -4,7 +4,7 @@
*
* This code is derived from the Stanford/CMU enet packet filter,
* (net/enet.c) distributed as part of 4.3BSD, and code contributed
* to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
* to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
* Berkeley Laboratory.
*
* Redistribution and use in source and binary forms, with or without

View file

@ -11,8 +11,8 @@
* 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
* 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
@ -31,7 +31,7 @@
* By Paolo Abeni <paolo.abeni@email.it>
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
@ -73,7 +73,7 @@ struct pcap_bt {
int dev_id; /* device ID of device we're bound to */
};
int
int
bt_findalldevs(pcap_if_t **alldevsp, char *err_str)
{
struct hci_dev_list_req *dev_list;
@ -84,18 +84,18 @@ bt_findalldevs(pcap_if_t **alldevsp, char *err_str)
sock = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
if (sock < 0)
{
/* if bluetooth is not supported this this is not fatal*/
/* if bluetooth is not supported this this is not fatal*/
if (errno == EAFNOSUPPORT)
return 0;
snprintf(err_str, PCAP_ERRBUF_SIZE,
pcap_snprintf(err_str, PCAP_ERRBUF_SIZE,
"Can't open raw Bluetooth socket: %s", strerror(errno));
return -1;
}
dev_list = malloc(HCI_MAX_DEV * sizeof(*dev_req) + sizeof(*dev_list));
if (!dev_list)
if (!dev_list)
{
snprintf(err_str, PCAP_ERRBUF_SIZE, "Can't allocate %zu bytes for Bluetooth device list",
pcap_snprintf(err_str, PCAP_ERRBUF_SIZE, "Can't allocate %zu bytes for Bluetooth device list",
HCI_MAX_DEV * sizeof(*dev_req) + sizeof(*dev_list));
ret = -1;
goto done;
@ -103,9 +103,9 @@ bt_findalldevs(pcap_if_t **alldevsp, char *err_str)
dev_list->dev_num = HCI_MAX_DEV;
if (ioctl(sock, HCIGETDEVLIST, (void *) dev_list) < 0)
if (ioctl(sock, HCIGETDEVLIST, (void *) dev_list) < 0)
{
snprintf(err_str, PCAP_ERRBUF_SIZE,
pcap_snprintf(err_str, PCAP_ERRBUF_SIZE,
"Can't get Bluetooth device list via ioctl: %s",
strerror(errno));
ret = -1;
@ -115,11 +115,11 @@ bt_findalldevs(pcap_if_t **alldevsp, char *err_str)
dev_req = dev_list->dev_req;
for (i = 0; i < dev_list->dev_num; i++, dev_req++) {
char dev_name[20], dev_descr[30];
snprintf(dev_name, 20, BT_IFACE"%d", dev_req->dev_id);
snprintf(dev_descr, 30, "Bluetooth adapter number %d", i);
if (pcap_add_if(alldevsp, dev_name, 0,
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)
{
ret = -1;
@ -171,7 +171,7 @@ bt_create(const char *device, char *ebuf, int *is_ours)
/* OK, it's probably ours. */
*is_ours = 1;
p = pcap_create_common(device, ebuf, sizeof (struct pcap_bt));
p = pcap_create_common(ebuf, sizeof (struct pcap_bt));
if (p == NULL)
return (NULL);
@ -190,17 +190,16 @@ bt_activate(pcap_t* handle)
int err = PCAP_ERROR;
/* get bt interface id */
if (sscanf(handle->opt.source, BT_IFACE"%d", &dev_id) != 1)
if (sscanf(handle->opt.device, BT_IFACE"%d", &dev_id) != 1)
{
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't get Bluetooth device index from %s",
handle->opt.source);
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't get Bluetooth device index from %s",
handle->opt.device);
return PCAP_ERROR;
}
/* Initialize some components of the pcap structure. */
handle->bufsize = handle->snapshot+BT_CTRL_SIZE+sizeof(pcap_bluetooth_h4_header);
handle->offset = BT_CTRL_SIZE;
handle->bufsize = BT_CTRL_SIZE+sizeof(pcap_bluetooth_h4_header)+handle->snapshot;
handle->linktype = DLT_BLUETOOTH_HCI_H4_WITH_PHDR;
handle->read_op = bt_read_linux;
@ -212,43 +211,43 @@ bt_activate(pcap_t* handle)
handle->setnonblock_op = pcap_setnonblock_fd;
handle->stats_op = bt_stats_linux;
handlep->dev_id = dev_id;
/* Create HCI socket */
handle->fd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
if (handle->fd < 0) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't create raw socket: %s", strerror(errno));
return PCAP_ERROR;
}
handle->buffer = malloc(handle->bufsize);
if (!handle->buffer) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't allocate dump buffer: %s",
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't allocate dump buffer: %s",
pcap_strerror(errno));
goto close_fail;
}
opt = 1;
if (setsockopt(handle->fd, SOL_HCI, HCI_DATA_DIR, &opt, sizeof(opt)) < 0) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't enable data direction info: %s", strerror(errno));
goto close_fail;
}
opt = 1;
if (setsockopt(handle->fd, SOL_HCI, HCI_TIME_STAMP, &opt, sizeof(opt)) < 0) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't enable time stamp: %s", strerror(errno));
goto close_fail;
}
/* Setup filter, do not call hci function to avoid dependence on
/* Setup filter, do not call hci function to avoid dependence on
* external libs */
memset(&flt, 0, sizeof(flt));
memset((void *) &flt.type_mask, 0xff, sizeof(flt.type_mask));
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) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't set filter: %s", strerror(errno));
goto close_fail;
}
@ -261,7 +260,7 @@ bt_activate(pcap_t* handle)
addr.hci_channel = HCI_CHANNEL_RAW;
#endif
if (bind(handle->fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't attach to device %d: %s", handlep->dev_id,
strerror(errno));
goto close_fail;
@ -282,7 +281,7 @@ bt_activate(pcap_t* handle)
if (setsockopt(handle->fd, SOL_SOCKET, SO_RCVBUF,
&handle->opt.buffer_size,
sizeof(handle->opt.buffer_size)) == -1) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"SO_RCVBUF: %s", pcap_strerror(errno));
goto close_fail;
}
@ -305,16 +304,19 @@ bt_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *us
ssize_t ret;
struct pcap_pkthdr pkth;
pcap_bluetooth_h4_header* bthdr;
u_char *pktd;
int in = 0;
bthdr = (pcap_bluetooth_h4_header*) &handle->buffer[handle->offset];
iv.iov_base = &handle->buffer[handle->offset+sizeof(pcap_bluetooth_h4_header)];
pktd = (u_char *)handle->buffer + BT_CTRL_SIZE;
bthdr = (pcap_bluetooth_h4_header*)(void *)pktd;
iv.iov_base = pktd + sizeof(pcap_bluetooth_h4_header);
iv.iov_len = handle->snapshot;
memset(&msg, 0, sizeof(msg));
msg.msg_iov = &iv;
msg.msg_iovlen = 1;
msg.msg_control = handle->buffer;
msg.msg_controllen = handle->offset;
msg.msg_controllen = BT_CTRL_SIZE;
/* ignore interrupt system call error */
do {
@ -327,16 +329,15 @@ bt_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *us
} while ((ret == -1) && (errno == EINTR));
if (ret < 0) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't receive packet: %s", strerror(errno));
return -1;
}
pkth.caplen = ret;
/* get direction and timestamp*/
/* get direction and timestamp*/
cmsg = CMSG_FIRSTHDR(&msg);
int in=0;
while (cmsg) {
switch (cmsg->cmsg_type) {
case HCI_CMSG_DIR:
@ -349,7 +350,7 @@ bt_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *us
}
cmsg = CMSG_NXTHDR(&msg, cmsg);
}
if ((in && (handle->direction == PCAP_D_OUT)) ||
if ((in && (handle->direction == PCAP_D_OUT)) ||
((!in) && (handle->direction == PCAP_D_IN)))
return 0;
@ -357,9 +358,8 @@ bt_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *us
pkth.caplen+=sizeof(pcap_bluetooth_h4_header);
pkth.len = pkth.caplen;
if (handle->fcode.bf_insns == NULL ||
bpf_filter(handle->fcode.bf_insns, &handle->buffer[handle->offset],
pkth.len, pkth.caplen)) {
callback(user, &pkth, &handle->buffer[handle->offset]);
bpf_filter(handle->fcode.bf_insns, pktd, pkth.len, pkth.caplen)) {
callback(user, &pkth, pktd);
return 1;
}
return 0; /* didn't pass filter */
@ -368,13 +368,13 @@ 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)
{
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "inject not supported on "
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "inject not supported on "
"bluetooth devices");
return (-1);
}
}
static int
static int
bt_stats_linux(pcap_t *handle, struct pcap_stat *stats)
{
struct pcap_bt *handlep = handle->priv;
@ -382,28 +382,28 @@ bt_stats_linux(pcap_t *handle, struct pcap_stat *stats)
struct hci_dev_info dev_info;
struct hci_dev_stats * s = &dev_info.stat;
dev_info.dev_id = handlep->dev_id;
/* ignore eintr */
do {
ret = ioctl(handle->fd, HCIGETDEVINFO, (void *)&dev_info);
} while ((ret == -1) && (errno == EINTR));
if (ret < 0) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't get stats via ioctl: %s", strerror(errno));
return (-1);
}
/* we receive both rx and tx frames, so comulate all stats */
stats->ps_recv = s->evt_rx + s->acl_rx + s->sco_rx + s->cmd_tx +
/* we receive both rx and tx frames, so comulate all stats */
stats->ps_recv = s->evt_rx + s->acl_rx + s->sco_rx + s->cmd_tx +
s->acl_tx +s->sco_tx;
stats->ps_drop = s->err_rx + s->err_tx;
stats->ps_ifdrop = 0;
return 0;
}
static int
static int
bt_setdirection_linux(pcap_t *p, pcap_direction_t d)
{
p->direction = d;

View file

@ -11,8 +11,8 @@
* 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
* 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

View file

@ -34,19 +34,31 @@
#endif
#include <errno.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/mgmt.h>
#include "pcap/bluetooth.h"
#include "pcap-int.h"
#include "pcap-bt-monitor-linux.h"
#define BT_CONTROL_SIZE 32
#define INTERFACE_NAME "bluetooth-monitor"
/*
* Fields and alignment must match the declaration in the Linux kernel 3.4+.
* See struct hci_mon_hdr in include/net/bluetooth/hci_mon.h.
*/
struct hci_mon_hdr {
uint16_t opcode;
uint16_t index;
uint16_t len;
} __attribute__((packed));
int
bt_monitor_findalldevs(pcap_if_t **alldevsp, char *err_str)
{
@ -70,14 +82,15 @@ bt_monitor_read(pcap_t *handle, int max_packets _U_, pcap_handler callback, u_ch
ssize_t ret;
struct pcap_pkthdr pkth;
pcap_bluetooth_linux_monitor_header *bthdr;
struct mgmt_hdr hdr;
int in = 0;
u_char *pktd;
struct hci_mon_hdr hdr;
bthdr = (pcap_bluetooth_linux_monitor_header*) &handle->buffer[handle->offset];
pktd = (u_char *)handle->buffer + BT_CONTROL_SIZE;
bthdr = (pcap_bluetooth_linux_monitor_header*)(void *)pktd;
iv[0].iov_base = &hdr;
iv[0].iov_len = MGMT_HDR_SIZE;
iv[1].iov_base = &handle->buffer[handle->offset + sizeof(pcap_bluetooth_linux_monitor_header)];
iv[0].iov_len = sizeof(hdr);
iv[1].iov_base = pktd + sizeof(pcap_bluetooth_linux_monitor_header);
iv[1].iov_len = handle->snapshot;
memset(&pkth.ts, 0, sizeof(pkth.ts));
@ -85,7 +98,7 @@ bt_monitor_read(pcap_t *handle, int max_packets _U_, pcap_handler callback, u_ch
msg.msg_iov = iv;
msg.msg_iovlen = 2;
msg.msg_control = handle->buffer;
msg.msg_controllen = handle->offset;
msg.msg_controllen = BT_CONTROL_SIZE;
do {
ret = recvmsg(handle->fd, &msg, 0);
@ -97,12 +110,12 @@ bt_monitor_read(pcap_t *handle, int max_packets _U_, pcap_handler callback, u_ch
} while ((ret == -1) && (errno == EINTR));
if (ret < 0) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't receive packet: %s", strerror(errno));
return -1;
}
pkth.caplen = ret - MGMT_HDR_SIZE + sizeof(pcap_bluetooth_linux_monitor_header);
pkth.caplen = ret - sizeof(hdr) + sizeof(pcap_bluetooth_linux_monitor_header);
pkth.len = pkth.caplen;
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
@ -117,9 +130,8 @@ bt_monitor_read(pcap_t *handle, int max_packets _U_, pcap_handler callback, u_ch
bthdr->opcode = htons(hdr.opcode);
if (handle->fcode.bf_insns == NULL ||
bpf_filter(handle->fcode.bf_insns, &handle->buffer[handle->offset],
pkth.len, pkth.caplen)) {
callback(user, &pkth, &handle->buffer[handle->offset]);
bpf_filter(handle->fcode.bf_insns, pktd, pkth.len, pkth.caplen)) {
callback(user, &pkth, pktd);
return 1;
}
return 0; /* didn't pass filter */
@ -128,7 +140,7 @@ bt_monitor_read(pcap_t *handle, int max_packets _U_, pcap_handler callback, u_ch
static int
bt_monitor_inject(pcap_t *handle, const void *buf _U_, size_t size _U_)
{
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "inject not supported yet");
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "inject not supported yet");
return -1;
}
@ -161,8 +173,7 @@ bt_monitor_activate(pcap_t* handle)
return PCAP_ERROR_RFMON_NOTSUP;
}
handle->bufsize = handle->snapshot + BT_CONTROL_SIZE + sizeof(pcap_bluetooth_linux_monitor_header);
handle->offset = BT_CONTROL_SIZE;
handle->bufsize = BT_CONTROL_SIZE + sizeof(pcap_bluetooth_linux_monitor_header) + handle->snapshot;
handle->linktype = DLT_BLUETOOTH_LINUX_MONITOR;
handle->read_op = bt_monitor_read;
@ -176,14 +187,14 @@ bt_monitor_activate(pcap_t* handle)
handle->fd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
if (handle->fd < 0) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't create raw socket: %s", strerror(errno));
return PCAP_ERROR;
}
handle->buffer = malloc(handle->bufsize);
if (!handle->buffer) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't allocate dump buffer: %s",
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't allocate dump buffer: %s",
pcap_strerror(errno));
goto close_fail;
}
@ -194,14 +205,14 @@ bt_monitor_activate(pcap_t* handle)
addr.hci_channel = HCI_CHANNEL_MONITOR;
if (bind(handle->fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't attach to interface: %s", strerror(errno));
goto close_fail;
}
opt = 1;
if (setsockopt(handle->fd, SOL_SOCKET, SO_TIMESTAMP, &opt, sizeof(opt)) < 0) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't enable time stamp: %s", strerror(errno));
goto close_fail;
}
@ -231,7 +242,7 @@ bt_monitor_create(const char *device, char *ebuf, int *is_ours)
}
*is_ours = 1;
p = pcap_create_common(device, ebuf, 0);
p = pcap_create_common(ebuf, 0);
if (p == NULL)
return NULL;

View file

@ -1,319 +0,0 @@
/*
* Copyright (c) 2009 Felix Obenhuber
* 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.
*
* SocketCan sniffing API implementation for Linux platform
* By Felix Obenhuber <felix@obenhuber.de>
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "pcap-int.h"
#include "pcap-can-linux.h"
#ifdef NEED_STRERROR_H
#include "strerror.h"
#endif
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <arpa/inet.h>
#include <linux/can.h>
#include <linux/can/raw.h>
/* not yet defined anywhere */
#ifndef PF_CAN
#define PF_CAN 29
#endif
#ifndef AF_CAN
#define AF_CAN PF_CAN
#endif
/* forward declaration */
static int can_activate(pcap_t *);
static int can_read_linux(pcap_t *, int , pcap_handler , u_char *);
static int can_inject_linux(pcap_t *, const void *, size_t);
static int can_setfilter_linux(pcap_t *, struct bpf_program *);
static int can_setdirection_linux(pcap_t *, pcap_direction_t);
static int can_stats_linux(pcap_t *, struct pcap_stat *);
/*
* Private data for capturing on Linux CANbus devices.
*/
struct pcap_can {
int ifindex; /* interface index of device we're bound to */
};
int
can_findalldevs(pcap_if_t **devlistp, char *errbuf)
{
/*
* There are no platform-specific devices since each device
* exists as a regular network interface.
*
* XXX - true?
*/
return 0;
}
pcap_t *
can_create(const char *device, char *ebuf, int *is_ours)
{
const char *cp;
char *cpend;
long devnum;
pcap_t* p;
/* Does this look like a CANbus device? */
cp = strrchr(device, '/');
if (cp == NULL)
cp = device;
/* Does it begin with "can" or "vcan"? */
if (strncmp(cp, "can", 3) == 0) {
/* Begins with "can" */
cp += 3; /* skip past "can" */
} else if (strncmp(cp, "vcan", 4) == 0) {
/* Begins with "vcan" */
cp += 4;
} else {
/* Nope, doesn't begin with "can" or "vcan" */
*is_ours = 0;
return NULL;
}
/* Yes - is "can" or "vcan" followed by a number from 0? */
devnum = strtol(cp, &cpend, 10);
if (cpend == cp || *cpend != '\0') {
/* Not followed by a number. */
*is_ours = 0;
return NULL;
}
if (devnum < 0) {
/* Followed by a non-valid number. */
*is_ours = 0;
return NULL;
}
/* OK, it's probably ours. */
*is_ours = 1;
p = pcap_create_common(device, ebuf, sizeof (struct pcap_can));
if (p == NULL)
return (NULL);
p->activate_op = can_activate;
return (p);
}
static int
can_activate(pcap_t* handle)
{
struct pcap_can *handlep = handle->priv;
struct sockaddr_can addr;
struct ifreq ifr;
/* Initialize some components of the pcap structure. */
handle->bufsize = 24;
handle->offset = 8;
handle->linktype = DLT_CAN_SOCKETCAN;
handle->read_op = can_read_linux;
handle->inject_op = can_inject_linux;
handle->setfilter_op = can_setfilter_linux;
handle->setdirection_op = can_setdirection_linux;
handle->set_datalink_op = NULL;
handle->getnonblock_op = pcap_getnonblock_fd;
handle->setnonblock_op = pcap_setnonblock_fd;
handle->stats_op = can_stats_linux;
/* Create socket */
handle->fd = socket(PF_CAN, SOCK_RAW, CAN_RAW);
if (handle->fd < 0)
{
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't create raw socket %d:%s",
errno, strerror(errno));
return PCAP_ERROR;
}
/* get interface index */
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, handle->opt.source, sizeof(ifr.ifr_name));
if (ioctl(handle->fd, SIOCGIFINDEX, &ifr) < 0)
{
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Unable to get interface index: %s",
pcap_strerror(errno));
pcap_cleanup_live_common(handle);
return PCAP_ERROR;
}
handlep->ifindex = ifr.ifr_ifindex;
/* allocate butter */
handle->buffer = malloc(handle->bufsize);
if (!handle->buffer)
{
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't allocate dump buffer: %s",
pcap_strerror(errno));
pcap_cleanup_live_common(handle);
return PCAP_ERROR;
}
/* Bind to the socket */
addr.can_family = AF_CAN;
addr.can_ifindex = handlep->ifindex;
if( bind( handle->fd, (struct sockaddr*)&addr, sizeof(addr) ) < 0 )
{
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't attach to device %d %d:%s",
handlep->ifindex, errno, strerror(errno));
pcap_cleanup_live_common(handle);
return PCAP_ERROR;
}
if (handle->opt.rfmon)
{
/* Monitor mode doesn't apply to CAN devices. */
pcap_cleanup_live_common(handle);
return PCAP_ERROR_RFMON_NOTSUP;
}
handle->selectable_fd = handle->fd;
return 0;
}
static int
can_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user)
{
struct msghdr msg;
struct pcap_pkthdr pkth;
struct iovec iv;
struct can_frame* cf;
iv.iov_base = &handle->buffer[handle->offset];
iv.iov_len = handle->snapshot;
memset(&msg, 0, sizeof(msg));
msg.msg_iov = &iv;
msg.msg_iovlen = 1;
msg.msg_control = handle->buffer;
msg.msg_controllen = handle->offset;
do
{
pkth.caplen = recvmsg(handle->fd, &msg, 0);
if (handle->break_loop)
{
handle->break_loop = 0;
return -2;
}
} while ((pkth.caplen == -1) && (errno == EINTR));
if (pkth.caplen == -1)
{
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't receive packet %d:%s",
errno, strerror(errno));
return -1;
}
/* adjust capture len according to frame len */
cf = (struct can_frame*)&handle->buffer[8];
pkth.caplen -= 8 - cf->can_dlc;
pkth.len = pkth.caplen;
cf->can_id = htonl( cf->can_id );
if( -1 == gettimeofday(&pkth.ts, NULL) )
{
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't get time of day %d:%s",
errno, strerror(errno));
return -1;
}
callback(user, &pkth, &handle->buffer[8]);
return 1;
}
static int
can_inject_linux(pcap_t *handle, const void *buf, size_t size)
{
/* not yet implemented */
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "inject not supported on "
"can devices");
return (-1);
}
static int
can_stats_linux(pcap_t *handle, struct pcap_stat *stats)
{
/* not yet implemented */
stats->ps_recv = 0; /* number of packets received */
stats->ps_drop = 0; /* number of packets dropped */
stats->ps_ifdrop = 0; /* drops by interface -- only supported on some platforms */
return 0;
}
static int
can_setfilter_linux(pcap_t *p, struct bpf_program *fp)
{
/* not yet implemented */
return 0;
}
static int
can_setdirection_linux(pcap_t *p, pcap_direction_t d)
{
/* no support for PCAP_D_OUT */
if (d == PCAP_D_OUT)
{
snprintf(p->errbuf, sizeof(p->errbuf),
"Setting direction to PCAP_D_OUT is not supported on can");
return -1;
}
p->direction = d;
return 0;
}
/* eof */

View file

@ -1,36 +0,0 @@
/*
* Copyright (c) 2009 Felix Obenhuber
* 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.
*
*/
/*
* Prototypes for SocketCAN related functions
*/
pcap_t* can_create(const char *device, char *ebuf, int *is_ours);
int can_findalldevs(pcap_if_t **devlistp, char *errbuf);

View file

@ -1,472 +0,0 @@
/*
* Copyright (c) 2009 Felix Obenhuber
* 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.
*
* Sockettrace sniffing API implementation for Linux platform
* By Felix Obenhuber <felix@obenhuber.de>
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <libusb-1.0/libusb.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <pthread.h>
#include "pcap-int.h"
#include "pcap-canusb-linux.h"
#define CANUSB_IFACE "canusb"
#define CANUSB_VID 0x0403
#define CANUSB_PID 0x8990
#define USE_THREAD 1
#if USE_THREAD == 0
#include <signal.h>
#endif
/* forward declaration */
static int canusb_activate(pcap_t *);
static int canusb_read_linux(pcap_t *, int , pcap_handler , u_char *);
static int canusb_inject_linux(pcap_t *, const void *, size_t);
static int canusb_setfilter_linux(pcap_t *, struct bpf_program *);
static int canusb_setdirection_linux(pcap_t *, pcap_direction_t);
static int canusb_stats_linux(pcap_t *, struct pcap_stat *);
struct CAN_Msg
{
uint32_t timestamp;
uint32_t id;
uint32_t length;
uint8_t data[8];
};
/*
* Private data for capturing on Linux CANbus USB devices.
*/
struct pcap_canusb {
libusb_context *ctx;
libusb_device_handle *dev;
pthread_t worker;
int rdpipe, wrpipe;
volatile int loop;
};
int canusb_findalldevs(pcap_if_t **alldevsp, char *err_str)
{
libusb_context *fdctx;
libusb_device** devs;
unsigned char sernum[65];
int cnt, i;
if (libusb_init(&fdctx) != 0) {
/*
* XXX - if this doesn't just mean "no USB file system mounted",
* perhaps we should report a real error rather than just
* saying "no CANUSB devices".
*/
return 0;
}
cnt = libusb_get_device_list(fdctx,&devs);
for(i=0;i<cnt;i++)
{
int ret;
// Check if this device is interesting.
struct libusb_device_descriptor desc;
libusb_get_device_descriptor(devs[i],&desc);
if ((desc.idVendor != CANUSB_VID) || (desc.idProduct != CANUSB_PID))
continue; //It is not, check next device
//It is!
libusb_device_handle *dh = NULL;
if ((ret = libusb_open(devs[i],&dh)) == 0)
{
char dev_name[30];
char dev_descr[50];
int n = libusb_get_string_descriptor_ascii(dh,desc.iSerialNumber,sernum,64);
sernum[n] = 0;
snprintf(dev_name, 30, CANUSB_IFACE"%s", sernum);
snprintf(dev_descr, 50, "CanUSB [%s]", sernum);
libusb_close(dh);
if (pcap_add_if(alldevsp, dev_name, 0, dev_descr, err_str) < 0)
{
libusb_free_device_list(devs,1);
libusb_exit(fdctx);
return -1;
}
}
}
libusb_free_device_list(devs,1);
libusb_exit(fdctx);
return 0;
}
static libusb_device_handle* canusb_opendevice(struct libusb_context *ctx, char* devserial)
{
libusb_device** devs;
unsigned char serial[65];
int cnt,i,n;
cnt = libusb_get_device_list(ctx,&devs);
for(i=0;i<cnt;i++)
{
// Check if this device is interesting.
struct libusb_device_descriptor desc;
libusb_get_device_descriptor(devs[i],&desc);
if ((desc.idVendor != CANUSB_VID) || (desc.idProduct != CANUSB_PID))
continue;
//Found one!
libusb_device_handle *dh = NULL;
if (libusb_open(devs[i],&dh) != 0) continue;
n = libusb_get_string_descriptor_ascii(dh,desc.iSerialNumber,serial,64);
serial[n] = 0;
if ((devserial) && (strcmp((char *)serial,devserial) != 0))
{
libusb_close(dh);
continue;
}
if ((libusb_kernel_driver_active(dh,0)) && (libusb_detach_kernel_driver(dh,0) != 0))
{
libusb_close(dh);
continue;
}
if (libusb_set_configuration(dh,1) != 0)
{
libusb_close(dh);
continue;
}
if (libusb_claim_interface(dh,0) != 0)
{
libusb_close(dh);
continue;
}
//Fount it!
libusb_free_device_list(devs,1);
return dh;
}
libusb_free_device_list(devs,1);
return NULL;
}
pcap_t *
canusb_create(const char *device, char *ebuf, int *is_ours)
{
const char *cp;
char *cpend;
long devnum;
pcap_t* p;
struct pcap_canusb *canusb;
/* Does this look like a DAG device? */
cp = strrchr(device, '/');
if (cp == NULL)
cp = device;
/* Does it begin with "canusb"? */
if (strncmp(cp, "canusb", 6) != 0) {
/* Nope, doesn't begin with "canusb" */
*is_ours = 0;
return NULL;
}
/* Yes - is "canusb" followed by a number? */
cp += 6;
devnum = strtol(cp, &cpend, 10);
if (cpend == cp || *cpend != '\0') {
/* Not followed by a number. */
*is_ours = 0;
return NULL;
}
if (devnum < 0) {
/* Followed by a non-valid number. */
*is_ours = 0;
return NULL;
}
/* OK, it's probably ours. */
*is_ours = 1;
p = pcap_create_common(device, ebuf, sizeof (struct pcap_canusb));
if (p == NULL)
return (NULL);
canusb = p->priv;
canusb->ctx = NULL;
canusb->dev = NULL;
canusb->rdpipe = -1;
canusb->wrpipe = -1;
p->activate_op = canusb_activate;
return (p);
}
static void* canusb_capture_thread(void *arg)
{
struct pcap_canusb *canusb = arg;
int i;
struct
{
uint8_t rxsz, txsz;
} status;
fcntl(canusb->wrpipe, F_SETFL, O_NONBLOCK);
while(canusb->loop)
{
int sz;
struct CAN_Msg msg;
libusb_interrupt_transfer(canusb->dev, 0x81, (unsigned char*)&status, sizeof(status), &sz, 100);
//HACK!!!!! -> drop buffered data, read new one by reading twice.
libusb_interrupt_transfer(canusb->dev, 0x81, (unsigned char*)&status, sizeof(status), &sz, 100);
for(i = 0; i<status.rxsz; i++)
{
libusb_bulk_transfer(canusb->dev, 0x85, (unsigned char*)&msg, sizeof(msg), &sz, 100);
write(canusb->wrpipe, &msg, sizeof(msg));
}
}
return NULL;
}
static int canusb_startcapture(struct pcap_canusb* this)
{
int pipefd[2];
if (pipe(pipefd) == -1)
return -1;
this->rdpipe = pipefd[0];
this->wrpipe = pipefd[1];
this->loop = 1;
pthread_create(&this->worker, NULL, canusb_capture_thread, this);
return this->rdpipe;
}
static void canusb_clearbufs(struct pcap_canusb* this)
{
unsigned char cmd[16];
int al;
cmd[0] = 1; //Empty incoming buffer
cmd[1] = 1; //Empty outgoing buffer
cmd[3] = 0; //Not a write to serial number
memset(&cmd[4],0,16-4);
libusb_interrupt_transfer(this->dev, 0x1,cmd,16,&al,100);
}
static void canusb_close(pcap_t* handle)
{
struct pcap_canusb *canusb = handle->priv;
canusb->loop = 0;
pthread_join(canusb->worker, NULL);
if (canusb->dev)
{
libusb_close(canusb->dev);
canusb->dev = NULL;
}
if (canusb->ctx)
{
libusb_exit(canusb->ctx);
canusb->ctx = NULL;
}
}
static int canusb_activate(pcap_t* handle)
{
struct pcap_canusb *canusb = handle->priv;
char *serial;
if (libusb_init(&canusb->ctx) != 0) {
/*
* XXX - what causes this to fail?
*/
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "libusb_init() failed");
return PCAP_ERROR;
}
handle->read_op = canusb_read_linux;
handle->inject_op = canusb_inject_linux;
handle->setfilter_op = canusb_setfilter_linux;
handle->setdirection_op = canusb_setdirection_linux;
handle->getnonblock_op = pcap_getnonblock_fd;
handle->setnonblock_op = pcap_setnonblock_fd;
handle->stats_op = canusb_stats_linux;
handle->cleanup_op = canusb_close;
/* Initialize some components of the pcap structure. */
handle->bufsize = 32;
handle->offset = 8;
handle->linktype = DLT_CAN_SOCKETCAN;
handle->set_datalink_op = NULL;
serial = handle->opt.source + strlen(CANUSB_IFACE);
canusb->dev = canusb_opendevice(canusb->ctx, serial);
if (!canusb->dev)
{
libusb_exit(canusb->ctx);
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't open USB Device");
return PCAP_ERROR;
}
canusb_clearbufs(canusb);
handle->fd = canusb_startcapture(canusb);
handle->selectable_fd = handle->fd;
return 0;
}
static int
canusb_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user)
{
static struct timeval firstpacket = { -1, -1};
int i = 0;
struct CAN_Msg msg;
struct pcap_pkthdr pkth;
while(i < max_packets)
{
int n;
usleep(10 * 1000);
n = read(handle->fd, &msg, sizeof(msg));
if (n <= 0)
break;
pkth.caplen = pkth.len = n;
pkth.caplen -= 4;
pkth.caplen -= 8 - msg.length;
if ((firstpacket.tv_sec == -1) && (firstpacket.tv_usec == -1))
gettimeofday(&firstpacket, NULL);
pkth.ts.tv_usec = firstpacket.tv_usec + (msg.timestamp % 100) * 10000;
pkth.ts.tv_sec = firstpacket.tv_usec + (msg.timestamp / 100);
if (pkth.ts.tv_usec > 1000000)
{
pkth.ts.tv_usec -= 1000000;
pkth.ts.tv_sec++;
}
callback(user, &pkth, (void*)&msg.id);
i++;
}
return i;
}
static int
canusb_inject_linux(pcap_t *handle, const void *buf, size_t size)
{
/* not yet implemented */
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "inject not supported on canusb devices");
return (-1);
}
static int
canusb_stats_linux(pcap_t *handle, struct pcap_stat *stats)
{
/* not yet implemented */
stats->ps_recv = 0; /* number of packets received */
stats->ps_drop = 0; /* number of packets dropped */
stats->ps_ifdrop = 0; /* drops by interface -- only supported on some platforms */
return 0;
}
static int
canusb_setfilter_linux(pcap_t *p, struct bpf_program *fp)
{
/* not yet implemented */
return 0;
}
static int
canusb_setdirection_linux(pcap_t *p, pcap_direction_t d)
{
/* no support for PCAP_D_OUT */
if (d == PCAP_D_OUT)
{
snprintf(p->errbuf, sizeof(p->errbuf),
"Setting direction to PCAP_D_OUT is not supported on this interface");
return -1;
}
p->direction = d;
return 0;
}
/* eof */

View file

@ -25,9 +25,9 @@
#include "config.h"
#endif
#ifdef WIN32
#ifdef _WIN32
#include <pcap-stdinc.h>
#else /* WIN32 */
#else /* _WIN32 */
#if HAVE_INTTYPES_H
#include <inttypes.h>
#elif HAVE_STDINT_H
@ -37,11 +37,14 @@
#include <sys/bitypes.h>
#endif
#include <sys/types.h>
#endif /* WIN32 */
#endif /* _WIN32 */
#include "pcap-int.h"
#include "extract.h"
#include "pcap/sll.h"
#include "pcap/usb.h"
#include "pcap/nflog.h"
#include "pcap/can_socketcan.h"
#include "pcap-common.h"
@ -351,7 +354,7 @@
#define LINKTYPE_GPRS_LLC 169 /* GPRS LLC */
#define LINKTYPE_GPF_T 170 /* GPF-T (ITU-T G.7041/Y.1303) */
#define LINKTYPE_GPF_F 171 /* GPF-T (ITU-T G.7041/Y.1303) */
#define LINKTYPE_GPF_F 171 /* GPF-F (ITU-T G.7041/Y.1303) */
/*
* Requested by Oolan Zimmer <oz@gcom.com> for use in Gcom's T1/E1 line
@ -386,7 +389,7 @@
/*
* Juniper-private data link type, as per request from
* Hannes Gredler <hannes@juniper.net>.
* Hannes Gredler <hannes@juniper.net>.
* The Link Types are used for prepending meta-information
* like interface index, interface name
* before standard Ethernet, PPP, Frelay & C-HDLC Frames
@ -403,7 +406,7 @@
/*
* Juniper-private data link type, as per request from
* Hannes Gredler <hannes@juniper.net>.
* Hannes Gredler <hannes@juniper.net>.
* The DLT_ is used for internal communication with a
* voice Adapter Card (PIC)
*/
@ -426,10 +429,17 @@
#define LINKTYPE_A653_ICM 185
/*
* USB packets, beginning with a USB setup header; requested by
* Paolo Abeni <paolo.abeni@email.it>.
* This used to be "USB packets, beginning with a USB setup header;
* requested by Paolo Abeni <paolo.abeni@email.it>."
*
* However, that header didn't work all that well - it left out some
* useful information - and was abandoned in favor of the DLT_USB_LINUX
* header.
*
* This is now used by FreeBSD for its BPF taps for USB; that has its
* own headers. So it is written, so it is done.
*/
#define LINKTYPE_USB 186
#define LINKTYPE_USB_FREEBSD 186
/*
* Bluetooth HCI UART transport layer (part H:4); requested by
@ -478,7 +488,7 @@
/*
* Juniper-private data link type, as per request from
* Hannes Gredler <hannes@juniper.net>.
* Hannes Gredler <hannes@juniper.net>.
* The DLT_ is used for internal communication with a
* integrated service module (ISM).
*/
@ -519,7 +529,7 @@
/*
* Juniper-private data link type, as per request from
* Hannes Gredler <hannes@juniper.net>.
* Hannes Gredler <hannes@juniper.net>.
* The DLT_ is used for capturing data on a secure tunnel interface.
*/
#define LINKTYPE_JUNIPER_ST 200
@ -611,11 +621,11 @@
*/
#define LINKTYPE_IEEE802_15_4_NONASK_PHY 215
/*
/*
* David Gibson <david@gibson.dropbear.id.au> requested this for
* captures from the Linux kernel /dev/input/eventN devices. This
* is used to communicate keystrokes and mouse movements from the
* Linux kernel to display systems, such as Xorg.
* Linux kernel to display systems, such as Xorg.
*/
#define LINKTYPE_LINUX_EVDEV 216
@ -736,8 +746,10 @@
/*
* CAN (Controller Area Network) frames, with a pseudo-header as supplied
* by Linux SocketCAN. See Documentation/networking/can.txt in the Linux
* source.
* by Linux SocketCAN, and with multi-byte numerical fields in that header
* in big-endian byte order.
*
* See Documentation/networking/can.txt in the Linux source.
*
* Requested by Felix Obenhuber <felix@obenhuber.de>.
*/
@ -777,7 +789,7 @@
/*
* Juniper-private data link type, as per request from
* Hannes Gredler <hannes@juniper.net>.
* Hannes Gredler <hannes@juniper.net>.
*/
#define LINKTYPE_JUNIPER_VS 232
#define LINKTYPE_JUNIPER_SRX_E2E 233
@ -809,12 +821,12 @@
/*
* Juniper-private data link type, as per request from
* Hannes Gredler <hannes@juniper.net>.
* Hannes Gredler <hannes@juniper.net>.
*/
#define LINKTYPE_JUNIPER_ATM_CEMIC 238
/*
* NetFilter LOG messages
* NetFilter LOG messages
* (payload of netlink NFNL_SUBSYS_ULOG/NFULNL_MSG_PACKET packets)
*
* Requested by Jakub Zawadzki <darkjames-ws@darkjames.pl>
@ -922,7 +934,7 @@
/*
* Link-layer header type for upper-protocol layer PDU saves from wireshark.
*
*
* the actual contents are determined by two TAGs stored with each
* packet:
* EXP_PDU_TAG_LINKTYPE the link type (LINKTYPE_ value) of the
@ -959,7 +971,6 @@
*/
#define LINKTYPE_PROFIBUS_DL 257
/*
* Apple's DLT_PKTAP headers.
*
@ -994,7 +1005,30 @@
*/
#define LINKTYPE_IPMI_HPM_2 260
#define LINKTYPE_MATCHING_MAX 260 /* highest value in the "matching" range */
/*
* per Joshua Wright <jwright@hasborg.com>, formats for Zwave captures.
*/
#define LINKTYPE_ZWAVE_R1_R2 261
#define LINKTYPE_ZWAVE_R3 262
/*
* per Steve Karg <skarg@users.sourceforge.net>, formats for Wattstopper
* Digital Lighting Management room bus serial protocol captures.
*/
#define LINKTYPE_WATTSTOPPER_DLM 263
/*
* ISO 14443 contactless smart card messages.
*/
#define LINKTYPE_ISO_14443 264
/*
* Radio data system (RDS) groups. IEC 62106.
* Per Jonathan Brucker <jonathan.brucke@gmail.com>.
*/
#define LINKTYPE_RDS 265
#define LINKTYPE_MATCHING_MAX 265 /* highest value in the "matching" range */
static struct linktype_map {
int dlt;
@ -1141,6 +1175,48 @@ linktype_to_dlt(int linktype)
return linktype;
}
#define EXTRACT_
/*
* DLT_LINUX_SLL packets with a protocol type of LINUX_SLL_P_CAN or
* LINUX_SLL_P_CANFD have SocketCAN headers in front of the payload,
* with the CAN ID being in host byte order.
*
* When reading a DLT_LINUX_SLL capture file, we need to check for those
* packets and convert the CAN ID from the byte order of the host that
* wrote the file to this host's byte order.
*/
static void
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;
pcap_can_socketcan_hdr *chdr;
if (caplen < (u_int) sizeof(struct sll_header) ||
length < (u_int) sizeof(struct sll_header)) {
/* Not enough data to have the protocol field */
return;
}
protocol = EXTRACT_16BITS(&shdr->sll_protocol);
if (protocol != LINUX_SLL_P_CAN && protocol != LINUX_SLL_P_CANFD)
return;
/*
* SocketCAN packet; fix up the packet's header.
*/
chdr = (pcap_can_socketcan_hdr *)(buf + sizeof(struct sll_header));
if (caplen < (u_int) sizeof(struct sll_header) + sizeof(chdr->can_id) ||
length < (u_int) sizeof(struct sll_header) + sizeof(chdr->can_id)) {
/* Not enough data to have the CAN ID */
return;
}
chdr->can_id = SWAPLONG(chdr->can_id);
}
/*
* The DLT_USB_LINUX and DLT_USB_LINUX_MMAPPED headers are in host
* byte order when capturing (it's supplied directly from a
@ -1156,8 +1232,6 @@ swap_linux_usb_header(const struct pcap_pkthdr *hdr, u_char *buf,
{
pcap_usb_header_mmapped *uhdr = (pcap_usb_header_mmapped *)buf;
bpf_u_int32 offset = 0;
usb_isodesc *pisodesc;
int32_t numdesc, i;
/*
* "offset" is the offset *past* the field we're swapping;
@ -1166,7 +1240,7 @@ swap_linux_usb_header(const struct pcap_pkthdr *hdr, u_char *buf,
*/
/*
* The URB id is a totally opaque value; do we really need to
* The URB id is a totally opaque value; do we really need to
* convert it to the reading host's byte order???
*/
offset += 8; /* skip past id */
@ -1221,6 +1295,17 @@ swap_linux_usb_header(const struct pcap_pkthdr *hdr, u_char *buf,
} else
offset += 8; /* skip USB setup header */
/*
* With the old header, there are no isochronous descriptors
* after the header.
*
* With the new header, the actual number of descriptors in
* the header is not s.iso.numdesc, it's ndesc - only the
* first N descriptors, for some value of N, are put into
* the header, and ndesc is set to the actual number copied.
* In addition, if s.iso.numdesc is negative, no descriptors
* are captured, and ndesc is set to 0.
*/
if (header_len_64_bytes) {
/*
* This is either the "version 1" header, with
@ -1249,31 +1334,33 @@ swap_linux_usb_header(const struct pcap_pkthdr *hdr, u_char *buf,
if (hdr->caplen < offset)
return;
uhdr->ndesc = SWAPLONG(uhdr->ndesc);
}
if (uhdr->transfer_type == URB_ISOCHRONOUS) {
/* swap the values in struct linux_usb_isodesc */
pisodesc = (usb_isodesc *)(void *)(buf+offset);
numdesc = uhdr->s.iso.numdesc;
for (i = 0; i < numdesc; i++) {
offset += 4; /* skip past status */
if (hdr->caplen < offset)
return;
pisodesc->status = SWAPLONG(pisodesc->status);
if (uhdr->transfer_type == URB_ISOCHRONOUS) {
/* swap the values in struct linux_usb_isodesc */
usb_isodesc *pisodesc;
u_int32_t i;
offset += 4; /* skip past offset */
if (hdr->caplen < offset)
return;
pisodesc->offset = SWAPLONG(pisodesc->offset);
pisodesc = (usb_isodesc *)(void *)(buf+offset);
for (i = 0; i < uhdr->ndesc; i++) {
offset += 4; /* skip past status */
if (hdr->caplen < offset)
return;
pisodesc->status = SWAPLONG(pisodesc->status);
offset += 4; /* skip past len */
if (hdr->caplen < offset)
return;
pisodesc->len = SWAPLONG(pisodesc->len);
offset += 4; /* skip past offset */
if (hdr->caplen < offset)
return;
pisodesc->offset = SWAPLONG(pisodesc->offset);
offset += 4; /* skip past padding */
offset += 4; /* skip past len */
if (hdr->caplen < offset)
return;
pisodesc->len = SWAPLONG(pisodesc->len);
pisodesc++;
offset += 4; /* skip past padding */
pisodesc++;
}
}
}
}
@ -1299,12 +1386,13 @@ swap_nflog_header(const struct pcap_pkthdr *hdr, u_char *buf)
u_int length = hdr->len;
u_int16_t size;
if (caplen < (int) sizeof(nflog_hdr_t) || length < (int) sizeof(nflog_hdr_t)) {
if (caplen < (u_int) sizeof(nflog_hdr_t) ||
length < (u_int) sizeof(nflog_hdr_t)) {
/* Not enough data to have any TLVs. */
return;
}
if (!(nfhdr->nflog_version) == 0) {
if (nfhdr->nflog_version != 0) {
/* Unknown NFLOG version */
return;
}
@ -1354,6 +1442,10 @@ swap_pseudo_headers(int linktype, struct pcap_pkthdr *hdr, u_char *data)
*/
switch (linktype) {
case DLT_LINUX_SLL:
swap_linux_sll_header(hdr, data);
break;
case DLT_USB_LINUX:
swap_linux_usb_header(hdr, data, 0);
break;

View file

@ -18,7 +18,7 @@
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\"
.TH PCAP-CONFIG 1 "22 May 2009"
.TH PCAP-CONFIG 1 "15 February 2015"
.SH NAME
pcap-config \- write libpcap compiler and linker flags to standard output
.SH SYNOPSIS

View file

@ -1,5 +1,5 @@
/*
* pcap-dag.c: Packet capture interface for Endace DAG card.
* pcap-dag.c: Packet capture interface for Emulex EndaceDAG cards.
*
* The functionality of this code attempts to mimic that of pcap-linux as much
* as possible. This code is compiled in several different ways depending on
@ -10,9 +10,9 @@
* called as required from their pcap-linux/bpf equivalents.
*
* Authors: Richard Littin, Sean Irvine ({richard,sean}@reeltwo.com)
* Modifications: Jesper Peterson <support@endace.com>
* Koryn Grant <support@endace.com>
* Stephen Donnelly <support@endace.com>
* Modifications: Jesper Peterson
* Koryn Grant
* Stephen Donnelly <stephen.donnelly@emulex.com>
*/
#ifdef HAVE_CONFIG_H
@ -40,6 +40,7 @@ struct rtentry; /* declarations in <net/if.h> */
#include "dagnew.h"
#include "dagapi.h"
#include "dagpci.h"
#include "pcap-dag.h"
@ -52,6 +53,99 @@ struct rtentry; /* declarations in <net/if.h> */
#define DAG_MAX_BOARDS 32
#endif
#ifndef TYPE_AAL5
#define TYPE_AAL5 4
#endif
#ifndef TYPE_MC_HDLC
#define TYPE_MC_HDLC 5
#endif
#ifndef TYPE_MC_RAW
#define TYPE_MC_RAW 6
#endif
#ifndef TYPE_MC_ATM
#define TYPE_MC_ATM 7
#endif
#ifndef TYPE_MC_RAW_CHANNEL
#define TYPE_MC_RAW_CHANNEL 8
#endif
#ifndef TYPE_MC_AAL5
#define TYPE_MC_AAL5 9
#endif
#ifndef TYPE_COLOR_HDLC_POS
#define TYPE_COLOR_HDLC_POS 10
#endif
#ifndef TYPE_COLOR_ETH
#define TYPE_COLOR_ETH 11
#endif
#ifndef TYPE_MC_AAL2
#define TYPE_MC_AAL2 12
#endif
#ifndef TYPE_IP_COUNTER
#define TYPE_IP_COUNTER 13
#endif
#ifndef TYPE_TCP_FLOW_COUNTER
#define TYPE_TCP_FLOW_COUNTER 14
#endif
#ifndef TYPE_DSM_COLOR_HDLC_POS
#define TYPE_DSM_COLOR_HDLC_POS 15
#endif
#ifndef TYPE_DSM_COLOR_ETH
#define TYPE_DSM_COLOR_ETH 16
#endif
#ifndef TYPE_COLOR_MC_HDLC_POS
#define TYPE_COLOR_MC_HDLC_POS 17
#endif
#ifndef TYPE_AAL2
#define TYPE_AAL2 18
#endif
#ifndef TYPE_COLOR_HASH_POS
#define TYPE_COLOR_HASH_POS 19
#endif
#ifndef TYPE_COLOR_HASH_ETH
#define TYPE_COLOR_HASH_ETH 20
#endif
#ifndef TYPE_INFINIBAND
#define TYPE_INFINIBAND 21
#endif
#ifndef TYPE_IPV4
#define TYPE_IPV4 22
#endif
#ifndef TYPE_IPV6
#define TYPE_IPV6 23
#endif
#ifndef TYPE_RAW_LINK
#define TYPE_RAW_LINK 24
#endif
#ifndef TYPE_INFINIBAND_LINK
#define TYPE_INFINIBAND_LINK 25
#endif
#ifndef TYPE_PAD
#define TYPE_PAD 48
#endif
#define ATM_CELL_SIZE 52
#define ATM_HDR_SIZE 4
@ -143,28 +237,25 @@ delete_pcap_dag(pcap_t *p)
static void
dag_platform_cleanup(pcap_t *p)
{
struct pcap_dag *pd;
struct pcap_dag *pd = p->pr;
if (p != NULL) {
pd = p->priv;
#ifdef HAVE_DAG_STREAMS_API
if(dag_stop_stream(p->fd, pd->dag_stream) < 0)
fprintf(stderr,"dag_stop_stream: %s\n", strerror(errno));
if(dag_detach_stream(p->fd, pd->dag_stream) < 0)
fprintf(stderr,"dag_detach_stream: %s\n", strerror(errno));
if(dag_stop_stream(p->fd, pd->dag_stream) < 0)
fprintf(stderr,"dag_stop_stream: %s\n", strerror(errno));
if(dag_detach_stream(p->fd, pd->dag_stream) < 0)
fprintf(stderr,"dag_detach_stream: %s\n", strerror(errno));
#else
if(dag_stop(p->fd) < 0)
fprintf(stderr,"dag_stop: %s\n", strerror(errno));
if(dag_stop(p->fd) < 0)
fprintf(stderr,"dag_stop: %s\n", strerror(errno));
#endif /* HAVE_DAG_STREAMS_API */
if(p->fd != -1) {
if(dag_close(p->fd) < 0)
fprintf(stderr,"dag_close: %s\n", strerror(errno));
p->fd = -1;
}
delete_pcap_dag(p);
pcap_cleanup_live_common(p);
if(p->fd != -1) {
if(dag_close(p->fd) < 0)
fprintf(stderr,"dag_close: %s\n", strerror(errno));
p->fd = -1;
}
delete_pcap_dag(p);
pcap_cleanup_live_common(p);
/* Note: don't need to call close(p->fd) here as dag_close(p->fd) does this. */
}
@ -173,7 +264,8 @@ atexit_handler(void)
{
while (pcap_dags != NULL) {
if (pcap_dags->pid == getpid()) {
dag_platform_cleanup(pcap_dags->p);
if (pcap_dags->p != NULL)
dag_platform_cleanup(pcap_dags->p);
} else {
delete_pcap_dag(pcap_dags->p);
}
@ -221,7 +313,7 @@ dag_erf_ext_header_count(uint8_t * erf, size_t len)
/* loop over the extension headers */
do {
/* sanity check we have enough bytes */
if ( len < (24 + (hdr_num * 8)) )
return hdr_num;
@ -248,10 +340,11 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
int flags = pd->dag_offset_flags;
unsigned int nonblocking = flags & DAGF_NONBLOCK;
unsigned int num_ext_hdr = 0;
unsigned int ticks_per_second;
/* Get the next bufferful of packets (if necessary). */
while (pd->dag_mem_top - pd->dag_mem_bottom < dag_record_size) {
/*
* Has "pcap_breakloop()" been called?
*/
@ -290,7 +383,7 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
/* Pcap is configured to process only available packets, and there aren't any, return immediately. */
return 0;
}
if(!nonblocking &&
pd->dag_timeout &&
(pd->dag_mem_top - pd->dag_mem_bottom < dag_record_size))
@ -300,14 +393,14 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
}
}
/* Process the packets. */
while (pd->dag_mem_top - pd->dag_mem_bottom >= dag_record_size) {
unsigned short packet_len = 0;
int caplen = 0;
struct pcap_pkthdr pcap_header;
#ifdef HAVE_DAG_STREAMS_API
dag_record_t *header = (dag_record_t *)(pd->dag_mem_bottom);
#else
@ -316,7 +409,7 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
u_char *dp = ((u_char *)header); /* + dag_record_size; */
unsigned short rlen;
/*
* Has "pcap_breakloop()" been called?
*/
@ -329,7 +422,7 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
p->break_loop = 0;
return -2;
}
rlen = ntohs(header->rlen);
if (rlen < dag_record_size)
{
@ -359,7 +452,7 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
}
}
}
if ((header->type & 0x7f) == TYPE_PAD) {
continue;
}
@ -367,13 +460,13 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
num_ext_hdr = dag_erf_ext_header_count(dp, rlen);
/* ERF encapsulation */
/* The Extensible Record Format is not dropped for this kind of encapsulation,
/* The Extensible Record Format is not dropped for this kind of encapsulation,
* and will be handled as a pseudo header by the decoding application.
* The information carried in the ERF header and in the optional subheader (if present)
* could be merged with the libpcap information, to offer a better decoding.
* The packet length is
* o the length of the packet on the link (header->wlen),
* o plus the length of the ERF header (dag_record_size), as the length of the
* o plus the length of the ERF header (dag_record_size), as the length of the
* pseudo header will be adjusted during the decoding,
* o plus the length of the optional subheader (if present).
*
@ -415,7 +508,7 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
dp += dag_record_size;
/* Skip over extension headers */
dp += 8 * num_ext_hdr;
switch((header->type & 0x7f)) {
case TYPE_ATM:
case TYPE_AAL5:
@ -434,19 +527,22 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
caplen = rlen - dag_record_size - 4;
dp+=4;
}
/* Skip over extension headers */
caplen -= (8 * num_ext_hdr);
if (header->type == TYPE_ATM) {
caplen = packet_len = ATM_CELL_SIZE;
}
if (p->linktype == DLT_SUNATM) {
struct sunatm_hdr *sunatm = (struct sunatm_hdr *)dp;
unsigned long rawatm;
rawatm = ntohl(*((unsigned long *)dp));
sunatm->vci = htons((rawatm >> 4) & 0xffff);
sunatm->vpi = (rawatm >> 20) & 0x00ff;
sunatm->flags = ((header->flags.iface & 1) ? 0x80 : 0x00) |
sunatm->flags = ((header->flags.iface & 1) ? 0x80 : 0x00) |
((sunatm->vpi == 0 && sunatm->vci == htons(5)) ? 6 :
((sunatm->vpi == 0 && sunatm->vci == htons(16)) ? 5 :
((sunatm->vpi == 0 && sunatm->vci == htons(16)) ? 5 :
((dp[ATM_HDR_SIZE] == 0xaa &&
dp[ATM_HDR_SIZE+1] == 0xaa &&
dp[ATM_HDR_SIZE+2] == 0x03) ? 2 : 1)));
@ -465,6 +561,8 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
packet_len = ntohs(header->wlen);
packet_len -= (pd->dag_fcs_bits >> 3);
caplen = rlen - dag_record_size - 2;
/* Skip over extension headers */
caplen -= (8 * num_ext_hdr);
if (caplen > packet_len) {
caplen = packet_len;
}
@ -478,6 +576,8 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
packet_len = ntohs(header->wlen);
packet_len -= (pd->dag_fcs_bits >> 3);
caplen = rlen - dag_record_size;
/* Skip over extension headers */
caplen -= (8 * num_ext_hdr);
if (caplen > packet_len) {
caplen = packet_len;
}
@ -488,6 +588,8 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
packet_len = ntohs(header->wlen);
packet_len -= (pd->dag_fcs_bits >> 3);
caplen = rlen - dag_record_size - 4;
/* Skip over extension headers */
caplen -= (8 * num_ext_hdr);
if (caplen > packet_len) {
caplen = packet_len;
}
@ -498,7 +600,7 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
/* Add the MTP2 Pseudo Header */
caplen += MTP2_HDR_LEN;
packet_len += MTP2_HDR_LEN;
TempPkt[MTP2_SENT_OFFSET] = 0;
TempPkt[MTP2_ANNEX_A_USED_OFFSET] = MTP2_ANNEX_A_USED_UNKNOWN;
*(TempPkt+MTP2_LINK_NUMBER_OFFSET) = ((header->rec.mc_hdlc.mc_header>>16)&0x01);
@ -513,6 +615,8 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
case TYPE_IPV6:
packet_len = ntohs(header->wlen);
caplen = rlen - dag_record_size;
/* Skip over extension headers */
caplen -= (8 * num_ext_hdr);
if (caplen > packet_len) {
caplen = packet_len;
}
@ -533,45 +637,52 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
continue;
} /* switch type */
/* Skip over extension headers */
caplen -= (8 * num_ext_hdr);
} /* ERF encapsulation */
if (caplen > p->snapshot)
caplen = p->snapshot;
/* Run the packet filter if there is one. */
if ((p->fcode.bf_insns == NULL) || bpf_filter(p->fcode.bf_insns, dp, packet_len, caplen)) {
/* convert between timestamp formats */
register unsigned long long ts;
if (IS_BIGENDIAN()) {
ts = SWAPLL(header->ts);
} else {
ts = header->ts;
}
switch (p->opt.tstamp_precision) {
case PCAP_TSTAMP_PRECISION_NANO:
ticks_per_second = 1000000000;
break;
case PCAP_TSTAMP_PRECISION_MICRO:
default:
ticks_per_second = 1000000;
break;
}
pcap_header.ts.tv_sec = ts >> 32;
ts = (ts & 0xffffffffULL) * 1000000;
ts = (ts & 0xffffffffULL) * ticks_per_second;
ts += 0x80000000; /* rounding */
pcap_header.ts.tv_usec = ts >> 32;
if (pcap_header.ts.tv_usec >= 1000000) {
pcap_header.ts.tv_usec -= 1000000;
pcap_header.ts.tv_usec = ts >> 32;
if (pcap_header.ts.tv_usec >= ticks_per_second) {
pcap_header.ts.tv_usec -= ticks_per_second;
pcap_header.ts.tv_sec++;
}
/* Fill in our own header data */
pcap_header.caplen = caplen;
pcap_header.len = packet_len;
/* Count the packet. */
pd->stat.ps_recv++;
/* Call the user supplied callback function */
callback(user, &pcap_header, dp);
/* Only count packets that pass the filter, for consistency with standard Linux behaviour. */
processed++;
if (processed == cnt && !PACKET_COUNT_IS_UNLIMITED(cnt))
@ -598,7 +709,7 @@ dag_inject(pcap_t *p, const void *buf _U_, size_t size _U_)
* device will result in a failure. The promisc flag is ignored because DAG
* cards are always promiscuous. The to_ms parameter is used in setting the
* API polling parameters.
*
*
* snaplen is now also ignored, until we get per-stream slen support. Set
* slen with approprite DAG tool BEFORE pcap_activate().
*
@ -614,7 +725,7 @@ static int dag_activate(pcap_t* handle)
int n;
daginf_t* daginf;
char * newDev = NULL;
char * device = handle->opt.source;
char * device = handle->opt.device;
#ifdef HAVE_DAG_STREAMS_API
uint32_t mindata;
struct timeval maxwait;
@ -622,7 +733,7 @@ static int dag_activate(pcap_t* handle)
#endif
if (device == NULL) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "device is NULL: %s", pcap_strerror(errno));
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "device is NULL: %s", pcap_strerror(errno));
return -1;
}
@ -631,26 +742,26 @@ static int dag_activate(pcap_t* handle)
#ifdef HAVE_DAG_STREAMS_API
newDev = (char *)malloc(strlen(device) + 16);
if (newDev == NULL) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't allocate string for device name: %s\n", pcap_strerror(errno));
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't allocate string for device name: %s", pcap_strerror(errno));
goto fail;
}
/* Parse input name to get dag device and stream number if provided */
if (dag_parse_name(device, newDev, strlen(device) + 16, &handlep->dag_stream) < 0) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_parse_name: %s\n", pcap_strerror(errno));
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_parse_name: %s", pcap_strerror(errno));
goto fail;
}
device = newDev;
if (handlep->dag_stream%2) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_parse_name: tx (even numbered) streams not supported for capture\n");
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_parse_name: tx (even numbered) streams not supported for capture");
goto fail;
}
#else
if (strncmp(device, "/dev/", 5) != 0) {
newDev = (char *)malloc(strlen(device) + 5);
if (newDev == NULL) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't allocate string for device name: %s\n", pcap_strerror(errno));
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't allocate string for device name: %s", pcap_strerror(errno));
goto fail;
}
strcpy(newDev, "/dev/");
@ -661,14 +772,14 @@ static int dag_activate(pcap_t* handle)
/* setup device parameters */
if((handle->fd = dag_open((char *)device)) < 0) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_open %s: %s", device, pcap_strerror(errno));
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_open %s: %s", device, pcap_strerror(errno));
goto fail;
}
#ifdef HAVE_DAG_STREAMS_API
/* Open requested stream. Can fail if already locked or on error */
if (dag_attach_stream(handle->fd, handlep->dag_stream, 0, 0) < 0) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_attach_stream: %s\n", pcap_strerror(errno));
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_attach_stream: %s", pcap_strerror(errno));
goto failclose;
}
@ -677,10 +788,10 @@ static int dag_activate(pcap_t* handle)
*/
if (dag_get_stream_poll(handle->fd, handlep->dag_stream,
&mindata, &maxwait, &poll) < 0) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_get_stream_poll: %s\n", pcap_strerror(errno));
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_get_stream_poll: %s", pcap_strerror(errno));
goto faildetach;
}
if (handle->opt.immediate) {
/* Call callback immediately.
* XXX - is this the right way to handle this?
@ -702,13 +813,13 @@ static int dag_activate(pcap_t* handle)
if (dag_set_stream_poll(handle->fd, handlep->dag_stream,
mindata, &maxwait, &poll) < 0) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_set_stream_poll: %s\n", pcap_strerror(errno));
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_set_stream_poll: %s", pcap_strerror(errno));
goto faildetach;
}
#else
if((handlep->dag_mem_base = dag_mmap(handle->fd)) == MAP_FAILED) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,"dag_mmap %s: %s\n", device, pcap_strerror(errno));
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,"dag_mmap %s: %s", device, pcap_strerror(errno));
goto failclose;
}
@ -728,22 +839,22 @@ static int dag_activate(pcap_t* handle)
handle->snapshot = MIN_DAG_SNAPLEN;
}
/* snap len has to be a multiple of 4 */
snprintf(conf, 30, "varlen slen=%d", (snaplen + 3) & ~3);
pcap_snprintf(conf, 30, "varlen slen=%d", (snaplen + 3) & ~3);
if(dag_configure(handle->fd, conf) < 0) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,"dag_configure %s: %s\n", device, pcap_strerror(errno));
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,"dag_configure %s: %s", device, pcap_strerror(errno));
goto faildetach;
}
#endif
#endif
#ifdef HAVE_DAG_STREAMS_API
if(dag_start_stream(handle->fd, handlep->dag_stream) < 0) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_start_stream %s: %s\n", device, pcap_strerror(errno));
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_start_stream %s: %s", device, pcap_strerror(errno));
goto faildetach;
}
#else
if(dag_start(handle->fd) < 0) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_start %s: %s\n", device, pcap_strerror(errno));
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_start %s: %s", device, pcap_strerror(errno));
goto failclose;
}
#endif /* HAVE_DAG_STREAMS_API */
@ -778,8 +889,8 @@ static int dag_activate(pcap_t* handle)
if ((n = atoi(s)) == 0 || n == 16 || n == 32) {
handlep->dag_fcs_bits = n;
} else {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"pcap_activate %s: bad ERF_FCS_BITS value (%d) in environment\n", device, n);
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"pcap_activate %s: bad ERF_FCS_BITS value (%d) in environment", device, n);
goto failstop;
}
}
@ -802,11 +913,11 @@ static int dag_activate(pcap_t* handle)
handle->linktype = -1;
if (dag_get_datalink(handle) < 0)
goto failstop;
handle->bufsize = 0;
if (new_pcap_dag(handle) < 0) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "new_pcap_dag %s: %s\n", device, pcap_strerror(errno));
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "new_pcap_dag %s: %s", device, pcap_strerror(errno));
goto failstop;
}
@ -833,12 +944,12 @@ static int dag_activate(pcap_t* handle)
handlep->stat.ps_ifdrop = 0;
return 0;
#ifdef HAVE_DAG_STREAMS_API
#ifdef HAVE_DAG_STREAMS_API
failstop:
if (dag_stop_stream(handle->fd, handlep->dag_stream) < 0) {
fprintf(stderr,"dag_stop_stream: %s\n", strerror(errno));
}
faildetach:
if (dag_detach_stream(handle->fd, handlep->dag_stream) < 0)
fprintf(stderr,"dag_detach_stream: %s\n", strerror(errno));
@ -847,7 +958,7 @@ static int dag_activate(pcap_t* handle)
if (dag_stop(handle->fd) < 0)
fprintf(stderr,"dag_stop: %s\n", strerror(errno));
#endif /* HAVE_DAG_STREAMS_API */
failclose:
if (dag_close(handle->fd) < 0)
fprintf(stderr,"dag_close: %s\n", strerror(errno));
@ -912,11 +1023,29 @@ pcap_t *dag_create(const char *device, char *ebuf, int *is_ours)
/* OK, it's probably ours. */
*is_ours = 1;
p = pcap_create_common(device, ebuf, sizeof (struct pcap_dag));
p = pcap_create_common(ebuf, sizeof (struct pcap_dag));
if (p == NULL)
return NULL;
p->activate_op = dag_activate;
/*
* We claim that we support microsecond and nanosecond time
* stamps.
*
* XXX Our native precision is 2^-32s, but libpcap doesn't support
* power of two precisions yet. We can convert to either MICRO or NANO.
*/
p->tstamp_precision_count = 2;
p->tstamp_precision_list = malloc(2 * sizeof(u_int));
if (p->tstamp_precision_list == NULL) {
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
pcap_strerror(errno));
pcap_close(p);
return NULL;
}
p->tstamp_precision_list[0] = PCAP_TSTAMP_PRECISION_MICRO;
p->tstamp_precision_list[1] = PCAP_TSTAMP_PRECISION_NANO;
return p;
}
@ -929,9 +1058,9 @@ dag_stats(pcap_t *p, struct pcap_stat *ps) {
*/
/*pd->stat.ps_recv = 0;*/
/*pd->stat.ps_drop = 0;*/
*ps = pd->stat;
return 0;
}
@ -953,16 +1082,21 @@ dag_findalldevs(pcap_if_t **devlistp, char *errbuf)
char dagname[DAGNAME_BUFSIZE];
int dagstream;
int dagfd;
dag_card_inf_t *inf;
char *description;
/* Try all the DAGs 0-DAG_MAX_BOARDS */
for (c = 0; c < DAG_MAX_BOARDS; c++) {
snprintf(name, 12, "dag%d", c);
pcap_snprintf(name, 12, "dag%d", c);
if (-1 == dag_parse_name(name, dagname, DAGNAME_BUFSIZE, &dagstream))
{
return -1;
}
description = NULL;
if ( (dagfd = dag_open(dagname)) >= 0 ) {
if (pcap_add_if(devlistp, name, 0, NULL, errbuf) == -1) {
if ((inf = dag_pciinfo(dagfd)))
description = dag_device_name(inf->device_code, 1);
if (pcap_add_if(devlistp, name, 0, description, errbuf) == -1) {
/*
* Failure.
*/
@ -976,20 +1110,20 @@ dag_findalldevs(pcap_if_t **devlistp, char *errbuf)
if (0 == dag_attach_stream(dagfd, stream, 0, 0)) {
dag_detach_stream(dagfd, stream);
snprintf(name, 10, "dag%d:%d", c, stream);
if (pcap_add_if(devlistp, name, 0, NULL, errbuf) == -1) {
pcap_snprintf(name, 10, "dag%d:%d", c, stream);
if (pcap_add_if(devlistp, name, 0, description, errbuf) == -1) {
/*
* Failure.
*/
ret = -1;
}
rxstreams--;
if(rxstreams <= 0) {
break;
}
}
}
}
}
#endif /* HAVE_DAG_STREAMS_API */
dag_close(dagfd);
@ -1049,13 +1183,13 @@ dag_setnonblock(pcap_t *p, int nonblock, char *errbuf)
uint32_t mindata;
struct timeval maxwait;
struct timeval poll;
if (dag_get_stream_poll(p->fd, pd->dag_stream,
&mindata, &maxwait, &poll) < 0) {
snprintf(errbuf, PCAP_ERRBUF_SIZE, "dag_get_stream_poll: %s\n", pcap_strerror(errno));
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "dag_get_stream_poll: %s", pcap_strerror(errno));
return -1;
}
/* Amount of data to collect in Bytes before calling callbacks.
* Important for efficiency, but can introduce latency
* at low packet rates if to_ms not set!
@ -1064,10 +1198,10 @@ dag_setnonblock(pcap_t *p, int nonblock, char *errbuf)
mindata = 0;
else
mindata = 65536;
if (dag_set_stream_poll(p->fd, pd->dag_stream,
mindata, &maxwait, &poll) < 0) {
snprintf(errbuf, PCAP_ERRBUF_SIZE, "dag_set_stream_poll: %s\n", pcap_strerror(errno));
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "dag_set_stream_poll: %s", pcap_strerror(errno));
return -1;
}
}
@ -1079,7 +1213,7 @@ dag_setnonblock(pcap_t *p, int nonblock, char *errbuf)
}
return (0);
}
static int
dag_get_datalink(pcap_t *p)
{
@ -1090,7 +1224,7 @@ dag_get_datalink(pcap_t *p)
memset(types, 0, 255);
if (p->dlt_list == NULL && (p->dlt_list = malloc(255*sizeof(*(p->dlt_list)))) == NULL) {
(void)snprintf(p->errbuf, sizeof(p->errbuf), "malloc: %s", pcap_strerror(errno));
(void)pcap_snprintf(p->errbuf, sizeof(p->errbuf), "malloc: %s", pcap_strerror(errno));
return (-1);
}
@ -1099,19 +1233,19 @@ dag_get_datalink(pcap_t *p)
#ifdef HAVE_DAG_GET_STREAM_ERF_TYPES
/* Get list of possible ERF types for this card */
if (dag_get_stream_erf_types(p->fd, pd->dag_stream, types, 255) < 0) {
snprintf(p->errbuf, sizeof(p->errbuf), "dag_get_stream_erf_types: %s", pcap_strerror(errno));
return (-1);
pcap_snprintf(p->errbuf, sizeof(p->errbuf), "dag_get_stream_erf_types: %s", pcap_strerror(errno));
return (-1);
}
while (types[index]) {
#elif defined HAVE_DAG_GET_ERF_TYPES
/* Get list of possible ERF types for this card */
if (dag_get_erf_types(p->fd, types, 255) < 0) {
snprintf(p->errbuf, sizeof(p->errbuf), "dag_get_erf_types: %s", pcap_strerror(errno));
return (-1);
pcap_snprintf(p->errbuf, sizeof(p->errbuf), "dag_get_erf_types: %s", pcap_strerror(errno));
return (-1);
}
while (types[index]) {
#else
/* Check the type through a dagapi call. */
@ -1157,7 +1291,7 @@ dag_get_datalink(pcap_t *p)
p->linktype = DLT_EN10MB;
break;
case TYPE_ATM:
case TYPE_ATM:
case TYPE_AAL5:
case TYPE_MC_ATM:
case TYPE_MC_AAL5:
@ -1215,3 +1349,31 @@ dag_get_datalink(pcap_t *p)
return p->linktype;
}
#ifdef DAG_ONLY
/*
* This libpcap build supports only DAG cards, not regular network
* interfaces.
*/
/*
* There are no regular interfaces, just DAG interfaces.
*/
int
pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
{
*alldevsp = NULL;
return (0);
}
/*
* Attempts to open a regular interface fail.
*/
pcap_t *
pcap_create_interface(const char *device, char *errbuf)
{
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"This version of libpcap only supports DAG cards");
return NULL;
}
#endif

View file

@ -10,97 +10,3 @@
pcap_t *dag_create(const char *, char *, int *);
int dag_findalldevs(pcap_if_t **devlistp, char *errbuf);
#ifndef TYPE_AAL5
#define TYPE_AAL5 4
#endif
#ifndef TYPE_MC_HDLC
#define TYPE_MC_HDLC 5
#endif
#ifndef TYPE_MC_RAW
#define TYPE_MC_RAW 6
#endif
#ifndef TYPE_MC_ATM
#define TYPE_MC_ATM 7
#endif
#ifndef TYPE_MC_RAW_CHANNEL
#define TYPE_MC_RAW_CHANNEL 8
#endif
#ifndef TYPE_MC_AAL5
#define TYPE_MC_AAL5 9
#endif
#ifndef TYPE_COLOR_HDLC_POS
#define TYPE_COLOR_HDLC_POS 10
#endif
#ifndef TYPE_COLOR_ETH
#define TYPE_COLOR_ETH 11
#endif
#ifndef TYPE_MC_AAL2
#define TYPE_MC_AAL2 12
#endif
#ifndef TYPE_IP_COUNTER
#define TYPE_IP_COUNTER 13
#endif
#ifndef TYPE_TCP_FLOW_COUNTER
#define TYPE_TCP_FLOW_COUNTER 14
#endif
#ifndef TYPE_DSM_COLOR_HDLC_POS
#define TYPE_DSM_COLOR_HDLC_POS 15
#endif
#ifndef TYPE_DSM_COLOR_ETH
#define TYPE_DSM_COLOR_ETH 16
#endif
#ifndef TYPE_COLOR_MC_HDLC_POS
#define TYPE_COLOR_MC_HDLC_POS 17
#endif
#ifndef TYPE_AAL2
#define TYPE_AAL2 18
#endif
#ifndef TYPE_COLOR_HASH_POS
#define TYPE_COLOR_HASH_POS 19
#endif
#ifndef TYPE_COLOR_HASH_ETH
#define TYPE_COLOR_HASH_ETH 20
#endif
#ifndef TYPE_INFINIBAND
#define TYPE_INFINIBAND 21
#endif
#ifndef TYPE_IPV4
#define TYPE_IPV4 22
#endif
#ifndef TYPE_IPV6
#define TYPE_IPV6 23
#endif
#ifndef TYPE_RAW_LINK
#define TYPE_RAW_LINK 24
#endif
#ifndef TYPE_INFINIBAND_LINK
#define TYPE_INFINIBAND_LINK 25
#endif
#ifndef TYPE_PAD
#define TYPE_PAD 48
#endif

View file

@ -11,8 +11,8 @@
* 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
* 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
@ -66,9 +66,9 @@ dbus_read(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user)
message = dbus_connection_pop_message(handlep->conn);
while (!message) {
// XXX handle->opt.timeout = timeout_ms;
/* XXX handle->opt.timeout = timeout_ms; */
if (!dbus_connection_read_write(handlep->conn, 100)) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Connection closed");
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Connection closed");
return -1;
}
@ -81,7 +81,7 @@ dbus_read(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user)
}
if (dbus_message_is_signal(message, DBUS_INTERFACE_LOCAL, "Disconnected")) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Disconnected");
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Disconnected");
return -1;
}
@ -112,7 +112,7 @@ dbus_write(pcap_t *handle, const void *buf, size_t size)
DBusMessage *msg;
if (!(msg = dbus_message_demarshal(buf, size, &error))) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dbus_message_demarshal() failed: %s", error.message);
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dbus_message_demarshal() failed: %s", error.message);
dbus_error_free(&error);
return -1;
}
@ -122,7 +122,7 @@ dbus_write(pcap_t *handle, const void *buf, size_t size)
dbus_message_unref(msg);
return 0;
}
}
static int
dbus_stats(pcap_t *handle, struct pcap_stat *stats)
@ -160,21 +160,21 @@ dbus_activate(pcap_t *handle)
#define N_RULES sizeof(rules)/sizeof(rules[0])
struct pcap_dbus *handlep = handle->priv;
const char *dev = handle->opt.source;
const char *dev = handle->opt.device;
DBusError error = DBUS_ERROR_INIT;
int i;
u_int i;
if (strcmp(dev, "dbus-system") == 0) {
if (!(handlep->conn = dbus_bus_get(DBUS_BUS_SYSTEM, &error))) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Failed to get system bus: %s", error.message);
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Failed to get system bus: %s", error.message);
dbus_error_free(&error);
return PCAP_ERROR;
}
} else if (strcmp(dev, "dbus-session") == 0) {
if (!(handlep->conn = dbus_bus_get(DBUS_BUS_SESSION, &error))) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Failed to get session bus: %s", error.message);
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Failed to get session bus: %s", error.message);
dbus_error_free(&error);
return PCAP_ERROR;
}
@ -183,19 +183,19 @@ dbus_activate(pcap_t *handle)
const char *addr = dev + 7;
if (!(handlep->conn = dbus_connection_open(addr, &error))) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Failed to open connection to: %s: %s", addr, error.message);
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Failed to open connection to: %s: %s", addr, error.message);
dbus_error_free(&error);
return PCAP_ERROR;
}
if (!dbus_bus_register(handlep->conn, &error)) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Failed to register bus %s: %s\n", addr, error.message);
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Failed to register bus %s: %s\n", addr, error.message);
dbus_error_free(&error);
return PCAP_ERROR;
}
} else {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't get bus address from %s", handle->opt.source);
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't get bus address from %s", handle->opt.device);
return PCAP_ERROR;
}
@ -234,7 +234,7 @@ dbus_activate(pcap_t *handle)
/* try without eavesdrop */
dbus_bus_add_match(handlep->conn, rules[i] + strlen(EAVESDROPPING_RULE), &error);
if (dbus_error_is_set(&error)) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Failed to add bus match: %s\n", error.message);
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Failed to add bus match: %s\n", error.message);
dbus_error_free(&error);
dbus_cleanup(handle);
return PCAP_ERROR;
@ -250,8 +250,8 @@ dbus_create(const char *device, char *ebuf, int *is_ours)
{
pcap_t *p;
if (strcmp(device, "dbus-system") &&
strcmp(device, "dbus-session") &&
if (strcmp(device, "dbus-system") &&
strcmp(device, "dbus-session") &&
strncmp(device, "dbus://", 7))
{
*is_ours = 0;
@ -259,7 +259,7 @@ dbus_create(const char *device, char *ebuf, int *is_ours)
}
*is_ours = 1;
p = pcap_create_common(device, ebuf, sizeof (struct pcap_dbus));
p = pcap_create_common(ebuf, sizeof (struct pcap_dbus));
if (p == NULL)
return (NULL);
@ -267,7 +267,7 @@ dbus_create(const char *device, char *ebuf, int *is_ours)
return (p);
}
int
int
dbus_findalldevs(pcap_if_t **alldevsp, char *err_str)
{
if (pcap_add_if(alldevsp, "dbus-system", 0, "D-Bus system bus", err_str) < 0)

View file

@ -153,10 +153,12 @@ static void dlpassive(int, char *);
static int dlrawdatareq(int, const u_char *, int);
#endif
static int recv_ack(int, int, const char *, char *, char *, int *);
static char *dlstrerror(bpf_u_int32);
static char *dlprim(bpf_u_int32);
static char *dlstrerror(char *, size_t, bpf_u_int32);
static char *dlprim(char *, size_t, bpf_u_int32);
#if defined(HAVE_SOLARIS) && defined(HAVE_SYS_BUFMOD_H)
static char *get_release(bpf_u_int32 *, bpf_u_int32 *, bpf_u_int32 *);
#define GET_RELEASE_BUFSIZE 32
static void get_release(char *, size_t, bpf_u_int32 *, bpf_u_int32 *,
bpf_u_int32 *);
#endif
static int send_request(int, char *, int, char *, char *);
#ifdef HAVE_HPUX9
@ -166,14 +168,6 @@ static int dlpi_kread(int, off_t, void *, u_int, char *);
static int get_dlpi_ppa(int, const char *, int, char *);
#endif
/* XXX Needed by HP-UX (at least) */
static bpf_u_int32 ctlbuf[MAXDLBUF];
static struct strbuf ctl = {
MAXDLBUF,
0,
(char *)ctlbuf
};
/*
* Cast a buffer to "union DL_primitives" without provoking warnings
* from the compiler.
@ -186,6 +180,12 @@ pcap_read_dlpi(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
int cc;
u_char *bp;
int flags;
bpf_u_int32 ctlbuf[MAXDLBUF];
struct strbuf ctl = {
MAXDLBUF,
0,
(char *)ctlbuf
};
struct strbuf data;
flags = 0;
@ -213,6 +213,9 @@ pcap_read_dlpi(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
* would be DL_HP_RAWDATA_IND on HP-UX
* if we're in raw mode?
*/
ctl.buf = (char *)ctlbuf;
ctl.maxlen = MAXDLBUF;
ctl.len = 0;
if (getmsg(p->fd, &ctl, &data, &flags) < 0) {
/* Don't choke when we get ptraced */
switch (errno) {
@ -230,7 +233,7 @@ pcap_read_dlpi(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
}
cc = data.len;
} while (cc == 0);
bp = p->buffer + p->offset;
bp = (u_char *)p->buffer + p->offset;
} else
bp = p->bp;
@ -248,19 +251,19 @@ pcap_inject_dlpi(pcap_t *p, const void *buf, size_t size)
#if defined(DLIOCRAW)
ret = write(p->fd, buf, size);
if (ret == -1) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
pcap_strerror(errno));
return (-1);
}
#elif defined(DL_HP_RAWDLS)
if (pd->send_fd < 0) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"send: Output FD couldn't be opened");
return (-1);
}
ret = dlrawdatareq(pd->send_fd, buf, size);
if (ret == -1) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
pcap_strerror(errno));
return (-1);
}
@ -298,7 +301,7 @@ pcap_inject_dlpi(pcap_t *p, const void *buf, size_t size)
ret = -1;
#endif /* raw mode */
return (ret);
}
}
#ifndef DL_IPATM
#define DL_IPATM 0x12 /* ATM Classical IP interface */
@ -331,28 +334,12 @@ pcap_cleanup_dlpi(pcap_t *p)
}
static int
pcap_activate_dlpi(pcap_t *p)
open_dlpi_device(const char *name, int *ppa, char *errbuf)
{
#ifdef DL_HP_RAWDLS
struct pcap_dlpi *pd = p->priv;
#endif
int status = 0;
int retv;
register char *cp;
int ppa;
#ifdef HAVE_SOLARIS
int isatm = 0;
#endif
register dl_info_ack_t *infop;
#ifdef HAVE_SYS_BUFMOD_H
bpf_u_int32 ss;
#ifdef HAVE_SOLARIS
register char *release;
bpf_u_int32 osmajor, osminor, osmicro;
#endif
#endif
bpf_u_int32 buf[MAXDLBUF];
int status;
char dname[100];
char *cp;
int fd;
#ifndef HAVE_DEV_DLPI
char dname2[100];
#endif
@ -361,9 +348,9 @@ pcap_activate_dlpi(pcap_t *p)
/*
** Remove any "/dev/" on the front of the device.
*/
cp = strrchr(p->opt.source, '/');
cp = strrchr(name, '/');
if (cp == NULL)
strlcpy(dname, p->opt.source, sizeof(dname));
strlcpy(dname, name, sizeof(dname));
else
strlcpy(dname, cp + 1, sizeof(dname));
@ -371,11 +358,9 @@ pcap_activate_dlpi(pcap_t *p)
* 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, p->errbuf);
if (cp == NULL) {
status = PCAP_ERROR_NO_SUCH_DEVICE;
goto bad;
}
cp = split_dname(dname, ppa, errbuf);
if (cp == NULL)
return (PCAP_ERROR_NO_SUCH_DEVICE);
*cp = '\0';
/*
@ -390,13 +375,137 @@ pcap_activate_dlpi(pcap_t *p)
* device number, rather than hardwiring "/dev/dlpi".
*/
cp = "/dev/dlpi";
if ((p->fd = open(cp, O_RDWR)) < 0) {
if ((fd = open(cp, O_RDWR)) < 0) {
if (errno == EPERM || errno == EACCES)
status = PCAP_ERROR_PERM_DENIED;
else
status = PCAP_ERROR;
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"%s: %s", cp, pcap_strerror(errno));
return (status);
}
/*
* 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) {
close(fd);
return (*ppa);
}
#else
/*
* If the device name begins with "/", assume it begins with
* the pathname of the directory containing the device to open;
* otherwise, concatenate the device directory name and the
* device name.
*/
if (*name == '/')
strlcpy(dname, name, sizeof(dname));
else
pcap_snprintf(dname, sizeof(dname), "%s/%s", PCAP_DEV_PREFIX,
name);
/*
* Get the unit number, and a pointer to the end of the device
* type name.
*/
cp = split_dname(dname, ppa, errbuf);
if (cp == NULL)
return (PCAP_ERROR_NO_SUCH_DEVICE);
/*
* Make a copy of the device pathname, and then remove the unit
* number from the device pathname.
*/
strlcpy(dname2, dname, sizeof(dname));
*cp = '\0';
/* Try device without unit number */
if ((fd = open(dname, O_RDWR)) < 0) {
if (errno != ENOENT) {
if (errno == EPERM || errno == EACCES)
status = PCAP_ERROR_PERM_DENIED;
else
status = PCAP_ERROR;
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", dname,
pcap_strerror(errno));
return (status);
}
/* Try again with unit number */
if ((fd = open(dname2, O_RDWR)) < 0) {
if (errno == ENOENT) {
status = PCAP_ERROR_NO_SUCH_DEVICE;
/*
* We provide an error message even
* for this error, for diagnostic
* purposes (so that, for example,
* the app can show the message if the
* user requests it).
*
* In it, we just report "No DLPI device
* found" with the device name, so people
* don't get confused and think, for example,
* that if they can't capture on "lo0"
* on Solaris prior to Solaris 11 the fix
* is to change libpcap (or the application
* that uses it) to look for something other
* than "/dev/lo0", as the fix is to use
* Solaris 11 or some operating system
* other than Solaris - you just *can't*
* capture on a loopback interface
* on Solaris prior to Solaris 11, the lack
* of a DLPI device for the loopback
* interface is just a symptom of that
* inability.
*/
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"%s: No DLPI device found", name);
} else {
if (errno == EPERM || errno == EACCES)
status = PCAP_ERROR_PERM_DENIED;
else
status = PCAP_ERROR;
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s",
dname2, pcap_strerror(errno));
}
return (status);
}
/* XXX Assume unit zero */
*ppa = 0;
}
#endif
return (fd);
}
static int
pcap_activate_dlpi(pcap_t *p)
{
#ifdef DL_HP_RAWDLS
struct pcap_dlpi *pd = p->priv;
#endif
int status = 0;
int retv;
int ppa;
#ifdef HAVE_SOLARIS
int isatm = 0;
#endif
register dl_info_ack_t *infop;
#ifdef HAVE_SYS_BUFMOD_H
bpf_u_int32 ss;
#ifdef HAVE_SOLARIS
char release[GET_RELEASE_BUFSIZE];
bpf_u_int32 osmajor, osminor, osmicro;
#endif
#endif
bpf_u_int32 buf[MAXDLBUF];
p->fd = open_dlpi_device(p->opt.device, &ppa, p->errbuf);
if (p->fd < 0) {
status = p->fd;
goto bad;
}
@ -412,101 +521,7 @@ pcap_activate_dlpi(pcap_t *p)
* to open it for reading only and, if that succeeds, just let
* the send attempts fail.
*/
pd->send_fd = open(cp, O_RDWR);
#endif
/*
* Get a table of all PPAs for that device, and search that
* table for the specified device type name and unit number.
*/
ppa = get_dlpi_ppa(p->fd, dname, ppa, p->errbuf);
if (ppa < 0) {
status = ppa;
goto bad;
}
#else
/*
* If the device name begins with "/", assume it begins with
* the pathname of the directory containing the device to open;
* otherwise, concatenate the device directory name and the
* device name.
*/
if (*p->opt.source == '/')
strlcpy(dname, p->opt.source, sizeof(dname));
else
snprintf(dname, sizeof(dname), "%s/%s", PCAP_DEV_PREFIX,
p->opt.source);
/*
* Get the unit number, and a pointer to the end of the device
* type name.
*/
cp = split_dname(dname, &ppa, p->errbuf);
if (cp == NULL) {
status = PCAP_ERROR_NO_SUCH_DEVICE;
goto bad;
}
/*
* Make a copy of the device pathname, and then remove the unit
* number from the device pathname.
*/
strlcpy(dname2, dname, sizeof(dname));
*cp = '\0';
/* Try device without unit number */
if ((p->fd = open(dname, O_RDWR)) < 0) {
if (errno != ENOENT) {
if (errno == EPERM || errno == EACCES)
status = PCAP_ERROR_PERM_DENIED;
else
status = PCAP_ERROR;
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s", dname,
pcap_strerror(errno));
goto bad;
}
/* Try again with unit number */
if ((p->fd = open(dname2, O_RDWR)) < 0) {
if (errno == ENOENT) {
status = PCAP_ERROR_NO_SUCH_DEVICE;
/*
* We provide an error message even
* for this error, for diagnostic
* purposes (so that, for example,
* the app can show the message if the
* user requests it).
*
* In it, we just report "No DLPI device
* found" with the device name, so people
* don't get confused and think, for example,
* that if they can't capture on "lo0"
* on Solaris the fix is to change libpcap
* (or the application that uses it) to
* look for something other than "/dev/lo0",
* as the fix is to look for an operating
* system other than Solaris - you just
* *can't* capture on a loopback interface
* on Solaris, the lack of a DLPI device
* for the loopback interface is just a
* symptom of that inability.
*/
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"%s: No DLPI device found", p->opt.source);
} else {
if (errno == EPERM || errno == EACCES)
status = PCAP_ERROR_PERM_DENIED;
else
status = PCAP_ERROR;
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s",
dname2, pcap_strerror(errno));
}
goto bad;
}
/* XXX Assume unit zero */
ppa = 0;
}
pd->send_fd = open("/dev/dlpi", O_RDWR);
#endif
/*
@ -627,7 +642,7 @@ pcap_activate_dlpi(pcap_t *p)
*/
if (strioctl(p->fd, A_PROMISCON_REQ, 0, NULL) < 0) {
status = PCAP_ERROR;
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"A_PROMISCON_REQ: %s", pcap_strerror(errno));
goto bad;
}
@ -745,7 +760,7 @@ pcap_activate_dlpi(pcap_t *p)
*/
if (strioctl(p->fd, DLIOCRAW, 0, NULL) < 0) {
status = PCAP_ERROR;
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "DLIOCRAW: %s",
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "DLIOCRAW: %s",
pcap_strerror(errno));
goto bad;
}
@ -763,10 +778,10 @@ pcap_activate_dlpi(pcap_t *p)
** Ask for bugid 1149065.
*/
#ifdef HAVE_SOLARIS
release = get_release(&osmajor, &osminor, &osmicro);
get_release(release, sizeof (release), &osmajor, &osminor, &osmicro);
if (osmajor == 5 && (osminor <= 2 || (osminor == 3 && osmicro < 2)) &&
getenv("BUFMOD_FIXED") == NULL) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"WARNING: bufmod is broken in SunOS %s; ignoring snaplen.",
release);
ss = 0;
@ -786,7 +801,7 @@ pcap_activate_dlpi(pcap_t *p)
*/
if (ioctl(p->fd, I_FLUSH, FLUSHR) != 0) {
status = PCAP_ERROR;
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "FLUSHR: %s",
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "FLUSHR: %s",
pcap_strerror(errno));
goto bad;
}
@ -841,7 +856,7 @@ split_dname(char *device, int *unitp, char *ebuf)
*/
cp = device + strlen(device) - 1;
if (*cp < '0' || *cp > '9') {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s missing unit number",
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s missing unit number",
device);
return (NULL);
}
@ -853,16 +868,16 @@ split_dname(char *device, int *unitp, char *ebuf)
errno = 0;
unit = strtol(cp, &eos, 10);
if (*eos != '\0') {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s bad unit number", device);
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s bad unit number", device);
return (NULL);
}
if (errno == ERANGE || unit > INT_MAX) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s unit number too large",
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s unit number too large",
device);
return (NULL);
}
if (unit < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s unit number is negative",
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s unit number is negative",
device);
return (NULL);
}
@ -960,6 +975,56 @@ dlpromiscon(pcap_t *p, bpf_u_int32 level)
return (0);
}
/*
* Not all interfaces are DLPI interfaces, and thus not all interfaces
* can be opened with DLPI (for example, the loopback interface is not
* a DLPI interface on Solaris prior to Solaris 11), so try to open
* the specified interface; return 0 if we fail with PCAP_ERROR_NO_SUCH_DEVICE
* and 1 otherwise.
*/
static int
is_dlpi_interface(const char *name)
{
int fd;
int ppa;
char errbuf[PCAP_ERRBUF_SIZE];
fd = open_dlpi_device(name, &ppa, errbuf);
if (fd < 0) {
/*
* Error - was it PCAP_ERROR_NO_SUCH_DEVICE?
*/
if (fd == PCAP_ERROR_NO_SUCH_DEVICE) {
/*
* Yes, so we can't open this because it's
* not a DLPI interface.
*/
return (0);
}
/*
* No, so, in the case where there's a single DLPI
* device for all interfaces of this type ("style
* 2" providers?), we don't know whether it's a DLPI
* interface or not, as we didn't try an attach.
* Say it is a DLPI device, so that the user can at
* least try to open it and report the error (which
* is probably "you don't have permission to open that
* DLPI device"; reporting those interfaces means
* users will ask "why am I getting a permissions error
* when I try to capture" rather than "why am I not
* seeing any interfaces", making the underlying problem
* clearer).
*/
return (1);
}
/*
* Success.
*/
close(fd);
return (1);
}
int
pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
{
@ -972,7 +1037,15 @@ pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
} buf;
char baname[2+1+1];
u_int i;
#endif
/*
* Get the list of regular interfaces first.
*/
if (pcap_findalldevs_interfaces(alldevsp, errbuf, is_dlpi_interface) == -1)
return (-1); /* failure */
#ifdef HAVE_SOLARIS
/*
* We may have to do special magic to get ATM devices.
*/
@ -989,12 +1062,12 @@ pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
}
if (strioctl(fd, A_GET_UNITS, sizeof(buf), (char *)&buf) < 0) {
snprintf(errbuf, PCAP_ERRBUF_SIZE, "A_GET_UNITS: %s",
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "A_GET_UNITS: %s",
pcap_strerror(errno));
return (-1);
}
for (i = 0; i < buf.nunits; i++) {
snprintf(baname, sizeof baname, "ba%u", i);
pcap_snprintf(baname, sizeof baname, "ba%u", i);
if (pcap_add_if(alldevsp, baname, 0, NULL, errbuf) < 0)
return (-1);
}
@ -1015,7 +1088,7 @@ send_request(int fd, char *ptr, int len, char *what, char *ebuf)
flags = 0;
if (putmsg(fd, &ctl, (struct strbuf *) NULL, flags) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE,
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
"send_request: putmsg \"%s\": %s",
what, pcap_strerror(errno));
return (-1);
@ -1029,6 +1102,8 @@ recv_ack(int fd, int size, const char *what, char *bufp, char *ebuf, int *uerror
union DL_primitives *dlp;
struct strbuf ctl;
int flags;
char errmsgbuf[PCAP_ERRBUF_SIZE];
char dlprimbuf[64];
/*
* Clear out "*uerror", so it's only set for DL_ERROR_ACK/DL_SYSERR,
@ -1043,7 +1118,7 @@ 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) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "recv_ack: %s getmsg: %s",
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "recv_ack: %s getmsg: %s",
what, pcap_strerror(errno));
return (PCAP_ERROR);
}
@ -1066,7 +1141,7 @@ 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;
snprintf(ebuf, PCAP_ERRBUF_SIZE,
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
"recv_ack: %s: UNIX error - %s",
what, pcap_strerror(dlp->error_ack.dl_unix_errno));
if (dlp->error_ack.dl_unix_errno == EPERM ||
@ -1075,8 +1150,9 @@ recv_ack(int fd, int size, const char *what, char *bufp, char *ebuf, int *uerror
break;
default:
snprintf(ebuf, PCAP_ERRBUF_SIZE, "recv_ack: %s: %s",
what, dlstrerror(dlp->error_ack.dl_errno));
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
"recv_ack: %s: %s", what,
dlstrerror(errmsgbuf, sizeof (errmsgbuf), dlp->error_ack.dl_errno));
if (dlp->error_ack.dl_errno == DL_BADPPA)
return (PCAP_ERROR_NO_SUCH_DEVICE);
else if (dlp->error_ack.dl_errno == DL_ACCESS)
@ -1086,14 +1162,14 @@ recv_ack(int fd, int size, const char *what, char *bufp, char *ebuf, int *uerror
return (PCAP_ERROR);
default:
snprintf(ebuf, PCAP_ERRBUF_SIZE,
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
"recv_ack: %s: Unexpected primitive ack %s",
what, dlprim(dlp->dl_primitive));
what, dlprim(dlprimbuf, sizeof (dlprimbuf), dlp->dl_primitive));
return (PCAP_ERROR);
}
if (ctl.len < size) {
snprintf(ebuf, PCAP_ERRBUF_SIZE,
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
"recv_ack: %s: Ack too small (%d < %d)",
what, ctl.len, size);
return (PCAP_ERROR);
@ -1102,10 +1178,8 @@ recv_ack(int fd, int size, const char *what, char *bufp, char *ebuf, int *uerror
}
static char *
dlstrerror(bpf_u_int32 dl_errno)
dlstrerror(char *errbuf, size_t errbufsize, bpf_u_int32 dl_errno)
{
static char errstring[6+2+8+1];
switch (dl_errno) {
case DL_ACCESS:
@ -1206,16 +1280,14 @@ dlstrerror(bpf_u_int32 dl_errno)
return ("Pending outstanding connect indications");
default:
sprintf(errstring, "Error %02x", dl_errno);
return (errstring);
pcap_snprintf(errbuf, errbufsize, "Error %02x", dl_errno);
return (errbuf);
}
}
static char *
dlprim(bpf_u_int32 prim)
dlprim(char *primbuf, size_t primbufsize, bpf_u_int32 prim)
{
static char primbuf[80];
switch (prim) {
case DL_INFO_REQ:
@ -1300,7 +1372,8 @@ dlprim(bpf_u_int32 prim)
return ("DL_RESET_CON");
default:
(void) sprintf(primbuf, "unknown primitive 0x%x", prim);
pcap_snprintf(primbuf, primbufsize, "unknown primitive 0x%x",
prim);
return (primbuf);
}
}
@ -1412,28 +1485,29 @@ dlrawdatareq(int fd, const u_char *datap, int datalen)
#endif /* DL_HP_RAWDLS */
#if defined(HAVE_SOLARIS) && defined(HAVE_SYS_BUFMOD_H)
static char *
get_release(bpf_u_int32 *majorp, bpf_u_int32 *minorp, bpf_u_int32 *microp)
static void
get_release(char *buf, size_t bufsize, bpf_u_int32 *majorp,
bpf_u_int32 *minorp, bpf_u_int32 *microp)
{
char *cp;
static char buf[32];
*majorp = 0;
*minorp = 0;
*microp = 0;
if (sysinfo(SI_RELEASE, buf, sizeof(buf)) < 0)
return ("?");
if (sysinfo(SI_RELEASE, buf, bufsize) < 0) {
strlcpy(buf, "?", bufsize);
return;
}
cp = buf;
if (!isdigit((unsigned char)*cp))
return (buf);
return;
*majorp = strtol(cp, &cp, 10);
if (*cp++ != '.')
return (buf);
return;
*minorp = strtol(cp, &cp, 10);
if (*cp++ != '.')
return (buf);
return;
*microp = strtol(cp, &cp, 10);
return (buf);
}
#endif
@ -1521,21 +1595,21 @@ 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) {
snprintf(ebuf, PCAP_ERRBUF_SIZE,
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
"get_dlpi_ppa: hpppa getmsg: %s", pcap_strerror(errno));
return (PCAP_ERROR);
}
dlp = (dl_hp_ppa_ack_t *)ctl.buf;
if (dlp->dl_primitive != DL_HP_PPA_ACK) {
snprintf(ebuf, PCAP_ERRBUF_SIZE,
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
"get_dlpi_ppa: hpppa unexpected primitive ack 0x%x",
(bpf_u_int32)dlp->dl_primitive);
return (PCAP_ERROR);
}
if (ctl.len < DL_HP_PPA_ACK_SIZE) {
snprintf(ebuf, PCAP_ERRBUF_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);
return (PCAP_ERROR);
@ -1543,7 +1617,7 @@ 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) {
snprintf(ebuf, PCAP_ERRBUF_SIZE,
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
"get_dlpi_ppa: hpppa malloc: %s", pcap_strerror(errno));
return (PCAP_ERROR);
}
@ -1552,13 +1626,13 @@ 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) {
snprintf(ebuf, PCAP_ERRBUF_SIZE,
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
"get_dlpi_ppa: hpppa getmsg: %s", pcap_strerror(errno));
free(ppa_data_buf);
return (PCAP_ERROR);
}
if (ctl.len < dlp->dl_length) {
snprintf(ebuf, PCAP_ERRBUF_SIZE,
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
"get_dlpi_ppa: hpppa ack too small (%d < %lu)",
ctl.len, (unsigned long)dlp->dl_length);
free(ppa_data_buf);
@ -1615,9 +1689,9 @@ 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.
*/
snprintf(dname, sizeof(dname), "/dev/%s%d", device, unit);
pcap_snprintf(dname, sizeof(dname), "/dev/%s%d", device, unit);
if (stat(dname, &statbuf) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "stat: %s: %s",
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "stat: %s: %s",
dname, pcap_strerror(errno));
return (PCAP_ERROR);
}
@ -1634,12 +1708,12 @@ get_dlpi_ppa(register int fd, register const char *device, register int unit,
}
}
if (i == ap->dl_count) {
snprintf(ebuf, PCAP_ERRBUF_SIZE,
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
"can't find /dev/dlpi PPA for %s%d", device, unit);
return (PCAP_ERROR_NO_SUCH_DEVICE);
}
if (ip->dl_hdw_state == HDW_DEAD) {
snprintf(ebuf, PCAP_ERRBUF_SIZE,
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
"%s%d: hardware state: DOWN\n", device, unit);
free(ppa_data_buf);
return (PCAP_ERROR);
@ -1678,19 +1752,19 @@ get_dlpi_ppa(register int fd, register const char *ifname, register int unit,
if (cp != NULL)
ifname = cp + 1;
if (nlist(path_vmunix, &nl) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "nlist %s failed",
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "nlist %s failed",
path_vmunix);
return (-1);
}
if (nl[NL_IFNET].n_value == 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE,
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
"could't find %s kernel symbol",
nl[NL_IFNET].n_name);
return (-1);
}
kd = open("/dev/kmem", O_RDONLY);
if (kd < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "kmem open: %s",
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "kmem open: %s",
pcap_strerror(errno));
return (-1);
}
@ -1712,7 +1786,7 @@ get_dlpi_ppa(register int fd, register const char *ifname, register int unit,
return (ifnet.if_index);
}
snprintf(ebuf, PCAP_ERRBUF_SIZE, "Can't find %s", ifname);
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "Can't find %s", ifname);
return (-1);
}
@ -1723,17 +1797,17 @@ dlpi_kread(register int fd, register off_t addr,
register int cc;
if (lseek(fd, addr, SEEK_SET) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "lseek: %s",
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "lseek: %s",
pcap_strerror(errno));
return (-1);
}
cc = read(fd, buf, len);
if (cc < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "read: %s",
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "read: %s",
pcap_strerror(errno));
return (-1);
} else if (cc != len) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "short read (%d != %d)", cc,
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "short read (%d != %d)", cc,
len);
return (-1);
}
@ -1742,14 +1816,14 @@ dlpi_kread(register int fd, register off_t addr,
#endif
pcap_t *
pcap_create_interface(const char *device, char *ebuf)
pcap_create_interface(const char *device _U_, char *ebuf)
{
pcap_t *p;
#ifdef DL_HP_RAWDLS
struct pcap_dlpi *pd;
#endif
p = pcap_create_common(device, ebuf, sizeof (struct pcap_dlpi));
p = pcap_create_common(ebuf, sizeof (struct pcap_dlpi));
if (p == NULL)
return (NULL);

View file

@ -1,6 +1,6 @@
/*
* This file is part of DOS-libpcap
* Ported to DOS/DOSX by G. Vanem <gvanem@broadpark.no>
* Ported to DOS/DOSX by G. Vanem <gvanem@yahoo.no>
*
* pcap-dos.c: Interface to PKTDRVR, NDIS2 and 32-bit pmode
* network drivers.
@ -145,15 +145,15 @@ static struct device *get_device (int fd)
* Private data for capturing on MS-DOS.
*/
struct pcap_dos {
void (*wait_proc)(void); /* call proc while waiting */
void (*wait_proc)(void); /* call proc while waiting */
struct pcap_stat stat;
};
pcap_t *pcap_create_interface (const char *device, char *ebuf)
pcap_t *pcap_create_interface (const char *device _U_, char *ebuf)
{
pcap_t *p;
p = pcap_create_common(device, ebuf, sizeof (struct pcap_dos));
p = pcap_create_common(ebuf, sizeof (struct pcap_dos));
if (p == NULL)
return (NULL);
@ -166,9 +166,7 @@ pcap_t *pcap_create_interface (const char *device, char *ebuf)
* network packets.
*/
static int pcap_activate_dos (pcap_t *pcap)
{
struct pcap_dos *pcapd = pcap->priv;
{
if (pcap->opt.rfmon) {
/*
* No monitor mode on DOS.
@ -188,23 +186,26 @@ static int pcap_activate_dos (pcap_t *pcap)
pcap->stats_op = pcap_stats_dos;
pcap->inject_op = pcap_sendpacket_dos;
pcap->setfilter_op = pcap_setfilter_dos;
pcap->setdirection_op = NULL; /* Not implemented.*/
pcap->setdirection_op = NULL; /* Not implemented.*/
pcap->fd = ++ref_count;
pcap->bufsize = ETH_MAX+100; /* add some margin */
pcap->buffer = calloc (pcap->bufsize, 1);
if (pcap->fd == 1) /* first time we're called */
{
if (!init_watt32(pcap, pcap->opt.source, pcap->errbuf) ||
!first_init(pcap->opt.source, pcap->errbuf, pcap->opt.promisc))
if (!init_watt32(pcap, pcap->opt.device, pcap->errbuf) ||
!first_init(pcap->opt.device, pcap->errbuf, pcap->opt.promisc))
{
return (PCAP_ERROR);
}
}
atexit (close_driver);
}
else if (stricmp(active_dev->name,pcap->opt.source))
else if (stricmp(active_dev->name,pcap->opt.device))
{
snprintf (pcap->errbuf, PCAP_ERRBUF_SIZE,
"Cannot use different devices simultaneously "
"(`%s' vs. `%s')", active_dev->name, pcap->opt.source);
pcap_snprintf (pcap->errbuf, PCAP_ERRBUF_SIZE,
"Cannot use different devices simultaneously "
"(`%s' vs. `%s')", active_dev->name, pcap->opt.device);
return (PCAP_ERROR);
}
handle_to_device [pcap->fd-1] = active_dev;
@ -221,7 +222,6 @@ pcap_read_one (pcap_t *p, pcap_handler callback, u_char *data)
struct pcap_dos *pd = p->priv;
struct pcap_pkthdr pcap;
struct timeval now, expiry = { 0,0 };
BYTE *rx_buf;
int rx_len = 0;
if (p->opt.timeout > 0)
@ -253,13 +253,11 @@ pcap_read_one (pcap_t *p, pcap_handler callback, u_char *data)
if (dev->peek_rx_buf)
{
PCAP_ASSERT (dev->release_rx_buf);
rx_len = (*dev->peek_rx_buf) (&rx_buf);
rx_len = (*dev->peek_rx_buf) (&p->buffer);
}
else
{
BYTE buf [ETH_MAX+100]; /* add some margin */
rx_len = (*dev->copy_rx_buf) (buf, p->snapshot);
rx_buf = buf;
rx_len = (*dev->copy_rx_buf) (p->buffer, p->snapshot);
}
if (rx_len > 0) /* got a packet */
@ -272,7 +270,7 @@ pcap_read_one (pcap_t *p, pcap_handler callback, u_char *data)
pcap.len = rx_len;
if (callback &&
(!p->fcode.bf_insns || bpf_filter(p->fcode.bf_insns, rx_buf, pcap.len, pcap.caplen)))
(!p->fcode.bf_insns || bpf_filter(p->fcode.bf_insns, p->buffer, pcap.len, pcap.caplen)))
{
filter_count++;
@ -280,11 +278,11 @@ pcap_read_one (pcap_t *p, pcap_handler callback, u_char *data)
* capture.
*/
gettimeofday2 (&pcap.ts, NULL);
(*callback) (data, &pcap, rx_buf);
(*callback) (data, &pcap, p->buffer);
}
if (dev->release_rx_buf)
(*dev->release_rx_buf) (rx_buf);
(*dev->release_rx_buf) (p->buffer);
if (pcap_pkt_debug > 0)
{
@ -296,6 +294,18 @@ pcap_read_one (pcap_t *p, pcap_handler callback, u_char *data)
return (1);
}
/* Has "pcap_breakloop()" been called?
*/
if (p->break_loop) {
/*
* Yes - clear the flag that indicates that it
* has, and return -2 to indicate that we were
* told to break out of the loop.
*/
p->break_loop = 0;
return (-2);
}
/* If not to wait for a packet or pcap_cleanup_dos() called from
* e.g. SIGINT handler, exit loop now.
*/
@ -311,8 +321,8 @@ pcap_read_one (pcap_t *p, pcap_handler callback, u_char *data)
kbhit(); /* a real CPU hog */
#endif
if (p->wait_proc)
(*p->wait_proc)(); /* call yield func */
if (pd->wait_proc)
(*pd->wait_proc)(); /* call yield func */
}
if (rx_len < 0) /* receive error */
@ -330,7 +340,6 @@ pcap_read_one (pcap_t *p, pcap_handler callback, u_char *data)
static int
pcap_read_dos (pcap_t *p, int cnt, pcap_handler callback, u_char *data)
{
struct pcap_dos *pd = p->priv;
int rc, num = 0;
while (num <= cnt || PACKET_COUNT_IS_UNLIMITED(cnt))
@ -401,7 +410,7 @@ int pcap_stats_ex (pcap_t *p, struct pcap_stat_ex *se)
strlcpy (p->errbuf, "pktdrvr doesn't have detailed statistics",
PCAP_ERRBUF_SIZE);
return (-1);
}
}
memcpy (se, (*dev->get_stats)(dev), sizeof(*se));
return (0);
}
@ -442,7 +451,7 @@ static void pcap_cleanup_dos (pcap_t *p)
{
struct pcap_dos *pd;
if (p && !exc_occured)
if (!exc_occured)
{
pd = p->priv;
if (pcap_stats(p,NULL) < 0)
@ -495,6 +504,8 @@ char *pcap_lookupdev (char *ebuf)
int pcap_lookupnet (const char *device, bpf_u_int32 *localnet,
bpf_u_int32 *netmask, char *errbuf)
{
DWORD mask, net;
if (!_watt_is_init)
{
strcpy (errbuf, "pcap_open_offline() or pcap_activate() must be "
@ -502,40 +513,43 @@ int pcap_lookupnet (const char *device, bpf_u_int32 *localnet,
return (-1);
}
*netmask = _w32_sin_mask;
*localnet = my_ip_addr & *netmask;
if (*localnet == 0)
mask = _w32_sin_mask;
net = my_ip_addr & mask;
if (net == 0)
{
if (IN_CLASSA(*netmask))
*localnet = IN_CLASSA_NET;
net = IN_CLASSA_NET;
else if (IN_CLASSB(*netmask))
*localnet = IN_CLASSB_NET;
net = IN_CLASSB_NET;
else if (IN_CLASSC(*netmask))
*localnet = IN_CLASSC_NET;
net = IN_CLASSC_NET;
else
{
sprintf (errbuf, "inet class for 0x%lx unknown", *netmask);
pcap_snprintf (errbuf, PCAP_ERRBUF_SIZE, "inet class for 0x%lx unknown", mask);
return (-1);
}
}
*localnet = htonl (net);
*netmask = htonl (mask);
ARGSUSED (device);
return (0);
}
}
/*
* 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
* The list, as returned through "alldevsp", may be NULL if no interfaces
* were up and could be opened.
*/
int pcap_findalldevs (pcap_if_t **alldevsp, char *errbuf)
int pcap_platform_finddevs (pcap_if_t **alldevsp, char *errbuf)
{
struct device *dev;
struct sockaddr_ll sa_ll_1, sa_ll_2;
struct sockaddr_in sa_ll_1, sa_ll_2;
struct sockaddr *addr, *netmask, *broadaddr, *dstaddr;
pcap_if_t *devlist = NULL;
int ret = 0;
size_t addr_size = sizeof(struct sockaddr_ll);
size_t addr_size = sizeof(*addr);
for (dev = (struct device*)dev_base; dev; dev = dev->next)
{
@ -550,14 +564,14 @@ int pcap_findalldevs (pcap_if_t **alldevsp, char *errbuf)
memset (&sa_ll_1, 0, sizeof(sa_ll_1));
memset (&sa_ll_2, 0, sizeof(sa_ll_2));
sa_ll_1.sll_family = AF_PACKET;
sa_ll_2.sll_family = AF_PACKET;
sa_ll_1.sin_family = AF_INET;
sa_ll_2.sin_family = AF_INET;
addr = (struct sockaddr*) &sa_ll_1;
netmask = (struct sockaddr*) &sa_ll_1;
dstaddr = (struct sockaddr*) &sa_ll_1;
broadaddr = (struct sockaddr*) &sa_ll_2;
memset (&sa_ll_2.sll_addr, 0xFF, sizeof(sa_ll_2.sll_addr));
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)
@ -565,13 +579,15 @@ int pcap_findalldevs (pcap_if_t **alldevsp, char *errbuf)
ret = -1;
break;
}
if (add_addr_to_iflist(&devlist,dev->name, dev->flags, addr, addr_size,
#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)
{
ret = -1;
break;
}
#endif
}
if (devlist && ret < 0)
@ -605,12 +621,12 @@ void pcap_assert (const char *what, const char *file, unsigned line)
*/
void pcap_set_wait (pcap_t *p, void (*yield)(void), int wait)
{
struct pcap_dos *pd;
if (p)
{
pd = p->priv;
pd->wait_proc = yield;
p->opt.timeout = wait;
struct pcap_dos *pd = p->priv;
pd->wait_proc = yield;
p->opt.timeout = wait;
}
}
@ -635,7 +651,7 @@ open_driver (const char *dev_name, char *ebuf, int promisc)
if (!(*dev->probe)(dev)) /* call the xx_probe() function */
{
sprintf (ebuf, "failed to detect device `%s'", dev_name);
pcap_snprintf (ebuf, PCAP_ERRBUF_SIZE, "failed to detect device `%s'", dev_name);
return (NULL);
}
probed_dev = dev; /* device is probed okay and may be used */
@ -657,7 +673,7 @@ open_driver (const char *dev_name, char *ebuf, int promisc)
if (!(*dev->open)(dev))
{
sprintf (ebuf, "failed to activate device `%s'", dev_name);
pcap_snprintf (ebuf, PCAP_ERRBUF_SIZE, "failed to activate device `%s'", dev_name);
if (pktInfo.error && !strncmp(dev->name,"pkt",3))
{
strcat (ebuf, ": ");
@ -679,14 +695,14 @@ open_driver (const char *dev_name, char *ebuf, int promisc)
*/
if (!dev)
{
sprintf (ebuf, "device `%s' not supported", dev_name);
pcap_snprintf (ebuf, PCAP_ERRBUF_SIZE, "device `%s' not supported", dev_name);
return (NULL);
}
not_probed:
if (!probed_dev)
{
sprintf (ebuf, "device `%s' not probed", dev_name);
pcap_snprintf (ebuf, PCAP_ERRBUF_SIZE, "device `%s' not probed", dev_name);
return (NULL);
}
return (dev);
@ -756,7 +772,7 @@ static void exc_handler (int sig)
fprintf (stderr, "Catching signal %d.\n", sig);
}
exc_occured = 1;
pcap_cleanup_dos (NULL);
close_driver();
}
#endif /* __DJGPP__ */
@ -933,7 +949,7 @@ static int init_watt32 (struct pcap *pcap, const char *dev_name, char *err_buf)
if (_watt_is_init)
sock_exit();
env = getenv ("PCAP_DEBUG");
env = getenv ("PCAP_TRACE");
if (env && atoi(env) > 0 &&
pcap_pkt_debug < 0) /* if not already set */
{
@ -960,7 +976,7 @@ static int init_watt32 (struct pcap *pcap, const char *dev_name, char *err_buf)
* have default values. Should be taken from another
* ini-file/environment in any case (ref. tcpdump.ini)
*/
_watt_is_init = 1;
_watt_is_init = 1;
if (!using_pktdrv || !has_ip_addr) /* for now .... */
{
@ -973,7 +989,7 @@ static int init_watt32 (struct pcap *pcap, const char *dev_name, char *err_buf)
}
else if (rc && using_pktdrv)
{
sprintf (err_buf, "sock_init() failed, code %d", rc);
pcap_snprintf (err_buf, PCAP_ERRBUF_SIZE, "sock_init() failed, code %d", rc);
return (0);
}
@ -1053,9 +1069,9 @@ static const struct config_table debug_tab[] = {
* pcap_config_hook() is an extension to application's config
* handling. Uses Watt-32's config-table function.
*/
int pcap_config_hook (const char *name, const char *value)
int pcap_config_hook (const char *keyword, const char *value)
{
return parse_config_table (debug_tab, NULL, name, value);
return parse_config_table (debug_tab, NULL, keyword, value);
}
/*
@ -1092,7 +1108,7 @@ static int pkt_open (struct device *dev)
if (!PktInitDriver(mode))
return (0);
PktResetStatistics (pktInfo.handle);
PktQueueBusy (FALSE);
return (1);
@ -1290,7 +1306,7 @@ struct device rtl8139_dev LOCKED_VAR = {
0,0,0,0,0,0,
&cs89_dev,
rtl8139_probe /* dev->probe routine */
};
};
/*
* Dequeue routine is called by polling.

View file

@ -214,7 +214,7 @@ extern void _w32_os_yield (void); /* Watt-32's misc.c */
#define PCAP_ASSERT(x) ((void)0)
#else
void pcap_assert (const char *what, const char *file, unsigned line);
void pcap_assert (const char *what, const char *file, unsigned line);
#define PCAP_ASSERT(x) do { \
if (!(x)) \

View file

@ -18,7 +18,7 @@
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\"
.TH PCAP-FILTER @MAN_MISC_INFO@ "17 May 2013"
.TH PCAP-FILTER @MAN_MISC_INFO@ "3 August 2015"
.SH NAME
pcap-filter \- packet filter syntax
.br
@ -298,7 +298,7 @@ of protocol type \fIprotocol\fP.
\fBicmp\fP, \fBicmp6\fP, \fBigmp\fP, \fBigrp\fP, \fBpim\fP, \fBah\fP,
\fBesp\fP, \fBvrrp\fP, \fBudp\fP, or \fBtcp\fP.
Note that the identifiers \fBtcp\fP, \fBudp\fP, and \fBicmp\fP are also
keywords and must be escaped via backslash (\\), which is \\\\ in the C-shell.
keywords and must be escaped via backslash (\\).
Note that this primitive does not chase the protocol header chain.
.IP "\fBip6 proto \fIprotocol\fR"
True if the packet is an IPv6 packet of protocol type \fIprotocol\fP.
@ -372,9 +372,9 @@ True if the packet is of ether type \fIprotocol\fR.
Note these identifiers are also keywords
and must be escaped via backslash (\\).
.IP
[In the case of FDDI (e.g., `\fBfddi protocol arp\fR'), Token Ring
(e.g., `\fBtr protocol arp\fR'), and IEEE 802.11 wireless LANS (e.g.,
`\fBwlan protocol arp\fR'), for most of those protocols, the
[In the case of FDDI (e.g., `\fBfddi proto arp\fR'), Token Ring
(e.g., `\fBtr proto arp\fR'), and IEEE 802.11 wireless LANS (e.g.,
`\fBwlan proto arp\fR'), for most of those protocols, the
protocol identification comes from the 802.2 Logical Link Control (LLC)
header, which is usually layered on top of the FDDI, Token Ring, or
802.11 header.
@ -697,7 +697,7 @@ changes the decoding offsets for the remainder of \fIexpression\fR on
the assumption that the packet is a MPLS-encapsulated IP packet. The
\fBmpls \fI[label_num]\fR expression may be used more than once, to
filter on MPLS hierarchies. Each use of that expression increments the
filter offsets by 4.
filter offsets by 4.
.IP
For example:
.in +.5i
@ -733,6 +733,22 @@ For example:
.fi
.in -.5i
filters IPv4 protocols encapsulated in PPPoE session id 0x27.
.IP "\fBgeneve \fI[vni]\fR"
True if the packet is a Geneve packet (UDP port 6081). If \fI[vni]\fR
is specified, only true if the packet has the specified \fIvni\fR.
Note that when the \fBgeneve\fR keyword is encountered in
\fIexpression\fR, it changes the decoding offsets for the remainder of
\fIexpression\fR on the assumption that the packet is a Geneve packet.
.IP
For example:
.in +.5i
.nf
\fBgeneve 0xb && ip\fR
.fi
.in -.5i
filters IPv4 protocols encapsulated in Geneve with VNI 0xb. This will
match both IP directly encapsulated in Geneve as well as IP contained
inside an Ethernet frame.
.IP "\fBiso proto \fIprotocol\fR"
True if the packet is an OSI packet of protocol type \fIprotocol\fP.
\fIProtocol\fP can be a number or one of the names
@ -864,8 +880,7 @@ The following TCP flags field values are available: \fBtcp-fin\fP,
.LP
Primitives may be combined using:
.IP
A parenthesized group of primitives and operators
(parentheses are special to the Shell and must be escaped).
A parenthesized group of primitives and operators.
.IP
Negation (`\fB!\fP' or `\fBnot\fP').
.IP

View file

@ -40,14 +40,16 @@
extern "C" {
#endif
#ifdef WIN32
#include <Packet32.h>
extern CRITICAL_SECTION g_PcapCompileCriticalSection;
#endif /* WIN32 */
#ifdef MSDOS
#include <fcntl.h>
#include <io.h>
#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)
#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*/
@ -106,9 +108,9 @@ extern CRITICAL_SECTION g_PcapCompileCriticalSection;
#define MAXIMUM_SNAPLEN 262144
struct pcap_opt {
char *source;
char *device;
int timeout; /* timeout for buffering */
int buffer_size;
u_int buffer_size;
int promisc;
int rfmon; /* monitor mode */
int immediate; /* immediate mode - deliver packets as soon as they arrive */
@ -126,11 +128,19 @@ 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 (*stats_op_t)(pcap_t *, struct pcap_stat *);
#ifdef WIN32
#ifdef _WIN32
typedef struct pcap_stat *(*stats_ex_op_t)(pcap_t *, int *);
typedef int (*setbuff_op_t)(pcap_t *, int);
typedef int (*setmode_op_t)(pcap_t *, int);
typedef int (*setmintocopy_op_t)(pcap_t *, int);
typedef Adapter *(*getadapter_op_t)(pcap_t *);
typedef HANDLE (*getevent_op_t)(pcap_t *);
typedef int (*oid_get_request_op_t)(pcap_t *, bpf_u_int32, void *, size_t *);
typedef int (*oid_set_request_op_t)(pcap_t *, bpf_u_int32, const void *, size_t *);
typedef u_int (*sendqueue_transmit_op_t)(pcap_t *, pcap_send_queue *, int);
typedef int (*setuserbuffer_op_t)(pcap_t *, int);
typedef int (*live_dump_op_t)(pcap_t *, char *, int, int);
typedef int (*live_dump_ended_op_t)(pcap_t *, int);
typedef PAirpcapHandle (*get_airpcap_handle_op_t)(pcap_t *);
#endif
typedef void (*cleanup_op_t)(pcap_t *);
@ -145,24 +155,22 @@ struct pcap {
read_op_t read_op;
/*
* Method to call to read to read packets from a savefile.
* Method to call to read packets from a savefile.
*/
int (*next_packet_op)(pcap_t *, struct pcap_pkthdr *, u_char **);
#ifdef WIN32
#ifdef _WIN32
ADAPTER *adapter;
LPPACKET Packet;
int nonblock;
#else
int fd;
int selectable_fd;
#endif /* WIN32 */
#endif /* _WIN32 */
/*
* Read buffer.
*/
int bufsize;
u_char *buffer;
u_int bufsize;
void *buffer;
u_char *bp;
int cc;
@ -172,7 +180,7 @@ struct pcap {
int swapped;
FILE *rfile; /* null if live capture, non-null if savefile */
int fddipad;
u_int fddipad;
struct pcap *next; /* list of open pcaps that need stuff cleared on close */
/*
@ -199,9 +207,18 @@ struct pcap {
*/
u_char *pkt;
#ifdef _WIN32
struct pcap_stat stat; /* used for pcap_stats_ex() */
#endif
/* We're accepting only packets in this direction/these directions. */
pcap_direction_t direction;
/*
* Flags to affect BPF code generation.
*/
int bpf_codegen_flags;
/*
* Placeholder for filter code if bpf not in kernel.
*/
@ -235,19 +252,32 @@ struct pcap {
*/
pcap_handler oneshot_callback;
#ifdef WIN32
#ifdef _WIN32
/*
* These are, at least currently, specific to the Win32 NPF
* driver.
*/
stats_ex_op_t stats_ex_op;
setbuff_op_t setbuff_op;
setmode_op_t setmode_op;
setmintocopy_op_t setmintocopy_op;
getadapter_op_t getadapter_op;
getevent_op_t getevent_op;
oid_get_request_op_t oid_get_request_op;
oid_set_request_op_t oid_set_request_op;
sendqueue_transmit_op_t sendqueue_transmit_op;
setuserbuffer_op_t setuserbuffer_op;
live_dump_op_t live_dump_op;
live_dump_ended_op_t live_dump_ended_op;
get_airpcap_handle_op_t get_airpcap_handle_op;
#endif
cleanup_op_t cleanup_op;
};
/*
* BPF code generation flags.
*/
#define BPF_SPECIAL_VLAN_HANDLING 0x00000001 /* special VLAN handling for Linux */
/*
* This is a timeval as stored in a savefile.
* It has to use the same types everywhere, independent of the actual
@ -328,34 +358,15 @@ struct oneshot_userdata {
pcap_t *pd;
};
int yylex(void);
#ifndef min
#define min(a, b) ((a) > (b) ? (b) : (a))
#endif
/* XXX should these be in pcap.h? */
int pcap_offline_read(pcap_t *, int, pcap_handler, u_char *);
int pcap_read(pcap_t *, int cnt, pcap_handler, u_char *);
#ifndef HAVE_STRLCPY
#define strlcpy(x, y, z) \
(strncpy((x), (y), (z)), \
((z) <= 0 ? 0 : ((x)[(z) - 1] = '\0')), \
strlen((y)))
#endif
#include <stdarg.h>
#if !defined(HAVE_SNPRINTF)
#define snprintf pcap_snprintf
extern int snprintf (char *, size_t, const char *, ...);
#endif
#if !defined(HAVE_VSNPRINTF)
#define vsnprintf pcap_vsnprintf
extern int vsnprintf (char *, size_t, const char *, va_list ap);
#endif
#include "portability.h"
/*
* Does the packet count argument to a module's read routine say
@ -366,7 +377,7 @@ extern int vsnprintf (char *, size_t, const char *, va_list ap);
/*
* Routines that most pcap implementations can use for non-blocking mode.
*/
#if !defined(WIN32) && !defined(MSDOS)
#if !defined(_WIN32) && !defined(MSDOS)
int pcap_getnonblock_fd(pcap_t *, char *);
int pcap_setnonblock_fd(pcap_t *p, int, char *);
#endif
@ -383,38 +394,43 @@ int pcap_setnonblock_fd(pcap_t *p, int, char *);
* by pcap_create routines.
*/
pcap_t *pcap_create_interface(const char *, char *);
pcap_t *pcap_create_common(const char *, char *, size_t);
pcap_t *pcap_create_common(char *, size_t);
int pcap_do_addexit(pcap_t *);
void pcap_add_to_pcaps_to_close(pcap_t *);
void pcap_remove_from_pcaps_to_close(pcap_t *);
void pcap_cleanup_live_common(pcap_t *);
int pcap_not_initialized(pcap_t *);
int pcap_check_activated(pcap_t *);
/*
* Internal interfaces for "pcap_findalldevs()".
*
* "pcap_findalldevs_interfaces()" finds interfaces using the
* "standard" mechanisms (SIOCGIFCONF, "getifaddrs()", etc.).
*
* "pcap_platform_finddevs()" is a platform-dependent routine to
* add devices not found by the "standard" mechanisms.
* 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.
*/
int pcap_findalldevs_interfaces(pcap_if_t **, char *);
int pcap_platform_finddevs(pcap_if_t **, char *);
int add_addr_to_iflist(pcap_if_t **, const char *, u_int, struct sockaddr *,
size_t, struct sockaddr *, size_t, struct sockaddr *, size_t,
struct sockaddr *, size_t, char *);
#if !defined(_WIN32) && !defined(MSDOS)
int pcap_findalldevs_interfaces(pcap_if_t **, char *,
int (*)(const char *));
#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 *);
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 *, u_int, const char *, char *);
struct sockaddr *dup_sockaddr(struct sockaddr *, size_t);
int add_or_find_if(pcap_if_t **, pcap_if_t **, const char *, u_int,
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);
#endif
/*
* Internal interfaces for "pcap_open_offline()".
@ -438,8 +454,8 @@ void sf_cleanup(pcap_t *p);
*/
void pcap_oneshot(u_char *, const struct pcap_pkthdr *, const u_char *);
#ifdef WIN32
char *pcap_win32strerror(void);
#ifdef _WIN32
void pcap_win32_err_to_str(DWORD, char *);
#endif
int install_bpf_program(pcap_t *, struct bpf_program *);

View file

@ -106,7 +106,7 @@ pcap_activate_libdlpi(pcap_t *p)
* dlpi_open() will not fail if the underlying link does not support
* passive mode. See dlpi(7P) for details.
*/
retv = dlpi_open(p->opt.source, &dh, DLPI_RAW|DLPI_PASSIVE);
retv = dlpi_open(p->opt.device, &dh, DLPI_RAW|DLPI_PASSIVE);
if (retv != DLPI_SUCCESS) {
if (retv == DLPI_ELINKNAMEINVAL || retv == DLPI_ENOLINK)
status = PCAP_ERROR_NO_SUCH_DEVICE;
@ -115,7 +115,7 @@ pcap_activate_libdlpi(pcap_t *p)
status = PCAP_ERROR_PERM_DENIED;
else
status = PCAP_ERROR;
pcap_libdlpi_err(p->opt.source, "dlpi_open", retv,
pcap_libdlpi_err(p->opt.device, "dlpi_open", retv,
p->errbuf);
return (status);
}
@ -133,7 +133,7 @@ pcap_activate_libdlpi(pcap_t *p)
/* Bind with DLPI_ANY_SAP. */
if ((retv = dlpi_bind(pd->dlpi_hd, DLPI_ANY_SAP, 0)) != DLPI_SUCCESS) {
status = PCAP_ERROR;
pcap_libdlpi_err(p->opt.source, "dlpi_bind", retv, p->errbuf);
pcap_libdlpi_err(p->opt.device, "dlpi_bind", retv, p->errbuf);
goto bad;
}
@ -187,7 +187,7 @@ pcap_activate_libdlpi(pcap_t *p)
/* Determine link type. */
if ((retv = dlpi_info(pd->dlpi_hd, &dlinfo, 0)) != DLPI_SUCCESS) {
status = PCAP_ERROR;
pcap_libdlpi_err(p->opt.source, "dlpi_info", retv, p->errbuf);
pcap_libdlpi_err(p->opt.device, "dlpi_info", retv, p->errbuf);
goto bad;
}
@ -209,7 +209,7 @@ pcap_activate_libdlpi(pcap_t *p)
*/
if (ioctl(p->fd, I_FLUSH, FLUSHR) != 0) {
status = PCAP_ERROR;
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "FLUSHR: %s",
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "FLUSHR: %s",
pcap_strerror(errno));
goto bad;
}
@ -258,13 +258,24 @@ dlpromiscon(pcap_t *p, bpf_u_int32 level)
err = PCAP_ERROR_PERM_DENIED;
else
err = PCAP_ERROR;
pcap_libdlpi_err(p->opt.source, "dlpi_promiscon" STRINGIFY(level),
pcap_libdlpi_err(p->opt.device, "dlpi_promiscon" STRINGIFY(level),
retv, p->errbuf);
return (err);
}
return (0);
}
/*
* Presumably everything returned by dlpi_walk() is a DLPI device,
* so there's no work to be done here to check whether name refers
* to a DLPI device.
*/
static int
is_dlpi_interface(const char *name _U_)
{
return (1);
}
/*
* In Solaris, the "standard" mechanism" i.e SIOCGLIFCONF will only find
* network links that are plumbed and are up. dlpi_walk(3DLPI) will find
@ -279,12 +290,18 @@ pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
linkwalk_t lw = {NULL, 0};
int save_errno;
/*
* Get the list of regular interfaces first.
*/
if (pcap_findalldevs_interfaces(alldevsp, errbuf, is_dlpi_interface) == -1)
return (-1); /* failure */
/* dlpi_walk() for loopback will be added here. */
dlpi_walk(list_interfaces, &lw, 0);
if (lw.lw_err != 0) {
snprintf(errbuf, PCAP_ERRBUF_SIZE,
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"dlpi_walk: %s", pcap_strerror(lw.lw_err));
retv = -1;
goto done;
@ -337,7 +354,7 @@ pcap_read_libdlpi(pcap_t *p, int count, pcap_handler callback, u_char *user)
}
msglen = p->bufsize;
bufp = p->buffer + p->offset;
bufp = (u_char *)p->buffer + p->offset;
retv = dlpi_recv(pd->dlpi_hd, NULL, NULL, bufp,
&msglen, -1, NULL);
@ -404,16 +421,16 @@ pcap_cleanup_libdlpi(pcap_t *p)
static void
pcap_libdlpi_err(const char *linkname, const char *func, int err, char *errbuf)
{
snprintf(errbuf, PCAP_ERRBUF_SIZE, "libpcap: %s failed on %s: %s",
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "libpcap: %s failed on %s: %s",
func, linkname, dlpi_strerror(err));
}
pcap_t *
pcap_create_interface(const char *device, char *ebuf)
pcap_create_interface(const char *device _U_, char *ebuf)
{
pcap_t *p;
p = pcap_create_common(device, ebuf, sizeof (struct pcap_dlpi));
p = pcap_create_common(ebuf, sizeof (struct pcap_dlpi));
if (p == NULL)
return (NULL);

View file

@ -18,7 +18,7 @@
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\"
.TH PCAP-LINKTYPE @MAN_MISC_INFO@ "12 March 2011"
.TH PCAP-LINKTYPE @MAN_MISC_INFO@ "7 April 2014"
.SH NAME
pcap-linktype \- link-layer header types supported by libpcap
.SH DESCRIPTION

File diff suppressed because it is too large Load diff

View file

@ -11,8 +11,8 @@
* 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
* 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
@ -57,14 +57,14 @@
#include <linux/netfilter/nfnetlink_queue.h>
/* NOTE: if your program drops privilages after pcap_activate() it WON'T work with nfqueue.
* It took me quite some time to debug ;/
* It took me quite some time to debug ;/
*
* Sending any data to nfnetlink socket requires CAP_NET_ADMIN privilages,
* and in nfqueue we need to send verdict reply after recving packet.
*
* In tcpdump you can disable dropping privilages with -Z root
*/
#include "pcap-netfilter-linux.h"
#define HDR_LENGTH (NLMSG_LENGTH(NLMSG_ALIGN(sizeof(struct nfgenmsg))))
@ -79,10 +79,12 @@ typedef enum { OTHER = -1, NFLOG, NFQUEUE } nftype_t;
*/
struct pcap_netfilter {
u_int packets_read; /* count of packets read with recvfrom() */
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
netfilter_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user)
{
@ -98,28 +100,29 @@ netfilter_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_c
handle->break_loop = 0;
return -2;
}
} while ((len == -1) && (errno == EINTR));
if(errno == ENOBUFS) handlep->packets_nobufs++;
} while ((len == -1) && (errno == EINTR || errno == ENOBUFS));
if (len < 0) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't receive packet %d:%s", errno, pcap_strerror(errno));
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't receive packet %d:%s", errno, pcap_strerror(errno));
return -1;
}
buf = handle->buffer;
while (len >= NLMSG_SPACE(0)) {
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;
nftype_t type = OTHER;
if (nlh->nlmsg_len < sizeof(struct nlmsghdr) || len < nlh->nlmsg_len) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Message truncated: (got: %d) (nlmsg_len: %u)", len, nlh->nlmsg_len);
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);
return -1;
}
if (NFNL_SUBSYS_ID(nlh->nlmsg_type) == NFNL_SUBSYS_ULOG &&
NFNL_MSG_TYPE(nlh->nlmsg_type) == NFULNL_MSG_PACKET)
if (NFNL_SUBSYS_ID(nlh->nlmsg_type) == NFNL_SUBSYS_ULOG &&
NFNL_MSG_TYPE(nlh->nlmsg_type) == NFULNL_MSG_PACKET)
type = NFLOG;
else if (NFNL_SUBSYS_ID(nlh->nlmsg_type) == NFNL_SUBSYS_QUEUE &&
else if (NFNL_SUBSYS_ID(nlh->nlmsg_type) == NFNL_SUBSYS_QUEUE &&
NFNL_MSG_TYPE(nlh->nlmsg_type) == NFQNL_MSG_PACKET)
type = NFQUEUE;
@ -127,14 +130,14 @@ netfilter_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_c
const unsigned char *payload = NULL;
struct pcap_pkthdr pkth;
const struct nfgenmsg *nfg;
const struct nfgenmsg *nfg = NULL;
int id = 0;
if (handle->linktype != DLT_NFLOG) {
const struct nfattr *payload_attr = NULL;
if (nlh->nlmsg_len < HDR_LENGTH) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Malformed message: (nlmsg_len: %u)", nlh->nlmsg_len);
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Malformed message: (nlmsg_len: %u)", nlh->nlmsg_len);
return -1;
}
@ -184,7 +187,7 @@ netfilter_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_c
gettimeofday(&pkth.ts, NULL);
if (handle->fcode.bf_insns == NULL ||
bpf_filter(handle->fcode.bf_insns, payload, pkth.len, pkth.caplen))
bpf_filter(handle->fcode.bf_insns, payload, pkth.len, pkth.caplen))
{
handlep->packets_read++;
callback(user, &pkth, payload);
@ -194,13 +197,16 @@ netfilter_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_c
if (type == NFQUEUE) {
/* XXX, possible responses: NF_DROP, NF_ACCEPT, NF_STOLEN, NF_QUEUE, NF_REPEAT, NF_STOP */
nfqueue_send_verdict(handle, ntohs(nfg->res_id), id, NF_ACCEPT);
/* if type == NFQUEUE, handle->linktype is always != DLT_NFLOG,
so nfg is always initialized to NLMSG_DATA(nlh). */
if (nfg != NULL)
nfqueue_send_verdict(handle, ntohs(nfg->res_id), id, NF_ACCEPT);
}
}
msg_len = NLMSG_ALIGN(nlh->nlmsg_len);
if (msg_len > len)
msg_len = len;
if (msg_len > (u_int)len)
msg_len = (u_int)len;
len -= msg_len;
buf += msg_len;
@ -221,7 +227,7 @@ netfilter_stats_linux(pcap_t *handle, struct pcap_stat *stats)
struct pcap_netfilter *handlep = handle->priv;
stats->ps_recv = handlep->packets_read;
stats->ps_drop = 0;
stats->ps_drop = handlep->packets_nobufs;
stats->ps_ifdrop = 0;
return 0;
}
@ -229,9 +235,9 @@ netfilter_stats_linux(pcap_t *handle, struct pcap_stat *stats)
static int
netfilter_inject_linux(pcap_t *handle, const void *buf, size_t size)
{
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "inject not supported on netfilter devices");
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "inject not supported on netfilter devices");
return (-1);
}
}
struct my_nfattr {
u_int16_t nfa_len;
@ -249,7 +255,7 @@ netfilter_send_config_msg(const pcap_t *handle, u_int16_t msg_type, int ack, u_i
struct sockaddr_nl snl;
static unsigned int seq_id;
if (!seq_id)
seq_id = time(NULL);
++seq_id;
@ -304,7 +310,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 (len >= NLMSG_SPACE(0) && NLMSG_OK(nlh, len)) {
while ((u_int)len >= NLMSG_SPACE(0) && NLMSG_OK(nlh, 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;
@ -341,7 +347,7 @@ nflog_send_config_cmd(const pcap_t *handle, u_int16_t group_id, u_int8_t cmd, u_
return nflog_send_config_msg(handle, family, group_id, &nfa);
}
static int
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)
{
struct nfulnl_msg_config_mode msg;
@ -395,7 +401,7 @@ nfqueue_send_config_cmd(const pcap_t *handle, u_int16_t group_id, u_int8_t cmd,
return nfqueue_send_config_msg(handle, AF_UNSPEC, group_id, &nfa);
}
static int
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)
{
struct nfqnl_msg_config_params msg;
@ -414,7 +420,7 @@ nfqueue_send_config_mode(const pcap_t *handle, u_int16_t group_id, u_int8_t copy
static int
netfilter_activate(pcap_t* handle)
{
const char *dev = handle->opt.source;
const char *dev = handle->opt.device;
unsigned short groups[32];
int group_count = 0;
nftype_t type = OTHER;
@ -428,7 +434,7 @@ netfilter_activate(pcap_t* handle)
dev += strlen(NFQUEUE_IFACE);
type = NFQUEUE;
}
if (type != OTHER && *dev == ':') {
dev++;
while (*dev) {
@ -436,16 +442,16 @@ netfilter_activate(pcap_t* handle)
char *end_dev;
if (group_count == 32) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Maximum 32 netfilter groups! dev: %s",
handle->opt.source);
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Maximum 32 netfilter groups! dev: %s",
handle->opt.device);
return PCAP_ERROR;
}
group_id = strtol(dev, &end_dev, 0);
if (end_dev != dev) {
if (group_id < 0 || group_id > 65535) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Netfilter group range from 0 to 65535 (got %ld)",
group_id);
return PCAP_ERROR;
@ -461,9 +467,9 @@ netfilter_activate(pcap_t* handle)
}
if (type == OTHER || *dev) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't get netfilter group(s) index from %s",
handle->opt.source);
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't get netfilter group(s) index from %s",
handle->opt.device);
return PCAP_ERROR;
}
@ -488,7 +494,7 @@ netfilter_activate(pcap_t* handle)
/* Create netlink socket */
handle->fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_NETFILTER);
if (handle->fd < 0) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't create raw socket %d:%s", errno, pcap_strerror(errno));
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't create raw socket %d:%s", errno, pcap_strerror(errno));
return PCAP_ERROR;
}
@ -506,54 +512,54 @@ netfilter_activate(pcap_t* handle)
handle->buffer = malloc(handle->bufsize);
if (!handle->buffer) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't allocate dump buffer: %s", pcap_strerror(errno));
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't allocate dump buffer: %s", pcap_strerror(errno));
goto close_fail;
}
if (type == NFLOG) {
if (nflog_send_config_cmd(handle, 0, NFULNL_CFG_CMD_PF_UNBIND, AF_INET) < 0) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "NFULNL_CFG_CMD_PF_UNBIND: %s", pcap_strerror(errno));
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "NFULNL_CFG_CMD_PF_UNBIND: %s", pcap_strerror(errno));
goto close_fail;
}
if (nflog_send_config_cmd(handle, 0, NFULNL_CFG_CMD_PF_BIND, AF_INET) < 0) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "NFULNL_CFG_CMD_PF_BIND: %s", pcap_strerror(errno));
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "NFULNL_CFG_CMD_PF_BIND: %s", pcap_strerror(errno));
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) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't listen on group group index: %s", pcap_strerror(errno));
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't listen on group group index: %s", pcap_strerror(errno));
goto close_fail;
}
if (nflog_send_config_mode(handle, groups[i], NFULNL_COPY_PACKET, handle->snapshot) < 0) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "NFULNL_COPY_PACKET: %s", pcap_strerror(errno));
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "NFULNL_COPY_PACKET: %s", pcap_strerror(errno));
goto close_fail;
}
}
} else {
if (nfqueue_send_config_cmd(handle, 0, NFQNL_CFG_CMD_PF_UNBIND, AF_INET) < 0) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "NFQNL_CFG_CMD_PF_UNBIND: %s", pcap_strerror(errno));
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "NFQNL_CFG_CMD_PF_UNBIND: %s", pcap_strerror(errno));
goto close_fail;
}
if (nfqueue_send_config_cmd(handle, 0, NFQNL_CFG_CMD_PF_BIND, AF_INET) < 0) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "NFQNL_CFG_CMD_PF_BIND: %s", pcap_strerror(errno));
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "NFQNL_CFG_CMD_PF_BIND: %s", pcap_strerror(errno));
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) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't listen on group group index: %s", pcap_strerror(errno));
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't listen on group group index: %s", pcap_strerror(errno));
goto close_fail;
}
if (nfqueue_send_config_mode(handle, groups[i], NFQNL_COPY_PACKET, handle->snapshot) < 0) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "NFQNL_COPY_PACKET: %s", pcap_strerror(errno));
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "NFQNL_COPY_PACKET: %s", pcap_strerror(errno));
goto close_fail;
}
}
@ -572,7 +578,7 @@ 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) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "SO_RCVBUF: %s", pcap_strerror(errno));
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "SO_RCVBUF: %s", pcap_strerror(errno));
goto close_fail;
}
}
@ -599,7 +605,7 @@ netfilter_create(const char *device, char *ebuf, int *is_ours)
/* Does it begin with NFLOG_IFACE or NFQUEUE_IFACE? */
if (strncmp(cp, NFLOG_IFACE, sizeof NFLOG_IFACE - 1) == 0)
cp += sizeof NFLOG_IFACE - 1;
else if (strncmp(cp, NFQUEUE_IFACE, sizeof NFQUEUE_IFACE - 1) == 0)
else if (strncmp(cp, NFQUEUE_IFACE, sizeof NFQUEUE_IFACE - 1) == 0)
cp += sizeof NFQUEUE_IFACE - 1;
else {
/* Nope, doesn't begin with NFLOG_IFACE nor NFQUEUE_IFACE */
@ -620,7 +626,7 @@ netfilter_create(const char *device, char *ebuf, int *is_ours)
/* OK, it's probably ours. */
*is_ours = 1;
p = pcap_create_common(device, ebuf, sizeof (struct pcap_netfilter));
p = pcap_create_common(ebuf, sizeof (struct pcap_netfilter));
if (p == NULL)
return (NULL);
@ -628,17 +634,17 @@ netfilter_create(const char *device, char *ebuf, int *is_ours)
return (p);
}
int
int
netfilter_findalldevs(pcap_if_t **alldevsp, char *err_str)
{
int sock;
sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_NETFILTER);
if (sock < 0) {
/* if netlink is not supported this is not fatal */
if (errno == EAFNOSUPPORT || errno == EPROTONOSUPPORT)
return 0;
snprintf(err_str, PCAP_ERRBUF_SIZE, "Can't open netlink socket %d:%s",
pcap_snprintf(err_str, PCAP_ERRBUF_SIZE, "Can't open netlink socket %d:%s",
errno, pcap_strerror(errno));
return -1;
}

View file

@ -11,8 +11,8 @@
* 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
* 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

1265
contrib/libpcap/pcap-new.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -114,11 +114,11 @@ pcap_read_nit(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
if (cc < 0) {
if (errno == EWOULDBLOCK)
return (0);
snprintf(p->errbuf, sizeof(p->errbuf), "pcap_read: %s",
pcap_snprintf(p->errbuf, sizeof(p->errbuf), "pcap_read: %s",
pcap_strerror(errno));
return (-1);
}
bp = p->buffer;
bp = (u_char *)p->buffer;
} else
bp = p->bp;
@ -168,7 +168,7 @@ pcap_read_nit(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
continue;
default:
snprintf(p->errbuf, sizeof(p->errbuf),
pcap_snprintf(p->errbuf, sizeof(p->errbuf),
"bad nit state %d", nh->nh_state);
return (-1);
}
@ -206,12 +206,12 @@ 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) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
pcap_strerror(errno));
return (-1);
}
return (ret);
}
}
static int
nit_setflags(pcap_t *p)
@ -249,7 +249,7 @@ nit_setflags(pcap_t *p)
nioc.nioc_flags |= NF_PROMISC;
if (ioctl(p->fd, SIOCSNIT, &nioc) < 0) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "SIOCSNIT: %s",
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "SIOCSNIT: %s",
pcap_strerror(errno));
return (-1);
}
@ -280,15 +280,22 @@ pcap_activate_nit(pcap_t *p)
memset(p, 0, sizeof(*p));
p->fd = fd = socket(AF_NIT, SOCK_RAW, NITPROTO_RAW);
if (fd < 0) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"socket: %s", pcap_strerror(errno));
goto bad;
}
snit.snit_family = AF_NIT;
(void)strncpy(snit.snit_ifname, p->opt.source, NITIFSIZ);
(void)strncpy(snit.snit_ifname, p->opt.device, NITIFSIZ);
if (bind(fd, (struct sockaddr *)&snit, sizeof(snit))) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
/*
* XXX - there's probably a particular bind error that
* means "there's no such device" and a particular bind
* error that means "that device doesn't support NIT";
* 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));
goto bad;
}
@ -301,7 +308,7 @@ pcap_activate_nit(pcap_t *p)
p->linktype = DLT_EN10MB;
p->bufsize = BUFSPACE;
p->buffer = (u_char *)malloc(p->bufsize);
p->buffer = malloc(p->bufsize);
if (p->buffer == NULL) {
strlcpy(p->errbuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
goto bad;
@ -348,11 +355,11 @@ pcap_activate_nit(pcap_t *p)
}
pcap_t *
pcap_create_interface(const char *device, char *ebuf)
pcap_create_interface(const char *device _U_, char *ebuf)
{
pcap_t *p;
p = pcap_create_common(device, ebuf, sizeof (struct pcap_nit));
p = pcap_create_common(ebuf, sizeof (struct pcap_nit));
if (p == NULL)
return (NULL);
@ -360,8 +367,18 @@ pcap_create_interface(const char *device, char *ebuf)
return (p);
}
/*
* XXX - there's probably a particular bind error that means "that device
* doesn't support NIT"; if so, we should try a bind and use that.
*/
static int
can_be_bound(const char *name _U_)
{
return (1);
}
int
pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
{
return (0);
return (pcap_findalldevs_interfaces(alldevsp, errbuf, can_be_bound));
}

View file

@ -36,7 +36,7 @@
static char nosup[] = "live packet capture not supported on this system";
pcap_t *
pcap_create_interface(const char *device, char *ebuf)
pcap_create_interface(const char *device _U_, char *ebuf)
{
(void)strlcpy(ebuf, nosup, PCAP_ERRBUF_SIZE);
return (NULL);
@ -45,5 +45,9 @@ pcap_create_interface(const char *device, char *ebuf)
int
pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
{
/*
* There are no interfaces on which we can capture.
*/
*alldevsp = NULL;
return (0);
}

View file

@ -107,7 +107,7 @@ pcap_read_pf(pcap_t *pc, int cnt, pcap_handler callback, u_char *user)
#ifdef LBL_ALIGN
struct enstamp stamp;
#endif
register int pad;
register u_int pad;
again:
cc = pc->cc;
@ -127,11 +127,11 @@ pcap_read_pf(pcap_t *pc, int cnt, pcap_handler callback, u_char *user)
(void)lseek(pc->fd, 0L, SEEK_SET);
goto again;
}
snprintf(pc->errbuf, sizeof(pc->errbuf), "pf read: %s",
pcap_snprintf(pc->errbuf, sizeof(pc->errbuf), "pf read: %s",
pcap_strerror(errno));
return (-1);
}
bp = pc->buffer + pc->offset;
bp = (u_char *)pc->buffer + pc->offset;
} else
bp = pc->bp;
/*
@ -160,7 +160,7 @@ pcap_read_pf(pcap_t *pc, int cnt, pcap_handler callback, u_char *user)
}
}
if (cc < sizeof(*sp)) {
snprintf(pc->errbuf, sizeof(pc->errbuf),
pcap_snprintf(pc->errbuf, sizeof(pc->errbuf),
"pf short read (%d)", cc);
return (-1);
}
@ -172,7 +172,7 @@ pcap_read_pf(pcap_t *pc, int cnt, pcap_handler callback, u_char *user)
#endif
sp = (struct enstamp *)bp;
if (sp->ens_stamplen != sizeof(*sp)) {
snprintf(pc->errbuf, sizeof(pc->errbuf),
pcap_snprintf(pc->errbuf, sizeof(pc->errbuf),
"pf short stamplen (%d)",
sp->ens_stamplen);
return (-1);
@ -232,12 +232,12 @@ pcap_inject_pf(pcap_t *p, const void *buf, size_t size)
ret = write(p->fd, buf, size);
if (ret == -1) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
pcap_strerror(errno));
return (-1);
}
return (ret);
}
}
static int
pcap_stats_pf(pcap_t *p, struct pcap_stat *ps)
@ -321,14 +321,17 @@ pcap_activate_pf(pcap_t *p)
* its argument, even though it takes a "char *" rather than a
* "const char *" as its first argument. That appears to be
* the case, at least on Digital UNIX 4.0.
*
* XXX - is there an error that means "no such device"? Is
* there one that means "that device doesn't support pf"?
*/
p->fd = pfopen(p->opt.source, O_RDWR);
p->fd = pfopen(p->opt.device, O_RDWR);
if (p->fd == -1 && errno == EACCES)
p->fd = pfopen(p->opt.source, O_RDONLY);
p->fd = pfopen(p->opt.device, O_RDONLY);
if (p->fd < 0) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "pf open: %s: %s\n\
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.source, pcap_strerror(errno));
p->opt.device, pcap_strerror(errno));
goto bad;
}
pf->OrigMissed = -1;
@ -338,7 +341,7 @@ 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) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCMBIS: %s",
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCMBIS: %s",
pcap_strerror(errno));
goto bad;
}
@ -349,13 +352,13 @@ 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) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCSETW: %s",
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCSETW: %s",
pcap_strerror(errno));
goto bad;
}
/* discover interface type */
if (ioctl(p->fd, EIOCDEVP, (caddr_t)&devparams) < 0) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCDEVP: %s",
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCDEVP: %s",
pcap_strerror(errno));
goto bad;
}
@ -437,7 +440,7 @@ your system may not be properly configured; see the packetfilter(4) man page\n",
* framing", there's not much we can do, as that
* doesn't specify a particular type of header.
*/
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"unknown data-link type %u", devparams.end_dev_type);
goto bad;
}
@ -450,7 +453,7 @@ 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) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCTRUNCATE: %s",
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCTRUNCATE: %s",
pcap_strerror(errno));
goto bad;
}
@ -459,7 +462,7 @@ 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) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCSETF: %s",
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCSETF: %s",
pcap_strerror(errno));
goto bad;
}
@ -469,14 +472,14 @@ 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) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCSRTIMEOUT: %s",
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCSRTIMEOUT: %s",
pcap_strerror(errno));
goto bad;
}
}
p->bufsize = BUFSPACE;
p->buffer = (u_char*)malloc(p->bufsize + p->offset);
p->buffer = malloc(p->bufsize + p->offset);
if (p->buffer == NULL) {
strlcpy(p->errbuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
goto bad;
@ -503,11 +506,11 @@ your system may not be properly configured; see the packetfilter(4) man page\n",
}
pcap_t *
pcap_create_interface(const char *device, char *ebuf)
pcap_create_interface(const char *device _U_, char *ebuf)
{
pcap_t *p;
p = pcap_create_common(device, ebuf, sizeof (struct pcap_pf));
p = pcap_create_common(ebuf, sizeof (struct pcap_pf));
if (p == NULL)
return (NULL);
@ -515,10 +518,20 @@ pcap_create_interface(const char *device, char *ebuf)
return (p);
}
/*
* XXX - is there an error from pfopen() that means "no such device"?
* Is there one that means "that device doesn't support pf"?
*/
static int
can_be_bound(const char *name _U_)
{
return (1);
}
int
pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
{
return (0);
return (pcap_findalldevs_interfaces(alldevsp, errbuf, can_be_bound));
}
static int
@ -547,7 +560,7 @@ 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) {
snprintf(p->errbuf, sizeof(p->errbuf),
pcap_snprintf(p->errbuf, sizeof(p->errbuf),
"BIOCSETF: %s", pcap_strerror(errno));
return (-1);
}

2127
contrib/libpcap/pcap-rpcap.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,465 @@
/*
* Copyright (c) 2002 - 2005 NetGroup, Politecnico di Torino (Italy)
* Copyright (c) 2005 - 2008 CACE Technologies, Davis (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. Neither the name of the Politecnico di Torino, CACE Technologies
* 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 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.
*
*/
#ifndef __PCAP_RPCAP_H__
#define __PCAP_RPCAP_H__
#include "pcap.h"
#include "sockutils.h" /* Needed for some structures (like SOCKET, sockaddr_in) which are used here */
/*
* \file pcap-pcap.h
*
* This file keeps all the new definitions and typedefs that are exported to the user and
* that are needed for the RPCAP protocol.
*
* \warning All the RPCAP functions that are allowed to return a buffer containing
* the error description can return max PCAP_ERRBUF_SIZE characters.
* However there is no guarantees that the string will be zero-terminated.
* Best practice is to define the errbuf variable as a char of size 'PCAP_ERRBUF_SIZE+1'
* and to insert manually the termination char at the end of the buffer. This will
* guarantee that no buffer overflows occur even if we use the printf() to show
* the error on the screen.
*
* \warning This file declares some typedefs that MUST be of a specific size.
* These definitions (i.e. typedefs) could need to be changed on other platforms than
* Intel IA32.
*
* \warning This file defines some structures that are used to transfer data on the network.
* Be careful that you compiler MUST not insert padding into these structures
* for better alignment.
* These structures have been created in order to be correctly aligned to a 32 bits
* boundary, but be careful in any case.
*/
/*********************************************************
* *
* General definitions / typedefs for the RPCAP protocol *
* *
*********************************************************/
/* All the following structures and typedef belongs to the Private Documentation */
/*
* \addtogroup remote_pri_struct
* \{
*/
#define RPCAP_DEFAULT_NETPORT "2002" /* Default port on which the RPCAP daemon is waiting for connections. */
/* Default port on which the client workstation is waiting for connections in case of active mode. */
#define RPCAP_DEFAULT_NETPORT_ACTIVE "2003"
#define RPCAP_DEFAULT_NETADDR "" /* Default network address on which the RPCAP daemon binds to. */
#define RPCAP_VERSION 0 /* Present version of the RPCAP protocol (0 = Experimental). */
#define RPCAP_TIMEOUT_INIT 90 /* Initial timeout for RPCAP connections (default: 90 sec) */
#define RPCAP_TIMEOUT_RUNTIME 180 /* Run-time timeout for RPCAP connections (default: 3 min) */
#define RPCAP_ACTIVE_WAIT 30 /* Waiting time between two attempts to open a connection, in active mode (default: 30 sec) */
#define RPCAP_SUSPEND_WRONGAUTH 1 /* If the authentication is wrong, stops 1 sec before accepting a new auth message */
/*
* \brief Buffer used by socket functions to send-receive packets.
* In case you plan to have messages larger than this value, you have to increase it.
*/
#define RPCAP_NETBUF_SIZE 64000
/*
* \brief Separators used for the host list.
*
* It is used:
* - by the rpcapd daemon, when you types a list of allowed connecting hosts
* - by the rpcap in active mode, when the client waits for incoming connections from other hosts
*/
#define RPCAP_HOSTLIST_SEP " ,;\n\r"
/* WARNING: These could need to be changed on other platforms */
typedef unsigned char uint8; /* Provides an 8-bits unsigned integer */
typedef unsigned short uint16; /* Provides a 16-bits unsigned integer */
typedef unsigned int uint32; /* Provides a 32-bits unsigned integer */
typedef int int32; /* Provides a 32-bits integer */
/*
* \brief Keeps a list of all the opened connections in the active mode.
*
* This structure defines a linked list of items that are needed to keep the info required to
* manage the active mode.
* In other words, when a new connection in active mode starts, this structure is updated so that
* it reflects the list of active mode connections currently opened.
* This structure is required by findalldevs() and open_remote() to see if they have to open a new
* control connection toward the host, or they already have a control connection in place.
*/
struct activehosts
{
struct sockaddr_storage host;
SOCKET sockctrl;
struct activehosts *next;
};
/*********************************************************
* *
* Protocol messages formats *
* *
*********************************************************/
/* WARNING Take care you compiler does not insert padding for better alignments into these structs */
/* Common header for all the RPCAP messages */
struct rpcap_header
{
uint8 ver; /* RPCAP version number */
uint8 type; /* RPCAP message type (error, findalldevs, ...) */
uint16 value; /* Message-dependent value (not always used) */
uint32 plen; /* Length of the payload of this RPCAP message */
};
/* Format of the message for the interface description (findalldevs command) */
struct rpcap_findalldevs_if
{
uint16 namelen; /* Length of the interface name */
uint16 desclen; /* Length of the interface description */
uint32 flags; /* Interface flags */
uint16 naddr; /* Number of addresses */
uint16 dummy; /* Must be zero */
};
/* Format of the message for the address listing (findalldevs command) */
struct rpcap_findalldevs_ifaddr
{
struct sockaddr_storage addr; /* Network address */
struct sockaddr_storage netmask; /* Netmask for that address */
struct sockaddr_storage broadaddr; /* Broadcast address for that address */
struct sockaddr_storage dstaddr; /* P2P destination address for that address */
};
/*
* \brief Format of the message of the connection opening reply (open command).
*
* This structure transfers over the network some of the values useful on the client side.
*/
struct rpcap_openreply
{
int32 linktype; /* Link type */
int32 tzoff; /* Timezone offset */
};
/* Format of the message that starts a remote capture (startcap command) */
struct rpcap_startcapreq
{
uint32 snaplen; /* Length of the snapshot (number of bytes to capture for each packet) */
uint32 read_timeout; /* Read timeout in milliseconds */
uint16 flags; /* Flags (see RPCAP_STARTCAPREQ_FLAG_xxx) */
uint16 portdata; /* Network port on which the client is waiting at (if 'serveropen') */
};
/* Format of the reply message that devoted to start a remote capture (startcap reply command) */
struct rpcap_startcapreply
{
int32 bufsize; /* Size of the user buffer allocated by WinPcap; it can be different from the one we chose */
uint16 portdata; /* Network port on which the server is waiting at (passive mode only) */
uint16 dummy; /* Must be zero */
};
/*
* \brief Format of the header which encapsulates captured packets when transmitted on the network.
*
* This message requires the general header as well, since we want to be able to exchange
* more information across the network in the future (for example statistics, and kind like that).
*/
struct rpcap_pkthdr
{
uint32 timestamp_sec; /* 'struct timeval' compatible, it represents the 'tv_sec' field */
uint32 timestamp_usec; /* 'struct timeval' compatible, it represents the 'tv_usec' field */
uint32 caplen; /* Length of portion present in the capture */
uint32 len; /* Real length this packet (off wire) */
uint32 npkt; /* Ordinal number of the packet (i.e. the first one captured has '1', the second one '2', etc) */
};
/* General header used for the pcap_setfilter() command; keeps just the number of BPF instructions */
struct rpcap_filter
{
uint16 filtertype; /* type of the filter transferred (BPF instructions, ...) */
uint16 dummy; /* Must be zero */
uint32 nitems; /* Number of items contained into the filter (e.g. BPF instructions for BPF filters) */
};
/* Structure that keeps a single BPF instuction; it is repeated 'ninsn' times according to the 'rpcap_filterbpf' header */
struct rpcap_filterbpf_insn
{
uint16 code; /* opcode of the instruction */
uint8 jt; /* relative offset to jump to in case of 'true' */
uint8 jf; /* relative offset to jump to in case of 'false' */
int32 k; /* instruction-dependent value */
};
/* Structure that keeps the data required for the authentication on the remote host */
struct rpcap_auth
{
uint16 type; /* Authentication type */
uint16 dummy; /* Must be zero */
uint16 slen1; /* Length of the first authentication item (e.g. username) */
uint16 slen2; /* Length of the second authentication item (e.g. password) */
};
/* Structure that keeps the statistics about the number of packets captured, dropped, etc. */
struct rpcap_stats
{
uint32 ifrecv; /* Packets received by the kernel filter (i.e. pcap_stats.ps_recv) */
uint32 ifdrop; /* Packets dropped by the network interface (e.g. not enough buffers) (i.e. pcap_stats.ps_ifdrop) */
uint32 krnldrop; /* Packets dropped by the kernel filter (i.e. pcap_stats.ps_drop) */
uint32 svrcapt; /* Packets captured by the RPCAP daemon and sent on the network */
};
/* Structure that is needed to set sampling parameters */
struct rpcap_sampling
{
uint8 method; /* Sampling method */
uint8 dummy1; /* Must be zero */
uint16 dummy2; /* Must be zero */
uint32 value; /* Parameter related to the sampling method */
};
/*
* Private data for doing a live capture.
*/
struct pcap_md {
struct pcap_stat stat;
/* XXX */
int use_bpf; /* using kernel filter */
u_long TotPkts; /* can't overflow for 79 hrs on ether */
u_long TotAccepted; /* count accepted by filter */
u_long TotDrops; /* count of dropped packets */
long TotMissed; /* missed by i/f during this run */
long OrigMissed; /* missed by i/f before this run */
char *device; /* device name */
int timeout; /* timeout for buffering */
int must_clear; /* stuff we must clear when we close */
struct pcap *next; /* list of open pcaps that need stuff cleared on close */
#ifdef linux
int sock_packet; /* using Linux 2.0 compatible interface */
int cooked; /* using SOCK_DGRAM rather than SOCK_RAW */
int ifindex; /* interface index of device we're bound to */
int lo_ifindex; /* interface index of the loopback device */
u_int packets_read; /* count of packets read with recvfrom() */
bpf_u_int32 oldmode; /* mode to restore when turning monitor mode off */
u_int tp_version; /* version of tpacket_hdr for mmaped ring */
u_int tp_hdrlen; /* hdrlen of tpacket_hdr for mmaped ring */
#endif /* linux */
#ifdef HAVE_DAG_API
#ifdef HAVE_DAG_STREAMS_API
u_char *dag_mem_bottom;/* DAG card current memory bottom pointer */
u_char *dag_mem_top; /* DAG card current memory top pointer */
#else /* HAVE_DAG_STREAMS_API */
void *dag_mem_base; /* DAG card memory base address */
u_int dag_mem_bottom; /* DAG card current memory bottom offset */
u_int dag_mem_top; /* DAG card current memory top offset */
#endif /* HAVE_DAG_STREAMS_API */
int dag_fcs_bits; /* Number of checksum bits from link layer */
int dag_offset_flags; /* Flags to pass to dag_offset(). */
int dag_stream; /* DAG stream number */
int dag_timeout; /* timeout specified to pcap_open_live.
* Same as in linux above, introduce
* generally?
*/
#endif /* HAVE_DAG_API */
#ifdef HAVE_ZEROCOPY_BPF
/*
* Zero-copy read buffer -- for zero-copy BPF. 'buffer' above will
* alternative between these two actual mmap'd buffers as required.
* As there is a header on the front size of the mmap'd buffer, only
* some of the buffer is exposed to libpcap as a whole via bufsize;
* zbufsize is the true size. zbuffer tracks the current zbuf
* associated with buffer so that it can be used to decide which the
* next buffer to read will be.
*/
u_char *zbuf1, *zbuf2, *zbuffer;
u_int zbufsize;
u_int zerocopy;
u_int interrupted;
struct timespec firstsel;
/*
* If there's currently a buffer being actively processed, then it is
* referenced here; 'buffer' is also pointed at it, but offset by the
* size of the header.
*/
struct bpf_zbuf_header *bzh;
#endif /* HAVE_ZEROCOPY_BPF */
#ifdef HAVE_REMOTE
/*
* There is really a mess with previous variables, and it seems to me that they are not used
* (they are used in pcap_pf.c only). I think we have to start using them.
* The meaning is the following:
*
* - TotPkts: the amount of packets received by the bpf filter, *before* applying the filter
* - TotAccepted: the amount of packets that satisfies the filter
* - TotDrops: the amount of packet that were dropped into the kernel buffer because of lack of space
* - TotMissed: the amount of packets that were dropped by the physical interface; it is basically
* the value of the hardware counter into the card. This number is never put to zero, so this number
* takes into account the *total* number of interface drops starting from the interface power-on.
* - OrigMissed: the amount of packets that were dropped by the interface *when the capture begins*.
* This value is used to detect the number of packets dropped by the interface *during the present
* capture*, so that (ps_ifdrops= TotMissed - OrigMissed).
*/
unsigned int TotNetDrops; /* keeps the number of packets that have been dropped by the network */
/*
* \brief It keeps the number of packets that have been received by the application.
*
* Packets dropped by the kernel buffer are not counted in this variable. The variable is always
* equal to (TotAccepted - TotDrops), except for the case of remote capture, in which we have also
* packets in flight, i.e. that have been transmitted by the remote host, but that have not been
* received (yet) from the client. In this case, (TotAccepted - TotDrops - TotNetDrops) gives a
* wrong result, since this number does not corresponds always to the number of packet received by
* the application. For this reason, in the remote capture we need another variable that takes
* into account of the number of packets actually received by the application.
*/
unsigned int TotCapt;
/*! \brief '1' if we're the network client; needed by several functions (like pcap_setfilter() ) to know if
they have to use the socket or they have to open the local adapter. */
int rmt_clientside;
SOCKET rmt_sockctrl; //!< socket ID of the socket used for the control connection
SOCKET rmt_sockdata; //!< socket ID of the socket used for the data connection
int rmt_flags; //!< we have to save flags, since they are passed by the pcap_open_live(), but they are used by the pcap_startcapture()
int rmt_capstarted; //!< 'true' if the capture is already started (needed to knoe if we have to call the pcap_startcapture()
struct pcap_samp rmt_samp; //!< Keeps the parameters related to the sampling process.
char *currentfilter; //!< Pointer to a buffer (allocated at run-time) that stores the current filter. Needed when flag PCAP_OPENFLAG_NOCAPTURE_RPCAP is turned on.
#endif /* HAVE_REMOTE */
};
/* Messages field coding */
#define RPCAP_MSG_ERROR 1 /* Message that keeps an error notification */
#define RPCAP_MSG_FINDALLIF_REQ 2 /* Request to list all the remote interfaces */
#define RPCAP_MSG_OPEN_REQ 3 /* Request to open a remote device */
#define RPCAP_MSG_STARTCAP_REQ 4 /* Request to start a capture on a remote device */
#define RPCAP_MSG_UPDATEFILTER_REQ 5 /* Send a compiled filter into the remote device */
#define RPCAP_MSG_CLOSE 6 /* Close the connection with the remote peer */
#define RPCAP_MSG_PACKET 7 /* This is a 'data' message, which carries a network packet */
#define RPCAP_MSG_AUTH_REQ 8 /* Message that keeps the authentication parameters */
#define RPCAP_MSG_STATS_REQ 9 /* It requires to have network statistics */
#define RPCAP_MSG_ENDCAP_REQ 10 /* Stops the current capture, keeping the device open */
#define RPCAP_MSG_SETSAMPLING_REQ 11 /* Set sampling parameters */
#define RPCAP_MSG_FINDALLIF_REPLY (128+RPCAP_MSG_FINDALLIF_REQ) /* Keeps the list of all the remote interfaces */
#define RPCAP_MSG_OPEN_REPLY (128+RPCAP_MSG_OPEN_REQ) /* The remote device has been opened correctly */
#define RPCAP_MSG_STARTCAP_REPLY (128+RPCAP_MSG_STARTCAP_REQ) /* The capture is starting correctly */
#define RPCAP_MSG_UPDATEFILTER_REPLY (128+RPCAP_MSG_UPDATEFILTER_REQ) /* The filter has been applied correctly on the remote device */
#define RPCAP_MSG_AUTH_REPLY (128+RPCAP_MSG_AUTH_REQ) /* Sends a message that says 'ok, authorization successful' */
#define RPCAP_MSG_STATS_REPLY (128+RPCAP_MSG_STATS_REQ) /* Message that keeps the network statistics */
#define RPCAP_MSG_ENDCAP_REPLY (128+RPCAP_MSG_ENDCAP_REQ) /* Confirms that the capture stopped successfully */
#define RPCAP_MSG_SETSAMPLING_REPLY (128+RPCAP_MSG_SETSAMPLING_REQ) /* Confirms that the capture stopped successfully */
#define RPCAP_STARTCAPREQ_FLAG_PROMISC 1 /* Enables promiscuous mode (default: disabled) */
#define RPCAP_STARTCAPREQ_FLAG_DGRAM 2 /* Use a datagram (i.e. UDP) connection for the data stream (default: use TCP)*/
#define RPCAP_STARTCAPREQ_FLAG_SERVEROPEN 4 /* The server has to open the data connection toward the client */
#define RPCAP_STARTCAPREQ_FLAG_INBOUND 8 /* Capture only inbound packets (take care: the flag has no effects with promiscuous enabled) */
#define RPCAP_STARTCAPREQ_FLAG_OUTBOUND 16 /* Capture only outbound packets (take care: the flag has no effects with promiscuous enabled) */
#define RPCAP_UPDATEFILTER_BPF 1 /* This code tells us that the filter is encoded with the BPF/NPF syntax */
/* Network error codes */
#define PCAP_ERR_NETW 1 /* Network error */
#define PCAP_ERR_INITTIMEOUT 2 /* The RPCAP initial timeout has expired */
#define PCAP_ERR_AUTH 3 /* Generic authentication error */
#define PCAP_ERR_FINDALLIF 4 /* Generic findalldevs error */
#define PCAP_ERR_NOREMOTEIF 5 /* The findalldevs was ok, but the remote end had no interfaces to list */
#define PCAP_ERR_OPEN 6 /* Generic pcap_open error */
#define PCAP_ERR_UPDATEFILTER 7 /* Generic updatefilter error */
#define PCAP_ERR_GETSTATS 8 /* Generic pcap_stats error */
#define PCAP_ERR_READEX 9 /* Generic pcap_next_ex error */
#define PCAP_ERR_HOSTNOAUTH 10 /* The host is not authorized to connect to this server */
#define PCAP_ERR_REMOTEACCEPT 11 /* Generic pcap_remoteaccept error */
#define PCAP_ERR_STARTCAPTURE 12 /* Generic pcap_startcapture error */
#define PCAP_ERR_ENDCAPTURE 13 /* Generic pcap_endcapture error */
#define PCAP_ERR_RUNTIMETIMEOUT 14 /* The RPCAP run-time timeout has expired */
#define PCAP_ERR_SETSAMPLING 15 /* Error during the settings of sampling parameters */
#define PCAP_ERR_WRONGMSG 16 /* The other end endpoint sent a message which has not been recognized */
#define PCAP_ERR_WRONGVER 17 /* The other end endpoint has a version number that is not compatible with our */
/*
* \}
* // end of private documentation
*/
/*********************************************************
* *
* Exported function prototypes *
* *
*********************************************************/
int pcap_opensource_remote(pcap_t *p, struct pcap_rmtauth *auth);
int pcap_startcapture_remote(pcap_t *fp);
void rpcap_createhdr(struct rpcap_header *header, uint8 type, uint16 value, uint32 length);
int rpcap_deseraddr(struct sockaddr_storage *sockaddrin, struct sockaddr_storage **sockaddrout, char *errbuf);
int rpcap_checkmsg(char *errbuf, SOCKET sock, struct rpcap_header *header, uint8 first, ...);
int rpcap_senderror(SOCKET sock, char *error, unsigned short errcode, char *errbuf);
int rpcap_sendauth(SOCKET sock, struct pcap_rmtauth *auth, char *errbuf);
SOCKET rpcap_remoteact_getsock(const char *host, int *isactive, char *errbuf);
#endif

View file

@ -17,12 +17,12 @@
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\"
.TH PCAP-SAVEFILE @MAN_FILE_FORMATS@ "29 July 2013"
.TH PCAP-SAVEFILE @MAN_FILE_FORMATS@ "8 March 2015"
.SH NAME
pcap-savefile \- libpcap savefile format
.SH DESCRIPTION
NOTE: applications and libraries should, if possible, use libpcap to
read savefiles, rather than having their own code to read savefiles.
read savefiles, rather than having their own code to read savefiles.
If, in the future, a new file format is supported by libpcap,
applications and libraries using libpcap to read savefiles will be able
to read the new format of savefiles, but applications and libraries

View file

@ -194,9 +194,9 @@ septel_inject(pcap_t *handle, const void *buf _U_, size_t size _U_)
* See also pcap(3).
*/
static pcap_t *septel_activate(pcap_t* handle) {
/* Initialize some components of the pcap structure. */
/* Initialize some components of the pcap structure. */
handle->linktype = DLT_MTP2;
handle->bufsize = 0;
/*
@ -232,7 +232,7 @@ pcap_t *septel_create(const char *device, char *ebuf, int *is_ours) {
/* OK, it's probably ours. */
*is_ours = 1;
p = pcap_create_common(device, ebuf, sizeof (struct pcap_septel));
p = pcap_create_common(ebuf, sizeof (struct pcap_septel));
if (p == NULL)
return NULL;
@ -244,9 +244,9 @@ static int septel_stats(pcap_t *p, struct pcap_stat *ps) {
struct pcap_septel *handlep = p->priv;
/*handlep->stat.ps_recv = 0;*/
/*handlep->stat.ps_drop = 0;*/
*ps = handlep->stat;
return 0;
}
@ -276,7 +276,7 @@ static int septel_setfilter(pcap_t *p, struct bpf_program *fp) {
/* Make our private copy of the filter */
if (install_bpf_program(p, fp) < 0) {
snprintf(p->errbuf, sizeof(p->errbuf),
pcap_snprintf(p->errbuf, sizeof(p->errbuf),
"malloc: %s", pcap_strerror(errno));
return -1;
}
@ -291,3 +291,31 @@ septel_setnonblock(pcap_t *p, int nonblock, char *errbuf)
fprintf(errbuf, PCAP_ERRBUF_SIZE, "Non-blocking mode not supported on Septel devices");
return (-1);
}
#ifdef SEPTEL_ONLY
/*
* This libpcap build supports only Septel cards, not regular network
* interfaces.
*/
/*
* There are no regular interfaces, just Septel interfaces.
*/
int
pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
{
*alldevsp = NULL;
return (0);
}
/*
* Attempts to open a regular interface fail.
*/
pcap_t *
pcap_create_interface(const char *device, char *errbuf)
{
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"This version of libpcap only supports Septel cards");
return (NULL);
}
#endif

View file

@ -183,7 +183,7 @@ static int read_client_nbytes(int fd, int count, unsigned char *buf) {
find_unit_by_fd(fd, &chassis, &geoslot, &u);
while (count) {
if ((len = recv(fd, buf, count, 0)) <= 0) return -1; /* read in whatever data was sent to us */
count -= len;
count -= len;
buf += len;
} /* till we have everything we are looking for */
return 0;
@ -208,10 +208,14 @@ static void empty_unit(int chassis, int geoslot) {
empty_unit_iface(u);
if (u->imsg) { /* then if an inbound message buffer exists */
u->imsg = (char *)realloc(u->imsg, 1); /* and re-allocate the old large buffer into a new small one */
if (u->imsg == NULL) { /* oops, realloc call failed */
void *bigger_buffer;
bigger_buffer = (char *)realloc(u->imsg, 1); /* and re-allocate the old large buffer into a new small one */
if (bigger_buffer == NULL) { /* oops, realloc call failed */
fprintf(stderr, "Warning...call to realloc() failed, value of errno is %d\n", errno);
return;
}
u->imsg = bigger_buffer;
}
}
@ -262,7 +266,7 @@ int acn_parse_hosts_file(char *errbuf) { /* returns: -1 = error, 0 = OK */
empty_unit_table();
if ((fp = fopen("/etc/hosts", "r")) == NULL) { /* try to open the hosts file and if it fails */
snprintf(errbuf, PCAP_ERRBUF_SIZE, "Cannot open '/etc/hosts' for reading."); /* return the nohostsfile error response */
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Cannot open '/etc/hosts' for reading."); /* return the nohostsfile error response */
return -1;
}
while (fgets(buf, MAX_LINE_SIZE-1, fp)) { /* while looping over the file */
@ -285,11 +289,11 @@ int acn_parse_hosts_file(char *errbuf) { /* returns: -1 = error, 0 = OK */
geoslot = *(ptr2 + 5) - '0'; /* and geo-slot number */
if (chassis < 1 || chassis > MAX_CHASSIS ||
geoslot < 1 || geoslot > MAX_GEOSLOT) { /* if the chassis and/or slot numbers appear to be bad... */
snprintf(errbuf, PCAP_ERRBUF_SIZE, "Invalid ACN name in '/etc/hosts'."); /* warn the user */
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Invalid ACN name in '/etc/hosts'."); /* warn the user */
continue; /* and ignore the entry */
}
if ((ptr2 = (char *)malloc(strlen(ptr) + 1)) == NULL) {
snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
continue;
}
strcpy(ptr2, ptr); /* copy the IP address into our malloc'ed memory */
@ -402,14 +406,14 @@ static void acn_freealldevs(void) {
static void nonUnified_IOP_port_name(char *buf, size_t bufsize, const char *proto, unit_t *u) {
snprintf(buf, bufsize, "%s_%d_%d", proto, u->chassis, u->geoslot);
pcap_snprintf(buf, bufsize, "%s_%d_%d", proto, u->chassis, u->geoslot);
}
static void unified_IOP_port_name(char *buf, size_t bufsize, const char *proto, unit_t *u, int IOPportnum) {
int portnum;
portnum = ((u->chassis - 1) * 64) + ((u->geoslot - 1) * 8) + IOPportnum + 1;
snprintf(buf, bufsize, "%s_%d", proto, portnum);
pcap_snprintf(buf, bufsize, "%s_%d", proto, portnum);
}
static char *translate_IOP_to_pcap_name(unit_t *u, char *IOPname, bpf_u_int32 iftype) {
@ -553,10 +557,10 @@ static void sort_if_table(void) {
}
if (has_swapped == 0)
return;
}
}
return;
}
static int process_client_data (char *errbuf) { /* returns: -1 = error, 0 = OK */
int chassis, geoslot;
unit_t *u;
@ -568,6 +572,7 @@ static int process_client_data (char *errbuf) { /* returns: -1 = error, 0
char *newname;
bpf_u_int32 interfaceType;
unsigned char flags;
void *bigger_buffer;
prev_iff = 0;
for (chassis = 0; chassis <= MAX_CHASSIS; chassis++) {
@ -577,7 +582,7 @@ static int process_client_data (char *errbuf) { /* returns: -1 = error, 0
ptr = u->imsg; /* point to the start of the msg for this IOP */
while (ptr < (u->imsg + u->len)) {
if ((iff = malloc(sizeof(pcap_if_t))) == NULL) {
snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
return -1;
}
memset((char *)iff, 0, sizeof(pcap_if_t)); /* bzero() is deprecated, replaced with memset() */
@ -586,7 +591,7 @@ static int process_client_data (char *errbuf) { /* returns: -1 = error, 0
if (*ptr) { /* if there is a count for the name */
if ((iff->name = malloc(*ptr + 1)) == NULL) { /* get that amount of space */
snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
return -1;
}
memcpy(iff->name, (ptr + 1), *ptr); /* copy the name into the malloc'ed space */
@ -597,7 +602,7 @@ static int process_client_data (char *errbuf) { /* returns: -1 = error, 0
if (*ptr) { /* if there is a count for the description */
if ((iff->description = malloc(*ptr + 1)) == NULL) { /* get that amount of space */
snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
return -1;
}
memcpy(iff->description, (ptr + 1), *ptr); /* copy the name into the malloc'ed space */
@ -617,15 +622,15 @@ static int process_client_data (char *errbuf) { /* returns: -1 = error, 0
prev_addr = 0;
while (address_count--) {
if ((addr = malloc(sizeof(pcap_addr_t))) == NULL) {
snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
return -1;
}
+ memset((char *)addr, 0, sizeof(pcap_addr_t)); /* bzero() is deprecated, replaced with memset() */
memset((char *)addr, 0, sizeof(pcap_addr_t)); /* bzero() is deprecated, replaced with memset() */
if (iff->addresses == 0) iff->addresses = addr;
if (prev_addr) prev_addr->next = addr; /* insert a forward link */
if (*ptr) { /* if there is a count for the address */
if ((s = malloc(sizeof(struct sockaddr_in))) == NULL) { /* get that amount of space */
snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
return -1;
}
memset((char *)s, 0, sizeof(struct sockaddr_in)); /* bzero() is deprecated, replaced with memset() */
@ -637,7 +642,7 @@ static int process_client_data (char *errbuf) { /* returns: -1 = error, 0
ptr++; /* then forwards one more for the 'length of the address' field */
if (*ptr) { /* process any netmask */
if ((s = malloc(sizeof(struct sockaddr_in))) == NULL) {
snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
return -1;
}
/* bzero() is deprecated, replaced with memset() */
@ -651,7 +656,7 @@ static int process_client_data (char *errbuf) { /* returns: -1 = error, 0
ptr++;
if (*ptr) { /* process any broadcast address */
if ((s = malloc(sizeof(struct sockaddr_in))) == NULL) {
snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
return -1;
}
/* bzero() is deprecated, replaced with memset() */
@ -665,7 +670,7 @@ static int process_client_data (char *errbuf) { /* returns: -1 = error, 0
ptr++;
if (*ptr) { /* process any destination address */
if ((s = malloc(sizeof(struct sockaddr_in))) == NULL) {
snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
return -1;
}
/* bzero() is deprecated, replaced with memset() */
@ -682,10 +687,12 @@ static int process_client_data (char *errbuf) { /* returns: -1 = error, 0
prev_iff = iff;
newname = translate_IOP_to_pcap_name(u, iff->name, interfaceType); /* add a translation entry and get a point to the mangled name */
if ((iff->name = realloc(iff->name, strlen(newname) + 1)) == NULL) { /* we now re-write the name stored in the interface list */
snprintf(errbuf, PCAP_ERRBUF_SIZE, "realloc: %s", pcap_strerror(errno));
bigger_buffer = realloc(iff->name, strlen(newname) + 1));
if (bigger_buffer == NULL) { /* we now re-write the name stored in the interface list */
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "realloc: %s", pcap_strerror(errno));
return -1;
}
iff->name = bigger_buffer;
strcpy(iff->name, newname); /* to this new name */
}
}
@ -816,7 +823,7 @@ static int acn_open_live(const char *name, char *errbuf, int *linktype) { /* re
iface_t *p;
pcap_if_t *alldevsp;
pcap_findalldevs_interfaces(&alldevsp, errbuf);
pcap_platform_finddevs(&alldevsp, errbuf);
for (chassis = 0; chassis <= MAX_CHASSIS; chassis++) { /* scan the table... */
for (geoslot = 0; geoslot <= MAX_GEOSLOT; geoslot++) {
u = &units[chassis][geoslot];
@ -892,7 +899,7 @@ static int pcap_setfilter_acn(pcap_t *handle, struct bpf_program *bpf) {
}
static int pcap_setdirection_acn(pcap_t *handle, pcap_direction_t d) {
snprintf(handle->errbuf, sizeof(handle->errbuf),
pcap_snprintf(handle->errbuf, sizeof(handle->errbuf),
"Setting direction is not supported on ACN adapters");
return -1;
}
@ -951,7 +958,7 @@ static int pcap_read_acn(pcap_t *handle, int max_packets, pcap_handler callback,
pcap_header.caplen = ntohl(*(uint32_t *)&packet_header[8]); /* caplen */
pcap_header.len = ntohl(*(uint32_t *)&packet_header[12]); /* len */
handle->bp = handle->buffer + handle->offset; /* start off the receive pointer at the right spot */
handle->bp = (u_char *)handle->buffer + handle->offset; /* start off the receive pointer at the right spot */
if (acn_read_n_bytes_with_timeout(handle, pcap_header.caplen) == -1) return 0; /* then try to read in the rest of the data */
callback(user, &pcap_header, handle->bp); /* call the user supplied callback function */
@ -981,7 +988,7 @@ static int pcap_activate_sita(pcap_t *handle) {
handle->read_op = pcap_read_acn;
handle->stats_op = pcap_stats_acn;
fd = acn_open_live(handle->opt.source, handle->errbuf,
fd = acn_open_live(handle->opt.device, handle->errbuf,
&handle->linktype);
if (fd == -1)
return PCAP_ERROR;
@ -992,7 +999,7 @@ static int pcap_activate_sita(pcap_t *handle) {
handle->buffer = malloc(handle->bufsize + handle->offset);
if (!handle->buffer) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"malloc: %s", pcap_strerror(errno));
pcap_cleanup_acn(handle);
return PCAP_ERROR;
@ -1007,13 +1014,36 @@ static int pcap_activate_sita(pcap_t *handle) {
return 0;
}
pcap_t *pcap_create_interface(const char *device, char *ebuf) {
pcap_t *pcap_create_interface(const char *device _U_, char *ebuf) {
pcap_t *p;
p = pcap_create_common(device, ebuf, 0);
p = pcap_create_common(ebuf, 0);
if (p == NULL)
return (NULL);
p->activate_op = pcap_activate_sita;
return (p);
}
int pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf) {
//printf("pcap_findalldevs()\n"); // fulko
*alldevsp = 0; /* initialize the returned variables before we do anything */
strcpy(errbuf, "");
if (acn_parse_hosts_file(errbuf)) /* scan the hosts file for potential IOPs */
{
//printf("pcap_findalldevs() returning BAD after parsehosts\n"); // fulko
return -1;
}
//printf("pcap_findalldevs() got hostlist now finding devs\n"); // fulko
if (acn_findalldevs(errbuf)) /* then ask the IOPs for their monitorable devices */
{
//printf("pcap_findalldevs() returning BAD after findalldevs\n"); // fulko
return -1;
}
*alldevsp = acn_if_list;
acn_if_list = 0; /* then forget our list head, because someone will call pcap_freealldevs() to empty the malloc'ed stuff */
//printf("pcap_findalldevs() returning ZERO OK\n"); // fulko
return 0;
}

View file

@ -16,6 +16,9 @@
#include <unistd.h>
#include <snf.h>
#if SNF_VERSION_API >= 0x0003
#define SNF_HAVE_INJECT_API
#endif
#include "pcap-int.h"
#include "pcap-snf.h"
@ -26,6 +29,9 @@
struct pcap_snf {
snf_handle_t snf_handle; /* opaque device handle */
snf_ring_t snf_ring; /* opaque device ring handle */
#ifdef SNF_HAVE_INJECT_API
snf_inject_t snf_inj; /* inject handle, if inject is used */
#endif
int snf_timeout;
int snf_boardnum;
};
@ -41,10 +47,11 @@ static int
snf_pcap_stats(pcap_t *p, struct pcap_stat *ps)
{
struct snf_ring_stats stats;
struct pcap_snf *snfps = p->priv;
int rc;
if ((rc = snf_ring_getstats(ps->snf_ring, &stats))) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "snf_get_stats: %s",
if ((rc = snf_ring_getstats(snfps->snf_ring, &stats))) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "snf_get_stats: %s",
pcap_strerror(rc));
return -1;
}
@ -57,12 +64,12 @@ snf_pcap_stats(pcap_t *p, struct pcap_stat *ps)
static void
snf_platform_cleanup(pcap_t *p)
{
struct pcap_snf *ps;
if (p == NULL)
return;
ps = p->priv;
struct pcap_snf *ps = p->priv;
#ifdef SNF_HAVE_INJECT_API
if (ps->snf_inj)
snf_inject_close(ps->snf_inj);
#endif
snf_ring_close(ps->snf_ring);
snf_close(ps->snf_handle);
pcap_cleanup_live_common(p);
@ -96,14 +103,23 @@ snf_setnonblock(pcap_t *p, int nonblock, char *errbuf)
static inline
struct timeval
snf_timestamp_to_timeval(const int64_t ts_nanosec)
snf_timestamp_to_timeval(const int64_t ts_nanosec, const int tstamp_precision)
{
struct timeval tv;
int32_t rem;
long tv_nsec;
if (ts_nanosec == 0)
return (struct timeval) { 0, 0 };
tv.tv_sec = ts_nanosec / _NSEC_PER_SEC;
tv.tv_usec = (ts_nanosec % _NSEC_PER_SEC) / 1000;
tv_nsec = (ts_nanosec % _NSEC_PER_SEC);
/* libpcap expects tv_usec to be nanos if using nanosecond precision. */
if (tstamp_precision == PCAP_TSTAMP_PRECISION_NANO)
tv.tv_usec = tv_nsec;
else
tv.tv_usec = tv_nsec / 1000;
return tv;
}
@ -114,11 +130,13 @@ snf_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
struct pcap_pkthdr hdr;
int i, flags, err, caplen, n;
struct snf_recv_req req;
int nonblock, timeout;
if (!p || cnt == 0)
if (!p)
return -1;
n = 0;
timeout = ps->snf_timeout;
while (n < cnt || PACKET_COUNT_IS_UNLIMITED(cnt)) {
/*
* Has "pcap_breakloop()" been called?
@ -132,15 +150,18 @@ snf_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
}
}
err = snf_ring_recv(ps->snf_ring, ps->snf_timeout, &req);
err = snf_ring_recv(ps->snf_ring, timeout, &req);
if (err) {
if (err == EBUSY || err == EAGAIN)
return (0);
if (err == EINTR)
if (err == EBUSY || err == EAGAIN) {
return (n);
}
else if (err == EINTR) {
timeout = 0;
continue;
if (err != 0) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "snf_read: %s",
}
else {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "snf_read: %s",
pcap_strerror(err));
return -1;
}
@ -152,12 +173,17 @@ snf_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
if ((p->fcode.bf_insns == NULL) ||
bpf_filter(p->fcode.bf_insns, req.pkt_addr, req.length, caplen)) {
hdr.ts = snf_timestamp_to_timeval(req.timestamp);
hdr.ts = snf_timestamp_to_timeval(req.timestamp, p->opt.tstamp_precision);
hdr.caplen = caplen;
hdr.len = req.length;
callback(user, &hdr, req.pkt_addr);
}
n++;
/* After one successful packet is received, we won't block
* again for that timeout. */
if (timeout != 0)
timeout = 0;
}
return (n);
}
@ -184,30 +210,55 @@ snf_setfilter(pcap_t *p, struct bpf_program *fp)
static int
snf_inject(pcap_t *p, const void *buf _U_, size_t size _U_)
{
strlcpy(p->errbuf, "Sending packets isn't supported with snf",
#ifdef SNF_HAVE_INJECT_API
struct pcap_snf *ps = p->priv;
int rc;
if (ps->snf_inj == NULL) {
rc = snf_inject_open(ps->snf_boardnum, 0, &ps->snf_inj);
if (rc) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"snf_inject_open: %s", pcap_strerror(rc));
return (-1);
}
}
rc = snf_inject_send(ps->snf_inj, -1, 0, buf, size);
if (!rc) {
return (size);
}
else {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "snf_inject_send: %s",
pcap_strerror(rc));
return (-1);
}
#else
strlcpy(p->errbuf, "Sending packets isn't supported with this snf version",
PCAP_ERRBUF_SIZE);
return (-1);
#endif
}
static int
snf_activate(pcap_t* p)
{
struct pcap_snf *ps = p->priv;
char *device = p->opt.source;
char *device = p->opt.device;
const char *nr = NULL;
int err;
int flags = 0;
int flags = -1, ring_id = -1;
if (device == NULL) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"device is NULL: %s", pcap_strerror(errno));
return -1;
}
/* In Libpcap, we set pshared by default if NUM_RINGS is set to > 1.
* Since libpcap isn't thread-safe */
if ((nr = getenv("SNF_NUM_RINGS")) && *nr && atoi(nr) > 1)
flags |= SNF_F_PSHARED;
if ((nr = getenv("SNF_FLAGS")) && *nr)
flags = strtol(nr, NULL, 0);
else if ((nr = getenv("SNF_NUM_RINGS")) && *nr && atoi(nr) > 1)
flags = SNF_F_PSHARED;
else
nr = NULL;
@ -218,15 +269,19 @@ snf_activate(pcap_t* p)
flags, /* may want pshared */
&ps->snf_handle);
if (err != 0) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"snf_open failed: %s", pcap_strerror(err));
return -1;
}
err = snf_ring_open(ps->snf_handle, &ps->snf_ring);
if ((nr = getenv("SNF_PCAP_RING_ID")) && *nr) {
ring_id = (int) strtol(nr, NULL, 0);
}
err = snf_ring_open_id(ps->snf_handle, ring_id, &ps->snf_ring);
if (err != 0) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"snf_ring_open failed: %s", pcap_strerror(err));
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"snf_ring_open_id(ring=%d) failed: %s",
ring_id, pcap_strerror(err));
return -1;
}
@ -237,7 +292,7 @@ snf_activate(pcap_t* p)
err = snf_start(ps->snf_handle);
if (err != 0) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"snf_start failed: %s", pcap_strerror(err));
return -1;
}
@ -256,12 +311,104 @@ snf_activate(pcap_t* p)
p->setnonblock_op = snf_setnonblock;
p->stats_op = snf_pcap_stats;
p->cleanup_op = snf_platform_cleanup;
#ifdef SNF_HAVE_INJECT_API
ps->snf_inj = NULL;
#endif
return 0;
}
#define MAX_DESC_LENGTH 128
int
snf_findalldevs(pcap_if_t **devlistp, char *errbuf)
{
pcap_if_t *devlist = NULL,*curdev,*prevdev;
pcap_addr_t *curaddr;
struct snf_ifaddrs *ifaddrs, *ifa;
char desc[MAX_DESC_LENGTH];
int ret;
if (snf_init(SNF_VERSION_API))
return (-1);
if (snf_getifaddrs(&ifaddrs) || ifaddrs == NULL)
{
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"snf_getifaddrs: %s", pcap_strerror(errno));
return (-1);
}
ifa = ifaddrs;
while (ifa)
{
/*
* Allocate a new entry
*/
curdev = (pcap_if_t *)malloc(sizeof(pcap_if_t));
if (curdev == NULL) {
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"snf_findalldevs malloc: %s", pcap_strerror(errno));
return (-1);
}
if (devlist == NULL) /* save first entry */
devlist = curdev;
else
prevdev->next = curdev;
/*
* Fill in the entry.
*/
curdev->next = NULL;
curdev->name = strdup(ifa->snf_ifa_name);
if (curdev->name == NULL) {
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"snf_findalldevs strdup: %s", pcap_strerror(errno));
free(curdev);
return (-1);
}
(void)pcap_snprintf(desc,MAX_DESC_LENGTH,"Myricom snf%d",
ifa->snf_ifa_portnum);
curdev->description = strdup(desc);
if (curdev->description == NULL) {
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"snf_findalldevs strdup1: %s", pcap_strerror(errno));
free(curdev->name);
free(curdev);
return (-1);
}
curdev->addresses = NULL;
curdev->flags = 0;
curaddr = (pcap_addr_t *)malloc(sizeof(pcap_addr_t));
if (curaddr == NULL) {
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"snf_findalldevs malloc1: %s", pcap_strerror(errno));
free(curdev->description);
free(curdev->name);
free(curdev);
return (-1);
}
curdev->addresses = curaddr;
curaddr->next = NULL;
curaddr->addr = (struct sockaddr*)malloc(sizeof(struct sockaddr_storage));
if (curaddr->addr == NULL) {
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"malloc2: %s", pcap_strerror(errno));
free(curdev->description);
free(curdev->name);
free(curaddr);
free(curdev);
return (-1);
}
curaddr->addr->sa_family = AF_INET;
curaddr->netmask = NULL;
curaddr->broadaddr = NULL;
curaddr->dstaddr = NULL;
curaddr->next = NULL;
prevdev = curdev;
ifa = ifa->snf_ifa_next;
}
snf_freeifaddrs(ifaddrs);
*devlistp = devlist;
/*
* There are no platform-specific devices since each device
* exists as a regular Ethernet device.
@ -320,12 +467,54 @@ snf_create(const char *device, char *ebuf, int *is_ours)
/* OK, it's probably ours. */
*is_ours = 1;
p = pcap_create_common(device, ebuf, sizeof (struct pcap_snf));
p = pcap_create_common(ebuf, sizeof (struct pcap_snf));
if (p == NULL)
return NULL;
ps = p->priv;
/*
* We support microsecond and nanosecond time stamps.
*/
p->tstamp_precision_count = 2;
p->tstamp_precision_list = malloc(2 * sizeof(u_int));
if (p->tstamp_precision_list == NULL) {
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
pcap_strerror(errno));
pcap_close(p);
return NULL;
}
p->tstamp_precision_list[0] = PCAP_TSTAMP_PRECISION_MICRO;
p->tstamp_precision_list[1] = PCAP_TSTAMP_PRECISION_NANO;
p->activate_op = snf_activate;
ps->snf_boardnum = boardnum;
return p;
}
#ifdef SNF_ONLY
/*
* This libpcap build supports only SNF cards, not regular network
* interfaces..
*/
/*
* There are no regular interfaces, just DAG interfaces.
*/
int
pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
{
*alldevsp = NULL;
return (0);
}
/*
* Attempts to open a regular interface fail.
*/
pcap_t *
pcap_create_interface(const char *device, char *errbuf)
{
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"This version of libpcap only supports SNF cards");
return NULL;
}
#endif

View file

@ -130,11 +130,11 @@ pcap_read_snit(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
if (cc < 0) {
if (errno == EWOULDBLOCK)
return (0);
snprintf(p->errbuf, sizeof(p->errbuf), "pcap_read: %s",
pcap_snprintf(p->errbuf, sizeof(p->errbuf), "pcap_read: %s",
pcap_strerror(errno));
return (-1);
}
bp = p->buffer;
bp = (u_char *)p->buffer;
} else
bp = p->bp;
@ -211,7 +211,7 @@ static int
pcap_inject_snit(pcap_t *p, const void *buf, size_t size)
{
struct strbuf ctl, data;
/*
* XXX - can we just do
*
@ -223,7 +223,7 @@ pcap_inject_snit(pcap_t *p, const void *buf, size_t size)
data.len = size;
ret = putmsg(p->fd, &ctl, &data);
if (ret == -1) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
pcap_strerror(errno));
return (-1);
}
@ -247,7 +247,7 @@ nit_setflags(pcap_t *p)
si.ic_len = sizeof(zero);
si.ic_dp = (char *)&zero;
if (ioctl(p->fd, I_STR, (char *)&si) < 0) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "NIOCSCHUNK: %s",
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "NIOCSCHUNK: %s",
pcap_strerror(errno));
return (-1);
}
@ -260,7 +260,7 @@ nit_setflags(pcap_t *p)
si.ic_len = sizeof(timeout);
si.ic_dp = (char *)&timeout;
if (ioctl(p->fd, I_STR, (char *)&si) < 0) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "NIOCSTIME: %s",
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "NIOCSTIME: %s",
pcap_strerror(errno));
return (-1);
}
@ -272,7 +272,7 @@ nit_setflags(pcap_t *p)
si.ic_len = sizeof(flags);
si.ic_dp = (char *)&flags;
if (ioctl(p->fd, I_STR, (char *)&si) < 0) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "NIOCSFLAGS: %s",
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "NIOCSFLAGS: %s",
pcap_strerror(errno));
return (-1);
}
@ -286,7 +286,7 @@ pcap_activate_snit(pcap_t *p)
struct ifreq ifr; /* interface request struct */
int chunksize = CHUNKSIZE;
int fd;
static char dev[] = "/dev/nit";
static const char dev[] = "/dev/nit";
if (p->opt.rfmon) {
/*
@ -320,19 +320,19 @@ pcap_activate_snit(pcap_t *p)
if (fd < 0 && errno == EACCES)
p->fd = fd = open(dev, O_RDONLY);
if (fd < 0) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s", dev,
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s", dev,
pcap_strerror(errno));
goto bad;
}
/* arrange to get discrete messages from the STREAM and use NIT_BUF */
if (ioctl(fd, I_SRDOPT, (char *)RMSGD) < 0) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "I_SRDOPT: %s",
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "I_SRDOPT: %s",
pcap_strerror(errno));
goto bad;
}
if (ioctl(fd, I_PUSH, "nbuf") < 0) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "push nbuf: %s",
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "push nbuf: %s",
pcap_strerror(errno));
goto bad;
}
@ -342,19 +342,24 @@ pcap_activate_snit(pcap_t *p)
si.ic_len = sizeof(chunksize);
si.ic_dp = (char *)&chunksize;
if (ioctl(fd, I_STR, (char *)&si) < 0) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "NIOCSCHUNK: %s",
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "NIOCSCHUNK: %s",
pcap_strerror(errno));
goto bad;
}
/* request the interface */
strncpy(ifr.ifr_name, p->opt.source, sizeof(ifr.ifr_name));
strncpy(ifr.ifr_name, p->opt.device, sizeof(ifr.ifr_name));
ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0';
si.ic_cmd = NIOCBIND;
si.ic_len = sizeof(ifr);
si.ic_dp = (char *)&ifr;
if (ioctl(fd, I_STR, (char *)&si) < 0) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "NIOCBIND: %s: %s",
/*
* XXX - is there an error that means "no such device"?
* Is there one that means "that device doesn't support
* STREAMS NIT"?
*/
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "NIOCBIND: %s: %s",
ifr.ifr_name, pcap_strerror(errno));
goto bad;
}
@ -364,7 +369,7 @@ pcap_activate_snit(pcap_t *p)
si.ic_len = sizeof(p->snapshot);
si.ic_dp = (char *)&p->snapshot;
if (ioctl(fd, I_STR, (char *)&si) < 0) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "NIOCSSNAP: %s",
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "NIOCSSNAP: %s",
pcap_strerror(errno));
goto bad;
}
@ -378,7 +383,7 @@ pcap_activate_snit(pcap_t *p)
p->linktype = DLT_EN10MB;
p->bufsize = BUFSPACE;
p->buffer = (u_char *)malloc(p->bufsize);
p->buffer = malloc(p->bufsize);
if (p->buffer == NULL) {
strlcpy(p->errbuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
goto bad;
@ -426,11 +431,11 @@ pcap_activate_snit(pcap_t *p)
}
pcap_t *
pcap_create_interface(const char *device, char *ebuf)
pcap_create_interface(const char *device _U_, char *ebuf)
{
pcap_t *p;
p = pcap_create_common(device, ebuf, sizeof (struct pcap_snit));
p = pcap_create_common(ebuf, sizeof (struct pcap_snit));
if (p == NULL)
return (NULL);
@ -438,8 +443,18 @@ pcap_create_interface(const char *device, char *ebuf)
return (p);
}
/*
* XXX - there's probably a NIOCBIND error that means "that device
* doesn't support NIT"; if so, we should try an NIOCBIND and use that.
*/
static int
can_be_bound(const char *name _U_)
{
return (1);
}
int
pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
{
return (0);
return (pcap_findalldevs_interfaces(alldevsp, errbuf, can_be_bound));
}

View file

@ -95,7 +95,7 @@ pcap_read_snoop(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
case EWOULDBLOCK:
return (0); /* XXX */
}
snprintf(p->errbuf, sizeof(p->errbuf),
pcap_snprintf(p->errbuf, sizeof(p->errbuf),
"read: %s", pcap_strerror(errno));
return (-1);
}
@ -114,7 +114,7 @@ pcap_read_snoop(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
caplen = (datalen < p->snapshot) ? datalen : p->snapshot;
cp = (u_char *)(sh + 1) + p->offset; /* XXX */
/*
/*
* XXX unfortunately snoop loopback isn't exactly like
* BSD's. The address family is encoded in the first 2
* bytes rather than the first 4 bytes! Luckily the last
@ -150,12 +150,12 @@ pcap_inject_snoop(pcap_t *p, const void *buf, size_t size)
*/
ret = write(p->fd, buf, size);
if (ret == -1) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
pcap_strerror(errno));
return (-1);
}
return (ret);
}
}
static int
pcap_stats_snoop(pcap_t *p, struct pcap_stat *ps)
@ -167,7 +167,7 @@ pcap_stats_snoop(pcap_t *p, struct pcap_stat *ps)
rs = &rawstats;
memset(rs, 0, sizeof(*rs));
if (ioctl(p->fd, SIOCRAWSTATS, (char *)rs) < 0) {
snprintf(p->errbuf, sizeof(p->errbuf),
pcap_snprintf(p->errbuf, sizeof(p->errbuf),
"SIOCRAWSTATS: %s", pcap_strerror(errno));
return (-1);
}
@ -212,22 +212,29 @@ pcap_activate_snoop(pcap_t *p)
fd = socket(PF_RAW, SOCK_RAW, RAWPROTO_SNOOP);
if (fd < 0) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "snoop socket: %s",
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "snoop socket: %s",
pcap_strerror(errno));
goto bad;
}
p->fd = fd;
memset(&sr, 0, sizeof(sr));
sr.sr_family = AF_RAW;
(void)strncpy(sr.sr_ifname, p->opt.source, sizeof(sr.sr_ifname));
(void)strncpy(sr.sr_ifname, p->opt.device, sizeof(sr.sr_ifname));
if (bind(fd, (struct sockaddr *)&sr, sizeof(sr))) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "snoop bind: %s",
/*
* XXX - there's probably a particular bind error that
* means "there's no such device" and a particular bind
* error that means "that device doesn't support snoop";
* they might be the same error, if they both end up
* meaning "snoop doesn't know about that device".
*/
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "snoop bind: %s",
pcap_strerror(errno));
goto bad;
}
memset(&sf, 0, sizeof(sf));
if (ioctl(fd, SIOCADDSNOOP, &sf) < 0) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "SIOCADDSNOOP: %s",
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "SIOCADDSNOOP: %s",
pcap_strerror(errno));
goto bad;
}
@ -239,19 +246,19 @@ pcap_activate_snoop(pcap_t *p)
/*
* XXX hack - map device name to link layer type
*/
if (strncmp("et", p->opt.source, 2) == 0 || /* Challenge 10 Mbit */
strncmp("ec", p->opt.source, 2) == 0 || /* Indigo/Indy 10 Mbit,
if (strncmp("et", p->opt.device, 2) == 0 || /* Challenge 10 Mbit */
strncmp("ec", p->opt.device, 2) == 0 || /* Indigo/Indy 10 Mbit,
O2 10/100 */
strncmp("ef", p->opt.source, 2) == 0 || /* O200/2000 10/100 Mbit */
strncmp("eg", p->opt.source, 2) == 0 || /* Octane/O2xxx/O3xxx Gigabit */
strncmp("gfe", p->opt.source, 3) == 0 || /* GIO 100 Mbit */
strncmp("fxp", p->opt.source, 3) == 0 || /* Challenge VME Enet */
strncmp("ep", p->opt.source, 2) == 0 || /* Challenge 8x10 Mbit EPLEX */
strncmp("vfe", p->opt.source, 3) == 0 || /* Challenge VME 100Mbit */
strncmp("fa", p->opt.source, 2) == 0 ||
strncmp("qaa", p->opt.source, 3) == 0 ||
strncmp("cip", p->opt.source, 3) == 0 ||
strncmp("el", p->opt.source, 2) == 0) {
strncmp("ef", p->opt.device, 2) == 0 || /* O200/2000 10/100 Mbit */
strncmp("eg", p->opt.device, 2) == 0 || /* Octane/O2xxx/O3xxx Gigabit */
strncmp("gfe", p->opt.device, 3) == 0 || /* GIO 100 Mbit */
strncmp("fxp", p->opt.device, 3) == 0 || /* Challenge VME Enet */
strncmp("ep", p->opt.device, 2) == 0 || /* Challenge 8x10 Mbit EPLEX */
strncmp("vfe", p->opt.device, 3) == 0 || /* Challenge VME 100Mbit */
strncmp("fa", p->opt.device, 2) == 0 ||
strncmp("qaa", p->opt.device, 3) == 0 ||
strncmp("cip", p->opt.device, 3) == 0 ||
strncmp("el", p->opt.device, 2) == 0) {
p->linktype = DLT_EN10MB;
p->offset = RAW_HDRPAD(sizeof(struct ether_header));
ll_hdrlen = sizeof(struct ether_header);
@ -284,26 +291,26 @@ pcap_activate_snoop(pcap_t *p)
p->dlt_list[1] = DLT_DOCSIS;
p->dlt_count = 2;
}
} else if (strncmp("ipg", p->opt.source, 3) == 0 ||
strncmp("rns", p->opt.source, 3) == 0 || /* O2/200/2000 FDDI */
strncmp("xpi", p->opt.source, 3) == 0) {
} else if (strncmp("ipg", p->opt.device, 3) == 0 ||
strncmp("rns", p->opt.device, 3) == 0 || /* O2/200/2000 FDDI */
strncmp("xpi", p->opt.device, 3) == 0) {
p->linktype = DLT_FDDI;
p->offset = 3; /* XXX yeah? */
ll_hdrlen = 13;
} else if (strncmp("ppp", p->opt.source, 3) == 0) {
} else if (strncmp("ppp", p->opt.device, 3) == 0) {
p->linktype = DLT_RAW;
ll_hdrlen = 0; /* DLT_RAW meaning "no PPP header, just the IP packet"? */
} else if (strncmp("qfa", p->opt.source, 3) == 0) {
} else if (strncmp("qfa", p->opt.device, 3) == 0) {
p->linktype = DLT_IP_OVER_FC;
ll_hdrlen = 24;
} else if (strncmp("pl", p->opt.source, 2) == 0) {
} else if (strncmp("pl", p->opt.device, 2) == 0) {
p->linktype = DLT_RAW;
ll_hdrlen = 0; /* Cray UNICOS/mp pseudo link */
} else if (strncmp("lo", p->opt.source, 2) == 0) {
} else if (strncmp("lo", p->opt.device, 2) == 0) {
p->linktype = DLT_NULL;
ll_hdrlen = 4;
} else {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"snoop: unknown physical layer type");
goto bad;
}
@ -323,9 +330,9 @@ pcap_activate_snoop(pcap_t *p)
* the MTU first and, if that succeeds, trim the snap length
* to be no greater than the MTU.
*/
(void)strncpy(ifr.ifr_name, p->opt.source, sizeof(ifr.ifr_name));
(void)strncpy(ifr.ifr_name, p->opt.device, sizeof(ifr.ifr_name));
if (ioctl(fd, SIOCGIFMTU, (char *)&ifr) < 0) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "SIOCGIFMTU: %s",
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "SIOCGIFMTU: %s",
pcap_strerror(errno));
goto bad;
}
@ -359,21 +366,21 @@ pcap_activate_snoop(pcap_t *p)
if (snooplen < 0)
snooplen = 0;
if (ioctl(fd, SIOCSNOOPLEN, &snooplen) < 0) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "SIOCSNOOPLEN: %s",
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "SIOCSNOOPLEN: %s",
pcap_strerror(errno));
goto bad;
}
v = 1;
if (ioctl(fd, SIOCSNOOPING, &v) < 0) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "SIOCSNOOPING: %s",
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "SIOCSNOOPING: %s",
pcap_strerror(errno));
goto bad;
}
p->bufsize = 4096; /* XXX */
p->buffer = (u_char *)malloc(p->bufsize);
p->buffer = malloc(p->bufsize);
if (p->buffer == NULL) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "malloc: %s",
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "malloc: %s",
pcap_strerror(errno));
goto bad;
}
@ -399,11 +406,11 @@ pcap_activate_snoop(pcap_t *p)
}
pcap_t *
pcap_create_interface(const char *device, char *ebuf)
pcap_create_interface(const char *device _U_, char *ebuf)
{
pcap_t *p;
p = pcap_create_common(device, ebuf, sizeof (struct pcap_snoop));
p = pcap_create_common(ebuf, sizeof (struct pcap_snoop));
if (p == NULL)
return (NULL);
@ -411,8 +418,18 @@ pcap_create_interface(const char *device, char *ebuf)
return (p);
}
/*
* XXX - there's probably a particular bind error that means "that device
* doesn't support snoop"; if so, we should try a bind and use that.
*/
static int
can_be_bound(const char *name _U_)
{
return (1);
}
int
pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
{
return (0);
return (pcap_findalldevs_interfaces(alldevsp, errbuf, can_be_bound));
}

View file

@ -28,6 +28,35 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Copyright (C) 1999 WIDE Project.
* 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. Neither the name of the project 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 PROJECT 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 PROJECT 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 pcap_stdinc_h
#define pcap_stdinc_h
@ -45,39 +74,53 @@
#include <time.h>
#include <io.h>
#include "bittypes.h"
#include "IP6_misc.h"
#define caddr_t char*
#include <ws2tcpip.h>
#if defined(_MSC_VER)
#define snprintf _snprintf
#define vsnprintf _vsnprintf
#define strdup _strdup
/*
* MSVC.
*/
#if _MSC_VER >= 1800
/*
* VS 2013 or newer; we have <inttypes.h>.
*/
#include <inttypes.h>
#define u_int8_t uint8_t
#define u_int16_t uint16_t
#define u_int32_t uint32_t
#define u_int64_t uint64_t
#else
/*
* Earlier VS; we have to define this stuff ourselves.
*/
#ifndef HAVE_U_INT8_T
typedef unsigned char u_int8_t;
typedef signed char int8_t;
#endif
#ifndef HAVE_U_INT16_T
typedef unsigned short u_int16_t;
typedef signed short int16_t;
#endif
#ifndef HAVE_U_INT32_T
typedef unsigned int u_int32_t;
typedef signed int int32_t;
#endif
#ifndef HAVE_U_INT64_T
#ifdef _MSC_EXTENSIONS
typedef unsigned _int64 u_int64_t;
typedef _int64 int64_t;
#else /* _MSC_EXTENSIONS */
typedef unsigned long long u_int64_t;
typedef long long int64_t;
#endif
#endif
#endif
#elif defined(__MINGW32__)
#include <stdint.h>
#endif
#define inline __inline
#ifdef __MINGW32__
#include <stdint.h>
#else
#ifndef _UINTPTR_T_DEFINED
#ifdef _WIN64
typedef unsigned __int64 uintptr_t;
#else
typedef _W64 unsigned int uintptr_t;
#endif
#define _UINTPTR_T_DEFINED
#endif
#ifndef _INTPTR_T_DEFINED
#ifdef _WIN64
typedef __int64 intptr_t;
#else
typedef _W64 int intptr_t;
#endif
#define _INTPTR_T_DEFINED
#endif
#endif /*__MINGW32__*/
#endif /* pcap_stdinc_h */

1284
contrib/libpcap/pcap-tc.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009 Felix Obenhuber
* Copyright (c) 2008 CACE Technologies, Davis (California)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -11,9 +11,9 @@
* 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.
* 3. Neither the name of CACE Technologies 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 COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@ -29,9 +29,26 @@
*
*/
/*
* Prototypes for SocketCAN related functions
*/
pcap_t* canusb_create(const char *device, char *ebuf, int *is_ours);
int canusb_findalldevs(pcap_if_t **pdevlist, char* errbuf);
#ifndef __PCAP_TC_H__
#define __PCAP_TC_H__
/*
* needed because gcc headers do not have C_ASSERT
*/
#ifndef C_ASSERT
#define C_ASSERT(a)
#endif
#include <TcApi.h>
/*
* functions used effectively by the pcap library
*/
pcap_t *
TcCreate(const char *device, char *ebuf, int *is_ours);
int
TcFindAllDevs(pcap_if_t **alldevsp, char *errbuf);
#endif

View file

@ -19,7 +19,7 @@
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\"
.TH PCAP-TSTAMP @MAN_MISC_INFO@ "21 December 2013"
.TH PCAP-TSTAMP @MAN_MISC_INFO@ "8 March 2015"
.SH NAME
pcap-tstamp \- packet time stamps in libpcap
.SH DESCRIPTION
@ -104,12 +104,12 @@ precision of this time stamp is unspecified; it might or might not be
synchronized with the host operating system's clock.
.TP 5
.BR PCAP_TSTAMP_HOST_LOWPREC " - " host_lowprec
Time stamp provided by the host on which the capture is being done.
Time stamp provided by the host on which the capture is being done.
This is a low-precision time stamp, synchronized with the host operating
system's clock.
.TP 5
.BR PCAP_TSTAMP_HOST_HIPREC " - " host_hiprec
Time stamp provided by the host on which the capture is being done.
Time stamp provided by the host on which the capture is being done.
This is a high-precision time stamp; it might or might not be
synchronized with the host operating system's clock. It might be more
expensive to fetch than
@ -125,8 +125,51 @@ Time stamp provided by the network adapter on which the capture is being
done. This is a high-precision time stamp; it is not synchronized with
the host operating system's clock.
.RE
.LP
By default, when performing a live capture or reading from a savefile,
time stamps are supplied as seconds since January 1, 1970, 00:00:00 UTC,
and microseconds since that seconds value, even if higher-resolution
time stamps are available from the capture device or in the savefile.
If, when reading a savefile, the time stamps in the file have a higher
resolution than one microsecond, the additional digits of resolution are
discarded.
.LP
The
.BR pcap_set_tstamp_precision (3PCAP)
routine can be used after a
.B pcap_create()
call and after a
.B pcap_activate()
call to specify the resolution of the time stamps to get for the device.
If the hardware or software cannot supply a higher-resolution time
stamp, the
.B pcap_set_tstamp_precision()
call will fail, and the time stamps supplied after the
.B pcap_activate()
call will have microsecond resolution.
.LP
When opening a savefile, the
.BR pcap_open_offline_with_tstamp_precision (3PCAP)
and
.BR pcap_fopen_offline_with_tstamp_precision (3PCAP)
routines can be used to specify the resolution of time stamps to be read
from the file; if the time stamps in the file have a lower resolution,
the fraction-of-a-second portion of the time stamps will be scaled to
the specified resolution.
.LP
The
.BR pcap_get_tstamp_precision (3PCAP)
routine returns the resolution of time stamps that will be supplied;
when capturing packets, this does not reflect the actual precision of
the time stamp supplied by the hardware or operating system and, when
reading a savefile, this does not indicate the actual precision of time
stamps in the file.
.SH SEE ALSO
pcap_set_tstamp_type(3PCAP),
pcap_list_tstamp_types(3PCAP),
pcap_tstamp_type_val_to_name(3PCAP),
pcap_tstamp_type_name_to_val(3PCAP)
pcap_tstamp_type_name_to_val(3PCAP),
pcap_set_tstamp_precision(3PCAP),
pcap_open_offline_with_tstamp_precision(3PCAP),
pcap_fopen_offline_with_tstamp_precision(3PCAP),
pcap_get_tstamp_precision(3PCAP)

View file

@ -11,8 +11,8 @@
* 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
* 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
@ -32,7 +32,7 @@
* Modifications: Kris Katterjohn <katterjohn@gmail.com>
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
@ -139,23 +139,24 @@ static int usb_setdirection_linux(pcap_t *, pcap_direction_t);
static void usb_cleanup_linux_mmap(pcap_t *);
/* facility to add an USB device to the device list*/
static int
static int
usb_dev_add(pcap_if_t** alldevsp, int n, char *err_str)
{
char dev_name[10];
char dev_descr[30];
snprintf(dev_name, 10, USB_IFACE"%d", n);
snprintf(dev_descr, 30, "USB bus number %d", n);
char dev_descr[30];
pcap_snprintf(dev_name, 10, USB_IFACE"%d", n);
pcap_snprintf(dev_descr, 30, "USB bus number %d", n);
if (pcap_add_if(alldevsp, dev_name, 0,
if (pcap_add_if(alldevsp, dev_name, 0,
dev_descr, err_str) < 0)
return -1;
return 0;
return 0;
}
int
int
usb_findalldevs(pcap_if_t **alldevsp, char *err_str)
{
int fd;
struct dirent* data;
int ret = 0;
DIR* dir;
@ -163,7 +164,46 @@ usb_findalldevs(pcap_if_t **alldevsp, char *err_str)
char* name;
size_t len;
/* try scanning sysfs usb bus directory */
/*
* Do we have a "scan all buses" device?
* First, try the binary device.
*/
fd = open(LINUX_USB_MON_DEV"0", O_RDONLY, 0);
if (fd >= 0) {
/*
* Yes.
*/
close(fd);
if (pcap_add_if(alldevsp, "usbmon0", 0, "All USB buses",
err_str) < 0)
return -1;
} else {
/*
* No binary device; do we have the text device?
*/
fd = open(USB_TEXT_DIR"/0t", O_RDONLY, 0);
if (fd < 0) {
/*
* Not at the new location; try the old location.
*/
fd = open(USB_TEXT_DIR_OLD"/0t", O_RDONLY, 0);
}
if (fd >= 0) {
/*
* We found it.
*/
close(fd);
if (pcap_add_if(alldevsp, "usbmon0", 0, "All USB buses",
err_str) < 0)
return -1;
}
}
/*
* Now look for individual USB buses.
*
* First, try scanning sysfs USB bus directory.
*/
dir = opendir(SYS_USB_BUS_DIR);
if (dir != NULL) {
while ((ret == 0) && ((data = readdir(dir)) != 0)) {
@ -172,7 +212,7 @@ usb_findalldevs(pcap_if_t **alldevsp, char *err_str)
if (strncmp(name, "usb", 3) != 0)
continue;
if (sscanf(&name[3], "%d", &n) == 0)
if (sscanf(&name[3], "%d", &n) == 0)
continue;
ret = usb_dev_add(alldevsp, n, err_str);
@ -182,7 +222,7 @@ usb_findalldevs(pcap_if_t **alldevsp, char *err_str)
return ret;
}
/* that didn't work; try scanning procfs usb bus directory */
/* That didn't work; try scanning procfs USB bus directory. */
dir = opendir(PROC_USB_BUS_DIR);
if (dir != NULL) {
while ((ret == 0) && ((data = readdir(dir)) != 0)) {
@ -193,7 +233,7 @@ usb_findalldevs(pcap_if_t **alldevsp, char *err_str)
if ((len < 1) || !isdigit(name[--len]))
continue;
while (isdigit(name[--len]));
if (sscanf(&name[len+1], "%d", &n) != 1)
if (sscanf(&name[len+1], "%d", &n) != 1)
continue;
ret = usb_dev_add(alldevsp, n, err_str);
@ -207,12 +247,12 @@ usb_findalldevs(pcap_if_t **alldevsp, char *err_str)
return 0;
}
static
static
int usb_mmap(pcap_t* handle)
{
struct pcap_usb_linux *handlep = handle->priv;
int len = ioctl(handle->fd, MON_IOCQ_RING_SIZE);
if (len < 0)
if (len < 0)
return 0;
handlep->mmapbuflen = len;
@ -247,7 +287,7 @@ probe_devices(int bus)
DIR* dir;
/* scan usb bus directories for device nodes */
snprintf(buf, sizeof(buf), "/dev/bus/usb/%03d", bus);
pcap_snprintf(buf, sizeof(buf), "/dev/bus/usb/%03d", bus);
dir = opendir(buf);
if (!dir)
return;
@ -259,8 +299,8 @@ probe_devices(int bus)
if (name[0] == '.')
continue;
snprintf(buf, sizeof(buf), "/dev/bus/usb/%03d/%s", bus, data->d_name);
pcap_snprintf(buf, sizeof(buf), "/dev/bus/usb/%03d/%s", bus, data->d_name);
fd = open(buf, O_RDWR);
if (fd == -1)
continue;
@ -328,7 +368,7 @@ usb_create(const char *device, char *ebuf, int *is_ours)
/* OK, it's probably ours. */
*is_ours = 1;
p = pcap_create_common(device, ebuf, sizeof (struct pcap_usb_linux));
p = pcap_create_common(ebuf, sizeof (struct pcap_usb_linux));
if (p == NULL)
return (NULL);
@ -355,15 +395,15 @@ usb_activate(pcap_t* handle)
handle->setnonblock_op = pcap_setnonblock_fd;
/*get usb bus index from device name */
if (sscanf(handle->opt.source, USB_IFACE"%d", &handlep->bus_index) != 1)
if (sscanf(handle->opt.device, USB_IFACE"%d", &handlep->bus_index) != 1)
{
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't get USB bus index from %s", handle->opt.source);
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't get USB bus index from %s", handle->opt.device);
return PCAP_ERROR;
}
/*now select the read method: try to open binary interface */
snprintf(full_path, USB_LINE_LEN, LINUX_USB_MON_DEV"%d", handlep->bus_index);
pcap_snprintf(full_path, USB_LINE_LEN, LINUX_USB_MON_DEV"%d", handlep->bus_index);
handle->fd = open(full_path, O_RDONLY, 0);
if (handle->fd >= 0)
{
@ -402,7 +442,7 @@ usb_activate(pcap_t* handle)
}
else {
/*Binary interface not available, try open text interface */
snprintf(full_path, USB_LINE_LEN, USB_TEXT_DIR"/%dt", handlep->bus_index);
pcap_snprintf(full_path, USB_LINE_LEN, USB_TEXT_DIR"/%dt", handlep->bus_index);
handle->fd = open(full_path, O_RDONLY, 0);
if (handle->fd < 0)
{
@ -412,12 +452,12 @@ usb_activate(pcap_t* handle)
* Not found at the new location; try
* the old location.
*/
snprintf(full_path, USB_LINE_LEN, USB_TEXT_DIR_OLD"/%dt", handlep->bus_index);
pcap_snprintf(full_path, USB_LINE_LEN, USB_TEXT_DIR_OLD"/%dt", handlep->bus_index);
handle->fd = open(full_path, O_RDONLY, 0);
}
if (handle->fd < 0) {
/* no more fallback, give it up*/
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't open USB bus file %s: %s", full_path, strerror(errno));
return PCAP_ERROR;
}
@ -445,7 +485,7 @@ usb_activate(pcap_t* handle)
* buffer */
handle->buffer = malloc(handle->bufsize);
if (!handle->buffer) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"malloc: %s", pcap_strerror(errno));
close(handle->fd);
return PCAP_ERROR;
@ -453,22 +493,22 @@ usb_activate(pcap_t* handle)
return 0;
}
static inline int
static inline int
ascii_to_int(char c)
{
return c < 'A' ? c- '0': ((c<'a') ? c - 'A' + 10: c-'a'+10);
}
/*
* see <linux-kernel-source>/Documentation/usb/usbmon.txt and
* <linux-kernel-source>/drivers/usb/mon/mon_text.c for urb string
* see <linux-kernel-source>/Documentation/usb/usbmon.txt and
* <linux-kernel-source>/drivers/usb/mon/mon_text.c for urb string
* format description
*/
static int
usb_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user)
{
/* see:
* /usr/src/linux/Documentation/usb/usbmon.txt
* /usr/src/linux/Documentation/usb/usbmon.txt
* for message format
*/
struct pcap_usb_linux *handlep = handle->priv;
@ -496,20 +536,20 @@ usb_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *u
if (errno == EAGAIN)
return 0; /* no data there */
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't read from fd %d: %s", handle->fd, strerror(errno));
return -1;
}
/* read urb header; %n argument may increment return value, but it's
/* read urb header; %n argument may increment return value, but it's
* not mandatory, so does not count on it*/
string[ret] = 0;
ret = sscanf(string, "%x %d %c %c%c:%d:%d %s%n", &tag, &timestamp, &etype,
&pipeid1, &pipeid2, &dev_addr, &ep_num, status,
ret = sscanf(string, "%x %d %c %c%c:%d:%d %s%n", &tag, &timestamp, &etype,
&pipeid1, &pipeid2, &dev_addr, &ep_num, status,
&cnt);
if (ret < 8)
{
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't parse USB bus message '%s', too few tokens (expected 8 got %d)",
string, ret);
return -1;
@ -521,10 +561,10 @@ usb_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *u
string += cnt;
/* don't use usbmon provided timestamp, since it have low precision*/
if (gettimeofday(&pkth.ts, NULL) < 0)
if (gettimeofday(&pkth.ts, NULL) < 0)
{
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't get timestamp for message '%s' %d:%s",
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't get timestamp for message '%s' %d:%s",
string, errno, strerror(errno));
return -1;
}
@ -567,15 +607,15 @@ usb_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *u
if (ret != 1)
{
/* this a setup packet, setup data can be filled with underscore if
* usbmon has not been able to read them, so we must parse this fields as
* usbmon has not been able to read them, so we must parse this fields as
* strings */
pcap_usb_setup* shdr;
char str1[3], str2[3], str3[5], str4[5], str5[5];
ret = sscanf(string, "%s %s %s %s %s%n", str1, str2, str3, str4,
ret = sscanf(string, "%s %s %s %s %s%n", str1, str2, str3, str4,
str5, &cnt);
if (ret < 5)
{
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't parse USB bus message '%s', too few tokens (expected 5 got %d)",
string, ret);
return -1;
@ -592,20 +632,20 @@ usb_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *u
uhdr->setup_flag = 0;
}
else
else
uhdr->setup_flag = 1;
/* read urb data */
ret = sscanf(string, " %d%n", &urb_len, &cnt);
if (ret < 1)
{
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't parse urb length from '%s'", string);
return -1;
}
string += cnt;
/* urb tag is not present if urb length is 0, so we can stop here
/* urb tag is not present if urb length is 0, so we can stop here
* text parsing */
pkth.len = urb_len+pkth.caplen;
uhdr->urb_len = urb_len;
@ -617,12 +657,12 @@ usb_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *u
/* check for data presence; data is present if and only if urb tag is '=' */
if (sscanf(string, " %c", &urb_tag) != 1)
{
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't parse urb tag from '%s'", string);
return -1;
}
if (urb_tag != '=')
if (urb_tag != '=')
goto got;
/* skip urb tag and following space */
@ -631,12 +671,12 @@ usb_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *u
/* if we reach this point we got some urb data*/
uhdr->data_flag = 0;
/* read all urb data; if urb length is greater then the usbmon internal
/* read all urb data; if urb length is greater then the usbmon internal
* buffer length used by the kernel to spool the URB, we get only
* a partial information.
* At least until linux 2.6.17 there is no way to set usbmon intenal buffer
* length and default value is 130. */
while ((string[0] != 0) && (string[1] != 0) && (pkth.caplen < handle->snapshot))
while ((string[0] != 0) && (string[1] != 0) && (pkth.caplen < (bpf_u_int32)handle->snapshot))
{
rawdata[0] = ascii_to_int(string[0]) * 16 + ascii_to_int(string[1]);
rawdata++;
@ -649,8 +689,8 @@ usb_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *u
got:
uhdr->data_len = data_len;
if (pkth.caplen > handle->snapshot)
pkth.caplen = handle->snapshot;
if (pkth.caplen > (bpf_u_int32)handle->snapshot)
pkth.caplen = (bpf_u_int32)handle->snapshot;
if (handle->fcode.bf_insns == NULL ||
bpf_filter(handle->fcode.bf_insns, handle->buffer,
@ -665,12 +705,12 @@ usb_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *u
static int
usb_inject_linux(pcap_t *handle, const void *buf, size_t size)
{
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "inject not supported on "
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "inject not supported on "
"USB devices");
return (-1);
}
static int
static int
usb_stats_linux(pcap_t *handle, struct pcap_stat *stats)
{
struct pcap_usb_linux *handlep = handle->priv;
@ -680,7 +720,7 @@ usb_stats_linux(pcap_t *handle, struct pcap_stat *stats)
char * ptr = string;
int fd;
snprintf(string, USB_LINE_LEN, USB_TEXT_DIR"/%ds", handlep->bus_index);
pcap_snprintf(string, USB_LINE_LEN, USB_TEXT_DIR"/%ds", handlep->bus_index);
fd = open(string, O_RDONLY, 0);
if (fd < 0)
{
@ -690,12 +730,12 @@ usb_stats_linux(pcap_t *handle, struct pcap_stat *stats)
* Not found at the new location; try the old
* location.
*/
snprintf(string, USB_LINE_LEN, USB_TEXT_DIR_OLD"/%ds", handlep->bus_index);
pcap_snprintf(string, USB_LINE_LEN, USB_TEXT_DIR_OLD"/%ds", handlep->bus_index);
fd = open(string, O_RDONLY, 0);
}
if (fd < 0) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't open USB stats file %s: %s",
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't open USB stats file %s: %s",
string, strerror(errno));
return -1;
}
@ -709,7 +749,7 @@ usb_stats_linux(pcap_t *handle, struct pcap_stat *stats)
if (ret < 0)
{
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't read stats from fd %d ", fd);
return -1;
}
@ -717,11 +757,11 @@ usb_stats_linux(pcap_t *handle, struct pcap_stat *stats)
/* extract info on dropped urbs */
for (consumed=0; consumed < ret; ) {
/* from the sscanf man page:
* The C standard says: "Execution of a %n directive does
/* from the sscanf man page:
* The C standard says: "Execution of a %n directive does
* not increment the assignment count returned at the completion
* of execution" but the Corrigendum seems to contradict this.
* Do not make any assumptions on the effect of %n conversions
* Do not make any assumptions on the effect of %n conversions
* on the return value and explicitly check for cnt assignmet*/
int ntok;
@ -733,7 +773,7 @@ usb_stats_linux(pcap_t *handle, struct pcap_stat *stats)
ptr += cnt;
if (strcmp(token, "nreaders") == 0)
ret = sscanf(ptr, "%d", &stats->ps_drop);
else
else
ret = sscanf(ptr, "%d", &dummy);
if (ntok != 1)
break;
@ -746,7 +786,7 @@ usb_stats_linux(pcap_t *handle, struct pcap_stat *stats)
return 0;
}
static int
static int
usb_setdirection_linux(pcap_t *p, pcap_direction_t d)
{
p->direction = d;
@ -754,7 +794,7 @@ usb_setdirection_linux(pcap_t *p, pcap_direction_t d)
}
static int
static int
usb_stats_linux_bin(pcap_t *handle, struct pcap_stat *stats)
{
struct pcap_usb_linux *handlep = handle->priv;
@ -763,7 +803,7 @@ usb_stats_linux_bin(pcap_t *handle, struct pcap_stat *stats)
ret = ioctl(handle->fd, MON_IOCG_STATS, &st);
if (ret < 0)
{
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't read stats from fd %d:%s ", handle->fd, strerror(errno));
return -1;
}
@ -775,7 +815,7 @@ usb_stats_linux_bin(pcap_t *handle, struct pcap_stat *stats)
}
/*
* see <linux-kernel-source>/Documentation/usb/usbmon.txt and
* see <linux-kernel-source>/Documentation/usb/usbmon.txt and
* <linux-kernel-source>/drivers/usb/mon/mon_bin.c binary ABI
*/
static int
@ -785,11 +825,11 @@ usb_read_linux_bin(pcap_t *handle, int max_packets, pcap_handler callback, u_cha
struct mon_bin_get info;
int ret;
struct pcap_pkthdr pkth;
int clen = handle->snapshot - sizeof(pcap_usb_header);
u_int clen = handle->snapshot - sizeof(pcap_usb_header);
/* the usb header is going to be part of 'packet' data*/
info.hdr = (pcap_usb_header*) handle->buffer;
info.data = handle->buffer + sizeof(pcap_usb_header);
info.data = (u_char *)handle->buffer + sizeof(pcap_usb_header);
info.data_len = clen;
/* ignore interrupt system call errors */
@ -806,7 +846,7 @@ usb_read_linux_bin(pcap_t *handle, int max_packets, pcap_handler callback, u_cha
if (errno == EAGAIN)
return 0; /* no data there */
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't read from fd %d: %s", handle->fd, strerror(errno));
return -1;
}
@ -833,7 +873,7 @@ usb_read_linux_bin(pcap_t *handle, int max_packets, pcap_handler callback, u_cha
}
/*
* see <linux-kernel-source>/Documentation/usb/usbmon.txt and
* see <linux-kernel-source>/Documentation/usb/usbmon.txt and
* <linux-kernel-source>/drivers/usb/mon/mon_bin.c binary ABI
*/
#define VEC_SIZE 32
@ -847,7 +887,7 @@ usb_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback, u_ch
pcap_usb_header* hdr;
int nflush = 0;
int packets = 0;
int clen, max_clen;
u_int clen, max_clen;
max_clen = handle->snapshot - sizeof(pcap_usb_header);
@ -877,7 +917,7 @@ usb_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback, u_ch
if (errno == EAGAIN)
return 0; /* no data there */
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't mfetch fd %d: %s", handle->fd, strerror(errno));
return -1;
}
@ -887,7 +927,7 @@ usb_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback, u_ch
for (i=0; i<fetch.nfetch; ++i) {
/* discard filler */
hdr = (pcap_usb_header*) &handlep->mmapbuf[vec[i]];
if (hdr->event_type == '@')
if (hdr->event_type == '@')
continue;
/* we can get less that than really captured from kernel, depending on
@ -917,7 +957,11 @@ usb_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback, u_ch
}
/* flush pending events*/
ioctl(handle->fd, MON_IOCH_MFLUSH, nflush);
if (ioctl(handle->fd, MON_IOCH_MFLUSH, nflush) == -1) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't mflush fd %d: %s", handle->fd, strerror(errno));
return -1;
}
return packets;
}

View file

@ -11,8 +11,8 @@
* 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
* 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

File diff suppressed because it is too large Load diff

View file

@ -17,7 +17,7 @@
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\"
.TH PCAP 3PCAP "16 April 2014"
.TH PCAP 3PCAP "8 March 2015"
.SH NAME
pcap \- Packet Capture library
.SH SYNOPSIS
@ -354,12 +354,25 @@ open a
.B pcap_t
for a ``savefile'', given a pathname
.TP
.BR pcap_open_offline_with_tstamp_precision (3PCAP)
open a
.B pcap_t
for a ``savefile'', given a pathname, and specify the precision to
provide for packet time stamps
.TP
.BR pcap_fopen_offline (3PCAP)
open a
.B pcap_t
for a ``savefile'', given a
.B "FILE\ *"
.TP
.BR pcap_fopen_offline_with_tstamp_precision (3PCAP)
open a
.B pcap_t
for a ``savefile'', given a
.BR "FILE\ *" ,
and specify the precision to provide for packet time stamps
.TP
.BR pcap_open_dead (3PCAP)
create a ``fake''
.B pcap_t
@ -424,6 +437,16 @@ get description for a time stamp type
.BR pcap_tstamp_type_name_to_val (3PCAP)
get time stamp type corresponding to a name
.TP
.BR pcap_set_tstamp_precision (3PCAP)
set time stamp precision for a not-yet-activated
.B pcap_t
for live capture
.TP
.BR pcap_get_tstamp_precision (3PCAP)
get the time stamp precision of a
.B pcap_t
for live capture
.TP
.BR pcap_datalink (3PCAP)
get link-layer header type for a
.B pcap_t
@ -552,7 +575,7 @@ bytes of the packet on success, and NULL on error.
.BR pcap_next_ex ()
is passed two pointer arguments, one of which points to a
.IR struct pcap_pkthdr *
and one of which points to a
and one of which points to a
.IR "const u_char" *.
It sets the first pointer to point to a
.I struct pcap_pkthdr
@ -580,7 +603,9 @@ for packets to become available. On some, but
all, platforms, if a read timeout was specified, the wait will terminate
after the read timeout expires; applications should be prepared for
this, as it happens on some platforms, but should not rely on it, as it
does not happen on other platforms.
does not happen on other platforms. Note that the wait might, or might
not, terminate even if no packets are available; applications should be
prepared for this to happen, but must not rely on it happening.
.PP
A handle can be put into ``non-blocking mode'', so that those routines
will, rather than blocking, return an indication that no packets are
@ -596,8 +621,8 @@ Non-blocking mode is often combined with routines such as
.BR select (2)
or
.BR poll (2)
or other routines a platform offers to wait for the availability of data
on any of a set of descriptors. To obtain, for a handle, a descriptor
or other routines a platform offers to wait for any of a set of
descriptors to be ready to read. To obtain, for a handle, a descriptor
that can be used in those routines, call
.BR pcap_get_selectable_fd ().
Not all handles have such a descriptor available;
@ -606,7 +631,14 @@ will return \-1 if no such descriptor exists. In addition, for various
reasons, one or more of those routines will not work properly with the
descriptor; the documentation for
.BR pcap_get_selectable_fd ()
gives details.
gives details. Note that, just as an attempt to read packets from a
.B pcap_t
may not return any packets if the read timeout expires, a
.BR select (),
.BR poll (),
or other such call may, if the read timeout expires, indicate that a
descriptor is ready to read even if there are no packets available to
read.
.TP
.B Routines
.RS

File diff suppressed because it is too large Load diff

View file

@ -11,8 +11,8 @@
* 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
* 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
@ -30,9 +30,9 @@
* bluetooth data struct
* By Paolo Abeni <paolo.abeni@email.it>
*/
#ifndef _PCAP_BLUETOOTH_STRUCTS_H__
#define _PCAP_BLUETOOTH_STRUCTS_H__
#ifndef lib_pcap_bluetooth_h
#define lib_pcap_bluetooth_h
/*
* Header prepended libpcap to each bluetooth h4 frame,

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,54 @@
/*-
* Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
* The Regents of the University of California. All rights reserved.
*
* This code is derived from the Stanford/CMU enet packet filter,
* (net/enet.c) distributed as part of 4.3BSD, and code contributed
* to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
* Berkeley Laboratory.
*
* 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.
*/
#ifndef lib_pcap_can_socketcan_h
#define lib_pcap_can_socketcan_h
/*
* SocketCAN header, as per Documentation/networking/can.txt in the
* Linux source.
*/
typedef struct {
u_int32_t can_id;
u_int8_t payload_length;
u_int8_t pad;
u_int8_t reserved1;
u_int8_t reserved2;
} pcap_can_socketcan_hdr;
#endif

1340
contrib/libpcap/pcap/dlt.h Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,108 @@
/* -*- 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 lib_pcap_export_defs_h
#define lib_pcap_export_defs_h
/*
* PCAP_API_DEF must be used when defining *data* exported from
* libpcap. It can be used when defining *functions* exported
* from libpcap, but it doesn't have to be used there. It
* should not be used in declarations in headers.
*
* PCAP_API must be used when *declaring* data or functions
* exported from libpcap; PCAP_API_DEF won't work on all platforms.
*/
/*
* Check whether this is GCC major.minor or a later release, or some
* compiler that claims to be "just like GCC" of that version or a
* later release.
*/
#define IS_AT_LEAST_GNUC_VERSION(major, minor) \
(defined(__GNUC__) && \
(__GNUC__ > (major) || \
(__GNUC__ == (major) && __GNUC_MINOR__ >= (minor))))
#if defined(_WIN32)
#ifdef BUILDING_PCAP
/*
* We're compiling libpcap, so we should export functions in our
* API.
*/
#define PCAP_API_DEF __declspec(dllexport)
#else
#define PCAP_API_DEF __declspec(dllimport)
#endif
#elif defined(MSDOS)
/* XXX - does this need special treatment? */
#define PCAP_API_DEF
#else /* UN*X */
#ifdef BUILDING_PCAP
/*
* We're compiling libpcap, so we should export functions in our API.
* The compiler might be configured not to export functions from a
* shared library by default, so we might have to explicitly mark
* functions as exported.
*/
#if IS_AT_LEAST_GNUC_VERSION(3, 4)
/*
* GCC 3.4 or later, or some compiler asserting compatibility with
* GCC 3.4 or later, so we have __attribute__((visibility()).
*/
#define PCAP_API_DEF __attribute__((visibility("default")))
#elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550)
/*
* Sun C 5.5 or later, so we have __global.
* (Sun C 5.9 and later also have __attribute__((visibility()),
* but there's no reason to prefer it with Sun C.)
*/
#define PCAP_API_DEF __global
#else
/*
* We don't have anything to say.
*/
#define PCAP_API_DEF
#endif
#else
/*
* We're not building libpcap.
*/
#define PCAP_API_DEF
#endif
#endif /* _WIN32/MSDOS/UN*X */
#define PCAP_API PCAP_API_DEF extern
#endif /* lib_pcap_export_defs_h */

View file

@ -43,7 +43,10 @@ extern "C" {
* XXX this stuff doesn't belong in this interface, but this
* library already must do name to address translation, so
* on systems that don't have support for /etc/ethers, we
* export these hooks since they'll
* export these hooks since they're already being used by
* some applications (such as tcpdump) and already being
* marked as exported in some OSes offering libpcap (such
* as Debian).
*/
struct pcap_etherent {
u_char addr[6];
@ -52,21 +55,21 @@ struct pcap_etherent {
#ifndef PCAP_ETHERS_FILE
#define PCAP_ETHERS_FILE "/etc/ethers"
#endif
struct pcap_etherent *pcap_next_etherent(FILE *);
u_char *pcap_ether_hostton(const char*);
u_char *pcap_ether_aton(const char *);
PCAP_API struct pcap_etherent *pcap_next_etherent(FILE *);
PCAP_API u_char *pcap_ether_hostton(const char*);
PCAP_API u_char *pcap_ether_aton(const char *);
bpf_u_int32 **pcap_nametoaddr(const char *);
PCAP_API bpf_u_int32 **pcap_nametoaddr(const char *);
#ifdef INET6
struct addrinfo *pcap_nametoaddrinfo(const char *);
PCAP_API struct addrinfo *pcap_nametoaddrinfo(const char *);
#endif
bpf_u_int32 pcap_nametonetaddr(const char *);
PCAP_API bpf_u_int32 pcap_nametonetaddr(const char *);
int pcap_nametoport(const char *, int *, int *);
int pcap_nametoportrange(const char *, int *, int *, int *);
int pcap_nametoproto(const char *);
int pcap_nametoeproto(const char *);
int pcap_nametollc(const char *);
PCAP_API int pcap_nametoport(const char *, int *, int *);
PCAP_API int pcap_nametoportrange(const char *, int *, int *, int *);
PCAP_API int pcap_nametoproto(const char *);
PCAP_API int pcap_nametoeproto(const char *);
PCAP_API int pcap_nametollc(const char *);
/*
* If a protocol is unknown, PROTO_UNDEF is returned.
* Also, pcap_nametoport() returns the protocol along with the port number.
@ -75,11 +78,6 @@ int pcap_nametollc(const char *);
*/
#define PROTO_UNDEF -1
/* XXX move these to pcap-int.h? */
int __pcap_atodn(const char *, bpf_u_int32 *);
int __pcap_atoin(const char *, bpf_u_int32 *);
u_short __pcap_nametodnaddr(const char *);
#ifdef __cplusplus
}
#endif

View file

@ -25,8 +25,8 @@
* DAMAGE.
*/
#ifndef _PCAP_NFLOG_H__
#define _PCAP_NFLOG_H__
#ifndef lib_pcap_nflog_h
#define lib_pcap_nflog_h
/*
* Structure of an NFLOG header and TLV parts, as described at

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