mirror of
https://github.com/freebsd/freebsd-src
synced 2024-10-15 12:54:27 +00:00
MFV r313676: libpcap 1.8.1
MFC after: 1 month
This commit is contained in:
commit
ada6f083b9
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=313695
|
@ -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
|
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
|
Don't crash on filters testing a non-existent link-layer type
|
||||||
field.
|
field.
|
||||||
Fix sending in non-blocking mode on Linux with memory-mapped
|
Fix sending in non-blocking mode on Linux with memory-mapped
|
||||||
|
@ -8,12 +83,12 @@ Monday Aug. 12, 2014 guy@alum.mit.edu
|
||||||
machines.
|
machines.
|
||||||
|
|
||||||
Saturday Jul. 19, 2014 mcr@sandelman.ca
|
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
|
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
|
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
|
Don't support D-Bus sniffing on OS X
|
||||||
fixes for byte order issues with NFLOG captures
|
fixes for byte order issues with NFLOG captures
|
||||||
Handle using cooked mode for DLT_NETLINK in activate_new().
|
Handle using cooked mode for DLT_NETLINK in activate_new().
|
||||||
|
|
|
@ -2,11 +2,12 @@ This file lists people who have contributed to libpcap:
|
||||||
|
|
||||||
The current maintainers:
|
The current maintainers:
|
||||||
Bill Fenner <fenner at research dot att dot com>
|
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>
|
Fulvio Risso <risso at polito dot it>
|
||||||
Guy Harris <guy at alum dot mit dot edu>
|
Guy Harris <guy at alum dot mit dot edu>
|
||||||
Hannes Gredler <hannes at juniper dot net>
|
Hannes Gredler <hannes at juniper dot net>
|
||||||
Michael Richardson <mcr at sandelman dot ottawa dot on dot ca>
|
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:
|
Additional people who have contributed patches:
|
||||||
|
|
||||||
|
@ -45,7 +46,7 @@ Additional people who have contributed patches:
|
||||||
David Young <dyoung at ojctech dot com>
|
David Young <dyoung at ojctech dot com>
|
||||||
Dean Gaudet <dean at arctic dot org>
|
Dean Gaudet <dean at arctic dot org>
|
||||||
dhruv <rsrivat at sourceforge dot net>
|
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>
|
Dug Song <dugsong at monkey dot org>
|
||||||
Dustin Spicuzza <dustin at virtualroadside dot com>
|
Dustin Spicuzza <dustin at virtualroadside dot com>
|
||||||
dzejarczech <dzejarczech at sourceforge dot net>
|
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>
|
Jefferson Ogata <jogata at nodc dot noaa dot gov>
|
||||||
Jesper Dangaard Brouer <hawk at comx dot dk>
|
Jesper Dangaard Brouer <hawk at comx dot dk>
|
||||||
Jesper Peterson <jesper at endace dot com>
|
Jesper Peterson <jesper at endace dot com>
|
||||||
|
Jesse Gross <jesse at nicira dot com>
|
||||||
Jiri Slaby <jirislaby at gmail dot com>
|
Jiri Slaby <jirislaby at gmail dot com>
|
||||||
Joerg Mayer <jmayer at loplof dot de>
|
Joerg Mayer <jmayer at loplof dot de>
|
||||||
John Bankier <jbankier at rainfinity dot com>
|
John Bankier <jbankier at rainfinity dot com>
|
||||||
|
@ -105,6 +107,7 @@ Additional people who have contributed patches:
|
||||||
Mansour Behabadi <mansour at oxplot dot com>
|
Mansour Behabadi <mansour at oxplot dot com>
|
||||||
Marcus Felipe Pereira <marcus at task dot com dot br>
|
Marcus Felipe Pereira <marcus at task dot com dot br>
|
||||||
Mark C. Brown <mbrown at hp dot com>
|
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>
|
Mark Pizzolato <List-tcpdump-workers at subscriptions dot pizzolato dot net>
|
||||||
Markus Mayer <markus_mayer at sourceforge dot net>
|
Markus Mayer <markus_mayer at sourceforge dot net>
|
||||||
Martin Husemann <martin at netbsd dot org>
|
Martin Husemann <martin at netbsd dot org>
|
||||||
|
|
|
@ -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
|
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
|
packet capture not supported by libpcap, please send us patches; don't
|
||||||
forget to include an autoconf fragment suitable for use in
|
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
|
It is possible to override the default packet capture type, although
|
||||||
the circumstance where this works are limited. For example if you have
|
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
|
will abort if your compiler is not ANSI compliant. If this happens, use
|
||||||
the generally available GNU C compiler (GCC).
|
the generally available GNU C compiler (GCC).
|
||||||
|
|
||||||
If you use flex, you must use version 2.4.6 or higher. The configure
|
You will need either Flex 2.5.31 or later, or a version of Lex
|
||||||
script automatically detects the version of flex and will not use it
|
compatible with it (if any exist), to build libpcap. The configure
|
||||||
unless it is new enough. You can use "flex -V" to see what version you
|
script will abort if there isn't any such program. If you have an older
|
||||||
have (unless it's really old). The current version of flex is available
|
version of Flex, or don't have a compatible version of Lex, the current
|
||||||
at flex.sourceforge.net and often comes packaged by means of the OS.
|
version of flex is available at flex.sourceforge.net.
|
||||||
As of this writing, the current version is 2.5.37.
|
|
||||||
|
|
||||||
If you use bison, you must use flex (and visa versa). The configure
|
You will need either Bison, Berkeley YACC, or a version of YACC
|
||||||
script automatically falls back to lex and yacc if both flex and bison
|
compatible with them (if any exist), to build libpcap. The configure
|
||||||
are not found.
|
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
|
Sometimes the stock C compiler does not interact well with Flex and
|
||||||
bison. The list of problems includes undefined references for alloca.
|
Bison. The list of problems includes undefined references for alloca.
|
||||||
You can get around this by installing gcc or manually disabling flex
|
You can get around this by installing GCC.
|
||||||
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.
|
|
||||||
|
|
||||||
If you use Solaris, there is a bug with bufmod(7) that is fixed in
|
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
|
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.
|
handling of the timestamp in the kernel.
|
||||||
|
|
||||||
Note well: there is rumoured to be a version of tcpdump floating around
|
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
|
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
|
The LBNL Network Research Group notes with interest that a standard
|
||||||
cracker trick to get people to install trojans is to distribute bogus
|
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 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
|
If you are having trouble but aren't using a version that came from
|
||||||
tcpdump.org, please try that before submitting a bug report!
|
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.
|
build without changes on UnixWare 7.
|
||||||
|
|
||||||
If linking tcpdump fails with "Undefined: _alloca" when using bison on
|
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
|
higher is recommended (1.14 is known to cause problems 1.16 is known to
|
||||||
work). Either pick up a current version from:
|
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:
|
or hack around it by inserting the lines:
|
||||||
|
|
||||||
|
@ -289,6 +271,7 @@ FILES
|
||||||
CHANGES - description of differences between releases
|
CHANGES - description of differences between releases
|
||||||
ChmodBPF/* - Mac OS X startup item to set ownership and permissions
|
ChmodBPF/* - Mac OS X startup item to set ownership and permissions
|
||||||
on /dev/bpf*
|
on /dev/bpf*
|
||||||
|
CMakeLists.txt - CMake file
|
||||||
CREDITS - people that have helped libpcap along
|
CREDITS - people that have helped libpcap along
|
||||||
INSTALL.txt - this file
|
INSTALL.txt - this file
|
||||||
LICENSE - the license under which tcpdump is distributed
|
LICENSE - the license under which tcpdump is distributed
|
||||||
|
@ -317,7 +300,7 @@ config.guess - autoconf support
|
||||||
config.h.in - autoconf input
|
config.h.in - autoconf input
|
||||||
config.sub - autoconf support
|
config.sub - autoconf support
|
||||||
configure - configure script (run this first)
|
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.c - DLPI-related functions for pcap-dlpi.c and pcap-libdlpi.c
|
||||||
dlpisubs.h - DLPI-related function declarations
|
dlpisubs.h - DLPI-related function declarations
|
||||||
etherent.c - /etc/ethers support routines
|
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-getad.c - pcap_findalldevs() for systems with getifaddrs()
|
||||||
fad-gifc.c - pcap_findalldevs() for systems with only SIOCGIFLIST
|
fad-gifc.c - pcap_findalldevs() for systems with only SIOCGIFLIST
|
||||||
fad-glifc.c - pcap_findalldevs() for systems with SIOCGLIFCONF
|
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
|
filtertest.c - test program for BPF compiler
|
||||||
findalldevstest.c - test program for pcap_findalldevs()
|
findalldevstest.c - test program for pcap_findalldevs()
|
||||||
gencode.c - BPF code generation routines
|
gencode.c - BPF code generation routines
|
||||||
|
@ -345,7 +325,6 @@ nametoaddr.c - hostname to address routines
|
||||||
nlpid.h - OSI network layer protocol identifier definitions
|
nlpid.h - OSI network layer protocol identifier definitions
|
||||||
net - symlink to bpf/net
|
net - symlink to bpf/net
|
||||||
optimize.c - BPF optimization routines
|
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/bluetooth.h - public definition of DLT_BLUETOOTH_HCI_H4_WITH_PHDR header
|
||||||
pcap/bpf.h - BPF definitions
|
pcap/bpf.h - BPF definitions
|
||||||
pcap/namedb.h - public libpcap name database 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-filter.4 - manual entry for filter syntax
|
||||||
pcap-linktype.4 - manual entry for link-layer header types
|
pcap-linktype.4 - manual entry for link-layer header types
|
||||||
ppp.h - Point to Point Protocol definitions
|
ppp.h - Point to Point Protocol definitions
|
||||||
runlex.sh - wrapper for Lex/Flex
|
|
||||||
savefile.c - offline support
|
savefile.c - offline support
|
||||||
scanner.l - filter string scanner
|
scanner.l - filter string scanner
|
||||||
sunatmpos.h - definitions for SunATM capturing
|
sunatmpos.h - definitions for SunATM capturing
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
License: BSD
|
License: BSD
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
modification, are permitted provided that the following conditions
|
modification, are permitted provided that the following conditions
|
||||||
are met:
|
are met:
|
||||||
|
|
||||||
1. Redistributions of source code must retain the above copyright
|
1. Redistributions of source code must retain the above copyright
|
||||||
notice, this list of conditions and the following disclaimer.
|
notice, this list of conditions and the following disclaimer.
|
||||||
2. Redistributions in binary form must reproduce the above copyright
|
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
|
3. The names of the authors may not be used to endorse or promote
|
||||||
products derived from this software without specific prior
|
products derived from this software without specific prior
|
||||||
written permission.
|
written permission.
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||||
IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
|
@ -2,12 +2,12 @@
|
||||||
# Auto-regenerate configure script or Makefile when things change.
|
# Auto-regenerate configure script or Makefile when things change.
|
||||||
# From autoconf.info . Works best with GNU Make.
|
# From autoconf.info . Works best with GNU Make.
|
||||||
#
|
#
|
||||||
${srcdir}/configure: configure.in aclocal.m4
|
${srcdir}/configure: configure.ac aclocal.m4
|
||||||
cd ${srcdir} && autoconf
|
cd ${srcdir} && autoconf
|
||||||
|
|
||||||
# autoheader might not change config.h.in, so touch a stamp file.
|
# autoheader might not change config.h.in, so touch a stamp file.
|
||||||
${srcdir}/config.h.in: ${srcdir}/stamp-h.in
|
${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
|
cd ${srcdir} && autoheader
|
||||||
echo timestamp > ${srcdir}/stamp-h.in
|
echo timestamp > ${srcdir}/stamp-h.in
|
||||||
|
|
||||||
|
|
|
@ -49,12 +49,13 @@ LN_S = @LN_S@
|
||||||
MKDEP = @MKDEP@
|
MKDEP = @MKDEP@
|
||||||
CCOPT = @V_CCOPT@
|
CCOPT = @V_CCOPT@
|
||||||
INCLS = -I. @V_INCLS@
|
INCLS = -I. @V_INCLS@
|
||||||
DEFS = @DEFS@ @V_DEFS@
|
DEFS = -DBUILDING_PCAP @DEFS@ @V_DEFS@
|
||||||
ADDLOBJS = @ADDLOBJS@
|
ADDLOBJS = @ADDLOBJS@
|
||||||
ADDLARCHIVEOBJS = @ADDLARCHIVEOBJS@
|
ADDLARCHIVEOBJS = @ADDLARCHIVEOBJS@
|
||||||
LIBS = @LIBS@
|
LIBS = @LIBS@
|
||||||
CFLAGS = @CFLAGS@
|
CROSSFLAGS=
|
||||||
LDFLAGS = @LDFLAGS@
|
CFLAGS = @CFLAGS@ ${CROSSFLAGS}
|
||||||
|
LDFLAGS = @LDFLAGS@ ${CROSSFLAGS}
|
||||||
DYEXT = @DYEXT@
|
DYEXT = @DYEXT@
|
||||||
V_RPATH_OPT = @V_RPATH_OPT@
|
V_RPATH_OPT = @V_RPATH_OPT@
|
||||||
DEPENDENCY_CFLAG = @DEPENDENCY_CFLAG@
|
DEPENDENCY_CFLAG = @DEPENDENCY_CFLAG@
|
||||||
|
@ -68,13 +69,8 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||||
INSTALL_DATA = @INSTALL_DATA@
|
INSTALL_DATA = @INSTALL_DATA@
|
||||||
RANLIB = @RANLIB@
|
RANLIB = @RANLIB@
|
||||||
|
|
||||||
#
|
LEX = @LEX@
|
||||||
# Flex and bison allow you to specify the prefixes of the global symbols
|
YACC = @YACC@
|
||||||
# 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@
|
|
||||||
|
|
||||||
# Explicitly define compilation rule since SunOS 4's make doesn't like gcc.
|
# 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
|
# Also, gcc does not remove the .o before forking 'as', which can be a
|
||||||
|
@ -83,11 +79,11 @@ YACC = @V_YACC@
|
||||||
@rm -f $@
|
@rm -f $@
|
||||||
$(CC) $(FULL_CFLAGS) -c $(srcdir)/$*.c
|
$(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@
|
PSRC = pcap-@V_PCAP@.c @USB_SRC@ @BT_SRC@ @BT_MONITOR_SRC@ @NETFILTER_SRC@ @DBUS_SRC@
|
||||||
FSRC = fad-@V_FINDALLDEVS@.c
|
FSRC = @V_FINDALLDEVS@
|
||||||
SSRC = @SSRC@
|
SSRC = @SSRC@
|
||||||
CSRC = pcap.c inet.c gencode.c optimize.c nametoaddr.c etherent.c \
|
CSRC = pcap.c inet.c fad-helpers.c gencode.c optimize.c nametoaddr.c \
|
||||||
savefile.c sf-pcap.c sf-pcap-ng.c pcap-common.c \
|
etherent.c savefile.c sf-pcap.c sf-pcap-ng.c pcap-common.c \
|
||||||
bpf_image.c bpf_dump.c
|
bpf_image.c bpf_dump.c
|
||||||
GENSRC = scanner.c grammar.c bpf_filter.c version.c
|
GENSRC = scanner.c grammar.c bpf_filter.c version.c
|
||||||
LIBOBJS = @LIBOBJS@
|
LIBOBJS = @LIBOBJS@
|
||||||
|
@ -103,6 +99,9 @@ PUBHDR = \
|
||||||
pcap-namedb.h \
|
pcap-namedb.h \
|
||||||
pcap/bpf.h \
|
pcap/bpf.h \
|
||||||
pcap/bluetooth.h \
|
pcap/bluetooth.h \
|
||||||
|
pcap/can_socketcan.h \
|
||||||
|
pcap/dlt.h \
|
||||||
|
pcap/export-defs.h \
|
||||||
pcap/ipnet.h \
|
pcap/ipnet.h \
|
||||||
pcap/namedb.h \
|
pcap/namedb.h \
|
||||||
pcap/nflog.h \
|
pcap/nflog.h \
|
||||||
|
@ -115,37 +114,43 @@ HDR = $(PUBHDR) \
|
||||||
arcnet.h \
|
arcnet.h \
|
||||||
atmuni31.h \
|
atmuni31.h \
|
||||||
ethertype.h \
|
ethertype.h \
|
||||||
|
extract.h \
|
||||||
gencode.h \
|
gencode.h \
|
||||||
ieee80211.h \
|
ieee80211.h \
|
||||||
llc.h \
|
llc.h \
|
||||||
|
nametoaddr.h \
|
||||||
nlpid.h \
|
nlpid.h \
|
||||||
pcap-common.h \
|
pcap-common.h \
|
||||||
pcap-int.h \
|
pcap-int.h \
|
||||||
pcap-stdinc.h \
|
pcap-stdinc.h \
|
||||||
|
portability.h \
|
||||||
ppp.h \
|
ppp.h \
|
||||||
sf-pcap.h \
|
sf-pcap.h \
|
||||||
sf-pcap-ng.h \
|
sf-pcap-ng.h \
|
||||||
sunatmpos.h
|
sunatmpos.h
|
||||||
|
|
||||||
TESTS = \
|
TESTS = \
|
||||||
|
@VALGRINDTEST@ \
|
||||||
capturetest \
|
capturetest \
|
||||||
|
can_set_rfmon_test \
|
||||||
filtertest \
|
filtertest \
|
||||||
findalldevstest \
|
findalldevstest \
|
||||||
opentest \
|
opentest \
|
||||||
selpolltest \
|
reactivatetest \
|
||||||
valgrindtest
|
selpolltest
|
||||||
|
|
||||||
TESTS_SRC = \
|
TESTS_SRC = \
|
||||||
|
tests/valgrindtest.c \
|
||||||
tests/capturetest.c \
|
tests/capturetest.c \
|
||||||
|
tests/can_set_rfmon_test.c \
|
||||||
tests/filtertest.c \
|
tests/filtertest.c \
|
||||||
tests/findalldevstest.c \
|
tests/findalldevstest.c \
|
||||||
tests/opentest.c \
|
tests/opentest.c \
|
||||||
tests/reactivatetest.c \
|
tests/reactivatetest.c \
|
||||||
tests/selpolltest.c \
|
tests/selpolltest.c
|
||||||
tests/valgrindtest.c
|
|
||||||
|
|
||||||
GENHDR = \
|
GENHDR = \
|
||||||
scanner.h tokdefs.h version.h
|
scanner.h grammar.h pcap_version.h
|
||||||
|
|
||||||
TAGFILES = \
|
TAGFILES = \
|
||||||
$(SRC) $(HDR)
|
$(SRC) $(HDR)
|
||||||
|
@ -231,6 +236,8 @@ EXTRA_DIST = \
|
||||||
ChmodBPF/ChmodBPF \
|
ChmodBPF/ChmodBPF \
|
||||||
ChmodBPF/StartupParameters.plist \
|
ChmodBPF/StartupParameters.plist \
|
||||||
CREDITS \
|
CREDITS \
|
||||||
|
CMakeLists.txt \
|
||||||
|
GenVersion.bat \
|
||||||
INSTALL.txt \
|
INSTALL.txt \
|
||||||
LICENSE \
|
LICENSE \
|
||||||
Makefile.in \
|
Makefile.in \
|
||||||
|
@ -253,29 +260,37 @@ EXTRA_DIST = \
|
||||||
aclocal.m4 \
|
aclocal.m4 \
|
||||||
bpf/net/bpf_filter.c \
|
bpf/net/bpf_filter.c \
|
||||||
chmod_bpf \
|
chmod_bpf \
|
||||||
|
cmakeconfig.h.in \
|
||||||
|
cmake/preconfigure.cmake \
|
||||||
|
config/have_siocglifconf.c \
|
||||||
config.guess \
|
config.guess \
|
||||||
config.h.in \
|
config.h.in \
|
||||||
config.sub \
|
config.sub \
|
||||||
configure \
|
configure \
|
||||||
configure.in \
|
configure.ac \
|
||||||
dlpisubs.c \
|
dlpisubs.c \
|
||||||
dlpisubs.h \
|
dlpisubs.h \
|
||||||
fad-getad.c \
|
fad-getad.c \
|
||||||
fad-gifc.c \
|
fad-gifc.c \
|
||||||
fad-glifc.c \
|
fad-glifc.c \
|
||||||
fad-null.c \
|
fad-helpers.c \
|
||||||
fad-sita.c \
|
gen_version_c.sh \
|
||||||
fad-win32.c \
|
gen_version_header.sh \
|
||||||
grammar.y \
|
grammar.y \
|
||||||
install-sh \
|
install-sh \
|
||||||
lbl/os-aix4.h \
|
lbl/os-aix4.h \
|
||||||
|
lbl/os-aix7.h \
|
||||||
lbl/os-hpux11.h \
|
lbl/os-hpux11.h \
|
||||||
lbl/os-osf4.h \
|
lbl/os-osf4.h \
|
||||||
lbl/os-osf5.h \
|
lbl/os-osf5.h \
|
||||||
lbl/os-solaris2.h \
|
lbl/os-solaris2.h \
|
||||||
lbl/os-sunos4.h \
|
lbl/os-sunos4.h \
|
||||||
lbl/os-ultrix4.h \
|
lbl/os-ultrix4.h \
|
||||||
|
missing/getopt.c \
|
||||||
|
missing/getopt.h \
|
||||||
missing/snprintf.c \
|
missing/snprintf.c \
|
||||||
|
missing/strtok_r.c \
|
||||||
|
missing/win_snprintf.c \
|
||||||
mkdep \
|
mkdep \
|
||||||
msdos/bin2c.c \
|
msdos/bin2c.c \
|
||||||
msdos/common.dj \
|
msdos/common.dj \
|
||||||
|
@ -291,16 +306,11 @@ EXTRA_DIST = \
|
||||||
msdos/pktdrvr.h \
|
msdos/pktdrvr.h \
|
||||||
msdos/readme.dos \
|
msdos/readme.dos \
|
||||||
org.tcpdump.chmod_bpf.plist \
|
org.tcpdump.chmod_bpf.plist \
|
||||||
packaging/pcap.spec.in \
|
|
||||||
pcap-bpf.c \
|
pcap-bpf.c \
|
||||||
pcap-bt-linux.c \
|
pcap-bt-linux.c \
|
||||||
pcap-bt-linux.h \
|
pcap-bt-linux.h \
|
||||||
pcap-bt-monitor-linux.c \
|
pcap-bt-monitor-linux.c \
|
||||||
pcap-bt-monitor-linux.h \
|
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-config.in \
|
||||||
pcap-dag.c \
|
pcap-dag.c \
|
||||||
pcap-dag.h \
|
pcap-dag.h \
|
||||||
|
@ -314,11 +324,14 @@ EXTRA_DIST = \
|
||||||
pcap-libdlpi.c \
|
pcap-libdlpi.c \
|
||||||
pcap-linux.c \
|
pcap-linux.c \
|
||||||
pcap-namedb.h \
|
pcap-namedb.h \
|
||||||
|
pcap-new.c \
|
||||||
pcap-netfilter-linux.c \
|
pcap-netfilter-linux.c \
|
||||||
pcap-netfilter-linux.h \
|
pcap-netfilter-linux.h \
|
||||||
pcap-nit.c \
|
pcap-nit.c \
|
||||||
pcap-null.c \
|
pcap-null.c \
|
||||||
pcap-pf.c \
|
pcap-pf.c \
|
||||||
|
pcap-rpcap.c \
|
||||||
|
pcap-rpcap.h \
|
||||||
pcap-septel.c \
|
pcap-septel.c \
|
||||||
pcap-septel.h \
|
pcap-septel.h \
|
||||||
pcap-sita.h \
|
pcap-sita.h \
|
||||||
|
@ -328,34 +341,22 @@ EXTRA_DIST = \
|
||||||
pcap-snf.h \
|
pcap-snf.h \
|
||||||
pcap-snit.c \
|
pcap-snit.c \
|
||||||
pcap-snoop.c \
|
pcap-snoop.c \
|
||||||
|
pcap-tc.c \
|
||||||
|
pcap-tc.h \
|
||||||
pcap-usb-linux.c \
|
pcap-usb-linux.c \
|
||||||
pcap-usb-linux.h \
|
pcap-usb-linux.h \
|
||||||
pcap-win32.c \
|
pcap-win32.c \
|
||||||
runlex.sh \
|
remote-ext.h \
|
||||||
|
sockutils.c \
|
||||||
|
sockutils.h \
|
||||||
scanner.l \
|
scanner.l \
|
||||||
|
tests/CMakeLists.txt \
|
||||||
|
pcap_version.h.in \
|
||||||
Win32/Include/Gnuc.h \
|
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/if.h \
|
||||||
Win32/Include/net/netdb.h \
|
Win32/Prj/wpcap.sln \
|
||||||
Win32/Include/net/paths.h \
|
Win32/Prj/wpcap.vcxproj \
|
||||||
Win32/Prj/libpcap.dsp \
|
Win32/Prj/wpcap.vcxproj.filters
|
||||||
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
|
|
||||||
|
|
||||||
all: libpcap.a shared pcap-config
|
all: libpcap.a shared pcap-config
|
||||||
|
|
||||||
|
@ -443,24 +444,33 @@ libpcap.shareda: $(OBJ)
|
||||||
libpcap.none:
|
libpcap.none:
|
||||||
|
|
||||||
scanner.c: $(srcdir)/scanner.l
|
scanner.c: $(srcdir)/scanner.l
|
||||||
@rm -f $@
|
$(LEX) -P pcap_ --header-file=scanner.h --nounput -o scanner.c $<
|
||||||
$(srcdir)/runlex.sh $(LEX) -o$@ $<
|
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
|
$(CC) $(FULL_CFLAGS) -c scanner.c
|
||||||
|
|
||||||
pcap.o: version.h
|
pcap.o: pcap_version.h
|
||||||
|
|
||||||
tokdefs.h: grammar.c
|
|
||||||
grammar.c: $(srcdir)/grammar.y
|
grammar.c: $(srcdir)/grammar.y
|
||||||
@rm -f grammar.c tokdefs.h
|
$(YACC) -p pcap_ -o grammar.c -d $<
|
||||||
$(YACC) -d $<
|
grammar.h: grammar.c
|
||||||
mv y.tab.c grammar.c
|
## Recover from the removal of $@
|
||||||
mv y.tab.h tokdefs.h
|
@if test -f $@; then :; else \
|
||||||
|
rm -f grammar.c; \
|
||||||
|
$(MAKE) $(MAKEFLAGS) grammar.c; \
|
||||||
|
fi
|
||||||
|
|
||||||
grammar.o: grammar.c
|
grammar.o: grammar.c
|
||||||
@rm -f $@
|
$(CC) $(FULL_CFLAGS) -c grammar.c
|
||||||
$(CC) $(FULL_CFLAGS) -Dyylval=pcap_lval -c grammar.c
|
|
||||||
|
gencode.o: $(srcdir)/gencode.c grammar.h scanner.h
|
||||||
|
$(CC) $(FULL_CFLAGS) -c $(srcdir)/gencode.c
|
||||||
|
|
||||||
version.o: version.c
|
version.o: version.c
|
||||||
$(CC) $(FULL_CFLAGS) -c version.c
|
$(CC) $(FULL_CFLAGS) -c version.c
|
||||||
|
@ -468,32 +478,21 @@ version.o: version.c
|
||||||
snprintf.o: $(srcdir)/missing/snprintf.c
|
snprintf.o: $(srcdir)/missing/snprintf.c
|
||||||
$(CC) $(FULL_CFLAGS) -o $@ -c $(srcdir)/missing/snprintf.c
|
$(CC) $(FULL_CFLAGS) -o $@ -c $(srcdir)/missing/snprintf.c
|
||||||
|
|
||||||
version.c: $(srcdir)/VERSION
|
strtok_r.o: $(srcdir)/missing/strtok_r.c
|
||||||
@rm -f $@
|
$(CC) $(FULL_CFLAGS) -o $@ -c $(srcdir)/missing/strtok_r.c
|
||||||
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[] = "&";/' > $@
|
|
||||||
|
|
||||||
#
|
version.c: $(srcdir)/VERSION $(srcdir)/gen_version_c.sh
|
||||||
# NOTE: this really is supposed to be static; importing a string
|
#
|
||||||
# from a shared library does not work very well on many
|
# Older programs import this if they want to show the
|
||||||
# versions of UNIX (Solaris, Linux, and the BSDs, for example),
|
# libpcap version number, rather than calling
|
||||||
# so we make the version string static and return it from
|
# pcap_lib_version(), so we need to export it.
|
||||||
# a function, which does work.
|
#
|
||||||
#
|
|
||||||
version.h: $(srcdir)/VERSION
|
|
||||||
@rm -f $@
|
@rm -f $@
|
||||||
if grep GIT ${srcdir}/VERSION >/dev/null; then \
|
$(srcdir)/gen_version_c.sh $(srcdir)/VERSION $@
|
||||||
read ver <${srcdir}/VERSION; \
|
|
||||||
echo $$ver | tr -d '\012'; \
|
pcap_version.h: $(srcdir)/VERSION $(srcdir)/pcap_version.h.in $(srcdir)/gen_version_header.sh
|
||||||
date +_%Y_%m_%d; \
|
@rm -f $@
|
||||||
else \
|
$(srcdir)/gen_version_header.sh $(srcdir)/VERSION $(srcdir)/pcap_version.h.in $@
|
||||||
cat ${srcdir}/VERSION; \
|
|
||||||
fi | sed -e 's/.*/static const char pcap_version_string[] = "libpcap version &";/' > $@
|
|
||||||
|
|
||||||
bpf_filter.c: $(srcdir)/bpf/net/bpf_filter.c
|
bpf_filter.c: $(srcdir)/bpf/net/bpf_filter.c
|
||||||
rm -f bpf_filter.c
|
rm -f bpf_filter.c
|
||||||
|
@ -530,6 +529,9 @@ tests: $(TESTS)
|
||||||
capturetest: tests/capturetest.c libpcap.a
|
capturetest: tests/capturetest.c libpcap.a
|
||||||
$(CC) $(FULL_CFLAGS) -I. -L. -o capturetest $(srcdir)/tests/capturetest.c libpcap.a $(LIBS)
|
$(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
|
filtertest: tests/filtertest.c libpcap.a
|
||||||
$(CC) $(FULL_CFLAGS) -I. -L. -o filtertest $(srcdir)/tests/filtertest.c libpcap.a $(LIBS)
|
$(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
|
opentest: tests/opentest.c libpcap.a
|
||||||
$(CC) $(FULL_CFLAGS) -I. -L. -o opentest $(srcdir)/tests/opentest.c libpcap.a $(LIBS)
|
$(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
|
selpolltest: tests/selpolltest.c libpcap.a
|
||||||
$(CC) $(FULL_CFLAGS) -I. -L. -o selpolltest $(srcdir)/tests/selpolltest.c libpcap.a $(LIBS)
|
$(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 -f $(MAN3PCAP_EXPAND:.in=) $(MANFILE:.in=) $(MANMISC:.in=)
|
||||||
rm -rf autom4te.cache
|
rm -rf autom4te.cache
|
||||||
|
|
||||||
|
extags: $(TAGFILES)
|
||||||
|
ctags $(TAGFILES)
|
||||||
|
|
||||||
tags: $(TAGFILES)
|
tags: $(TAGFILES)
|
||||||
ctags -wtd $(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:
|
releasetar:
|
||||||
@cwd=`pwd` ; dir=`basename $$cwd` ; name=$(PROG)-`cat VERSION` ; \
|
@cwd=`pwd` ; dir=`basename $$cwd` ; name=$(PROG)-`cat VERSION` ; \
|
||||||
mkdir $$name; \
|
mkdir $$name; \
|
||||||
|
|
|
@ -76,15 +76,15 @@ information on configuring that option.
|
||||||
|
|
||||||
Note to Linux distributions and *BSD systems that include libpcap:
|
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.
|
and *BSD, among other platforms.
|
||||||
|
|
||||||
It sets the soname of the library to "libpcap.so.1"; this is what it
|
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
|
should be, *NOT* libpcap.so.1.x or libpcap.so.1.x.y or something such as
|
||||||
that.
|
that.
|
||||||
|
|
||||||
We've been maintaining binary compatibility between libpcap releases for
|
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
|
quite a while; there's no reason to tie a binary linked with libpcap to
|
||||||
a particular release of libpcap.
|
a particular release of libpcap.
|
||||||
|
|
||||||
Problems, bugs, questions, desirable enhancements, etc. should be sent
|
Problems, bugs, questions, desirable enhancements, etc. should be sent
|
||||||
|
|
|
@ -6,11 +6,11 @@ Important stuff (to be done before the next release)
|
||||||
|
|
||||||
General
|
General
|
||||||
|
|
||||||
- configure should not be in Git. Most open source projects have an
|
- configure should not be in Git. Most open source projects have an
|
||||||
autogen.sh script to run autoconf etc. after checkout. I think we
|
autogen.sh script to run autoconf etc. after checkout. I think we
|
||||||
should stick to the standard.
|
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
|
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
|
style (okay, you can guess that by looking at the code) and a guide for
|
||||||
what needs to be documented.
|
what needs to be documented.
|
||||||
|
@ -18,7 +18,7 @@ General
|
||||||
Less urgent items
|
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:
|
problems at the first glance which needs fixing:
|
||||||
+ pcap_lookupnet makes little to no sense with protocols != IPv4
|
+ pcap_lookupnet makes little to no sense with protocols != IPv4
|
||||||
+ not very well suited for interactive programs (think ethereal). There
|
+ not very well suited for interactive programs (think ethereal). There
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
1.6.2
|
1.8.1
|
||||||
|
|
|
@ -42,11 +42,11 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef _WIN32
|
||||||
|
|
||||||
#include <pcap-stdinc.h>
|
#include <pcap-stdinc.h>
|
||||||
|
|
||||||
#else /* WIN32 */
|
#else /* _WIN32 */
|
||||||
|
|
||||||
#if HAVE_INTTYPES_H
|
#if HAVE_INTTYPES_H
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
@ -73,7 +73,7 @@
|
||||||
# define MLEN(m) ((m)->m_len)
|
# define MLEN(m) ((m)->m_len)
|
||||||
#endif /* defined(__hpux) || SOLARIS */
|
#endif /* defined(__hpux) || SOLARIS */
|
||||||
|
|
||||||
#endif /* WIN32 */
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
#include <pcap/bpf.h>
|
#include <pcap/bpf.h>
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef LBL_ALIGN
|
#ifndef LBL_ALIGN
|
||||||
#ifndef WIN32
|
#ifndef _WIN32
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -195,23 +195,41 @@ m_xhalf(m, k, err)
|
||||||
}
|
}
|
||||||
#endif
|
#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
|
* Execute the filter program starting at pc on the packet p
|
||||||
* wirelen is the length of the original packet
|
* wirelen is the length of the original packet
|
||||||
* buflen is the amount of data present
|
* 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,
|
* 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.
|
* 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
|
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 struct bpf_insn *pc;
|
||||||
register const u_char *p;
|
register const u_char *p;
|
||||||
u_int wirelen;
|
u_int wirelen;
|
||||||
register u_int buflen;
|
register u_int buflen;
|
||||||
|
register const struct bpf_aux_data *aux_data;
|
||||||
{
|
{
|
||||||
register u_int32 A, X;
|
register u_int32 A, X;
|
||||||
register int k;
|
register bpf_u_int32 k;
|
||||||
int32 mem[BPF_MEMWORDS];
|
u_int32 mem[BPF_MEMWORDS];
|
||||||
#if defined(KERNEL) || defined(_KERNEL)
|
#if defined(KERNEL) || defined(_KERNEL)
|
||||||
struct mbuf *m, *n;
|
struct mbuf *m, *n;
|
||||||
int merr, len;
|
int merr, len;
|
||||||
|
@ -250,7 +268,7 @@ bpf_filter(pc, p, wirelen, buflen)
|
||||||
|
|
||||||
case BPF_LD|BPF_W|BPF_ABS:
|
case BPF_LD|BPF_W|BPF_ABS:
|
||||||
k = pc->k;
|
k = pc->k;
|
||||||
if (k + sizeof(int32) > buflen) {
|
if (k > buflen || sizeof(int32_t) > buflen - k) {
|
||||||
#if defined(KERNEL) || defined(_KERNEL)
|
#if defined(KERNEL) || defined(_KERNEL)
|
||||||
if (m == NULL)
|
if (m == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -267,7 +285,7 @@ bpf_filter(pc, p, wirelen, buflen)
|
||||||
|
|
||||||
case BPF_LD|BPF_H|BPF_ABS:
|
case BPF_LD|BPF_H|BPF_ABS:
|
||||||
k = pc->k;
|
k = pc->k;
|
||||||
if (k + sizeof(short) > buflen) {
|
if (k > buflen || sizeof(int16_t) > buflen - k) {
|
||||||
#if defined(KERNEL) || defined(_KERNEL)
|
#if defined(KERNEL) || defined(_KERNEL)
|
||||||
if (m == NULL)
|
if (m == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -283,22 +301,50 @@ bpf_filter(pc, p, wirelen, buflen)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case BPF_LD|BPF_B|BPF_ABS:
|
case BPF_LD|BPF_B|BPF_ABS:
|
||||||
k = pc->k;
|
{
|
||||||
if (k >= buflen) {
|
#if defined(SKF_AD_VLAN_TAG) && defined(SKF_AD_VLAN_TAG_PRESENT)
|
||||||
#if defined(KERNEL) || defined(_KERNEL)
|
int code = BPF_S_ANC_NONE;
|
||||||
if (m == NULL)
|
#define ANCILLARY(CODE) case SKF_AD_OFF + SKF_AD_##CODE: \
|
||||||
return 0;
|
code = BPF_S_ANC_##CODE; \
|
||||||
n = m;
|
if (!aux_data) \
|
||||||
MINDEX(len, n, k);
|
return 0; \
|
||||||
A = mtod(n, u_char *)[k];
|
break;
|
||||||
continue;
|
|
||||||
#else
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
A = p[k];
|
|
||||||
continue;
|
|
||||||
|
|
||||||
|
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:
|
case BPF_LD|BPF_W|BPF_LEN:
|
||||||
A = wirelen;
|
A = wirelen;
|
||||||
continue;
|
continue;
|
||||||
|
@ -309,7 +355,8 @@ bpf_filter(pc, p, wirelen, buflen)
|
||||||
|
|
||||||
case BPF_LD|BPF_W|BPF_IND:
|
case BPF_LD|BPF_W|BPF_IND:
|
||||||
k = X + pc->k;
|
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 defined(KERNEL) || defined(_KERNEL)
|
||||||
if (m == NULL)
|
if (m == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -326,7 +373,8 @@ bpf_filter(pc, p, wirelen, buflen)
|
||||||
|
|
||||||
case BPF_LD|BPF_H|BPF_IND:
|
case BPF_LD|BPF_H|BPF_IND:
|
||||||
k = X + pc->k;
|
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 defined(KERNEL) || defined(_KERNEL)
|
||||||
if (m == NULL)
|
if (m == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -343,7 +391,7 @@ bpf_filter(pc, p, wirelen, buflen)
|
||||||
|
|
||||||
case BPF_LD|BPF_B|BPF_IND:
|
case BPF_LD|BPF_B|BPF_IND:
|
||||||
k = X + pc->k;
|
k = X + pc->k;
|
||||||
if (k >= buflen) {
|
if (pc->k >= buflen || X >= buflen - pc->k) {
|
||||||
#if defined(KERNEL) || defined(_KERNEL)
|
#if defined(KERNEL) || defined(_KERNEL)
|
||||||
if (m == NULL)
|
if (m == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -531,7 +579,12 @@ bpf_filter(pc, p, wirelen, buflen)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case BPF_ALU|BPF_NEG:
|
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;
|
continue;
|
||||||
|
|
||||||
case BPF_MISC|BPF_TAX:
|
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.
|
* Return true if the 'fcode' is a valid filter program.
|
||||||
* The constraints are that each jump be forward and to a valid
|
* The constraints are that each jump be forward and to a valid
|
||||||
|
@ -574,7 +638,7 @@ bpf_validate(f, len)
|
||||||
return 0;
|
return 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (i = 0; i < len; ++i) {
|
for (i = 0; i < (u_int)len; ++i) {
|
||||||
p = &f[i];
|
p = &f[i];
|
||||||
switch (BPF_CLASS(p->code)) {
|
switch (BPF_CLASS(p->code)) {
|
||||||
/*
|
/*
|
||||||
|
@ -675,7 +739,7 @@ bpf_validate(f, len)
|
||||||
#if defined(KERNEL) || defined(_KERNEL)
|
#if defined(KERNEL) || defined(_KERNEL)
|
||||||
if (from + p->k < from || from + p->k >= len)
|
if (from + p->k < from || from + p->k >= len)
|
||||||
#else
|
#else
|
||||||
if (from + p->k >= len)
|
if (from + p->k >= (u_int)len)
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
|
@ -683,7 +747,7 @@ bpf_validate(f, len)
|
||||||
case BPF_JGT:
|
case BPF_JGT:
|
||||||
case BPF_JGE:
|
case BPF_JGE:
|
||||||
case BPF_JSET:
|
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;
|
return 0;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -51,7 +51,10 @@ bpf_dump(const struct bpf_program *p, int option)
|
||||||
for (i = 0; i < n; ++insn, ++i) {
|
for (i = 0; i < n; ++insn, ++i) {
|
||||||
#ifdef BDEBUG
|
#ifdef BDEBUG
|
||||||
extern int bids[];
|
extern int bids[];
|
||||||
printf(bids[i] > 0 ? "[%02d]" : " -- ", bids[i] - 1);
|
if (bids[i] > 0)
|
||||||
|
printf("[%02d]", bids[i] - 1);
|
||||||
|
else
|
||||||
|
printf(" -- ");
|
||||||
#endif
|
#endif
|
||||||
puts(bpf_image(insn, i));
|
puts(bpf_image(insn, i));
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,9 +23,9 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef _WIN32
|
||||||
#include <pcap-stdinc.h>
|
#include <pcap-stdinc.h>
|
||||||
#else /* WIN32 */
|
#else /* _WIN32 */
|
||||||
#if HAVE_INTTYPES_H
|
#if HAVE_INTTYPES_H
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#elif HAVE_STDINT_H
|
#elif HAVE_STDINT_H
|
||||||
|
@ -35,7 +35,7 @@
|
||||||
#include <sys/bitypes.h>
|
#include <sys/bitypes.h>
|
||||||
#endif
|
#endif
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#endif /* WIN32 */
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -306,13 +306,13 @@ bpf_image(p, n)
|
||||||
fmt = "";
|
fmt = "";
|
||||||
break;
|
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) {
|
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",
|
"(%03d) %-8s %-16s jt %d\tjf %d",
|
||||||
n, op, operand, n + 1 + p->jt, n + 1 + p->jf);
|
n, op, operand, n + 1 + p->jt, n + 1 + p->jf);
|
||||||
} else {
|
} else {
|
||||||
(void)snprintf(image, sizeof image,
|
(void)pcap_snprintf(image, sizeof image,
|
||||||
"(%03d) %-8s %s",
|
"(%03d) %-8s %s",
|
||||||
n, op, operand);
|
n, op, operand);
|
||||||
}
|
}
|
||||||
|
|
373
contrib/libpcap/config.guess
vendored
373
contrib/libpcap/config.guess
vendored
|
@ -1,14 +1,12 @@
|
||||||
#! /bin/sh
|
#! /bin/sh
|
||||||
# Attempt to guess a canonical system name.
|
# Attempt to guess a canonical system name.
|
||||||
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
# Copyright 1992-2015 Free Software Foundation, Inc.
|
||||||
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
|
||||||
# 2011, 2012 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
|
# 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
|
# 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.
|
# (at your option) any later version.
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful, but
|
# 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
|
# As a special exception to the GNU General Public License, if you
|
||||||
# distribute this file as part of a program that contains a
|
# distribute this file as part of a program that contains a
|
||||||
# configuration script generated by Autoconf, you may include it under
|
# 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").
|
||||||
# Originally written by Per Bothner. Please send patches (context
|
|
||||||
# diff format) to <config-patches@gnu.org> and include a ChangeLog
|
|
||||||
# entry.
|
|
||||||
#
|
#
|
||||||
# This script attempts to guess a canonical system name similar to
|
# Originally written by Per Bothner; maintained since 2000 by Ben Elliston.
|
||||||
# config.sub. If it succeeds, it prints the system name on stdout, and
|
|
||||||
# exits with 0. Otherwise, it exits with 1.
|
|
||||||
#
|
#
|
||||||
# You can get the latest version of this script from:
|
# 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
|
# 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,.*/,,'`
|
me=`echo "$0" | sed -e 's,.*/,,'`
|
||||||
|
|
||||||
|
@ -54,9 +50,7 @@ version="\
|
||||||
GNU config.guess ($timestamp)
|
GNU config.guess ($timestamp)
|
||||||
|
|
||||||
Originally written by Per Bothner.
|
Originally written by Per Bothner.
|
||||||
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
|
Copyright 1992-2015 Free Software Foundation, Inc.
|
||||||
2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
|
|
||||||
Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This is free software; see the source for copying conditions. There is NO
|
This is free software; see the source for copying conditions. There is NO
|
||||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
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_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
|
||||||
UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=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.
|
# Note: order is significant - the case branches are not exclusive.
|
||||||
|
|
||||||
case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
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
|
# Note: NetBSD doesn't particularly care about the vendor
|
||||||
# portion of the name. We always set it to "unknown".
|
# portion of the name. We always set it to "unknown".
|
||||||
sysctl="sysctl -n hw.machine_arch"
|
sysctl="sysctl -n hw.machine_arch"
|
||||||
UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
|
UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \
|
||||||
/usr/sbin/$sysctl 2>/dev/null || echo unknown)`
|
/sbin/$sysctl 2>/dev/null || \
|
||||||
|
/usr/sbin/$sysctl 2>/dev/null || \
|
||||||
|
echo unknown)`
|
||||||
case "${UNAME_MACHINE_ARCH}" in
|
case "${UNAME_MACHINE_ARCH}" in
|
||||||
armeb) machine=armeb-unknown ;;
|
armeb) machine=armeb-unknown ;;
|
||||||
arm*) machine=arm-unknown ;;
|
arm*) machine=arm-unknown ;;
|
||||||
sh3el) machine=shl-unknown ;;
|
sh3el) machine=shl-unknown ;;
|
||||||
sh3eb) machine=sh-unknown ;;
|
sh3eb) machine=sh-unknown ;;
|
||||||
sh5el) machine=sh5le-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 ;;
|
*) machine=${UNAME_MACHINE_ARCH}-unknown ;;
|
||||||
esac
|
esac
|
||||||
# The Operating System including object format, if it has switched
|
# The Operating System including object format, if it has switched
|
||||||
# to ELF recently, or will in the future.
|
# to ELF recently, or will in the future.
|
||||||
case "${UNAME_MACHINE_ARCH}" in
|
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
|
eval $set_cc_for_build
|
||||||
if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
|
if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
|
||||||
| grep -q __ELF__
|
| grep -q __ELF__
|
||||||
|
@ -182,6 +204,13 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||||
os=netbsd
|
os=netbsd
|
||||||
;;
|
;;
|
||||||
esac
|
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
|
# The OS release
|
||||||
# Debian GNU/NetBSD machines have a different userland, and
|
# Debian GNU/NetBSD machines have a different userland, and
|
||||||
# thus, need a distinct triplet. However, they do not need
|
# 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:
|
# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
|
||||||
# contains redundant information, the shorter form:
|
# contains redundant information, the shorter form:
|
||||||
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
|
# 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 ;;
|
exit ;;
|
||||||
*:OpenBSD:*:*)
|
*:OpenBSD:*:*)
|
||||||
UNAME_MACHINE_ARCH=`arch | sed 's/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]*:*)
|
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
|
||||||
echo arm-acorn-riscix${UNAME_RELEASE}
|
echo arm-acorn-riscix${UNAME_RELEASE}
|
||||||
exit ;;
|
exit ;;
|
||||||
arm:riscos:*:*|arm:RISCOS:*:*)
|
arm*:riscos:*:*|arm*:RISCOS:*:*)
|
||||||
echo arm-unknown-riscos
|
echo arm-unknown-riscos
|
||||||
exit ;;
|
exit ;;
|
||||||
SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
|
SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
|
||||||
|
@ -560,8 +593,9 @@ EOF
|
||||||
else
|
else
|
||||||
IBM_ARCH=powerpc
|
IBM_ARCH=powerpc
|
||||||
fi
|
fi
|
||||||
if [ -x /usr/bin/oslevel ] ; then
|
if [ -x /usr/bin/lslpp ] ; then
|
||||||
IBM_REV=`/usr/bin/oslevel`
|
IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc |
|
||||||
|
awk -F: '{ print $3 }' | sed s/[0-9]*$/0/`
|
||||||
else
|
else
|
||||||
IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
|
IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
|
||||||
fi
|
fi
|
||||||
|
@ -801,10 +835,13 @@ EOF
|
||||||
i*:CYGWIN*:*)
|
i*:CYGWIN*:*)
|
||||||
echo ${UNAME_MACHINE}-pc-cygwin
|
echo ${UNAME_MACHINE}-pc-cygwin
|
||||||
exit ;;
|
exit ;;
|
||||||
|
*:MINGW64*:*)
|
||||||
|
echo ${UNAME_MACHINE}-pc-mingw64
|
||||||
|
exit ;;
|
||||||
*:MINGW*:*)
|
*:MINGW*:*)
|
||||||
echo ${UNAME_MACHINE}-pc-mingw32
|
echo ${UNAME_MACHINE}-pc-mingw32
|
||||||
exit ;;
|
exit ;;
|
||||||
i*:MSYS*:*)
|
*:MSYS*:*)
|
||||||
echo ${UNAME_MACHINE}-pc-msys
|
echo ${UNAME_MACHINE}-pc-msys
|
||||||
exit ;;
|
exit ;;
|
||||||
i*:windows32*:*)
|
i*:windows32*:*)
|
||||||
|
@ -852,21 +889,21 @@ EOF
|
||||||
exit ;;
|
exit ;;
|
||||||
*:GNU:*:*)
|
*:GNU:*:*)
|
||||||
# the GNU system
|
# 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 ;;
|
exit ;;
|
||||||
*:GNU/*:*:*)
|
*:GNU/*:*:*)
|
||||||
# other systems with GNU libc and userland
|
# 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 ;;
|
exit ;;
|
||||||
i*86:Minix:*:*)
|
i*86:Minix:*:*)
|
||||||
echo ${UNAME_MACHINE}-pc-minix
|
echo ${UNAME_MACHINE}-pc-minix
|
||||||
exit ;;
|
exit ;;
|
||||||
aarch64:Linux:*:*)
|
aarch64:Linux:*:*)
|
||||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||||
exit ;;
|
exit ;;
|
||||||
aarch64_be:Linux:*:*)
|
aarch64_be:Linux:*:*)
|
||||||
UNAME_MACHINE=aarch64_be
|
UNAME_MACHINE=aarch64_be
|
||||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||||
exit ;;
|
exit ;;
|
||||||
alpha:Linux:*:*)
|
alpha:Linux:*:*)
|
||||||
case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
|
case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
|
||||||
|
@ -879,59 +916,54 @@ EOF
|
||||||
EV68*) UNAME_MACHINE=alphaev68 ;;
|
EV68*) UNAME_MACHINE=alphaev68 ;;
|
||||||
esac
|
esac
|
||||||
objdump --private-headers /bin/sh | grep -q ld.so.1
|
objdump --private-headers /bin/sh | grep -q ld.so.1
|
||||||
if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
|
if test "$?" = 0 ; then LIBC="gnulibc1" ; fi
|
||||||
echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
|
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||||
|
exit ;;
|
||||||
|
arc:Linux:*:* | arceb:Linux:*:*)
|
||||||
|
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||||
exit ;;
|
exit ;;
|
||||||
arm*:Linux:*:*)
|
arm*:Linux:*:*)
|
||||||
eval $set_cc_for_build
|
eval $set_cc_for_build
|
||||||
if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
|
if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
|
||||||
| grep -q __ARM_EABI__
|
| grep -q __ARM_EABI__
|
||||||
then
|
then
|
||||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||||
else
|
else
|
||||||
if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
|
if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
|
||||||
| grep -q __ARM_PCS_VFP
|
| grep -q __ARM_PCS_VFP
|
||||||
then
|
then
|
||||||
echo ${UNAME_MACHINE}-unknown-linux-gnueabi
|
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi
|
||||||
else
|
else
|
||||||
echo ${UNAME_MACHINE}-unknown-linux-gnueabihf
|
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
exit ;;
|
exit ;;
|
||||||
avr32*:Linux:*:*)
|
avr32*:Linux:*:*)
|
||||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||||
exit ;;
|
exit ;;
|
||||||
cris:Linux:*:*)
|
cris:Linux:*:*)
|
||||||
echo ${UNAME_MACHINE}-axis-linux-gnu
|
echo ${UNAME_MACHINE}-axis-linux-${LIBC}
|
||||||
exit ;;
|
exit ;;
|
||||||
crisv32:Linux:*:*)
|
crisv32:Linux:*:*)
|
||||||
echo ${UNAME_MACHINE}-axis-linux-gnu
|
echo ${UNAME_MACHINE}-axis-linux-${LIBC}
|
||||||
exit ;;
|
exit ;;
|
||||||
frv:Linux:*:*)
|
frv:Linux:*:*)
|
||||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||||
exit ;;
|
exit ;;
|
||||||
hexagon:Linux:*:*)
|
hexagon:Linux:*:*)
|
||||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||||
exit ;;
|
exit ;;
|
||||||
i*86:Linux:*:*)
|
i*86:Linux:*:*)
|
||||||
LIBC=gnu
|
echo ${UNAME_MACHINE}-pc-linux-${LIBC}
|
||||||
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}"
|
|
||||||
exit ;;
|
exit ;;
|
||||||
ia64:Linux:*:*)
|
ia64:Linux:*:*)
|
||||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||||
exit ;;
|
exit ;;
|
||||||
m32r*:Linux:*:*)
|
m32r*:Linux:*:*)
|
||||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||||
exit ;;
|
exit ;;
|
||||||
m68*:Linux:*:*)
|
m68*:Linux:*:*)
|
||||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||||
exit ;;
|
exit ;;
|
||||||
mips:Linux:*:* | mips64:Linux:*:*)
|
mips:Linux:*:* | mips64:Linux:*:*)
|
||||||
eval $set_cc_for_build
|
eval $set_cc_for_build
|
||||||
|
@ -950,54 +982,63 @@ EOF
|
||||||
#endif
|
#endif
|
||||||
EOF
|
EOF
|
||||||
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
|
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:*:*)
|
openrisc*:Linux:*:*)
|
||||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
echo or1k-unknown-linux-${LIBC}
|
||||||
|
exit ;;
|
||||||
|
or32:Linux:*:* | or1k*:Linux:*:*)
|
||||||
|
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||||
exit ;;
|
exit ;;
|
||||||
padre:Linux:*:*)
|
padre:Linux:*:*)
|
||||||
echo sparc-unknown-linux-gnu
|
echo sparc-unknown-linux-${LIBC}
|
||||||
exit ;;
|
exit ;;
|
||||||
parisc64:Linux:*:* | hppa64:Linux:*:*)
|
parisc64:Linux:*:* | hppa64:Linux:*:*)
|
||||||
echo hppa64-unknown-linux-gnu
|
echo hppa64-unknown-linux-${LIBC}
|
||||||
exit ;;
|
exit ;;
|
||||||
parisc:Linux:*:* | hppa:Linux:*:*)
|
parisc:Linux:*:* | hppa:Linux:*:*)
|
||||||
# Look for CPU level
|
# Look for CPU level
|
||||||
case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
|
case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
|
||||||
PA7*) echo hppa1.1-unknown-linux-gnu ;;
|
PA7*) echo hppa1.1-unknown-linux-${LIBC} ;;
|
||||||
PA8*) echo hppa2.0-unknown-linux-gnu ;;
|
PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;
|
||||||
*) echo hppa-unknown-linux-gnu ;;
|
*) echo hppa-unknown-linux-${LIBC} ;;
|
||||||
esac
|
esac
|
||||||
exit ;;
|
exit ;;
|
||||||
ppc64:Linux:*:*)
|
ppc64:Linux:*:*)
|
||||||
echo powerpc64-unknown-linux-gnu
|
echo powerpc64-unknown-linux-${LIBC}
|
||||||
exit ;;
|
exit ;;
|
||||||
ppc:Linux:*:*)
|
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 ;;
|
exit ;;
|
||||||
s390:Linux:*:* | s390x:Linux:*:*)
|
s390:Linux:*:* | s390x:Linux:*:*)
|
||||||
echo ${UNAME_MACHINE}-ibm-linux
|
echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
|
||||||
exit ;;
|
exit ;;
|
||||||
sh64*:Linux:*:*)
|
sh64*:Linux:*:*)
|
||||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||||
exit ;;
|
exit ;;
|
||||||
sh*:Linux:*:*)
|
sh*:Linux:*:*)
|
||||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||||
exit ;;
|
exit ;;
|
||||||
sparc:Linux:*:* | sparc64:Linux:*:*)
|
sparc:Linux:*:* | sparc64:Linux:*:*)
|
||||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||||
exit ;;
|
exit ;;
|
||||||
tile*:Linux:*:*)
|
tile*:Linux:*:*)
|
||||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||||
exit ;;
|
exit ;;
|
||||||
vax:Linux:*:*)
|
vax:Linux:*:*)
|
||||||
echo ${UNAME_MACHINE}-dec-linux-gnu
|
echo ${UNAME_MACHINE}-dec-linux-${LIBC}
|
||||||
exit ;;
|
exit ;;
|
||||||
x86_64:Linux:*:*)
|
x86_64:Linux:*:*)
|
||||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||||
exit ;;
|
exit ;;
|
||||||
xtensa*:Linux:*:*)
|
xtensa*:Linux:*:*)
|
||||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||||
exit ;;
|
exit ;;
|
||||||
i*86:DYNIX/ptx:4*:*)
|
i*86:DYNIX/ptx:4*:*)
|
||||||
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
|
# 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.
|
BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
|
||||||
echo i586-pc-haiku
|
echo i586-pc-haiku
|
||||||
exit ;;
|
exit ;;
|
||||||
|
x86_64:Haiku:*:*)
|
||||||
|
echo x86_64-unknown-haiku
|
||||||
|
exit ;;
|
||||||
SX-4:SUPER-UX:*:*)
|
SX-4:SUPER-UX:*:*)
|
||||||
echo sx4-nec-superux${UNAME_RELEASE}
|
echo sx4-nec-superux${UNAME_RELEASE}
|
||||||
exit ;;
|
exit ;;
|
||||||
|
@ -1227,19 +1271,31 @@ EOF
|
||||||
exit ;;
|
exit ;;
|
||||||
*:Darwin:*:*)
|
*:Darwin:*:*)
|
||||||
UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
|
UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
|
||||||
case $UNAME_PROCESSOR in
|
eval $set_cc_for_build
|
||||||
i386)
|
if test "$UNAME_PROCESSOR" = unknown ; then
|
||||||
eval $set_cc_for_build
|
UNAME_PROCESSOR=powerpc
|
||||||
if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
|
fi
|
||||||
if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
|
if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then
|
||||||
(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
|
if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
|
||||||
grep IS_64BIT_ARCH >/dev/null
|
if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
|
||||||
then
|
(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
|
||||||
UNAME_PROCESSOR="x86_64"
|
grep IS_64BIT_ARCH >/dev/null
|
||||||
fi
|
then
|
||||||
fi ;;
|
case $UNAME_PROCESSOR in
|
||||||
unknown) UNAME_PROCESSOR=powerpc ;;
|
i386) UNAME_PROCESSOR=x86_64 ;;
|
||||||
esac
|
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}
|
echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
|
||||||
exit ;;
|
exit ;;
|
||||||
*:procnto*:*:* | *:QNX:[0123456789]*:*)
|
*:procnto*:*:* | *:QNX:[0123456789]*:*)
|
||||||
|
@ -1256,7 +1312,7 @@ EOF
|
||||||
NEO-?:NONSTOP_KERNEL:*:*)
|
NEO-?:NONSTOP_KERNEL:*:*)
|
||||||
echo neo-tandem-nsk${UNAME_RELEASE}
|
echo neo-tandem-nsk${UNAME_RELEASE}
|
||||||
exit ;;
|
exit ;;
|
||||||
NSE-?:NONSTOP_KERNEL:*:*)
|
NSE-*:NONSTOP_KERNEL:*:*)
|
||||||
echo nse-tandem-nsk${UNAME_RELEASE}
|
echo nse-tandem-nsk${UNAME_RELEASE}
|
||||||
exit ;;
|
exit ;;
|
||||||
NSR-?:NONSTOP_KERNEL:*:*)
|
NSR-?:NONSTOP_KERNEL:*:*)
|
||||||
|
@ -1330,157 +1386,6 @@ EOF
|
||||||
exit ;;
|
exit ;;
|
||||||
esac
|
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
|
cat >&2 <<EOF
|
||||||
$0: unable to guess system type
|
$0: unable to guess system type
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
/* Enable optimizer debugging */
|
||||||
#undef BDEBUG
|
#undef BDEBUG
|
||||||
|
@ -76,12 +76,18 @@
|
||||||
/* Define to 1 if you have the <linux/ethtool.h> header file. */
|
/* Define to 1 if you have the <linux/ethtool.h> header file. */
|
||||||
#undef HAVE_LINUX_ETHTOOL_H
|
#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. */
|
/* Define to 1 if you have the <linux/if_packet.h> header file. */
|
||||||
#undef HAVE_LINUX_IF_PACKET_H
|
#undef HAVE_LINUX_IF_PACKET_H
|
||||||
|
|
||||||
/* Define to 1 if you have the <linux/net_tstamp.h> header file. */
|
/* Define to 1 if you have the <linux/net_tstamp.h> header file. */
|
||||||
#undef HAVE_LINUX_NET_TSTAMP_H
|
#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 */
|
/* if tp_vlan_tci exists */
|
||||||
#undef HAVE_LINUX_TPACKET_AUXDATA_TP_VLAN_TCI
|
#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 */
|
/* if there's an os_proto.h for this platform, to use additional prototypes */
|
||||||
#undef HAVE_OS_PROTO_H
|
#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 */
|
/* define if net/pfvar.h defines PF_NAT through PF_NORDR */
|
||||||
#undef HAVE_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
|
#undef HAVE_SEPTEL_API
|
||||||
|
|
||||||
/* define if you have Myricom SNF API */
|
/* define if you have the Myricom SNF API */
|
||||||
#undef HAVE_SNF_API
|
#undef HAVE_SNF_API
|
||||||
|
|
||||||
/* Define to 1 if you have the `snprintf' function. */
|
/* Define to 1 if you have the `snprintf' function. */
|
||||||
|
@ -163,6 +166,9 @@
|
||||||
/* Define to 1 if you have the `strlcpy' function. */
|
/* Define to 1 if you have the `strlcpy' function. */
|
||||||
#undef HAVE_STRLCPY
|
#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'. */
|
/* Define to 1 if the system has the type `struct BPF_TIMEVAL'. */
|
||||||
#undef HAVE_STRUCT_BPF_TIMEVAL
|
#undef HAVE_STRUCT_BPF_TIMEVAL
|
||||||
|
|
||||||
|
@ -181,6 +187,9 @@
|
||||||
/* Define to 1 if you have the <sys/ioccom.h> header file. */
|
/* Define to 1 if you have the <sys/ioccom.h> header file. */
|
||||||
#undef HAVE_SYS_IOCCOM_H
|
#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. */
|
/* Define to 1 if you have the <sys/sockio.h> header file. */
|
||||||
#undef HAVE_SYS_SOCKIO_H
|
#undef HAVE_SYS_SOCKIO_H
|
||||||
|
|
||||||
|
@ -190,6 +199,9 @@
|
||||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||||
#undef HAVE_SYS_TYPES_H
|
#undef HAVE_SYS_TYPES_H
|
||||||
|
|
||||||
|
/* define if you have the TurboCap API */
|
||||||
|
#undef HAVE_TC_API
|
||||||
|
|
||||||
/* if if_packet.h has tpacket_stats defined */
|
/* if if_packet.h has tpacket_stats defined */
|
||||||
#undef HAVE_TPACKET_STATS
|
#undef HAVE_TPACKET_STATS
|
||||||
|
|
||||||
|
@ -199,9 +211,6 @@
|
||||||
/* if struct usbdevfs_ctrltransfer has bRequestType */
|
/* if struct usbdevfs_ctrltransfer has bRequestType */
|
||||||
#undef HAVE_USBDEVFS_CTRLTRANSFER_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. */
|
/* Define to 1 if you have the `vsnprintf' function. */
|
||||||
#undef HAVE_VSNPRINTF
|
#undef HAVE_VSNPRINTF
|
||||||
|
|
||||||
|
@ -220,9 +229,6 @@
|
||||||
/* path for device for USB sniffing */
|
/* path for device for USB sniffing */
|
||||||
#undef LINUX_USB_MON_DEV
|
#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' */
|
/* Define to 1 if netinet/ether.h declares `ether_hostton' */
|
||||||
#undef NETINET_ETHER_H_DECLARES_ETHER_HOSTTON
|
#undef NETINET_ETHER_H_DECLARES_ETHER_HOSTTON
|
||||||
|
|
||||||
|
@ -259,18 +265,15 @@
|
||||||
/* target host supports Bluetooth Monitor */
|
/* target host supports Bluetooth Monitor */
|
||||||
#undef PCAP_SUPPORT_BT_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 */
|
/* support D-Bus sniffing */
|
||||||
#undef PCAP_SUPPORT_DBUS
|
#undef PCAP_SUPPORT_DBUS
|
||||||
|
|
||||||
/* target host supports netfilter sniffing */
|
/* target host supports netfilter sniffing */
|
||||||
#undef PCAP_SUPPORT_NETFILTER
|
#undef PCAP_SUPPORT_NETFILTER
|
||||||
|
|
||||||
|
/* use Linux packet ring capture if available */
|
||||||
|
#undef PCAP_SUPPORT_PACKET_RING
|
||||||
|
|
||||||
/* target host supports USB sniffing */
|
/* target host supports USB sniffing */
|
||||||
#undef PCAP_SUPPORT_USB
|
#undef PCAP_SUPPORT_USB
|
||||||
|
|
||||||
|
@ -286,6 +289,10 @@
|
||||||
/* Enable parser debugging */
|
/* Enable parser debugging */
|
||||||
#undef YYDEBUG
|
#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. */
|
/* Enable large inode numbers on Mac OS X 10.5. */
|
||||||
#ifndef _DARWIN_USE_64_BIT_INODE
|
#ifndef _DARWIN_USE_64_BIT_INODE
|
||||||
# define _DARWIN_USE_64_BIT_INODE 1
|
# define _DARWIN_USE_64_BIT_INODE 1
|
||||||
|
|
128
contrib/libpcap/config.sub
vendored
128
contrib/libpcap/config.sub
vendored
|
@ -1,24 +1,18 @@
|
||||||
#! /bin/sh
|
#! /bin/sh
|
||||||
# Configuration validation subroutine script.
|
# Configuration validation subroutine script.
|
||||||
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
# Copyright 1992-2015 Free Software Foundation, Inc.
|
||||||
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
|
||||||
# 2011, 2012 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
timestamp='2012-04-18'
|
timestamp='2015-02-22'
|
||||||
|
|
||||||
# This file is (in principle) common to ALL GNU software.
|
# This file is free software; you can redistribute it and/or modify it
|
||||||
# The presence of a machine in this file suggests that SOME GNU software
|
# under the terms of the GNU General Public License as published by
|
||||||
# can handle that machine. It does not imply ALL GNU software can.
|
# the Free Software Foundation; either version 3 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 2 of the License, or
|
|
||||||
# (at your option) any later version.
|
# (at your option) any later version.
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful,
|
# This program is distributed in the hope that it will be useful, but
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
# GNU General Public License for more details.
|
# General Public License for more details.
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program; if not, see <http://www.gnu.org/licenses/>.
|
# 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
|
# As a special exception to the GNU General Public License, if you
|
||||||
# distribute this file as part of a program that contains a
|
# distribute this file as part of a program that contains a
|
||||||
# configuration script generated by Autoconf, you may include it under
|
# 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
|
# Please send patches to <config-patches@gnu.org>.
|
||||||
# diff and a properly formatted GNU ChangeLog entry.
|
|
||||||
#
|
#
|
||||||
# Configuration subroutine to validate and canonicalize a configuration type.
|
# Configuration subroutine to validate and canonicalize a configuration type.
|
||||||
# Supply the specified configuration type as an argument.
|
# Supply the specified configuration type as an argument.
|
||||||
|
@ -73,9 +68,7 @@ Report bugs and patches to <config-patches@gnu.org>."
|
||||||
version="\
|
version="\
|
||||||
GNU config.sub ($timestamp)
|
GNU config.sub ($timestamp)
|
||||||
|
|
||||||
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
|
Copyright 1992-2015 Free Software Foundation, Inc.
|
||||||
2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
|
|
||||||
Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This is free software; see the source for copying conditions. There is NO
|
This is free software; see the source for copying conditions. There is NO
|
||||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
||||||
|
@ -123,8 +116,8 @@ esac
|
||||||
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
|
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
|
||||||
case $maybe_os in
|
case $maybe_os in
|
||||||
nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
|
nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
|
||||||
linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
|
linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
|
||||||
knetbsd*-gnu* | netbsd*-gnu* | \
|
knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \
|
||||||
kopensolaris*-gnu* | \
|
kopensolaris*-gnu* | \
|
||||||
storm-chaos* | os2-emx* | rtmk-nova*)
|
storm-chaos* | os2-emx* | rtmk-nova*)
|
||||||
os=-$maybe_os
|
os=-$maybe_os
|
||||||
|
@ -156,7 +149,7 @@ case $os in
|
||||||
-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
|
-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
|
||||||
-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
|
-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
|
||||||
-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
|
-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
|
||||||
-apple | -axis | -knuth | -cray | -microblaze)
|
-apple | -axis | -knuth | -cray | -microblaze*)
|
||||||
os=
|
os=
|
||||||
basic_machine=$1
|
basic_machine=$1
|
||||||
;;
|
;;
|
||||||
|
@ -259,21 +252,24 @@ case $basic_machine in
|
||||||
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
|
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
|
||||||
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
|
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
|
||||||
| am33_2.0 \
|
| am33_2.0 \
|
||||||
| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
|
| arc | arceb \
|
||||||
| be32 | be64 \
|
| arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
|
||||||
|
| avr | avr32 \
|
||||||
|
| be32 | be64 \
|
||||||
| bfin \
|
| bfin \
|
||||||
| c4x | clipper \
|
| c4x | c8051 | clipper \
|
||||||
| d10v | d30v | dlx | dsp16xx \
|
| d10v | d30v | dlx | dsp16xx \
|
||||||
| epiphany \
|
| epiphany \
|
||||||
| fido | fr30 | frv \
|
| fido | fr30 | frv | ft32 \
|
||||||
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
|
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
|
||||||
| hexagon \
|
| hexagon \
|
||||||
| i370 | i860 | i960 | ia64 \
|
| i370 | i860 | i960 | ia64 \
|
||||||
| ip2k | iq2000 \
|
| ip2k | iq2000 \
|
||||||
|
| k1om \
|
||||||
| le32 | le64 \
|
| le32 | le64 \
|
||||||
| lm32 \
|
| lm32 \
|
||||||
| m32c | m32r | m32rle | m68000 | m68k | m88k \
|
| m32c | m32r | m32rle | m68000 | m68k | m88k \
|
||||||
| maxq | mb | microblaze | mcore | mep | metag \
|
| maxq | mb | microblaze | microblazeel | mcore | mep | metag \
|
||||||
| mips | mipsbe | mipseb | mipsel | mipsle \
|
| mips | mipsbe | mipseb | mipsel | mipsle \
|
||||||
| mips16 \
|
| mips16 \
|
||||||
| mips64 | mips64el \
|
| mips64 | mips64el \
|
||||||
|
@ -287,23 +283,26 @@ case $basic_machine in
|
||||||
| mips64vr5900 | mips64vr5900el \
|
| mips64vr5900 | mips64vr5900el \
|
||||||
| mipsisa32 | mipsisa32el \
|
| mipsisa32 | mipsisa32el \
|
||||||
| mipsisa32r2 | mipsisa32r2el \
|
| mipsisa32r2 | mipsisa32r2el \
|
||||||
|
| mipsisa32r6 | mipsisa32r6el \
|
||||||
| mipsisa64 | mipsisa64el \
|
| mipsisa64 | mipsisa64el \
|
||||||
| mipsisa64r2 | mipsisa64r2el \
|
| mipsisa64r2 | mipsisa64r2el \
|
||||||
|
| mipsisa64r6 | mipsisa64r6el \
|
||||||
| mipsisa64sb1 | mipsisa64sb1el \
|
| mipsisa64sb1 | mipsisa64sb1el \
|
||||||
| mipsisa64sr71k | mipsisa64sr71kel \
|
| mipsisa64sr71k | mipsisa64sr71kel \
|
||||||
|
| mipsr5900 | mipsr5900el \
|
||||||
| mipstx39 | mipstx39el \
|
| mipstx39 | mipstx39el \
|
||||||
| mn10200 | mn10300 \
|
| mn10200 | mn10300 \
|
||||||
| moxie \
|
| moxie \
|
||||||
| mt \
|
| mt \
|
||||||
| msp430 \
|
| msp430 \
|
||||||
| nds32 | nds32le | nds32be \
|
| nds32 | nds32le | nds32be \
|
||||||
| nios | nios2 \
|
| nios | nios2 | nios2eb | nios2el \
|
||||||
| ns16k | ns32k \
|
| ns16k | ns32k \
|
||||||
| open8 \
|
| open8 | or1k | or1knd | or32 \
|
||||||
| or32 \
|
|
||||||
| pdp10 | pdp11 | pj | pjl \
|
| pdp10 | pdp11 | pj | pjl \
|
||||||
| powerpc | powerpc64 | powerpc64le | powerpcle \
|
| powerpc | powerpc64 | powerpc64le | powerpcle \
|
||||||
| pyramid \
|
| pyramid \
|
||||||
|
| riscv32 | riscv64 \
|
||||||
| rl78 | rx \
|
| rl78 | rx \
|
||||||
| score \
|
| score \
|
||||||
| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
|
| 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 \
|
| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
|
||||||
| ubicom32 \
|
| ubicom32 \
|
||||||
| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
|
| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
|
||||||
|
| visium \
|
||||||
| we32k \
|
| we32k \
|
||||||
| x86 | xc16x | xstormy16 | xtensa \
|
| x86 | xc16x | xstormy16 | xtensa \
|
||||||
| z8k | z80)
|
| z8k | z80)
|
||||||
|
@ -328,7 +328,10 @@ case $basic_machine in
|
||||||
c6x)
|
c6x)
|
||||||
basic_machine=tic6x-unknown
|
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
|
basic_machine=$basic_machine-unknown
|
||||||
os=-none
|
os=-none
|
||||||
;;
|
;;
|
||||||
|
@ -370,13 +373,13 @@ case $basic_machine in
|
||||||
| aarch64-* | aarch64_be-* \
|
| aarch64-* | aarch64_be-* \
|
||||||
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
|
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
|
||||||
| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
|
| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
|
||||||
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
|
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
|
||||||
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \
|
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \
|
||||||
| avr-* | avr32-* \
|
| avr-* | avr32-* \
|
||||||
| be32-* | be64-* \
|
| be32-* | be64-* \
|
||||||
| bfin-* | bs2000-* \
|
| bfin-* | bs2000-* \
|
||||||
| c[123]* | c30-* | [cjt]90-* | c4x-* \
|
| c[123]* | c30-* | [cjt]90-* | c4x-* \
|
||||||
| clipper-* | craynv-* | cydra-* \
|
| c8051-* | clipper-* | craynv-* | cydra-* \
|
||||||
| d10v-* | d30v-* | dlx-* \
|
| d10v-* | d30v-* | dlx-* \
|
||||||
| elxsi-* \
|
| elxsi-* \
|
||||||
| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
|
| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
|
||||||
|
@ -385,11 +388,13 @@ case $basic_machine in
|
||||||
| hexagon-* \
|
| hexagon-* \
|
||||||
| i*86-* | i860-* | i960-* | ia64-* \
|
| i*86-* | i860-* | i960-* | ia64-* \
|
||||||
| ip2k-* | iq2000-* \
|
| ip2k-* | iq2000-* \
|
||||||
|
| k1om-* \
|
||||||
| le32-* | le64-* \
|
| le32-* | le64-* \
|
||||||
| lm32-* \
|
| lm32-* \
|
||||||
| m32c-* | m32r-* | m32rle-* \
|
| m32c-* | m32r-* | m32rle-* \
|
||||||
| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
|
| 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-* \
|
| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
|
||||||
| mips16-* \
|
| mips16-* \
|
||||||
| mips64-* | mips64el-* \
|
| mips64-* | mips64el-* \
|
||||||
|
@ -403,18 +408,22 @@ case $basic_machine in
|
||||||
| mips64vr5900-* | mips64vr5900el-* \
|
| mips64vr5900-* | mips64vr5900el-* \
|
||||||
| mipsisa32-* | mipsisa32el-* \
|
| mipsisa32-* | mipsisa32el-* \
|
||||||
| mipsisa32r2-* | mipsisa32r2el-* \
|
| mipsisa32r2-* | mipsisa32r2el-* \
|
||||||
|
| mipsisa32r6-* | mipsisa32r6el-* \
|
||||||
| mipsisa64-* | mipsisa64el-* \
|
| mipsisa64-* | mipsisa64el-* \
|
||||||
| mipsisa64r2-* | mipsisa64r2el-* \
|
| mipsisa64r2-* | mipsisa64r2el-* \
|
||||||
|
| mipsisa64r6-* | mipsisa64r6el-* \
|
||||||
| mipsisa64sb1-* | mipsisa64sb1el-* \
|
| mipsisa64sb1-* | mipsisa64sb1el-* \
|
||||||
| mipsisa64sr71k-* | mipsisa64sr71kel-* \
|
| mipsisa64sr71k-* | mipsisa64sr71kel-* \
|
||||||
|
| mipsr5900-* | mipsr5900el-* \
|
||||||
| mipstx39-* | mipstx39el-* \
|
| mipstx39-* | mipstx39el-* \
|
||||||
| mmix-* \
|
| mmix-* \
|
||||||
| mt-* \
|
| mt-* \
|
||||||
| msp430-* \
|
| msp430-* \
|
||||||
| nds32-* | nds32le-* | nds32be-* \
|
| nds32-* | nds32le-* | nds32be-* \
|
||||||
| nios-* | nios2-* \
|
| nios-* | nios2-* | nios2eb-* | nios2el-* \
|
||||||
| none-* | np1-* | ns16k-* | ns32k-* \
|
| none-* | np1-* | ns16k-* | ns32k-* \
|
||||||
| open8-* \
|
| open8-* \
|
||||||
|
| or1k*-* \
|
||||||
| orion-* \
|
| orion-* \
|
||||||
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
|
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
|
||||||
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
|
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
|
||||||
|
@ -432,6 +441,7 @@ case $basic_machine in
|
||||||
| ubicom32-* \
|
| ubicom32-* \
|
||||||
| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
|
| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
|
||||||
| vax-* \
|
| vax-* \
|
||||||
|
| visium-* \
|
||||||
| we32k-* \
|
| we32k-* \
|
||||||
| x86-* | x86_64-* | xc16x-* | xps100-* \
|
| x86-* | x86_64-* | xc16x-* | xps100-* \
|
||||||
| xstormy16-* | xtensa*-* \
|
| xstormy16-* | xtensa*-* \
|
||||||
|
@ -769,6 +779,9 @@ case $basic_machine in
|
||||||
basic_machine=m68k-isi
|
basic_machine=m68k-isi
|
||||||
os=-sysv
|
os=-sysv
|
||||||
;;
|
;;
|
||||||
|
leon-*|leon[3-9]-*)
|
||||||
|
basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'`
|
||||||
|
;;
|
||||||
m68knommu)
|
m68knommu)
|
||||||
basic_machine=m68k-unknown
|
basic_machine=m68k-unknown
|
||||||
os=-linux
|
os=-linux
|
||||||
|
@ -788,11 +801,15 @@ case $basic_machine in
|
||||||
basic_machine=ns32k-utek
|
basic_machine=ns32k-utek
|
||||||
os=-sysv
|
os=-sysv
|
||||||
;;
|
;;
|
||||||
microblaze)
|
microblaze*)
|
||||||
basic_machine=microblaze-xilinx
|
basic_machine=microblaze-xilinx
|
||||||
;;
|
;;
|
||||||
|
mingw64)
|
||||||
|
basic_machine=x86_64-pc
|
||||||
|
os=-mingw64
|
||||||
|
;;
|
||||||
mingw32)
|
mingw32)
|
||||||
basic_machine=i386-pc
|
basic_machine=i686-pc
|
||||||
os=-mingw32
|
os=-mingw32
|
||||||
;;
|
;;
|
||||||
mingw32ce)
|
mingw32ce)
|
||||||
|
@ -820,6 +837,10 @@ case $basic_machine in
|
||||||
basic_machine=powerpc-unknown
|
basic_machine=powerpc-unknown
|
||||||
os=-morphos
|
os=-morphos
|
||||||
;;
|
;;
|
||||||
|
moxiebox)
|
||||||
|
basic_machine=moxie-unknown
|
||||||
|
os=-moxiebox
|
||||||
|
;;
|
||||||
msdos)
|
msdos)
|
||||||
basic_machine=i386-pc
|
basic_machine=i386-pc
|
||||||
os=-msdos
|
os=-msdos
|
||||||
|
@ -828,7 +849,7 @@ case $basic_machine in
|
||||||
basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
|
basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
|
||||||
;;
|
;;
|
||||||
msys)
|
msys)
|
||||||
basic_machine=i386-pc
|
basic_machine=i686-pc
|
||||||
os=-msys
|
os=-msys
|
||||||
;;
|
;;
|
||||||
mvs)
|
mvs)
|
||||||
|
@ -1019,7 +1040,11 @@ case $basic_machine in
|
||||||
basic_machine=i586-unknown
|
basic_machine=i586-unknown
|
||||||
os=-pw32
|
os=-pw32
|
||||||
;;
|
;;
|
||||||
rdos)
|
rdos | rdos64)
|
||||||
|
basic_machine=x86_64-pc
|
||||||
|
os=-rdos
|
||||||
|
;;
|
||||||
|
rdos32)
|
||||||
basic_machine=i386-pc
|
basic_machine=i386-pc
|
||||||
os=-rdos
|
os=-rdos
|
||||||
;;
|
;;
|
||||||
|
@ -1346,29 +1371,29 @@ case $os in
|
||||||
-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
|
-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
|
||||||
| -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
|
| -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
|
||||||
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
|
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
|
||||||
| -sym* | -kopensolaris* \
|
| -sym* | -kopensolaris* | -plan9* \
|
||||||
| -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
|
| -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
|
||||||
| -aos* | -aros* \
|
| -aos* | -aros* \
|
||||||
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
|
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
|
||||||
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
|
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
|
||||||
| -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
|
| -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
|
||||||
| -openbsd* | -solidbsd* \
|
| -bitrig* | -openbsd* | -solidbsd* \
|
||||||
| -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
|
| -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
|
||||||
| -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
|
| -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
|
||||||
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
|
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
|
||||||
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
|
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
|
||||||
| -chorusos* | -chorusrdb* | -cegcc* \
|
| -chorusos* | -chorusrdb* | -cegcc* \
|
||||||
| -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
|
| -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
|
||||||
| -mingw32* | -linux-gnu* | -linux-android* \
|
| -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
|
||||||
| -linux-newlib* | -linux-uclibc* \
|
| -linux-newlib* | -linux-musl* | -linux-uclibc* \
|
||||||
| -uxpv* | -beos* | -mpeix* | -udk* \
|
| -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
|
||||||
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
|
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
|
||||||
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
|
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
|
||||||
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
|
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
|
||||||
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
|
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
|
||||||
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
|
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
|
||||||
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
|
| -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.
|
# Remember, each alternative MUST END IN *, to match a version number.
|
||||||
;;
|
;;
|
||||||
-qnx*)
|
-qnx*)
|
||||||
|
@ -1492,9 +1517,6 @@ case $os in
|
||||||
-aros*)
|
-aros*)
|
||||||
os=-aros
|
os=-aros
|
||||||
;;
|
;;
|
||||||
-kaos*)
|
|
||||||
os=-kaos
|
|
||||||
;;
|
|
||||||
-zvmoe)
|
-zvmoe)
|
||||||
os=-zvmoe
|
os=-zvmoe
|
||||||
;;
|
;;
|
||||||
|
@ -1543,6 +1565,12 @@ case $basic_machine in
|
||||||
c4x-* | tic4x-*)
|
c4x-* | tic4x-*)
|
||||||
os=-coff
|
os=-coff
|
||||||
;;
|
;;
|
||||||
|
c8051-*)
|
||||||
|
os=-elf
|
||||||
|
;;
|
||||||
|
hexagon-*)
|
||||||
|
os=-elf
|
||||||
|
;;
|
||||||
tic54x-*)
|
tic54x-*)
|
||||||
os=-coff
|
os=-coff
|
||||||
;;
|
;;
|
||||||
|
|
6
contrib/libpcap/config/have_siocglifconf.c
Normal file
6
contrib/libpcap/config/have_siocglifconf.c
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/sockio.h>
|
||||||
|
int main() {
|
||||||
|
ioctl(0, SIOCGLIFCONF, (char *)0);
|
||||||
|
}
|
1614
contrib/libpcap/configure
vendored
1614
contrib/libpcap/configure
vendored
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -186,8 +186,8 @@ pcap_process_pkts(pcap_t *p, pcap_handler callback, u_char *user,
|
||||||
pkthdr.len = origlen;
|
pkthdr.len = origlen;
|
||||||
pkthdr.caplen = caplen;
|
pkthdr.caplen = caplen;
|
||||||
/* Insure caplen does not exceed snapshot */
|
/* Insure caplen does not exceed snapshot */
|
||||||
if (pkthdr.caplen > p->snapshot)
|
if (pkthdr.caplen > (bpf_u_int32)p->snapshot)
|
||||||
pkthdr.caplen = p->snapshot;
|
pkthdr.caplen = (bpf_u_int32)p->snapshot;
|
||||||
(*callback)(user, &pkthdr, pk);
|
(*callback)(user, &pkthdr, pk);
|
||||||
if (++n >= count && !PACKET_COUNT_IS_UNLIMITED(count)) {
|
if (++n >= count && !PACKET_COUNT_IS_UNLIMITED(count)) {
|
||||||
p->cc = ep - bufp;
|
p->cc = ep - bufp;
|
||||||
|
@ -255,8 +255,29 @@ pcap_process_mactype(pcap_t *p, u_int mactype)
|
||||||
break;
|
break;
|
||||||
#endif
|
#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:
|
default:
|
||||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "unknown mactype %u",
|
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "unknown mactype 0x%x",
|
||||||
mactype);
|
mactype);
|
||||||
retv = -1;
|
retv = -1;
|
||||||
}
|
}
|
||||||
|
@ -326,7 +347,7 @@ int
|
||||||
pcap_alloc_databuf(pcap_t *p)
|
pcap_alloc_databuf(pcap_t *p)
|
||||||
{
|
{
|
||||||
p->bufsize = PKTBUFSIZE;
|
p->bufsize = PKTBUFSIZE;
|
||||||
p->buffer = (u_char *)malloc(p->bufsize + p->offset);
|
p->buffer = malloc(p->bufsize + p->offset);
|
||||||
if (p->buffer == NULL) {
|
if (p->buffer == NULL) {
|
||||||
strlcpy(p->errbuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
|
strlcpy(p->errbuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
|
||||||
return (-1);
|
return (-1);
|
||||||
|
@ -362,6 +383,6 @@ strioctl(int fd, int cmd, int len, char *dp)
|
||||||
static void
|
static void
|
||||||
pcap_stream_err(const char *func, int err, char *errbuf)
|
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
|
#endif
|
||||||
|
|
|
@ -23,9 +23,9 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef _WIN32
|
||||||
#include <pcap-stdinc.h>
|
#include <pcap-stdinc.h>
|
||||||
#else /* WIN32 */
|
#else /* _WIN32 */
|
||||||
#if HAVE_INTTYPES_H
|
#if HAVE_INTTYPES_H
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#elif HAVE_STDINT_H
|
#elif HAVE_STDINT_H
|
||||||
|
@ -35,7 +35,7 @@
|
||||||
#include <sys/bitypes.h>
|
#include <sys/bitypes.h>
|
||||||
#endif
|
#endif
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#endif /* WIN32 */
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <memory.h>
|
#include <memory.h>
|
||||||
|
|
|
@ -112,6 +112,9 @@
|
||||||
#ifndef ETHERTYPE_PPPOES
|
#ifndef ETHERTYPE_PPPOES
|
||||||
#define ETHERTYPE_PPPOES 0x8864
|
#define ETHERTYPE_PPPOES 0x8864
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef ETHERTYPE_8021AD
|
||||||
|
#define ETHERTYPE_8021AD 0x88a8
|
||||||
|
#endif
|
||||||
#ifndef ETHERTYPE_LOOPBACK
|
#ifndef ETHERTYPE_LOOPBACK
|
||||||
#define ETHERTYPE_LOOPBACK 0x9000
|
#define ETHERTYPE_LOOPBACK 0x9000
|
||||||
#endif
|
#endif
|
||||||
|
|
221
contrib/libpcap/extract.h
Normal file
221
contrib/libpcap/extract.h
Normal 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)))
|
|
@ -144,7 +144,8 @@ get_sa_len(struct sockaddr *addr)
|
||||||
* could be opened.
|
* could be opened.
|
||||||
*/
|
*/
|
||||||
int
|
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;
|
pcap_if_t *devlist = NULL;
|
||||||
struct ifaddrs *ifap, *ifa;
|
struct ifaddrs *ifap, *ifa;
|
||||||
|
@ -168,11 +169,50 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
|
||||||
* those.
|
* those.
|
||||||
*/
|
*/
|
||||||
if (getifaddrs(&ifap) != 0) {
|
if (getifaddrs(&ifap) != 0) {
|
||||||
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||||
"getifaddrs: %s", pcap_strerror(errno));
|
"getifaddrs: %s", pcap_strerror(errno));
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
|
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
|
* "ifa_addr" was apparently null on at least one
|
||||||
* interface on some system. Therefore, we supply
|
* interface on some system. Therefore, we supply
|
||||||
|
@ -222,40 +262,12 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
|
||||||
dstaddr_size = 0;
|
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.
|
* Add information for this address to the list.
|
||||||
*/
|
*/
|
||||||
if (add_addr_to_iflist(&devlist, ifa->ifa_name,
|
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,
|
broadaddr, broadaddr_size, dstaddr, dstaddr_size,
|
||||||
errbuf) < 0) {
|
errbuf) < 0) {
|
||||||
ret = -1;
|
ret = -1;
|
||||||
|
|
|
@ -132,12 +132,13 @@ struct rtentry; /* declarations in <net/if.h> */
|
||||||
* we already have that.
|
* we already have that.
|
||||||
*/
|
*/
|
||||||
int
|
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;
|
pcap_if_t *devlist = NULL;
|
||||||
register int fd;
|
register int fd;
|
||||||
register struct ifreq *ifrp, *ifend, *ifnext;
|
register struct ifreq *ifrp, *ifend, *ifnext;
|
||||||
int n;
|
size_t n;
|
||||||
struct ifconf ifc;
|
struct ifconf ifc;
|
||||||
char *buf = NULL;
|
char *buf = NULL;
|
||||||
unsigned buf_size;
|
unsigned buf_size;
|
||||||
|
@ -154,7 +155,7 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
|
||||||
*/
|
*/
|
||||||
fd = socket(AF_INET, SOCK_DGRAM, 0);
|
fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||||
"socket: %s", pcap_strerror(errno));
|
"socket: %s", pcap_strerror(errno));
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
@ -170,7 +171,7 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
|
||||||
for (;;) {
|
for (;;) {
|
||||||
buf = malloc(buf_size);
|
buf = malloc(buf_size);
|
||||||
if (buf == NULL) {
|
if (buf == NULL) {
|
||||||
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||||
"malloc: %s", pcap_strerror(errno));
|
"malloc: %s", pcap_strerror(errno));
|
||||||
(void)close(fd);
|
(void)close(fd);
|
||||||
return (-1);
|
return (-1);
|
||||||
|
@ -181,7 +182,7 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
|
||||||
memset(buf, 0, buf_size);
|
memset(buf, 0, buf_size);
|
||||||
if (ioctl(fd, SIOCGIFCONF, (char *)&ifc) < 0
|
if (ioctl(fd, SIOCGIFCONF, (char *)&ifc) < 0
|
||||||
&& errno != EINVAL) {
|
&& errno != EINVAL) {
|
||||||
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||||
"SIOCGIFCONF: %s", pcap_strerror(errno));
|
"SIOCGIFCONF: %s", pcap_strerror(errno));
|
||||||
(void)close(fd);
|
(void)close(fd);
|
||||||
free(buf);
|
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
|
* XXX - The 32-bit compatibility layer for Linux on IA-64
|
||||||
* is slightly broken. It correctly converts the structures
|
* is slightly broken. It correctly converts the structures
|
||||||
* to and from kernel land from 64 bit to 32 bit but
|
* to and from kernel land from 64 bit to 32 bit but
|
||||||
* doesn't update ifc.ifc_len, leaving it larger than the
|
* doesn't update ifc.ifc_len, leaving it larger than the
|
||||||
* amount really used. This means we read off the end
|
* amount really used. This means we read off the end
|
||||||
* of the buffer and encounter an interface with an
|
* of the buffer and encounter an interface with an
|
||||||
* "empty" name. Since this is highly unlikely to ever
|
* "empty" name. Since this is highly unlikely to ever
|
||||||
* occur in a valid case we can just finish looking for
|
* occur in a valid case we can just finish looking for
|
||||||
* interfaces if we see an empty name.
|
* interfaces if we see an empty name.
|
||||||
*/
|
*/
|
||||||
if (!(*ifrp->ifr_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)
|
if (strncmp(ifrp->ifr_name, "dummy", 5) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Can we capture on this device?
|
||||||
|
*/
|
||||||
|
if (!(*check_usable)(ifrp->ifr_name)) {
|
||||||
|
/*
|
||||||
|
* No.
|
||||||
|
*/
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the flags for this interface.
|
* 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 (ioctl(fd, SIOCGIFFLAGS, (char *)&ifrflags) < 0) {
|
||||||
if (errno == ENXIO)
|
if (errno == ENXIO)
|
||||||
continue;
|
continue;
|
||||||
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||||
"SIOCGIFFLAGS: %.*s: %s",
|
"SIOCGIFFLAGS: %.*s: %s",
|
||||||
(int)sizeof(ifrflags.ifr_name),
|
(int)sizeof(ifrflags.ifr_name),
|
||||||
ifrflags.ifr_name,
|
ifrflags.ifr_name,
|
||||||
|
@ -268,7 +279,7 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
|
||||||
netmask = NULL;
|
netmask = NULL;
|
||||||
netmask_size = 0;
|
netmask_size = 0;
|
||||||
} else {
|
} else {
|
||||||
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||||
"SIOCGIFNETMASK: %.*s: %s",
|
"SIOCGIFNETMASK: %.*s: %s",
|
||||||
(int)sizeof(ifrnetmask.ifr_name),
|
(int)sizeof(ifrnetmask.ifr_name),
|
||||||
ifrnetmask.ifr_name,
|
ifrnetmask.ifr_name,
|
||||||
|
@ -299,7 +310,7 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
|
||||||
broadaddr = NULL;
|
broadaddr = NULL;
|
||||||
broadaddr_size = 0;
|
broadaddr_size = 0;
|
||||||
} else {
|
} else {
|
||||||
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||||
"SIOCGIFBRDADDR: %.*s: %s",
|
"SIOCGIFBRDADDR: %.*s: %s",
|
||||||
(int)sizeof(ifrbroadaddr.ifr_name),
|
(int)sizeof(ifrbroadaddr.ifr_name),
|
||||||
ifrbroadaddr.ifr_name,
|
ifrbroadaddr.ifr_name,
|
||||||
|
@ -338,7 +349,7 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
|
||||||
dstaddr = NULL;
|
dstaddr = NULL;
|
||||||
dstaddr_size = 0;
|
dstaddr_size = 0;
|
||||||
} else {
|
} else {
|
||||||
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||||
"SIOCGIFDSTADDR: %.*s: %s",
|
"SIOCGIFDSTADDR: %.*s: %s",
|
||||||
(int)sizeof(ifrdstaddr.ifr_name),
|
(int)sizeof(ifrdstaddr.ifr_name),
|
||||||
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.
|
* Add information for this address to the list.
|
||||||
*/
|
*/
|
||||||
if (add_addr_to_iflist(&devlist, ifrp->ifr_name,
|
if (add_addr_to_iflist(&devlist, ifrp->ifr_name,
|
||||||
ifrflags.ifr_flags, &ifrp->ifr_addr,
|
if_flags_to_pcap_flags(ifrp->ifr_name, ifrflags.ifr_flags),
|
||||||
SA_LEN(&ifrp->ifr_addr), netmask, netmask_size,
|
&ifrp->ifr_addr, SA_LEN(&ifrp->ifr_addr),
|
||||||
broadaddr, broadaddr_size, dstaddr, dstaddr_size,
|
netmask, netmask_size, broadaddr, broadaddr_size,
|
||||||
errbuf) < 0) {
|
dstaddr, dstaddr_size, errbuf) < 0) {
|
||||||
ret = -1;
|
ret = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,7 +75,8 @@ struct rtentry; /* declarations in <net/if.h> */
|
||||||
* SIOCGLIFCONF rather than SIOCGIFCONF in order to get IPv6 addresses.)
|
* SIOCGLIFCONF rather than SIOCGIFCONF in order to get IPv6 addresses.)
|
||||||
*/
|
*/
|
||||||
int
|
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;
|
pcap_if_t *devlist = NULL;
|
||||||
register int fd4, fd6, fd;
|
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);
|
fd4 = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
if (fd4 < 0) {
|
if (fd4 < 0) {
|
||||||
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||||
"socket: %s", pcap_strerror(errno));
|
"socket: %s", pcap_strerror(errno));
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
@ -107,7 +108,7 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
|
||||||
*/
|
*/
|
||||||
fd6 = socket(AF_INET6, SOCK_DGRAM, 0);
|
fd6 = socket(AF_INET6, SOCK_DGRAM, 0);
|
||||||
if (fd6 < 0) {
|
if (fd6 < 0) {
|
||||||
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||||
"socket: %s", pcap_strerror(errno));
|
"socket: %s", pcap_strerror(errno));
|
||||||
(void)close(fd4);
|
(void)close(fd4);
|
||||||
return (-1);
|
return (-1);
|
||||||
|
@ -120,7 +121,7 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
|
||||||
ifn.lifn_flags = 0;
|
ifn.lifn_flags = 0;
|
||||||
ifn.lifn_count = 0;
|
ifn.lifn_count = 0;
|
||||||
if (ioctl(fd4, SIOCGLIFNUM, (char *)&ifn) < 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));
|
"SIOCGLIFNUM: %s", pcap_strerror(errno));
|
||||||
(void)close(fd6);
|
(void)close(fd6);
|
||||||
(void)close(fd4);
|
(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_size = ifn.lifn_count * sizeof (struct lifreq);
|
||||||
buf = malloc(buf_size);
|
buf = malloc(buf_size);
|
||||||
if (buf == NULL) {
|
if (buf == NULL) {
|
||||||
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||||
"malloc: %s", pcap_strerror(errno));
|
"malloc: %s", pcap_strerror(errno));
|
||||||
(void)close(fd6);
|
(void)close(fd6);
|
||||||
(void)close(fd4);
|
(void)close(fd4);
|
||||||
|
@ -149,7 +150,7 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
|
||||||
ifc.lifc_flags = 0;
|
ifc.lifc_flags = 0;
|
||||||
memset(buf, 0, buf_size);
|
memset(buf, 0, buf_size);
|
||||||
if (ioctl(fd4, SIOCGLIFCONF, (char *)&ifc) < 0) {
|
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));
|
"SIOCGLIFCONF: %s", pcap_strerror(errno));
|
||||||
(void)close(fd6);
|
(void)close(fd6);
|
||||||
(void)close(fd4);
|
(void)close(fd4);
|
||||||
|
@ -164,14 +165,6 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
|
||||||
ifend = (struct lifreq *)(buf + ifc.lifc_len);
|
ifend = (struct lifreq *)(buf + ifc.lifc_len);
|
||||||
|
|
||||||
for (; ifrp < ifend; ifrp++) {
|
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".
|
* Skip entries that begin with "dummy".
|
||||||
* XXX - what are these? Is this Linux-specific?
|
* 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)
|
if (strncmp(ifrp->lifr_name, "dummy", 5) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
#ifdef HAVE_SOLARIS
|
|
||||||
/*
|
/*
|
||||||
* Skip entries that have a ":" followed by a number
|
* Can we capture on this device?
|
||||||
* at the end - those are Solaris virtual interfaces
|
|
||||||
* on which you can't capture.
|
|
||||||
*/
|
*/
|
||||||
p = strchr(ifrp->lifr_name, ':');
|
if (!(*check_usable)(ifrp->lifr_name)) {
|
||||||
if (p != NULL) {
|
|
||||||
/*
|
/*
|
||||||
* We have a ":"; is it followed by a number?
|
* No.
|
||||||
*/
|
*/
|
||||||
while (isdigit((unsigned char)*p))
|
continue;
|
||||||
p++;
|
|
||||||
if (*p == '\0') {
|
|
||||||
/*
|
|
||||||
* All digits after the ":" until the end.
|
|
||||||
*/
|
|
||||||
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.
|
* 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 (ioctl(fd, SIOCGLIFFLAGS, (char *)&ifrflags) < 0) {
|
||||||
if (errno == ENXIO)
|
if (errno == ENXIO)
|
||||||
continue;
|
continue;
|
||||||
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||||
"SIOCGLIFFLAGS: %.*s: %s",
|
"SIOCGLIFFLAGS: %.*s: %s",
|
||||||
(int)sizeof(ifrflags.lifr_name),
|
(int)sizeof(ifrflags.lifr_name),
|
||||||
ifrflags.lifr_name,
|
ifrflags.lifr_name,
|
||||||
|
@ -233,7 +222,7 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
|
||||||
*/
|
*/
|
||||||
netmask = NULL;
|
netmask = NULL;
|
||||||
} else {
|
} else {
|
||||||
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||||
"SIOCGLIFNETMASK: %.*s: %s",
|
"SIOCGLIFNETMASK: %.*s: %s",
|
||||||
(int)sizeof(ifrnetmask.lifr_name),
|
(int)sizeof(ifrnetmask.lifr_name),
|
||||||
ifrnetmask.lifr_name,
|
ifrnetmask.lifr_name,
|
||||||
|
@ -261,7 +250,7 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
|
||||||
*/
|
*/
|
||||||
broadaddr = NULL;
|
broadaddr = NULL;
|
||||||
} else {
|
} else {
|
||||||
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||||
"SIOCGLIFBRDADDR: %.*s: %s",
|
"SIOCGLIFBRDADDR: %.*s: %s",
|
||||||
(int)sizeof(ifrbroadaddr.lifr_name),
|
(int)sizeof(ifrbroadaddr.lifr_name),
|
||||||
ifrbroadaddr.lifr_name,
|
ifrbroadaddr.lifr_name,
|
||||||
|
@ -296,7 +285,7 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
|
||||||
*/
|
*/
|
||||||
dstaddr = NULL;
|
dstaddr = NULL;
|
||||||
} else {
|
} else {
|
||||||
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||||
"SIOCGLIFDSTADDR: %.*s: %s",
|
"SIOCGLIFDSTADDR: %.*s: %s",
|
||||||
(int)sizeof(ifrdstaddr.lifr_name),
|
(int)sizeof(ifrdstaddr.lifr_name),
|
||||||
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.
|
* Add information for this address to the list.
|
||||||
*/
|
*/
|
||||||
if (add_addr_to_iflist(&devlist, ifrp->lifr_name,
|
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),
|
sizeof (struct sockaddr_storage),
|
||||||
netmask, sizeof (struct sockaddr_storage),
|
netmask, sizeof (struct sockaddr_storage),
|
||||||
broadaddr, sizeof (struct sockaddr_storage),
|
broadaddr, sizeof (struct sockaddr_storage),
|
||||||
|
|
884
contrib/libpcap/fad-helpers.c
Normal file
884
contrib/libpcap/fad-helpers.c
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
|
||||||
}
|
|
11
contrib/libpcap/gen_version_c.sh
Executable file
11
contrib/libpcap/gen_version_c.sh
Executable 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"
|
||||||
|
|
19
contrib/libpcap/gen_version_header.sh
Executable file
19
contrib/libpcap/gen_version_header.sh
Executable 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
|
@ -161,7 +161,7 @@
|
||||||
#define A_CONNECTACK 44 /* Connect Ack message */
|
#define A_CONNECTACK 44 /* Connect Ack message */
|
||||||
#define A_RELEASE 45 /* Release message */
|
#define A_RELEASE 45 /* Release message */
|
||||||
#define A_RELEASE_DONE 46 /* Release message */
|
#define A_RELEASE_DONE 46 /* Release message */
|
||||||
|
|
||||||
/* ATM field types */
|
/* ATM field types */
|
||||||
#define A_VPI 51
|
#define A_VPI 51
|
||||||
#define A_VCI 52
|
#define A_VCI 52
|
||||||
|
@ -281,83 +281,115 @@ struct qual {
|
||||||
unsigned char pad;
|
unsigned char pad;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct arth *gen_loadi(int);
|
struct _compiler_state;
|
||||||
struct arth *gen_load(int, struct arth *, int);
|
|
||||||
struct arth *gen_loadlen(void);
|
typedef struct _compiler_state compiler_state_t;
|
||||||
struct arth *gen_neg(struct arth *);
|
|
||||||
struct arth *gen_arth(int, struct arth *, struct arth *);
|
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_and(struct block *, struct block *);
|
||||||
void gen_or(struct block *, struct block *);
|
void gen_or(struct block *, struct block *);
|
||||||
void gen_not(struct block *);
|
void gen_not(struct block *);
|
||||||
|
|
||||||
struct block *gen_scode(const char *, struct qual);
|
struct block *gen_scode(compiler_state_t *, const char *, struct qual);
|
||||||
struct block *gen_ecode(const u_char *, struct qual);
|
struct block *gen_ecode(compiler_state_t *, const u_char *, struct qual);
|
||||||
struct block *gen_acode(const u_char *, struct qual);
|
struct block *gen_acode(compiler_state_t *, const u_char *, struct qual);
|
||||||
struct block *gen_mcode(const char *, const char *, int, struct qual);
|
struct block *gen_mcode(compiler_state_t *, const char *, const char *,
|
||||||
|
unsigned int, struct qual);
|
||||||
#ifdef INET6
|
#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
|
#endif
|
||||||
struct block *gen_ncode(const char *, bpf_u_int32, struct qual);
|
struct block *gen_ncode(compiler_state_t *, const char *, bpf_u_int32,
|
||||||
struct block *gen_proto_abbrev(int);
|
struct qual);
|
||||||
struct block *gen_relation(int, struct arth *, struct arth *, int);
|
struct block *gen_proto_abbrev(compiler_state_t *, int);
|
||||||
struct block *gen_less(int);
|
struct block *gen_relation(compiler_state_t *, int, struct arth *,
|
||||||
struct block *gen_greater(int);
|
struct arth *, int);
|
||||||
struct block *gen_byteop(int, int, int);
|
struct block *gen_less(compiler_state_t *, int);
|
||||||
struct block *gen_broadcast(int);
|
struct block *gen_greater(compiler_state_t *, int);
|
||||||
struct block *gen_multicast(int);
|
struct block *gen_byteop(compiler_state_t *, int, int, int);
|
||||||
struct block *gen_inbound(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(compiler_state_t *);
|
||||||
struct block *gen_llc_i(void);
|
struct block *gen_llc_i(compiler_state_t *);
|
||||||
struct block *gen_llc_s(void);
|
struct block *gen_llc_s(compiler_state_t *);
|
||||||
struct block *gen_llc_u(void);
|
struct block *gen_llc_u(compiler_state_t *);
|
||||||
struct block *gen_llc_s_subtype(bpf_u_int32);
|
struct block *gen_llc_s_subtype(compiler_state_t *, bpf_u_int32);
|
||||||
struct block *gen_llc_u_subtype(bpf_u_int32);
|
struct block *gen_llc_u_subtype(compiler_state_t *, bpf_u_int32);
|
||||||
|
|
||||||
struct block *gen_vlan(int);
|
struct block *gen_vlan(compiler_state_t *, int);
|
||||||
struct block *gen_mpls(int);
|
struct block *gen_mpls(compiler_state_t *, int);
|
||||||
|
|
||||||
struct block *gen_pppoed(void);
|
struct block *gen_pppoed(compiler_state_t *);
|
||||||
struct block *gen_pppoes(int);
|
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_geneve(compiler_state_t *, int);
|
||||||
struct block *gen_atmtype_abbrev(int type);
|
|
||||||
struct block *gen_atmmulti_abbrev(int type);
|
|
||||||
|
|
||||||
struct block *gen_mtp2type_abbrev(int type);
|
struct block *gen_atmfield_code(compiler_state_t *, int, bpf_int32,
|
||||||
struct block *gen_mtp3field_code(int mtp3field, bpf_u_int32 jvalue, bpf_u_int32 jtype, int reverse);
|
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_mtp2type_abbrev(compiler_state_t *, int type);
|
||||||
struct block *gen_pf_rnr(int);
|
struct block *gen_mtp3field_code(compiler_state_t *, int, bpf_u_int32,
|
||||||
struct block *gen_pf_srnr(int);
|
bpf_u_int32, 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_p80211_type(int, int);
|
struct block *gen_pf_ifname(compiler_state_t *, const char *);
|
||||||
struct block *gen_p80211_fcdir(int);
|
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 **);
|
struct block *gen_p80211_type(compiler_state_t *, int, int);
|
||||||
void bpf_error(const char *, ...)
|
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))
|
__attribute__((noreturn))
|
||||||
#ifdef __ATTRIBUTE___FORMAT_OK
|
#ifdef __ATTRIBUTE___FORMAT_OK
|
||||||
__attribute__((format (printf, 1, 2)))
|
__attribute__((format (printf, 2, 3)))
|
||||||
#endif /* __ATTRIBUTE___FORMAT_OK */
|
#endif /* __ATTRIBUTE___FORMAT_OK */
|
||||||
;
|
;
|
||||||
|
|
||||||
void finish_parse(struct block *);
|
void finish_parse(compiler_state_t *, struct block *);
|
||||||
char *sdup(const char *);
|
char *sdup(compiler_state_t *, const char *);
|
||||||
|
|
||||||
struct bpf_insn *icode_to_fcode(struct block *, u_int *);
|
struct _opt_state;
|
||||||
int pcap_parse(void);
|
typedef struct _opt_state opt_state_t;
|
||||||
void lex_init(const char *);
|
|
||||||
void lex_cleanup(void);
|
struct bpf_insn *icode_to_fcode(compiler_state_t *, struct icode *,
|
||||||
|
struct block *, u_int *);
|
||||||
void sappend(struct slist *, struct slist *);
|
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 */
|
/* XXX */
|
||||||
#define JT(b) ((b)->et.succ)
|
#define JT(b) ((b)->et.succ)
|
||||||
#define JF(b) ((b)->ef.succ)
|
#define JF(b) ((b)->ef.succ)
|
||||||
|
|
||||||
extern int no_optimize;
|
|
||||||
|
|
|
@ -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
|
* Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
|
||||||
|
@ -26,16 +51,16 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef _WIN32
|
||||||
#include <pcap-stdinc.h>
|
#include <pcap-stdinc.h>
|
||||||
#else /* WIN32 */
|
#else /* _WIN32 */
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#endif /* WIN32 */
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef _WIN32
|
||||||
#if __STDC__
|
#if __STDC__
|
||||||
struct mbuf;
|
struct mbuf;
|
||||||
struct rtentry;
|
struct rtentry;
|
||||||
|
@ -43,13 +68,16 @@ struct rtentry;
|
||||||
|
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#endif /* WIN32 */
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "pcap-int.h"
|
#include "pcap-int.h"
|
||||||
|
|
||||||
#include "gencode.h"
|
#include "gencode.h"
|
||||||
|
#include "grammar.h"
|
||||||
|
#include "scanner.h"
|
||||||
|
|
||||||
#ifdef HAVE_NET_PFVAR_H
|
#ifdef HAVE_NET_PFVAR_H
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
#include <netpfil/pf/pf.h>
|
#include <netpfil/pf/pf.h>
|
||||||
|
@ -170,31 +198,18 @@ str2tok(const char *str, const struct tok *toks)
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int n_errors = 0;
|
|
||||||
|
|
||||||
static struct qual qerr = { Q_UNDEF, Q_UNDEF, Q_UNDEF, Q_UNDEF };
|
static struct qual qerr = { Q_UNDEF, Q_UNDEF, Q_UNDEF, Q_UNDEF };
|
||||||
|
|
||||||
static void
|
static void
|
||||||
yyerror(const char *msg)
|
yyerror(void *yyscanner, compiler_state_t *cstate, const char *msg)
|
||||||
{
|
{
|
||||||
++n_errors;
|
bpf_syntax_error(cstate, msg);
|
||||||
bpf_error("%s", msg);
|
|
||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef NEED_YYPARSE_WRAPPER
|
|
||||||
int yyparse(void);
|
|
||||||
|
|
||||||
int
|
|
||||||
pcap_parse()
|
|
||||||
{
|
|
||||||
return (yyparse());
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_NET_PFVAR_H
|
#ifdef HAVE_NET_PFVAR_H
|
||||||
static int
|
static int
|
||||||
pfreason_to_num(const char *reason)
|
pfreason_to_num(compiler_state_t *cstate, const char *reason)
|
||||||
{
|
{
|
||||||
const char *reasons[] = PFRES_NAMES;
|
const char *reasons[] = PFRES_NAMES;
|
||||||
int i;
|
int i;
|
||||||
|
@ -203,12 +218,12 @@ pfreason_to_num(const char *reason)
|
||||||
if (pcap_strcasecmp(reason, reasons[i]) == 0)
|
if (pcap_strcasecmp(reason, reasons[i]) == 0)
|
||||||
return (i);
|
return (i);
|
||||||
}
|
}
|
||||||
bpf_error("unknown PF reason");
|
bpf_error(cstate, "unknown PF reason");
|
||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pfaction_to_num(const char *action)
|
pfaction_to_num(compiler_state_t *cstate, const char *action)
|
||||||
{
|
{
|
||||||
if (pcap_strcasecmp(action, "pass") == 0 ||
|
if (pcap_strcasecmp(action, "pass") == 0 ||
|
||||||
pcap_strcasecmp(action, "accept") == 0)
|
pcap_strcasecmp(action, "accept") == 0)
|
||||||
|
@ -227,15 +242,15 @@ pfaction_to_num(const char *action)
|
||||||
return (PF_NORDR);
|
return (PF_NORDR);
|
||||||
#endif
|
#endif
|
||||||
else {
|
else {
|
||||||
bpf_error("unknown PF action");
|
bpf_error(cstate, "unknown PF action");
|
||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else /* !HAVE_NET_PFVAR_H */
|
#else /* !HAVE_NET_PFVAR_H */
|
||||||
static int
|
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*/
|
/*NOTREACHED*/
|
||||||
|
|
||||||
/* this is to make the VC compiler happy */
|
/* this is to make the VC compiler happy */
|
||||||
|
@ -243,9 +258,9 @@ pfreason_to_num(const char *reason)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
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*/
|
/*NOTREACHED*/
|
||||||
|
|
||||||
/* this is to make the VC compiler happy */
|
/* this is to make the VC compiler happy */
|
||||||
|
@ -300,8 +315,8 @@ pfaction_to_num(const char *action)
|
||||||
%token LEN
|
%token LEN
|
||||||
%token IPV6 ICMPV6 AH ESP
|
%token IPV6 ICMPV6 AH ESP
|
||||||
%token VLAN MPLS
|
%token VLAN MPLS
|
||||||
%token PPPOED PPPOES
|
%token PPPOED PPPOES GENEVE
|
||||||
%token ISO ESIS CLNP ISIS L1 L2 IIH LSP SNP CSNP PSNP
|
%token ISO ESIS CLNP ISIS L1 L2 IIH LSP SNP CSNP PSNP
|
||||||
%token STP
|
%token STP
|
||||||
%token IPX
|
%token IPX
|
||||||
%token NETBEUI
|
%token NETBEUI
|
||||||
|
@ -311,7 +326,7 @@ pfaction_to_num(const char *action)
|
||||||
%token RADIO
|
%token RADIO
|
||||||
%token FISU LSSU MSU HFISU HLSSU HMSU
|
%token FISU LSSU MSU HFISU HLSSU HMSU
|
||||||
%token SIO OPC DPC SLS HSIO HOPC HDPC HSLS
|
%token SIO OPC DPC SLS HSIO HOPC HDPC HSLS
|
||||||
|
|
||||||
|
|
||||||
%type <s> ID
|
%type <s> ID
|
||||||
%type <e> EID
|
%type <e> EID
|
||||||
|
@ -330,7 +345,7 @@ pfaction_to_num(const char *action)
|
||||||
%%
|
%%
|
||||||
prog: null expr
|
prog: null expr
|
||||||
{
|
{
|
||||||
finish_parse($2.b);
|
finish_parse(cstate, $2.b);
|
||||||
}
|
}
|
||||||
| null
|
| null
|
||||||
;
|
;
|
||||||
|
@ -347,48 +362,48 @@ and: AND { $$ = $<blk>0; }
|
||||||
or: OR { $$ = $<blk>0; }
|
or: OR { $$ = $<blk>0; }
|
||||||
;
|
;
|
||||||
id: nid
|
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); }
|
$$.q = $<blk>0.q); }
|
||||||
| paren pid ')' { $$ = $2; }
|
| paren pid ')' { $$ = $2; }
|
||||||
;
|
;
|
||||||
nid: ID { $$.b = gen_scode($1, $$.q = $<blk>0.q); }
|
nid: ID { $$.b = gen_scode(cstate, $1, $$.q = $<blk>0.q); }
|
||||||
| HID '/' NUM { $$.b = gen_mcode($1, NULL, $3,
|
| HID '/' NUM { $$.b = gen_mcode(cstate, $1, NULL, $3,
|
||||||
$$.q = $<blk>0.q); }
|
$$.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); }
|
$$.q = $<blk>0.q); }
|
||||||
| HID {
|
| HID {
|
||||||
/* Decide how to parse HID based on proto */
|
/* Decide how to parse HID based on proto */
|
||||||
$$.q = $<blk>0.q;
|
$$.q = $<blk>0.q;
|
||||||
if ($$.q.addr == Q_PORT)
|
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)
|
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)
|
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)
|
else if ($$.q.addr == Q_PROTOCHAIN)
|
||||||
bpf_error("'protochain' modifier applied to ip host");
|
bpf_error(cstate, "'protochain' modifier applied to ip host");
|
||||||
$$.b = gen_ncode($1, 0, $$.q);
|
$$.b = gen_ncode(cstate, $1, 0, $$.q);
|
||||||
}
|
}
|
||||||
| HID6 '/' NUM {
|
| HID6 '/' NUM {
|
||||||
#ifdef INET6
|
#ifdef INET6
|
||||||
$$.b = gen_mcode6($1, NULL, $3,
|
$$.b = gen_mcode6(cstate, $1, NULL, $3,
|
||||||
$$.q = $<blk>0.q);
|
$$.q = $<blk>0.q);
|
||||||
#else
|
#else
|
||||||
bpf_error("'ip6addr/prefixlen' not supported "
|
bpf_error(cstate, "'ip6addr/prefixlen' not supported "
|
||||||
"in this configuration");
|
"in this configuration");
|
||||||
#endif /*INET6*/
|
#endif /*INET6*/
|
||||||
}
|
}
|
||||||
| HID6 {
|
| HID6 {
|
||||||
#ifdef INET6
|
#ifdef INET6
|
||||||
$$.b = gen_mcode6($1, 0, 128,
|
$$.b = gen_mcode6(cstate, $1, 0, 128,
|
||||||
$$.q = $<blk>0.q);
|
$$.q = $<blk>0.q);
|
||||||
#else
|
#else
|
||||||
bpf_error("'ip6addr' not supported "
|
bpf_error(cstate, "'ip6addr' not supported "
|
||||||
"in this configuration");
|
"in this configuration");
|
||||||
#endif /*INET6*/
|
#endif /*INET6*/
|
||||||
}
|
}
|
||||||
| EID {
|
| EID {
|
||||||
$$.b = gen_ecode($1, $$.q = $<blk>0.q);
|
$$.b = gen_ecode(cstate, $1, $$.q = $<blk>0.q);
|
||||||
/*
|
/*
|
||||||
* $1 was allocated by "pcap_ether_aton()",
|
* $1 was allocated by "pcap_ether_aton()",
|
||||||
* so we must free it now that we're done
|
* 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);
|
free($1);
|
||||||
}
|
}
|
||||||
| AID {
|
| 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()",
|
* $1 was allocated by "pcap_ether_aton()",
|
||||||
* so we must free it now that we're done
|
* 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 and id { gen_and($1.b, $3.b); $$ = $3; }
|
||||||
| qid or id { gen_or($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); }
|
$$.q = $<blk>0.q); }
|
||||||
| pid
|
| pid
|
||||||
;
|
;
|
||||||
|
@ -431,16 +446,16 @@ head: pqual dqual aqual { QSET($$.q, $1, $2, $3); }
|
||||||
;
|
;
|
||||||
rterm: head id { $$ = $2; }
|
rterm: head id { $$ = $2; }
|
||||||
| paren expr ')' { $$.b = $2.b; $$.q = $1.q; }
|
| paren expr ')' { $$.b = $2.b; $$.q = $1.q; }
|
||||||
| pname { $$.b = gen_proto_abbrev($1); $$.q = qerr; }
|
| pname { $$.b = gen_proto_abbrev(cstate, $1); $$.q = qerr; }
|
||||||
| arth relop arth { $$.b = gen_relation($2, $1, $3, 0);
|
| arth relop arth { $$.b = gen_relation(cstate, $2, $1, $3, 0);
|
||||||
$$.q = qerr; }
|
$$.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; }
|
$$.q = qerr; }
|
||||||
| other { $$.b = $1; $$.q = qerr; }
|
| other { $$.b = $1; $$.q = qerr; }
|
||||||
| atmtype { $$.b = gen_atmtype_abbrev($1); $$.q = qerr; }
|
| atmtype { $$.b = gen_atmtype_abbrev(cstate, $1); $$.q = qerr; }
|
||||||
| atmmultitype { $$.b = gen_atmmulti_abbrev($1); $$.q = qerr; }
|
| atmmultitype { $$.b = gen_atmmulti_abbrev(cstate, $1); $$.q = qerr; }
|
||||||
| atmfield atmvalue { $$.b = $2.b; $$.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; }
|
| mtp3field mtp3value { $$.b = $2.b; $$.q = qerr; }
|
||||||
;
|
;
|
||||||
/* protocol level qualifiers */
|
/* protocol level qualifiers */
|
||||||
|
@ -510,52 +525,54 @@ pname: LINK { $$ = Q_LINK; }
|
||||||
| NETBEUI { $$ = Q_NETBEUI; }
|
| NETBEUI { $$ = Q_NETBEUI; }
|
||||||
| RADIO { $$ = Q_RADIO; }
|
| RADIO { $$ = Q_RADIO; }
|
||||||
;
|
;
|
||||||
other: pqual TK_BROADCAST { $$ = gen_broadcast($1); }
|
other: pqual TK_BROADCAST { $$ = gen_broadcast(cstate, $1); }
|
||||||
| pqual TK_MULTICAST { $$ = gen_multicast($1); }
|
| pqual TK_MULTICAST { $$ = gen_multicast(cstate, $1); }
|
||||||
| LESS NUM { $$ = gen_less($2); }
|
| LESS NUM { $$ = gen_less(cstate, $2); }
|
||||||
| GREATER NUM { $$ = gen_greater($2); }
|
| GREATER NUM { $$ = gen_greater(cstate, $2); }
|
||||||
| CBYTE NUM byteop NUM { $$ = gen_byteop($3, $2, $4); }
|
| CBYTE NUM byteop NUM { $$ = gen_byteop(cstate, $3, $2, $4); }
|
||||||
| INBOUND { $$ = gen_inbound(0); }
|
| INBOUND { $$ = gen_inbound(cstate, 0); }
|
||||||
| OUTBOUND { $$ = gen_inbound(1); }
|
| OUTBOUND { $$ = gen_inbound(cstate, 1); }
|
||||||
| VLAN pnum { $$ = gen_vlan($2); }
|
| VLAN pnum { $$ = gen_vlan(cstate, $2); }
|
||||||
| VLAN { $$ = gen_vlan(-1); }
|
| VLAN { $$ = gen_vlan(cstate, -1); }
|
||||||
| MPLS pnum { $$ = gen_mpls($2); }
|
| MPLS pnum { $$ = gen_mpls(cstate, $2); }
|
||||||
| MPLS { $$ = gen_mpls(-1); }
|
| MPLS { $$ = gen_mpls(cstate, -1); }
|
||||||
| PPPOED { $$ = gen_pppoed(); }
|
| PPPOED { $$ = gen_pppoed(cstate); }
|
||||||
| PPPOES pnum { $$ = gen_pppoes($2); }
|
| PPPOES pnum { $$ = gen_pppoes(cstate, $2); }
|
||||||
| PPPOES { $$ = gen_pppoes(-1); }
|
| PPPOES { $$ = gen_pppoes(cstate, -1); }
|
||||||
|
| GENEVE pnum { $$ = gen_geneve(cstate, $2); }
|
||||||
|
| GENEVE { $$ = gen_geneve(cstate, -1); }
|
||||||
| pfvar { $$ = $1; }
|
| pfvar { $$ = $1; }
|
||||||
| pqual p80211 { $$ = $2; }
|
| pqual p80211 { $$ = $2; }
|
||||||
| pllc { $$ = $1; }
|
| pllc { $$ = $1; }
|
||||||
;
|
;
|
||||||
|
|
||||||
pfvar: PF_IFNAME ID { $$ = gen_pf_ifname($2); }
|
pfvar: PF_IFNAME ID { $$ = gen_pf_ifname(cstate, $2); }
|
||||||
| PF_RSET ID { $$ = gen_pf_ruleset($2); }
|
| PF_RSET ID { $$ = gen_pf_ruleset(cstate, $2); }
|
||||||
| PF_RNR NUM { $$ = gen_pf_rnr($2); }
|
| PF_RNR NUM { $$ = gen_pf_rnr(cstate, $2); }
|
||||||
| PF_SRNR NUM { $$ = gen_pf_srnr($2); }
|
| PF_SRNR NUM { $$ = gen_pf_srnr(cstate, $2); }
|
||||||
| PF_REASON reason { $$ = gen_pf_reason($2); }
|
| PF_REASON reason { $$ = gen_pf_reason(cstate, $2); }
|
||||||
| PF_ACTION action { $$ = gen_pf_action($2); }
|
| PF_ACTION action { $$ = gen_pf_action(cstate, $2); }
|
||||||
;
|
;
|
||||||
|
|
||||||
p80211: TYPE type SUBTYPE subtype
|
p80211: TYPE type SUBTYPE subtype
|
||||||
{ $$ = gen_p80211_type($2 | $4,
|
{ $$ = gen_p80211_type(cstate, $2 | $4,
|
||||||
IEEE80211_FC0_TYPE_MASK |
|
IEEE80211_FC0_TYPE_MASK |
|
||||||
IEEE80211_FC0_SUBTYPE_MASK);
|
IEEE80211_FC0_SUBTYPE_MASK);
|
||||||
}
|
}
|
||||||
| TYPE type { $$ = gen_p80211_type($2,
|
| TYPE type { $$ = gen_p80211_type(cstate, $2,
|
||||||
IEEE80211_FC0_TYPE_MASK);
|
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_TYPE_MASK |
|
||||||
IEEE80211_FC0_SUBTYPE_MASK);
|
IEEE80211_FC0_SUBTYPE_MASK);
|
||||||
}
|
}
|
||||||
| DIR dir { $$ = gen_p80211_fcdir($2); }
|
| DIR dir { $$ = gen_p80211_fcdir(cstate, $2); }
|
||||||
;
|
;
|
||||||
|
|
||||||
type: NUM
|
type: NUM
|
||||||
| ID { $$ = str2tok($1, ieee80211_types);
|
| ID { $$ = str2tok($1, ieee80211_types);
|
||||||
if ($$ == -1)
|
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++) {
|
for (i = 0;; i++) {
|
||||||
if (ieee80211_type_subtypes[i].tok == NULL) {
|
if (ieee80211_type_subtypes[i].tok == NULL) {
|
||||||
/* Ran out of types */
|
/* Ran out of types */
|
||||||
bpf_error("unknown 802.11 type");
|
bpf_error(cstate, "unknown 802.11 type");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ($<i>-1 == ieee80211_type_subtypes[i].type) {
|
if ($<i>-1 == ieee80211_type_subtypes[i].type) {
|
||||||
|
@ -576,7 +593,7 @@ subtype: NUM
|
||||||
|
|
||||||
$$ = str2tok($1, types);
|
$$ = str2tok($1, types);
|
||||||
if ($$ == -1)
|
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++) {
|
for (i = 0;; i++) {
|
||||||
if (ieee80211_type_subtypes[i].tok == NULL) {
|
if (ieee80211_type_subtypes[i].tok == NULL) {
|
||||||
/* Ran out of types */
|
/* Ran out of types */
|
||||||
bpf_error("unknown 802.11 type name");
|
bpf_error(cstate, "unknown 802.11 type name");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
$$ = str2tok($1, ieee80211_type_subtypes[i].tok);
|
$$ = 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)
|
| LLC ID { if (pcap_strcasecmp($2, "i") == 0)
|
||||||
$$ = gen_llc_i();
|
$$ = gen_llc_i(cstate);
|
||||||
else if (pcap_strcasecmp($2, "s") == 0)
|
else if (pcap_strcasecmp($2, "s") == 0)
|
||||||
$$ = gen_llc_s();
|
$$ = gen_llc_s(cstate);
|
||||||
else if (pcap_strcasecmp($2, "u") == 0)
|
else if (pcap_strcasecmp($2, "u") == 0)
|
||||||
$$ = gen_llc_u();
|
$$ = gen_llc_u(cstate);
|
||||||
else {
|
else {
|
||||||
u_int subtype;
|
int subtype;
|
||||||
|
|
||||||
subtype = str2tok($2, llc_s_subtypes);
|
subtype = str2tok($2, llc_s_subtypes);
|
||||||
if (subtype != -1)
|
if (subtype != -1)
|
||||||
$$ = gen_llc_s_subtype(subtype);
|
$$ = gen_llc_s_subtype(cstate, subtype);
|
||||||
else {
|
else {
|
||||||
subtype = str2tok($2, llc_u_subtypes);
|
subtype = str2tok($2, llc_u_subtypes);
|
||||||
if (subtype == -1)
|
if (subtype == -1)
|
||||||
bpf_error("unknown LLC type name \"%s\"", $2);
|
bpf_error(cstate, "unknown LLC type name \"%s\"", $2);
|
||||||
$$ = gen_llc_u_subtype(subtype);
|
$$ = gen_llc_u_subtype(cstate, subtype);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* sigh, "rnr" is already a keyword for PF */
|
/* 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
|
dir: NUM
|
||||||
|
@ -631,15 +648,15 @@ dir: NUM
|
||||||
else if (pcap_strcasecmp($1, "dstods") == 0)
|
else if (pcap_strcasecmp($1, "dstods") == 0)
|
||||||
$$ = IEEE80211_FC1_DIR_DSTODS;
|
$$ = IEEE80211_FC1_DIR_DSTODS;
|
||||||
else
|
else
|
||||||
bpf_error("unknown 802.11 direction");
|
bpf_error(cstate, "unknown 802.11 direction");
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
reason: NUM { $$ = $1; }
|
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; }
|
relop: '>' { $$ = BPF_JGT; }
|
||||||
|
@ -650,24 +667,24 @@ irelop: LEQ { $$ = BPF_JGT; }
|
||||||
| '<' { $$ = BPF_JGE; }
|
| '<' { $$ = BPF_JGE; }
|
||||||
| NEQ { $$ = BPF_JEQ; }
|
| NEQ { $$ = BPF_JEQ; }
|
||||||
;
|
;
|
||||||
arth: pnum { $$ = gen_loadi($1); }
|
arth: pnum { $$ = gen_loadi(cstate, $1); }
|
||||||
| narth
|
| narth
|
||||||
;
|
;
|
||||||
narth: pname '[' arth ']' { $$ = gen_load($1, $3, 1); }
|
narth: pname '[' arth ']' { $$ = gen_load(cstate, $1, $3, 1); }
|
||||||
| pname '[' arth ':' NUM ']' { $$ = gen_load($1, $3, $5); }
|
| pname '[' arth ':' NUM ']' { $$ = gen_load(cstate, $1, $3, $5); }
|
||||||
| arth '+' arth { $$ = gen_arth(BPF_ADD, $1, $3); }
|
| arth '+' arth { $$ = gen_arth(cstate, BPF_ADD, $1, $3); }
|
||||||
| arth '-' arth { $$ = gen_arth(BPF_SUB, $1, $3); }
|
| arth '-' arth { $$ = gen_arth(cstate, BPF_SUB, $1, $3); }
|
||||||
| arth '*' arth { $$ = gen_arth(BPF_MUL, $1, $3); }
|
| arth '*' arth { $$ = gen_arth(cstate, BPF_MUL, $1, $3); }
|
||||||
| arth '/' arth { $$ = gen_arth(BPF_DIV, $1, $3); }
|
| arth '/' arth { $$ = gen_arth(cstate, BPF_DIV, $1, $3); }
|
||||||
| arth '%' arth { $$ = gen_arth(BPF_MOD, $1, $3); }
|
| arth '%' arth { $$ = gen_arth(cstate, BPF_MOD, $1, $3); }
|
||||||
| arth '&' arth { $$ = gen_arth(BPF_AND, $1, $3); }
|
| arth '&' arth { $$ = gen_arth(cstate, BPF_AND, $1, $3); }
|
||||||
| arth '|' arth { $$ = gen_arth(BPF_OR, $1, $3); }
|
| arth '|' arth { $$ = gen_arth(cstate, BPF_OR, $1, $3); }
|
||||||
| arth '^' arth { $$ = gen_arth(BPF_XOR, $1, $3); }
|
| arth '^' arth { $$ = gen_arth(cstate, BPF_XOR, $1, $3); }
|
||||||
| arth LSH arth { $$ = gen_arth(BPF_LSH, $1, $3); }
|
| arth LSH arth { $$ = gen_arth(cstate, BPF_LSH, $1, $3); }
|
||||||
| arth RSH arth { $$ = gen_arth(BPF_RSH, $1, $3); }
|
| arth RSH arth { $$ = gen_arth(cstate, BPF_RSH, $1, $3); }
|
||||||
| '-' arth %prec UMINUS { $$ = gen_neg($2); }
|
| '-' arth %prec UMINUS { $$ = gen_neg(cstate, $2); }
|
||||||
| paren narth ')' { $$ = $2; }
|
| paren narth ')' { $$ = $2; }
|
||||||
| LEN { $$ = gen_loadlen(); }
|
| LEN { $$ = gen_loadlen(cstate); }
|
||||||
;
|
;
|
||||||
byteop: '&' { $$ = '&'; }
|
byteop: '&' { $$ = '&'; }
|
||||||
| '|' { $$ = '|'; }
|
| '|' { $$ = '|'; }
|
||||||
|
@ -696,15 +713,15 @@ atmfield: VPI { $$.atmfieldtype = A_VPI; }
|
||||||
| VCI { $$.atmfieldtype = A_VCI; }
|
| VCI { $$.atmfieldtype = A_VCI; }
|
||||||
;
|
;
|
||||||
atmvalue: atmfieldvalue
|
atmvalue: atmfieldvalue
|
||||||
| relop NUM { $$.b = gen_atmfield_code($<blk>0.atmfieldtype, (bpf_int32)$2, (bpf_u_int32)$1, 0); }
|
| relop NUM { $$.b = gen_atmfield_code(cstate, $<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); }
|
| 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; }
|
| paren atmlistvalue ')' { $$.b = $2.b; $$.q = qerr; }
|
||||||
;
|
;
|
||||||
atmfieldvalue: NUM {
|
atmfieldvalue: NUM {
|
||||||
$$.atmfieldtype = $<blk>0.atmfieldtype;
|
$$.atmfieldtype = $<blk>0.atmfieldtype;
|
||||||
if ($$.atmfieldtype == A_VPI ||
|
if ($$.atmfieldtype == A_VPI ||
|
||||||
$$.atmfieldtype == A_VCI)
|
$$.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
|
atmlistvalue: atmfieldvalue
|
||||||
|
@ -729,8 +746,8 @@ mtp3field: SIO { $$.mtp3fieldtype = M_SIO; }
|
||||||
| HSLS { $$.mtp3fieldtype = MH_SLS; }
|
| HSLS { $$.mtp3fieldtype = MH_SLS; }
|
||||||
;
|
;
|
||||||
mtp3value: mtp3fieldvalue
|
mtp3value: mtp3fieldvalue
|
||||||
| relop NUM { $$.b = gen_mtp3field_code($<blk>0.mtp3fieldtype, (u_int)$2, (u_int)$1, 0); }
|
| relop NUM { $$.b = gen_mtp3field_code(cstate, $<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); }
|
| irelop NUM { $$.b = gen_mtp3field_code(cstate, $<blk>0.mtp3fieldtype, (u_int)$2, (u_int)$1, 1); }
|
||||||
| paren mtp3listvalue ')' { $$.b = $2.b; $$.q = qerr; }
|
| paren mtp3listvalue ')' { $$.b = $2.b; $$.q = qerr; }
|
||||||
;
|
;
|
||||||
mtp3fieldvalue: NUM {
|
mtp3fieldvalue: NUM {
|
||||||
|
@ -743,7 +760,7 @@ mtp3fieldvalue: NUM {
|
||||||
$$.mtp3fieldtype == MH_OPC ||
|
$$.mtp3fieldtype == MH_OPC ||
|
||||||
$$.mtp3fieldtype == MH_DPC ||
|
$$.mtp3fieldtype == MH_DPC ||
|
||||||
$$.mtp3fieldtype == MH_SLS)
|
$$.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
|
mtp3listvalue: mtp3fieldvalue
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -115,7 +115,7 @@ fi
|
||||||
if [ x"$dir_arg" != x ]; then
|
if [ x"$dir_arg" != x ]; then
|
||||||
dst=$src
|
dst=$src
|
||||||
src=""
|
src=""
|
||||||
|
|
||||||
if [ -d $dst ]; then
|
if [ -d $dst ]; then
|
||||||
instcmd=:
|
instcmd=:
|
||||||
else
|
else
|
||||||
|
@ -124,7 +124,7 @@ if [ x"$dir_arg" != x ]; then
|
||||||
else
|
else
|
||||||
|
|
||||||
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
|
# 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 $src (and thus $dsttmp) contains '*'.
|
||||||
|
|
||||||
if [ -f $src -o -d $src ]
|
if [ -f $src -o -d $src ]
|
||||||
|
@ -134,7 +134,7 @@ else
|
||||||
echo "install: $src does not exist"
|
echo "install: $src does not exist"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ x"$dst" = x ]
|
if [ x"$dst" = x ]
|
||||||
then
|
then
|
||||||
echo "install: no destination specified"
|
echo "install: no destination specified"
|
||||||
|
@ -201,17 +201,17 @@ else
|
||||||
|
|
||||||
# If we're going to rename the final executable, determine the name now.
|
# If we're going to rename the final executable, determine the name now.
|
||||||
|
|
||||||
if [ x"$transformarg" = x ]
|
if [ x"$transformarg" = x ]
|
||||||
then
|
then
|
||||||
dstfile=`basename $dst`
|
dstfile=`basename $dst`
|
||||||
else
|
else
|
||||||
dstfile=`basename $dst $transformbasename |
|
dstfile=`basename $dst $transformbasename |
|
||||||
sed $transformarg`$transformbasename
|
sed $transformarg`$transformbasename
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# don't allow the sed command to completely eliminate the filename
|
# don't allow the sed command to completely eliminate the filename
|
||||||
|
|
||||||
if [ x"$dstfile" = x ]
|
if [ x"$dstfile" = x ]
|
||||||
then
|
then
|
||||||
dstfile=`basename $dst`
|
dstfile=`basename $dst`
|
||||||
else
|
else
|
||||||
|
@ -242,7 +242,7 @@ else
|
||||||
# Now rename the file to the real destination.
|
# Now rename the file to the real destination.
|
||||||
|
|
||||||
$doit $rmcmd -f $dstdir/$dstfile &&
|
$doit $rmcmd -f $dstdir/$dstfile &&
|
||||||
$doit $mvcmd $dsttmp $dstdir/$dstfile
|
$doit $mvcmd $dsttmp $dstdir/$dstfile
|
||||||
|
|
||||||
fi &&
|
fi &&
|
||||||
|
|
||||||
|
|
23
contrib/libpcap/lbl/os-aix7.h
Normal file
23
contrib/libpcap/lbl/os-aix7.h
Normal 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);
|
|
@ -20,7 +20,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Prototypes missing in Digital UNIX 4.x */
|
/* Prototypes missing in Digital UNIX 4.x */
|
||||||
int snprintf(char *, size_t, const char *, ...);
|
int pcap_snprintf(char *, size_t, const char *, ...);
|
||||||
int vsnprintf(char *, size_t, const char *, va_list);
|
int pcap_vsnprintf(char *, size_t, const char *, va_list);
|
||||||
int pfopen(char *, int);
|
int pfopen(char *, int);
|
||||||
|
|
||||||
|
|
|
@ -21,10 +21,10 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Prototypes missing in Tru64 UNIX 5.x
|
* 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>.
|
* #define the right value to get them defined by <stdio.h>.
|
||||||
*/
|
*/
|
||||||
int snprintf(char *, size_t, const char *, ...);
|
int pcap_snprintf(char *, size_t, const char *, ...);
|
||||||
int vsnprintf(char *, size_t, const char *, va_list);
|
int pcap_vsnprintf(char *, size_t, const char *, va_list);
|
||||||
int pfopen(char *, int);
|
int pfopen(char *, int);
|
||||||
|
|
||||||
|
|
|
@ -21,4 +21,4 @@
|
||||||
|
|
||||||
/* Prototypes missing in SunOS 5 */
|
/* Prototypes missing in SunOS 5 */
|
||||||
char *strerror(int);
|
char *strerror(int);
|
||||||
int snprintf(char *, size_t, const char *, ...);
|
int pcap_snprintf(char *, size_t, const char *, ...);
|
||||||
|
|
|
@ -65,7 +65,6 @@ int fchmod(int, int);
|
||||||
int fchown(int, int, int);
|
int fchown(int, int, int);
|
||||||
void endgrent(void);
|
void endgrent(void);
|
||||||
void endpwent(void);
|
void endpwent(void);
|
||||||
void endservent(void);
|
|
||||||
#ifdef __STDC__
|
#ifdef __STDC__
|
||||||
struct ether_addr;
|
struct ether_addr;
|
||||||
#endif
|
#endif
|
||||||
|
@ -146,7 +145,6 @@ int select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
|
||||||
int setpgrp(int, int);
|
int setpgrp(int, int);
|
||||||
void setpwent(void);
|
void setpwent(void);
|
||||||
int setrlimit(int, struct rlimit *);
|
int setrlimit(int, struct rlimit *);
|
||||||
void setservent(int);
|
|
||||||
int setsockopt(int, int, int, char *, int);
|
int setsockopt(int, int, int, char *, int);
|
||||||
int shutdown(int, int);
|
int shutdown(int, int);
|
||||||
int sigblock(int);
|
int sigblock(int);
|
||||||
|
@ -157,7 +155,7 @@ int sigsetmask(int);
|
||||||
struct sigvec;
|
struct sigvec;
|
||||||
#endif
|
#endif
|
||||||
int sigvec(int, struct sigvec *, struct sigvec*);
|
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 socket(int, int, int);
|
||||||
int socketpair(int, int, int, int *);
|
int socketpair(int, int, int, int *);
|
||||||
int symlink(const char *, const char *);
|
int symlink(const char *, const char *);
|
||||||
|
|
|
@ -23,7 +23,6 @@
|
||||||
int bcmp(const char *, const char *, u_int);
|
int bcmp(const char *, const char *, u_int);
|
||||||
void bcopy(const void *, void *, u_int);
|
void bcopy(const void *, void *, u_int);
|
||||||
void bzero(void *, u_int);
|
void bzero(void *, u_int);
|
||||||
void endservent(void);
|
|
||||||
int getopt(int, char * const *, const char *);
|
int getopt(int, char * const *, const char *);
|
||||||
#ifdef __STDC__
|
#ifdef __STDC__
|
||||||
struct timeval;
|
struct timeval;
|
||||||
|
|
126
contrib/libpcap/missing/getopt.c
Normal file
126
contrib/libpcap/missing/getopt.c
Normal 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 */
|
||||||
|
}
|
7
contrib/libpcap/missing/getopt.h
Normal file
7
contrib/libpcap/missing/getopt.h
Normal 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);
|
|
@ -456,13 +456,13 @@ xyzprintf (struct state *state, const char *char_format, va_list ap)
|
||||||
|
|
||||||
#ifndef HAVE_SNPRINTF
|
#ifndef HAVE_SNPRINTF
|
||||||
int
|
int
|
||||||
snprintf (char *str, size_t sz, const char *format, ...)
|
pcap_snprintf (char *str, size_t sz, const char *format, ...)
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
ret = vsnprintf (str, sz, format, args);
|
ret = pcap_vsnprintf (str, sz, format, args);
|
||||||
|
|
||||||
#ifdef PARANOIA
|
#ifdef PARANOIA
|
||||||
{
|
{
|
||||||
|
@ -473,7 +473,7 @@ snprintf (char *str, size_t sz, const char *format, ...)
|
||||||
if (tmp == NULL)
|
if (tmp == NULL)
|
||||||
abort ();
|
abort ();
|
||||||
|
|
||||||
ret2 = vsprintf (tmp, format, args);
|
ret2 = pcap_vsprintf (tmp, format, args);
|
||||||
if (ret != ret2 || strcmp(str, tmp))
|
if (ret != ret2 || strcmp(str, tmp))
|
||||||
abort ();
|
abort ();
|
||||||
free (tmp);
|
free (tmp);
|
||||||
|
@ -518,13 +518,13 @@ asprintf (char **ret, const char *format, ...)
|
||||||
|
|
||||||
#ifndef HAVE_ASNPRINTF
|
#ifndef HAVE_ASNPRINTF
|
||||||
int
|
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;
|
va_list args;
|
||||||
int val;
|
int val;
|
||||||
|
|
||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
val = vasnprintf (ret, max_sz, format, args);
|
val = pcap_vasnprintf (ret, max_sz, format, args);
|
||||||
|
|
||||||
#ifdef PARANOIA
|
#ifdef PARANOIA
|
||||||
{
|
{
|
||||||
|
@ -534,7 +534,7 @@ asnprintf (char **ret, size_t max_sz, const char *format, ...)
|
||||||
if (tmp == NULL)
|
if (tmp == NULL)
|
||||||
abort ();
|
abort ();
|
||||||
|
|
||||||
ret2 = vsprintf (tmp, format, args);
|
ret2 = pcap_vsprintf (tmp, format, args);
|
||||||
if (val != ret2 || strcmp(*ret, tmp))
|
if (val != ret2 || strcmp(*ret, tmp))
|
||||||
abort ();
|
abort ();
|
||||||
free (tmp);
|
free (tmp);
|
||||||
|
@ -548,16 +548,16 @@ asnprintf (char **ret, size_t max_sz, const char *format, ...)
|
||||||
|
|
||||||
#ifndef HAVE_VASPRINTF
|
#ifndef HAVE_VASPRINTF
|
||||||
int
|
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
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifndef HAVE_VASNPRINTF
|
#ifndef HAVE_VASNPRINTF
|
||||||
int
|
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;
|
int st;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
@ -600,7 +600,7 @@ vasnprintf (char **ret, size_t max_sz, const char *format, va_list args)
|
||||||
|
|
||||||
#ifndef HAVE_VSNPRINTF
|
#ifndef HAVE_VSNPRINTF
|
||||||
int
|
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;
|
struct state state;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
87
contrib/libpcap/missing/strtok_r.c
Normal file
87
contrib/libpcap/missing/strtok_r.c
Normal 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 */
|
||||||
|
}
|
31
contrib/libpcap/missing/win_snprintf.c
Normal file
31
contrib/libpcap/missing/win_snprintf.c
Normal 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);
|
||||||
|
}
|
|
@ -13,9 +13,6 @@
|
||||||
# @(#)mkdep.sh 5.11 (Berkeley) 5/5/88
|
# @(#)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"
|
MAKE=Makefile # default makefile name is "Makefile"
|
||||||
CC=cc # default C compiler is "cc"
|
CC=cc # default C compiler is "cc"
|
||||||
DEPENDENCY_CFLAG=-M # default dependency-generation flag is -M
|
DEPENDENCY_CFLAG=-M # default dependency-generation flag is -M
|
||||||
|
|
|
@ -33,10 +33,36 @@
|
||||||
#include <netdnet/dnetdb.h>
|
#include <netdnet/dnetdb.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef _WIN32
|
||||||
#include <pcap-stdinc.h>
|
#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/param.h>
|
||||||
#include <sys/types.h> /* concession to AIX */
|
#include <sys/types.h> /* concession to AIX */
|
||||||
|
@ -44,9 +70,9 @@
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#endif /* WIN32 */
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef _WIN32
|
||||||
#ifdef HAVE_ETHER_HOSTTON
|
#ifdef HAVE_ETHER_HOSTTON
|
||||||
/*
|
/*
|
||||||
* XXX - do we need any of this if <netinet/if_ether.h> doesn't declare
|
* 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 */
|
#endif /* HAVE_ETHER_HOSTTON */
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#endif /* WIN32 */
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
@ -76,6 +102,7 @@ struct rtentry; /* declarations in <net/if.h> */
|
||||||
|
|
||||||
#include "gencode.h"
|
#include "gencode.h"
|
||||||
#include <pcap/namedb.h>
|
#include <pcap/namedb.h>
|
||||||
|
#include "nametoaddr.h"
|
||||||
|
|
||||||
#ifdef HAVE_OS_PROTO_H
|
#ifdef HAVE_OS_PROTO_H
|
||||||
#include "os-proto.h"
|
#include "os-proto.h"
|
||||||
|
@ -142,7 +169,7 @@ pcap_nametoaddrinfo(const char *name)
|
||||||
bpf_u_int32
|
bpf_u_int32
|
||||||
pcap_nametonetaddr(const char *name)
|
pcap_nametonetaddr(const char *name)
|
||||||
{
|
{
|
||||||
#ifndef WIN32
|
#ifndef _WIN32
|
||||||
struct netent *np;
|
struct netent *np;
|
||||||
|
|
||||||
if ((np = getnetbyname(name)) != NULL)
|
if ((np = getnetbyname(name)) != NULL)
|
||||||
|
@ -152,6 +179,15 @@ pcap_nametonetaddr(const char *name)
|
||||||
#else
|
#else
|
||||||
/*
|
/*
|
||||||
* There's no "getnetbyname()" on Windows.
|
* 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;
|
return 0;
|
||||||
#endif
|
#endif
|
||||||
|
@ -276,8 +312,14 @@ struct eproto {
|
||||||
u_short p;
|
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
|
#if 0
|
||||||
/* The FreeBSD elf linker generates a request to copy this array
|
/* The FreeBSD elf linker generates a request to copy this array
|
||||||
* (including its size) when you link with -lpcap. In order to
|
* (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;
|
u_int node, area;
|
||||||
|
|
||||||
if (sscanf(s, "%d.%d", &area, &node) != 2)
|
if (sscanf(s, "%d.%d", &area, &node) != 2)
|
||||||
bpf_error("malformed decnet address '%s'", s);
|
return(0);
|
||||||
|
|
||||||
*addr = (area << AREASHIFT) & AREAMASK;
|
*addr = (area << AREASHIFT) & AREAMASK;
|
||||||
*addr |= (node & NODEMASK);
|
*addr |= (node & NODEMASK);
|
||||||
|
@ -498,23 +540,20 @@ pcap_ether_hostton(const char *name)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
u_short
|
int
|
||||||
__pcap_nametodnaddr(const char *name)
|
__pcap_nametodnaddr(const char *name, u_short *res)
|
||||||
{
|
{
|
||||||
#ifdef DECNETLIB
|
#ifdef DECNETLIB
|
||||||
struct nodeent *getnodebyname();
|
struct nodeent *getnodebyname();
|
||||||
struct nodeent *nep;
|
struct nodeent *nep;
|
||||||
unsigned short res;
|
|
||||||
|
|
||||||
nep = getnodebyname(name);
|
nep = getnodebyname(name);
|
||||||
if (nep == ((struct nodeent *)0))
|
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));
|
memcpy((char *)res, (char *)nep->n_addr, sizeof(unsigned short));
|
||||||
return(res);
|
return(1);
|
||||||
#else
|
#else
|
||||||
bpf_error("decnet name support not included, '%s' cannot be translated\n",
|
|
||||||
name);
|
|
||||||
return(0);
|
return(0);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
48
contrib/libpcap/nametoaddr.h
Normal file
48
contrib/libpcap/nametoaddr.h
Normal 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
|
@ -4,7 +4,7 @@
|
||||||
*
|
*
|
||||||
* This code is derived from the Stanford/CMU enet packet filter,
|
* This code is derived from the Stanford/CMU enet packet filter,
|
||||||
* (net/enet.c) distributed as part of 4.3BSD, and code contributed
|
* (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.
|
* Berkeley Laboratory.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
|
|
@ -11,8 +11,8 @@
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
* 3. The name of the author may not be used to endorse or promote
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
* products derived from this software without specific prior written
|
* products derived from this software without specific prior written
|
||||||
* permission.
|
* permission.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
@ -31,7 +31,7 @@
|
||||||
* By Paolo Abeni <paolo.abeni@email.it>
|
* By Paolo Abeni <paolo.abeni@email.it>
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
@ -73,7 +73,7 @@ struct pcap_bt {
|
||||||
int dev_id; /* device ID of device we're bound to */
|
int dev_id; /* device ID of device we're bound to */
|
||||||
};
|
};
|
||||||
|
|
||||||
int
|
int
|
||||||
bt_findalldevs(pcap_if_t **alldevsp, char *err_str)
|
bt_findalldevs(pcap_if_t **alldevsp, char *err_str)
|
||||||
{
|
{
|
||||||
struct hci_dev_list_req *dev_list;
|
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);
|
sock = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
|
||||||
if (sock < 0)
|
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)
|
if (errno == EAFNOSUPPORT)
|
||||||
return 0;
|
return 0;
|
||||||
snprintf(err_str, PCAP_ERRBUF_SIZE,
|
pcap_snprintf(err_str, PCAP_ERRBUF_SIZE,
|
||||||
"Can't open raw Bluetooth socket: %s", strerror(errno));
|
"Can't open raw Bluetooth socket: %s", strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
dev_list = malloc(HCI_MAX_DEV * sizeof(*dev_req) + sizeof(*dev_list));
|
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));
|
HCI_MAX_DEV * sizeof(*dev_req) + sizeof(*dev_list));
|
||||||
ret = -1;
|
ret = -1;
|
||||||
goto done;
|
goto done;
|
||||||
|
@ -103,9 +103,9 @@ bt_findalldevs(pcap_if_t **alldevsp, char *err_str)
|
||||||
|
|
||||||
dev_list->dev_num = HCI_MAX_DEV;
|
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",
|
"Can't get Bluetooth device list via ioctl: %s",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
ret = -1;
|
ret = -1;
|
||||||
|
@ -115,11 +115,11 @@ bt_findalldevs(pcap_if_t **alldevsp, char *err_str)
|
||||||
dev_req = dev_list->dev_req;
|
dev_req = dev_list->dev_req;
|
||||||
for (i = 0; i < dev_list->dev_num; i++, dev_req++) {
|
for (i = 0; i < dev_list->dev_num; i++, dev_req++) {
|
||||||
char dev_name[20], dev_descr[30];
|
char dev_name[20], dev_descr[30];
|
||||||
|
|
||||||
snprintf(dev_name, 20, BT_IFACE"%d", dev_req->dev_id);
|
pcap_snprintf(dev_name, 20, BT_IFACE"%d", dev_req->dev_id);
|
||||||
snprintf(dev_descr, 30, "Bluetooth adapter number %d", i);
|
pcap_snprintf(dev_descr, 30, "Bluetooth adapter number %d", i);
|
||||||
|
|
||||||
if (pcap_add_if(alldevsp, dev_name, 0,
|
if (pcap_add_if(alldevsp, dev_name, 0,
|
||||||
dev_descr, err_str) < 0)
|
dev_descr, err_str) < 0)
|
||||||
{
|
{
|
||||||
ret = -1;
|
ret = -1;
|
||||||
|
@ -171,7 +171,7 @@ bt_create(const char *device, char *ebuf, int *is_ours)
|
||||||
/* OK, it's probably ours. */
|
/* OK, it's probably ours. */
|
||||||
*is_ours = 1;
|
*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)
|
if (p == NULL)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
|
@ -190,17 +190,16 @@ bt_activate(pcap_t* handle)
|
||||||
int err = PCAP_ERROR;
|
int err = PCAP_ERROR;
|
||||||
|
|
||||||
/* get bt interface id */
|
/* 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,
|
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||||
"Can't get Bluetooth device index from %s",
|
"Can't get Bluetooth device index from %s",
|
||||||
handle->opt.source);
|
handle->opt.device);
|
||||||
return PCAP_ERROR;
|
return PCAP_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize some components of the pcap structure. */
|
/* Initialize some components of the pcap structure. */
|
||||||
handle->bufsize = handle->snapshot+BT_CTRL_SIZE+sizeof(pcap_bluetooth_h4_header);
|
handle->bufsize = BT_CTRL_SIZE+sizeof(pcap_bluetooth_h4_header)+handle->snapshot;
|
||||||
handle->offset = BT_CTRL_SIZE;
|
|
||||||
handle->linktype = DLT_BLUETOOTH_HCI_H4_WITH_PHDR;
|
handle->linktype = DLT_BLUETOOTH_HCI_H4_WITH_PHDR;
|
||||||
|
|
||||||
handle->read_op = bt_read_linux;
|
handle->read_op = bt_read_linux;
|
||||||
|
@ -212,43 +211,43 @@ bt_activate(pcap_t* handle)
|
||||||
handle->setnonblock_op = pcap_setnonblock_fd;
|
handle->setnonblock_op = pcap_setnonblock_fd;
|
||||||
handle->stats_op = bt_stats_linux;
|
handle->stats_op = bt_stats_linux;
|
||||||
handlep->dev_id = dev_id;
|
handlep->dev_id = dev_id;
|
||||||
|
|
||||||
/* Create HCI socket */
|
/* Create HCI socket */
|
||||||
handle->fd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
|
handle->fd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
|
||||||
if (handle->fd < 0) {
|
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));
|
"Can't create raw socket: %s", strerror(errno));
|
||||||
return PCAP_ERROR;
|
return PCAP_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
handle->buffer = malloc(handle->bufsize);
|
handle->buffer = malloc(handle->bufsize);
|
||||||
if (!handle->buffer) {
|
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));
|
pcap_strerror(errno));
|
||||||
goto close_fail;
|
goto close_fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
opt = 1;
|
opt = 1;
|
||||||
if (setsockopt(handle->fd, SOL_HCI, HCI_DATA_DIR, &opt, sizeof(opt)) < 0) {
|
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));
|
"Can't enable data direction info: %s", strerror(errno));
|
||||||
goto close_fail;
|
goto close_fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
opt = 1;
|
opt = 1;
|
||||||
if (setsockopt(handle->fd, SOL_HCI, HCI_TIME_STAMP, &opt, sizeof(opt)) < 0) {
|
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));
|
"Can't enable time stamp: %s", strerror(errno));
|
||||||
goto close_fail;
|
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 */
|
* external libs */
|
||||||
memset(&flt, 0, sizeof(flt));
|
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));
|
memset((void *) &flt.event_mask, 0xff, sizeof(flt.event_mask));
|
||||||
if (setsockopt(handle->fd, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) {
|
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));
|
"Can't set filter: %s", strerror(errno));
|
||||||
goto close_fail;
|
goto close_fail;
|
||||||
}
|
}
|
||||||
|
@ -261,7 +260,7 @@ bt_activate(pcap_t* handle)
|
||||||
addr.hci_channel = HCI_CHANNEL_RAW;
|
addr.hci_channel = HCI_CHANNEL_RAW;
|
||||||
#endif
|
#endif
|
||||||
if (bind(handle->fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
|
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,
|
"Can't attach to device %d: %s", handlep->dev_id,
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
goto close_fail;
|
goto close_fail;
|
||||||
|
@ -282,7 +281,7 @@ bt_activate(pcap_t* handle)
|
||||||
if (setsockopt(handle->fd, SOL_SOCKET, SO_RCVBUF,
|
if (setsockopt(handle->fd, SOL_SOCKET, SO_RCVBUF,
|
||||||
&handle->opt.buffer_size,
|
&handle->opt.buffer_size,
|
||||||
sizeof(handle->opt.buffer_size)) == -1) {
|
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));
|
"SO_RCVBUF: %s", pcap_strerror(errno));
|
||||||
goto close_fail;
|
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;
|
ssize_t ret;
|
||||||
struct pcap_pkthdr pkth;
|
struct pcap_pkthdr pkth;
|
||||||
pcap_bluetooth_h4_header* bthdr;
|
pcap_bluetooth_h4_header* bthdr;
|
||||||
|
u_char *pktd;
|
||||||
|
int in = 0;
|
||||||
|
|
||||||
bthdr = (pcap_bluetooth_h4_header*) &handle->buffer[handle->offset];
|
pktd = (u_char *)handle->buffer + BT_CTRL_SIZE;
|
||||||
iv.iov_base = &handle->buffer[handle->offset+sizeof(pcap_bluetooth_h4_header)];
|
bthdr = (pcap_bluetooth_h4_header*)(void *)pktd;
|
||||||
|
iv.iov_base = pktd + sizeof(pcap_bluetooth_h4_header);
|
||||||
iv.iov_len = handle->snapshot;
|
iv.iov_len = handle->snapshot;
|
||||||
|
|
||||||
memset(&msg, 0, sizeof(msg));
|
memset(&msg, 0, sizeof(msg));
|
||||||
msg.msg_iov = &iv;
|
msg.msg_iov = &iv;
|
||||||
msg.msg_iovlen = 1;
|
msg.msg_iovlen = 1;
|
||||||
msg.msg_control = handle->buffer;
|
msg.msg_control = handle->buffer;
|
||||||
msg.msg_controllen = handle->offset;
|
msg.msg_controllen = BT_CTRL_SIZE;
|
||||||
|
|
||||||
/* ignore interrupt system call error */
|
/* ignore interrupt system call error */
|
||||||
do {
|
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));
|
} while ((ret == -1) && (errno == EINTR));
|
||||||
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||||
"Can't receive packet: %s", strerror(errno));
|
"Can't receive packet: %s", strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pkth.caplen = ret;
|
pkth.caplen = ret;
|
||||||
|
|
||||||
/* get direction and timestamp*/
|
/* get direction and timestamp*/
|
||||||
cmsg = CMSG_FIRSTHDR(&msg);
|
cmsg = CMSG_FIRSTHDR(&msg);
|
||||||
int in=0;
|
|
||||||
while (cmsg) {
|
while (cmsg) {
|
||||||
switch (cmsg->cmsg_type) {
|
switch (cmsg->cmsg_type) {
|
||||||
case HCI_CMSG_DIR:
|
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);
|
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)))
|
((!in) && (handle->direction == PCAP_D_IN)))
|
||||||
return 0;
|
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.caplen+=sizeof(pcap_bluetooth_h4_header);
|
||||||
pkth.len = pkth.caplen;
|
pkth.len = pkth.caplen;
|
||||||
if (handle->fcode.bf_insns == NULL ||
|
if (handle->fcode.bf_insns == NULL ||
|
||||||
bpf_filter(handle->fcode.bf_insns, &handle->buffer[handle->offset],
|
bpf_filter(handle->fcode.bf_insns, pktd, pkth.len, pkth.caplen)) {
|
||||||
pkth.len, pkth.caplen)) {
|
callback(user, &pkth, pktd);
|
||||||
callback(user, &pkth, &handle->buffer[handle->offset]);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0; /* didn't pass filter */
|
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
|
static int
|
||||||
bt_inject_linux(pcap_t *handle, const void *buf, size_t size)
|
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");
|
"bluetooth devices");
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
bt_stats_linux(pcap_t *handle, struct pcap_stat *stats)
|
bt_stats_linux(pcap_t *handle, struct pcap_stat *stats)
|
||||||
{
|
{
|
||||||
struct pcap_bt *handlep = handle->priv;
|
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_info dev_info;
|
||||||
struct hci_dev_stats * s = &dev_info.stat;
|
struct hci_dev_stats * s = &dev_info.stat;
|
||||||
dev_info.dev_id = handlep->dev_id;
|
dev_info.dev_id = handlep->dev_id;
|
||||||
|
|
||||||
/* ignore eintr */
|
/* ignore eintr */
|
||||||
do {
|
do {
|
||||||
ret = ioctl(handle->fd, HCIGETDEVINFO, (void *)&dev_info);
|
ret = ioctl(handle->fd, HCIGETDEVINFO, (void *)&dev_info);
|
||||||
} while ((ret == -1) && (errno == EINTR));
|
} while ((ret == -1) && (errno == EINTR));
|
||||||
|
|
||||||
if (ret < 0) {
|
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));
|
"Can't get stats via ioctl: %s", strerror(errno));
|
||||||
return (-1);
|
return (-1);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we receive both rx and tx frames, so comulate all stats */
|
/* 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 +
|
stats->ps_recv = s->evt_rx + s->acl_rx + s->sco_rx + s->cmd_tx +
|
||||||
s->acl_tx +s->sco_tx;
|
s->acl_tx +s->sco_tx;
|
||||||
stats->ps_drop = s->err_rx + s->err_tx;
|
stats->ps_drop = s->err_rx + s->err_tx;
|
||||||
stats->ps_ifdrop = 0;
|
stats->ps_ifdrop = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
bt_setdirection_linux(pcap_t *p, pcap_direction_t d)
|
bt_setdirection_linux(pcap_t *p, pcap_direction_t d)
|
||||||
{
|
{
|
||||||
p->direction = d;
|
p->direction = d;
|
||||||
|
|
|
@ -11,8 +11,8 @@
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
* 3. The name of the author may not be used to endorse or promote
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
* products derived from this software without specific prior written
|
* products derived from this software without specific prior written
|
||||||
* permission.
|
* permission.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
|
|
@ -34,19 +34,31 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <bluetooth/bluetooth.h>
|
#include <bluetooth/bluetooth.h>
|
||||||
#include <bluetooth/hci.h>
|
#include <bluetooth/hci.h>
|
||||||
#include <bluetooth/mgmt.h>
|
|
||||||
|
|
||||||
#include "pcap/bluetooth.h"
|
#include "pcap/bluetooth.h"
|
||||||
#include "pcap-int.h"
|
#include "pcap-int.h"
|
||||||
|
|
||||||
|
#include "pcap-bt-monitor-linux.h"
|
||||||
|
|
||||||
#define BT_CONTROL_SIZE 32
|
#define BT_CONTROL_SIZE 32
|
||||||
#define INTERFACE_NAME "bluetooth-monitor"
|
#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
|
int
|
||||||
bt_monitor_findalldevs(pcap_if_t **alldevsp, char *err_str)
|
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;
|
ssize_t ret;
|
||||||
struct pcap_pkthdr pkth;
|
struct pcap_pkthdr pkth;
|
||||||
pcap_bluetooth_linux_monitor_header *bthdr;
|
pcap_bluetooth_linux_monitor_header *bthdr;
|
||||||
struct mgmt_hdr hdr;
|
u_char *pktd;
|
||||||
int in = 0;
|
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_base = &hdr;
|
||||||
iv[0].iov_len = MGMT_HDR_SIZE;
|
iv[0].iov_len = sizeof(hdr);
|
||||||
iv[1].iov_base = &handle->buffer[handle->offset + sizeof(pcap_bluetooth_linux_monitor_header)];
|
iv[1].iov_base = pktd + sizeof(pcap_bluetooth_linux_monitor_header);
|
||||||
iv[1].iov_len = handle->snapshot;
|
iv[1].iov_len = handle->snapshot;
|
||||||
|
|
||||||
memset(&pkth.ts, 0, sizeof(pkth.ts));
|
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_iov = iv;
|
||||||
msg.msg_iovlen = 2;
|
msg.msg_iovlen = 2;
|
||||||
msg.msg_control = handle->buffer;
|
msg.msg_control = handle->buffer;
|
||||||
msg.msg_controllen = handle->offset;
|
msg.msg_controllen = BT_CONTROL_SIZE;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
ret = recvmsg(handle->fd, &msg, 0);
|
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));
|
} while ((ret == -1) && (errno == EINTR));
|
||||||
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||||
"Can't receive packet: %s", strerror(errno));
|
"Can't receive packet: %s", strerror(errno));
|
||||||
return -1;
|
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;
|
pkth.len = pkth.caplen;
|
||||||
|
|
||||||
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
|
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);
|
bthdr->opcode = htons(hdr.opcode);
|
||||||
|
|
||||||
if (handle->fcode.bf_insns == NULL ||
|
if (handle->fcode.bf_insns == NULL ||
|
||||||
bpf_filter(handle->fcode.bf_insns, &handle->buffer[handle->offset],
|
bpf_filter(handle->fcode.bf_insns, pktd, pkth.len, pkth.caplen)) {
|
||||||
pkth.len, pkth.caplen)) {
|
callback(user, &pkth, pktd);
|
||||||
callback(user, &pkth, &handle->buffer[handle->offset]);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0; /* didn't pass filter */
|
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
|
static int
|
||||||
bt_monitor_inject(pcap_t *handle, const void *buf _U_, size_t size _U_)
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,8 +173,7 @@ bt_monitor_activate(pcap_t* handle)
|
||||||
return PCAP_ERROR_RFMON_NOTSUP;
|
return PCAP_ERROR_RFMON_NOTSUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
handle->bufsize = handle->snapshot + BT_CONTROL_SIZE + sizeof(pcap_bluetooth_linux_monitor_header);
|
handle->bufsize = BT_CONTROL_SIZE + sizeof(pcap_bluetooth_linux_monitor_header) + handle->snapshot;
|
||||||
handle->offset = BT_CONTROL_SIZE;
|
|
||||||
handle->linktype = DLT_BLUETOOTH_LINUX_MONITOR;
|
handle->linktype = DLT_BLUETOOTH_LINUX_MONITOR;
|
||||||
|
|
||||||
handle->read_op = bt_monitor_read;
|
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);
|
handle->fd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
|
||||||
if (handle->fd < 0) {
|
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));
|
"Can't create raw socket: %s", strerror(errno));
|
||||||
return PCAP_ERROR;
|
return PCAP_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
handle->buffer = malloc(handle->bufsize);
|
handle->buffer = malloc(handle->bufsize);
|
||||||
if (!handle->buffer) {
|
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));
|
pcap_strerror(errno));
|
||||||
goto close_fail;
|
goto close_fail;
|
||||||
}
|
}
|
||||||
|
@ -194,14 +205,14 @@ bt_monitor_activate(pcap_t* handle)
|
||||||
addr.hci_channel = HCI_CHANNEL_MONITOR;
|
addr.hci_channel = HCI_CHANNEL_MONITOR;
|
||||||
|
|
||||||
if (bind(handle->fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
|
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));
|
"Can't attach to interface: %s", strerror(errno));
|
||||||
goto close_fail;
|
goto close_fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
opt = 1;
|
opt = 1;
|
||||||
if (setsockopt(handle->fd, SOL_SOCKET, SO_TIMESTAMP, &opt, sizeof(opt)) < 0) {
|
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));
|
"Can't enable time stamp: %s", strerror(errno));
|
||||||
goto close_fail;
|
goto close_fail;
|
||||||
}
|
}
|
||||||
|
@ -231,7 +242,7 @@ bt_monitor_create(const char *device, char *ebuf, int *is_ours)
|
||||||
}
|
}
|
||||||
|
|
||||||
*is_ours = 1;
|
*is_ours = 1;
|
||||||
p = pcap_create_common(device, ebuf, 0);
|
p = pcap_create_common(ebuf, 0);
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
|
|
@ -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);
|
|
|
@ -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 */
|
|
|
@ -25,9 +25,9 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef _WIN32
|
||||||
#include <pcap-stdinc.h>
|
#include <pcap-stdinc.h>
|
||||||
#else /* WIN32 */
|
#else /* _WIN32 */
|
||||||
#if HAVE_INTTYPES_H
|
#if HAVE_INTTYPES_H
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#elif HAVE_STDINT_H
|
#elif HAVE_STDINT_H
|
||||||
|
@ -37,11 +37,14 @@
|
||||||
#include <sys/bitypes.h>
|
#include <sys/bitypes.h>
|
||||||
#endif
|
#endif
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#endif /* WIN32 */
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
#include "pcap-int.h"
|
#include "pcap-int.h"
|
||||||
|
#include "extract.h"
|
||||||
|
#include "pcap/sll.h"
|
||||||
#include "pcap/usb.h"
|
#include "pcap/usb.h"
|
||||||
#include "pcap/nflog.h"
|
#include "pcap/nflog.h"
|
||||||
|
#include "pcap/can_socketcan.h"
|
||||||
|
|
||||||
#include "pcap-common.h"
|
#include "pcap-common.h"
|
||||||
|
|
||||||
|
@ -351,7 +354,7 @@
|
||||||
|
|
||||||
#define LINKTYPE_GPRS_LLC 169 /* GPRS LLC */
|
#define LINKTYPE_GPRS_LLC 169 /* GPRS LLC */
|
||||||
#define LINKTYPE_GPF_T 170 /* GPF-T (ITU-T G.7041/Y.1303) */
|
#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
|
* 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
|
* 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
|
* The Link Types are used for prepending meta-information
|
||||||
* like interface index, interface name
|
* like interface index, interface name
|
||||||
* before standard Ethernet, PPP, Frelay & C-HDLC Frames
|
* before standard Ethernet, PPP, Frelay & C-HDLC Frames
|
||||||
|
@ -403,7 +406,7 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Juniper-private data link type, as per request from
|
* 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
|
* The DLT_ is used for internal communication with a
|
||||||
* voice Adapter Card (PIC)
|
* voice Adapter Card (PIC)
|
||||||
*/
|
*/
|
||||||
|
@ -426,10 +429,17 @@
|
||||||
#define LINKTYPE_A653_ICM 185
|
#define LINKTYPE_A653_ICM 185
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* USB packets, beginning with a USB setup header; requested by
|
* This used to be "USB packets, beginning with a USB setup header;
|
||||||
* Paolo Abeni <paolo.abeni@email.it>.
|
* 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
|
* Bluetooth HCI UART transport layer (part H:4); requested by
|
||||||
|
@ -478,7 +488,7 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Juniper-private data link type, as per request from
|
* 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
|
* The DLT_ is used for internal communication with a
|
||||||
* integrated service module (ISM).
|
* integrated service module (ISM).
|
||||||
*/
|
*/
|
||||||
|
@ -519,7 +529,7 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Juniper-private data link type, as per request from
|
* 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.
|
* The DLT_ is used for capturing data on a secure tunnel interface.
|
||||||
*/
|
*/
|
||||||
#define LINKTYPE_JUNIPER_ST 200
|
#define LINKTYPE_JUNIPER_ST 200
|
||||||
|
@ -611,11 +621,11 @@
|
||||||
*/
|
*/
|
||||||
#define LINKTYPE_IEEE802_15_4_NONASK_PHY 215
|
#define LINKTYPE_IEEE802_15_4_NONASK_PHY 215
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* David Gibson <david@gibson.dropbear.id.au> requested this for
|
* David Gibson <david@gibson.dropbear.id.au> requested this for
|
||||||
* captures from the Linux kernel /dev/input/eventN devices. This
|
* captures from the Linux kernel /dev/input/eventN devices. This
|
||||||
* is used to communicate keystrokes and mouse movements from the
|
* 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
|
#define LINKTYPE_LINUX_EVDEV 216
|
||||||
|
|
||||||
|
@ -736,8 +746,10 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* CAN (Controller Area Network) frames, with a pseudo-header as supplied
|
* CAN (Controller Area Network) frames, with a pseudo-header as supplied
|
||||||
* by Linux SocketCAN. See Documentation/networking/can.txt in the Linux
|
* by Linux SocketCAN, and with multi-byte numerical fields in that header
|
||||||
* source.
|
* in big-endian byte order.
|
||||||
|
*
|
||||||
|
* See Documentation/networking/can.txt in the Linux source.
|
||||||
*
|
*
|
||||||
* Requested by Felix Obenhuber <felix@obenhuber.de>.
|
* Requested by Felix Obenhuber <felix@obenhuber.de>.
|
||||||
*/
|
*/
|
||||||
|
@ -777,7 +789,7 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Juniper-private data link type, as per request from
|
* 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_VS 232
|
||||||
#define LINKTYPE_JUNIPER_SRX_E2E 233
|
#define LINKTYPE_JUNIPER_SRX_E2E 233
|
||||||
|
@ -809,12 +821,12 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Juniper-private data link type, as per request from
|
* 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
|
#define LINKTYPE_JUNIPER_ATM_CEMIC 238
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NetFilter LOG messages
|
* NetFilter LOG messages
|
||||||
* (payload of netlink NFNL_SUBSYS_ULOG/NFULNL_MSG_PACKET packets)
|
* (payload of netlink NFNL_SUBSYS_ULOG/NFULNL_MSG_PACKET packets)
|
||||||
*
|
*
|
||||||
* Requested by Jakub Zawadzki <darkjames-ws@darkjames.pl>
|
* Requested by Jakub Zawadzki <darkjames-ws@darkjames.pl>
|
||||||
|
@ -922,7 +934,7 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Link-layer header type for upper-protocol layer PDU saves from wireshark.
|
* Link-layer header type for upper-protocol layer PDU saves from wireshark.
|
||||||
*
|
*
|
||||||
* the actual contents are determined by two TAGs stored with each
|
* the actual contents are determined by two TAGs stored with each
|
||||||
* packet:
|
* packet:
|
||||||
* EXP_PDU_TAG_LINKTYPE the link type (LINKTYPE_ value) of the
|
* EXP_PDU_TAG_LINKTYPE the link type (LINKTYPE_ value) of the
|
||||||
|
@ -959,7 +971,6 @@
|
||||||
*/
|
*/
|
||||||
#define LINKTYPE_PROFIBUS_DL 257
|
#define LINKTYPE_PROFIBUS_DL 257
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Apple's DLT_PKTAP headers.
|
* Apple's DLT_PKTAP headers.
|
||||||
*
|
*
|
||||||
|
@ -994,7 +1005,30 @@
|
||||||
*/
|
*/
|
||||||
#define LINKTYPE_IPMI_HPM_2 260
|
#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 {
|
static struct linktype_map {
|
||||||
int dlt;
|
int dlt;
|
||||||
|
@ -1141,6 +1175,48 @@ linktype_to_dlt(int linktype)
|
||||||
return 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
|
* The DLT_USB_LINUX and DLT_USB_LINUX_MMAPPED headers are in host
|
||||||
* byte order when capturing (it's supplied directly from a
|
* 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;
|
pcap_usb_header_mmapped *uhdr = (pcap_usb_header_mmapped *)buf;
|
||||||
bpf_u_int32 offset = 0;
|
bpf_u_int32 offset = 0;
|
||||||
usb_isodesc *pisodesc;
|
|
||||||
int32_t numdesc, i;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* "offset" is the offset *past* the field we're swapping;
|
* "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???
|
* convert it to the reading host's byte order???
|
||||||
*/
|
*/
|
||||||
offset += 8; /* skip past id */
|
offset += 8; /* skip past id */
|
||||||
|
@ -1221,6 +1295,17 @@ swap_linux_usb_header(const struct pcap_pkthdr *hdr, u_char *buf,
|
||||||
} else
|
} else
|
||||||
offset += 8; /* skip USB setup header */
|
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) {
|
if (header_len_64_bytes) {
|
||||||
/*
|
/*
|
||||||
* This is either the "version 1" header, with
|
* 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)
|
if (hdr->caplen < offset)
|
||||||
return;
|
return;
|
||||||
uhdr->ndesc = SWAPLONG(uhdr->ndesc);
|
uhdr->ndesc = SWAPLONG(uhdr->ndesc);
|
||||||
}
|
|
||||||
|
|
||||||
if (uhdr->transfer_type == URB_ISOCHRONOUS) {
|
if (uhdr->transfer_type == URB_ISOCHRONOUS) {
|
||||||
/* swap the values in struct linux_usb_isodesc */
|
/* swap the values in struct linux_usb_isodesc */
|
||||||
pisodesc = (usb_isodesc *)(void *)(buf+offset);
|
usb_isodesc *pisodesc;
|
||||||
numdesc = uhdr->s.iso.numdesc;
|
u_int32_t i;
|
||||||
for (i = 0; i < numdesc; i++) {
|
|
||||||
offset += 4; /* skip past status */
|
|
||||||
if (hdr->caplen < offset)
|
|
||||||
return;
|
|
||||||
pisodesc->status = SWAPLONG(pisodesc->status);
|
|
||||||
|
|
||||||
offset += 4; /* skip past offset */
|
pisodesc = (usb_isodesc *)(void *)(buf+offset);
|
||||||
if (hdr->caplen < offset)
|
for (i = 0; i < uhdr->ndesc; i++) {
|
||||||
return;
|
offset += 4; /* skip past status */
|
||||||
pisodesc->offset = SWAPLONG(pisodesc->offset);
|
if (hdr->caplen < offset)
|
||||||
|
return;
|
||||||
|
pisodesc->status = SWAPLONG(pisodesc->status);
|
||||||
|
|
||||||
offset += 4; /* skip past len */
|
offset += 4; /* skip past offset */
|
||||||
if (hdr->caplen < offset)
|
if (hdr->caplen < offset)
|
||||||
return;
|
return;
|
||||||
pisodesc->len = SWAPLONG(pisodesc->len);
|
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_int length = hdr->len;
|
||||||
u_int16_t size;
|
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. */
|
/* Not enough data to have any TLVs. */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(nfhdr->nflog_version) == 0) {
|
if (nfhdr->nflog_version != 0) {
|
||||||
/* Unknown NFLOG version */
|
/* Unknown NFLOG version */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1354,6 +1442,10 @@ swap_pseudo_headers(int linktype, struct pcap_pkthdr *hdr, u_char *data)
|
||||||
*/
|
*/
|
||||||
switch (linktype) {
|
switch (linktype) {
|
||||||
|
|
||||||
|
case DLT_LINUX_SLL:
|
||||||
|
swap_linux_sll_header(hdr, data);
|
||||||
|
break;
|
||||||
|
|
||||||
case DLT_USB_LINUX:
|
case DLT_USB_LINUX:
|
||||||
swap_linux_usb_header(hdr, data, 0);
|
swap_linux_usb_header(hdr, data, 0);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||||
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
.\"
|
.\"
|
||||||
.TH PCAP-CONFIG 1 "22 May 2009"
|
.TH PCAP-CONFIG 1 "15 February 2015"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
pcap-config \- write libpcap compiler and linker flags to standard output
|
pcap-config \- write libpcap compiler and linker flags to standard output
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
|
|
|
@ -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
|
* 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
|
* 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.
|
* called as required from their pcap-linux/bpf equivalents.
|
||||||
*
|
*
|
||||||
* Authors: Richard Littin, Sean Irvine ({richard,sean}@reeltwo.com)
|
* Authors: Richard Littin, Sean Irvine ({richard,sean}@reeltwo.com)
|
||||||
* Modifications: Jesper Peterson <support@endace.com>
|
* Modifications: Jesper Peterson
|
||||||
* Koryn Grant <support@endace.com>
|
* Koryn Grant
|
||||||
* Stephen Donnelly <support@endace.com>
|
* Stephen Donnelly <stephen.donnelly@emulex.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
|
@ -40,6 +40,7 @@ struct rtentry; /* declarations in <net/if.h> */
|
||||||
|
|
||||||
#include "dagnew.h"
|
#include "dagnew.h"
|
||||||
#include "dagapi.h"
|
#include "dagapi.h"
|
||||||
|
#include "dagpci.h"
|
||||||
|
|
||||||
#include "pcap-dag.h"
|
#include "pcap-dag.h"
|
||||||
|
|
||||||
|
@ -52,6 +53,99 @@ struct rtentry; /* declarations in <net/if.h> */
|
||||||
#define DAG_MAX_BOARDS 32
|
#define DAG_MAX_BOARDS 32
|
||||||
#endif
|
#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_CELL_SIZE 52
|
||||||
#define ATM_HDR_SIZE 4
|
#define ATM_HDR_SIZE 4
|
||||||
|
|
||||||
|
@ -143,28 +237,25 @@ delete_pcap_dag(pcap_t *p)
|
||||||
static void
|
static void
|
||||||
dag_platform_cleanup(pcap_t *p)
|
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
|
#ifdef HAVE_DAG_STREAMS_API
|
||||||
if(dag_stop_stream(p->fd, pd->dag_stream) < 0)
|
if(dag_stop_stream(p->fd, pd->dag_stream) < 0)
|
||||||
fprintf(stderr,"dag_stop_stream: %s\n", strerror(errno));
|
fprintf(stderr,"dag_stop_stream: %s\n", strerror(errno));
|
||||||
|
|
||||||
if(dag_detach_stream(p->fd, pd->dag_stream) < 0)
|
if(dag_detach_stream(p->fd, pd->dag_stream) < 0)
|
||||||
fprintf(stderr,"dag_detach_stream: %s\n", strerror(errno));
|
fprintf(stderr,"dag_detach_stream: %s\n", strerror(errno));
|
||||||
#else
|
#else
|
||||||
if(dag_stop(p->fd) < 0)
|
if(dag_stop(p->fd) < 0)
|
||||||
fprintf(stderr,"dag_stop: %s\n", strerror(errno));
|
fprintf(stderr,"dag_stop: %s\n", strerror(errno));
|
||||||
#endif /* HAVE_DAG_STREAMS_API */
|
#endif /* HAVE_DAG_STREAMS_API */
|
||||||
if(p->fd != -1) {
|
if(p->fd != -1) {
|
||||||
if(dag_close(p->fd) < 0)
|
if(dag_close(p->fd) < 0)
|
||||||
fprintf(stderr,"dag_close: %s\n", strerror(errno));
|
fprintf(stderr,"dag_close: %s\n", strerror(errno));
|
||||||
p->fd = -1;
|
p->fd = -1;
|
||||||
}
|
|
||||||
delete_pcap_dag(p);
|
|
||||||
pcap_cleanup_live_common(p);
|
|
||||||
}
|
}
|
||||||
|
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. */
|
/* 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) {
|
while (pcap_dags != NULL) {
|
||||||
if (pcap_dags->pid == getpid()) {
|
if (pcap_dags->pid == getpid()) {
|
||||||
dag_platform_cleanup(pcap_dags->p);
|
if (pcap_dags->p != NULL)
|
||||||
|
dag_platform_cleanup(pcap_dags->p);
|
||||||
} else {
|
} else {
|
||||||
delete_pcap_dag(pcap_dags->p);
|
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 */
|
/* loop over the extension headers */
|
||||||
do {
|
do {
|
||||||
|
|
||||||
/* sanity check we have enough bytes */
|
/* sanity check we have enough bytes */
|
||||||
if ( len < (24 + (hdr_num * 8)) )
|
if ( len < (24 + (hdr_num * 8)) )
|
||||||
return hdr_num;
|
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;
|
int flags = pd->dag_offset_flags;
|
||||||
unsigned int nonblocking = flags & DAGF_NONBLOCK;
|
unsigned int nonblocking = flags & DAGF_NONBLOCK;
|
||||||
unsigned int num_ext_hdr = 0;
|
unsigned int num_ext_hdr = 0;
|
||||||
|
unsigned int ticks_per_second;
|
||||||
|
|
||||||
/* Get the next bufferful of packets (if necessary). */
|
/* Get the next bufferful of packets (if necessary). */
|
||||||
while (pd->dag_mem_top - pd->dag_mem_bottom < dag_record_size) {
|
while (pd->dag_mem_top - pd->dag_mem_bottom < dag_record_size) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Has "pcap_breakloop()" been called?
|
* 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. */
|
/* Pcap is configured to process only available packets, and there aren't any, return immediately. */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!nonblocking &&
|
if(!nonblocking &&
|
||||||
pd->dag_timeout &&
|
pd->dag_timeout &&
|
||||||
(pd->dag_mem_top - pd->dag_mem_bottom < dag_record_size))
|
(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. */
|
/* Process the packets. */
|
||||||
while (pd->dag_mem_top - pd->dag_mem_bottom >= dag_record_size) {
|
while (pd->dag_mem_top - pd->dag_mem_bottom >= dag_record_size) {
|
||||||
|
|
||||||
unsigned short packet_len = 0;
|
unsigned short packet_len = 0;
|
||||||
int caplen = 0;
|
int caplen = 0;
|
||||||
struct pcap_pkthdr pcap_header;
|
struct pcap_pkthdr pcap_header;
|
||||||
|
|
||||||
#ifdef HAVE_DAG_STREAMS_API
|
#ifdef HAVE_DAG_STREAMS_API
|
||||||
dag_record_t *header = (dag_record_t *)(pd->dag_mem_bottom);
|
dag_record_t *header = (dag_record_t *)(pd->dag_mem_bottom);
|
||||||
#else
|
#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; */
|
u_char *dp = ((u_char *)header); /* + dag_record_size; */
|
||||||
unsigned short rlen;
|
unsigned short rlen;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Has "pcap_breakloop()" been called?
|
* 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;
|
p->break_loop = 0;
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
rlen = ntohs(header->rlen);
|
rlen = ntohs(header->rlen);
|
||||||
if (rlen < dag_record_size)
|
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) {
|
if ((header->type & 0x7f) == TYPE_PAD) {
|
||||||
continue;
|
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);
|
num_ext_hdr = dag_erf_ext_header_count(dp, rlen);
|
||||||
|
|
||||||
/* ERF encapsulation */
|
/* 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.
|
* 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)
|
* 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.
|
* could be merged with the libpcap information, to offer a better decoding.
|
||||||
* The packet length is
|
* The packet length is
|
||||||
* o the length of the packet on the link (header->wlen),
|
* 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,
|
* pseudo header will be adjusted during the decoding,
|
||||||
* o plus the length of the optional subheader (if present).
|
* 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;
|
dp += dag_record_size;
|
||||||
/* Skip over extension headers */
|
/* Skip over extension headers */
|
||||||
dp += 8 * num_ext_hdr;
|
dp += 8 * num_ext_hdr;
|
||||||
|
|
||||||
switch((header->type & 0x7f)) {
|
switch((header->type & 0x7f)) {
|
||||||
case TYPE_ATM:
|
case TYPE_ATM:
|
||||||
case TYPE_AAL5:
|
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;
|
caplen = rlen - dag_record_size - 4;
|
||||||
dp+=4;
|
dp+=4;
|
||||||
}
|
}
|
||||||
|
/* Skip over extension headers */
|
||||||
|
caplen -= (8 * num_ext_hdr);
|
||||||
|
|
||||||
if (header->type == TYPE_ATM) {
|
if (header->type == TYPE_ATM) {
|
||||||
caplen = packet_len = ATM_CELL_SIZE;
|
caplen = packet_len = ATM_CELL_SIZE;
|
||||||
}
|
}
|
||||||
if (p->linktype == DLT_SUNATM) {
|
if (p->linktype == DLT_SUNATM) {
|
||||||
struct sunatm_hdr *sunatm = (struct sunatm_hdr *)dp;
|
struct sunatm_hdr *sunatm = (struct sunatm_hdr *)dp;
|
||||||
unsigned long rawatm;
|
unsigned long rawatm;
|
||||||
|
|
||||||
rawatm = ntohl(*((unsigned long *)dp));
|
rawatm = ntohl(*((unsigned long *)dp));
|
||||||
sunatm->vci = htons((rawatm >> 4) & 0xffff);
|
sunatm->vci = htons((rawatm >> 4) & 0xffff);
|
||||||
sunatm->vpi = (rawatm >> 20) & 0x00ff;
|
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(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] == 0xaa &&
|
||||||
dp[ATM_HDR_SIZE+1] == 0xaa &&
|
dp[ATM_HDR_SIZE+1] == 0xaa &&
|
||||||
dp[ATM_HDR_SIZE+2] == 0x03) ? 2 : 1)));
|
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 = ntohs(header->wlen);
|
||||||
packet_len -= (pd->dag_fcs_bits >> 3);
|
packet_len -= (pd->dag_fcs_bits >> 3);
|
||||||
caplen = rlen - dag_record_size - 2;
|
caplen = rlen - dag_record_size - 2;
|
||||||
|
/* Skip over extension headers */
|
||||||
|
caplen -= (8 * num_ext_hdr);
|
||||||
if (caplen > packet_len) {
|
if (caplen > packet_len) {
|
||||||
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 = ntohs(header->wlen);
|
||||||
packet_len -= (pd->dag_fcs_bits >> 3);
|
packet_len -= (pd->dag_fcs_bits >> 3);
|
||||||
caplen = rlen - dag_record_size;
|
caplen = rlen - dag_record_size;
|
||||||
|
/* Skip over extension headers */
|
||||||
|
caplen -= (8 * num_ext_hdr);
|
||||||
if (caplen > packet_len) {
|
if (caplen > packet_len) {
|
||||||
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 = ntohs(header->wlen);
|
||||||
packet_len -= (pd->dag_fcs_bits >> 3);
|
packet_len -= (pd->dag_fcs_bits >> 3);
|
||||||
caplen = rlen - dag_record_size - 4;
|
caplen = rlen - dag_record_size - 4;
|
||||||
|
/* Skip over extension headers */
|
||||||
|
caplen -= (8 * num_ext_hdr);
|
||||||
if (caplen > packet_len) {
|
if (caplen > packet_len) {
|
||||||
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 */
|
/* Add the MTP2 Pseudo Header */
|
||||||
caplen += MTP2_HDR_LEN;
|
caplen += MTP2_HDR_LEN;
|
||||||
packet_len += MTP2_HDR_LEN;
|
packet_len += MTP2_HDR_LEN;
|
||||||
|
|
||||||
TempPkt[MTP2_SENT_OFFSET] = 0;
|
TempPkt[MTP2_SENT_OFFSET] = 0;
|
||||||
TempPkt[MTP2_ANNEX_A_USED_OFFSET] = MTP2_ANNEX_A_USED_UNKNOWN;
|
TempPkt[MTP2_ANNEX_A_USED_OFFSET] = MTP2_ANNEX_A_USED_UNKNOWN;
|
||||||
*(TempPkt+MTP2_LINK_NUMBER_OFFSET) = ((header->rec.mc_hdlc.mc_header>>16)&0x01);
|
*(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:
|
case TYPE_IPV6:
|
||||||
packet_len = ntohs(header->wlen);
|
packet_len = ntohs(header->wlen);
|
||||||
caplen = rlen - dag_record_size;
|
caplen = rlen - dag_record_size;
|
||||||
|
/* Skip over extension headers */
|
||||||
|
caplen -= (8 * num_ext_hdr);
|
||||||
if (caplen > packet_len) {
|
if (caplen > packet_len) {
|
||||||
caplen = packet_len;
|
caplen = packet_len;
|
||||||
}
|
}
|
||||||
|
@ -533,45 +637,52 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||||
continue;
|
continue;
|
||||||
} /* switch type */
|
} /* switch type */
|
||||||
|
|
||||||
/* Skip over extension headers */
|
|
||||||
caplen -= (8 * num_ext_hdr);
|
|
||||||
|
|
||||||
} /* ERF encapsulation */
|
} /* ERF encapsulation */
|
||||||
|
|
||||||
if (caplen > p->snapshot)
|
if (caplen > p->snapshot)
|
||||||
caplen = p->snapshot;
|
caplen = p->snapshot;
|
||||||
|
|
||||||
/* Run the packet filter if there is one. */
|
/* Run the packet filter if there is one. */
|
||||||
if ((p->fcode.bf_insns == NULL) || bpf_filter(p->fcode.bf_insns, dp, packet_len, caplen)) {
|
if ((p->fcode.bf_insns == NULL) || bpf_filter(p->fcode.bf_insns, dp, packet_len, caplen)) {
|
||||||
|
|
||||||
/* convert between timestamp formats */
|
/* convert between timestamp formats */
|
||||||
register unsigned long long ts;
|
register unsigned long long ts;
|
||||||
|
|
||||||
if (IS_BIGENDIAN()) {
|
if (IS_BIGENDIAN()) {
|
||||||
ts = SWAPLL(header->ts);
|
ts = SWAPLL(header->ts);
|
||||||
} else {
|
} else {
|
||||||
ts = header->ts;
|
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;
|
pcap_header.ts.tv_sec = ts >> 32;
|
||||||
ts = (ts & 0xffffffffULL) * 1000000;
|
ts = (ts & 0xffffffffULL) * ticks_per_second;
|
||||||
ts += 0x80000000; /* rounding */
|
ts += 0x80000000; /* rounding */
|
||||||
pcap_header.ts.tv_usec = ts >> 32;
|
pcap_header.ts.tv_usec = ts >> 32;
|
||||||
if (pcap_header.ts.tv_usec >= 1000000) {
|
if (pcap_header.ts.tv_usec >= ticks_per_second) {
|
||||||
pcap_header.ts.tv_usec -= 1000000;
|
pcap_header.ts.tv_usec -= ticks_per_second;
|
||||||
pcap_header.ts.tv_sec++;
|
pcap_header.ts.tv_sec++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fill in our own header data */
|
/* Fill in our own header data */
|
||||||
pcap_header.caplen = caplen;
|
pcap_header.caplen = caplen;
|
||||||
pcap_header.len = packet_len;
|
pcap_header.len = packet_len;
|
||||||
|
|
||||||
/* Count the packet. */
|
/* Count the packet. */
|
||||||
pd->stat.ps_recv++;
|
pd->stat.ps_recv++;
|
||||||
|
|
||||||
/* Call the user supplied callback function */
|
/* Call the user supplied callback function */
|
||||||
callback(user, &pcap_header, dp);
|
callback(user, &pcap_header, dp);
|
||||||
|
|
||||||
/* Only count packets that pass the filter, for consistency with standard Linux behaviour. */
|
/* Only count packets that pass the filter, for consistency with standard Linux behaviour. */
|
||||||
processed++;
|
processed++;
|
||||||
if (processed == cnt && !PACKET_COUNT_IS_UNLIMITED(cnt))
|
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
|
* 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
|
* cards are always promiscuous. The to_ms parameter is used in setting the
|
||||||
* API polling parameters.
|
* API polling parameters.
|
||||||
*
|
*
|
||||||
* snaplen is now also ignored, until we get per-stream slen support. Set
|
* snaplen is now also ignored, until we get per-stream slen support. Set
|
||||||
* slen with approprite DAG tool BEFORE pcap_activate().
|
* slen with approprite DAG tool BEFORE pcap_activate().
|
||||||
*
|
*
|
||||||
|
@ -614,7 +725,7 @@ static int dag_activate(pcap_t* handle)
|
||||||
int n;
|
int n;
|
||||||
daginf_t* daginf;
|
daginf_t* daginf;
|
||||||
char * newDev = NULL;
|
char * newDev = NULL;
|
||||||
char * device = handle->opt.source;
|
char * device = handle->opt.device;
|
||||||
#ifdef HAVE_DAG_STREAMS_API
|
#ifdef HAVE_DAG_STREAMS_API
|
||||||
uint32_t mindata;
|
uint32_t mindata;
|
||||||
struct timeval maxwait;
|
struct timeval maxwait;
|
||||||
|
@ -622,7 +733,7 @@ static int dag_activate(pcap_t* handle)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (device == NULL) {
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -631,26 +742,26 @@ static int dag_activate(pcap_t* handle)
|
||||||
#ifdef HAVE_DAG_STREAMS_API
|
#ifdef HAVE_DAG_STREAMS_API
|
||||||
newDev = (char *)malloc(strlen(device) + 16);
|
newDev = (char *)malloc(strlen(device) + 16);
|
||||||
if (newDev == NULL) {
|
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;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parse input name to get dag device and stream number if provided */
|
/* 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) {
|
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;
|
goto fail;
|
||||||
}
|
}
|
||||||
device = newDev;
|
device = newDev;
|
||||||
|
|
||||||
if (handlep->dag_stream%2) {
|
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;
|
goto fail;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if (strncmp(device, "/dev/", 5) != 0) {
|
if (strncmp(device, "/dev/", 5) != 0) {
|
||||||
newDev = (char *)malloc(strlen(device) + 5);
|
newDev = (char *)malloc(strlen(device) + 5);
|
||||||
if (newDev == NULL) {
|
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;
|
goto fail;
|
||||||
}
|
}
|
||||||
strcpy(newDev, "/dev/");
|
strcpy(newDev, "/dev/");
|
||||||
|
@ -661,14 +772,14 @@ static int dag_activate(pcap_t* handle)
|
||||||
|
|
||||||
/* setup device parameters */
|
/* setup device parameters */
|
||||||
if((handle->fd = dag_open((char *)device)) < 0) {
|
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;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_DAG_STREAMS_API
|
#ifdef HAVE_DAG_STREAMS_API
|
||||||
/* Open requested stream. Can fail if already locked or on error */
|
/* Open requested stream. Can fail if already locked or on error */
|
||||||
if (dag_attach_stream(handle->fd, handlep->dag_stream, 0, 0) < 0) {
|
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;
|
goto failclose;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -677,10 +788,10 @@ static int dag_activate(pcap_t* handle)
|
||||||
*/
|
*/
|
||||||
if (dag_get_stream_poll(handle->fd, handlep->dag_stream,
|
if (dag_get_stream_poll(handle->fd, handlep->dag_stream,
|
||||||
&mindata, &maxwait, &poll) < 0) {
|
&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;
|
goto faildetach;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (handle->opt.immediate) {
|
if (handle->opt.immediate) {
|
||||||
/* Call callback immediately.
|
/* Call callback immediately.
|
||||||
* XXX - is this the right way to handle this?
|
* 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,
|
if (dag_set_stream_poll(handle->fd, handlep->dag_stream,
|
||||||
mindata, &maxwait, &poll) < 0) {
|
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;
|
goto faildetach;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
if((handlep->dag_mem_base = dag_mmap(handle->fd)) == MAP_FAILED) {
|
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;
|
goto failclose;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -728,22 +839,22 @@ static int dag_activate(pcap_t* handle)
|
||||||
handle->snapshot = MIN_DAG_SNAPLEN;
|
handle->snapshot = MIN_DAG_SNAPLEN;
|
||||||
}
|
}
|
||||||
/* snap len has to be a multiple of 4 */
|
/* 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) {
|
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;
|
goto faildetach;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_DAG_STREAMS_API
|
#ifdef HAVE_DAG_STREAMS_API
|
||||||
if(dag_start_stream(handle->fd, handlep->dag_stream) < 0) {
|
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;
|
goto faildetach;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if(dag_start(handle->fd) < 0) {
|
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;
|
goto failclose;
|
||||||
}
|
}
|
||||||
#endif /* HAVE_DAG_STREAMS_API */
|
#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) {
|
if ((n = atoi(s)) == 0 || n == 16 || n == 32) {
|
||||||
handlep->dag_fcs_bits = n;
|
handlep->dag_fcs_bits = n;
|
||||||
} else {
|
} else {
|
||||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||||
"pcap_activate %s: bad ERF_FCS_BITS value (%d) in environment\n", device, n);
|
"pcap_activate %s: bad ERF_FCS_BITS value (%d) in environment", device, n);
|
||||||
goto failstop;
|
goto failstop;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -802,11 +913,11 @@ static int dag_activate(pcap_t* handle)
|
||||||
handle->linktype = -1;
|
handle->linktype = -1;
|
||||||
if (dag_get_datalink(handle) < 0)
|
if (dag_get_datalink(handle) < 0)
|
||||||
goto failstop;
|
goto failstop;
|
||||||
|
|
||||||
handle->bufsize = 0;
|
handle->bufsize = 0;
|
||||||
|
|
||||||
if (new_pcap_dag(handle) < 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;
|
goto failstop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -833,12 +944,12 @@ static int dag_activate(pcap_t* handle)
|
||||||
handlep->stat.ps_ifdrop = 0;
|
handlep->stat.ps_ifdrop = 0;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
#ifdef HAVE_DAG_STREAMS_API
|
#ifdef HAVE_DAG_STREAMS_API
|
||||||
failstop:
|
failstop:
|
||||||
if (dag_stop_stream(handle->fd, handlep->dag_stream) < 0) {
|
if (dag_stop_stream(handle->fd, handlep->dag_stream) < 0) {
|
||||||
fprintf(stderr,"dag_stop_stream: %s\n", strerror(errno));
|
fprintf(stderr,"dag_stop_stream: %s\n", strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
faildetach:
|
faildetach:
|
||||||
if (dag_detach_stream(handle->fd, handlep->dag_stream) < 0)
|
if (dag_detach_stream(handle->fd, handlep->dag_stream) < 0)
|
||||||
fprintf(stderr,"dag_detach_stream: %s\n", strerror(errno));
|
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)
|
if (dag_stop(handle->fd) < 0)
|
||||||
fprintf(stderr,"dag_stop: %s\n", strerror(errno));
|
fprintf(stderr,"dag_stop: %s\n", strerror(errno));
|
||||||
#endif /* HAVE_DAG_STREAMS_API */
|
#endif /* HAVE_DAG_STREAMS_API */
|
||||||
|
|
||||||
failclose:
|
failclose:
|
||||||
if (dag_close(handle->fd) < 0)
|
if (dag_close(handle->fd) < 0)
|
||||||
fprintf(stderr,"dag_close: %s\n", strerror(errno));
|
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. */
|
/* OK, it's probably ours. */
|
||||||
*is_ours = 1;
|
*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)
|
if (p == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
p->activate_op = dag_activate;
|
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;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -929,9 +1058,9 @@ dag_stats(pcap_t *p, struct pcap_stat *ps) {
|
||||||
*/
|
*/
|
||||||
/*pd->stat.ps_recv = 0;*/
|
/*pd->stat.ps_recv = 0;*/
|
||||||
/*pd->stat.ps_drop = 0;*/
|
/*pd->stat.ps_drop = 0;*/
|
||||||
|
|
||||||
*ps = pd->stat;
|
*ps = pd->stat;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -953,16 +1082,21 @@ dag_findalldevs(pcap_if_t **devlistp, char *errbuf)
|
||||||
char dagname[DAGNAME_BUFSIZE];
|
char dagname[DAGNAME_BUFSIZE];
|
||||||
int dagstream;
|
int dagstream;
|
||||||
int dagfd;
|
int dagfd;
|
||||||
|
dag_card_inf_t *inf;
|
||||||
|
char *description;
|
||||||
|
|
||||||
/* Try all the DAGs 0-DAG_MAX_BOARDS */
|
/* Try all the DAGs 0-DAG_MAX_BOARDS */
|
||||||
for (c = 0; c < DAG_MAX_BOARDS; c++) {
|
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))
|
if (-1 == dag_parse_name(name, dagname, DAGNAME_BUFSIZE, &dagstream))
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
description = NULL;
|
||||||
if ( (dagfd = dag_open(dagname)) >= 0 ) {
|
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.
|
* Failure.
|
||||||
*/
|
*/
|
||||||
|
@ -976,20 +1110,20 @@ dag_findalldevs(pcap_if_t **devlistp, char *errbuf)
|
||||||
if (0 == dag_attach_stream(dagfd, stream, 0, 0)) {
|
if (0 == dag_attach_stream(dagfd, stream, 0, 0)) {
|
||||||
dag_detach_stream(dagfd, stream);
|
dag_detach_stream(dagfd, stream);
|
||||||
|
|
||||||
snprintf(name, 10, "dag%d:%d", c, stream);
|
pcap_snprintf(name, 10, "dag%d:%d", c, stream);
|
||||||
if (pcap_add_if(devlistp, name, 0, NULL, errbuf) == -1) {
|
if (pcap_add_if(devlistp, name, 0, description, errbuf) == -1) {
|
||||||
/*
|
/*
|
||||||
* Failure.
|
* Failure.
|
||||||
*/
|
*/
|
||||||
ret = -1;
|
ret = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
rxstreams--;
|
rxstreams--;
|
||||||
if(rxstreams <= 0) {
|
if(rxstreams <= 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* HAVE_DAG_STREAMS_API */
|
#endif /* HAVE_DAG_STREAMS_API */
|
||||||
dag_close(dagfd);
|
dag_close(dagfd);
|
||||||
|
@ -1049,13 +1183,13 @@ dag_setnonblock(pcap_t *p, int nonblock, char *errbuf)
|
||||||
uint32_t mindata;
|
uint32_t mindata;
|
||||||
struct timeval maxwait;
|
struct timeval maxwait;
|
||||||
struct timeval poll;
|
struct timeval poll;
|
||||||
|
|
||||||
if (dag_get_stream_poll(p->fd, pd->dag_stream,
|
if (dag_get_stream_poll(p->fd, pd->dag_stream,
|
||||||
&mindata, &maxwait, &poll) < 0) {
|
&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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Amount of data to collect in Bytes before calling callbacks.
|
/* Amount of data to collect in Bytes before calling callbacks.
|
||||||
* Important for efficiency, but can introduce latency
|
* Important for efficiency, but can introduce latency
|
||||||
* at low packet rates if to_ms not set!
|
* at low packet rates if to_ms not set!
|
||||||
|
@ -1064,10 +1198,10 @@ dag_setnonblock(pcap_t *p, int nonblock, char *errbuf)
|
||||||
mindata = 0;
|
mindata = 0;
|
||||||
else
|
else
|
||||||
mindata = 65536;
|
mindata = 65536;
|
||||||
|
|
||||||
if (dag_set_stream_poll(p->fd, pd->dag_stream,
|
if (dag_set_stream_poll(p->fd, pd->dag_stream,
|
||||||
mindata, &maxwait, &poll) < 0) {
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1079,7 +1213,7 @@ dag_setnonblock(pcap_t *p, int nonblock, char *errbuf)
|
||||||
}
|
}
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
dag_get_datalink(pcap_t *p)
|
dag_get_datalink(pcap_t *p)
|
||||||
{
|
{
|
||||||
|
@ -1090,7 +1224,7 @@ dag_get_datalink(pcap_t *p)
|
||||||
memset(types, 0, 255);
|
memset(types, 0, 255);
|
||||||
|
|
||||||
if (p->dlt_list == NULL && (p->dlt_list = malloc(255*sizeof(*(p->dlt_list)))) == NULL) {
|
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);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1099,19 +1233,19 @@ dag_get_datalink(pcap_t *p)
|
||||||
#ifdef HAVE_DAG_GET_STREAM_ERF_TYPES
|
#ifdef HAVE_DAG_GET_STREAM_ERF_TYPES
|
||||||
/* Get list of possible ERF types for this card */
|
/* Get list of possible ERF types for this card */
|
||||||
if (dag_get_stream_erf_types(p->fd, pd->dag_stream, types, 255) < 0) {
|
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));
|
pcap_snprintf(p->errbuf, sizeof(p->errbuf), "dag_get_stream_erf_types: %s", pcap_strerror(errno));
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (types[index]) {
|
while (types[index]) {
|
||||||
|
|
||||||
#elif defined HAVE_DAG_GET_ERF_TYPES
|
#elif defined HAVE_DAG_GET_ERF_TYPES
|
||||||
/* Get list of possible ERF types for this card */
|
/* Get list of possible ERF types for this card */
|
||||||
if (dag_get_erf_types(p->fd, types, 255) < 0) {
|
if (dag_get_erf_types(p->fd, types, 255) < 0) {
|
||||||
snprintf(p->errbuf, sizeof(p->errbuf), "dag_get_erf_types: %s", pcap_strerror(errno));
|
pcap_snprintf(p->errbuf, sizeof(p->errbuf), "dag_get_erf_types: %s", pcap_strerror(errno));
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (types[index]) {
|
while (types[index]) {
|
||||||
#else
|
#else
|
||||||
/* Check the type through a dagapi call. */
|
/* Check the type through a dagapi call. */
|
||||||
|
@ -1157,7 +1291,7 @@ dag_get_datalink(pcap_t *p)
|
||||||
p->linktype = DLT_EN10MB;
|
p->linktype = DLT_EN10MB;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TYPE_ATM:
|
case TYPE_ATM:
|
||||||
case TYPE_AAL5:
|
case TYPE_AAL5:
|
||||||
case TYPE_MC_ATM:
|
case TYPE_MC_ATM:
|
||||||
case TYPE_MC_AAL5:
|
case TYPE_MC_AAL5:
|
||||||
|
@ -1215,3 +1349,31 @@ dag_get_datalink(pcap_t *p)
|
||||||
|
|
||||||
return p->linktype;
|
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
|
||||||
|
|
|
@ -10,97 +10,3 @@
|
||||||
|
|
||||||
pcap_t *dag_create(const char *, char *, int *);
|
pcap_t *dag_create(const char *, char *, int *);
|
||||||
int dag_findalldevs(pcap_if_t **devlistp, char *errbuf);
|
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
|
|
||||||
|
|
|
@ -11,8 +11,8 @@
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
* 3. The name of the author may not be used to endorse or promote
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
* products derived from this software without specific prior written
|
* products derived from this software without specific prior written
|
||||||
* permission.
|
* permission.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
* 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);
|
message = dbus_connection_pop_message(handlep->conn);
|
||||||
|
|
||||||
while (!message) {
|
while (!message) {
|
||||||
// XXX handle->opt.timeout = timeout_ms;
|
/* XXX handle->opt.timeout = timeout_ms; */
|
||||||
if (!dbus_connection_read_write(handlep->conn, 100)) {
|
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;
|
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")) {
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,7 +112,7 @@ dbus_write(pcap_t *handle, const void *buf, size_t size)
|
||||||
DBusMessage *msg;
|
DBusMessage *msg;
|
||||||
|
|
||||||
if (!(msg = dbus_message_demarshal(buf, size, &error))) {
|
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);
|
dbus_error_free(&error);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -122,7 +122,7 @@ dbus_write(pcap_t *handle, const void *buf, size_t size)
|
||||||
|
|
||||||
dbus_message_unref(msg);
|
dbus_message_unref(msg);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
dbus_stats(pcap_t *handle, struct pcap_stat *stats)
|
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])
|
#define N_RULES sizeof(rules)/sizeof(rules[0])
|
||||||
|
|
||||||
struct pcap_dbus *handlep = handle->priv;
|
struct pcap_dbus *handlep = handle->priv;
|
||||||
const char *dev = handle->opt.source;
|
const char *dev = handle->opt.device;
|
||||||
|
|
||||||
DBusError error = DBUS_ERROR_INIT;
|
DBusError error = DBUS_ERROR_INIT;
|
||||||
int i;
|
u_int i;
|
||||||
|
|
||||||
if (strcmp(dev, "dbus-system") == 0) {
|
if (strcmp(dev, "dbus-system") == 0) {
|
||||||
if (!(handlep->conn = dbus_bus_get(DBUS_BUS_SYSTEM, &error))) {
|
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);
|
dbus_error_free(&error);
|
||||||
return PCAP_ERROR;
|
return PCAP_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (strcmp(dev, "dbus-session") == 0) {
|
} else if (strcmp(dev, "dbus-session") == 0) {
|
||||||
if (!(handlep->conn = dbus_bus_get(DBUS_BUS_SESSION, &error))) {
|
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);
|
dbus_error_free(&error);
|
||||||
return PCAP_ERROR;
|
return PCAP_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -183,19 +183,19 @@ dbus_activate(pcap_t *handle)
|
||||||
const char *addr = dev + 7;
|
const char *addr = dev + 7;
|
||||||
|
|
||||||
if (!(handlep->conn = dbus_connection_open(addr, &error))) {
|
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);
|
dbus_error_free(&error);
|
||||||
return PCAP_ERROR;
|
return PCAP_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dbus_bus_register(handlep->conn, &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);
|
dbus_error_free(&error);
|
||||||
return PCAP_ERROR;
|
return PCAP_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} 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;
|
return PCAP_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,7 +234,7 @@ dbus_activate(pcap_t *handle)
|
||||||
/* try without eavesdrop */
|
/* try without eavesdrop */
|
||||||
dbus_bus_add_match(handlep->conn, rules[i] + strlen(EAVESDROPPING_RULE), &error);
|
dbus_bus_add_match(handlep->conn, rules[i] + strlen(EAVESDROPPING_RULE), &error);
|
||||||
if (dbus_error_is_set(&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_error_free(&error);
|
||||||
dbus_cleanup(handle);
|
dbus_cleanup(handle);
|
||||||
return PCAP_ERROR;
|
return PCAP_ERROR;
|
||||||
|
@ -250,8 +250,8 @@ dbus_create(const char *device, char *ebuf, int *is_ours)
|
||||||
{
|
{
|
||||||
pcap_t *p;
|
pcap_t *p;
|
||||||
|
|
||||||
if (strcmp(device, "dbus-system") &&
|
if (strcmp(device, "dbus-system") &&
|
||||||
strcmp(device, "dbus-session") &&
|
strcmp(device, "dbus-session") &&
|
||||||
strncmp(device, "dbus://", 7))
|
strncmp(device, "dbus://", 7))
|
||||||
{
|
{
|
||||||
*is_ours = 0;
|
*is_ours = 0;
|
||||||
|
@ -259,7 +259,7 @@ dbus_create(const char *device, char *ebuf, int *is_ours)
|
||||||
}
|
}
|
||||||
|
|
||||||
*is_ours = 1;
|
*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)
|
if (p == NULL)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
|
@ -267,7 +267,7 @@ dbus_create(const char *device, char *ebuf, int *is_ours)
|
||||||
return (p);
|
return (p);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
dbus_findalldevs(pcap_if_t **alldevsp, char *err_str)
|
dbus_findalldevs(pcap_if_t **alldevsp, char *err_str)
|
||||||
{
|
{
|
||||||
if (pcap_add_if(alldevsp, "dbus-system", 0, "D-Bus system bus", err_str) < 0)
|
if (pcap_add_if(alldevsp, "dbus-system", 0, "D-Bus system bus", err_str) < 0)
|
||||||
|
|
|
@ -153,10 +153,12 @@ static void dlpassive(int, char *);
|
||||||
static int dlrawdatareq(int, const u_char *, int);
|
static int dlrawdatareq(int, const u_char *, int);
|
||||||
#endif
|
#endif
|
||||||
static int recv_ack(int, int, const char *, char *, char *, int *);
|
static int recv_ack(int, int, const char *, char *, char *, int *);
|
||||||
static char *dlstrerror(bpf_u_int32);
|
static char *dlstrerror(char *, size_t, bpf_u_int32);
|
||||||
static char *dlprim(bpf_u_int32);
|
static char *dlprim(char *, size_t, bpf_u_int32);
|
||||||
#if defined(HAVE_SOLARIS) && defined(HAVE_SYS_BUFMOD_H)
|
#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
|
#endif
|
||||||
static int send_request(int, char *, int, char *, char *);
|
static int send_request(int, char *, int, char *, char *);
|
||||||
#ifdef HAVE_HPUX9
|
#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 *);
|
static int get_dlpi_ppa(int, const char *, int, char *);
|
||||||
#endif
|
#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
|
* Cast a buffer to "union DL_primitives" without provoking warnings
|
||||||
* from the compiler.
|
* from the compiler.
|
||||||
|
@ -186,6 +180,12 @@ pcap_read_dlpi(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||||
int cc;
|
int cc;
|
||||||
u_char *bp;
|
u_char *bp;
|
||||||
int flags;
|
int flags;
|
||||||
|
bpf_u_int32 ctlbuf[MAXDLBUF];
|
||||||
|
struct strbuf ctl = {
|
||||||
|
MAXDLBUF,
|
||||||
|
0,
|
||||||
|
(char *)ctlbuf
|
||||||
|
};
|
||||||
struct strbuf data;
|
struct strbuf data;
|
||||||
|
|
||||||
flags = 0;
|
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
|
* would be DL_HP_RAWDATA_IND on HP-UX
|
||||||
* if we're in raw mode?
|
* if we're in raw mode?
|
||||||
*/
|
*/
|
||||||
|
ctl.buf = (char *)ctlbuf;
|
||||||
|
ctl.maxlen = MAXDLBUF;
|
||||||
|
ctl.len = 0;
|
||||||
if (getmsg(p->fd, &ctl, &data, &flags) < 0) {
|
if (getmsg(p->fd, &ctl, &data, &flags) < 0) {
|
||||||
/* Don't choke when we get ptraced */
|
/* Don't choke when we get ptraced */
|
||||||
switch (errno) {
|
switch (errno) {
|
||||||
|
@ -230,7 +233,7 @@ pcap_read_dlpi(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||||
}
|
}
|
||||||
cc = data.len;
|
cc = data.len;
|
||||||
} while (cc == 0);
|
} while (cc == 0);
|
||||||
bp = p->buffer + p->offset;
|
bp = (u_char *)p->buffer + p->offset;
|
||||||
} else
|
} else
|
||||||
bp = p->bp;
|
bp = p->bp;
|
||||||
|
|
||||||
|
@ -248,19 +251,19 @@ pcap_inject_dlpi(pcap_t *p, const void *buf, size_t size)
|
||||||
#if defined(DLIOCRAW)
|
#if defined(DLIOCRAW)
|
||||||
ret = write(p->fd, buf, size);
|
ret = write(p->fd, buf, size);
|
||||||
if (ret == -1) {
|
if (ret == -1) {
|
||||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
|
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
|
||||||
pcap_strerror(errno));
|
pcap_strerror(errno));
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
#elif defined(DL_HP_RAWDLS)
|
#elif defined(DL_HP_RAWDLS)
|
||||||
if (pd->send_fd < 0) {
|
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");
|
"send: Output FD couldn't be opened");
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
ret = dlrawdatareq(pd->send_fd, buf, size);
|
ret = dlrawdatareq(pd->send_fd, buf, size);
|
||||||
if (ret == -1) {
|
if (ret == -1) {
|
||||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
|
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
|
||||||
pcap_strerror(errno));
|
pcap_strerror(errno));
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
@ -298,7 +301,7 @@ pcap_inject_dlpi(pcap_t *p, const void *buf, size_t size)
|
||||||
ret = -1;
|
ret = -1;
|
||||||
#endif /* raw mode */
|
#endif /* raw mode */
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef DL_IPATM
|
#ifndef DL_IPATM
|
||||||
#define DL_IPATM 0x12 /* ATM Classical IP interface */
|
#define DL_IPATM 0x12 /* ATM Classical IP interface */
|
||||||
|
@ -331,28 +334,12 @@ pcap_cleanup_dlpi(pcap_t *p)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pcap_activate_dlpi(pcap_t *p)
|
open_dlpi_device(const char *name, int *ppa, char *errbuf)
|
||||||
{
|
{
|
||||||
#ifdef DL_HP_RAWDLS
|
int status;
|
||||||
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];
|
|
||||||
char dname[100];
|
char dname[100];
|
||||||
|
char *cp;
|
||||||
|
int fd;
|
||||||
#ifndef HAVE_DEV_DLPI
|
#ifndef HAVE_DEV_DLPI
|
||||||
char dname2[100];
|
char dname2[100];
|
||||||
#endif
|
#endif
|
||||||
|
@ -361,9 +348,9 @@ pcap_activate_dlpi(pcap_t *p)
|
||||||
/*
|
/*
|
||||||
** Remove any "/dev/" on the front of the device.
|
** Remove any "/dev/" on the front of the device.
|
||||||
*/
|
*/
|
||||||
cp = strrchr(p->opt.source, '/');
|
cp = strrchr(name, '/');
|
||||||
if (cp == NULL)
|
if (cp == NULL)
|
||||||
strlcpy(dname, p->opt.source, sizeof(dname));
|
strlcpy(dname, name, sizeof(dname));
|
||||||
else
|
else
|
||||||
strlcpy(dname, cp + 1, sizeof(dname));
|
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;
|
* 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.
|
* chop off the unit number, so "dname" is just a device type name.
|
||||||
*/
|
*/
|
||||||
cp = split_dname(dname, &ppa, p->errbuf);
|
cp = split_dname(dname, ppa, errbuf);
|
||||||
if (cp == NULL) {
|
if (cp == NULL)
|
||||||
status = PCAP_ERROR_NO_SUCH_DEVICE;
|
return (PCAP_ERROR_NO_SUCH_DEVICE);
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
*cp = '\0';
|
*cp = '\0';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -390,13 +375,137 @@ pcap_activate_dlpi(pcap_t *p)
|
||||||
* device number, rather than hardwiring "/dev/dlpi".
|
* device number, rather than hardwiring "/dev/dlpi".
|
||||||
*/
|
*/
|
||||||
cp = "/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)
|
if (errno == EPERM || errno == EACCES)
|
||||||
status = PCAP_ERROR_PERM_DENIED;
|
status = PCAP_ERROR_PERM_DENIED;
|
||||||
else
|
else
|
||||||
status = PCAP_ERROR;
|
status = PCAP_ERROR;
|
||||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||||
"%s: %s", cp, pcap_strerror(errno));
|
"%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;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -412,101 +521,7 @@ pcap_activate_dlpi(pcap_t *p)
|
||||||
* to open it for reading only and, if that succeeds, just let
|
* to open it for reading only and, if that succeeds, just let
|
||||||
* the send attempts fail.
|
* the send attempts fail.
|
||||||
*/
|
*/
|
||||||
pd->send_fd = open(cp, O_RDWR);
|
pd->send_fd = open("/dev/dlpi", 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;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -627,7 +642,7 @@ pcap_activate_dlpi(pcap_t *p)
|
||||||
*/
|
*/
|
||||||
if (strioctl(p->fd, A_PROMISCON_REQ, 0, NULL) < 0) {
|
if (strioctl(p->fd, A_PROMISCON_REQ, 0, NULL) < 0) {
|
||||||
status = PCAP_ERROR;
|
status = PCAP_ERROR;
|
||||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||||
"A_PROMISCON_REQ: %s", pcap_strerror(errno));
|
"A_PROMISCON_REQ: %s", pcap_strerror(errno));
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
@ -745,7 +760,7 @@ pcap_activate_dlpi(pcap_t *p)
|
||||||
*/
|
*/
|
||||||
if (strioctl(p->fd, DLIOCRAW, 0, NULL) < 0) {
|
if (strioctl(p->fd, DLIOCRAW, 0, NULL) < 0) {
|
||||||
status = PCAP_ERROR;
|
status = PCAP_ERROR;
|
||||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "DLIOCRAW: %s",
|
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "DLIOCRAW: %s",
|
||||||
pcap_strerror(errno));
|
pcap_strerror(errno));
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
@ -763,10 +778,10 @@ pcap_activate_dlpi(pcap_t *p)
|
||||||
** Ask for bugid 1149065.
|
** Ask for bugid 1149065.
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_SOLARIS
|
#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)) &&
|
if (osmajor == 5 && (osminor <= 2 || (osminor == 3 && osmicro < 2)) &&
|
||||||
getenv("BUFMOD_FIXED") == NULL) {
|
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.",
|
"WARNING: bufmod is broken in SunOS %s; ignoring snaplen.",
|
||||||
release);
|
release);
|
||||||
ss = 0;
|
ss = 0;
|
||||||
|
@ -786,7 +801,7 @@ pcap_activate_dlpi(pcap_t *p)
|
||||||
*/
|
*/
|
||||||
if (ioctl(p->fd, I_FLUSH, FLUSHR) != 0) {
|
if (ioctl(p->fd, I_FLUSH, FLUSHR) != 0) {
|
||||||
status = PCAP_ERROR;
|
status = PCAP_ERROR;
|
||||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "FLUSHR: %s",
|
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "FLUSHR: %s",
|
||||||
pcap_strerror(errno));
|
pcap_strerror(errno));
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
@ -841,7 +856,7 @@ split_dname(char *device, int *unitp, char *ebuf)
|
||||||
*/
|
*/
|
||||||
cp = device + strlen(device) - 1;
|
cp = device + strlen(device) - 1;
|
||||||
if (*cp < '0' || *cp > '9') {
|
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);
|
device);
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
@ -853,16 +868,16 @@ split_dname(char *device, int *unitp, char *ebuf)
|
||||||
errno = 0;
|
errno = 0;
|
||||||
unit = strtol(cp, &eos, 10);
|
unit = strtol(cp, &eos, 10);
|
||||||
if (*eos != '\0') {
|
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);
|
return (NULL);
|
||||||
}
|
}
|
||||||
if (errno == ERANGE || unit > INT_MAX) {
|
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);
|
device);
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
if (unit < 0) {
|
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);
|
device);
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
@ -960,6 +975,56 @@ dlpromiscon(pcap_t *p, bpf_u_int32 level)
|
||||||
return (0);
|
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
|
int
|
||||||
pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
|
pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
|
||||||
{
|
{
|
||||||
|
@ -972,7 +1037,15 @@ pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
|
||||||
} buf;
|
} buf;
|
||||||
char baname[2+1+1];
|
char baname[2+1+1];
|
||||||
u_int i;
|
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.
|
* 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) {
|
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));
|
pcap_strerror(errno));
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
for (i = 0; i < buf.nunits; i++) {
|
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)
|
if (pcap_add_if(alldevsp, baname, 0, NULL, errbuf) < 0)
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
@ -1015,7 +1088,7 @@ send_request(int fd, char *ptr, int len, char *what, char *ebuf)
|
||||||
|
|
||||||
flags = 0;
|
flags = 0;
|
||||||
if (putmsg(fd, &ctl, (struct strbuf *) NULL, 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",
|
"send_request: putmsg \"%s\": %s",
|
||||||
what, pcap_strerror(errno));
|
what, pcap_strerror(errno));
|
||||||
return (-1);
|
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;
|
union DL_primitives *dlp;
|
||||||
struct strbuf ctl;
|
struct strbuf ctl;
|
||||||
int flags;
|
int flags;
|
||||||
|
char errmsgbuf[PCAP_ERRBUF_SIZE];
|
||||||
|
char dlprimbuf[64];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Clear out "*uerror", so it's only set for DL_ERROR_ACK/DL_SYSERR,
|
* 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;
|
flags = 0;
|
||||||
if (getmsg(fd, &ctl, (struct strbuf*)NULL, &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));
|
what, pcap_strerror(errno));
|
||||||
return (PCAP_ERROR);
|
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:
|
case DL_SYSERR:
|
||||||
if (uerror != NULL)
|
if (uerror != NULL)
|
||||||
*uerror = dlp->error_ack.dl_unix_errno;
|
*uerror = dlp->error_ack.dl_unix_errno;
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
||||||
"recv_ack: %s: UNIX error - %s",
|
"recv_ack: %s: UNIX error - %s",
|
||||||
what, pcap_strerror(dlp->error_ack.dl_unix_errno));
|
what, pcap_strerror(dlp->error_ack.dl_unix_errno));
|
||||||
if (dlp->error_ack.dl_unix_errno == EPERM ||
|
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;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "recv_ack: %s: %s",
|
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
||||||
what, dlstrerror(dlp->error_ack.dl_errno));
|
"recv_ack: %s: %s", what,
|
||||||
|
dlstrerror(errmsgbuf, sizeof (errmsgbuf), dlp->error_ack.dl_errno));
|
||||||
if (dlp->error_ack.dl_errno == DL_BADPPA)
|
if (dlp->error_ack.dl_errno == DL_BADPPA)
|
||||||
return (PCAP_ERROR_NO_SUCH_DEVICE);
|
return (PCAP_ERROR_NO_SUCH_DEVICE);
|
||||||
else if (dlp->error_ack.dl_errno == DL_ACCESS)
|
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);
|
return (PCAP_ERROR);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
||||||
"recv_ack: %s: Unexpected primitive ack %s",
|
"recv_ack: %s: Unexpected primitive ack %s",
|
||||||
what, dlprim(dlp->dl_primitive));
|
what, dlprim(dlprimbuf, sizeof (dlprimbuf), dlp->dl_primitive));
|
||||||
return (PCAP_ERROR);
|
return (PCAP_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctl.len < size) {
|
if (ctl.len < size) {
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
||||||
"recv_ack: %s: Ack too small (%d < %d)",
|
"recv_ack: %s: Ack too small (%d < %d)",
|
||||||
what, ctl.len, size);
|
what, ctl.len, size);
|
||||||
return (PCAP_ERROR);
|
return (PCAP_ERROR);
|
||||||
|
@ -1102,10 +1178,8 @@ recv_ack(int fd, int size, const char *what, char *bufp, char *ebuf, int *uerror
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *
|
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) {
|
switch (dl_errno) {
|
||||||
|
|
||||||
case DL_ACCESS:
|
case DL_ACCESS:
|
||||||
|
@ -1206,16 +1280,14 @@ dlstrerror(bpf_u_int32 dl_errno)
|
||||||
return ("Pending outstanding connect indications");
|
return ("Pending outstanding connect indications");
|
||||||
|
|
||||||
default:
|
default:
|
||||||
sprintf(errstring, "Error %02x", dl_errno);
|
pcap_snprintf(errbuf, errbufsize, "Error %02x", dl_errno);
|
||||||
return (errstring);
|
return (errbuf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
dlprim(bpf_u_int32 prim)
|
dlprim(char *primbuf, size_t primbufsize, bpf_u_int32 prim)
|
||||||
{
|
{
|
||||||
static char primbuf[80];
|
|
||||||
|
|
||||||
switch (prim) {
|
switch (prim) {
|
||||||
|
|
||||||
case DL_INFO_REQ:
|
case DL_INFO_REQ:
|
||||||
|
@ -1300,7 +1372,8 @@ dlprim(bpf_u_int32 prim)
|
||||||
return ("DL_RESET_CON");
|
return ("DL_RESET_CON");
|
||||||
|
|
||||||
default:
|
default:
|
||||||
(void) sprintf(primbuf, "unknown primitive 0x%x", prim);
|
pcap_snprintf(primbuf, primbufsize, "unknown primitive 0x%x",
|
||||||
|
prim);
|
||||||
return (primbuf);
|
return (primbuf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1412,28 +1485,29 @@ dlrawdatareq(int fd, const u_char *datap, int datalen)
|
||||||
#endif /* DL_HP_RAWDLS */
|
#endif /* DL_HP_RAWDLS */
|
||||||
|
|
||||||
#if defined(HAVE_SOLARIS) && defined(HAVE_SYS_BUFMOD_H)
|
#if defined(HAVE_SOLARIS) && defined(HAVE_SYS_BUFMOD_H)
|
||||||
static char *
|
static void
|
||||||
get_release(bpf_u_int32 *majorp, bpf_u_int32 *minorp, bpf_u_int32 *microp)
|
get_release(char *buf, size_t bufsize, bpf_u_int32 *majorp,
|
||||||
|
bpf_u_int32 *minorp, bpf_u_int32 *microp)
|
||||||
{
|
{
|
||||||
char *cp;
|
char *cp;
|
||||||
static char buf[32];
|
|
||||||
|
|
||||||
*majorp = 0;
|
*majorp = 0;
|
||||||
*minorp = 0;
|
*minorp = 0;
|
||||||
*microp = 0;
|
*microp = 0;
|
||||||
if (sysinfo(SI_RELEASE, buf, sizeof(buf)) < 0)
|
if (sysinfo(SI_RELEASE, buf, bufsize) < 0) {
|
||||||
return ("?");
|
strlcpy(buf, "?", bufsize);
|
||||||
|
return;
|
||||||
|
}
|
||||||
cp = buf;
|
cp = buf;
|
||||||
if (!isdigit((unsigned char)*cp))
|
if (!isdigit((unsigned char)*cp))
|
||||||
return (buf);
|
return;
|
||||||
*majorp = strtol(cp, &cp, 10);
|
*majorp = strtol(cp, &cp, 10);
|
||||||
if (*cp++ != '.')
|
if (*cp++ != '.')
|
||||||
return (buf);
|
return;
|
||||||
*minorp = strtol(cp, &cp, 10);
|
*minorp = strtol(cp, &cp, 10);
|
||||||
if (*cp++ != '.')
|
if (*cp++ != '.')
|
||||||
return (buf);
|
return;
|
||||||
*microp = strtol(cp, &cp, 10);
|
*microp = strtol(cp, &cp, 10);
|
||||||
return (buf);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1521,21 +1595,21 @@ get_dlpi_ppa(register int fd, register const char *device, register int unit,
|
||||||
*/
|
*/
|
||||||
/* get the head first */
|
/* get the head first */
|
||||||
if (getmsg(fd, &ctl, (struct strbuf *)NULL, &flags) < 0) {
|
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));
|
"get_dlpi_ppa: hpppa getmsg: %s", pcap_strerror(errno));
|
||||||
return (PCAP_ERROR);
|
return (PCAP_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
dlp = (dl_hp_ppa_ack_t *)ctl.buf;
|
dlp = (dl_hp_ppa_ack_t *)ctl.buf;
|
||||||
if (dlp->dl_primitive != DL_HP_PPA_ACK) {
|
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",
|
"get_dlpi_ppa: hpppa unexpected primitive ack 0x%x",
|
||||||
(bpf_u_int32)dlp->dl_primitive);
|
(bpf_u_int32)dlp->dl_primitive);
|
||||||
return (PCAP_ERROR);
|
return (PCAP_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctl.len < DL_HP_PPA_ACK_SIZE) {
|
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)",
|
"get_dlpi_ppa: hpppa ack too small (%d < %lu)",
|
||||||
ctl.len, (unsigned long)DL_HP_PPA_ACK_SIZE);
|
ctl.len, (unsigned long)DL_HP_PPA_ACK_SIZE);
|
||||||
return (PCAP_ERROR);
|
return (PCAP_ERROR);
|
||||||
|
@ -1543,7 +1617,7 @@ get_dlpi_ppa(register int fd, register const char *device, register int unit,
|
||||||
|
|
||||||
/* allocate buffer */
|
/* allocate buffer */
|
||||||
if ((ppa_data_buf = (char *)malloc(dlp->dl_length)) == NULL) {
|
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));
|
"get_dlpi_ppa: hpppa malloc: %s", pcap_strerror(errno));
|
||||||
return (PCAP_ERROR);
|
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;
|
ctl.buf = (char *)ppa_data_buf;
|
||||||
/* get the data */
|
/* get the data */
|
||||||
if (getmsg(fd, &ctl, (struct strbuf *)NULL, &flags) < 0) {
|
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));
|
"get_dlpi_ppa: hpppa getmsg: %s", pcap_strerror(errno));
|
||||||
free(ppa_data_buf);
|
free(ppa_data_buf);
|
||||||
return (PCAP_ERROR);
|
return (PCAP_ERROR);
|
||||||
}
|
}
|
||||||
if (ctl.len < dlp->dl_length) {
|
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)",
|
"get_dlpi_ppa: hpppa ack too small (%d < %lu)",
|
||||||
ctl.len, (unsigned long)dlp->dl_length);
|
ctl.len, (unsigned long)dlp->dl_length);
|
||||||
free(ppa_data_buf);
|
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>",
|
* device number of a device with the name "/dev/<dev><unit>",
|
||||||
* if such a device exists, as the old code did.
|
* 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) {
|
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));
|
dname, pcap_strerror(errno));
|
||||||
return (PCAP_ERROR);
|
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) {
|
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);
|
"can't find /dev/dlpi PPA for %s%d", device, unit);
|
||||||
return (PCAP_ERROR_NO_SUCH_DEVICE);
|
return (PCAP_ERROR_NO_SUCH_DEVICE);
|
||||||
}
|
}
|
||||||
if (ip->dl_hdw_state == HDW_DEAD) {
|
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);
|
"%s%d: hardware state: DOWN\n", device, unit);
|
||||||
free(ppa_data_buf);
|
free(ppa_data_buf);
|
||||||
return (PCAP_ERROR);
|
return (PCAP_ERROR);
|
||||||
|
@ -1678,19 +1752,19 @@ get_dlpi_ppa(register int fd, register const char *ifname, register int unit,
|
||||||
if (cp != NULL)
|
if (cp != NULL)
|
||||||
ifname = cp + 1;
|
ifname = cp + 1;
|
||||||
if (nlist(path_vmunix, &nl) < 0) {
|
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);
|
path_vmunix);
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
if (nl[NL_IFNET].n_value == 0) {
|
if (nl[NL_IFNET].n_value == 0) {
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
||||||
"could't find %s kernel symbol",
|
"could't find %s kernel symbol",
|
||||||
nl[NL_IFNET].n_name);
|
nl[NL_IFNET].n_name);
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
kd = open("/dev/kmem", O_RDONLY);
|
kd = open("/dev/kmem", O_RDONLY);
|
||||||
if (kd < 0) {
|
if (kd < 0) {
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "kmem open: %s",
|
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "kmem open: %s",
|
||||||
pcap_strerror(errno));
|
pcap_strerror(errno));
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
@ -1712,7 +1786,7 @@ get_dlpi_ppa(register int fd, register const char *ifname, register int unit,
|
||||||
return (ifnet.if_index);
|
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);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1723,17 +1797,17 @@ dlpi_kread(register int fd, register off_t addr,
|
||||||
register int cc;
|
register int cc;
|
||||||
|
|
||||||
if (lseek(fd, addr, SEEK_SET) < 0) {
|
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));
|
pcap_strerror(errno));
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
cc = read(fd, buf, len);
|
cc = read(fd, buf, len);
|
||||||
if (cc < 0) {
|
if (cc < 0) {
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "read: %s",
|
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "read: %s",
|
||||||
pcap_strerror(errno));
|
pcap_strerror(errno));
|
||||||
return (-1);
|
return (-1);
|
||||||
} else if (cc != len) {
|
} 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);
|
len);
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
@ -1742,14 +1816,14 @@ dlpi_kread(register int fd, register off_t addr,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
pcap_t *
|
pcap_t *
|
||||||
pcap_create_interface(const char *device, char *ebuf)
|
pcap_create_interface(const char *device _U_, char *ebuf)
|
||||||
{
|
{
|
||||||
pcap_t *p;
|
pcap_t *p;
|
||||||
#ifdef DL_HP_RAWDLS
|
#ifdef DL_HP_RAWDLS
|
||||||
struct pcap_dlpi *pd;
|
struct pcap_dlpi *pd;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
p = pcap_create_common(device, ebuf, sizeof (struct pcap_dlpi));
|
p = pcap_create_common(ebuf, sizeof (struct pcap_dlpi));
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of DOS-libpcap
|
* 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
|
* pcap-dos.c: Interface to PKTDRVR, NDIS2 and 32-bit pmode
|
||||||
* network drivers.
|
* network drivers.
|
||||||
|
@ -145,15 +145,15 @@ static struct device *get_device (int fd)
|
||||||
* Private data for capturing on MS-DOS.
|
* Private data for capturing on MS-DOS.
|
||||||
*/
|
*/
|
||||||
struct pcap_dos {
|
struct pcap_dos {
|
||||||
void (*wait_proc)(void); /* call proc while waiting */
|
void (*wait_proc)(void); /* call proc while waiting */
|
||||||
struct pcap_stat stat;
|
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;
|
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)
|
if (p == NULL)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
|
@ -166,9 +166,7 @@ pcap_t *pcap_create_interface (const char *device, char *ebuf)
|
||||||
* network packets.
|
* network packets.
|
||||||
*/
|
*/
|
||||||
static int pcap_activate_dos (pcap_t *pcap)
|
static int pcap_activate_dos (pcap_t *pcap)
|
||||||
{
|
{
|
||||||
struct pcap_dos *pcapd = pcap->priv;
|
|
||||||
|
|
||||||
if (pcap->opt.rfmon) {
|
if (pcap->opt.rfmon) {
|
||||||
/*
|
/*
|
||||||
* No monitor mode on DOS.
|
* No monitor mode on DOS.
|
||||||
|
@ -188,23 +186,26 @@ static int pcap_activate_dos (pcap_t *pcap)
|
||||||
pcap->stats_op = pcap_stats_dos;
|
pcap->stats_op = pcap_stats_dos;
|
||||||
pcap->inject_op = pcap_sendpacket_dos;
|
pcap->inject_op = pcap_sendpacket_dos;
|
||||||
pcap->setfilter_op = pcap_setfilter_dos;
|
pcap->setfilter_op = pcap_setfilter_dos;
|
||||||
pcap->setdirection_op = NULL; /* Not implemented.*/
|
pcap->setdirection_op = NULL; /* Not implemented.*/
|
||||||
pcap->fd = ++ref_count;
|
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 (pcap->fd == 1) /* first time we're called */
|
||||||
{
|
{
|
||||||
if (!init_watt32(pcap, pcap->opt.source, pcap->errbuf) ||
|
if (!init_watt32(pcap, pcap->opt.device, pcap->errbuf) ||
|
||||||
!first_init(pcap->opt.source, pcap->errbuf, pcap->opt.promisc))
|
!first_init(pcap->opt.device, pcap->errbuf, pcap->opt.promisc))
|
||||||
{
|
{
|
||||||
return (PCAP_ERROR);
|
return (PCAP_ERROR);
|
||||||
}
|
}
|
||||||
atexit (close_driver);
|
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,
|
pcap_snprintf (pcap->errbuf, PCAP_ERRBUF_SIZE,
|
||||||
"Cannot use different devices simultaneously "
|
"Cannot use different devices simultaneously "
|
||||||
"(`%s' vs. `%s')", active_dev->name, pcap->opt.source);
|
"(`%s' vs. `%s')", active_dev->name, pcap->opt.device);
|
||||||
return (PCAP_ERROR);
|
return (PCAP_ERROR);
|
||||||
}
|
}
|
||||||
handle_to_device [pcap->fd-1] = active_dev;
|
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_dos *pd = p->priv;
|
||||||
struct pcap_pkthdr pcap;
|
struct pcap_pkthdr pcap;
|
||||||
struct timeval now, expiry = { 0,0 };
|
struct timeval now, expiry = { 0,0 };
|
||||||
BYTE *rx_buf;
|
|
||||||
int rx_len = 0;
|
int rx_len = 0;
|
||||||
|
|
||||||
if (p->opt.timeout > 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)
|
if (dev->peek_rx_buf)
|
||||||
{
|
{
|
||||||
PCAP_ASSERT (dev->release_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
|
else
|
||||||
{
|
{
|
||||||
BYTE buf [ETH_MAX+100]; /* add some margin */
|
rx_len = (*dev->copy_rx_buf) (p->buffer, p->snapshot);
|
||||||
rx_len = (*dev->copy_rx_buf) (buf, p->snapshot);
|
|
||||||
rx_buf = buf;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rx_len > 0) /* got a packet */
|
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;
|
pcap.len = rx_len;
|
||||||
|
|
||||||
if (callback &&
|
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++;
|
filter_count++;
|
||||||
|
|
||||||
|
@ -280,11 +278,11 @@ pcap_read_one (pcap_t *p, pcap_handler callback, u_char *data)
|
||||||
* capture.
|
* capture.
|
||||||
*/
|
*/
|
||||||
gettimeofday2 (&pcap.ts, NULL);
|
gettimeofday2 (&pcap.ts, NULL);
|
||||||
(*callback) (data, &pcap, rx_buf);
|
(*callback) (data, &pcap, p->buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dev->release_rx_buf)
|
if (dev->release_rx_buf)
|
||||||
(*dev->release_rx_buf) (rx_buf);
|
(*dev->release_rx_buf) (p->buffer);
|
||||||
|
|
||||||
if (pcap_pkt_debug > 0)
|
if (pcap_pkt_debug > 0)
|
||||||
{
|
{
|
||||||
|
@ -296,6 +294,18 @@ pcap_read_one (pcap_t *p, pcap_handler callback, u_char *data)
|
||||||
return (1);
|
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
|
/* If not to wait for a packet or pcap_cleanup_dos() called from
|
||||||
* e.g. SIGINT handler, exit loop now.
|
* 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 */
|
kbhit(); /* a real CPU hog */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (p->wait_proc)
|
if (pd->wait_proc)
|
||||||
(*p->wait_proc)(); /* call yield func */
|
(*pd->wait_proc)(); /* call yield func */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rx_len < 0) /* receive error */
|
if (rx_len < 0) /* receive error */
|
||||||
|
@ -330,7 +340,6 @@ pcap_read_one (pcap_t *p, pcap_handler callback, u_char *data)
|
||||||
static int
|
static int
|
||||||
pcap_read_dos (pcap_t *p, int cnt, pcap_handler callback, u_char *data)
|
pcap_read_dos (pcap_t *p, int cnt, pcap_handler callback, u_char *data)
|
||||||
{
|
{
|
||||||
struct pcap_dos *pd = p->priv;
|
|
||||||
int rc, num = 0;
|
int rc, num = 0;
|
||||||
|
|
||||||
while (num <= cnt || PACKET_COUNT_IS_UNLIMITED(cnt))
|
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",
|
strlcpy (p->errbuf, "pktdrvr doesn't have detailed statistics",
|
||||||
PCAP_ERRBUF_SIZE);
|
PCAP_ERRBUF_SIZE);
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
memcpy (se, (*dev->get_stats)(dev), sizeof(*se));
|
memcpy (se, (*dev->get_stats)(dev), sizeof(*se));
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
@ -442,7 +451,7 @@ static void pcap_cleanup_dos (pcap_t *p)
|
||||||
{
|
{
|
||||||
struct pcap_dos *pd;
|
struct pcap_dos *pd;
|
||||||
|
|
||||||
if (p && !exc_occured)
|
if (!exc_occured)
|
||||||
{
|
{
|
||||||
pd = p->priv;
|
pd = p->priv;
|
||||||
if (pcap_stats(p,NULL) < 0)
|
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,
|
int pcap_lookupnet (const char *device, bpf_u_int32 *localnet,
|
||||||
bpf_u_int32 *netmask, char *errbuf)
|
bpf_u_int32 *netmask, char *errbuf)
|
||||||
{
|
{
|
||||||
|
DWORD mask, net;
|
||||||
|
|
||||||
if (!_watt_is_init)
|
if (!_watt_is_init)
|
||||||
{
|
{
|
||||||
strcpy (errbuf, "pcap_open_offline() or pcap_activate() must be "
|
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);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
*netmask = _w32_sin_mask;
|
mask = _w32_sin_mask;
|
||||||
*localnet = my_ip_addr & *netmask;
|
net = my_ip_addr & mask;
|
||||||
if (*localnet == 0)
|
if (net == 0)
|
||||||
{
|
{
|
||||||
if (IN_CLASSA(*netmask))
|
if (IN_CLASSA(*netmask))
|
||||||
*localnet = IN_CLASSA_NET;
|
net = IN_CLASSA_NET;
|
||||||
else if (IN_CLASSB(*netmask))
|
else if (IN_CLASSB(*netmask))
|
||||||
*localnet = IN_CLASSB_NET;
|
net = IN_CLASSB_NET;
|
||||||
else if (IN_CLASSC(*netmask))
|
else if (IN_CLASSC(*netmask))
|
||||||
*localnet = IN_CLASSC_NET;
|
net = IN_CLASSC_NET;
|
||||||
else
|
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);
|
return (-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*localnet = htonl (net);
|
||||||
|
*netmask = htonl (mask);
|
||||||
|
|
||||||
ARGSUSED (device);
|
ARGSUSED (device);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get a list of all interfaces that are present and that we probe okay.
|
* Get a list of all interfaces that are present and that we probe okay.
|
||||||
* Returns -1 on error, 0 otherwise.
|
* 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.
|
* 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 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;
|
struct sockaddr *addr, *netmask, *broadaddr, *dstaddr;
|
||||||
pcap_if_t *devlist = NULL;
|
pcap_if_t *devlist = NULL;
|
||||||
int ret = 0;
|
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)
|
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_1, 0, sizeof(sa_ll_1));
|
||||||
memset (&sa_ll_2, 0, sizeof(sa_ll_2));
|
memset (&sa_ll_2, 0, sizeof(sa_ll_2));
|
||||||
sa_ll_1.sll_family = AF_PACKET;
|
sa_ll_1.sin_family = AF_INET;
|
||||||
sa_ll_2.sll_family = AF_PACKET;
|
sa_ll_2.sin_family = AF_INET;
|
||||||
|
|
||||||
addr = (struct sockaddr*) &sa_ll_1;
|
addr = (struct sockaddr*) &sa_ll_1;
|
||||||
netmask = (struct sockaddr*) &sa_ll_1;
|
netmask = (struct sockaddr*) &sa_ll_1;
|
||||||
dstaddr = (struct sockaddr*) &sa_ll_1;
|
dstaddr = (struct sockaddr*) &sa_ll_1;
|
||||||
broadaddr = (struct sockaddr*) &sa_ll_2;
|
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,
|
if (pcap_add_if(&devlist, dev->name, dev->flags,
|
||||||
dev->long_name, errbuf) < 0)
|
dev->long_name, errbuf) < 0)
|
||||||
|
@ -565,13 +579,15 @@ int pcap_findalldevs (pcap_if_t **alldevsp, char *errbuf)
|
||||||
ret = -1;
|
ret = -1;
|
||||||
break;
|
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,
|
netmask, addr_size, broadaddr, addr_size,
|
||||||
dstaddr, addr_size, errbuf) < 0)
|
dstaddr, addr_size, errbuf) < 0)
|
||||||
{
|
{
|
||||||
ret = -1;
|
ret = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (devlist && ret < 0)
|
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)
|
void pcap_set_wait (pcap_t *p, void (*yield)(void), int wait)
|
||||||
{
|
{
|
||||||
struct pcap_dos *pd;
|
|
||||||
if (p)
|
if (p)
|
||||||
{
|
{
|
||||||
pd = p->priv;
|
struct pcap_dos *pd = p->priv;
|
||||||
pd->wait_proc = yield;
|
|
||||||
p->opt.timeout = wait;
|
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 */
|
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);
|
return (NULL);
|
||||||
}
|
}
|
||||||
probed_dev = dev; /* device is probed okay and may be used */
|
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))
|
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))
|
if (pktInfo.error && !strncmp(dev->name,"pkt",3))
|
||||||
{
|
{
|
||||||
strcat (ebuf, ": ");
|
strcat (ebuf, ": ");
|
||||||
|
@ -679,14 +695,14 @@ open_driver (const char *dev_name, char *ebuf, int promisc)
|
||||||
*/
|
*/
|
||||||
if (!dev)
|
if (!dev)
|
||||||
{
|
{
|
||||||
sprintf (ebuf, "device `%s' not supported", dev_name);
|
pcap_snprintf (ebuf, PCAP_ERRBUF_SIZE, "device `%s' not supported", dev_name);
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
not_probed:
|
not_probed:
|
||||||
if (!probed_dev)
|
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 (NULL);
|
||||||
}
|
}
|
||||||
return (dev);
|
return (dev);
|
||||||
|
@ -756,7 +772,7 @@ static void exc_handler (int sig)
|
||||||
fprintf (stderr, "Catching signal %d.\n", sig);
|
fprintf (stderr, "Catching signal %d.\n", sig);
|
||||||
}
|
}
|
||||||
exc_occured = 1;
|
exc_occured = 1;
|
||||||
pcap_cleanup_dos (NULL);
|
close_driver();
|
||||||
}
|
}
|
||||||
#endif /* __DJGPP__ */
|
#endif /* __DJGPP__ */
|
||||||
|
|
||||||
|
@ -933,7 +949,7 @@ static int init_watt32 (struct pcap *pcap, const char *dev_name, char *err_buf)
|
||||||
if (_watt_is_init)
|
if (_watt_is_init)
|
||||||
sock_exit();
|
sock_exit();
|
||||||
|
|
||||||
env = getenv ("PCAP_DEBUG");
|
env = getenv ("PCAP_TRACE");
|
||||||
if (env && atoi(env) > 0 &&
|
if (env && atoi(env) > 0 &&
|
||||||
pcap_pkt_debug < 0) /* if not already set */
|
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
|
* have default values. Should be taken from another
|
||||||
* ini-file/environment in any case (ref. tcpdump.ini)
|
* 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 .... */
|
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)
|
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);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1053,9 +1069,9 @@ static const struct config_table debug_tab[] = {
|
||||||
* pcap_config_hook() is an extension to application's config
|
* pcap_config_hook() is an extension to application's config
|
||||||
* handling. Uses Watt-32's config-table function.
|
* 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))
|
if (!PktInitDriver(mode))
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
PktResetStatistics (pktInfo.handle);
|
PktResetStatistics (pktInfo.handle);
|
||||||
PktQueueBusy (FALSE);
|
PktQueueBusy (FALSE);
|
||||||
return (1);
|
return (1);
|
||||||
|
@ -1290,7 +1306,7 @@ struct device rtl8139_dev LOCKED_VAR = {
|
||||||
0,0,0,0,0,0,
|
0,0,0,0,0,0,
|
||||||
&cs89_dev,
|
&cs89_dev,
|
||||||
rtl8139_probe /* dev->probe routine */
|
rtl8139_probe /* dev->probe routine */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Dequeue routine is called by polling.
|
* Dequeue routine is called by polling.
|
||||||
|
|
|
@ -214,7 +214,7 @@ extern void _w32_os_yield (void); /* Watt-32's misc.c */
|
||||||
#define PCAP_ASSERT(x) ((void)0)
|
#define PCAP_ASSERT(x) ((void)0)
|
||||||
|
|
||||||
#else
|
#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 { \
|
#define PCAP_ASSERT(x) do { \
|
||||||
if (!(x)) \
|
if (!(x)) \
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||||
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
.\" 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
|
.SH NAME
|
||||||
pcap-filter \- packet filter syntax
|
pcap-filter \- packet filter syntax
|
||||||
.br
|
.br
|
||||||
|
@ -298,7 +298,7 @@ of protocol type \fIprotocol\fP.
|
||||||
\fBicmp\fP, \fBicmp6\fP, \fBigmp\fP, \fBigrp\fP, \fBpim\fP, \fBah\fP,
|
\fBicmp\fP, \fBicmp6\fP, \fBigmp\fP, \fBigrp\fP, \fBpim\fP, \fBah\fP,
|
||||||
\fBesp\fP, \fBvrrp\fP, \fBudp\fP, or \fBtcp\fP.
|
\fBesp\fP, \fBvrrp\fP, \fBudp\fP, or \fBtcp\fP.
|
||||||
Note that the identifiers \fBtcp\fP, \fBudp\fP, and \fBicmp\fP are also
|
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.
|
Note that this primitive does not chase the protocol header chain.
|
||||||
.IP "\fBip6 proto \fIprotocol\fR"
|
.IP "\fBip6 proto \fIprotocol\fR"
|
||||||
True if the packet is an IPv6 packet of protocol type \fIprotocol\fP.
|
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
|
Note these identifiers are also keywords
|
||||||
and must be escaped via backslash (\\).
|
and must be escaped via backslash (\\).
|
||||||
.IP
|
.IP
|
||||||
[In the case of FDDI (e.g., `\fBfddi protocol arp\fR'), Token Ring
|
[In the case of FDDI (e.g., `\fBfddi proto arp\fR'), Token Ring
|
||||||
(e.g., `\fBtr protocol arp\fR'), and IEEE 802.11 wireless LANS (e.g.,
|
(e.g., `\fBtr proto arp\fR'), and IEEE 802.11 wireless LANS (e.g.,
|
||||||
`\fBwlan protocol arp\fR'), for most of those protocols, the
|
`\fBwlan proto arp\fR'), for most of those protocols, the
|
||||||
protocol identification comes from the 802.2 Logical Link Control (LLC)
|
protocol identification comes from the 802.2 Logical Link Control (LLC)
|
||||||
header, which is usually layered on top of the FDDI, Token Ring, or
|
header, which is usually layered on top of the FDDI, Token Ring, or
|
||||||
802.11 header.
|
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
|
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
|
\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 on MPLS hierarchies. Each use of that expression increments the
|
||||||
filter offsets by 4.
|
filter offsets by 4.
|
||||||
.IP
|
.IP
|
||||||
For example:
|
For example:
|
||||||
.in +.5i
|
.in +.5i
|
||||||
|
@ -733,6 +733,22 @@ For example:
|
||||||
.fi
|
.fi
|
||||||
.in -.5i
|
.in -.5i
|
||||||
filters IPv4 protocols encapsulated in PPPoE session id 0x27.
|
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"
|
.IP "\fBiso proto \fIprotocol\fR"
|
||||||
True if the packet is an OSI packet of protocol type \fIprotocol\fP.
|
True if the packet is an OSI packet of protocol type \fIprotocol\fP.
|
||||||
\fIProtocol\fP can be a number or one of the names
|
\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
|
.LP
|
||||||
Primitives may be combined using:
|
Primitives may be combined using:
|
||||||
.IP
|
.IP
|
||||||
A parenthesized group of primitives and operators
|
A parenthesized group of primitives and operators.
|
||||||
(parentheses are special to the Shell and must be escaped).
|
|
||||||
.IP
|
.IP
|
||||||
Negation (`\fB!\fP' or `\fBnot\fP').
|
Negation (`\fB!\fP' or `\fBnot\fP').
|
||||||
.IP
|
.IP
|
||||||
|
|
|
@ -40,14 +40,16 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WIN32
|
#if defined(_WIN32)
|
||||||
#include <Packet32.h>
|
/*
|
||||||
extern CRITICAL_SECTION g_PcapCompileCriticalSection;
|
* Make sure Packet32.h doesn't define BPF structures that we've
|
||||||
#endif /* WIN32 */
|
* probably already defined as a result of including <pcap/pcap.h>.
|
||||||
|
*/
|
||||||
#ifdef MSDOS
|
#define BPF_MAJOR_VERSION
|
||||||
#include <fcntl.h>
|
#include <Packet32.h>
|
||||||
#include <io.h>
|
#elif defined(MSDOS)
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <io.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (defined(_MSC_VER) && (_MSC_VER <= 1200)) /* we are compiling with Visual Studio 6, that doesn't support the LL suffix*/
|
#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
|
#define MAXIMUM_SNAPLEN 262144
|
||||||
|
|
||||||
struct pcap_opt {
|
struct pcap_opt {
|
||||||
char *source;
|
char *device;
|
||||||
int timeout; /* timeout for buffering */
|
int timeout; /* timeout for buffering */
|
||||||
int buffer_size;
|
u_int buffer_size;
|
||||||
int promisc;
|
int promisc;
|
||||||
int rfmon; /* monitor mode */
|
int rfmon; /* monitor mode */
|
||||||
int immediate; /* immediate mode - deliver packets as soon as they arrive */
|
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 (*getnonblock_op_t)(pcap_t *, char *);
|
||||||
typedef int (*setnonblock_op_t)(pcap_t *, int, char *);
|
typedef int (*setnonblock_op_t)(pcap_t *, int, char *);
|
||||||
typedef int (*stats_op_t)(pcap_t *, struct pcap_stat *);
|
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 (*setbuff_op_t)(pcap_t *, int);
|
||||||
typedef int (*setmode_op_t)(pcap_t *, int);
|
typedef int (*setmode_op_t)(pcap_t *, int);
|
||||||
typedef int (*setmintocopy_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
|
#endif
|
||||||
typedef void (*cleanup_op_t)(pcap_t *);
|
typedef void (*cleanup_op_t)(pcap_t *);
|
||||||
|
|
||||||
|
@ -145,24 +155,22 @@ struct pcap {
|
||||||
read_op_t read_op;
|
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 **);
|
int (*next_packet_op)(pcap_t *, struct pcap_pkthdr *, u_char **);
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef _WIN32
|
||||||
ADAPTER *adapter;
|
ADAPTER *adapter;
|
||||||
LPPACKET Packet;
|
|
||||||
int nonblock;
|
|
||||||
#else
|
#else
|
||||||
int fd;
|
int fd;
|
||||||
int selectable_fd;
|
int selectable_fd;
|
||||||
#endif /* WIN32 */
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Read buffer.
|
* Read buffer.
|
||||||
*/
|
*/
|
||||||
int bufsize;
|
u_int bufsize;
|
||||||
u_char *buffer;
|
void *buffer;
|
||||||
u_char *bp;
|
u_char *bp;
|
||||||
int cc;
|
int cc;
|
||||||
|
|
||||||
|
@ -172,7 +180,7 @@ struct pcap {
|
||||||
|
|
||||||
int swapped;
|
int swapped;
|
||||||
FILE *rfile; /* null if live capture, non-null if savefile */
|
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 */
|
struct pcap *next; /* list of open pcaps that need stuff cleared on close */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -199,9 +207,18 @@ struct pcap {
|
||||||
*/
|
*/
|
||||||
u_char *pkt;
|
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. */
|
/* We're accepting only packets in this direction/these directions. */
|
||||||
pcap_direction_t direction;
|
pcap_direction_t direction;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Flags to affect BPF code generation.
|
||||||
|
*/
|
||||||
|
int bpf_codegen_flags;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Placeholder for filter code if bpf not in kernel.
|
* Placeholder for filter code if bpf not in kernel.
|
||||||
*/
|
*/
|
||||||
|
@ -235,19 +252,32 @@ struct pcap {
|
||||||
*/
|
*/
|
||||||
pcap_handler oneshot_callback;
|
pcap_handler oneshot_callback;
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef _WIN32
|
||||||
/*
|
/*
|
||||||
* These are, at least currently, specific to the Win32 NPF
|
* These are, at least currently, specific to the Win32 NPF
|
||||||
* driver.
|
* driver.
|
||||||
*/
|
*/
|
||||||
|
stats_ex_op_t stats_ex_op;
|
||||||
setbuff_op_t setbuff_op;
|
setbuff_op_t setbuff_op;
|
||||||
setmode_op_t setmode_op;
|
setmode_op_t setmode_op;
|
||||||
setmintocopy_op_t setmintocopy_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
|
#endif
|
||||||
cleanup_op_t cleanup_op;
|
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.
|
* This is a timeval as stored in a savefile.
|
||||||
* It has to use the same types everywhere, independent of the actual
|
* It has to use the same types everywhere, independent of the actual
|
||||||
|
@ -328,34 +358,15 @@ struct oneshot_userdata {
|
||||||
pcap_t *pd;
|
pcap_t *pd;
|
||||||
};
|
};
|
||||||
|
|
||||||
int yylex(void);
|
|
||||||
|
|
||||||
#ifndef min
|
#ifndef min
|
||||||
#define min(a, b) ((a) > (b) ? (b) : (a))
|
#define min(a, b) ((a) > (b) ? (b) : (a))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* XXX should these be in pcap.h? */
|
|
||||||
int pcap_offline_read(pcap_t *, int, pcap_handler, u_char *);
|
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>
|
#include <stdarg.h>
|
||||||
|
|
||||||
#if !defined(HAVE_SNPRINTF)
|
#include "portability.h"
|
||||||
#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
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Does the packet count argument to a module's read routine say
|
* 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.
|
* 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_getnonblock_fd(pcap_t *, char *);
|
||||||
int pcap_setnonblock_fd(pcap_t *p, int, char *);
|
int pcap_setnonblock_fd(pcap_t *p, int, char *);
|
||||||
#endif
|
#endif
|
||||||
|
@ -383,38 +394,43 @@ int pcap_setnonblock_fd(pcap_t *p, int, char *);
|
||||||
* by pcap_create routines.
|
* by pcap_create routines.
|
||||||
*/
|
*/
|
||||||
pcap_t *pcap_create_interface(const char *, char *);
|
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 *);
|
int pcap_do_addexit(pcap_t *);
|
||||||
void pcap_add_to_pcaps_to_close(pcap_t *);
|
void pcap_add_to_pcaps_to_close(pcap_t *);
|
||||||
void pcap_remove_from_pcaps_to_close(pcap_t *);
|
void pcap_remove_from_pcaps_to_close(pcap_t *);
|
||||||
void pcap_cleanup_live_common(pcap_t *);
|
void pcap_cleanup_live_common(pcap_t *);
|
||||||
int pcap_not_initialized(pcap_t *);
|
|
||||||
int pcap_check_activated(pcap_t *);
|
int pcap_check_activated(pcap_t *);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Internal interfaces for "pcap_findalldevs()".
|
* 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
|
* "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
|
* "pcap_add_if()" adds an interface to the list of interfaces, for
|
||||||
* use by various "find interfaces" routines.
|
* use by various "find interfaces" routines.
|
||||||
*/
|
*/
|
||||||
int pcap_findalldevs_interfaces(pcap_if_t **, char *);
|
|
||||||
int pcap_platform_finddevs(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 *,
|
#if !defined(_WIN32) && !defined(MSDOS)
|
||||||
size_t, struct sockaddr *, size_t, struct sockaddr *, size_t,
|
int pcap_findalldevs_interfaces(pcap_if_t **, char *,
|
||||||
struct sockaddr *, size_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,
|
int add_addr_to_dev(pcap_if_t *, struct sockaddr *, size_t,
|
||||||
struct sockaddr *, size_t, struct sockaddr *, size_t,
|
struct sockaddr *, size_t, struct sockaddr *, size_t,
|
||||||
struct sockaddr *dstaddr, size_t, char *errbuf);
|
struct sockaddr *dstaddr, size_t, char *errbuf);
|
||||||
int pcap_add_if(pcap_if_t **, const char *, u_int, const char *, char *);
|
int pcap_add_if(pcap_if_t **, const char *, bpf_u_int32, const char *,
|
||||||
struct sockaddr *dup_sockaddr(struct sockaddr *, size_t);
|
char *);
|
||||||
int add_or_find_if(pcap_if_t **, pcap_if_t **, const char *, u_int,
|
int add_or_find_if(pcap_if_t **, pcap_if_t **, const char *, bpf_u_int32,
|
||||||
const char *, char *);
|
const char *, char *);
|
||||||
|
#ifndef _WIN32
|
||||||
|
bpf_u_int32 if_flags_to_pcap_flags(const char *, u_int);
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Internal interfaces for "pcap_open_offline()".
|
* 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 *);
|
void pcap_oneshot(u_char *, const struct pcap_pkthdr *, const u_char *);
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef _WIN32
|
||||||
char *pcap_win32strerror(void);
|
void pcap_win32_err_to_str(DWORD, char *);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int install_bpf_program(pcap_t *, struct bpf_program *);
|
int install_bpf_program(pcap_t *, struct bpf_program *);
|
||||||
|
|
|
@ -106,7 +106,7 @@ pcap_activate_libdlpi(pcap_t *p)
|
||||||
* dlpi_open() will not fail if the underlying link does not support
|
* dlpi_open() will not fail if the underlying link does not support
|
||||||
* passive mode. See dlpi(7P) for details.
|
* 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_SUCCESS) {
|
||||||
if (retv == DLPI_ELINKNAMEINVAL || retv == DLPI_ENOLINK)
|
if (retv == DLPI_ELINKNAMEINVAL || retv == DLPI_ENOLINK)
|
||||||
status = PCAP_ERROR_NO_SUCH_DEVICE;
|
status = PCAP_ERROR_NO_SUCH_DEVICE;
|
||||||
|
@ -115,7 +115,7 @@ pcap_activate_libdlpi(pcap_t *p)
|
||||||
status = PCAP_ERROR_PERM_DENIED;
|
status = PCAP_ERROR_PERM_DENIED;
|
||||||
else
|
else
|
||||||
status = PCAP_ERROR;
|
status = PCAP_ERROR;
|
||||||
pcap_libdlpi_err(p->opt.source, "dlpi_open", retv,
|
pcap_libdlpi_err(p->opt.device, "dlpi_open", retv,
|
||||||
p->errbuf);
|
p->errbuf);
|
||||||
return (status);
|
return (status);
|
||||||
}
|
}
|
||||||
|
@ -133,7 +133,7 @@ pcap_activate_libdlpi(pcap_t *p)
|
||||||
/* Bind with DLPI_ANY_SAP. */
|
/* Bind with DLPI_ANY_SAP. */
|
||||||
if ((retv = dlpi_bind(pd->dlpi_hd, DLPI_ANY_SAP, 0)) != DLPI_SUCCESS) {
|
if ((retv = dlpi_bind(pd->dlpi_hd, DLPI_ANY_SAP, 0)) != DLPI_SUCCESS) {
|
||||||
status = PCAP_ERROR;
|
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;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,7 +187,7 @@ pcap_activate_libdlpi(pcap_t *p)
|
||||||
/* Determine link type. */
|
/* Determine link type. */
|
||||||
if ((retv = dlpi_info(pd->dlpi_hd, &dlinfo, 0)) != DLPI_SUCCESS) {
|
if ((retv = dlpi_info(pd->dlpi_hd, &dlinfo, 0)) != DLPI_SUCCESS) {
|
||||||
status = PCAP_ERROR;
|
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;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -209,7 +209,7 @@ pcap_activate_libdlpi(pcap_t *p)
|
||||||
*/
|
*/
|
||||||
if (ioctl(p->fd, I_FLUSH, FLUSHR) != 0) {
|
if (ioctl(p->fd, I_FLUSH, FLUSHR) != 0) {
|
||||||
status = PCAP_ERROR;
|
status = PCAP_ERROR;
|
||||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "FLUSHR: %s",
|
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "FLUSHR: %s",
|
||||||
pcap_strerror(errno));
|
pcap_strerror(errno));
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
@ -258,13 +258,24 @@ dlpromiscon(pcap_t *p, bpf_u_int32 level)
|
||||||
err = PCAP_ERROR_PERM_DENIED;
|
err = PCAP_ERROR_PERM_DENIED;
|
||||||
else
|
else
|
||||||
err = PCAP_ERROR;
|
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);
|
retv, p->errbuf);
|
||||||
return (err);
|
return (err);
|
||||||
}
|
}
|
||||||
return (0);
|
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
|
* In Solaris, the "standard" mechanism" i.e SIOCGLIFCONF will only find
|
||||||
* network links that are plumbed and are up. dlpi_walk(3DLPI) will 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};
|
linkwalk_t lw = {NULL, 0};
|
||||||
int save_errno;
|
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() for loopback will be added here. */
|
||||||
|
|
||||||
dlpi_walk(list_interfaces, &lw, 0);
|
dlpi_walk(list_interfaces, &lw, 0);
|
||||||
|
|
||||||
if (lw.lw_err != 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));
|
"dlpi_walk: %s", pcap_strerror(lw.lw_err));
|
||||||
retv = -1;
|
retv = -1;
|
||||||
goto done;
|
goto done;
|
||||||
|
@ -337,7 +354,7 @@ pcap_read_libdlpi(pcap_t *p, int count, pcap_handler callback, u_char *user)
|
||||||
}
|
}
|
||||||
|
|
||||||
msglen = p->bufsize;
|
msglen = p->bufsize;
|
||||||
bufp = p->buffer + p->offset;
|
bufp = (u_char *)p->buffer + p->offset;
|
||||||
|
|
||||||
retv = dlpi_recv(pd->dlpi_hd, NULL, NULL, bufp,
|
retv = dlpi_recv(pd->dlpi_hd, NULL, NULL, bufp,
|
||||||
&msglen, -1, NULL);
|
&msglen, -1, NULL);
|
||||||
|
@ -404,16 +421,16 @@ pcap_cleanup_libdlpi(pcap_t *p)
|
||||||
static void
|
static void
|
||||||
pcap_libdlpi_err(const char *linkname, const char *func, int err, char *errbuf)
|
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));
|
func, linkname, dlpi_strerror(err));
|
||||||
}
|
}
|
||||||
|
|
||||||
pcap_t *
|
pcap_t *
|
||||||
pcap_create_interface(const char *device, char *ebuf)
|
pcap_create_interface(const char *device _U_, char *ebuf)
|
||||||
{
|
{
|
||||||
pcap_t *p;
|
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)
|
if (p == NULL)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||||
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
.\" 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
|
.SH NAME
|
||||||
pcap-linktype \- link-layer header types supported by libpcap
|
pcap-linktype \- link-layer header types supported by libpcap
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -11,8 +11,8 @@
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
* 3. The name of the author may not be used to endorse or promote
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
* products derived from this software without specific prior written
|
* products derived from this software without specific prior written
|
||||||
* permission.
|
* permission.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
@ -57,14 +57,14 @@
|
||||||
#include <linux/netfilter/nfnetlink_queue.h>
|
#include <linux/netfilter/nfnetlink_queue.h>
|
||||||
|
|
||||||
/* NOTE: if your program drops privilages after pcap_activate() it WON'T work with nfqueue.
|
/* 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,
|
* Sending any data to nfnetlink socket requires CAP_NET_ADMIN privilages,
|
||||||
* and in nfqueue we need to send verdict reply after recving packet.
|
* and in nfqueue we need to send verdict reply after recving packet.
|
||||||
*
|
*
|
||||||
* In tcpdump you can disable dropping privilages with -Z root
|
* In tcpdump you can disable dropping privilages with -Z root
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "pcap-netfilter-linux.h"
|
#include "pcap-netfilter-linux.h"
|
||||||
|
|
||||||
#define HDR_LENGTH (NLMSG_LENGTH(NLMSG_ALIGN(sizeof(struct nfgenmsg))))
|
#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 {
|
struct pcap_netfilter {
|
||||||
u_int packets_read; /* count of packets read with recvfrom() */
|
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 nfqueue_send_verdict(const pcap_t *handle, u_int16_t group_id, u_int32_t id, u_int32_t verdict);
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
netfilter_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user)
|
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;
|
handle->break_loop = 0;
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
} while ((len == -1) && (errno == EINTR));
|
if(errno == ENOBUFS) handlep->packets_nobufs++;
|
||||||
|
} while ((len == -1) && (errno == EINTR || errno == ENOBUFS));
|
||||||
|
|
||||||
if (len < 0) {
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf = handle->buffer;
|
buf = (unsigned char *)handle->buffer;
|
||||||
while (len >= NLMSG_SPACE(0)) {
|
while ((u_int)len >= NLMSG_SPACE(0)) {
|
||||||
const struct nlmsghdr *nlh = (const struct nlmsghdr *) buf;
|
const struct nlmsghdr *nlh = (const struct nlmsghdr *) buf;
|
||||||
u_int32_t msg_len;
|
u_int32_t msg_len;
|
||||||
nftype_t type = OTHER;
|
nftype_t type = OTHER;
|
||||||
|
|
||||||
if (nlh->nlmsg_len < sizeof(struct nlmsghdr) || len < nlh->nlmsg_len) {
|
if (nlh->nlmsg_len < sizeof(struct nlmsghdr) || (u_int)len < nlh->nlmsg_len) {
|
||||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Message truncated: (got: %d) (nlmsg_len: %u)", len, nlh->nlmsg_len);
|
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Message truncated: (got: %d) (nlmsg_len: %u)", len, nlh->nlmsg_len);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NFNL_SUBSYS_ID(nlh->nlmsg_type) == NFNL_SUBSYS_ULOG &&
|
if (NFNL_SUBSYS_ID(nlh->nlmsg_type) == NFNL_SUBSYS_ULOG &&
|
||||||
NFNL_MSG_TYPE(nlh->nlmsg_type) == NFULNL_MSG_PACKET)
|
NFNL_MSG_TYPE(nlh->nlmsg_type) == NFULNL_MSG_PACKET)
|
||||||
type = NFLOG;
|
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)
|
NFNL_MSG_TYPE(nlh->nlmsg_type) == NFQNL_MSG_PACKET)
|
||||||
type = NFQUEUE;
|
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;
|
const unsigned char *payload = NULL;
|
||||||
struct pcap_pkthdr pkth;
|
struct pcap_pkthdr pkth;
|
||||||
|
|
||||||
const struct nfgenmsg *nfg;
|
const struct nfgenmsg *nfg = NULL;
|
||||||
int id = 0;
|
int id = 0;
|
||||||
|
|
||||||
if (handle->linktype != DLT_NFLOG) {
|
if (handle->linktype != DLT_NFLOG) {
|
||||||
const struct nfattr *payload_attr = NULL;
|
const struct nfattr *payload_attr = NULL;
|
||||||
|
|
||||||
if (nlh->nlmsg_len < HDR_LENGTH) {
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,7 +187,7 @@ netfilter_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_c
|
||||||
|
|
||||||
gettimeofday(&pkth.ts, NULL);
|
gettimeofday(&pkth.ts, NULL);
|
||||||
if (handle->fcode.bf_insns == 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++;
|
handlep->packets_read++;
|
||||||
callback(user, &pkth, payload);
|
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) {
|
if (type == NFQUEUE) {
|
||||||
/* XXX, possible responses: NF_DROP, NF_ACCEPT, NF_STOLEN, NF_QUEUE, NF_REPEAT, NF_STOP */
|
/* 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);
|
msg_len = NLMSG_ALIGN(nlh->nlmsg_len);
|
||||||
if (msg_len > len)
|
if (msg_len > (u_int)len)
|
||||||
msg_len = len;
|
msg_len = (u_int)len;
|
||||||
|
|
||||||
len -= msg_len;
|
len -= msg_len;
|
||||||
buf += 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;
|
struct pcap_netfilter *handlep = handle->priv;
|
||||||
|
|
||||||
stats->ps_recv = handlep->packets_read;
|
stats->ps_recv = handlep->packets_read;
|
||||||
stats->ps_drop = 0;
|
stats->ps_drop = handlep->packets_nobufs;
|
||||||
stats->ps_ifdrop = 0;
|
stats->ps_ifdrop = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -229,9 +235,9 @@ netfilter_stats_linux(pcap_t *handle, struct pcap_stat *stats)
|
||||||
static int
|
static int
|
||||||
netfilter_inject_linux(pcap_t *handle, const void *buf, size_t size)
|
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);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct my_nfattr {
|
struct my_nfattr {
|
||||||
u_int16_t nfa_len;
|
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;
|
struct sockaddr_nl snl;
|
||||||
static unsigned int seq_id;
|
static unsigned int seq_id;
|
||||||
|
|
||||||
if (!seq_id)
|
if (!seq_id)
|
||||||
seq_id = time(NULL);
|
seq_id = time(NULL);
|
||||||
++seq_id;
|
++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 */
|
if (snl.nl_pid != 0 || seq_id != nlh->nlmsg_seq) /* if not from kernel or wrong sequence skip */
|
||||||
continue;
|
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_type == NLMSG_ERROR || (nlh->nlmsg_type == NLMSG_DONE && nlh->nlmsg_flags & NLM_F_MULTI)) {
|
||||||
if (nlh->nlmsg_len < NLMSG_ALIGN(sizeof(struct nlmsgerr))) {
|
if (nlh->nlmsg_len < NLMSG_ALIGN(sizeof(struct nlmsgerr))) {
|
||||||
errno = EBADMSG;
|
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);
|
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)
|
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;
|
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);
|
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)
|
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;
|
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
|
static int
|
||||||
netfilter_activate(pcap_t* handle)
|
netfilter_activate(pcap_t* handle)
|
||||||
{
|
{
|
||||||
const char *dev = handle->opt.source;
|
const char *dev = handle->opt.device;
|
||||||
unsigned short groups[32];
|
unsigned short groups[32];
|
||||||
int group_count = 0;
|
int group_count = 0;
|
||||||
nftype_t type = OTHER;
|
nftype_t type = OTHER;
|
||||||
|
@ -428,7 +434,7 @@ netfilter_activate(pcap_t* handle)
|
||||||
dev += strlen(NFQUEUE_IFACE);
|
dev += strlen(NFQUEUE_IFACE);
|
||||||
type = NFQUEUE;
|
type = NFQUEUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type != OTHER && *dev == ':') {
|
if (type != OTHER && *dev == ':') {
|
||||||
dev++;
|
dev++;
|
||||||
while (*dev) {
|
while (*dev) {
|
||||||
|
@ -436,16 +442,16 @@ netfilter_activate(pcap_t* handle)
|
||||||
char *end_dev;
|
char *end_dev;
|
||||||
|
|
||||||
if (group_count == 32) {
|
if (group_count == 32) {
|
||||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||||
"Maximum 32 netfilter groups! dev: %s",
|
"Maximum 32 netfilter groups! dev: %s",
|
||||||
handle->opt.source);
|
handle->opt.device);
|
||||||
return PCAP_ERROR;
|
return PCAP_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
group_id = strtol(dev, &end_dev, 0);
|
group_id = strtol(dev, &end_dev, 0);
|
||||||
if (end_dev != dev) {
|
if (end_dev != dev) {
|
||||||
if (group_id < 0 || group_id > 65535) {
|
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)",
|
"Netfilter group range from 0 to 65535 (got %ld)",
|
||||||
group_id);
|
group_id);
|
||||||
return PCAP_ERROR;
|
return PCAP_ERROR;
|
||||||
|
@ -461,9 +467,9 @@ netfilter_activate(pcap_t* handle)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == OTHER || *dev) {
|
if (type == OTHER || *dev) {
|
||||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||||
"Can't get netfilter group(s) index from %s",
|
"Can't get netfilter group(s) index from %s",
|
||||||
handle->opt.source);
|
handle->opt.device);
|
||||||
return PCAP_ERROR;
|
return PCAP_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -488,7 +494,7 @@ netfilter_activate(pcap_t* handle)
|
||||||
/* Create netlink socket */
|
/* Create netlink socket */
|
||||||
handle->fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_NETFILTER);
|
handle->fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_NETFILTER);
|
||||||
if (handle->fd < 0) {
|
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;
|
return PCAP_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -506,54 +512,54 @@ netfilter_activate(pcap_t* handle)
|
||||||
|
|
||||||
handle->buffer = malloc(handle->bufsize);
|
handle->buffer = malloc(handle->bufsize);
|
||||||
if (!handle->buffer) {
|
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;
|
goto close_fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == NFLOG) {
|
if (type == NFLOG) {
|
||||||
if (nflog_send_config_cmd(handle, 0, NFULNL_CFG_CMD_PF_UNBIND, AF_INET) < 0) {
|
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;
|
goto close_fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nflog_send_config_cmd(handle, 0, NFULNL_CFG_CMD_PF_BIND, AF_INET) < 0) {
|
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;
|
goto close_fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Bind socket to the nflog groups */
|
/* Bind socket to the nflog groups */
|
||||||
for (i = 0; i < group_count; i++) {
|
for (i = 0; i < group_count; i++) {
|
||||||
if (nflog_send_config_cmd(handle, groups[i], NFULNL_CFG_CMD_BIND, AF_UNSPEC) < 0) {
|
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;
|
goto close_fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nflog_send_config_mode(handle, groups[i], NFULNL_COPY_PACKET, handle->snapshot) < 0) {
|
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;
|
goto close_fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (nfqueue_send_config_cmd(handle, 0, NFQNL_CFG_CMD_PF_UNBIND, AF_INET) < 0) {
|
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;
|
goto close_fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nfqueue_send_config_cmd(handle, 0, NFQNL_CFG_CMD_PF_BIND, AF_INET) < 0) {
|
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;
|
goto close_fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Bind socket to the nfqueue groups */
|
/* Bind socket to the nfqueue groups */
|
||||||
for (i = 0; i < group_count; i++) {
|
for (i = 0; i < group_count; i++) {
|
||||||
if (nfqueue_send_config_cmd(handle, groups[i], NFQNL_CFG_CMD_BIND, AF_UNSPEC) < 0) {
|
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;
|
goto close_fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nfqueue_send_config_mode(handle, groups[i], NFQNL_COPY_PACKET, handle->snapshot) < 0) {
|
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;
|
goto close_fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -572,7 +578,7 @@ netfilter_activate(pcap_t* handle)
|
||||||
* Set the socket buffer size to the specified value.
|
* 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) {
|
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;
|
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? */
|
/* Does it begin with NFLOG_IFACE or NFQUEUE_IFACE? */
|
||||||
if (strncmp(cp, NFLOG_IFACE, sizeof NFLOG_IFACE - 1) == 0)
|
if (strncmp(cp, NFLOG_IFACE, sizeof NFLOG_IFACE - 1) == 0)
|
||||||
cp += sizeof NFLOG_IFACE - 1;
|
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;
|
cp += sizeof NFQUEUE_IFACE - 1;
|
||||||
else {
|
else {
|
||||||
/* Nope, doesn't begin with NFLOG_IFACE nor NFQUEUE_IFACE */
|
/* 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. */
|
/* OK, it's probably ours. */
|
||||||
*is_ours = 1;
|
*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)
|
if (p == NULL)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
|
@ -628,17 +634,17 @@ netfilter_create(const char *device, char *ebuf, int *is_ours)
|
||||||
return (p);
|
return (p);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
netfilter_findalldevs(pcap_if_t **alldevsp, char *err_str)
|
netfilter_findalldevs(pcap_if_t **alldevsp, char *err_str)
|
||||||
{
|
{
|
||||||
int sock;
|
int sock;
|
||||||
|
|
||||||
sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_NETFILTER);
|
sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_NETFILTER);
|
||||||
if (sock < 0) {
|
if (sock < 0) {
|
||||||
/* if netlink is not supported this is not fatal */
|
/* if netlink is not supported this is not fatal */
|
||||||
if (errno == EAFNOSUPPORT || errno == EPROTONOSUPPORT)
|
if (errno == EAFNOSUPPORT || errno == EPROTONOSUPPORT)
|
||||||
return 0;
|
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));
|
errno, pcap_strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,8 +11,8 @@
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
* 3. The name of the author may not be used to endorse or promote
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
* products derived from this software without specific prior written
|
* products derived from this software without specific prior written
|
||||||
* permission.
|
* permission.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
|
1265
contrib/libpcap/pcap-new.c
Normal file
1265
contrib/libpcap/pcap-new.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -114,11 +114,11 @@ pcap_read_nit(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||||
if (cc < 0) {
|
if (cc < 0) {
|
||||||
if (errno == EWOULDBLOCK)
|
if (errno == EWOULDBLOCK)
|
||||||
return (0);
|
return (0);
|
||||||
snprintf(p->errbuf, sizeof(p->errbuf), "pcap_read: %s",
|
pcap_snprintf(p->errbuf, sizeof(p->errbuf), "pcap_read: %s",
|
||||||
pcap_strerror(errno));
|
pcap_strerror(errno));
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
bp = p->buffer;
|
bp = (u_char *)p->buffer;
|
||||||
} else
|
} else
|
||||||
bp = p->bp;
|
bp = p->bp;
|
||||||
|
|
||||||
|
@ -168,7 +168,7 @@ pcap_read_nit(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
snprintf(p->errbuf, sizeof(p->errbuf),
|
pcap_snprintf(p->errbuf, sizeof(p->errbuf),
|
||||||
"bad nit state %d", nh->nh_state);
|
"bad nit state %d", nh->nh_state);
|
||||||
return (-1);
|
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));
|
strncpy(sa.sa_data, device, sizeof(sa.sa_data));
|
||||||
ret = sendto(p->fd, buf, size, 0, &sa, sizeof(sa));
|
ret = sendto(p->fd, buf, size, 0, &sa, sizeof(sa));
|
||||||
if (ret == -1) {
|
if (ret == -1) {
|
||||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
|
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
|
||||||
pcap_strerror(errno));
|
pcap_strerror(errno));
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
nit_setflags(pcap_t *p)
|
nit_setflags(pcap_t *p)
|
||||||
|
@ -249,7 +249,7 @@ nit_setflags(pcap_t *p)
|
||||||
nioc.nioc_flags |= NF_PROMISC;
|
nioc.nioc_flags |= NF_PROMISC;
|
||||||
|
|
||||||
if (ioctl(p->fd, SIOCSNIT, &nioc) < 0) {
|
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));
|
pcap_strerror(errno));
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
@ -280,15 +280,22 @@ pcap_activate_nit(pcap_t *p)
|
||||||
memset(p, 0, sizeof(*p));
|
memset(p, 0, sizeof(*p));
|
||||||
p->fd = fd = socket(AF_NIT, SOCK_RAW, NITPROTO_RAW);
|
p->fd = fd = socket(AF_NIT, SOCK_RAW, NITPROTO_RAW);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||||
"socket: %s", pcap_strerror(errno));
|
"socket: %s", pcap_strerror(errno));
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
snit.snit_family = AF_NIT;
|
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))) {
|
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));
|
"bind: %s: %s", snit.snit_ifname, pcap_strerror(errno));
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
@ -301,7 +308,7 @@ pcap_activate_nit(pcap_t *p)
|
||||||
p->linktype = DLT_EN10MB;
|
p->linktype = DLT_EN10MB;
|
||||||
|
|
||||||
p->bufsize = BUFSPACE;
|
p->bufsize = BUFSPACE;
|
||||||
p->buffer = (u_char *)malloc(p->bufsize);
|
p->buffer = malloc(p->bufsize);
|
||||||
if (p->buffer == NULL) {
|
if (p->buffer == NULL) {
|
||||||
strlcpy(p->errbuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
|
strlcpy(p->errbuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
|
||||||
goto bad;
|
goto bad;
|
||||||
|
@ -348,11 +355,11 @@ pcap_activate_nit(pcap_t *p)
|
||||||
}
|
}
|
||||||
|
|
||||||
pcap_t *
|
pcap_t *
|
||||||
pcap_create_interface(const char *device, char *ebuf)
|
pcap_create_interface(const char *device _U_, char *ebuf)
|
||||||
{
|
{
|
||||||
pcap_t *p;
|
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)
|
if (p == NULL)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
|
@ -360,8 +367,18 @@ pcap_create_interface(const char *device, char *ebuf)
|
||||||
return (p);
|
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
|
int
|
||||||
pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
|
pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
|
||||||
{
|
{
|
||||||
return (0);
|
return (pcap_findalldevs_interfaces(alldevsp, errbuf, can_be_bound));
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
static char nosup[] = "live packet capture not supported on this system";
|
static char nosup[] = "live packet capture not supported on this system";
|
||||||
|
|
||||||
pcap_t *
|
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);
|
(void)strlcpy(ebuf, nosup, PCAP_ERRBUF_SIZE);
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
@ -45,5 +45,9 @@ pcap_create_interface(const char *device, char *ebuf)
|
||||||
int
|
int
|
||||||
pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
|
pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* There are no interfaces on which we can capture.
|
||||||
|
*/
|
||||||
|
*alldevsp = NULL;
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,7 +107,7 @@ pcap_read_pf(pcap_t *pc, int cnt, pcap_handler callback, u_char *user)
|
||||||
#ifdef LBL_ALIGN
|
#ifdef LBL_ALIGN
|
||||||
struct enstamp stamp;
|
struct enstamp stamp;
|
||||||
#endif
|
#endif
|
||||||
register int pad;
|
register u_int pad;
|
||||||
|
|
||||||
again:
|
again:
|
||||||
cc = pc->cc;
|
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);
|
(void)lseek(pc->fd, 0L, SEEK_SET);
|
||||||
goto again;
|
goto again;
|
||||||
}
|
}
|
||||||
snprintf(pc->errbuf, sizeof(pc->errbuf), "pf read: %s",
|
pcap_snprintf(pc->errbuf, sizeof(pc->errbuf), "pf read: %s",
|
||||||
pcap_strerror(errno));
|
pcap_strerror(errno));
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
bp = pc->buffer + pc->offset;
|
bp = (u_char *)pc->buffer + pc->offset;
|
||||||
} else
|
} else
|
||||||
bp = pc->bp;
|
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)) {
|
if (cc < sizeof(*sp)) {
|
||||||
snprintf(pc->errbuf, sizeof(pc->errbuf),
|
pcap_snprintf(pc->errbuf, sizeof(pc->errbuf),
|
||||||
"pf short read (%d)", cc);
|
"pf short read (%d)", cc);
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
@ -172,7 +172,7 @@ pcap_read_pf(pcap_t *pc, int cnt, pcap_handler callback, u_char *user)
|
||||||
#endif
|
#endif
|
||||||
sp = (struct enstamp *)bp;
|
sp = (struct enstamp *)bp;
|
||||||
if (sp->ens_stamplen != sizeof(*sp)) {
|
if (sp->ens_stamplen != sizeof(*sp)) {
|
||||||
snprintf(pc->errbuf, sizeof(pc->errbuf),
|
pcap_snprintf(pc->errbuf, sizeof(pc->errbuf),
|
||||||
"pf short stamplen (%d)",
|
"pf short stamplen (%d)",
|
||||||
sp->ens_stamplen);
|
sp->ens_stamplen);
|
||||||
return (-1);
|
return (-1);
|
||||||
|
@ -232,12 +232,12 @@ pcap_inject_pf(pcap_t *p, const void *buf, size_t size)
|
||||||
|
|
||||||
ret = write(p->fd, buf, size);
|
ret = write(p->fd, buf, size);
|
||||||
if (ret == -1) {
|
if (ret == -1) {
|
||||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
|
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
|
||||||
pcap_strerror(errno));
|
pcap_strerror(errno));
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pcap_stats_pf(pcap_t *p, struct pcap_stat *ps)
|
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
|
* its argument, even though it takes a "char *" rather than a
|
||||||
* "const char *" as its first argument. That appears to be
|
* "const char *" as its first argument. That appears to be
|
||||||
* the case, at least on Digital UNIX 4.0.
|
* 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)
|
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) {
|
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",
|
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;
|
goto bad;
|
||||||
}
|
}
|
||||||
pf->OrigMissed = -1;
|
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)
|
if (p->opt.promisc)
|
||||||
enmode |= ENPROMISC;
|
enmode |= ENPROMISC;
|
||||||
if (ioctl(p->fd, EIOCMBIS, (caddr_t)&enmode) < 0) {
|
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));
|
pcap_strerror(errno));
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
@ -349,13 +352,13 @@ your system may not be properly configured; see the packetfilter(4) man page\n",
|
||||||
#endif
|
#endif
|
||||||
/* set the backlog */
|
/* set the backlog */
|
||||||
if (ioctl(p->fd, EIOCSETW, (caddr_t)&backlog) < 0) {
|
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));
|
pcap_strerror(errno));
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
/* discover interface type */
|
/* discover interface type */
|
||||||
if (ioctl(p->fd, EIOCDEVP, (caddr_t)&devparams) < 0) {
|
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));
|
pcap_strerror(errno));
|
||||||
goto bad;
|
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
|
* framing", there's not much we can do, as that
|
||||||
* doesn't specify a particular type of header.
|
* 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);
|
"unknown data-link type %u", devparams.end_dev_type);
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
@ -450,7 +453,7 @@ your system may not be properly configured; see the packetfilter(4) man page\n",
|
||||||
} else
|
} else
|
||||||
p->fddipad = 0;
|
p->fddipad = 0;
|
||||||
if (ioctl(p->fd, EIOCTRUNCATE, (caddr_t)&p->snapshot) < 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));
|
pcap_strerror(errno));
|
||||||
goto bad;
|
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_Priority = 37; /* anything > 2 */
|
||||||
Filter.enf_FilterLen = 0; /* means "always true" */
|
Filter.enf_FilterLen = 0; /* means "always true" */
|
||||||
if (ioctl(p->fd, EIOCSETF, (caddr_t)&Filter) < 0) {
|
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));
|
pcap_strerror(errno));
|
||||||
goto bad;
|
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_sec = p->opt.timeout / 1000;
|
||||||
timeout.tv_usec = (p->opt.timeout * 1000) % 1000000;
|
timeout.tv_usec = (p->opt.timeout * 1000) % 1000000;
|
||||||
if (ioctl(p->fd, EIOCSRTIMEOUT, (caddr_t)&timeout) < 0) {
|
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));
|
pcap_strerror(errno));
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
p->bufsize = BUFSPACE;
|
p->bufsize = BUFSPACE;
|
||||||
p->buffer = (u_char*)malloc(p->bufsize + p->offset);
|
p->buffer = malloc(p->bufsize + p->offset);
|
||||||
if (p->buffer == NULL) {
|
if (p->buffer == NULL) {
|
||||||
strlcpy(p->errbuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
|
strlcpy(p->errbuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
|
||||||
goto bad;
|
goto bad;
|
||||||
|
@ -503,11 +506,11 @@ your system may not be properly configured; see the packetfilter(4) man page\n",
|
||||||
}
|
}
|
||||||
|
|
||||||
pcap_t *
|
pcap_t *
|
||||||
pcap_create_interface(const char *device, char *ebuf)
|
pcap_create_interface(const char *device _U_, char *ebuf)
|
||||||
{
|
{
|
||||||
pcap_t *p;
|
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)
|
if (p == NULL)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
|
@ -515,10 +518,20 @@ pcap_create_interface(const char *device, char *ebuf)
|
||||||
return (p);
|
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
|
int
|
||||||
pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
|
pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
|
||||||
{
|
{
|
||||||
return (0);
|
return (pcap_findalldevs_interfaces(alldevsp, errbuf, can_be_bound));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -547,7 +560,7 @@ pcap_setfilter_pf(pcap_t *p, struct bpf_program *fp)
|
||||||
* Yes. Try to install the filter.
|
* Yes. Try to install the filter.
|
||||||
*/
|
*/
|
||||||
if (ioctl(p->fd, BIOCSETF, (caddr_t)fp) < 0) {
|
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));
|
"BIOCSETF: %s", pcap_strerror(errno));
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
2127
contrib/libpcap/pcap-rpcap.c
Normal file
2127
contrib/libpcap/pcap-rpcap.c
Normal file
File diff suppressed because it is too large
Load diff
465
contrib/libpcap/pcap-rpcap.h
Normal file
465
contrib/libpcap/pcap-rpcap.h
Normal 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
|
||||||
|
|
|
@ -17,12 +17,12 @@
|
||||||
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||||
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
.\" 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
|
.SH NAME
|
||||||
pcap-savefile \- libpcap savefile format
|
pcap-savefile \- libpcap savefile format
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
NOTE: applications and libraries should, if possible, use libpcap to
|
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,
|
If, in the future, a new file format is supported by libpcap,
|
||||||
applications and libraries using libpcap to read savefiles will be able
|
applications and libraries using libpcap to read savefiles will be able
|
||||||
to read the new format of savefiles, but applications and libraries
|
to read the new format of savefiles, but applications and libraries
|
||||||
|
|
|
@ -194,9 +194,9 @@ septel_inject(pcap_t *handle, const void *buf _U_, size_t size _U_)
|
||||||
* See also pcap(3).
|
* See also pcap(3).
|
||||||
*/
|
*/
|
||||||
static pcap_t *septel_activate(pcap_t* handle) {
|
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->linktype = DLT_MTP2;
|
||||||
|
|
||||||
handle->bufsize = 0;
|
handle->bufsize = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -232,7 +232,7 @@ pcap_t *septel_create(const char *device, char *ebuf, int *is_ours) {
|
||||||
/* OK, it's probably ours. */
|
/* OK, it's probably ours. */
|
||||||
*is_ours = 1;
|
*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)
|
if (p == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
@ -244,9 +244,9 @@ static int septel_stats(pcap_t *p, struct pcap_stat *ps) {
|
||||||
struct pcap_septel *handlep = p->priv;
|
struct pcap_septel *handlep = p->priv;
|
||||||
/*handlep->stat.ps_recv = 0;*/
|
/*handlep->stat.ps_recv = 0;*/
|
||||||
/*handlep->stat.ps_drop = 0;*/
|
/*handlep->stat.ps_drop = 0;*/
|
||||||
|
|
||||||
*ps = handlep->stat;
|
*ps = handlep->stat;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -276,7 +276,7 @@ static int septel_setfilter(pcap_t *p, struct bpf_program *fp) {
|
||||||
/* Make our private copy of the filter */
|
/* Make our private copy of the filter */
|
||||||
|
|
||||||
if (install_bpf_program(p, fp) < 0) {
|
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));
|
"malloc: %s", pcap_strerror(errno));
|
||||||
return -1;
|
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");
|
fprintf(errbuf, PCAP_ERRBUF_SIZE, "Non-blocking mode not supported on Septel devices");
|
||||||
return (-1);
|
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
|
||||||
|
|
|
@ -183,7 +183,7 @@ static int read_client_nbytes(int fd, int count, unsigned char *buf) {
|
||||||
find_unit_by_fd(fd, &chassis, &geoslot, &u);
|
find_unit_by_fd(fd, &chassis, &geoslot, &u);
|
||||||
while (count) {
|
while (count) {
|
||||||
if ((len = recv(fd, buf, count, 0)) <= 0) return -1; /* read in whatever data was sent to us */
|
if ((len = recv(fd, buf, count, 0)) <= 0) return -1; /* read in whatever data was sent to us */
|
||||||
count -= len;
|
count -= len;
|
||||||
buf += len;
|
buf += len;
|
||||||
} /* till we have everything we are looking for */
|
} /* till we have everything we are looking for */
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -208,10 +208,14 @@ static void empty_unit(int chassis, int geoslot) {
|
||||||
|
|
||||||
empty_unit_iface(u);
|
empty_unit_iface(u);
|
||||||
if (u->imsg) { /* then if an inbound message buffer exists */
|
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 */
|
void *bigger_buffer;
|
||||||
if (u->imsg == NULL) { /* oops, realloc call failed */
|
|
||||||
|
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);
|
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();
|
empty_unit_table();
|
||||||
if ((fp = fopen("/etc/hosts", "r")) == NULL) { /* try to open the hosts file and if it fails */
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
while (fgets(buf, MAX_LINE_SIZE-1, fp)) { /* while looping over the file */
|
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 */
|
geoslot = *(ptr2 + 5) - '0'; /* and geo-slot number */
|
||||||
if (chassis < 1 || chassis > MAX_CHASSIS ||
|
if (chassis < 1 || chassis > MAX_CHASSIS ||
|
||||||
geoslot < 1 || geoslot > MAX_GEOSLOT) { /* if the chassis and/or slot numbers appear to be bad... */
|
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 */
|
continue; /* and ignore the entry */
|
||||||
}
|
}
|
||||||
if ((ptr2 = (char *)malloc(strlen(ptr) + 1)) == NULL) {
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
strcpy(ptr2, ptr); /* copy the IP address into our malloc'ed memory */
|
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) {
|
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) {
|
static void unified_IOP_port_name(char *buf, size_t bufsize, const char *proto, unit_t *u, int IOPportnum) {
|
||||||
int portnum;
|
int portnum;
|
||||||
|
|
||||||
portnum = ((u->chassis - 1) * 64) + ((u->geoslot - 1) * 8) + IOPportnum + 1;
|
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) {
|
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)
|
if (has_swapped == 0)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int process_client_data (char *errbuf) { /* returns: -1 = error, 0 = OK */
|
static int process_client_data (char *errbuf) { /* returns: -1 = error, 0 = OK */
|
||||||
int chassis, geoslot;
|
int chassis, geoslot;
|
||||||
unit_t *u;
|
unit_t *u;
|
||||||
|
@ -568,6 +572,7 @@ static int process_client_data (char *errbuf) { /* returns: -1 = error, 0
|
||||||
char *newname;
|
char *newname;
|
||||||
bpf_u_int32 interfaceType;
|
bpf_u_int32 interfaceType;
|
||||||
unsigned char flags;
|
unsigned char flags;
|
||||||
|
void *bigger_buffer;
|
||||||
|
|
||||||
prev_iff = 0;
|
prev_iff = 0;
|
||||||
for (chassis = 0; chassis <= MAX_CHASSIS; chassis++) {
|
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 */
|
ptr = u->imsg; /* point to the start of the msg for this IOP */
|
||||||
while (ptr < (u->imsg + u->len)) {
|
while (ptr < (u->imsg + u->len)) {
|
||||||
if ((iff = malloc(sizeof(pcap_if_t))) == NULL) {
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
memset((char *)iff, 0, sizeof(pcap_if_t)); /* bzero() is deprecated, replaced with memset() */
|
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 (*ptr) { /* if there is a count for the name */
|
||||||
if ((iff->name = malloc(*ptr + 1)) == NULL) { /* get that amount of space */
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
memcpy(iff->name, (ptr + 1), *ptr); /* copy the name into the malloc'ed space */
|
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 (*ptr) { /* if there is a count for the description */
|
||||||
if ((iff->description = malloc(*ptr + 1)) == NULL) { /* get that amount of space */
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
memcpy(iff->description, (ptr + 1), *ptr); /* copy the name into the malloc'ed space */
|
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;
|
prev_addr = 0;
|
||||||
while (address_count--) {
|
while (address_count--) {
|
||||||
if ((addr = malloc(sizeof(pcap_addr_t))) == NULL) {
|
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;
|
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 (iff->addresses == 0) iff->addresses = addr;
|
||||||
if (prev_addr) prev_addr->next = addr; /* insert a forward link */
|
if (prev_addr) prev_addr->next = addr; /* insert a forward link */
|
||||||
if (*ptr) { /* if there is a count for the address */
|
if (*ptr) { /* if there is a count for the address */
|
||||||
if ((s = malloc(sizeof(struct sockaddr_in))) == NULL) { /* get that amount of space */
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
memset((char *)s, 0, sizeof(struct sockaddr_in)); /* bzero() is deprecated, replaced with memset() */
|
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 */
|
ptr++; /* then forwards one more for the 'length of the address' field */
|
||||||
if (*ptr) { /* process any netmask */
|
if (*ptr) { /* process any netmask */
|
||||||
if ((s = malloc(sizeof(struct sockaddr_in))) == NULL) {
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
/* bzero() is deprecated, replaced with memset() */
|
/* bzero() is deprecated, replaced with memset() */
|
||||||
|
@ -651,7 +656,7 @@ static int process_client_data (char *errbuf) { /* returns: -1 = error, 0
|
||||||
ptr++;
|
ptr++;
|
||||||
if (*ptr) { /* process any broadcast address */
|
if (*ptr) { /* process any broadcast address */
|
||||||
if ((s = malloc(sizeof(struct sockaddr_in))) == NULL) {
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
/* bzero() is deprecated, replaced with memset() */
|
/* bzero() is deprecated, replaced with memset() */
|
||||||
|
@ -665,7 +670,7 @@ static int process_client_data (char *errbuf) { /* returns: -1 = error, 0
|
||||||
ptr++;
|
ptr++;
|
||||||
if (*ptr) { /* process any destination address */
|
if (*ptr) { /* process any destination address */
|
||||||
if ((s = malloc(sizeof(struct sockaddr_in))) == NULL) {
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
/* bzero() is deprecated, replaced with memset() */
|
/* bzero() is deprecated, replaced with memset() */
|
||||||
|
@ -682,10 +687,12 @@ static int process_client_data (char *errbuf) { /* returns: -1 = error, 0
|
||||||
prev_iff = iff;
|
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 */
|
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 */
|
bigger_buffer = realloc(iff->name, strlen(newname) + 1));
|
||||||
snprintf(errbuf, PCAP_ERRBUF_SIZE, "realloc: %s", pcap_strerror(errno));
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
iff->name = bigger_buffer;
|
||||||
strcpy(iff->name, newname); /* to this new name */
|
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;
|
iface_t *p;
|
||||||
pcap_if_t *alldevsp;
|
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 (chassis = 0; chassis <= MAX_CHASSIS; chassis++) { /* scan the table... */
|
||||||
for (geoslot = 0; geoslot <= MAX_GEOSLOT; geoslot++) {
|
for (geoslot = 0; geoslot <= MAX_GEOSLOT; geoslot++) {
|
||||||
u = &units[chassis][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) {
|
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");
|
"Setting direction is not supported on ACN adapters");
|
||||||
return -1;
|
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.caplen = ntohl(*(uint32_t *)&packet_header[8]); /* caplen */
|
||||||
pcap_header.len = ntohl(*(uint32_t *)&packet_header[12]); /* len */
|
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 */
|
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 */
|
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->read_op = pcap_read_acn;
|
||||||
handle->stats_op = pcap_stats_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);
|
&handle->linktype);
|
||||||
if (fd == -1)
|
if (fd == -1)
|
||||||
return PCAP_ERROR;
|
return PCAP_ERROR;
|
||||||
|
@ -992,7 +999,7 @@ static int pcap_activate_sita(pcap_t *handle) {
|
||||||
|
|
||||||
handle->buffer = malloc(handle->bufsize + handle->offset);
|
handle->buffer = malloc(handle->bufsize + handle->offset);
|
||||||
if (!handle->buffer) {
|
if (!handle->buffer) {
|
||||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||||
"malloc: %s", pcap_strerror(errno));
|
"malloc: %s", pcap_strerror(errno));
|
||||||
pcap_cleanup_acn(handle);
|
pcap_cleanup_acn(handle);
|
||||||
return PCAP_ERROR;
|
return PCAP_ERROR;
|
||||||
|
@ -1007,13 +1014,36 @@ static int pcap_activate_sita(pcap_t *handle) {
|
||||||
return 0;
|
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;
|
pcap_t *p;
|
||||||
|
|
||||||
p = pcap_create_common(device, ebuf, 0);
|
p = pcap_create_common(ebuf, 0);
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
p->activate_op = pcap_activate_sita;
|
p->activate_op = pcap_activate_sita;
|
||||||
return (p);
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -16,6 +16,9 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include <snf.h>
|
#include <snf.h>
|
||||||
|
#if SNF_VERSION_API >= 0x0003
|
||||||
|
#define SNF_HAVE_INJECT_API
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "pcap-int.h"
|
#include "pcap-int.h"
|
||||||
#include "pcap-snf.h"
|
#include "pcap-snf.h"
|
||||||
|
@ -26,6 +29,9 @@
|
||||||
struct pcap_snf {
|
struct pcap_snf {
|
||||||
snf_handle_t snf_handle; /* opaque device handle */
|
snf_handle_t snf_handle; /* opaque device handle */
|
||||||
snf_ring_t snf_ring; /* opaque device ring 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_timeout;
|
||||||
int snf_boardnum;
|
int snf_boardnum;
|
||||||
};
|
};
|
||||||
|
@ -41,10 +47,11 @@ static int
|
||||||
snf_pcap_stats(pcap_t *p, struct pcap_stat *ps)
|
snf_pcap_stats(pcap_t *p, struct pcap_stat *ps)
|
||||||
{
|
{
|
||||||
struct snf_ring_stats stats;
|
struct snf_ring_stats stats;
|
||||||
|
struct pcap_snf *snfps = p->priv;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if ((rc = snf_ring_getstats(ps->snf_ring, &stats))) {
|
if ((rc = snf_ring_getstats(snfps->snf_ring, &stats))) {
|
||||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "snf_get_stats: %s",
|
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "snf_get_stats: %s",
|
||||||
pcap_strerror(rc));
|
pcap_strerror(rc));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -57,12 +64,12 @@ snf_pcap_stats(pcap_t *p, struct pcap_stat *ps)
|
||||||
static void
|
static void
|
||||||
snf_platform_cleanup(pcap_t *p)
|
snf_platform_cleanup(pcap_t *p)
|
||||||
{
|
{
|
||||||
struct pcap_snf *ps;
|
struct pcap_snf *ps = p->priv;
|
||||||
|
|
||||||
if (p == NULL)
|
|
||||||
return;
|
|
||||||
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_ring_close(ps->snf_ring);
|
||||||
snf_close(ps->snf_handle);
|
snf_close(ps->snf_handle);
|
||||||
pcap_cleanup_live_common(p);
|
pcap_cleanup_live_common(p);
|
||||||
|
@ -96,14 +103,23 @@ snf_setnonblock(pcap_t *p, int nonblock, char *errbuf)
|
||||||
|
|
||||||
static inline
|
static inline
|
||||||
struct timeval
|
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;
|
struct timeval tv;
|
||||||
int32_t rem;
|
long tv_nsec;
|
||||||
|
|
||||||
if (ts_nanosec == 0)
|
if (ts_nanosec == 0)
|
||||||
return (struct timeval) { 0, 0 };
|
return (struct timeval) { 0, 0 };
|
||||||
|
|
||||||
tv.tv_sec = ts_nanosec / _NSEC_PER_SEC;
|
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;
|
return tv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,11 +130,13 @@ snf_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||||
struct pcap_pkthdr hdr;
|
struct pcap_pkthdr hdr;
|
||||||
int i, flags, err, caplen, n;
|
int i, flags, err, caplen, n;
|
||||||
struct snf_recv_req req;
|
struct snf_recv_req req;
|
||||||
|
int nonblock, timeout;
|
||||||
|
|
||||||
if (!p || cnt == 0)
|
if (!p)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
n = 0;
|
n = 0;
|
||||||
|
timeout = ps->snf_timeout;
|
||||||
while (n < cnt || PACKET_COUNT_IS_UNLIMITED(cnt)) {
|
while (n < cnt || PACKET_COUNT_IS_UNLIMITED(cnt)) {
|
||||||
/*
|
/*
|
||||||
* Has "pcap_breakloop()" been called?
|
* 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) {
|
||||||
if (err == EBUSY || err == EAGAIN)
|
if (err == EBUSY || err == EAGAIN) {
|
||||||
return (0);
|
return (n);
|
||||||
if (err == EINTR)
|
}
|
||||||
|
else if (err == EINTR) {
|
||||||
|
timeout = 0;
|
||||||
continue;
|
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));
|
pcap_strerror(err));
|
||||||
return -1;
|
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) ||
|
if ((p->fcode.bf_insns == NULL) ||
|
||||||
bpf_filter(p->fcode.bf_insns, req.pkt_addr, req.length, caplen)) {
|
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.caplen = caplen;
|
||||||
hdr.len = req.length;
|
hdr.len = req.length;
|
||||||
callback(user, &hdr, req.pkt_addr);
|
callback(user, &hdr, req.pkt_addr);
|
||||||
}
|
}
|
||||||
n++;
|
n++;
|
||||||
|
|
||||||
|
/* After one successful packet is received, we won't block
|
||||||
|
* again for that timeout. */
|
||||||
|
if (timeout != 0)
|
||||||
|
timeout = 0;
|
||||||
}
|
}
|
||||||
return (n);
|
return (n);
|
||||||
}
|
}
|
||||||
|
@ -184,30 +210,55 @@ snf_setfilter(pcap_t *p, struct bpf_program *fp)
|
||||||
static int
|
static int
|
||||||
snf_inject(pcap_t *p, const void *buf _U_, size_t size _U_)
|
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);
|
PCAP_ERRBUF_SIZE);
|
||||||
return (-1);
|
return (-1);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
snf_activate(pcap_t* p)
|
snf_activate(pcap_t* p)
|
||||||
{
|
{
|
||||||
struct pcap_snf *ps = p->priv;
|
struct pcap_snf *ps = p->priv;
|
||||||
char *device = p->opt.source;
|
char *device = p->opt.device;
|
||||||
const char *nr = NULL;
|
const char *nr = NULL;
|
||||||
int err;
|
int err;
|
||||||
int flags = 0;
|
int flags = -1, ring_id = -1;
|
||||||
|
|
||||||
if (device == NULL) {
|
if (device == NULL) {
|
||||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||||
"device is NULL: %s", pcap_strerror(errno));
|
"device is NULL: %s", pcap_strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* In Libpcap, we set pshared by default if NUM_RINGS is set to > 1.
|
/* In Libpcap, we set pshared by default if NUM_RINGS is set to > 1.
|
||||||
* Since libpcap isn't thread-safe */
|
* Since libpcap isn't thread-safe */
|
||||||
if ((nr = getenv("SNF_NUM_RINGS")) && *nr && atoi(nr) > 1)
|
if ((nr = getenv("SNF_FLAGS")) && *nr)
|
||||||
flags |= SNF_F_PSHARED;
|
flags = strtol(nr, NULL, 0);
|
||||||
|
else if ((nr = getenv("SNF_NUM_RINGS")) && *nr && atoi(nr) > 1)
|
||||||
|
flags = SNF_F_PSHARED;
|
||||||
else
|
else
|
||||||
nr = NULL;
|
nr = NULL;
|
||||||
|
|
||||||
|
@ -218,15 +269,19 @@ snf_activate(pcap_t* p)
|
||||||
flags, /* may want pshared */
|
flags, /* may want pshared */
|
||||||
&ps->snf_handle);
|
&ps->snf_handle);
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||||
"snf_open failed: %s", pcap_strerror(err));
|
"snf_open failed: %s", pcap_strerror(err));
|
||||||
return -1;
|
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) {
|
if (err != 0) {
|
||||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||||
"snf_ring_open failed: %s", pcap_strerror(err));
|
"snf_ring_open_id(ring=%d) failed: %s",
|
||||||
|
ring_id, pcap_strerror(err));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,7 +292,7 @@ snf_activate(pcap_t* p)
|
||||||
|
|
||||||
err = snf_start(ps->snf_handle);
|
err = snf_start(ps->snf_handle);
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||||
"snf_start failed: %s", pcap_strerror(err));
|
"snf_start failed: %s", pcap_strerror(err));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -256,12 +311,104 @@ snf_activate(pcap_t* p)
|
||||||
p->setnonblock_op = snf_setnonblock;
|
p->setnonblock_op = snf_setnonblock;
|
||||||
p->stats_op = snf_pcap_stats;
|
p->stats_op = snf_pcap_stats;
|
||||||
p->cleanup_op = snf_platform_cleanup;
|
p->cleanup_op = snf_platform_cleanup;
|
||||||
|
#ifdef SNF_HAVE_INJECT_API
|
||||||
|
ps->snf_inj = NULL;
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define MAX_DESC_LENGTH 128
|
||||||
int
|
int
|
||||||
snf_findalldevs(pcap_if_t **devlistp, char *errbuf)
|
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
|
* There are no platform-specific devices since each device
|
||||||
* exists as a regular Ethernet 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. */
|
/* OK, it's probably ours. */
|
||||||
*is_ours = 1;
|
*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)
|
if (p == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
ps = p->priv;
|
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;
|
p->activate_op = snf_activate;
|
||||||
ps->snf_boardnum = boardnum;
|
ps->snf_boardnum = boardnum;
|
||||||
return p;
|
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
|
||||||
|
|
|
@ -130,11 +130,11 @@ pcap_read_snit(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||||
if (cc < 0) {
|
if (cc < 0) {
|
||||||
if (errno == EWOULDBLOCK)
|
if (errno == EWOULDBLOCK)
|
||||||
return (0);
|
return (0);
|
||||||
snprintf(p->errbuf, sizeof(p->errbuf), "pcap_read: %s",
|
pcap_snprintf(p->errbuf, sizeof(p->errbuf), "pcap_read: %s",
|
||||||
pcap_strerror(errno));
|
pcap_strerror(errno));
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
bp = p->buffer;
|
bp = (u_char *)p->buffer;
|
||||||
} else
|
} else
|
||||||
bp = p->bp;
|
bp = p->bp;
|
||||||
|
|
||||||
|
@ -211,7 +211,7 @@ static int
|
||||||
pcap_inject_snit(pcap_t *p, const void *buf, size_t size)
|
pcap_inject_snit(pcap_t *p, const void *buf, size_t size)
|
||||||
{
|
{
|
||||||
struct strbuf ctl, data;
|
struct strbuf ctl, data;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XXX - can we just do
|
* XXX - can we just do
|
||||||
*
|
*
|
||||||
|
@ -223,7 +223,7 @@ pcap_inject_snit(pcap_t *p, const void *buf, size_t size)
|
||||||
data.len = size;
|
data.len = size;
|
||||||
ret = putmsg(p->fd, &ctl, &data);
|
ret = putmsg(p->fd, &ctl, &data);
|
||||||
if (ret == -1) {
|
if (ret == -1) {
|
||||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
|
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
|
||||||
pcap_strerror(errno));
|
pcap_strerror(errno));
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
@ -247,7 +247,7 @@ nit_setflags(pcap_t *p)
|
||||||
si.ic_len = sizeof(zero);
|
si.ic_len = sizeof(zero);
|
||||||
si.ic_dp = (char *)&zero;
|
si.ic_dp = (char *)&zero;
|
||||||
if (ioctl(p->fd, I_STR, (char *)&si) < 0) {
|
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));
|
pcap_strerror(errno));
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
@ -260,7 +260,7 @@ nit_setflags(pcap_t *p)
|
||||||
si.ic_len = sizeof(timeout);
|
si.ic_len = sizeof(timeout);
|
||||||
si.ic_dp = (char *)&timeout;
|
si.ic_dp = (char *)&timeout;
|
||||||
if (ioctl(p->fd, I_STR, (char *)&si) < 0) {
|
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));
|
pcap_strerror(errno));
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
@ -272,7 +272,7 @@ nit_setflags(pcap_t *p)
|
||||||
si.ic_len = sizeof(flags);
|
si.ic_len = sizeof(flags);
|
||||||
si.ic_dp = (char *)&flags;
|
si.ic_dp = (char *)&flags;
|
||||||
if (ioctl(p->fd, I_STR, (char *)&si) < 0) {
|
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));
|
pcap_strerror(errno));
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
@ -286,7 +286,7 @@ pcap_activate_snit(pcap_t *p)
|
||||||
struct ifreq ifr; /* interface request struct */
|
struct ifreq ifr; /* interface request struct */
|
||||||
int chunksize = CHUNKSIZE;
|
int chunksize = CHUNKSIZE;
|
||||||
int fd;
|
int fd;
|
||||||
static char dev[] = "/dev/nit";
|
static const char dev[] = "/dev/nit";
|
||||||
|
|
||||||
if (p->opt.rfmon) {
|
if (p->opt.rfmon) {
|
||||||
/*
|
/*
|
||||||
|
@ -320,19 +320,19 @@ pcap_activate_snit(pcap_t *p)
|
||||||
if (fd < 0 && errno == EACCES)
|
if (fd < 0 && errno == EACCES)
|
||||||
p->fd = fd = open(dev, O_RDONLY);
|
p->fd = fd = open(dev, O_RDONLY);
|
||||||
if (fd < 0) {
|
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));
|
pcap_strerror(errno));
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* arrange to get discrete messages from the STREAM and use NIT_BUF */
|
/* arrange to get discrete messages from the STREAM and use NIT_BUF */
|
||||||
if (ioctl(fd, I_SRDOPT, (char *)RMSGD) < 0) {
|
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));
|
pcap_strerror(errno));
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
if (ioctl(fd, I_PUSH, "nbuf") < 0) {
|
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));
|
pcap_strerror(errno));
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
@ -342,19 +342,24 @@ pcap_activate_snit(pcap_t *p)
|
||||||
si.ic_len = sizeof(chunksize);
|
si.ic_len = sizeof(chunksize);
|
||||||
si.ic_dp = (char *)&chunksize;
|
si.ic_dp = (char *)&chunksize;
|
||||||
if (ioctl(fd, I_STR, (char *)&si) < 0) {
|
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));
|
pcap_strerror(errno));
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* request the interface */
|
/* 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';
|
ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0';
|
||||||
si.ic_cmd = NIOCBIND;
|
si.ic_cmd = NIOCBIND;
|
||||||
si.ic_len = sizeof(ifr);
|
si.ic_len = sizeof(ifr);
|
||||||
si.ic_dp = (char *)𝔦
|
si.ic_dp = (char *)𝔦
|
||||||
if (ioctl(fd, I_STR, (char *)&si) < 0) {
|
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));
|
ifr.ifr_name, pcap_strerror(errno));
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
@ -364,7 +369,7 @@ pcap_activate_snit(pcap_t *p)
|
||||||
si.ic_len = sizeof(p->snapshot);
|
si.ic_len = sizeof(p->snapshot);
|
||||||
si.ic_dp = (char *)&p->snapshot;
|
si.ic_dp = (char *)&p->snapshot;
|
||||||
if (ioctl(fd, I_STR, (char *)&si) < 0) {
|
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));
|
pcap_strerror(errno));
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
@ -378,7 +383,7 @@ pcap_activate_snit(pcap_t *p)
|
||||||
p->linktype = DLT_EN10MB;
|
p->linktype = DLT_EN10MB;
|
||||||
|
|
||||||
p->bufsize = BUFSPACE;
|
p->bufsize = BUFSPACE;
|
||||||
p->buffer = (u_char *)malloc(p->bufsize);
|
p->buffer = malloc(p->bufsize);
|
||||||
if (p->buffer == NULL) {
|
if (p->buffer == NULL) {
|
||||||
strlcpy(p->errbuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
|
strlcpy(p->errbuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
|
||||||
goto bad;
|
goto bad;
|
||||||
|
@ -426,11 +431,11 @@ pcap_activate_snit(pcap_t *p)
|
||||||
}
|
}
|
||||||
|
|
||||||
pcap_t *
|
pcap_t *
|
||||||
pcap_create_interface(const char *device, char *ebuf)
|
pcap_create_interface(const char *device _U_, char *ebuf)
|
||||||
{
|
{
|
||||||
pcap_t *p;
|
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)
|
if (p == NULL)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
|
@ -438,8 +443,18 @@ pcap_create_interface(const char *device, char *ebuf)
|
||||||
return (p);
|
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
|
int
|
||||||
pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
|
pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
|
||||||
{
|
{
|
||||||
return (0);
|
return (pcap_findalldevs_interfaces(alldevsp, errbuf, can_be_bound));
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,7 +95,7 @@ pcap_read_snoop(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||||
case EWOULDBLOCK:
|
case EWOULDBLOCK:
|
||||||
return (0); /* XXX */
|
return (0); /* XXX */
|
||||||
}
|
}
|
||||||
snprintf(p->errbuf, sizeof(p->errbuf),
|
pcap_snprintf(p->errbuf, sizeof(p->errbuf),
|
||||||
"read: %s", pcap_strerror(errno));
|
"read: %s", pcap_strerror(errno));
|
||||||
return (-1);
|
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;
|
caplen = (datalen < p->snapshot) ? datalen : p->snapshot;
|
||||||
cp = (u_char *)(sh + 1) + p->offset; /* XXX */
|
cp = (u_char *)(sh + 1) + p->offset; /* XXX */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XXX unfortunately snoop loopback isn't exactly like
|
* XXX unfortunately snoop loopback isn't exactly like
|
||||||
* BSD's. The address family is encoded in the first 2
|
* BSD's. The address family is encoded in the first 2
|
||||||
* bytes rather than the first 4 bytes! Luckily the last
|
* 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);
|
ret = write(p->fd, buf, size);
|
||||||
if (ret == -1) {
|
if (ret == -1) {
|
||||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
|
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
|
||||||
pcap_strerror(errno));
|
pcap_strerror(errno));
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pcap_stats_snoop(pcap_t *p, struct pcap_stat *ps)
|
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;
|
rs = &rawstats;
|
||||||
memset(rs, 0, sizeof(*rs));
|
memset(rs, 0, sizeof(*rs));
|
||||||
if (ioctl(p->fd, SIOCRAWSTATS, (char *)rs) < 0) {
|
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));
|
"SIOCRAWSTATS: %s", pcap_strerror(errno));
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
@ -212,22 +212,29 @@ pcap_activate_snoop(pcap_t *p)
|
||||||
|
|
||||||
fd = socket(PF_RAW, SOCK_RAW, RAWPROTO_SNOOP);
|
fd = socket(PF_RAW, SOCK_RAW, RAWPROTO_SNOOP);
|
||||||
if (fd < 0) {
|
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));
|
pcap_strerror(errno));
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
p->fd = fd;
|
p->fd = fd;
|
||||||
memset(&sr, 0, sizeof(sr));
|
memset(&sr, 0, sizeof(sr));
|
||||||
sr.sr_family = AF_RAW;
|
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))) {
|
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));
|
pcap_strerror(errno));
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
memset(&sf, 0, sizeof(sf));
|
memset(&sf, 0, sizeof(sf));
|
||||||
if (ioctl(fd, SIOCADDSNOOP, &sf) < 0) {
|
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));
|
pcap_strerror(errno));
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
@ -239,19 +246,19 @@ pcap_activate_snoop(pcap_t *p)
|
||||||
/*
|
/*
|
||||||
* XXX hack - map device name to link layer type
|
* XXX hack - map device name to link layer type
|
||||||
*/
|
*/
|
||||||
if (strncmp("et", p->opt.source, 2) == 0 || /* Challenge 10 Mbit */
|
if (strncmp("et", p->opt.device, 2) == 0 || /* Challenge 10 Mbit */
|
||||||
strncmp("ec", p->opt.source, 2) == 0 || /* Indigo/Indy 10 Mbit,
|
strncmp("ec", p->opt.device, 2) == 0 || /* Indigo/Indy 10 Mbit,
|
||||||
O2 10/100 */
|
O2 10/100 */
|
||||||
strncmp("ef", p->opt.source, 2) == 0 || /* O200/2000 10/100 Mbit */
|
strncmp("ef", p->opt.device, 2) == 0 || /* O200/2000 10/100 Mbit */
|
||||||
strncmp("eg", p->opt.source, 2) == 0 || /* Octane/O2xxx/O3xxx Gigabit */
|
strncmp("eg", p->opt.device, 2) == 0 || /* Octane/O2xxx/O3xxx Gigabit */
|
||||||
strncmp("gfe", p->opt.source, 3) == 0 || /* GIO 100 Mbit */
|
strncmp("gfe", p->opt.device, 3) == 0 || /* GIO 100 Mbit */
|
||||||
strncmp("fxp", p->opt.source, 3) == 0 || /* Challenge VME Enet */
|
strncmp("fxp", p->opt.device, 3) == 0 || /* Challenge VME Enet */
|
||||||
strncmp("ep", p->opt.source, 2) == 0 || /* Challenge 8x10 Mbit EPLEX */
|
strncmp("ep", p->opt.device, 2) == 0 || /* Challenge 8x10 Mbit EPLEX */
|
||||||
strncmp("vfe", p->opt.source, 3) == 0 || /* Challenge VME 100Mbit */
|
strncmp("vfe", p->opt.device, 3) == 0 || /* Challenge VME 100Mbit */
|
||||||
strncmp("fa", p->opt.source, 2) == 0 ||
|
strncmp("fa", p->opt.device, 2) == 0 ||
|
||||||
strncmp("qaa", p->opt.source, 3) == 0 ||
|
strncmp("qaa", p->opt.device, 3) == 0 ||
|
||||||
strncmp("cip", p->opt.source, 3) == 0 ||
|
strncmp("cip", p->opt.device, 3) == 0 ||
|
||||||
strncmp("el", p->opt.source, 2) == 0) {
|
strncmp("el", p->opt.device, 2) == 0) {
|
||||||
p->linktype = DLT_EN10MB;
|
p->linktype = DLT_EN10MB;
|
||||||
p->offset = RAW_HDRPAD(sizeof(struct ether_header));
|
p->offset = RAW_HDRPAD(sizeof(struct ether_header));
|
||||||
ll_hdrlen = 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_list[1] = DLT_DOCSIS;
|
||||||
p->dlt_count = 2;
|
p->dlt_count = 2;
|
||||||
}
|
}
|
||||||
} else if (strncmp("ipg", p->opt.source, 3) == 0 ||
|
} else if (strncmp("ipg", p->opt.device, 3) == 0 ||
|
||||||
strncmp("rns", p->opt.source, 3) == 0 || /* O2/200/2000 FDDI */
|
strncmp("rns", p->opt.device, 3) == 0 || /* O2/200/2000 FDDI */
|
||||||
strncmp("xpi", p->opt.source, 3) == 0) {
|
strncmp("xpi", p->opt.device, 3) == 0) {
|
||||||
p->linktype = DLT_FDDI;
|
p->linktype = DLT_FDDI;
|
||||||
p->offset = 3; /* XXX yeah? */
|
p->offset = 3; /* XXX yeah? */
|
||||||
ll_hdrlen = 13;
|
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;
|
p->linktype = DLT_RAW;
|
||||||
ll_hdrlen = 0; /* DLT_RAW meaning "no PPP header, just the IP packet"? */
|
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;
|
p->linktype = DLT_IP_OVER_FC;
|
||||||
ll_hdrlen = 24;
|
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;
|
p->linktype = DLT_RAW;
|
||||||
ll_hdrlen = 0; /* Cray UNICOS/mp pseudo link */
|
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;
|
p->linktype = DLT_NULL;
|
||||||
ll_hdrlen = 4;
|
ll_hdrlen = 4;
|
||||||
} else {
|
} else {
|
||||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||||
"snoop: unknown physical layer type");
|
"snoop: unknown physical layer type");
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
@ -323,9 +330,9 @@ pcap_activate_snoop(pcap_t *p)
|
||||||
* the MTU first and, if that succeeds, trim the snap length
|
* the MTU first and, if that succeeds, trim the snap length
|
||||||
* to be no greater than the MTU.
|
* 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) {
|
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));
|
pcap_strerror(errno));
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
@ -359,21 +366,21 @@ pcap_activate_snoop(pcap_t *p)
|
||||||
if (snooplen < 0)
|
if (snooplen < 0)
|
||||||
snooplen = 0;
|
snooplen = 0;
|
||||||
if (ioctl(fd, SIOCSNOOPLEN, &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));
|
pcap_strerror(errno));
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
v = 1;
|
v = 1;
|
||||||
if (ioctl(fd, SIOCSNOOPING, &v) < 0) {
|
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));
|
pcap_strerror(errno));
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
p->bufsize = 4096; /* XXX */
|
p->bufsize = 4096; /* XXX */
|
||||||
p->buffer = (u_char *)malloc(p->bufsize);
|
p->buffer = malloc(p->bufsize);
|
||||||
if (p->buffer == NULL) {
|
if (p->buffer == NULL) {
|
||||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "malloc: %s",
|
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "malloc: %s",
|
||||||
pcap_strerror(errno));
|
pcap_strerror(errno));
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
@ -399,11 +406,11 @@ pcap_activate_snoop(pcap_t *p)
|
||||||
}
|
}
|
||||||
|
|
||||||
pcap_t *
|
pcap_t *
|
||||||
pcap_create_interface(const char *device, char *ebuf)
|
pcap_create_interface(const char *device _U_, char *ebuf)
|
||||||
{
|
{
|
||||||
pcap_t *p;
|
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)
|
if (p == NULL)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
|
@ -411,8 +418,18 @@ pcap_create_interface(const char *device, char *ebuf)
|
||||||
return (p);
|
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
|
int
|
||||||
pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
|
pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
|
||||||
{
|
{
|
||||||
return (0);
|
return (pcap_findalldevs_interfaces(alldevsp, errbuf, can_be_bound));
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,35 @@
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* 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
|
#ifndef pcap_stdinc_h
|
||||||
#define pcap_stdinc_h
|
#define pcap_stdinc_h
|
||||||
|
|
||||||
|
@ -45,39 +74,53 @@
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
|
|
||||||
#include "bittypes.h"
|
#include <ws2tcpip.h>
|
||||||
#include "IP6_misc.h"
|
|
||||||
|
|
||||||
#define caddr_t char*
|
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
#define snprintf _snprintf
|
/*
|
||||||
#define vsnprintf _vsnprintf
|
* MSVC.
|
||||||
#define strdup _strdup
|
*/
|
||||||
|
#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
|
#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 */
|
#endif /* pcap_stdinc_h */
|
||||||
|
|
1284
contrib/libpcap/pcap-tc.c
Normal file
1284
contrib/libpcap/pcap-tc.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2009 Felix Obenhuber
|
* Copyright (c) 2008 CACE Technologies, Davis (California)
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* 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
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
* 3. The name of the author may not be used to endorse or promote
|
* 3. Neither the name of CACE Technologies nor the names of its
|
||||||
* products derived from this software without specific prior written
|
* contributors may be used to endorse or promote products derived from
|
||||||
* permission.
|
* this software without specific prior written permission.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
@ -29,9 +29,26 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
#ifndef __PCAP_TC_H__
|
||||||
* Prototypes for SocketCAN related functions
|
#define __PCAP_TC_H__
|
||||||
*/
|
|
||||||
pcap_t* canusb_create(const char *device, char *ebuf, int *is_ours);
|
|
||||||
int canusb_findalldevs(pcap_if_t **pdevlist, char* errbuf);
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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
|
|
@ -19,7 +19,7 @@
|
||||||
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||||
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
.\" 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
|
.SH NAME
|
||||||
pcap-tstamp \- packet time stamps in libpcap
|
pcap-tstamp \- packet time stamps in libpcap
|
||||||
.SH DESCRIPTION
|
.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.
|
synchronized with the host operating system's clock.
|
||||||
.TP 5
|
.TP 5
|
||||||
.BR PCAP_TSTAMP_HOST_LOWPREC " - " host_lowprec
|
.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
|
This is a low-precision time stamp, synchronized with the host operating
|
||||||
system's clock.
|
system's clock.
|
||||||
.TP 5
|
.TP 5
|
||||||
.BR PCAP_TSTAMP_HOST_HIPREC " - " host_hiprec
|
.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
|
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
|
synchronized with the host operating system's clock. It might be more
|
||||||
expensive to fetch than
|
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
|
done. This is a high-precision time stamp; it is not synchronized with
|
||||||
the host operating system's clock.
|
the host operating system's clock.
|
||||||
.RE
|
.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
|
.SH SEE ALSO
|
||||||
pcap_set_tstamp_type(3PCAP),
|
pcap_set_tstamp_type(3PCAP),
|
||||||
pcap_list_tstamp_types(3PCAP),
|
pcap_list_tstamp_types(3PCAP),
|
||||||
pcap_tstamp_type_val_to_name(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)
|
||||||
|
|
|
@ -11,8 +11,8 @@
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
* 3. The name of the author may not be used to endorse or promote
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
* products derived from this software without specific prior written
|
* products derived from this software without specific prior written
|
||||||
* permission.
|
* permission.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
@ -32,7 +32,7 @@
|
||||||
* Modifications: Kris Katterjohn <katterjohn@gmail.com>
|
* Modifications: Kris Katterjohn <katterjohn@gmail.com>
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
@ -139,23 +139,24 @@ static int usb_setdirection_linux(pcap_t *, pcap_direction_t);
|
||||||
static void usb_cleanup_linux_mmap(pcap_t *);
|
static void usb_cleanup_linux_mmap(pcap_t *);
|
||||||
|
|
||||||
/* facility to add an USB device to the device list*/
|
/* 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)
|
usb_dev_add(pcap_if_t** alldevsp, int n, char *err_str)
|
||||||
{
|
{
|
||||||
char dev_name[10];
|
char dev_name[10];
|
||||||
char dev_descr[30];
|
char dev_descr[30];
|
||||||
snprintf(dev_name, 10, USB_IFACE"%d", n);
|
pcap_snprintf(dev_name, 10, USB_IFACE"%d", n);
|
||||||
snprintf(dev_descr, 30, "USB bus number %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)
|
dev_descr, err_str) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
usb_findalldevs(pcap_if_t **alldevsp, char *err_str)
|
usb_findalldevs(pcap_if_t **alldevsp, char *err_str)
|
||||||
{
|
{
|
||||||
|
int fd;
|
||||||
struct dirent* data;
|
struct dirent* data;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
DIR* dir;
|
DIR* dir;
|
||||||
|
@ -163,7 +164,46 @@ usb_findalldevs(pcap_if_t **alldevsp, char *err_str)
|
||||||
char* name;
|
char* name;
|
||||||
size_t len;
|
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);
|
dir = opendir(SYS_USB_BUS_DIR);
|
||||||
if (dir != NULL) {
|
if (dir != NULL) {
|
||||||
while ((ret == 0) && ((data = readdir(dir)) != 0)) {
|
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)
|
if (strncmp(name, "usb", 3) != 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (sscanf(&name[3], "%d", &n) == 0)
|
if (sscanf(&name[3], "%d", &n) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ret = usb_dev_add(alldevsp, n, err_str);
|
ret = usb_dev_add(alldevsp, n, err_str);
|
||||||
|
@ -182,7 +222,7 @@ usb_findalldevs(pcap_if_t **alldevsp, char *err_str)
|
||||||
return ret;
|
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);
|
dir = opendir(PROC_USB_BUS_DIR);
|
||||||
if (dir != NULL) {
|
if (dir != NULL) {
|
||||||
while ((ret == 0) && ((data = readdir(dir)) != 0)) {
|
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]))
|
if ((len < 1) || !isdigit(name[--len]))
|
||||||
continue;
|
continue;
|
||||||
while (isdigit(name[--len]));
|
while (isdigit(name[--len]));
|
||||||
if (sscanf(&name[len+1], "%d", &n) != 1)
|
if (sscanf(&name[len+1], "%d", &n) != 1)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ret = usb_dev_add(alldevsp, n, err_str);
|
ret = usb_dev_add(alldevsp, n, err_str);
|
||||||
|
@ -207,12 +247,12 @@ usb_findalldevs(pcap_if_t **alldevsp, char *err_str)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
int usb_mmap(pcap_t* handle)
|
int usb_mmap(pcap_t* handle)
|
||||||
{
|
{
|
||||||
struct pcap_usb_linux *handlep = handle->priv;
|
struct pcap_usb_linux *handlep = handle->priv;
|
||||||
int len = ioctl(handle->fd, MON_IOCQ_RING_SIZE);
|
int len = ioctl(handle->fd, MON_IOCQ_RING_SIZE);
|
||||||
if (len < 0)
|
if (len < 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
handlep->mmapbuflen = len;
|
handlep->mmapbuflen = len;
|
||||||
|
@ -247,7 +287,7 @@ probe_devices(int bus)
|
||||||
DIR* dir;
|
DIR* dir;
|
||||||
|
|
||||||
/* scan usb bus directories for device nodes */
|
/* 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);
|
dir = opendir(buf);
|
||||||
if (!dir)
|
if (!dir)
|
||||||
return;
|
return;
|
||||||
|
@ -259,8 +299,8 @@ probe_devices(int bus)
|
||||||
if (name[0] == '.')
|
if (name[0] == '.')
|
||||||
continue;
|
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);
|
fd = open(buf, O_RDWR);
|
||||||
if (fd == -1)
|
if (fd == -1)
|
||||||
continue;
|
continue;
|
||||||
|
@ -328,7 +368,7 @@ usb_create(const char *device, char *ebuf, int *is_ours)
|
||||||
/* OK, it's probably ours. */
|
/* OK, it's probably ours. */
|
||||||
*is_ours = 1;
|
*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)
|
if (p == NULL)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
|
@ -355,15 +395,15 @@ usb_activate(pcap_t* handle)
|
||||||
handle->setnonblock_op = pcap_setnonblock_fd;
|
handle->setnonblock_op = pcap_setnonblock_fd;
|
||||||
|
|
||||||
/*get usb bus index from device name */
|
/*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,
|
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||||
"Can't get USB bus index from %s", handle->opt.source);
|
"Can't get USB bus index from %s", handle->opt.device);
|
||||||
return PCAP_ERROR;
|
return PCAP_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*now select the read method: try to open binary interface */
|
/*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);
|
handle->fd = open(full_path, O_RDONLY, 0);
|
||||||
if (handle->fd >= 0)
|
if (handle->fd >= 0)
|
||||||
{
|
{
|
||||||
|
@ -402,7 +442,7 @@ usb_activate(pcap_t* handle)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/*Binary interface not available, try open text interface */
|
/*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);
|
handle->fd = open(full_path, O_RDONLY, 0);
|
||||||
if (handle->fd < 0)
|
if (handle->fd < 0)
|
||||||
{
|
{
|
||||||
|
@ -412,12 +452,12 @@ usb_activate(pcap_t* handle)
|
||||||
* Not found at the new location; try
|
* Not found at the new location; try
|
||||||
* the old location.
|
* 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);
|
handle->fd = open(full_path, O_RDONLY, 0);
|
||||||
}
|
}
|
||||||
if (handle->fd < 0) {
|
if (handle->fd < 0) {
|
||||||
/* no more fallback, give it up*/
|
/* 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));
|
"Can't open USB bus file %s: %s", full_path, strerror(errno));
|
||||||
return PCAP_ERROR;
|
return PCAP_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -445,7 +485,7 @@ usb_activate(pcap_t* handle)
|
||||||
* buffer */
|
* buffer */
|
||||||
handle->buffer = malloc(handle->bufsize);
|
handle->buffer = malloc(handle->bufsize);
|
||||||
if (!handle->buffer) {
|
if (!handle->buffer) {
|
||||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||||
"malloc: %s", pcap_strerror(errno));
|
"malloc: %s", pcap_strerror(errno));
|
||||||
close(handle->fd);
|
close(handle->fd);
|
||||||
return PCAP_ERROR;
|
return PCAP_ERROR;
|
||||||
|
@ -453,22 +493,22 @@ usb_activate(pcap_t* handle)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
ascii_to_int(char c)
|
ascii_to_int(char c)
|
||||||
{
|
{
|
||||||
return c < 'A' ? c- '0': ((c<'a') ? c - 'A' + 10: c-'a'+10);
|
return c < 'A' ? c- '0': ((c<'a') ? c - 'A' + 10: c-'a'+10);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 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_text.c for urb string
|
* <linux-kernel-source>/drivers/usb/mon/mon_text.c for urb string
|
||||||
* format description
|
* format description
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
usb_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user)
|
usb_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user)
|
||||||
{
|
{
|
||||||
/* see:
|
/* see:
|
||||||
* /usr/src/linux/Documentation/usb/usbmon.txt
|
* /usr/src/linux/Documentation/usb/usbmon.txt
|
||||||
* for message format
|
* for message format
|
||||||
*/
|
*/
|
||||||
struct pcap_usb_linux *handlep = handle->priv;
|
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)
|
if (errno == EAGAIN)
|
||||||
return 0; /* no data there */
|
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));
|
"Can't read from fd %d: %s", handle->fd, strerror(errno));
|
||||||
return -1;
|
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*/
|
* not mandatory, so does not count on it*/
|
||||||
string[ret] = 0;
|
string[ret] = 0;
|
||||||
ret = sscanf(string, "%x %d %c %c%c:%d:%d %s%n", &tag, ×tamp, &etype,
|
ret = sscanf(string, "%x %d %c %c%c:%d:%d %s%n", &tag, ×tamp, &etype,
|
||||||
&pipeid1, &pipeid2, &dev_addr, &ep_num, status,
|
&pipeid1, &pipeid2, &dev_addr, &ep_num, status,
|
||||||
&cnt);
|
&cnt);
|
||||||
if (ret < 8)
|
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)",
|
"Can't parse USB bus message '%s', too few tokens (expected 8 got %d)",
|
||||||
string, ret);
|
string, ret);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -521,10 +561,10 @@ usb_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *u
|
||||||
string += cnt;
|
string += cnt;
|
||||||
|
|
||||||
/* don't use usbmon provided timestamp, since it have low precision*/
|
/* 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,
|
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||||
"Can't get timestamp for message '%s' %d:%s",
|
"Can't get timestamp for message '%s' %d:%s",
|
||||||
string, errno, strerror(errno));
|
string, errno, strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -567,15 +607,15 @@ usb_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *u
|
||||||
if (ret != 1)
|
if (ret != 1)
|
||||||
{
|
{
|
||||||
/* this a setup packet, setup data can be filled with underscore if
|
/* 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 */
|
* strings */
|
||||||
pcap_usb_setup* shdr;
|
pcap_usb_setup* shdr;
|
||||||
char str1[3], str2[3], str3[5], str4[5], str5[5];
|
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);
|
str5, &cnt);
|
||||||
if (ret < 5)
|
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)",
|
"Can't parse USB bus message '%s', too few tokens (expected 5 got %d)",
|
||||||
string, ret);
|
string, ret);
|
||||||
return -1;
|
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;
|
uhdr->setup_flag = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
uhdr->setup_flag = 1;
|
uhdr->setup_flag = 1;
|
||||||
|
|
||||||
/* read urb data */
|
/* read urb data */
|
||||||
ret = sscanf(string, " %d%n", &urb_len, &cnt);
|
ret = sscanf(string, " %d%n", &urb_len, &cnt);
|
||||||
if (ret < 1)
|
if (ret < 1)
|
||||||
{
|
{
|
||||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||||
"Can't parse urb length from '%s'", string);
|
"Can't parse urb length from '%s'", string);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
string += cnt;
|
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 */
|
* text parsing */
|
||||||
pkth.len = urb_len+pkth.caplen;
|
pkth.len = urb_len+pkth.caplen;
|
||||||
uhdr->urb_len = urb_len;
|
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 '=' */
|
/* check for data presence; data is present if and only if urb tag is '=' */
|
||||||
if (sscanf(string, " %c", &urb_tag) != 1)
|
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);
|
"Can't parse urb tag from '%s'", string);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (urb_tag != '=')
|
if (urb_tag != '=')
|
||||||
goto got;
|
goto got;
|
||||||
|
|
||||||
/* skip urb tag and following space */
|
/* 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*/
|
/* if we reach this point we got some urb data*/
|
||||||
uhdr->data_flag = 0;
|
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
|
* buffer length used by the kernel to spool the URB, we get only
|
||||||
* a partial information.
|
* a partial information.
|
||||||
* At least until linux 2.6.17 there is no way to set usbmon intenal buffer
|
* At least until linux 2.6.17 there is no way to set usbmon intenal buffer
|
||||||
* length and default value is 130. */
|
* 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[0] = ascii_to_int(string[0]) * 16 + ascii_to_int(string[1]);
|
||||||
rawdata++;
|
rawdata++;
|
||||||
|
@ -649,8 +689,8 @@ usb_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *u
|
||||||
|
|
||||||
got:
|
got:
|
||||||
uhdr->data_len = data_len;
|
uhdr->data_len = data_len;
|
||||||
if (pkth.caplen > handle->snapshot)
|
if (pkth.caplen > (bpf_u_int32)handle->snapshot)
|
||||||
pkth.caplen = handle->snapshot;
|
pkth.caplen = (bpf_u_int32)handle->snapshot;
|
||||||
|
|
||||||
if (handle->fcode.bf_insns == NULL ||
|
if (handle->fcode.bf_insns == NULL ||
|
||||||
bpf_filter(handle->fcode.bf_insns, handle->buffer,
|
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
|
static int
|
||||||
usb_inject_linux(pcap_t *handle, const void *buf, size_t size)
|
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");
|
"USB devices");
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
usb_stats_linux(pcap_t *handle, struct pcap_stat *stats)
|
usb_stats_linux(pcap_t *handle, struct pcap_stat *stats)
|
||||||
{
|
{
|
||||||
struct pcap_usb_linux *handlep = handle->priv;
|
struct pcap_usb_linux *handlep = handle->priv;
|
||||||
|
@ -680,7 +720,7 @@ usb_stats_linux(pcap_t *handle, struct pcap_stat *stats)
|
||||||
char * ptr = string;
|
char * ptr = string;
|
||||||
int fd;
|
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);
|
fd = open(string, O_RDONLY, 0);
|
||||||
if (fd < 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
|
* Not found at the new location; try the old
|
||||||
* location.
|
* 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);
|
fd = open(string, O_RDONLY, 0);
|
||||||
}
|
}
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||||
"Can't open USB stats file %s: %s",
|
"Can't open USB stats file %s: %s",
|
||||||
string, strerror(errno));
|
string, strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -709,7 +749,7 @@ usb_stats_linux(pcap_t *handle, struct pcap_stat *stats)
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||||
"Can't read stats from fd %d ", fd);
|
"Can't read stats from fd %d ", fd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -717,11 +757,11 @@ usb_stats_linux(pcap_t *handle, struct pcap_stat *stats)
|
||||||
|
|
||||||
/* extract info on dropped urbs */
|
/* extract info on dropped urbs */
|
||||||
for (consumed=0; consumed < ret; ) {
|
for (consumed=0; consumed < ret; ) {
|
||||||
/* from the sscanf man page:
|
/* from the sscanf man page:
|
||||||
* The C standard says: "Execution of a %n directive does
|
* The C standard says: "Execution of a %n directive does
|
||||||
* not increment the assignment count returned at the completion
|
* not increment the assignment count returned at the completion
|
||||||
* of execution" but the Corrigendum seems to contradict this.
|
* 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*/
|
* on the return value and explicitly check for cnt assignmet*/
|
||||||
int ntok;
|
int ntok;
|
||||||
|
|
||||||
|
@ -733,7 +773,7 @@ usb_stats_linux(pcap_t *handle, struct pcap_stat *stats)
|
||||||
ptr += cnt;
|
ptr += cnt;
|
||||||
if (strcmp(token, "nreaders") == 0)
|
if (strcmp(token, "nreaders") == 0)
|
||||||
ret = sscanf(ptr, "%d", &stats->ps_drop);
|
ret = sscanf(ptr, "%d", &stats->ps_drop);
|
||||||
else
|
else
|
||||||
ret = sscanf(ptr, "%d", &dummy);
|
ret = sscanf(ptr, "%d", &dummy);
|
||||||
if (ntok != 1)
|
if (ntok != 1)
|
||||||
break;
|
break;
|
||||||
|
@ -746,7 +786,7 @@ usb_stats_linux(pcap_t *handle, struct pcap_stat *stats)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
usb_setdirection_linux(pcap_t *p, pcap_direction_t d)
|
usb_setdirection_linux(pcap_t *p, pcap_direction_t d)
|
||||||
{
|
{
|
||||||
p->direction = 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)
|
usb_stats_linux_bin(pcap_t *handle, struct pcap_stat *stats)
|
||||||
{
|
{
|
||||||
struct pcap_usb_linux *handlep = handle->priv;
|
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);
|
ret = ioctl(handle->fd, MON_IOCG_STATS, &st);
|
||||||
if (ret < 0)
|
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));
|
"Can't read stats from fd %d:%s ", handle->fd, strerror(errno));
|
||||||
return -1;
|
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
|
* <linux-kernel-source>/drivers/usb/mon/mon_bin.c binary ABI
|
||||||
*/
|
*/
|
||||||
static int
|
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;
|
struct mon_bin_get info;
|
||||||
int ret;
|
int ret;
|
||||||
struct pcap_pkthdr pkth;
|
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*/
|
/* the usb header is going to be part of 'packet' data*/
|
||||||
info.hdr = (pcap_usb_header*) handle->buffer;
|
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;
|
info.data_len = clen;
|
||||||
|
|
||||||
/* ignore interrupt system call errors */
|
/* 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)
|
if (errno == EAGAIN)
|
||||||
return 0; /* no data there */
|
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));
|
"Can't read from fd %d: %s", handle->fd, strerror(errno));
|
||||||
return -1;
|
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
|
* <linux-kernel-source>/drivers/usb/mon/mon_bin.c binary ABI
|
||||||
*/
|
*/
|
||||||
#define VEC_SIZE 32
|
#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;
|
pcap_usb_header* hdr;
|
||||||
int nflush = 0;
|
int nflush = 0;
|
||||||
int packets = 0;
|
int packets = 0;
|
||||||
int clen, max_clen;
|
u_int clen, max_clen;
|
||||||
|
|
||||||
max_clen = handle->snapshot - sizeof(pcap_usb_header);
|
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)
|
if (errno == EAGAIN)
|
||||||
return 0; /* no data there */
|
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));
|
"Can't mfetch fd %d: %s", handle->fd, strerror(errno));
|
||||||
return -1;
|
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) {
|
for (i=0; i<fetch.nfetch; ++i) {
|
||||||
/* discard filler */
|
/* discard filler */
|
||||||
hdr = (pcap_usb_header*) &handlep->mmapbuf[vec[i]];
|
hdr = (pcap_usb_header*) &handlep->mmapbuf[vec[i]];
|
||||||
if (hdr->event_type == '@')
|
if (hdr->event_type == '@')
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* we can get less that than really captured from kernel, depending on
|
/* 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*/
|
/* 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;
|
return packets;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,8 @@
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
* 3. The name of the author may not be used to endorse or promote
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
* products derived from this software without specific prior written
|
* products derived from this software without specific prior written
|
||||||
* permission.
|
* permission.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -17,7 +17,7 @@
|
||||||
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||||
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
.\"
|
.\"
|
||||||
.TH PCAP 3PCAP "16 April 2014"
|
.TH PCAP 3PCAP "8 March 2015"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
pcap \- Packet Capture library
|
pcap \- Packet Capture library
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
|
@ -354,12 +354,25 @@ open a
|
||||||
.B pcap_t
|
.B pcap_t
|
||||||
for a ``savefile'', given a pathname
|
for a ``savefile'', given a pathname
|
||||||
.TP
|
.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)
|
.BR pcap_fopen_offline (3PCAP)
|
||||||
open a
|
open a
|
||||||
.B pcap_t
|
.B pcap_t
|
||||||
for a ``savefile'', given a
|
for a ``savefile'', given a
|
||||||
.B "FILE\ *"
|
.B "FILE\ *"
|
||||||
.TP
|
.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)
|
.BR pcap_open_dead (3PCAP)
|
||||||
create a ``fake''
|
create a ``fake''
|
||||||
.B pcap_t
|
.B pcap_t
|
||||||
|
@ -424,6 +437,16 @@ get description for a time stamp type
|
||||||
.BR pcap_tstamp_type_name_to_val (3PCAP)
|
.BR pcap_tstamp_type_name_to_val (3PCAP)
|
||||||
get time stamp type corresponding to a name
|
get time stamp type corresponding to a name
|
||||||
.TP
|
.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)
|
.BR pcap_datalink (3PCAP)
|
||||||
get link-layer header type for a
|
get link-layer header type for a
|
||||||
.B pcap_t
|
.B pcap_t
|
||||||
|
@ -552,7 +575,7 @@ bytes of the packet on success, and NULL on error.
|
||||||
.BR pcap_next_ex ()
|
.BR pcap_next_ex ()
|
||||||
is passed two pointer arguments, one of which points to a
|
is passed two pointer arguments, one of which points to a
|
||||||
.IR struct pcap_pkthdr *
|
.IR struct pcap_pkthdr *
|
||||||
and one of which points to a
|
and one of which points to a
|
||||||
.IR "const u_char" *.
|
.IR "const u_char" *.
|
||||||
It sets the first pointer to point to a
|
It sets the first pointer to point to a
|
||||||
.I struct pcap_pkthdr
|
.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
|
all, platforms, if a read timeout was specified, the wait will terminate
|
||||||
after the read timeout expires; applications should be prepared for
|
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
|
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
|
.PP
|
||||||
A handle can be put into ``non-blocking mode'', so that those routines
|
A handle can be put into ``non-blocking mode'', so that those routines
|
||||||
will, rather than blocking, return an indication that no packets are
|
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)
|
.BR select (2)
|
||||||
or
|
or
|
||||||
.BR poll (2)
|
.BR poll (2)
|
||||||
or other routines a platform offers to wait for the availability of data
|
or other routines a platform offers to wait for any of a set of
|
||||||
on any of a set of descriptors. To obtain, for a handle, a descriptor
|
descriptors to be ready to read. To obtain, for a handle, a descriptor
|
||||||
that can be used in those routines, call
|
that can be used in those routines, call
|
||||||
.BR pcap_get_selectable_fd ().
|
.BR pcap_get_selectable_fd ().
|
||||||
Not all handles have such a descriptor available;
|
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
|
reasons, one or more of those routines will not work properly with the
|
||||||
descriptor; the documentation for
|
descriptor; the documentation for
|
||||||
.BR pcap_get_selectable_fd ()
|
.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
|
.TP
|
||||||
.B Routines
|
.B Routines
|
||||||
.RS
|
.RS
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -11,8 +11,8 @@
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
* 3. The name of the author may not be used to endorse or promote
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
* products derived from this software without specific prior written
|
* products derived from this software without specific prior written
|
||||||
* permission.
|
* permission.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
@ -30,9 +30,9 @@
|
||||||
* bluetooth data struct
|
* bluetooth data struct
|
||||||
* By Paolo Abeni <paolo.abeni@email.it>
|
* By Paolo Abeni <paolo.abeni@email.it>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _PCAP_BLUETOOTH_STRUCTS_H__
|
#ifndef lib_pcap_bluetooth_h
|
||||||
#define _PCAP_BLUETOOTH_STRUCTS_H__
|
#define lib_pcap_bluetooth_h
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Header prepended libpcap to each bluetooth h4 frame,
|
* Header prepended libpcap to each bluetooth h4 frame,
|
||||||
|
|
File diff suppressed because it is too large
Load diff
54
contrib/libpcap/pcap/can_socketcan.h
Normal file
54
contrib/libpcap/pcap/can_socketcan.h
Normal 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
1340
contrib/libpcap/pcap/dlt.h
Normal file
File diff suppressed because it is too large
Load diff
108
contrib/libpcap/pcap/export-defs.h
Normal file
108
contrib/libpcap/pcap/export-defs.h
Normal 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 */
|
|
@ -43,7 +43,10 @@ extern "C" {
|
||||||
* XXX this stuff doesn't belong in this interface, but this
|
* XXX this stuff doesn't belong in this interface, but this
|
||||||
* library already must do name to address translation, so
|
* library already must do name to address translation, so
|
||||||
* on systems that don't have support for /etc/ethers, we
|
* 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 {
|
struct pcap_etherent {
|
||||||
u_char addr[6];
|
u_char addr[6];
|
||||||
|
@ -52,21 +55,21 @@ struct pcap_etherent {
|
||||||
#ifndef PCAP_ETHERS_FILE
|
#ifndef PCAP_ETHERS_FILE
|
||||||
#define PCAP_ETHERS_FILE "/etc/ethers"
|
#define PCAP_ETHERS_FILE "/etc/ethers"
|
||||||
#endif
|
#endif
|
||||||
struct pcap_etherent *pcap_next_etherent(FILE *);
|
PCAP_API struct pcap_etherent *pcap_next_etherent(FILE *);
|
||||||
u_char *pcap_ether_hostton(const char*);
|
PCAP_API u_char *pcap_ether_hostton(const char*);
|
||||||
u_char *pcap_ether_aton(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
|
#ifdef INET6
|
||||||
struct addrinfo *pcap_nametoaddrinfo(const char *);
|
PCAP_API struct addrinfo *pcap_nametoaddrinfo(const char *);
|
||||||
#endif
|
#endif
|
||||||
bpf_u_int32 pcap_nametonetaddr(const char *);
|
PCAP_API bpf_u_int32 pcap_nametonetaddr(const char *);
|
||||||
|
|
||||||
int pcap_nametoport(const char *, int *, int *);
|
PCAP_API int pcap_nametoport(const char *, int *, int *);
|
||||||
int pcap_nametoportrange(const char *, int *, int *, int *);
|
PCAP_API int pcap_nametoportrange(const char *, int *, int *, int *);
|
||||||
int pcap_nametoproto(const char *);
|
PCAP_API int pcap_nametoproto(const char *);
|
||||||
int pcap_nametoeproto(const char *);
|
PCAP_API int pcap_nametoeproto(const char *);
|
||||||
int pcap_nametollc(const char *);
|
PCAP_API int pcap_nametollc(const char *);
|
||||||
/*
|
/*
|
||||||
* If a protocol is unknown, PROTO_UNDEF is returned.
|
* If a protocol is unknown, PROTO_UNDEF is returned.
|
||||||
* Also, pcap_nametoport() returns the protocol along with the port number.
|
* Also, pcap_nametoport() returns the protocol along with the port number.
|
||||||
|
@ -75,11 +78,6 @@ int pcap_nametollc(const char *);
|
||||||
*/
|
*/
|
||||||
#define PROTO_UNDEF -1
|
#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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -25,8 +25,8 @@
|
||||||
* DAMAGE.
|
* DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _PCAP_NFLOG_H__
|
#ifndef lib_pcap_nflog_h
|
||||||
#define _PCAP_NFLOG_H__
|
#define lib_pcap_nflog_h
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Structure of an NFLOG header and TLV parts, as described at
|
* 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
Loading…
Reference in a new issue