1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-15 04:09:01 +00:00

Update included libpcap to 1.10.1

This commit is contained in:
dmiller
2022-08-31 18:39:55 +00:00
parent 04bcefd3e4
commit 65410fead1
174 changed files with 20680 additions and 14646 deletions

1
.gitignore vendored
View File

@@ -42,6 +42,7 @@ libpcap/pcap-linktype.manmisc
libpcap/pcap-savefile.manfile libpcap/pcap-savefile.manfile
libpcap/pcap-tstamp.manmisc libpcap/pcap-tstamp.manmisc
libpcap/pcap_version.h libpcap/pcap_version.h
libpcap/grammar.y
libssh2/src/libssh2_config.h libssh2/src/libssh2_config.h
libssh2/lib/ libssh2/lib/
libpcre/pcre-config libpcre/pcre-config

View File

@@ -1,3 +1,211 @@
Monthday, Month DD, YYYY
Summary for 1.10.1 libpcap release (so far!)
Packet filtering:
Fix "type XXX subtype YYY" giving a parse error
Source code:
Add PCAP_AVAILABLE_1_11.
Building and testing:
Rename struct bpf_aux_data to avoid NetBSD compile errors
Squelch some compiler warnings
Squelch some Bison warnings
Fix cross-builds with older kernels lacking BPF_MOD and BPF_XOR
Fix Bison detection for minor version 0.
Fix parallel build with FreeBSD make.
Get DLT_MATCHING_MAX right in gencode.c on NetBSD.
Define timeradd() and timersub() if necessary.
Fix Cygwin/MSYS target directories.
Fix symlinking with DESTDIR.
Fix generation of libpcap.pc with CMake when not building a shared
library.
Check for Arm64 as well as x86-64 when looking for packet.lib on
Windows.
Documentation:
Refine Markdown in README.md.
Improve the description of portrange in filters.
README.linux.md isn't Markdown, rename it just README.linux.
pcapng:
Support reading version 1.2, which some writers produce, and which
is the same as 1.0 (some new block types were added, but
that's not sufficient reason to bump the minor version number,
as code that understands those new block types can handle them
in a 1.0 file)
Linux:
Drop support for text-mode USB captures, as we require a 2.6.27
or later kernel (credit to Chaoyuan Peng for noting the
sscanf vulnerabilities in the text-mode code that got me to
realize that we didn't need this code any more)
Bluetooth: fix non-blocking mode.
Don't assume that all compilers used to build for Linux support
the __atomic builtins
Windows:
Add more information in "interface disappeared" error messages, in
the hopes of trying to figure out the cause.
Treat ERROR_DEVICE_REMOVED as "device was removed".
Indicate in the error message which "device was removed" error
occurred.
Report the Windows error status if PacketSendPacket() fails.
Use %lu for ULONGs in error message formats.
Don't treat the inability to find airpcap.dll as an error.
Ignore spurious error reports by Microsoft Surface mobile
telephony modem driver
rpcap:
Clean up error checking and error messages for server address
lookup.
Tuesday, December 29, 2020
Summary for 1.10.0 libpcap release
Add support for capturing on DPDK devices
Label most APIs by the first release in which they're available
Fix some memory leaks, including in pcap_compile()
Add pcap_datalink_val_to_description_or_dlt()
Handle the pcap private data in a fashion that makes fewer
assumptions about memory layouts (might fix GitHub issue #940
on ARM)
Fix some thread safety issues
pcap_findalldevs(): don't sort interfaces by unit number
Always return a list of supported time-stamp types, even if only
host time stamps are supported
Increase the maximum snaplen for LINKTYPE_USBPCAP/DLT_USBPCAP
Report the DLT description in error messages
Add pcap_init() for first-time initialization and global option
setting; it's not required, but may be used
Remove (unused) SITA support
Capture file reading:
Correctly handle pcapng captures with more than one IDB with a
snspshot length greater than the supported maximum
Capture file writing:
Create the file in pcap_dump_open_append() if it doesn't exist
Packet filtering:
Fix "unknown ether proto 'aarp'"
Add a new filter "ifindex" for DLT_LINUX_SLL2 files on all
platforms and live Linux captures
Add a hack to the optimizer to try to catch certain optimizer
loops (should prevent GitHub issue #112)
Show special Linux BPF offsets symbolically in bpf_image() and
bpf_dump()
Added support for ICMPv6 types 1-4 as tokens with names
Remove undocumented and rather old "ether proto" protocols
Catch invalid IPv4 addresses in filters
Don't assume ARM supports unaligned accesses
Security and other issues found by analysis:
Fix various security issues reported by Charles Smith at Tangible
Security
Fix various security issues reported by Include Security
Fix some issues found by cppcheck.
Add some overflow checks in the optimizer
rpcap:
Support rpcap-over-TLS
Redo protocol version negotiation to avoid problems with old
servers (it still works with servers using the old negotiation,
as well as servers not supporting negotiation)
Error handling cleanups
Add some new authentication libpcap error codes for specific
errors
Fix some inetd issues in rpcapd
Fix rpcapd core dumps with invalid configuration file
On UN*X, don't have rpcapd tell the client why authentication
failed, so a brute-force attacker can't distinguish between
"unknown user name" and "known user name, wrong password"
Allow rpcapd to rebind more rapidly (GitHub issue #765)
Documentation:
Improve man pages, including adding backward compatibility notes
Building and testing:
Require, and assume, some level of C99 support in the C compiler
Require Visual Studio 2015 or later if using Visual Studio
Fix configure script issues, including with libnl on Linux
Fix CMake issues
Squelch complaints from Bison about "%define api.pure" being
deprecated
Fix compilation of pcap-tc.c
Linux:
Require PF_PACKET support, and kernel 2.6.27 or later
Handle systems without AF_INET or AF_UNIX socket support
Get rid of Wireless Extensions for turning monitor mode on
Proper memory sync for PACKET_MMAP (may prevent GitHub issue
#898)
Drop support for libnl 1 and 2.
Return error on interface going away, but not if it just went
down but is still present
Set socket protocol only after packet ring configured,
reducing bogus packet drop reports
Get ifdrop stats from sysfs.
When adjusting BPF programs, do not subtract the
SLL[2]_HDR_LEN if the location is negative (special metadata
offset), to preserve references to metadata; see
https://github.com/the-tcpdump-group/tcpdump/issues/480#issuecomment-486827278
Report a warning for unknown ARPHRD types
Have pcap_breakloop() forcibly break out of a sleeping
capture loop
Add support for DSA data link types
For raw USB bus capture, use the snapshot length to set the
buffer size, and set the len field to reflect the length
in the URB (GitHub issue #808)
With a timeout of zero, wait indefinitely
Clean up support for some non-GNU libc C libraries
Add DLT_LINUX_SLL2 for cooked-mode captures
Probe CONFIGURATION descriptor of connected USB devices
Treat EPERM on ethtool ioctls as meaning "not supported", as
permissions checks are done before checking whether the
ioctl is supported at all
macOS:
Cope with getting EPWROFF from SIOCGIFMEDIA
Treat EPERM on SIOCGIFMEDIA as meaning "not supported", as
permissions checks are done before checking whether the
ioctl is supported at all
Treat ENXIO when reading packets as meaning "the interface
was removed"
Report "the interface disappeared", not "the interface went
down", if the interface was removed during a capture
FreeBSD:
Treat ENXIO as meaning "the interface was removed"
Report "the interface disappeared", not "the interface went
down", if the interface was removed during a capture
NetBSD:
Treat ENXIO as meaning "the interface was removed"
Report "the interface disappeared", not "the interface went
down", if the interface was removed during a capture
OpenBSD:
Treat EIO as meaning "the interface was removed"
Report "the interface disappeared", not "the interface went
down", if the interface was removed during a capture
DragonFly BSD:
Treat ENXIO as meaning "the interface was removed"
Report "the interface disappeared", not "the interface went
down", if the interface was removed during a capture
Solaris:
Treat ENXIO as meaning "the interface was removed"
Report "the interface disappeared", not "the interface went
down", if the interface was removed during a capture
AIX:
Fix loading of BPF kernel extension
Treat ENXIO as meaning "the interface was removed"
Report "the interface disappeared", not "the interface went
down", if the interface was removed during a capture
Windows:
Make the snapshot length work even if pcap_setfilter()
isn't called
Fix compilation on Cygwin/MSYS
Add pcap_handle(), and deprecate pcap_fileno()
Report PCAP_ERROR_NO_SUCH_DEVICE for a non-existent device
Return an appropriate error message for device removed or
device unusable due to a suspend/resume
Report a warning for unknown NdisMedium types
Have pcap_breakloop() forcibly break out of a sleeping
capture loop
Clean up building DLL
Handle CRT mismatch for pcap_dump_fopen()
Map NdisMediumWirelessWan to DLT_RAW
Add AirPcap support in a module, rather than using
WinPcap/Npcap's support for it
Report the system error for PacketSetHwFilter() failures
Add support for getting and setting packet time stamp types
with Npcap
Have pcap_init() allow selecting whether the API should use
local code page strings or UTF-8 strings (including error
messages)
Haiku:
Add capture support
Sunday, July 22, 2018 Sunday, July 22, 2018
Summary for 1.9.1 libpcap release Summary for 1.9.1 libpcap release
Mention pcap_get_required_select_timeout() in the main pcap man page Mention pcap_get_required_select_timeout() in the main pcap man page
@@ -93,7 +301,7 @@ Sunday, June 24, 2018, by mcr@sandelman.ca
Make VLAN filter handle both metadata and inline tags Make VLAN filter handle both metadata and inline tags
D-Bus captures can now be up to 128MB in size D-Bus captures can now be up to 128MB in size
Added LORATAP DLT value Added LORATAP DLT value
Added DLT_VSOCK for http://qemu-project.org/Features/VirtioVsock Added DLT_VSOCK for https://qemu-project.org/Features/VirtioVsock
probe_devices() fixes not to overrun buffer for name of device probe_devices() fixes not to overrun buffer for name of device
Add linux-specific pcap_set_protocol_linux() to allow specifying a specific capture protocol. Add linux-specific pcap_set_protocol_linux() to allow specifying a specific capture protocol.
RDMA sniffing support for pcap RDMA sniffing support for pcap
@@ -275,7 +483,7 @@ Summary for 1.5.0 libpcap release
than the mcr repository than the mcr repository
Checks added for malloc()/realloc()/etc. failures Checks added for malloc()/realloc()/etc. failures
Fixed build on Solaris 11 Fixed build on Solaris 11
Support filtering filtering E1 SS7 traffic on MTP2 layer Annex A Support filtering E1 SS7 traffic on MTP2 layer Annex A
Use "ln -s" to link man pages by default Use "ln -s" to link man pages by default
Add support for getting nanosecond-resolution time stamps when Add support for getting nanosecond-resolution time stamps when
capturing and reading capture files capturing and reading capture files
@@ -336,7 +544,7 @@ Summary for 1.3.0 libpcap release
Friday December 9, 2011. guy@alum.mit.edu. Friday December 9, 2011. guy@alum.mit.edu.
Summary for 1.2.1 libpcap release Summary for 1.2.1 libpcap release
Update README file. Update README file.
Fix typoes in README.linux file. Fix typos in README.linux file.
Clean up some compiler warnings. Clean up some compiler warnings.
Fix Linux compile problems and tests for ethtool.h. Fix Linux compile problems and tests for ethtool.h.
Treat Debian/kFreeBSD and GNU/Hurd as systems with GNU Treat Debian/kFreeBSD and GNU/Hurd as systems with GNU
@@ -369,7 +577,7 @@ Summary for 1.2 libpcap release
Noted real nature of LINKTYPE_ARCNET. Noted real nature of LINKTYPE_ARCNET.
Add a link-layer type for DVB-CI. Add a link-layer type for DVB-CI.
Fix configure-script discovery of VLAN acceleration support. Fix configure-script discovery of VLAN acceleration support.
see http://netoptimizer.blogspot.com/2010/09/tcpdump-vs-vlan-tags.html see https://netoptimizer.blogspot.com/2010/09/tcpdump-vs-vlan-tags.html
Linux, HP-UX, AIX, NetBSD and OpenBSD compilation/conflict fixes. Linux, HP-UX, AIX, NetBSD and OpenBSD compilation/conflict fixes.
Protect against including AIX 5.x's <net/bpf.h> having been included. Protect against including AIX 5.x's <net/bpf.h> having been included.
Add DLT_DBUS, for raw D-Bus messages. Add DLT_DBUS, for raw D-Bus messages.
@@ -568,7 +776,7 @@ Tue. September 19, 2006. ken@xelerance.com. Summary for 0.9.5 libpcap release
beginning+link-layer beginning+link-layer
Add DLT/LINKTYPE for carrying FRF.16 Multi-link Frame Relay Add DLT/LINKTYPE for carrying FRF.16 Multi-link Frame Relay
Fix allocation of buffer for list of link-layer types Fix allocation of buffer for list of link-layer types
Added a new DLT and LINKTYPE value for ARINC 653 Interpartition Communcation Messages Added a new DLT and LINKTYPE value for ARINC 653 Interpartition Communication Messages
Fixed a typo in a DLT value: it should start with DLT_ and not LINKTYPE_ Fixed a typo in a DLT value: it should start with DLT_ and not LINKTYPE_
Redefined DLT_CAN20B and LINKTYPE_CAN20B as #190 (as this is the right value for CAN). Redefined DLT_CAN20B and LINKTYPE_CAN20B as #190 (as this is the right value for CAN).
Added definition for DLT_A429 and LINKTYPE_A429 as #184. Added definition for DLT_A429 and LINKTYPE_A429 as #184.
@@ -682,7 +890,7 @@ Tuesday January 9, 2001. guy@alum.mit.edu. Summary for 0.6 release
Header files fixed to allow use in C++ programs. Header files fixed to allow use in C++ programs.
Removed dependancy on native headers for packet layout. Removed dependency on native headers for packet layout.
Removed Linux specific headers that were shipped. Removed Linux specific headers that were shipped.
Security fixes: Strcpy replaced with strlcpy, sprintf replaced Security fixes: Strcpy replaced with strlcpy, sprintf replaced
@@ -820,7 +1028,7 @@ v0.3 Sat Nov 30 20:56:27 PST 1996
v0.2.1 Sun Jul 14 03:02:26 PDT 1996 v0.2.1 Sun Jul 14 03:02:26 PDT 1996
- Fixes for HP-UX 10. Thanks in part to to Thomas Wolfram - Fixes for HP-UX 10. Thanks in part to Thomas Wolfram
(wolf@prz.tu-berlin.de) and Rick Jones (raj@hpisrdq.cup.hp.com) (wolf@prz.tu-berlin.de) and Rick Jones (raj@hpisrdq.cup.hp.com)
- Added support for SINIX. Thanks to Andrej Borsenkow - Added support for SINIX. Thanks to Andrej Borsenkow

File diff suppressed because it is too large Load Diff

View File

@@ -3,29 +3,42 @@ This file lists people who have contributed to libpcap.
The current maintainers (in alphabetical order): The current maintainers (in alphabetical order):
Denis Ovsienko <denis at ovsienko dot info> Denis Ovsienko <denis at ovsienko dot info>
Francois-Xavier Le Bail <devel dot fx dot lebail at orange dot fr> Francois-Xavier Le Bail <devel dot fx dot lebail at orange dot fr>
Guy Harris <guy at alum dot mit dot edu> Guy Harris <gharris at sonic dot net>
Michael Richardson <mcr at sandelman dot ottawa dot on dot ca> Michael Richardson <mcr at sandelman dot ottawa dot on dot ca>
Additional people who have contributed patches (in alphabetical order): Additional people who have contributed patches (in alphabetical order):
Adrian Budau <adbudau at bitdefender dot com>
Akos Vandra <axos88 at gmail dot com> Akos Vandra <axos88 at gmail dot com>
Alan Bawden <Alan at LCS dot MIT dot EDU> Alan Bawden <Alan at LCS dot MIT dot EDU>
Albert Chin <china at thewrittenword dot com> Albert Chin <china at thewrittenword dot com>
Alexander Galanin <al at galanin dot nnov dot ru>
Alexander 'Leo' Bergolth <Leo dot Bergolth at wu-wien dot ac dot at> Alexander 'Leo' Bergolth <Leo dot Bergolth at wu-wien dot ac dot at>
Alexey Kuznetsov <kuznet at ms2 dot inr dot ac dot ru> Alexey Kuznetsov <kuznet at ms2 dot inr dot ac dot ru>
Alex Smith <44322503+MadAlexUK at users dot noreply dot github dot com>
Alfredo Alvarez Fernandez <alfredoalvarezernandez at gmail dot com>
Ali Abdulkadir <autostart dot ini at gmail dot com> Ali Abdulkadir <autostart dot ini at gmail dot com>
Alon Bar-Lev <alonbl at sourceforge dot net> Alon Bar-Lev <alonbl at sourceforge dot net>
Anders Broman <anders dot broman at ericsson dot com>
Andres Perera <andres dot p at zoho dot com> Andres Perera <andres dot p at zoho dot com>
Andrew Brown <atatat at atatdot dot net> Andrew Brown <atatat at atatdot dot net>
<andy-1 at sourceforge dot net> <andy-1 at sourceforge dot net>
Ani Sinha <ani at aristanetworks dot com> Ani Sinha <ani at aristanetworks dot com>
Anthony Kirby <Anthony dot Kirby at nominet dot uk>
Antti Kantee <pooka at netbsd dot org> Antti Kantee <pooka at netbsd dot org>
Arien Vijn <arienvijn at sourceforge dot net> Arien Vijn <arienvijn at sourceforge dot net>
Arkadiusz Miskiewicz <misiek at pld dot org dot pl> Arkadiusz Miskiewicz <misiek at pld dot org dot pl>
Armando L. Caro Jr. <acaro at mail dot eecis dot udel dot edu> Armando L. Caro Jr. <acaro at mail dot eecis dot udel dot edu>
Assar Westerlund <assar at sics dot se> Assar Westerlund <assar at sics dot se>
Atzm Watanabe <atzm at atzm dot org>
Baptiste Peugnez <baptiste dot peugnez at cea dot fr>
Baruch Siach <baruch at tkos dot co dot il>
Bill Parker <wp02855 at gmail dot com> Bill Parker <wp02855 at gmail dot com>
blazeable <blazeable at blazeable dot eu>
bleader <bleader at ratonland dot org>
Brent Cook <brent at boundary dot com> Brent Cook <brent at boundary dot com>
Brian Ginsbach <ginsbach at cray dot com> Brian Ginsbach <ginsbach at cray dot com>
B. Scott Michel <scooter dot phd at gmail dot com>
Cedric Cellier <rixed at happyleptic dot org>
Charles M. Hannum <mycroft at netbsd dot org> Charles M. Hannum <mycroft at netbsd dot org>
Chris G. Demetriou <cgd at netbsd dot org> Chris G. Demetriou <cgd at netbsd dot org>
Chris Lightfoot <cwrl at users dot sourceforge dot net> Chris Lightfoot <cwrl at users dot sourceforge dot net>
@@ -34,15 +47,22 @@ Additional people who have contributed patches (in alphabetical order):
Christian Bell <csbell at myri dot com> Christian Bell <csbell at myri dot com>
Christian Peron <csjp at freebsd dot org> Christian Peron <csjp at freebsd dot org>
Christian Svensson <blue at cmd dot nu> Christian Svensson <blue at cmd dot nu>
Christopher K Lee <christopher dot lee at cspi dot com>
Daniel Borkmann <dborkman at redhat dot com>
Daniele Orlandi <daniele at orlandi dot com> Daniele Orlandi <daniele at orlandi dot com>
Daniel Lublin <daniel at lublin dot se>
Daniel Miller <dmiller at nmap dot org>
Dario Lombardo <lomato at gmail dot com>
Darren Lim <darren dot lim at endace dot com> Darren Lim <darren dot lim at endace dot com>
Darren Reed <darrenr at sun dot com> Darren Reed <darrenr at sun dot com>
Dave Barach <dave at barachs dot net>
David Clark <david dot clark at datasoft dot com> David Clark <david dot clark at datasoft dot com>
David Kaelbling <drk at sgi dot com> David Kaelbling <drk at sgi dot com>
David Ward <david dot ward at ll dot mit dot edu> David Ward <david dot ward at ll dot mit dot edu>
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>
Dmytro Ovdiienko <dmitriy dot ovdienko at gmail dot com>
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>
@@ -50,8 +70,12 @@ Additional people who have contributed patches (in alphabetical order):
Edward Sheldrake <ejs1920 at sourceforge dot net> Edward Sheldrake <ejs1920 at sourceforge dot net>
Eric Anderson <anderse at hpl dot hp dot com> Eric Anderson <anderse at hpl dot hp dot com>
Erik de Castro Lopo <erik dot de dot castro dot lopo at sensorynetworks dot com> Erik de Castro Lopo <erik dot de dot castro dot lopo at sensorynetworks dot com>
Fedor Sakharov <fedor dot sakharov at gmail dot com>
Felix Janda <felix dot janda at posteo dot de>
Felix Obenhuber <felix at obenhuber dot de> Felix Obenhuber <felix at obenhuber dot de>
Florent Drouin <Florent dot Drouin at alcatel-lucent dot fr> Florent Drouin <Florent dot Drouin at alcatel-lucent dot fr>
Florian Fainelli <f dot fainelli at gmail dot com>
François Revol <revol at free dot fr>
Franz Schaefer <schaefer at mond dot at> Franz Schaefer <schaefer at mond dot at>
frederich <frederich at sourceforge dot net> frederich <frederich at sourceforge dot net>
Fulko Hew <fulko dot hew at gmail dot com> Fulko Hew <fulko dot hew at gmail dot com>
@@ -59,6 +83,7 @@ Additional people who have contributed patches (in alphabetical order):
Gabor Tatarka <gabor dot tatarka at ericsson dot com> Gabor Tatarka <gabor dot tatarka at ericsson dot com>
Garrett Cooper <yaberauneya at sourceforge dot net> Garrett Cooper <yaberauneya at sourceforge dot net>
George Neville-Neil <gnn at freebsd dot org> George Neville-Neil <gnn at freebsd dot org>
Gerald Combs <gerald at zing dot org>
Gerard Garcia <nouboh at gmail dot com> Gerard Garcia <nouboh at gmail dot com>
Gianluca Varenni <gianluca dot varenni at gmail dot com> Gianluca Varenni <gianluca dot varenni at gmail dot com>
Gilbert Hoyek <gil_hoyek at hotmail dot com> Gilbert Hoyek <gil_hoyek at hotmail dot com>
@@ -71,47 +96,64 @@ Additional people who have contributed patches (in alphabetical order):
Gustavo Zacarias <gustavo at zacarias dot com dot ar> Gustavo Zacarias <gustavo at zacarias dot com dot ar>
Hagen Paul Pfeifer <hagen at jauu dot net> Hagen Paul Pfeifer <hagen at jauu dot net>
Henri Doreau <hdoreau at sourceforge dot net> Henri Doreau <hdoreau at sourceforge dot net>
Hiroaki KAWAI <kawai at stratosphere dot co dot jp>
Hyung Sik Yoon <hsyn at kr dot ibm dot com> Hyung Sik Yoon <hsyn at kr dot ibm dot com>
Igor Khristophorov <igor at atdot dot org> Igor Khristophorov <igor at atdot dot org>
Jakub Sitnicki <jsitnicki at gmail dot com>
Jakub Zawadzki <darkjames at darkjames dot pl> Jakub Zawadzki <darkjames at darkjames dot pl>
James Ko <jck at exegin dot com>
Jan-Philip Velders <jpv at veldersjes dot net> Jan-Philip Velders <jpv at veldersjes dot net>
Jason R. Thorpe <thorpej at netbsd dot org> Jason R. Thorpe <thorpej at netbsd dot org>
Javier Achirica <achirica at ttd dot net> Javier Achirica <achirica at ttd dot net>
Jean-Louis Charton <Jean-Louis dot CHARTON at oikialog dot com> Jean-Louis Charton <Jean-Louis dot CHARTON at oikialog dot com>
Jean Tourrilhes <jt at hpl dot hp dot com> Jean Tourrilhes <jt at hpl dot hp dot com>
Jefferson Ogata <jogata at nodc dot noaa dot gov> Jefferson Ogata <jogata at nodc dot noaa dot gov>
Jerome Duval <jerome dot duval at gmail dot com>
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> Jesse Gross <jesse at nicira dot com>
JHA <jon dot anderson at oracle dot com>
jingyu yang <jingleyang at users dot noreply dot github dot com>
Jiri Slaby <jirislaby at gmail dot com> Jiri Slaby <jirislaby at gmail dot com>
João Valverde <joao dot valverde at tecnico dot ulisboa dot pt>
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>
Jon Lindgren <jonl at yubyub dot net> Jon Lindgren <jonl at yubyub dot net>
Jon Smirl <jonsmirl at gmail dot com> Jon Smirl <jonsmirl at gmail dot com>
Jorge Boncompte [DTI2] <jorge at dti2 dot net> Jorge Boncompte [DTI2] <jorge at dti2 dot net>
jromanr <jromanr at hotmail dot com>
Juergen Schoenwaelder <schoenw at ibr dot cs dot tu-bs dot de> Juergen Schoenwaelder <schoenw at ibr dot cs dot tu-bs dot de>
Julien Moutinho <julm at savines dot alpes dot fr dot eu dot org> Julien Moutinho <julm at savines dot alpes dot fr dot eu dot org>
Jung-uk Kim <jkim at FreeBSD dot org> Jung-uk Kim <jkim at FreeBSD dot org>
Kazushi Sugyo <sugyo at pb dot jp dot nec dot com> Kazushi Sugyo <sugyo at pb dot jp dot nec dot com>
Kevin Boulain <kevin dot boulain at securactive dot net>
Klaus Klein <kleink at netbsd dot org> Klaus Klein <kleink at netbsd dot org>
Koryn Grant <koryn at endace dot com> Koryn Grant <koryn at endace dot com>
Kris Katterjohn <katterjohn at gmail dot com> Kris Katterjohn <katterjohn at gmail dot com>
Krzysztof Halasa <khc at pm dot waw dot pl> Krzysztof Halasa <khc at pm dot waw dot pl>
Lennert Buytenhek <buytenh at wantstofly dot org> Lennert Buytenhek <buytenh at wantstofly dot org>
lixiaoyan <lixiaoyan at google dot com>
Lorenzo Cavallaro <sullivan at sikurezza dot org> Lorenzo Cavallaro <sullivan at sikurezza dot org>
Loris Degioanni <loris at netgroup-serv dot polito dot it> Loris Degioanni <loris at netgroup-serv dot polito dot it>
Love Hörnquist-Åstrand <lha at stacken dot kth dot se> Love Hörnquist-Åstrand <lha at stacken dot kth dot se>
Luis MartinGarcia <luis dot mgarc at gmail dot com> Luis MartinGarcia <luis dot mgarc at gmail dot com>
lxy <391861737 at qq dot com>
Maciej W. Rozycki <macro at ds2 dot pg dot gda dot pl> Maciej W. Rozycki <macro at ds2 dot pg dot gda dot pl>
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>
Mario J. Rugiero <mrugiero at gmail dot com>
Mark C. Brown <mbrown at hp dot com> Mark C. Brown <mbrown at hp dot com>
Mark Johnston <markjdb at gmail dot com> Mark Johnston <markjdb at gmail dot com>
Mark Marshall <mark dot marshall at omicronenergy 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>
Márton Németh <nm127 at freemail dot hu> Márton Németh <nm127 at freemail dot hu>
Matt Eaton <agnosticdev at gmail dot com>
Matthew Luckie <mjl at luckie dot org dot nz> Matthew Luckie <mjl at luckie dot org dot nz>
Matthias Hannig <matthias at hannig dot cc>
Matwey V. Kornilov <matwey dot kornilov at gmail dot com>
maxice8 <thinkabit dot ukim at gmail dot com>
Max Laier <max at love2party dot net> Max Laier <max at love2party dot net>
Michal Kubecek <mkubecek at suse dot cz> Michal Kubecek <mkubecek at suse dot cz>
Michal Labedzki <michal dot labedzki at tieto dot com> Michal Labedzki <michal dot labedzki at tieto dot com>
@@ -119,25 +161,36 @@ Additional people who have contributed patches (in alphabetical order):
Mike Frysinger <vapier at gmail dot com> Mike Frysinger <vapier at gmail dot com>
Mike Kershaw <dragorn at kismetwireless dot net> Mike Kershaw <dragorn at kismetwireless dot net>
Mike Wiacek <mike at iroot dot net> Mike Wiacek <mike at iroot dot net>
Milosz Kaniewski <milosz dot kaniewski at gmail dot com>
Miroslav Lichvar <mlichvar at redhat dot com> Miroslav Lichvar <mlichvar at redhat dot com>
Monroe Williams <monroe at pobox dot com> Monroe Williams <monroe at pobox dot com>
Myricom Help <myri at users dot noreply dot github dot com>
Nan Xiao <nan at chinadtrace dot org>
Nick Kelsey <nickk at silicondust dot com>
Nicolas Dade <ndade at nsd dot dyndns dot org> Nicolas Dade <ndade at nsd dot dyndns dot org>
Niko Delarich <niko dot delarich at gmail dot com> Niko Delarich <niko dot delarich at gmail dot com>
N. Leiten <nleiten at sourceforge dot net> N. Leiten <nleiten at sourceforge dot net>
nnposter <nnposter at users dot noreply dot github dot com>
<nvercamm at sourceforge dot net> <nvercamm at sourceforge dot net>
Octavian Cerna <tavy at ylabs dot com> Octavian Cerna <tavy at ylabs dot com>
Olaf Kirch <okir at caldera dot de> Olaf Kirch <okir at caldera dot de>
Ollie Wild <aaw at users dot sourceforge dot net> Ollie Wild <aaw at users dot sourceforge dot net>
Ondřej Hošek <ondra dot hosek at gmail dot com>
Onno van der Linden <onno at simplex dot nl> Onno van der Linden <onno at simplex dot nl>
Orgad Shaneh <orgad dot shaneh at audiocodes dot com>
Ørjan Malde <red at foxi dot me>
Paolo Abeni <pabeni at redhat dot com> Paolo Abeni <pabeni at redhat dot com>
Patrick Marie <mycroft at virgaria dot org> Patrick Marie <mycroft at virgaria dot org>
Patrick McHardy <kaber at trash not net> Patrick McHardy <kaber at trash not net>
Paul Mundt <lethal at linux-sh dot org> Paul Mundt <lethal at linux-sh dot org>
Pavel Kankovsky <kan at dcit dot cz> Pavel Kankovsky <kan at dcit dot cz>
Pawel Brzezinski <pawel dot brzezinski at harman dot com>
Pawel Pokrywka <publicpp at gmail dot com> Pawel Pokrywka <publicpp at gmail dot com>
Peter Fales <peter at fales-lorenz dot net> Peter Fales <peter at fales-lorenz dot net>
Peter Jeremy <peter dot jeremy at alcatel dot com dot au> Peter Jeremy <peter dot jeremy at alcatel dot com dot au>
Peter Volkov <pva at gentoo dot org> Peter Volkov <pva at gentoo dot org>
Petr Vorel <pvorel at suse dot cz>
Philippe Antoine <contact at catenacyber dot fr>
Phil Wood <cpw at lanl dot gov> Phil Wood <cpw at lanl dot gov>
Rafal Maszkowski <rzm at icm dot edu dot pl> Rafal Maszkowski <rzm at icm dot edu dot pl>
<rcb-isis at users dot sourceforge dot net> <rcb-isis at users dot sourceforge dot net>
@@ -145,9 +198,9 @@ Additional people who have contributed patches (in alphabetical order):
Rick Jones <raj at cup dot hp dot com> Rick Jones <raj at cup dot hp dot com>
Robert Edmonds <stu-42 at sourceforge dot net> Robert Edmonds <stu-42 at sourceforge dot net>
Roberto Mariani <jelot-tcpdump at jelot dot it> Roberto Mariani <jelot-tcpdump at jelot dot it>
Rongxi Li <rongxi dot li at chaitin dot com>
Roland Dreier <roland at purestorage dot com> Roland Dreier <roland at purestorage dot com>
Romain Francoise <rfrancoise at debian dot org> Romain Francoise <rfrancoise at debian dot org>
Rongxi Li <rongxi dot li at chaitin dot com>
Sagun Shakya <sagun dot shakya at sun dot com> Sagun Shakya <sagun dot shakya at sun dot com>
Scott Barron <sb125499 at ohiou dot edu> Scott Barron <sb125499 at ohiou dot edu>
Scott Gifford <sgifford at tir dot com> Scott Gifford <sgifford at tir dot com>
@@ -156,22 +209,37 @@ Additional people who have contributed patches (in alphabetical order):
Sebastien Roy <Sebastien dot Roy at Sun dot COM> Sebastien Roy <Sebastien dot Roy at Sun dot COM>
Sepherosa Ziehau <sepherosa at gmail dot com> Sepherosa Ziehau <sepherosa at gmail dot com>
Shaun Clowes <delius at progsoc dot uts dot edu dot au> Shaun Clowes <delius at progsoc dot uts dot edu dot au>
solofox <wensg100 at sina dot com>
Solomon Peachy <pizza at shaftnet dot org> Solomon Peachy <pizza at shaftnet dot org>
Stefan Hudson <hudson at mbay dot net> Stefan Hudson <hudson at mbay dot net>
Stephen Donnelly <stephen at endace dot com> Stephen Donnelly <stephen at endace dot com>
Steve Karg <skarg at users dot sourceforge dot net>
stubbfel <stubbfel at gmail dot com>
Takashi Yamamoto <yamt at mwd dot biglobe dot ne dot jp> Takashi Yamamoto <yamt at mwd dot biglobe dot ne dot jp>
Tanaka Shin-ya <zstanaka at archer dot livedoor dot com> Tanaka Shin-ya <zstanaka at archer dot livedoor dot com>
Thomas Habets <habets at google dot com>
Thomas Petazzoni <thomas dot petazzoni at free-electrons dot com>
Tobias Poschwatta <posch at sourceforge dot net> Tobias Poschwatta <posch at sourceforge dot net>
Tomasz Moń <desowin at gmail dot com>
Tommy Beadle <tbeadle at arbor dot net>
Tony Li <tli at procket dot com> Tony Li <tli at procket dot com>
Torsten Landschoff <torsten at debian dot org> Torsten Landschoff <torsten at debian dot org>
Tymoteusz Blazejczyk <tymoteusz dot blazejczyk at intel dot com>
Uns Lider <unslider at miranda dot org> Uns Lider <unslider at miranda dot org>
Uwe Girlich <Uwe dot Girlich at philosys dot de> Uwe Girlich <Uwe dot Girlich at philosys dot de>
Vitaly Lavrov <vel21ripn at gmail dot com>
Vivien Didelot <vivien dot didelot at gmail dot com>
Vladimir Gladkov <vovkos at gmail dot com>
Vladimir Marek <vlmarek at volny dot cz>
Walter Schell <walterschell at users dot noreply dot github dot com>
Wesley Shields <wxs at FreeBSD dot org> Wesley Shields <wxs at FreeBSD dot org>
Xianjie Zhang <xzhang at cup dot hp dot com> Xianjie Zhang <xzhang at cup dot hp dot com>
Xin Li <delphij at FreeBSD dot org> Xin Li <delphij at FreeBSD dot org>
Xue Jiang Qing <xuejianqing at star-net dot cn> Xue Jiang Qing <xuejianqing at star-net dot cn>
Yang Luo <hsluoyz at qq dot com>
Yen Yen Lim Yen Yen Lim
Yoann Vandoorselaere <yoann at prelude-ids dot org> Yoann Vandoorselaere <yoann at prelude-ids dot org>
Yogesh Prasad <yogesh dot prasad at rockwellcollins dot com>
Yvan Vanhullebus <vanhu at sourceforge dot net> Yvan Vanhullebus <vanhu at sourceforge dot net>
The original LBL crew: The original LBL crew:

View File

@@ -41,8 +41,8 @@ You will need either Bison, Berkeley YACC, or a version of YACC
compatible with them (if any exist), to build libpcap. The configure compatible with them (if any exist), to build libpcap. The configure
script will abort if there isn't any such program. If you don't have 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 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 https://ftp.gnu.org/gnu/bison/ and the current version of Berkeley YACC
can be found at http://invisible-island.net/byacc/. can be found at https://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.
@@ -206,7 +206,7 @@ it appears that completely new code would need to be written to capture
network traffic. SCO do not appear to provide tcpdump binaries for network traffic. SCO do not appear to provide tcpdump binaries for
OpenServer 5 or OpenServer 6 as part of SCO Skunkware: OpenServer 5 or OpenServer 6 as part of SCO Skunkware:
http://www.sco.com/skunkware/ http://www.sco.com/skunkware/
If you use UnixWare, you might be able to build libpcap from this If you use UnixWare, you might be able to build libpcap from this
release, or you might not. We do not have a machine running UnixWare, release, or you might not. We do not have a machine running UnixWare,
@@ -221,7 +221,7 @@ 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:
http://ftp.gnu.org/gnu/bison/ https://ftp.gnu.org/gnu/bison/
or hack around it by inserting the lines: or hack around it by inserting the lines:
@@ -248,105 +248,104 @@ config and boot the new kernel.
FILES FILES
----- -----
CHANGES - description of differences between releases CHANGES - description of differences between releases
ChmodBPF/* - macOS startup item to set ownership and permissions ChmodBPF/* - macOS startup item to set ownership and permissions on /dev/bpf*
on /dev/bpf* CMakeLists.txt - CMake file
CMakeLists.txt - CMake file CONTRIBUTING.md - guidelines for contributing
CONTRIBUTING - guidelines for contributing CREDITS - people that have helped libpcap along
CREDITS - people that have helped libpcap along INSTALL.md - this file
INSTALL.md - this file LICENSE - the license under which tcpdump is distributed
LICENSE - the license under which tcpdump is distributed Makefile.in - compilation rules (input to the configure script)
Makefile.in - compilation rules (input to the configure script) README.md - description of distribution
README.md - description of distribution doc/README.aix - notes on using libpcap on AIX
doc/README.aix - notes on using libpcap on AIX doc/README.dag - notes on using libpcap to capture on Endace DAG devices
doc/README.dag - notes on using libpcap to capture on Endace DAG devices doc/README.hpux - notes on using libpcap on HP-UX
doc/README.hpux - notes on using libpcap on HP-UX doc/README.linux - notes on using libpcap on Linux
doc/README.linux.md - notes on using libpcap on Linux doc/README.macos - notes on using libpcap on macOS
doc/README.macos - notes on using libpcap on macOS doc/README.septel - notes on using libpcap to capture on Intel/Septel devices
doc/README.septel - notes on using libpcap to capture on Intel/Septel devices doc/README.sita - notes on using libpcap to capture on SITA devices
doc/README.sita - notes on using libpcap to capture on SITA devices doc/README.tru64 - notes on using libpcap on Digital/Tru64 UNIX
doc/README.tru64 - notes on using libpcap on Digital/Tru64 UNIX doc/README.Win32.md - notes on using libpcap on Win32 systems (with Npcap)
doc/README.Win32 - notes on using libpcap on Win32 systems (with Npcap) VERSION - version of this release
VERSION - version of this release acconfig.h - support for post-2.13 autoconf
acconfig.h - support for post-2.13 autoconf aclocal.m4 - autoconf macros
aclocal.m4 - autoconf macros arcnet.h - ARCNET definitions
arcnet.h - ARCNET definitions atmuni31.h - ATM Q.2931 definitions
atmuni31.h - ATM Q.2931 definitions bpf_dump.c - BPF program printing routines
bpf_dump.c - BPF program printing routines bpf_filter.c - BPF filtering routines
bpf_filter.c - BPF filtering routines bpf_image.c - BPF disassembly routine
bpf_image.c - BPF disassembly routine config.guess - autoconf support
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.ac - 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 ethertype.h - Ethernet protocol types and names definitions
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 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 gencode.h - BPF code generation definitions
gencode.h - BPF code generation definitions grammar.y - filter string grammar
grammar.y - filter string grammar ieee80211.h - 802.11 definitions
ieee80211.h - 802.11 definitions install-sh - BSD style install script
install-sh - BSD style install script lbl/os-*.h - OS-dependent defines and prototypes
lbl/os-*.h - OS-dependent defines and prototypes llc.h - 802.2 LLC SAP definitions
llc.h - 802.2 LLC SAP definitions missing/* - replacements for missing library functions
missing/* - replacements for missing library functions mkdep - construct Makefile dependency list
mkdep - construct Makefile dependency list msdos/* - drivers for MS-DOS capture support
msdos/* - drivers for MS-DOS capture support nametoaddr.c - hostname to address routines
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 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 pcap/pcap.h - public libpcap definitions
pcap/pcap.h - public libpcap definitions pcap/sll.h - public definitions of DLT_LINUX_SLL and DLT_LINUX_SLL2 headers
pcap/sll.h - public definition of DLT_LINUX_SLL header pcap/usb.h - public definition of DLT_USB header
pcap/usb.h - public definition of DLT_USB header pcap-bpf.c - BSD Packet Filter support
pcap-bpf.c - BSD Packet Filter support pcap-bpf.h - header for backwards compatibility
pcap-bpf.h - header for backwards compatibility pcap-bt-linux.c - Bluetooth capture support for Linux
pcap-bt-linux.c - Bluetooth capture support for Linux pcap-bt-linux.h - Bluetooth capture support for Linux
pcap-bt-linux.h - Bluetooth capture support for Linux pcap-dag.c - Endace DAG device capture support
pcap-dag.c - Endace DAG device capture support pcap-dag.h - Endace DAG device capture support
pcap-dag.h - Endace DAG device capture support pcap-dlpi.c - Data Link Provider Interface support
pcap-dlpi.c - Data Link Provider Interface support pcap-dos.c - MS-DOS capture support
pcap-dos.c - MS-DOS capture support pcap-dos.h - headers for MS-DOS capture support
pcap-dos.h - headers for MS-DOS capture support pcap-enet.c - enet support
pcap-enet.c - enet support pcap-int.h - internal libpcap definitions
pcap-int.h - internal libpcap definitions pcap-libdlpi.c - Data Link Provider Interface support for systems with libdlpi
pcap-libdlpi.c - Data Link Provider Interface support for systems with libdlpi pcap-linux.c - Linux packet socket support
pcap-linux.c - Linux packet socket support pcap-namedb.h - header for backwards compatibility
pcap-namedb.h - header for backwards compatibility pcap-nit.c - SunOS Network Interface Tap support
pcap-nit.c - SunOS Network Interface Tap support pcap-nit.h - SunOS Network Interface Tap definitions
pcap-nit.h - SunOS Network Interface Tap definitions pcap-npf.c - Npcap capture support
pcap-npf.c - WinPcap capture support pcap-null.c - dummy monitor support (allows offline use of libpcap)
pcap-null.c - dummy monitor support (allows offline use of libpcap) pcap-pf.c - Ultrix and Digital/Tru64 UNIX Packet Filter support
pcap-pf.c - Ultrix and Digital/Tru64 UNIX Packet Filter support pcap-pf.h - Ultrix and Digital/Tru64 UNIX Packet Filter definitions
pcap-pf.h - Ultrix and Digital/Tru64 UNIX Packet Filter definitions pcap-septel.c - Intel/Septel device capture support
pcap-septel.c - Intel/Septel device capture support pcap-septel.h - Intel/Septel device capture support
pcap-septel.h - Intel/Septel device capture support pcap-sita.c - SITA device capture support
pcap-sita.c - SITA device capture support pcap-sita.h - SITA device capture support
pcap-sita.h - SITA device capture support pcap-sita.html - SITA device capture documentation
pcap-sita.html - SITA device capture documentation pcap-stdinc.h - includes and #defines for compiling on Win32 systems
pcap-stdinc.h - includes and #defines for compiling on Win32 systems pcap-snit.c - SunOS 4.x STREAMS-based Network Interface Tap support
pcap-snit.c - SunOS 4.x STREAMS-based Network Interface Tap support pcap-snoop.c - IRIX Snoop network monitoring support
pcap-snoop.c - IRIX Snoop network monitoring support pcap-usb-linux.c - USB capture support for Linux
pcap-usb-linux.c - USB capture support for Linux pcap-usb-linux.h - USB capture support for Linux
pcap-usb-linux.h - USB capture support for Linux pcap.3pcap - manual entry for the library
pcap.3pcap - manual entry for the library pcap.c - pcap utility routines
pcap.c - pcap utility routines pcap.h - header for backwards compatibility
pcap.h - header for backwards compatibility pcap_*.3pcap - manual entries for library functions
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 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 Win32 - headers and routines for building on Win32 systems
Win32 - headers and routines for building on Win32 systems

View File

@@ -3,12 +3,12 @@
# From autoconf.info . Works best with GNU Make. # From autoconf.info . Works best with GNU Make.
# #
${srcdir}/configure: configure.ac 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.ac 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
config.h: stamp-h config.h: stamp-h

View File

@@ -38,6 +38,7 @@ mandir = @mandir@
# VPATH # VPATH
srcdir = @srcdir@ srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@ VPATH = @srcdir@
# #
@@ -70,6 +71,7 @@ EXTRA_NETWORK_LIBS=@EXTRA_NETWORK_LIBS@
# Standard CFLAGS for building members of a shared library # Standard CFLAGS for building members of a shared library
FULL_CFLAGS = $(CCOPT) @V_LIB_CCOPT_FAT@ $(SHLIB_CCOPT) $(INCLS) $(DEFS) $(CFLAGS) FULL_CFLAGS = $(CCOPT) @V_LIB_CCOPT_FAT@ $(SHLIB_CCOPT) $(INCLS) $(DEFS) $(CFLAGS)
CXXFLAGS = $(CCOPT) @V_LIB_CCOPT_FAT@ $(SHLIB_CCOPT) $(INCLS) $(DEFS) $(CFLAGS)
INSTALL = @INSTALL@ INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
@@ -83,21 +85,29 @@ RANLIB = @RANLIB@
@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@ @NETFILTER_SRC@ @DBUS_SRC@ @NETMAP_SRC@ @RDMA_SRC@ PLATFORM_C_SRC = @PLATFORM_C_SRC@
FSRC = @V_FINDALLDEVS@ PLATFORM_CXX_SRC = @PLATFORM_CXX_SRC@
SSRC = @SSRC@ MODULE_C_SRC = @MODULE_C_SRC@
CSRC = pcap.c gencode.c optimize.c nametoaddr.c etherent.c \ REMOTE_C_SRC = @REMOTE_C_SRC@
fmtutils.c \ COMMON_C_SRC = pcap.c gencode.c optimize.c nametoaddr.c etherent.c \
savefile.c sf-pcap.c sf-pcapng.c pcap-common.c \ fmtutils.c \
bpf_image.c bpf_filter.c bpf_dump.c savefile.c sf-pcap.c sf-pcapng.c pcap-common.c \
GENSRC = scanner.c grammar.c bpf_image.c bpf_filter.c bpf_dump.c
GENERATED_C_SRC = scanner.c grammar.c
LIBOBJS = @LIBOBJS@ LIBOBJS = @LIBOBJS@
SRC = $(PSRC) $(FSRC) $(CSRC) $(SSRC) $(GENSRC) SRC = $(PLATFORM_C_SRC) $(PLATFORM_CXX_SRC) \
$(MODULE_C_SRC) $(REMOTE_C_SRC) $(COMMON_C_SRC) \
$(GENERATED_C_SRC)
# We would like to say "OBJ = $(SRC:.c=.o)" but Ultrix's make cannot # We would like to say "OBJ = $(SRC:.c=.o)" but Ultrix's make cannot
# hack the extra indirection # hack the extra indirection, and we have to handle PLATFORM_CXX_SRC
OBJ = $(PSRC:.c=.o) $(FSRC:.c=.o) $(CSRC:.c=.o) $(SSRC:.c=.o) $(GENSRC:.c=.o) $(LIBOBJS) # differently from the defines for C source
OBJ = $(PLATFORM_C_SRC:.c=.o) $(PLATFORM_CXX_SRC:.cpp=.o) \
$(MODULE_C_SRC:.c=.o) $(REMOTE_C_SRC:.c=.o) $(COMMON_C_SRC:.c=.o) \
$(GENERATED_C_SRC:.c=.o) \
$(LIBOBJS)
PUBHDR = \ PUBHDR = \
pcap.h \ pcap.h \
pcap-bpf.h \ pcap-bpf.h \
@@ -190,6 +200,7 @@ MAN3PCAP_NOEXPAND = \
pcap_get_required_select_timeout.3pcap \ pcap_get_required_select_timeout.3pcap \
pcap_get_selectable_fd.3pcap \ pcap_get_selectable_fd.3pcap \
pcap_geterr.3pcap \ pcap_geterr.3pcap \
pcap_init.3pcap \
pcap_inject.3pcap \ pcap_inject.3pcap \
pcap_is_swapped.3pcap \ pcap_is_swapped.3pcap \
pcap_lib_version.3pcap \ pcap_lib_version.3pcap \
@@ -243,10 +254,13 @@ EXTRA_DIST = \
TODO \ TODO \
VERSION \ VERSION \
aclocal.m4 \ aclocal.m4 \
charconv.c \
charconv.h \
chmod_bpf \ chmod_bpf \
cmake_uninstall.cmake.in \ cmake_uninstall.cmake.in \
cmakeconfig.h.in \ cmakeconfig.h.in \
cmake/Modules/FindDAG.cmake \ cmake/Modules/FindDAG.cmake \
cmake/Modules/Finddpdk.cmake \
cmake/Modules/FindFseeko.cmake \ cmake/Modules/FindFseeko.cmake \
cmake/Modules/FindLFS.cmake \ cmake/Modules/FindLFS.cmake \
cmake/Modules/FindPacket.cmake \ cmake/Modules/FindPacket.cmake \
@@ -263,7 +277,7 @@ EXTRA_DIST = \
fad-getad.c \ fad-getad.c \
fad-gifc.c \ fad-gifc.c \
fad-glifc.c \ fad-glifc.c \
grammar.y \ grammar.y.in \
install-sh \ install-sh \
lbl/os-aix4.h \ lbl/os-aix4.h \
lbl/os-aix7.h \ lbl/os-aix7.h \
@@ -277,12 +291,10 @@ EXTRA_DIST = \
missing/asprintf.c \ missing/asprintf.c \
missing/getopt.c \ missing/getopt.c \
missing/getopt.h \ missing/getopt.h \
missing/snprintf.c \
missing/strlcat.c \ missing/strlcat.c \
missing/strlcpy.c \ missing/strlcpy.c \
missing/strtok_r.c \ missing/strtok_r.c \
missing/win_asprintf.c \ missing/win_asprintf.c \
missing/win_snprintf.c \
mkdep \ mkdep \
msdos/bin2c.c \ msdos/bin2c.c \
msdos/makefile \ msdos/makefile \
@@ -295,6 +307,8 @@ EXTRA_DIST = \
msdos/readme.dos \ msdos/readme.dos \
nomkdep \ nomkdep \
org.tcpdump.chmod_bpf.plist \ org.tcpdump.chmod_bpf.plist \
pcap-airpcap.c \
pcap-airpcap.h \
pcap-bpf.c \ pcap-bpf.c \
pcap-bt-linux.c \ pcap-bt-linux.c \
pcap-bt-linux.h \ pcap-bt-linux.h \
@@ -309,7 +323,10 @@ EXTRA_DIST = \
pcap-dlpi.c \ pcap-dlpi.c \
pcap-dos.c \ pcap-dos.c \
pcap-dos.h \ pcap-dos.h \
pcap-dpdk.c \
pcap-dpdk.h \
pcap-enet.c \ pcap-enet.c \
pcap-haiku.cpp \
pcap-int.h \ pcap-int.h \
pcap-libdlpi.c \ pcap-libdlpi.c \
pcap-linux.c \ pcap-linux.c \
@@ -364,6 +381,8 @@ EXTRA_DIST = \
rpcapd/win32-svc.h \ rpcapd/win32-svc.h \
sockutils.c \ sockutils.c \
sockutils.h \ sockutils.h \
sslutils.c \
sslutils.h \
scanner.l \ scanner.l \
testprogs/CMakeLists.txt \ testprogs/CMakeLists.txt \
testprogs/Makefile.in \ testprogs/Makefile.in \
@@ -371,12 +390,23 @@ EXTRA_DIST = \
testprogs/capturetest.c \ testprogs/capturetest.c \
testprogs/filtertest.c \ testprogs/filtertest.c \
testprogs/findalldevstest.c \ testprogs/findalldevstest.c \
testprogs/findalldevstest-perf.c \
testprogs/fuzz/CMakeLists.txt \
testprogs/fuzz/fuzz_both.c \
testprogs/fuzz/fuzz_both.options \
testprogs/fuzz/fuzz_filter.c \
testprogs/fuzz/fuzz_filter.options \
testprogs/fuzz/fuzz_pcap.c \
testprogs/fuzz/fuzz_pcap.options \
testprogs/fuzz/onefile.c \
testprogs/opentest.c \ testprogs/opentest.c \
testprogs/reactivatetest.c \ testprogs/reactivatetest.c \
testprogs/selpolltest.c \ testprogs/selpolltest.c \
testprogs/threadsignaltest.c \ testprogs/threadsignaltest.c \
testprogs/unix.h \ testprogs/unix.h \
testprogs/valgrindtest.c \ testprogs/valgrindtest.c \
testprogs/visopts.py \
testprogs/writecaptest.c \
tests/shb-option-too-long.pcapng \ tests/shb-option-too-long.pcapng \
Win32/Prj/wpcap.sln \ Win32/Prj/wpcap.sln \
Win32/Prj/wpcap.vcxproj \ Win32/Prj/wpcap.vcxproj \
@@ -477,6 +507,25 @@ libpcap.none:
scanner.o: scanner.c grammar.h scanner.o: scanner.c grammar.h
$(CC) $(FULL_CFLAGS) -c scanner.c $(CC) $(FULL_CFLAGS) -c scanner.c
#
# Generate the grammar.y file.
#
# Some Makes, e.g. AIX Make and Solaris Make, can't handle "--file=$@.tmp:$<";
# for example, the Solaris 9 make man page says
#
# Because make assigns $< and $* as it would for implicit rules
# (according to the suffixes list and the directory contents),
# they may be unreliable when used within explicit target entries.
#
# and this is an explicit target entry.
#
# Therefore, instead of using $<, we explicitly put in $(srcdir)/libpcap.pc.in.
#
grammar.y: $(srcdir)/grammar.y.in ./config.status
@rm -f $@ $@.tmp
./config.status --file=$@.tmp:$(srcdir)/grammar.y.in
mv $@.tmp $@
grammar.o: grammar.c scanner.h grammar.o: grammar.c scanner.h
$(CC) $(FULL_CFLAGS) -c grammar.c $(CC) $(FULL_CFLAGS) -c grammar.c
@@ -516,7 +565,6 @@ libpcap.pc: $(srcdir)/libpcap.pc.in ./config.status
@rm -f $@ $@.tmp @rm -f $@ $@.tmp
./config.status --file=$@.tmp:$(srcdir)/libpcap.pc.in ./config.status --file=$@.tmp:$(srcdir)/libpcap.pc.in
mv $@.tmp $@ mv $@.tmp $@
chmod a+x $@
# #
# Generate the pcap-config script. See above. # Generate the pcap-config script. See above.
@@ -531,13 +579,13 @@ pcap-config: $(srcdir)/pcap-config.in ./config.status
# Remote pcap daemon. # Remote pcap daemon.
# #
build-rpcapd: libpcap.a build-rpcapd: libpcap.a
cd rpcapd; $(MAKE) (cd rpcapd; $(MAKE))
# #
# Test programs - not built by default, and not installed. # Test programs - not built by default, and not installed.
# #
testprogs: FORCE testprogs: FORCE
cd testprogs; $(MAKE) (cd testprogs; $(MAKE))
FORCE: FORCE:
@@ -669,7 +717,7 @@ install-archive-shareda:
# #
install-rpcapd: install-rpcapd:
cd rpcapd; $(MAKE) DESTDIR=$(DESTDIR) install (cd rpcapd; $(MAKE) DESTDIR=$(DESTDIR) install)
uninstall: uninstall-shared uninstall-rpcapd uninstall: uninstall-shared uninstall-rpcapd
rm -f $(DESTDIR)$(libdir)/libpcap.a rm -f $(DESTDIR)$(libdir)/libpcap.a
@@ -683,6 +731,7 @@ uninstall: uninstall-shared uninstall-rpcapd
for i in $(MAN3PCAP); do \ for i in $(MAN3PCAP); do \
rm -f $(DESTDIR)$(mandir)/man3/$$i; done rm -f $(DESTDIR)$(mandir)/man3/$$i; done
rm -f $(DESTDIR)$(mandir)/man3/pcap_datalink_val_to_description.3pcap rm -f $(DESTDIR)$(mandir)/man3/pcap_datalink_val_to_description.3pcap
rm -f $(DESTDIR)$(mandir)/man3/pcap_datalink_val_to_description_or_dlt.3pcap
rm -f $(DESTDIR)$(mandir)/man3/pcap_dump_fopen.3pcap rm -f $(DESTDIR)$(mandir)/man3/pcap_dump_fopen.3pcap
rm -f $(DESTDIR)$(mandir)/man3/pcap_freealldevs.3pcap rm -f $(DESTDIR)$(mandir)/man3/pcap_freealldevs.3pcap
rm -f $(DESTDIR)$(mandir)/man3/pcap_perror.3pcap rm -f $(DESTDIR)$(mandir)/man3/pcap_perror.3pcap
@@ -725,13 +774,13 @@ uninstall-shared-shareda:
uninstall-shared-none: uninstall-shared-none:
uninstall-rpcapd: uninstall-rpcapd:
cd rpcapd; $(MAKE) DESTDIR=$(DESTDIR) uninstall (cd rpcapd; $(MAKE) DESTDIR=$(DESTDIR) uninstall)
clean: clean:
rm -f $(CLEANFILES) rm -f $(CLEANFILES)
distclean: clean distclean: clean
rm -f Makefile config.cache config.log config.status \ rm -f Makefile grammar.y config.cache config.log config.status \
config.h gnuc.h net os-proto.h libpcap.pc \ config.h gnuc.h net os-proto.h libpcap.pc \
pcap-config stamp-h stamp-h.in pcap-config stamp-h stamp-h.in
rm -f $(MAN3PCAP_EXPAND:.in=) $(MANFILE:.in=) $(MANMISC:.in=) rm -f $(MAN3PCAP_EXPAND:.in=) $(MANFILE:.in=) $(MANMISC:.in=)
@@ -744,13 +793,24 @@ tags: $(TAGFILES)
ctags -wtd $(TAGFILES) ctags -wtd $(TAGFILES)
releasetar: releasetar:
@cwd=`pwd` ; dir=`basename $$cwd` ; name=$(PROG)-`cat VERSION` ; \ @autoreconf -f; \
name=$(PROG)-`cat VERSION` ; \
mkdir $$name; \ mkdir $$name; \
tar -c --exclude='*~' -f - $(CSRC) $(HDR) $(MAN1) $(MAN3PCAP_EXPAND) \ tar -c --exclude='*~' -f - $(COMMON_C_SRC) $(HDR) $(MAN1) \
$(MAN3PCAP_NOEXPAND) $(MANFILE) $(MANMISC) $(EXTRA_DIST) | \ $(MAN3PCAP_EXPAND) $(MAN3PCAP_NOEXPAND) $(MANFILE) \
$(MANMISC) $(EXTRA_DIST) | \
(cd $$name; tar xf -); \ (cd $$name; tar xf -); \
tar -c -z -f $$name.tar.gz $$name; \ tar -c -z -f $$name.tar.gz $$name; \
rm -rf $$name rm -rf $$name
depend: $(GENSRC) $(GENHDR) rc1 rc2 rc3 rc4 rc5:
$(MKDEP) -c "$(CC)" -m "$(DEPENDENCY_CFLAG)" $(CFLAGS) $(DEFS) $(INCLS) $(SRC) @VER=`cat $(srcdir)/VERSION`; \
sed -i "s/$$VER/$${VER}$@/" VERSION ; \
make releasetar; \
git checkout VERSION configure
depend: $(GENERATED_C_SRC) $(GENHDR)
$(MKDEP) -c "$(CC)" -m "$(DEPENDENCY_CFLAG)" -s "$(srcdir)" $(CFLAGS) $(DEFS) $(INCLS) $(SRC)
shellcheck:
shellcheck -f gcc build.sh build_matrix.sh

View File

@@ -1,27 +1,25 @@
diff --git a/libpcap/Makefile.in b/libpcap/Makefile.in --- libpcap-1.10.1/Makefile.in 2021-06-07 20:21:35.000000000 +0000
index 5a6b165..e7f4167 100644 +++ libpcap/Makefile.in 2022-08-31 18:00:55.284383667 +0000
--- a/libpcap/Makefile.in @@ -78,9 +78,6 @@
+++ b/libpcap/Makefile.in
@@ -76,9 +76,6 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@ INSTALL_DATA = @INSTALL_DATA@
RANLIB = @RANLIB@ RANLIB = @RANLIB@
-LEX = @LEX@ -LEX = @LEX@
-YACC = @YACC@ -BISON_BYACC = @BISON_BYACC@
- -
# 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
# problem if you don't own the file but can write to the directory. # problem if you don't own the file but can write to the directory.
@@ -154,7 +151,7 @@ TAGFILES = \ @@ -164,7 +161,7 @@
$(SRC) $(HDR) $(SRC) $(HDR)
CLEANFILES = $(OBJ) libpcap.a libpcap.so.`cat $(srcdir)/VERSION` \ CLEANFILES = $(OBJ) libpcap.a libpcap.so.`cat $(srcdir)/VERSION` \
- $(PROG)-`cat $(srcdir)/VERSION`.tar.gz $(GENSRC) $(GENHDR) \ - $(PROG)-`cat $(srcdir)/VERSION`.tar.gz $(GENERATED_C_SRC) $(GENHDR) \
+ $(PROG)-`cat $(srcdir)/VERSION`.tar.gz \ + $(PROG)-`cat $(srcdir)/VERSION`.tar.gz \
lex.yy.c pcap-config libpcap.pc lex.yy.c pcap-config libpcap.pc
MAN1 = pcap-config.1 MAN1 = pcap-config.1
@@ -387,6 +384,15 @@ EXTRA_DIST = \ @@ -417,6 +414,15 @@
all: libpcap.a shared $(BUILD_RPCAPD) libpcap.pc pcap-config all: libpcap.a shared $(BUILD_RPCAPD) libpcap.pc pcap-config
@@ -37,7 +35,7 @@ index 5a6b165..e7f4167 100644
libpcap.a: $(OBJ) libpcap.a: $(OBJ)
@rm -f $@ @rm -f $@
$(AR) rc $@ $(OBJ) $(ADDLARCHIVEOBJS) $(AR) rc $@ $(OBJ) $(ADDLARCHIVEOBJS)
@@ -468,27 +474,9 @@ libpcap.shareda: $(OBJ) @@ -498,15 +504,6 @@
# #
libpcap.none: libpcap.none:
@@ -53,8 +51,12 @@ index 5a6b165..e7f4167 100644
scanner.o: scanner.c grammar.h scanner.o: scanner.c grammar.h
$(CC) $(FULL_CFLAGS) -c scanner.c $(CC) $(FULL_CFLAGS) -c scanner.c
-grammar.c: $(srcdir)/grammar.y @@ -529,15 +526,6 @@
- $(YACC) -p pcap_ -o grammar.c -d $< ./config.status --file=$@.tmp:$(srcdir)/grammar.y.in
mv $@.tmp $@
-grammar.c: grammar.y
- $(BISON_BYACC) -p pcap_ -o grammar.c -d $<
-grammar.h: grammar.c -grammar.h: grammar.c
-## Recover from the removal of $@ -## Recover from the removal of $@
- @if test -f $@; then :; else \ - @if test -f $@; then :; else \
@@ -65,11 +67,9 @@ index 5a6b165..e7f4167 100644
grammar.o: grammar.c scanner.h grammar.o: grammar.c scanner.h
$(CC) $(FULL_CFLAGS) -c grammar.c $(CC) $(FULL_CFLAGS) -c grammar.c
diff --git a/libpcap/configure.ac b/libpcap/configure.ac --- libpcap-1.10.1/configure.ac 2021-06-07 20:21:35.000000000 +0000
index 6255f07..5e741cb 100644 +++ libpcap/configure.ac 2022-08-31 18:02:07.017322554 +0000
--- a/libpcap/configure.ac @@ -1716,106 +1716,6 @@
+++ b/libpcap/configure.ac
@@ -1594,50 +1594,6 @@ fi
AC_MSG_RESULT(${enable_yydebug-no}) AC_MSG_RESULT(${enable_yydebug-no})
# #
@@ -97,35 +97,90 @@ index 6255f07..5e741cb 100644
- -
-# -#
-# Look for yacc/bison/byacc. -# Look for yacc/bison/byacc.
-# If it's Bison, we do not want -y, as 1) we will be using -o to cause
-# the output for XXX.y to be written to XXX.c and 2) we don't want
-# it to issue warnings about stuff not supported by POSIX YACC - we
-# want to use that stuff, and don't care whether plain YACC supports
-# it or not, we require either Bison or Berkeley YACC.
-# -#
-AC_PROG_YACC -BISON_BYACC=""
-
-# -#
-# Make sure it supports the -p flag and supports processing our -# Look for Bison.
-# grammar.y.
-# -#
-AC_CACHE_CHECK([for capable yacc/bison], tcpdump_cv_capable_yacc, -AC_CHECK_PROGS(BISON_BYACC, bison)
- if $YACC -p pcap_ -o /dev/null $srcdir/grammar.y >/dev/null 2>&1; then -if test x"$BISON_BYACC" != x; then
- tcpdump_cv_capable_yacc=yes - #
- # We found Bison.
- #
- # Bison prior to 2.4(.1) doesn't support "%define api.pure", so use
- # "%pure-parser".
- #
- bison_major_version=`$BISON_BYACC -V | sed -n 's/.* \(@<:@1-9@:>@@<:@0-9@:>@*\)\.@<:@0-9@:>@@<:@0-9.@:>@*/\1/p'`
- bison_minor_version=`$BISON_BYACC -V | sed -n 's/.* @<:@1-9@:>@@<:@0-9@:>@*\.\(@<:@0-9@:>@+\).*/\1/p'`
- if test "$bison_major_version" -lt 2 -o \
- \( "$bison_major_version" -eq 2 -a "$bison_major_version" -lt 4 \)
- then
- REENTRANT_PARSER="%pure-parser"
- else - else
- tcpdump_cv_capable_yacc=insufficient - REENTRANT_PARSER="%define api.pure"
- fi) - fi
-if test $tcpdump_cv_capable_yacc = insufficient ; then -else
- AC_MSG_ERROR([$YACC is insufficient to compile libpcap. - #
- # We didn't find Bison; check for Berkeley YACC, under the
- # names byacc and yacc.
- #
- AC_CHECK_PROGS(BISON_BYACC, byacc yacc)
- if test x"$BISON_BYACC" != x; then
- #
- # Make sure this is Berkeley YACC, not AT&T YACC;
- # the latter doesn't support reentrant parsers.
- # Run it with "-V"; that succeeds and reports the
- # version number with Berkeley YACC, but will
- # (probably) fail with various vendor flavors
- # of AT&T YACC.
- #
- # Hopefully this also eliminates any versions
- # of Berkeley YACC that don't support reentrant
- # parsers, if there are any.
- #
- AC_CACHE_CHECK([for capable yacc], tcpdump_cv_capable_yacc,
- if $BISON_BYACC -V >/dev/null 2>&1; then
- tcpdump_cv_capable_yacc=yes
- else
- tcpdump_cv_capable_yacc=insufficient
- fi)
- if test $tcpdump_cv_capable_yacc = insufficient ; then
- AC_MSG_ERROR([$YACC is insufficient to compile libpcap.
- libpcap requires Bison, a newer version of Berkeley YACC with support - libpcap requires Bison, a newer version of Berkeley YACC with support
- for reentrant parsers, or another YACC compatible with them.]) - for reentrant parsers, or another YACC compatible with them.])
- fi
- else
- #
- # OK, we found neither byacc nor yacc.
- #
- AC_MSG_ERROR([Neither bison, byacc, nor yacc was found.
- libpcap requires Bison, a newer version of Berkeley YACC with support
- for reentrant parsers, or another YACC compatible with them.])
- fi
-
- #
- # Berkeley YACC doesn't support "%define api.pure", so use
- # "%pure-parser".
- #
- REENTRANT_PARSER="%pure-parser"
-fi -fi
-AC_SUBST(BISON_BYACC)
-AC_SUBST(REENTRANT_PARSER)
- -
-# -#
# Do various checks for various OSes and versions of those OSes. # Do various checks for various OSes and versions of those OSes.
# #
# Assume, by default, no support for shared libraries and V7/BSD # Assume, by default, no support for shared libraries and V7/BSD
@@ -2050,14 +2006,12 @@ AC_SUBST(V_PROG_LDFLAGS_FAT) @@ -2237,13 +2137,11 @@
AC_SUBST(V_PROG_LDFLAGS_FAT)
AC_SUBST(V_DEFS) AC_SUBST(V_DEFS)
AC_SUBST(V_FINDALLDEVS)
AC_SUBST(V_INCLS) AC_SUBST(V_INCLS)
-AC_SUBST(V_LEX) -AC_SUBST(V_LEX)
AC_SUBST(V_PCAP)
AC_SUBST(V_SHLIB_CCOPT) AC_SUBST(V_SHLIB_CCOPT)
AC_SUBST(V_SHLIB_CMD) AC_SUBST(V_SHLIB_CMD)
AC_SUBST(V_SHLIB_OPT) AC_SUBST(V_SHLIB_OPT)
@@ -134,4 +189,4 @@ index 6255f07..5e741cb 100644
-AC_SUBST(V_YACC) -AC_SUBST(V_YACC)
AC_SUBST(ADDLOBJS) AC_SUBST(ADDLOBJS)
AC_SUBST(ADDLARCHIVEOBJS) AC_SUBST(ADDLARCHIVEOBJS)
AC_SUBST(SSRC) AC_SUBST(PLATFORM_C_SRC)

View File

@@ -1,109 +1,9 @@
diff --git a/libpcap/configure b/libpcap/configure
index fa15fc7..e40a4c4 100755
--- a/libpcap/configure
+++ b/libpcap/configure
@@ -1416,16 +1416,12 @@ Optional Features:
--enable-optimizer-dbg build optimizer debugging code
--enable-yydebug build parser debugging code
--disable-universal don't build universal on macOS
- --enable-shared build shared libraries [default=yes, if support
- available]
- --enable-usb enable USB capture support [default=yes, if support
- available]
+ --enable-shared build shared libraries [default=no]
+ --enable-usb enable USB capture support [default=no]
--enable-netmap enable netmap support [default=yes, if support
available]
- --enable-bluetooth enable Bluetooth support [default=yes, if support
- available]
- --enable-dbus enable D-Bus capture support [default=yes, if
- support available]
+ --enable-bluetooth enable Bluetooth support [default=no]
+ --enable-dbus enable D-Bus capture support [default=no]
--enable-rdma enable RDMA capture support [default=yes, if support
available]
@@ -1435,8 +1431,7 @@ Optional Packages:
--without-gcc don't use gcc
--with-sita include SITA support
--with-pcap=TYPE use packet capture TYPE
- --without-libnl disable libnl support [default=yes, on Linux, if
- present]
+ --without-libnl disable libnl support [default=disabled]
--with-dag[=DIR] include Endace DAG support (located in directory
DIR, if supplied). [default=yes, if present]
--with-dag-includes=IDIR
@@ -6516,7 +6511,7 @@ else
fi
- if test x$with_libnl != xno ; then
+ if test x$with_libnl = xyes ; then
have_any_nl="no"
incdir=-I/usr/include/libnl3
@@ -8572,7 +8567,7 @@ if test "${enable_shared+set}" = set; then :
enableval=$enable_shared;
fi
-test "x$enable_shared" = "xno" && DYEXT="none"
+test "x$enable_shared" != "xyes" && DYEXT="none"
if test -n "$ac_tool_prefix"; then
# Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
@@ -10397,7 +10392,7 @@ $as_echo "#define LBL_ALIGN 1" >>confdefs.h
if test "${enable_usb+set}" = set; then :
enableval=$enable_usb;
else
- enable_usb=yes
+ enable_usb=no
fi
@@ -10646,7 +10641,7 @@ fi
if test "${enable_bluetooth+set}" = set; then :
enableval=$enable_bluetooth;
else
- enable_bluetooth=ifsupportavailable
+ enable_bluetooth=no
fi
@@ -10771,7 +10766,7 @@ fi
if test "${enable_dbus+set}" = set; then :
enableval=$enable_dbus;
else
- enable_dbus=ifavailable
+ enable_dbus=no
fi
@@ -11131,7 +11126,7 @@ ac_config_headers="$ac_config_headers config.h"
ac_config_commands="$ac_config_commands default-1"
-ac_config_files="$ac_config_files Makefile pcap-filter.manmisc pcap-linktype.manmisc pcap-tstamp.manmisc pcap-savefile.manfile pcap.3pcap pcap_compile.3pcap pcap_datalink.3pcap pcap_dump_open.3pcap pcap_get_tstamp_precision.3pcap pcap_list_datalinks.3pcap pcap_list_tstamp_types.3pcap pcap_open_dead.3pcap pcap_open_offline.3pcap pcap_set_immediate_mode.3pcap pcap_set_tstamp_precision.3pcap pcap_set_tstamp_type.3pcap rpcapd/Makefile rpcapd/rpcapd.manadmin rpcapd/rpcapd-config.manfile testprogs/Makefile"
+ac_config_files="$ac_config_files Makefile pcap-filter.manmisc pcap-linktype.manmisc pcap-tstamp.manmisc pcap-savefile.manfile pcap.3pcap pcap_compile.3pcap pcap_datalink.3pcap pcap_dump_open.3pcap pcap_get_tstamp_precision.3pcap pcap_list_datalinks.3pcap pcap_list_tstamp_types.3pcap pcap_open_dead.3pcap pcap_open_offline.3pcap pcap_set_immediate_mode.3pcap pcap_set_tstamp_precision.3pcap pcap_set_tstamp_type.3pcap"
cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
@@ -11851,10 +11846,6 @@ do
"pcap_set_immediate_mode.3pcap") CONFIG_FILES="$CONFIG_FILES pcap_set_immediate_mode.3pcap" ;;
"pcap_set_tstamp_precision.3pcap") CONFIG_FILES="$CONFIG_FILES pcap_set_tstamp_precision.3pcap" ;;
"pcap_set_tstamp_type.3pcap") CONFIG_FILES="$CONFIG_FILES pcap_set_tstamp_type.3pcap" ;;
- "rpcapd/Makefile") CONFIG_FILES="$CONFIG_FILES rpcapd/Makefile" ;;
- "rpcapd/rpcapd.manadmin") CONFIG_FILES="$CONFIG_FILES rpcapd/rpcapd.manadmin" ;;
- "rpcapd/rpcapd-config.manfile") CONFIG_FILES="$CONFIG_FILES rpcapd/rpcapd-config.manfile" ;;
- "testprogs/Makefile") CONFIG_FILES="$CONFIG_FILES testprogs/Makefile" ;;
*) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
esac
diff --git a/libpcap/configure.ac b/libpcap/configure.ac diff --git a/libpcap/configure.ac b/libpcap/configure.ac
index eba2723..6255f07 100644 index eba2723..6255f07 100644
--- a/libpcap/configure.ac --- a/libpcap/configure.ac
+++ b/libpcap/configure.ac +++ b/libpcap/configure.ac
@@ -847,10 +847,10 @@ linux) @@ -860,10 +860,10 @@
# Do we have libnl? # let's drop support for older versions of libnl, too.
# #
AC_ARG_WITH(libnl, AC_ARG_WITH(libnl,
- AC_HELP_STRING([--without-libnl],[disable libnl support @<:@default=yes, on Linux, if present@:>@]), - AC_HELP_STRING([--without-libnl],[disable libnl support @<:@default=yes, on Linux, if present@:>@]),
@@ -112,10 +12,10 @@ index eba2723..6255f07 100644
- if test x$with_libnl != xno ; then - if test x$with_libnl != xno ; then
+ if test x$with_libnl = xyes ; then + if test x$with_libnl = xyes ; then
have_any_nl="no" if test "x$PKGCONFIG" != "xno"; then
#
incdir=-I/usr/include/libnl3 # We have pkg-config; see if we have libnl-genl-3.0
@@ -1993,8 +1993,8 @@ solaris*) @@ -2183,8 +2083,8 @@
esac esac
AC_ARG_ENABLE(shared, AC_ARG_ENABLE(shared,
@@ -126,20 +26,20 @@ index eba2723..6255f07 100644
AC_PROG_RANLIB AC_PROG_RANLIB
AC_CHECK_TOOL([AR], [ar]) AC_CHECK_TOOL([AR], [ar])
@@ -2073,9 +2073,9 @@ AC_SUBST(RPCAPD_LIBS) @@ -2265,9 +2163,9 @@
AC_SUBST(EXTRA_NETWORK_LIBS) # Various Linux-specific mechanisms.
#
AC_ARG_ENABLE([usb], AC_ARG_ENABLE([usb],
-[AC_HELP_STRING([--enable-usb],[enable USB capture support @<:@default=yes, if support available@:>@])], -[AC_HELP_STRING([--enable-usb],[enable Linux usbmon USB capture support @<:@default=yes, if support available@:>@])],
+[AC_HELP_STRING([--enable-usb],[enable USB capture support @<:@default=no@:>@])], +[AC_HELP_STRING([--enable-usb],[enable USB capture support @<:@default=no@:>@])],
[], [],
- [enable_usb=yes]) - [enable_usb=yes])
+ [enable_usb=no]) + [enable_usb=no])
if test "xxx_only" = yes; then #
# User requested something-else-only pcap, so they don't # If somebody requested an XXX-only pcap, that doesn't include
@@ -2221,9 +2221,9 @@ fi @@ -2627,9 +2525,9 @@
AC_SUBST(PCAP_SUPPORT_DPDK)
AC_ARG_ENABLE([bluetooth], AC_ARG_ENABLE([bluetooth],
-[AC_HELP_STRING([--enable-bluetooth],[enable Bluetooth support @<:@default=yes, if support available@:>@])], -[AC_HELP_STRING([--enable-bluetooth],[enable Bluetooth support @<:@default=yes, if support available@:>@])],
@@ -150,7 +50,7 @@ index eba2723..6255f07 100644
if test "xxx_only" = yes; then if test "xxx_only" = yes; then
# User requested something-else-only pcap, so they don't # User requested something-else-only pcap, so they don't
@@ -2306,9 +2306,9 @@ if test "x$enable_bluetooth" != "xno" ; then @@ -2710,9 +2608,9 @@
fi fi
AC_ARG_ENABLE([dbus], AC_ARG_ENABLE([dbus],
@@ -162,7 +62,7 @@ index eba2723..6255f07 100644
if test "xxx_only" = yes; then if test "xxx_only" = yes; then
# User requested something-else-only pcap, so they don't # User requested something-else-only pcap, so they don't
@@ -2460,6 +2460,5 @@ AC_OUTPUT(Makefile pcap-filter.manmisc pcap-linktype.manmisc @@ -2861,6 +2759,5 @@
pcap_list_tstamp_types.3pcap pcap_open_dead.3pcap pcap_list_tstamp_types.3pcap pcap_open_dead.3pcap
pcap_open_offline.3pcap pcap_set_immediate_mode.3pcap pcap_open_offline.3pcap pcap_set_immediate_mode.3pcap
pcap_set_tstamp_precision.3pcap pcap_set_tstamp_type.3pcap pcap_set_tstamp_precision.3pcap pcap_set_tstamp_type.3pcap
@@ -170,31 +70,32 @@ index eba2723..6255f07 100644
- testprogs/Makefile) - testprogs/Makefile)
+ ) + )
exit 0 exit 0
diff --git a/libpcap/Makefile.in b/libpcap/Makefile.in --- libpcap-1.10.1/Makefile.in 2021-06-07 20:21:35.000000000 +0000
index e7f4167..8eed20d 100644 +++ libpcap/Makefile.in 2022-08-31 18:00:55.284383667 +0000
--- a/libpcap/Makefile.in @@ -790,8 +778,6 @@
+++ b/libpcap/Makefile.in
@@ -729,8 +729,6 @@ uninstall-rpcapd:
clean: clean:
rm -f $(CLEANFILES) rm -f $(CLEANFILES)
- cd rpcapd; $(MAKE) clean - (cd rpcapd; $(MAKE) clean)
- cd testprogs; $(MAKE) clean - (cd testprogs; $(MAKE) clean)
distclean: clean distclean: clean
rm -f Makefile config.cache config.log config.status \ rm -f Makefile grammar.y config.cache config.log config.status \
@@ -738,8 +736,6 @@ distclean: clean @@ -799,8 +785,6 @@
pcap-config stamp-h stamp-h.in pcap-config stamp-h stamp-h.in
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
- cd rpcapd; $(MAKE) distclean - (cd rpcapd; $(MAKE) distclean)
- cd testprogs; $(MAKE) distclean - (cd testprogs; $(MAKE) distclean)
extags: $(TAGFILES) extags: $(TAGFILES)
ctags $(TAGFILES) ctags $(TAGFILES)
@@ -758,5 +754,3 @@ releasetar: @@ -827,8 +811,6 @@
depend: $(GENSRC) $(GENHDR) depend: $(GENERATED_C_SRC) $(GENHDR)
$(MKDEP) -c "$(CC)" -m "$(DEPENDENCY_CFLAG)" $(CFLAGS) $(DEFS) $(INCLS) $(SRC) $(MKDEP) -c "$(CC)" -m "$(DEPENDENCY_CFLAG)" -s "$(srcdir)" $(CFLAGS) $(DEFS) $(INCLS) $(SRC)
- cd rpcapd; $(MAKE) depend - (cd rpcapd; $(MAKE) depend)
- cd testprogs; $(MAKE) depend - (cd testprogs; $(MAKE) depend)
shellcheck:
shellcheck -f gcc build.sh build_matrix.sh

View File

@@ -1,22 +1,17 @@
To report a security issue please send an e-mail to security@tcpdump.org. # LIBPCAP 1.x.y by [The Tcpdump Group](https://www.tcpdump.org)
**To report a security issue please send an e-mail to security@tcpdump.org.**
To report bugs and other problems, contribute patches, request a To report bugs and other problems, contribute patches, request a
feature, provide generic feedback etc please see the file feature, provide generic feedback etc please see the
[CONTRIBUTING](CONTRIBUTING.md) in the libpcap source tree root. [guidelines for contributing](CONTRIBUTING.md).
The directory doc/ has README files about specific operating systems and The [documentation directory](doc/) has README files about specific
options. operating systems and options.
LIBPCAP 1.x.y
Now maintained by "The Tcpdump Group"
https://www.tcpdump.org
Anonymous Git is available via: Anonymous Git is available via:
https://github.com/the-tcpdump-group/libpcap.git
formerly from Lawrence Berkeley National Laboratory https://github.com/the-tcpdump-group/libpcap.git
Network Research Group <libpcap@ee.lbl.gov>
ftp://ftp.ee.lbl.gov/old/libpcap-0.4a7.tar.Z
This directory contains source code for libpcap, a system-independent This directory contains source code for libpcap, a system-independent
interface for user-level packet capture. libpcap provides a portable interface for user-level packet capture. libpcap provides a portable
@@ -28,7 +23,14 @@ require this functionality, we've created this system-independent API
to ease in porting and to alleviate the need for several to ease in porting and to alleviate the need for several
system-dependent packet capture modules in each application. system-dependent packet capture modules in each application.
For some platforms there are README.{system} files that discuss issues ```text
formerly from Lawrence Berkeley National Laboratory
Network Research Group <libpcap@ee.lbl.gov>
ftp://ftp.ee.lbl.gov/old/libpcap-0.4a7.tar.Z
```
### Support for particular platforms and BPF
For some platforms there are `README.{system}` files that discuss issues
with the OS's interface for packet capture on those platforms, such as with the OS's interface for packet capture on those platforms, such as
how to enable support for that interface in the OS, if it's not built in how to enable support for that interface in the OS, if it's not built in
by default. by default.
@@ -36,22 +38,10 @@ by default.
The libpcap interface supports a filtering mechanism based on the The libpcap interface supports a filtering mechanism based on the
architecture in the BSD packet filter. BPF is described in the 1993 architecture in the BSD packet filter. BPF is described in the 1993
Winter Usenix paper ``The BSD Packet Filter: A New Architecture for Winter Usenix paper ``The BSD Packet Filter: A New Architecture for
User-level Packet Capture''. A compressed PostScript version can be User-level Packet Capture''
found at ([compressed PostScript](https://www.tcpdump.org/papers/bpf-usenix93.ps.Z),
[gzipped PostScript](https://www.tcpdump.org/papers/bpf-usenix93.ps.gz),
ftp://ftp.ee.lbl.gov/papers/bpf-usenix93.ps.Z [PDF](https://www.tcpdump.org/papers/bpf-usenix93.pdf)).
or
https://www.tcpdump.org/papers/bpf-usenix93.ps.Z
and a gzipped version can be found at
https://www.tcpdump.org/papers/bpf-usenix93.ps.gz
A PDF version can be found at
https://www.tcpdump.org/papers/bpf-usenix93.pdf
Although most packet capture interfaces support in-kernel filtering, Although most packet capture interfaces support in-kernel filtering,
libpcap utilizes in-kernel filtering only for the BPF interface. libpcap utilizes in-kernel filtering only for the BPF interface.
@@ -66,28 +56,23 @@ BSD, and macOS; an older, modified and undocumented version is standard
in AIX. {DEC OSF/1, Digital UNIX, Tru64 UNIX} uses the packetfilter in AIX. {DEC OSF/1, Digital UNIX, Tru64 UNIX} uses the packetfilter
interface but has been extended to accept BPF filters (which libpcap interface but has been extended to accept BPF filters (which libpcap
utilizes). Also, you can add BPF filter support to Ultrix using the utilizes). Also, you can add BPF filter support to Ultrix using the
kernel source and/or object patches available in: kernel source and/or object patches available
[here](https://www.tcpdump.org/other/bpfext42.tar.Z).
https://www.tcpdump.org/other/bpfext42.tar.Z
Linux has a number of BPF based systems, and libpcap does not support Linux has a number of BPF based systems, and libpcap does not support
any of the eBPF mechanisms as yet, although it supports many of the any of the eBPF mechanisms as yet, although it supports many of the
memory mapped receive mechanisms. memory mapped receive mechanisms.
See the [README.linux](doc/README.linux.md) file for more information. See the [Linux-specific README](doc/README.linux) for more information.
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.
Current versions can be found at https://www.tcpdump.org.
- The TCPdump group

View File

@@ -31,5 +31,3 @@ Less urgent items
+ too many functions. There are a lot of functions for everything which + too many functions. There are a lot of functions for everything which
violates the KISS principle. Why do we need pcap_strerror, pcap_perror violates the KISS principle. Why do we need pcap_strerror, pcap_perror
and pcap_geterr? and pcap_geterr?
+ the manpage has a brief description of each function but where is the
big picture? Seems like you need to buy UNP for that...

View File

@@ -1 +1 @@
1.9.1 1.10.1

View File

@@ -0,0 +1,28 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.40629.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wpcap", "wpcap.vcxproj", "{8E92D840-6A36-452A-A13C-6E1BA5A2C5A9}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{8E92D840-6A36-452A-A13C-6E1BA5A2C5A9}.Debug|Win32.ActiveCfg = Debug|Win32
{8E92D840-6A36-452A-A13C-6E1BA5A2C5A9}.Debug|Win32.Build.0 = Debug|Win32
{8E92D840-6A36-452A-A13C-6E1BA5A2C5A9}.Debug|x64.ActiveCfg = Debug|x64
{8E92D840-6A36-452A-A13C-6E1BA5A2C5A9}.Debug|x64.Build.0 = Debug|x64
{8E92D840-6A36-452A-A13C-6E1BA5A2C5A9}.Release|Win32.ActiveCfg = Release|Win32
{8E92D840-6A36-452A-A13C-6E1BA5A2C5A9}.Release|Win32.Build.0 = Release|Win32
{8E92D840-6A36-452A-A13C-6E1BA5A2C5A9}.Release|x64.ActiveCfg = Release|x64
{8E92D840-6A36-452A-A13C-6E1BA5A2C5A9}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,233 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<SccProjectName />
<SccLocalPath />
<ProjectGuid>{8E92D840-6A36-452A-A13C-6E1BA5A2C5A9}</ProjectGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v120</PlatformToolset>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v120</PlatformToolset>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v120</PlatformToolset>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v120</PlatformToolset>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>.\Release\</OutDir>
<IntDir>.\Release\</IntDir>
<LinkIncremental>false</LinkIncremental>
<IncludePath>../../../;$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<IncludePath>../../../;$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>.\Debug\</OutDir>
<IntDir>.\Debug\</IntDir>
<LinkIncremental>true</LinkIncremental>
<IncludePath>../../../;$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<IncludePath>../../../;$(IncludePath)</IncludePath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<InlineFunctionExpansion>Default</InlineFunctionExpansion>
<StringPooling>true</StringPooling>
<FunctionLevelLinking>true</FunctionLevelLinking>
<Optimization>MaxSpeed</Optimization>
<SuppressStartupBanner>true</SuppressStartupBanner>
<WarningLevel>Level3</WarningLevel>
<AdditionalIncludeDirectories>../../;../../lbl/;../../bpf/;../include/;../../../../common;../../../../dag/include;../../../../dag/drv/windows;../../../Win32-Extensions;./;Win32-Extensions;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>HAVE_VERSION_H;__STDC_VERSION__=199901L;HAVE_PACKET_IS_LOOPBACK_ADAPTER;NDEBUG;YY_NEVER_INTERACTIVE;_USRDLL;pcap_EXPORTS;HAVE_STRERROR;__STDC__;INET6;_WINDOWS;ENABLE_REMOTE;WIN32;_U_=;YY_NO_UNISTD_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ResourceCompile>
<Culture>0x0409</Culture>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
<Link>
<AdditionalDependencies>ws2_32.lib;..\..\..\..\packetWin7\Dll\Project\Release No NetMon and AirPcap\Packet.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PreBuildEvent>
<Command>call ..\..\GenVersion.bat ..\..\VERSION ..\..\pcap_version.h.in ..\..\pcap_version.h
win_flex -Ppcap_ -7 --outfile=..\..\scanner.c --header-file=..\..\scanner.h ..\..\scanner.l
win_bison -ppcap_ --yacc --output=..\..\grammar.c --defines ..\..\grammar.y</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<InlineFunctionExpansion>Default</InlineFunctionExpansion>
<StringPooling>true</StringPooling>
<FunctionLevelLinking>true</FunctionLevelLinking>
<Optimization>MaxSpeed</Optimization>
<SuppressStartupBanner>true</SuppressStartupBanner>
<WarningLevel>Level3</WarningLevel>
<AdditionalIncludeDirectories>../../;../../lbl/;../../bpf/;../include/;../../../../common;../../../../dag/include;../../../../dag/drv/windows;../../../Win32-Extensions;./;Win32-Extensions;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>HAVE_VERSION_H;__STDC_VERSION__=199901L;HAVE_PACKET_IS_LOOPBACK_ADAPTER;NDEBUG;YY_NEVER_INTERACTIVE;_USRDLL;pcap_EXPORTS;HAVE_STRERROR;__STDC__;INET6;_WINDOWS;ENABLE_REMOTE;WIN32;_U_=;YY_NO_UNISTD_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ResourceCompile>
<Culture>0x0409</Culture>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
<Link>
<AdditionalDependencies>ws2_32.lib;..\..\..\..\packetWin7\Dll\Project\x64\Release No NetMon and AirPcap\Packet.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PreBuildEvent>
<Command>call ..\..\GenVersion.bat ..\..\VERSION ..\..\pcap_version.h.in ..\..\pcap_version.h
win_flex -Ppcap_ -7 --outfile=..\..\scanner.c --header-file=..\..\scanner.h ..\..\scanner.l
win_bison -ppcap_ --yacc --output=..\..\grammar.c --defines ..\..\grammar.y</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<InlineFunctionExpansion>Default</InlineFunctionExpansion>
<FunctionLevelLinking>false</FunctionLevelLinking>
<Optimization>Disabled</Optimization>
<SuppressStartupBanner>true</SuppressStartupBanner>
<WarningLevel>Level3</WarningLevel>
<MinimalRebuild>true</MinimalRebuild>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<AdditionalIncludeDirectories>../../;../../lbl/;../../bpf/;../include/;../../../../common;../../../../dag/include;../../../../dag/drv/windows;../../../Win32-Extensions;./;Win32-Extensions;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>HAVE_VERSION_H;__STDC_VERSION__=199901L;HAVE_PACKET_IS_LOOPBACK_ADAPTER;_DEBUG;YY_NEVER_INTERACTIVE;_USRDLL;pcap_EXPORTS;HAVE_STRERROR;__STDC__;INET6;_WINDOWS;ENABLE_REMOTE;WIN32;_U_=;YY_NO_UNISTD_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
</ClCompile>
<ResourceCompile>
<Culture>0x0409</Culture>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
<Link>
<AdditionalDependencies>ws2_32.lib;..\..\..\..\packetWin7\Dll\Project\Release No NetMon and AirPcap\Packet.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PreBuildEvent>
<Command>call ..\..\GenVersion.bat ..\..\VERSION ..\..\pcap_version.h.in ..\..\pcap_version.h
win_flex -Ppcap_ -7 --outfile=..\..\scanner.c --header-file=..\..\scanner.h ..\..\scanner.l
win_bison -ppcap_ --yacc --output=..\..\grammar.c --defines ..\..\grammar.y</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<InlineFunctionExpansion>Default</InlineFunctionExpansion>
<FunctionLevelLinking>false</FunctionLevelLinking>
<Optimization>Disabled</Optimization>
<SuppressStartupBanner>true</SuppressStartupBanner>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>../../;../../lbl/;../../bpf/;../include/;../../../../common;../../../../dag/include;../../../../dag/drv/windows;../../../Win32-Extensions;./;Win32-Extensions;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>HAVE_VERSION_H;__STDC_VERSION__=199901L;HAVE_PACKET_IS_LOOPBACK_ADAPTER;_DEBUG;YY_NEVER_INTERACTIVE;_USRDLL;pcap_EXPORTS;HAVE_STRERROR;__STDC__;INET6;_WINDOWS;ENABLE_REMOTE;WIN32;_U_=;YY_NO_UNISTD_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
</ClCompile>
<ResourceCompile>
<Culture>0x0409</Culture>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
<Link>
<AdditionalDependencies>ws2_32.lib;..\..\..\..\packetWin7\Dll\Project\x64\Release No NetMon and AirPcap\Packet.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PreBuildEvent>
<Command>call ..\..\GenVersion.bat ..\..\VERSION ..\..\pcap_version.h.in ..\..\pcap_version.h
win_flex -Ppcap_ -7 --outfile=..\..\scanner.c --header-file=..\..\scanner.h ..\..\scanner.l
win_bison -ppcap_ --yacc --output=..\..\grammar.c --defines ..\..\grammar.y</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\bpf\net\bpf_filter.c" />
<ClCompile Include="..\..\bpf_dump.c" />
<ClCompile Include="..\..\bpf_image.c" />
<ClCompile Include="..\..\etherent.c" />
<ClCompile Include="..\..\gencode.c" />
<ClCompile Include="..\..\grammar.c" />
<ClCompile Include="..\..\inet.c" />
<ClCompile Include="..\..\missing\win_snprintf.c" />
<ClCompile Include="..\..\nametoaddr.c" />
<ClCompile Include="..\..\optimize.c" />
<ClCompile Include="..\..\pcap-common.c" />
<ClCompile Include="..\..\pcap-new.c" />
<ClCompile Include="..\..\pcap-rpcap.c" />
<ClCompile Include="..\..\pcap-win32.c" />
<ClCompile Include="..\..\pcap.c" />
<ClCompile Include="..\..\savefile.c" />
<ClCompile Include="..\..\scanner.c" />
<ClCompile Include="..\..\sf-pcapng.c" />
<ClCompile Include="..\..\sf-pcap.c" />
<ClCompile Include="..\..\sockutils.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\pcap-common.h" />
<ClInclude Include="..\..\pcap-int.h" />
<ClInclude Include="..\..\pcap-rpcap.h" />
<ClInclude Include="..\..\pcap-stdinc.h" />
<ClInclude Include="..\..\pcap.h" />
<ClInclude Include="..\..\remote-ext.h" />
<ClInclude Include="..\..\sockutils.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\..\..\Win32-Extensions\version.rc" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@@ -0,0 +1,107 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="https://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="..\..\bpf_dump.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\bpf\net\bpf_filter.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\bpf_image.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\etherent.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\gencode.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\grammar.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\inet.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\nametoaddr.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\optimize.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\pcap.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\pcap-win32.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\savefile.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\scanner.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\sf-pcap.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\sf-pcapng.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\pcap-common.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\fad-helpers.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\missing\win_snprintf.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\pcap-new.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\pcap-rpcap.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\sockutils.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Filter Include="Header Files">
<UniqueIdentifier>{c51dce5e-0da9-4e33-a235-d5c76c76485c}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files">
<UniqueIdentifier>{5ec9fd4b-10b5-4527-b249-56b53d844fb1}</UniqueIdentifier>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{c90886f0-8973-436b-a7a1-b9e881544f9a}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\pcap-stdinc.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\pcap-common.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\pcap.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\pcap-int.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\pcap-rpcap.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\remote-ext.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\sockutils.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\..\..\Win32-Extensions\version.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
</Project>

461
libpcap/aclocal.m4 vendored
View File

@@ -271,7 +271,7 @@ dnl with the flag in question, and the "treat warnings as errors" flag
dnl set, and don't add the flag to the first argument if the compile dnl set, and don't add the flag to the first argument if the compile
dnl fails; this is for warning options cause problems that can't be dnl fails; this is for warning options cause problems that can't be
dnl worked around. If a third argument is supplied, a fourth argument dnl worked around. If a third argument is supplied, a fourth argument
dnl should also be supplied; it's a message desribing what the test dnl should also be supplied; it's a message describing what the test
dnl program is checking. dnl program is checking.
dnl dnl
AC_DEFUN(AC_LBL_CHECK_COMPILER_OPT, AC_DEFUN(AC_LBL_CHECK_COMPILER_OPT,
@@ -425,14 +425,14 @@ AC_DEFUN(AC_LBL_CHECK_DEPENDENCY_GENERATION_OPT,
if AC_RUN_LOG([eval "$CC $ac_lbl_dependency_flag conftest.c >/dev/null 2>&1"]); then if AC_RUN_LOG([eval "$CC $ac_lbl_dependency_flag conftest.c >/dev/null 2>&1"]); then
AC_MSG_RESULT([yes, with $ac_lbl_dependency_flag]) AC_MSG_RESULT([yes, with $ac_lbl_dependency_flag])
DEPENDENCY_CFLAG="$ac_lbl_dependency_flag" DEPENDENCY_CFLAG="$ac_lbl_dependency_flag"
MKDEP='${srcdir}/mkdep' MKDEP='${top_srcdir}/mkdep'
else else
AC_MSG_RESULT([no]) AC_MSG_RESULT([no])
# #
# We can't run mkdep, so have "make depend" do # We can't run mkdep, so have "make depend" do
# nothing. # nothing.
# #
MKDEP='${srcdir}/nomkdep' MKDEP='${top_srcdir}/nomkdep'
fi fi
rm -rf conftest* rm -rf conftest*
else else
@@ -441,7 +441,7 @@ AC_DEFUN(AC_LBL_CHECK_DEPENDENCY_GENERATION_OPT,
# We can't run mkdep, so have "make depend" do # We can't run mkdep, so have "make depend" do
# nothing. # nothing.
# #
MKDEP='${srcdir}/nomkdep' MKDEP='${top_srcdir}/nomkdep'
fi fi
AC_SUBST(DEPENDENCY_CFLAG) AC_SUBST(DEPENDENCY_CFLAG)
AC_SUBST(MKDEP) AC_SUBST(MKDEP)
@@ -484,8 +484,8 @@ AC_DEFUN(AC_LBL_SHLIBS_INIT,
aix*) aix*)
;; ;;
freebsd*|netbsd*|openbsd*|dragonfly*|linux*|osf*|midipix*) freebsd*|netbsd*|openbsd*|dragonfly*|linux*|osf*|haiku*|midipix*)
# #
# Platforms where the linker is the GNU linker # Platforms where the linker is the GNU linker
# or accepts command-line arguments like # or accepts command-line arguments like
# those the GNU linker accepts. # those the GNU linker accepts.
@@ -514,7 +514,7 @@ AC_DEFUN(AC_LBL_SHLIBS_INIT,
hpux*) hpux*)
V_SHLIB_CCOPT="$V_SHLIB_CCOPT -fpic" V_SHLIB_CCOPT="$V_SHLIB_CCOPT -fpic"
# #
# XXX - this assumes GCC is using the HP linker, # XXX - this assumes GCC is using the HP linker,
# rather than the GNU linker, and that the "+h" # rather than the GNU linker, and that the "+h"
# option is used on all HP-UX platforms, both .sl # option is used on all HP-UX platforms, both .sl
@@ -522,7 +522,7 @@ AC_DEFUN(AC_LBL_SHLIBS_INIT,
# #
V_SONAME_OPT="-Wl,+h," V_SONAME_OPT="-Wl,+h,"
# #
# By default, directories specifed with -L # By default, directories specified with -L
# are added to the run-time search path, so # are added to the run-time search path, so
# we don't add them in pcap-config. # we don't add them in pcap-config.
# #
@@ -583,14 +583,14 @@ AC_DEFUN(AC_LBL_SHLIBS_INIT,
V_SHLIB_OPT="-b" V_SHLIB_OPT="-b"
V_SONAME_OPT="+h " V_SONAME_OPT="+h "
# #
# By default, directories specifed with -L # By default, directories specified with -L
# are added to the run-time search path, so # are added to the run-time search path, so
# we don't add them in pcap-config. # we don't add them in pcap-config.
# #
;; ;;
osf*) osf*)
# #
# Presumed to be DEC OSF/1, Digital UNIX, or # Presumed to be DEC OSF/1, Digital UNIX, or
# Tru64 UNIX. # Tru64 UNIX.
# #
@@ -662,6 +662,48 @@ AC_DEFUN(AC_LBL_C_INLINE,
fi fi
AC_DEFINE_UNQUOTED(inline, $ac_cv_lbl_inline, [Define as token for inline if inlining supported])]) AC_DEFINE_UNQUOTED(inline, $ac_cv_lbl_inline, [Define as token for inline if inlining supported])])
FFF
#
# Test whether we have __atomic_load_n() and __atomic_store_n().
#
# We use AC_TRY_LINK because AC_TRY_COMPILE will succeed, as the
# compiler will just think that those functions are undefined,
# and perhaps warn about that, but not fail to compile.
#
AC_DEFUN(AC_PCAP_C___ATOMICS,
[
AC_MSG_CHECKING(for __atomic_load_n)
AC_CACHE_VAL(ac_cv_have___atomic_load_n,
AC_TRY_LINK([],
[
int i = 17;
int j;
j = __atomic_load_n(&i, __ATOMIC_RELAXED);
],
ac_have___atomic_load_n=yes,
ac_have___atomic_load_n=no))
AC_MSG_RESULT($ac_have___atomic_load_n)
if test $ac_have___atomic_load_n = yes ; then
AC_DEFINE(HAVE___ATOMIC_LOAD_N, 1,
[define if __atomic_load_n is supported by the compiler])
fi
AC_MSG_CHECKING(for __atomic_store_n)
AC_CACHE_VAL(ac_cv_have___atomic_store_n,
AC_TRY_LINK([],
[
int i;
__atomic_store_n(&i, 17, __ATOMIC_RELAXED);
],
ac_have___atomic_store_n=yes,
ac_have___atomic_store_n=no))
AC_MSG_RESULT($ac_have___atomic_store_n)
if test $ac_have___atomic_store_n = yes ; then
AC_DEFINE(HAVE___ATOMIC_STORE_N, 1,
[define if __atomic_store_n is supported by the compiler])
fi])
dnl dnl
dnl If using gcc, make sure we have ANSI ioctl definitions dnl If using gcc, make sure we have ANSI ioctl definitions
dnl dnl
@@ -752,106 +794,6 @@ AC_DEFUN(AC_LBL_HAVE_RUN_PATH,
AC_MSG_RESULT($ac_cv_lbl_have_run_path) AC_MSG_RESULT($ac_cv_lbl_have_run_path)
]) ])
dnl
dnl Checks to see if unaligned memory accesses fail
dnl
dnl usage:
dnl
dnl AC_LBL_UNALIGNED_ACCESS
dnl
dnl results:
dnl
dnl LBL_ALIGN (DEFINED)
dnl
AC_DEFUN(AC_LBL_UNALIGNED_ACCESS,
[AC_MSG_CHECKING(if unaligned accesses fail)
AC_CACHE_VAL(ac_cv_lbl_unaligned_fail,
[case "$host_cpu" in
#
# These are CPU types where:
#
# the CPU faults on an unaligned access, but at least some
# OSes that support that CPU catch the fault and simulate
# the unaligned access (e.g., Alpha/{Digital,Tru64} UNIX) -
# the simulation is slow, so we don't want to use it;
#
# the CPU, I infer (from the old
#
# XXX: should also check that they don't do weird things (like on arm)
#
# comment) doesn't fault on unaligned accesses, but doesn't
# do a normal unaligned fetch, either (e.g., presumably, ARM);
#
# for whatever reason, the test program doesn't work
# (this has been claimed to be the case for several of those
# CPUs - I don't know what the problem is; the problem
# was reported as "the test program dumps core" for SuperH,
# but that's what the test program is *supposed* to do -
# it dumps core before it writes anything, so the test
# for an empty output file should find an empty output
# file and conclude that unaligned accesses don't work).
#
# This run-time test won't work if you're cross-compiling, so
# in order to support cross-compiling for a particular CPU,
# we have to wire in the list of CPU types anyway, as far as
# I know, so perhaps we should just have a set of CPUs on
# which we know it doesn't work, a set of CPUs on which we
# know it does work, and have the script just fail on other
# cpu types and update it when such a failure occurs.
#
alpha*|arm*|bfin*|hp*|mips*|sh*|sparc*|ia64|nv1)
ac_cv_lbl_unaligned_fail=yes
;;
*)
cat >conftest.c <<EOF
# include <sys/types.h>
# include <sys/wait.h>
# include <stdio.h>
unsigned char a[[5]] = { 1, 2, 3, 4, 5 };
main() {
unsigned int i;
pid_t pid;
int status;
/* avoid "core dumped" message */
pid = fork();
if (pid < 0)
exit(2);
if (pid > 0) {
/* parent */
pid = waitpid(pid, &status, 0);
if (pid < 0)
exit(3);
exit(!WIFEXITED(status));
}
/* child */
i = *(unsigned int *)&a[[1]];
printf("%d\n", i);
exit(0);
}
EOF
${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS \
conftest.c $LIBS >/dev/null 2>&1
if test ! -x conftest ; then
dnl failed to compile for some reason
ac_cv_lbl_unaligned_fail=yes
else
./conftest >conftest.out
if test ! -s conftest.out ; then
ac_cv_lbl_unaligned_fail=yes
else
ac_cv_lbl_unaligned_fail=no
fi
fi
rm -f -r conftest* core core.conftest
;;
esac])
AC_MSG_RESULT($ac_cv_lbl_unaligned_fail)
if test $ac_cv_lbl_unaligned_fail = yes ; then
AC_DEFINE(LBL_ALIGN,1,[if unaligned access fails])
fi])
dnl dnl
dnl If the file .devel exists: dnl If the file .devel exists:
dnl Add some warning flags if the compiler supports them dnl Add some warning flags if the compiler supports them
@@ -881,12 +823,13 @@ AC_DEFUN(AC_LBL_DEVEL,
AC_LBL_CHECK_COMPILER_OPT($1, -W) AC_LBL_CHECK_COMPILER_OPT($1, -W)
AC_LBL_CHECK_COMPILER_OPT($1, -Wall) AC_LBL_CHECK_COMPILER_OPT($1, -Wall)
AC_LBL_CHECK_COMPILER_OPT($1, -Wcomma) AC_LBL_CHECK_COMPILER_OPT($1, -Wcomma)
AC_LBL_CHECK_COMPILER_OPT($1, -Wdeclaration-after-statement)
AC_LBL_CHECK_COMPILER_OPT($1, -Wdocumentation) AC_LBL_CHECK_COMPILER_OPT($1, -Wdocumentation)
AC_LBL_CHECK_COMPILER_OPT($1, -Wformat-nonliteral) AC_LBL_CHECK_COMPILER_OPT($1, -Wformat-nonliteral)
AC_LBL_CHECK_COMPILER_OPT($1, -Wmissing-noreturn) AC_LBL_CHECK_COMPILER_OPT($1, -Wmissing-noreturn)
AC_LBL_CHECK_COMPILER_OPT($1, -Wmissing-prototypes) AC_LBL_CHECK_COMPILER_OPT($1, -Wmissing-prototypes)
AC_LBL_CHECK_COMPILER_OPT($1, -Wmissing-variable-declarations) AC_LBL_CHECK_COMPILER_OPT($1, -Wmissing-variable-declarations)
AC_LBL_CHECK_COMPILER_OPT($1, -Wpointer-arith)
AC_LBL_CHECK_COMPILER_OPT($1, -Wpointer-sign)
AC_LBL_CHECK_COMPILER_OPT($1, -Wshadow) AC_LBL_CHECK_COMPILER_OPT($1, -Wshadow)
AC_LBL_CHECK_COMPILER_OPT($1, -Wsign-compare) AC_LBL_CHECK_COMPILER_OPT($1, -Wsign-compare)
AC_LBL_CHECK_COMPILER_OPT($1, -Wstrict-prototypes) AC_LBL_CHECK_COMPILER_OPT($1, -Wstrict-prototypes)
@@ -930,6 +873,7 @@ testme(unsigned short a)
} }
], ],
[generates warnings from ntohs()]) [generates warnings from ntohs()])
AC_LBL_CHECK_COMPILER_OPT($1, -Wshorten-64-to-32)
fi fi
AC_LBL_CHECK_DEPENDENCY_GENERATION_OPT() AC_LBL_CHECK_DEPENDENCY_GENERATION_OPT()
# #
@@ -1056,10 +1000,19 @@ AC_DEFUN(AC_LBL_LIBRARY_NET, [
LIBS="-lsocket -lnsl $LIBS" LIBS="-lsocket -lnsl $LIBS"
], ],
[ [
# AC_CHECK_LIB(network, getaddrinfo,
# We didn't find it. [
# #
AC_MSG_ERROR([getaddrinfo is required, but wasn't found]) # OK, we found it in libnetwork on Haiku.
#
LIBS="-lnetwork $LIBS"
],
[
#
# We didn't find it.
#
AC_MSG_ERROR([getaddrinfo is required, but wasn't found])
])
], -lnsl) ], -lnsl)
# #
@@ -1077,3 +1030,281 @@ AC_DEFUN(AC_LBL_LIBRARY_NET, [
# DLPI needs putmsg under HPUX so test for -lstr while we're at it # DLPI needs putmsg under HPUX so test for -lstr while we're at it
AC_SEARCH_LIBS(putmsg, str) AC_SEARCH_LIBS(putmsg, str)
]) ])
m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
dnl pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
dnl serial 11 (pkg-config-0.29)
dnl
dnl Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com>
dnl
dnl This program is free software; you can redistribute it and/or modify
dnl it under the terms of the GNU General Public License as published by
dnl the Free Software Foundation; either version 2 of the License, or
dnl (at your option) any later version.
dnl
dnl This program is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of
dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
dnl General Public License for more details.
dnl
dnl You should have received a copy of the GNU General Public License
dnl along with this program; if not, write to the Free Software
dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
dnl 02111-1307, USA.
dnl
dnl As a special exception to the GNU General Public License, if you
dnl distribute this file as part of a program that contains a
dnl configuration script generated by Autoconf, you may include it under
dnl the same distribution terms that you use for the rest of that
dnl program.
dnl PKG_PREREQ(MIN-VERSION)
dnl -----------------------
dnl Since: 0.29
dnl
dnl Verify that the version of the pkg-config macros are at least
dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's
dnl installed version of pkg-config, this checks the developer's version
dnl of pkg.m4 when generating configure.
dnl
dnl To ensure that this macro is defined, also add:
dnl m4_ifndef([PKG_PREREQ],
dnl [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])])
dnl
dnl See the "Since" comment for each macro you use to see what version
dnl of the macros you require.
m4_defun([PKG_PREREQ],
[m4_define([PKG_MACROS_VERSION], [0.29])
m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1,
[m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])])
])dnl PKG_PREREQ
dnl PKG_PROG_PKG_CONFIG([MIN-VERSION])
dnl ----------------------------------
dnl Since: 0.16
dnl
dnl Search for the pkg-config tool and set the PKG_CONFIG variable to
dnl first found in the path. Checks that the version of pkg-config found
dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is
dnl used since that's the first version where most current features of
dnl pkg-config existed.
AC_DEFUN([PKG_PROG_PKG_CONFIG],
[m4_pattern_forbid([^_?PKG_[A-Z_]+$])
m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$])
m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$])
AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])
AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path])
AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path])
if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
AC_PATH_TOOL([PKG_CONFIG], [pkg-config])
fi
if test -n "$PKG_CONFIG"; then
_pkg_min_version=m4_default([$1], [0.9.0])
AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version])
if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
PKG_CONFIG=""
fi
fi[]dnl
])dnl PKG_PROG_PKG_CONFIG
dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
dnl -------------------------------------------------------------------
dnl Since: 0.18
dnl
dnl Check to see whether a particular set of modules exists. Similar to
dnl PKG_CHECK_MODULES(), but does not set variables or print errors.
dnl
dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG])
dnl only at the first occurrence in configure.ac, so if the first place
dnl it's called might be skipped (such as if it is within an "if", you
dnl have to call PKG_CHECK_EXISTS manually
AC_DEFUN([PKG_CHECK_EXISTS],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
if test -n "$PKG_CONFIG" && \
AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then
m4_default([$2], [:])
m4_ifvaln([$3], [else
$3])dnl
fi])
dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
dnl ---------------------------------------------
dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting
dnl pkg_failed based on the result.
m4_define([_PKG_CONFIG],
[if test -n "$$1"; then
pkg_cv_[]$1="$$1"
elif test -n "$PKG_CONFIG"; then
PKG_CHECK_EXISTS([$3],
[pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`
test "x$?" != "x0" && pkg_failed=yes ],
[pkg_failed=yes])
else
pkg_failed=untried
fi[]dnl
])dnl _PKG_CONFIG
dnl _PKG_SHORT_ERRORS_SUPPORTED
dnl ---------------------------
dnl Internal check to see if pkg-config supports short errors.
AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])
if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
_pkg_short_errors_supported=yes
else
_pkg_short_errors_supported=no
fi[]dnl
])dnl _PKG_SHORT_ERRORS_SUPPORTED
dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
dnl [ACTION-IF-NOT-FOUND])
dnl --------------------------------------------------------------
dnl Since: 0.4.0
dnl
dnl Note that if there is a possibility the first call to
dnl PKG_CHECK_MODULES might not happen, you should be sure to include an
dnl explicit call to PKG_PROG_PKG_CONFIG in your configure.ac
AC_DEFUN([PKG_CHECK_MODULES],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
pkg_failed=no
AC_MSG_CHECKING([for $1])
_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
_PKG_CONFIG([$1][_LIBS], [libs], [$2])
m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS
and $1[]_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.])
if test $pkg_failed = yes; then
AC_MSG_RESULT([no])
_PKG_SHORT_ERRORS_SUPPORTED
if test $_pkg_short_errors_supported = yes; then
$1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1`
else
$1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1`
fi
# Put the nasty error message in config.log where it belongs
echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
m4_default([$4], [AC_MSG_ERROR(
[Package requirements ($2) were not met:
$$1_PKG_ERRORS
Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.
_PKG_TEXT])[]dnl
])
elif test $pkg_failed = untried; then
AC_MSG_RESULT([no])
m4_default([$4], [AC_MSG_FAILURE(
[The pkg-config script could not be found or is too old. Make sure it
is in your PATH or set the PKG_CONFIG environment variable to the full
path to pkg-config.
_PKG_TEXT
To get pkg-config, see <https://pkg-config.freedesktop.org/>.])[]dnl
])
else
$1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
$1[]_LIBS=$pkg_cv_[]$1[]_LIBS
AC_MSG_RESULT([yes])
$3
fi[]dnl
])dnl PKG_CHECK_MODULES
dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
dnl [ACTION-IF-NOT-FOUND])
dnl ---------------------------------------------------------------------
dnl Since: 0.29
dnl
dnl Checks for existence of MODULES and gathers its build flags with
dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags
dnl and VARIABLE-PREFIX_LIBS from --libs.
dnl
dnl Note that if there is a possibility the first call to
dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to
dnl include an explicit call to PKG_PROG_PKG_CONFIG in your
dnl configure.ac.
AC_DEFUN([PKG_CHECK_MODULES_STATIC],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
_save_PKG_CONFIG=$PKG_CONFIG
PKG_CONFIG="$PKG_CONFIG --static"
PKG_CHECK_MODULES($@)
PKG_CONFIG=$_save_PKG_CONFIG[]dnl
])dnl PKG_CHECK_MODULES_STATIC
dnl PKG_INSTALLDIR([DIRECTORY])
dnl -------------------------
dnl Since: 0.27
dnl
dnl Substitutes the variable pkgconfigdir as the location where a module
dnl should install pkg-config .pc files. By default the directory is
dnl $libdir/pkgconfig, but the default can be changed by passing
dnl DIRECTORY. The user can override through the --with-pkgconfigdir
dnl parameter.
AC_DEFUN([PKG_INSTALLDIR],
[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])])
m4_pushdef([pkg_description],
[pkg-config installation directory @<:@]pkg_default[@:>@])
AC_ARG_WITH([pkgconfigdir],
[AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],,
[with_pkgconfigdir=]pkg_default)
AC_SUBST([pkgconfigdir], [$with_pkgconfigdir])
m4_popdef([pkg_default])
m4_popdef([pkg_description])
])dnl PKG_INSTALLDIR
dnl PKG_NOARCH_INSTALLDIR([DIRECTORY])
dnl --------------------------------
dnl Since: 0.27
dnl
dnl Substitutes the variable noarch_pkgconfigdir as the location where a
dnl module should install arch-independent pkg-config .pc files. By
dnl default the directory is $datadir/pkgconfig, but the default can be
dnl changed by passing DIRECTORY. The user can override through the
dnl --with-noarch-pkgconfigdir parameter.
AC_DEFUN([PKG_NOARCH_INSTALLDIR],
[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])])
m4_pushdef([pkg_description],
[pkg-config arch-independent installation directory @<:@]pkg_default[@:>@])
AC_ARG_WITH([noarch-pkgconfigdir],
[AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],,
[with_noarch_pkgconfigdir=]pkg_default)
AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir])
m4_popdef([pkg_default])
m4_popdef([pkg_description])
])dnl PKG_NOARCH_INSTALLDIR
dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE,
dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
dnl -------------------------------------------
dnl Since: 0.28
dnl
dnl Retrieves the value of the pkg-config variable for the given module.
AC_DEFUN([PKG_CHECK_VAR],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl
_PKG_CONFIG([$1], [variable="][$3]["], [$2])
AS_VAR_COPY([$1], [pkg_cv_][$1])
AS_VAR_IF([$1], [""], [$5], [$4])dnl
])dnl PKG_CHECK_VAR

View File

@@ -76,7 +76,7 @@
#define PROTO_POS 0 /* offset of protocol discriminator */ #define PROTO_POS 0 /* offset of protocol discriminator */
#define CALL_REF_POS 2 /* offset of call reference value */ #define CALL_REF_POS 2 /* offset of call reference value */
#define MSG_TYPE_POS 5 /* offset of message type */ #define MSG_TYPE_POS 5 /* offset of message type */
#define MSG_LEN_POS 7 /* offset of mesage length */ #define MSG_LEN_POS 7 /* offset of message length */
#define IE_BEGIN_POS 9 /* offset of first information element */ #define IE_BEGIN_POS 9 /* offset of first information element */
/* format of signalling messages */ /* format of signalling messages */

View File

@@ -44,6 +44,11 @@
#include <pcap/pcap-inttypes.h> #include <pcap/pcap-inttypes.h>
#include "pcap-types.h" #include "pcap-types.h"
#include "extract.h"
#include "diag-control.h"
#define EXTRACT_SHORT EXTRACT_BE_U_2
#define EXTRACT_LONG EXTRACT_BE_U_4
#ifndef _WIN32 #ifndef _WIN32
#include <sys/param.h> #include <sys/param.h>
@@ -55,42 +60,6 @@
#include <stdlib.h> #include <stdlib.h>
#define int32 bpf_int32
#define u_int32 bpf_u_int32
#ifndef LBL_ALIGN
/*
* XXX - IA-64? If not, this probably won't work on Win64 IA-64
* systems, unless LBL_ALIGN is defined elsewhere for them.
* XXX - SuperH? If not, this probably won't work on WinCE SuperH
* systems, unless LBL_ALIGN is defined elsewhere for them.
*/
#if defined(sparc) || defined(__sparc__) || defined(mips) || \
defined(ibm032) || defined(__alpha) || defined(__hpux) || \
defined(__arm__)
#define LBL_ALIGN
#endif
#endif
#ifndef LBL_ALIGN
#ifndef _WIN32
#include <netinet/in.h>
#endif
#define EXTRACT_SHORT(p) ((u_short)ntohs(*(u_short *)p))
#define EXTRACT_LONG(p) (ntohl(*(u_int32 *)p))
#else
#define EXTRACT_SHORT(p)\
((u_short)\
((u_short)*((u_char *)p+0)<<8|\
(u_short)*((u_char *)p+1)<<0))
#define EXTRACT_LONG(p)\
((u_int32)*((u_char *)p+0)<<24|\
(u_int32)*((u_char *)p+1)<<16|\
(u_int32)*((u_char *)p+2)<<8|\
(u_int32)*((u_char *)p+3)<<0)
#endif
#ifdef __linux__ #ifdef __linux__
#include <linux/types.h> #include <linux/types.h>
#include <linux/if_packet.h> #include <linux/if_packet.h>
@@ -115,13 +84,19 @@ enum {
* *
* Thanks to Ani Sinha <ani@arista.com> for providing initial implementation * Thanks to Ani Sinha <ani@arista.com> for providing initial implementation
*/ */
#if defined(SKF_AD_VLAN_TAG_PRESENT)
u_int u_int
bpf_filter_with_aux_data(const struct bpf_insn *pc, const u_char *p, pcap_filter_with_aux_data(const struct bpf_insn *pc, const u_char *p,
u_int wirelen, u_int buflen, const struct bpf_aux_data *aux_data) u_int wirelen, u_int buflen, const struct pcap_bpf_aux_data *aux_data)
#else
u_int
pcap_filter_with_aux_data(const struct bpf_insn *pc, const u_char *p,
u_int wirelen, u_int buflen, const struct pcap_bpf_aux_data *aux_data _U_)
#endif
{ {
register u_int32 A, X; register uint32_t A, X;
register bpf_u_int32 k; register bpf_u_int32 k;
u_int32 mem[BPF_MEMWORDS]; uint32_t mem[BPF_MEMWORDS];
if (pc == 0) if (pc == 0)
/* /*
@@ -160,6 +135,13 @@ bpf_filter_with_aux_data(const struct bpf_insn *pc, const u_char *p,
continue; continue;
case BPF_LD|BPF_B|BPF_ABS: case BPF_LD|BPF_B|BPF_ABS:
/*
* Yes, we know, this switch doesn't do
* anything unless we're building for
* a Linux kernel with removed VLAN
* tags available as meta-data.
*/
DIAG_OFF_DEFAULT_ONLY_SWITCH
switch (pc->k) { switch (pc->k) {
#if defined(SKF_AD_VLAN_TAG_PRESENT) #if defined(SKF_AD_VLAN_TAG_PRESENT)
@@ -183,6 +165,7 @@ bpf_filter_with_aux_data(const struct bpf_insn *pc, const u_char *p,
A = p[k]; A = p[k];
break; break;
} }
DIAG_ON_DEFAULT_ONLY_SWITCH
continue; continue;
case BPF_LD|BPF_W|BPF_LEN: case BPF_LD|BPF_W|BPF_LEN:
@@ -405,13 +388,12 @@ bpf_filter_with_aux_data(const struct bpf_insn *pc, const u_char *p,
} }
u_int u_int
bpf_filter(const struct bpf_insn *pc, const u_char *p, u_int wirelen, pcap_filter(const struct bpf_insn *pc, const u_char *p, u_int wirelen,
u_int buflen) u_int buflen)
{ {
return bpf_filter_with_aux_data(pc, p, wirelen, buflen, NULL); return pcap_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
@@ -424,7 +406,7 @@ bpf_filter(const struct bpf_insn *pc, const u_char *p, u_int wirelen,
* Otherwise, a bogus program could easily crash the system. * Otherwise, a bogus program could easily crash the system.
*/ */
int int
bpf_validate(const struct bpf_insn *f, int len) pcap_validate_filter(const struct bpf_insn *f, int len)
{ {
u_int i, from; u_int i, from;
const struct bpf_insn *p; const struct bpf_insn *p;
@@ -546,3 +528,19 @@ bpf_validate(const struct bpf_insn *f, int len)
} }
return BPF_CLASS(f[len - 1].code) == BPF_RET; return BPF_CLASS(f[len - 1].code) == BPF_RET;
} }
/*
* Exported because older versions of libpcap exported them.
*/
u_int
bpf_filter(const struct bpf_insn *pc, const u_char *p, u_int wirelen,
u_int buflen)
{
return pcap_filter(pc, p, wirelen, buflen);
}
int
bpf_validate(const struct bpf_insn *f, int len)
{
return pcap_validate_filter(f, len);
}

View File

@@ -28,12 +28,104 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#ifdef __linux__
#include <linux/types.h>
#include <linux/if_packet.h>
#include <linux/filter.h>
/*
* We want our versions of these #defines, not Linux's version.
* (The two should be the same; if not, we have a problem; all BPF
* implementations *should* be source-compatible supersets of ours.)
*/
#undef BPF_STMT
#undef BPF_JUMP
#endif
#include "pcap-int.h" #include "pcap-int.h"
#ifdef HAVE_OS_PROTO_H #ifdef HAVE_OS_PROTO_H
#include "os-proto.h" #include "os-proto.h"
#endif #endif
#ifdef SKF_AD_OFF
/*
* Symbolic names for offsets that refer to the special Linux BPF locations.
*/
static const char *offsets[SKF_AD_MAX] = {
#ifdef SKF_AD_PROTOCOL
[SKF_AD_PROTOCOL] = "proto",
#endif
#ifdef SKF_AD_PKTTYPE
[SKF_AD_PKTTYPE] = "type",
#endif
#ifdef SKF_AD_IFINDEX
[SKF_AD_IFINDEX] = "ifidx",
#endif
#ifdef SKF_AD_NLATTR
[SKF_AD_NLATTR] = "nla",
#endif
#ifdef SKF_AD_NLATTR_NEST
[SKF_AD_NLATTR_NEST] = "nlan",
#endif
#ifdef SKF_AD_MARK
[SKF_AD_MARK] = "mark",
#endif
#ifdef SKF_AD_QUEUE
[SKF_AD_QUEUE] = "queue",
#endif
#ifdef SKF_AD_HATYPE
[SKF_AD_HATYPE] = "hatype",
#endif
#ifdef SKF_AD_RXHASH
[SKF_AD_RXHASH] = "rxhash",
#endif
#ifdef SKF_AD_CPU
[SKF_AD_CPU] = "cpu",
#endif
#ifdef SKF_AD_ALU_XOR_X
[SKF_AD_ALU_XOR_X] = "xor_x",
#endif
#ifdef SKF_AD_VLAN_TAG
[SKF_AD_VLAN_TAG] = "vlan_tci",
#endif
#ifdef SKF_AD_VLAN_TAG_PRESENT
[SKF_AD_VLAN_TAG_PRESENT] = "vlanp",
#endif
#ifdef SKF_AD_PAY_OFFSET
[SKF_AD_PAY_OFFSET] = "poff",
#endif
#ifdef SKF_AD_RANDOM
[SKF_AD_RANDOM] = "random",
#endif
#ifdef SKF_AD_VLAN_TPID
[SKF_AD_VLAN_TPID] = "vlan_tpid"
#endif
};
#endif
static void
bpf_print_abs_load_operand(char *buf, size_t bufsize, const struct bpf_insn *p)
{
#ifdef SKF_AD_OFF
const char *sym;
/*
* It's an absolute load.
* Is the offset a special Linux offset that we know about?
*/
if (p->k >= (bpf_u_int32)SKF_AD_OFF &&
p->k < (bpf_u_int32)(SKF_AD_OFF + SKF_AD_MAX) &&
(sym = offsets[p->k - (bpf_u_int32)SKF_AD_OFF]) != NULL) {
/*
* Yes. Print the offset symbolically.
*/
(void)snprintf(buf, bufsize, "[%s]", sym);
} else
#endif
(void)snprintf(buf, bufsize, "[%d]", p->k);
}
char * char *
bpf_image(const struct bpf_insn *p, int n) bpf_image(const struct bpf_insn *p, int n)
{ {
@@ -46,13 +138,13 @@ bpf_image(const struct bpf_insn *p, int n)
default: default:
op = "unimp"; op = "unimp";
(void)pcap_snprintf(operand_buf, sizeof operand_buf, "0x%x", p->code); (void)snprintf(operand_buf, sizeof operand_buf, "0x%x", p->code);
operand = operand_buf; operand = operand_buf;
break; break;
case BPF_RET|BPF_K: case BPF_RET|BPF_K:
op = "ret"; op = "ret";
(void)pcap_snprintf(operand_buf, sizeof operand_buf, "#%d", p->k); (void)snprintf(operand_buf, sizeof operand_buf, "#%d", p->k);
operand = operand_buf; operand = operand_buf;
break; break;
@@ -63,19 +155,19 @@ bpf_image(const struct bpf_insn *p, int n)
case BPF_LD|BPF_W|BPF_ABS: case BPF_LD|BPF_W|BPF_ABS:
op = "ld"; op = "ld";
(void)pcap_snprintf(operand_buf, sizeof operand_buf, "[%d]", p->k); bpf_print_abs_load_operand(operand_buf, sizeof operand_buf, p);
operand = operand_buf; operand = operand_buf;
break; break;
case BPF_LD|BPF_H|BPF_ABS: case BPF_LD|BPF_H|BPF_ABS:
op = "ldh"; op = "ldh";
(void)pcap_snprintf(operand_buf, sizeof operand_buf, "[%d]", p->k); bpf_print_abs_load_operand(operand_buf, sizeof operand_buf, p);
operand = operand_buf; operand = operand_buf;
break; break;
case BPF_LD|BPF_B|BPF_ABS: case BPF_LD|BPF_B|BPF_ABS:
op = "ldb"; op = "ldb";
(void)pcap_snprintf(operand_buf, sizeof operand_buf, "[%d]", p->k); bpf_print_abs_load_operand(operand_buf, sizeof operand_buf, p);
operand = operand_buf; operand = operand_buf;
break; break;
@@ -86,91 +178,91 @@ bpf_image(const struct bpf_insn *p, int n)
case BPF_LD|BPF_W|BPF_IND: case BPF_LD|BPF_W|BPF_IND:
op = "ld"; op = "ld";
(void)pcap_snprintf(operand_buf, sizeof operand_buf, "[x + %d]", p->k); (void)snprintf(operand_buf, sizeof operand_buf, "[x + %d]", p->k);
operand = operand_buf; operand = operand_buf;
break; break;
case BPF_LD|BPF_H|BPF_IND: case BPF_LD|BPF_H|BPF_IND:
op = "ldh"; op = "ldh";
(void)pcap_snprintf(operand_buf, sizeof operand_buf, "[x + %d]", p->k); (void)snprintf(operand_buf, sizeof operand_buf, "[x + %d]", p->k);
operand = operand_buf; operand = operand_buf;
break; break;
case BPF_LD|BPF_B|BPF_IND: case BPF_LD|BPF_B|BPF_IND:
op = "ldb"; op = "ldb";
(void)pcap_snprintf(operand_buf, sizeof operand_buf, "[x + %d]", p->k); (void)snprintf(operand_buf, sizeof operand_buf, "[x + %d]", p->k);
operand = operand_buf; operand = operand_buf;
break; break;
case BPF_LD|BPF_IMM: case BPF_LD|BPF_IMM:
op = "ld"; op = "ld";
(void)pcap_snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k); (void)snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k);
operand = operand_buf; operand = operand_buf;
break; break;
case BPF_LDX|BPF_IMM: case BPF_LDX|BPF_IMM:
op = "ldx"; op = "ldx";
(void)pcap_snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k); (void)snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k);
operand = operand_buf; operand = operand_buf;
break; break;
case BPF_LDX|BPF_MSH|BPF_B: case BPF_LDX|BPF_MSH|BPF_B:
op = "ldxb"; op = "ldxb";
(void)pcap_snprintf(operand_buf, sizeof operand_buf, "4*([%d]&0xf)", p->k); (void)snprintf(operand_buf, sizeof operand_buf, "4*([%d]&0xf)", p->k);
operand = operand_buf; operand = operand_buf;
break; break;
case BPF_LD|BPF_MEM: case BPF_LD|BPF_MEM:
op = "ld"; op = "ld";
(void)pcap_snprintf(operand_buf, sizeof operand_buf, "M[%d]", p->k); (void)snprintf(operand_buf, sizeof operand_buf, "M[%d]", p->k);
operand = operand_buf; operand = operand_buf;
break; break;
case BPF_LDX|BPF_MEM: case BPF_LDX|BPF_MEM:
op = "ldx"; op = "ldx";
(void)pcap_snprintf(operand_buf, sizeof operand_buf, "M[%d]", p->k); (void)snprintf(operand_buf, sizeof operand_buf, "M[%d]", p->k);
operand = operand_buf; operand = operand_buf;
break; break;
case BPF_ST: case BPF_ST:
op = "st"; op = "st";
(void)pcap_snprintf(operand_buf, sizeof operand_buf, "M[%d]", p->k); (void)snprintf(operand_buf, sizeof operand_buf, "M[%d]", p->k);
operand = operand_buf; operand = operand_buf;
break; break;
case BPF_STX: case BPF_STX:
op = "stx"; op = "stx";
(void)pcap_snprintf(operand_buf, sizeof operand_buf, "M[%d]", p->k); (void)snprintf(operand_buf, sizeof operand_buf, "M[%d]", p->k);
operand = operand_buf; operand = operand_buf;
break; break;
case BPF_JMP|BPF_JA: case BPF_JMP|BPF_JA:
op = "ja"; op = "ja";
(void)pcap_snprintf(operand_buf, sizeof operand_buf, "%d", n + 1 + p->k); (void)snprintf(operand_buf, sizeof operand_buf, "%d", n + 1 + p->k);
operand = operand_buf; operand = operand_buf;
break; break;
case BPF_JMP|BPF_JGT|BPF_K: case BPF_JMP|BPF_JGT|BPF_K:
op = "jgt"; op = "jgt";
(void)pcap_snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k); (void)snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k);
operand = operand_buf; operand = operand_buf;
break; break;
case BPF_JMP|BPF_JGE|BPF_K: case BPF_JMP|BPF_JGE|BPF_K:
op = "jge"; op = "jge";
(void)pcap_snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k); (void)snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k);
operand = operand_buf; operand = operand_buf;
break; break;
case BPF_JMP|BPF_JEQ|BPF_K: case BPF_JMP|BPF_JEQ|BPF_K:
op = "jeq"; op = "jeq";
(void)pcap_snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k); (void)snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k);
operand = operand_buf; operand = operand_buf;
break; break;
case BPF_JMP|BPF_JSET|BPF_K: case BPF_JMP|BPF_JSET|BPF_K:
op = "jset"; op = "jset";
(void)pcap_snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k); (void)snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k);
operand = operand_buf; operand = operand_buf;
break; break;
@@ -246,61 +338,61 @@ bpf_image(const struct bpf_insn *p, int n)
case BPF_ALU|BPF_ADD|BPF_K: case BPF_ALU|BPF_ADD|BPF_K:
op = "add"; op = "add";
(void)pcap_snprintf(operand_buf, sizeof operand_buf, "#%d", p->k); (void)snprintf(operand_buf, sizeof operand_buf, "#%d", p->k);
operand = operand_buf; operand = operand_buf;
break; break;
case BPF_ALU|BPF_SUB|BPF_K: case BPF_ALU|BPF_SUB|BPF_K:
op = "sub"; op = "sub";
(void)pcap_snprintf(operand_buf, sizeof operand_buf, "#%d", p->k); (void)snprintf(operand_buf, sizeof operand_buf, "#%d", p->k);
operand = operand_buf; operand = operand_buf;
break; break;
case BPF_ALU|BPF_MUL|BPF_K: case BPF_ALU|BPF_MUL|BPF_K:
op = "mul"; op = "mul";
(void)pcap_snprintf(operand_buf, sizeof operand_buf, "#%d", p->k); (void)snprintf(operand_buf, sizeof operand_buf, "#%d", p->k);
operand = operand_buf; operand = operand_buf;
break; break;
case BPF_ALU|BPF_DIV|BPF_K: case BPF_ALU|BPF_DIV|BPF_K:
op = "div"; op = "div";
(void)pcap_snprintf(operand_buf, sizeof operand_buf, "#%d", p->k); (void)snprintf(operand_buf, sizeof operand_buf, "#%d", p->k);
operand = operand_buf; operand = operand_buf;
break; break;
case BPF_ALU|BPF_MOD|BPF_K: case BPF_ALU|BPF_MOD|BPF_K:
op = "mod"; op = "mod";
(void)pcap_snprintf(operand_buf, sizeof operand_buf, "#%d", p->k); (void)snprintf(operand_buf, sizeof operand_buf, "#%d", p->k);
operand = operand_buf; operand = operand_buf;
break; break;
case BPF_ALU|BPF_AND|BPF_K: case BPF_ALU|BPF_AND|BPF_K:
op = "and"; op = "and";
(void)pcap_snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k); (void)snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k);
operand = operand_buf; operand = operand_buf;
break; break;
case BPF_ALU|BPF_OR|BPF_K: case BPF_ALU|BPF_OR|BPF_K:
op = "or"; op = "or";
(void)pcap_snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k); (void)snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k);
operand = operand_buf; operand = operand_buf;
break; break;
case BPF_ALU|BPF_XOR|BPF_K: case BPF_ALU|BPF_XOR|BPF_K:
op = "xor"; op = "xor";
(void)pcap_snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k); (void)snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k);
operand = operand_buf; operand = operand_buf;
break; break;
case BPF_ALU|BPF_LSH|BPF_K: case BPF_ALU|BPF_LSH|BPF_K:
op = "lsh"; op = "lsh";
(void)pcap_snprintf(operand_buf, sizeof operand_buf, "#%d", p->k); (void)snprintf(operand_buf, sizeof operand_buf, "#%d", p->k);
operand = operand_buf; operand = operand_buf;
break; break;
case BPF_ALU|BPF_RSH|BPF_K: case BPF_ALU|BPF_RSH|BPF_K:
op = "rsh"; op = "rsh";
(void)pcap_snprintf(operand_buf, sizeof operand_buf, "#%d", p->k); (void)snprintf(operand_buf, sizeof operand_buf, "#%d", p->k);
operand = operand_buf; operand = operand_buf;
break; break;
@@ -320,11 +412,11 @@ bpf_image(const struct bpf_insn *p, int n)
break; break;
} }
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)pcap_snprintf(image, sizeof image, (void)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)pcap_snprintf(image, sizeof image, (void)snprintf(image, sizeof image,
"(%03d) %-8s %s", "(%03d) %-8s %s",
n, op, operand); n, op, operand);
} }

216
libpcap/charconv.c Normal file
View File

@@ -0,0 +1,216 @@
/* -*- 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.
*/
#ifdef _WIN32
#include <stdio.h>
#include <pcap/pcap.h> /* Needed for PCAP_ERRBUF_SIZE */
#include "charconv.h"
wchar_t *
cp_to_utf_16le(UINT codepage, const char *cp_string, DWORD flags)
{
int utf16le_len;
wchar_t *utf16le_string;
/*
* Map from the specified code page to UTF-16LE.
* First, find out how big a buffer we'll need.
*/
utf16le_len = MultiByteToWideChar(codepage, flags, cp_string, -1,
NULL, 0);
if (utf16le_len == 0) {
/*
* Error. Fail with EINVAL.
*/
errno = EINVAL;
return (NULL);
}
/*
* Now attempt to allocate a buffer for that.
*/
utf16le_string = malloc(utf16le_len * sizeof (wchar_t));
if (utf16le_string == NULL) {
/*
* Not enough memory; assume errno has been
* set, and fail.
*/
return (NULL);
}
/*
* Now convert.
*/
utf16le_len = MultiByteToWideChar(codepage, flags, cp_string, -1,
utf16le_string, utf16le_len);
if (utf16le_len == 0) {
/*
* Error. Fail with EINVAL.
* XXX - should this ever happen, given that
* we already ran the string through
* MultiByteToWideChar() to find out how big
* a buffer we needed?
*/
free(utf16le_string);
errno = EINVAL;
return (NULL);
}
return (utf16le_string);
}
char *
utf_16le_to_cp(UINT codepage, const wchar_t *utf16le_string)
{
int cp_len;
char *cp_string;
/*
* Map from UTF-16LE to the specified code page.
* First, find out how big a buffer we'll need.
* We convert composite characters to precomposed characters,
* as that's what Windows expects.
*/
cp_len = WideCharToMultiByte(codepage, WC_COMPOSITECHECK,
utf16le_string, -1, NULL, 0, NULL, NULL);
if (cp_len == 0) {
/*
* Error. Fail with EINVAL.
*/
errno = EINVAL;
return (NULL);
}
/*
* Now attempt to allocate a buffer for that.
*/
cp_string = malloc(cp_len * sizeof (char));
if (cp_string == NULL) {
/*
* Not enough memory; assume errno has been
* set, and fail.
*/
return (NULL);
}
/*
* Now convert.
*/
cp_len = WideCharToMultiByte(codepage, WC_COMPOSITECHECK,
utf16le_string, -1, cp_string, cp_len, NULL, NULL);
if (cp_len == 0) {
/*
* Error. Fail with EINVAL.
* XXX - should this ever happen, given that
* we already ran the string through
* WideCharToMultiByte() to find out how big
* a buffer we needed?
*/
free(cp_string);
errno = EINVAL;
return (NULL);
}
return (cp_string);
}
/*
* Convert an error message string from UTF-8 to the local code page, as
* best we can.
*
* The buffer is assumed to be PCAP_ERRBUF_SIZE bytes long; we truncate
* if it doesn't fit.
*/
void
utf_8_to_acp_truncated(char *errbuf)
{
wchar_t *utf_16_errbuf;
int retval;
DWORD err;
/*
* Do this by converting to UTF-16LE and then to the local
* code page. That means we get to use Microsoft's
* conversion routines, rather than having to understand
* all the code pages ourselves, *and* that this routine
* can convert in place.
*/
/*
* Map from UTF-8 to UTF-16LE.
* First, find out how big a buffer we'll need.
* Convert any invalid characters to REPLACEMENT CHARACTER.
*/
utf_16_errbuf = cp_to_utf_16le(CP_UTF8, errbuf, 0);
if (utf_16_errbuf == NULL) {
/*
* Error. Give up.
*/
snprintf(errbuf, PCAP_ERRBUF_SIZE,
"Can't convert error string to the local code page");
return;
}
/*
* Now, convert that to the local code page.
* Use the current thread's code page. For unconvertable
* characters, let it pick the "best fit" character.
*
* XXX - we'd like some way to do what utf_16le_to_utf_8_truncated()
* does if the buffer isn't big enough, but we don't want to have
* to handle all local code pages ourselves; doing so requires
* knowledge of all those code pages, including knowledge of how
* characters are formed in thoe code pages so that we can avoid
* cutting a multi-byte character into pieces.
*
* Converting to an un-truncated string using Windows APIs, and
* then copying to the buffer, still requires knowledge of how
* characters are formed in the target code page.
*/
retval = WideCharToMultiByte(CP_THREAD_ACP, 0, utf_16_errbuf, -1,
errbuf, PCAP_ERRBUF_SIZE, NULL, NULL);
if (retval == 0) {
err = GetLastError();
free(utf_16_errbuf);
if (err == ERROR_INSUFFICIENT_BUFFER)
snprintf(errbuf, PCAP_ERRBUF_SIZE,
"The error string, in the local code page, didn't fit in the buffer");
else
snprintf(errbuf, PCAP_ERRBUF_SIZE,
"Can't convert error string to the local code page");
return;
}
free(utf_16_errbuf);
}
#endif

44
libpcap/charconv.h Normal file
View File

@@ -0,0 +1,44 @@
/* -*- 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 charonv_h
#define charonv_h
#ifdef _WIN32
extern wchar_t *cp_to_utf_16le(UINT codepage, const char *cp_string, DWORD flags);
extern char *utf_16le_to_cp(UINT codepage, const wchar_t *utf16le_string);
extern void utf_8_to_acp_truncated(char *);
#endif
#endif

View File

@@ -33,8 +33,7 @@
# PACKET_LIBRARY - relative or absolute path to the Packet library to # PACKET_LIBRARY - relative or absolute path to the Packet library to
# link with. An absolute path is will be used if the # link with. An absolute path is will be used if the
# Packet library is not located in the compiler's # Packet library is not located in the compiler's
# default search path. See e.g. PACKET_DLL_DIR # default search path.
# variable below.
# PACKET_FOUND - TRUE if the Packet library *and* header are found. # PACKET_FOUND - TRUE if the Packet library *and* header are found.
# #
@@ -42,10 +41,10 @@
# ================================ # ================================
# #
# To tell this module where to look, a user may set the environment variable # To tell this module where to look, a user may set the environment variable
# PACKET_DLL_DIR to point cmake to the *root* of a directory with include and # Packet_ROOT to point cmake to the *root* of a directory with include and
# lib subdirectories for packet.dll (e.g WpdPack/npcap-sdk). # lib subdirectories for packet.dll (e.g WpdPack or npcap-sdk).
# Alternatively, PACKET_DLL_DIR may also be set from cmake command line or GUI # Alternatively, Packet_ROOT may also be set from cmake command line or GUI
# (e.g cmake -DPACKET_DLL_DIR=/path/to/packet [...]) # (e.g cmake -DPacket_ROOT=C:\path\to\packet [...])
# #
# The 64-bit Packet.lib is located under /x64 # The 64-bit Packet.lib is located under /x64
@@ -59,19 +58,41 @@ if(CMAKE_SIZEOF_VOID_P EQUAL 8)
# without searching in the Lib directory first appears to be to set # without searching in the Lib directory first appears to be to set
# CMAKE_LIBRARY_ARCHITECTURE to "x64". # CMAKE_LIBRARY_ARCHITECTURE to "x64".
# #
set(CMAKE_LIBRARY_ARCHITECTURE "x64") # In newer versions of CMake, CMAKE_LIBRARY_ARCHITECTURE is set according to
# the language, e.g., CMAKE_<LANG>_LIBRARY_ARCHITECTURE. So, set the new
# variable, CMAKE_C_LIBRARY_ARCHITECTURE, so that CMAKE_LIBRARY_ARCHITECTURE
# inherits the correct value.
#
set(archdetect_c_code "
#ifndef _M_ARM64
#error Not ARM64
#endif
int main() { return 0; }
")
file(WRITE "${CMAKE_BINARY_DIR}/archdetect.c" "${archdetect_c_code}")
try_compile(
IsArm64
"${CMAKE_BINARY_DIR}/archdetect"
"${CMAKE_BINARY_DIR}/archdetect.c"
)
if(IsArm64)
set(CMAKE_C_LIBRARY_ARCHITECTURE "ARM64")
set(CMAKE_LIBRARY_ARCHITECTURE "ARM64")
else()
set(CMAKE_C_LIBRARY_ARCHITECTURE "x64")
set(CMAKE_LIBRARY_ARCHITECTURE "x64")
endif()
endif() endif()
# Find the header # Find the header
find_path(PACKET_INCLUDE_DIR Packet32.h find_path(PACKET_INCLUDE_DIR Packet32.h
HINTS "${PACKET_DLL_DIR}" ENV PACKET_DLL_DIR
PATH_SUFFIXES include Include PATH_SUFFIXES include Include
) )
# Find the library # Find the library
find_library(PACKET_LIBRARY find_library(PACKET_LIBRARY
NAMES Packet packet NAMES Packet packet
HINTS "${PACKET_DLL_DIR}" ENV PACKET_DLL_DIR
) )
# Set PACKET_FOUND to TRUE if PACKET_INCLUDE_DIR and PACKET_LIBRARY are TRUE. # Set PACKET_FOUND to TRUE if PACKET_INCLUDE_DIR and PACKET_LIBRARY are TRUE.

View File

@@ -0,0 +1,123 @@
# Try to find dpdk
#
# Once done, this will define
#
# dpdk_FOUND
# dpdk_INCLUDE_DIRS
# dpdk_LIBRARIES
if(PKG_CONFIG_FOUND)
pkg_check_modules(dpdk QUIET libdpdk)
endif()
message(STATUS "Executing Finddpdk")
if(NOT dpdk_INCLUDE_DIRS)
message(STATUS "Executing find_path")
find_path(dpdk_config_INCLUDE_DIR rte_config.h
HINTS
ENV DPDK_DIR
PATH_SUFFIXES
dpdk
include
)
find_path(dpdk_common_INCLUDE_DIR rte_common.h
HINTS
ENV DPDK_DIR
PATH_SUFFIXES
dpdk
include
)
set(dpdk_INCLUDE_DIRS "${dpdk_config_INCLUDE_DIR}")
if(NOT dpdk_config_INCLUDE_DIR STREQUAL dpdk_common_INCLUDE_DIR)
list(APPEND dpdk_INCLUDE_DIRS "${dpdk_common_INCLUDE_DIR}")
endif()
set(components
bus_pci
cmdline
eal
ethdev
hash
kvargs
mbuf
mempool
mempool_ring
mempool_stack
pci
pmd_af_packet
pmd_bond
pmd_i40e
pmd_ixgbe
pmd_mlx5
pmd_ring
pmd_vmxnet3_uio
ring)
set(dpdk_LIBRARIES)
foreach(c ${components})
find_library(DPDK_rte_${c}_LIBRARY rte_${c}
HINTS
ENV DPDK_DIR
${dpdk_LIBRARY_DIRS}
PATH_SUFFIXES lib)
if(DPDK_rte_${c}_LIBRARY)
set(dpdk_lib dpdk::${c})
if (NOT TARGET ${dpdk_lib})
add_library(${dpdk_lib} UNKNOWN IMPORTED)
set_target_properties(${dpdk_lib} PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${dpdk_INCLUDE_DIRS}"
IMPORTED_LOCATION "${DPDK_rte_${c}_LIBRARY}")
if(c STREQUAL pmd_mlx5)
find_package(verbs QUIET)
if(verbs_FOUND)
target_link_libraries(${dpdk_lib} INTERFACE IBVerbs::verbs)
endif()
endif()
endif()
list(APPEND dpdk_LIBRARIES ${dpdk_lib})
endif()
endforeach()
#
# Where the heck did this list come from? libdpdk on Ubuntu 20.04,
# for example, doesn't even *have* -ldpdk; that's why we go with
# pkg-config, in the hopes that it provides a correct set of flags
# for this tangled mess.
#
list(APPEND dpdk_LIBRARIES dpdk rt m numo dl)
endif()
mark_as_advanced(dpdk_INCLUDE_DIRS ${dpdk_LIBRARIES})
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(dpdk DEFAULT_MSG
dpdk_INCLUDE_DIRS
dpdk_LIBRARIES)
if(dpdk_FOUND)
if(NOT TARGET dpdk::cflags)
if(CMAKE_SYSTEM_PROCESSOR MATCHES "amd64|x86_64|AMD64")
set(rte_cflags "-march=core2")
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "arm|ARM")
set(rte_cflags "-march=armv7-a")
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|AARCH64")
set(rte_cflags "-march=armv8-a+crc")
endif()
add_library(dpdk::cflags INTERFACE IMPORTED)
if (rte_cflags)
set_target_properties(dpdk::cflags PROPERTIES
INTERFACE_COMPILE_OPTIONS "${rte_cflags}")
endif()
endif()
if(NOT TARGET dpdk::dpdk)
add_library(dpdk::dpdk INTERFACE IMPORTED)
find_package(Threads QUIET)
list(APPEND dpdk_LIBRARIES
Threads::Threads
dpdk::cflags)
set_target_properties(dpdk::dpdk PROPERTIES
INTERFACE_LINK_LIBRARIES "${dpdk_LIBRARIES}"
INTERFACE_INCLUDE_DIRECTORIES "${dpdk_INCLUDE_DIRS}")
endif()
endif()

View File

@@ -15,9 +15,15 @@
/* define if we have the AIX getprotobyname_r() */ /* define if we have the AIX getprotobyname_r() */
#cmakedefine HAVE_AIX_GETPROTOBYNAME_R 1 #cmakedefine HAVE_AIX_GETPROTOBYNAME_R 1
/* define if you have the AirPcap API */
#cmakedefine HAVE_AIRPCAP_API 1
/* Define to 1 if you have the `asprintf' function. */ /* Define to 1 if you have the `asprintf' function. */
#cmakedefine HAVE_ASPRINTF 1 #cmakedefine HAVE_ASPRINTF 1
/* Define to 1 if you have the <config/HaikuConfig.h> header file. */
#cmakedefine HAVE_CONFIG_HAIKUCONFIG_H 1
/* define if you have the DAG API */ /* define if you have the DAG API */
#cmakedefine HAVE_DAG_API 1 #cmakedefine HAVE_DAG_API 1
@@ -69,45 +75,21 @@
/* if libnl exists */ /* if libnl exists */
#cmakedefine HAVE_LIBNL 1 #cmakedefine HAVE_LIBNL 1
/* if libnl exists and is version 2.x */
#cmakedefine HAVE_LIBNL_2_x 1
/* if libnl exists and is version 3.x */
#cmakedefine HAVE_LIBNL_3_x 1
/* libnl has NLE_FAILURE */
#cmakedefine HAVE_LIBNL_NLE 1
/* libnl has new-style socket api */
#cmakedefine HAVE_LIBNL_SOCKETS 1
/* Define to 1 if you have the <limits.h> header file. */
#cmakedefine HAVE_LIMITS_H 1
/* Define to 1 if you have the <linux/compiler.h> header file. */ /* Define to 1 if you have the <linux/compiler.h> header file. */
#cmakedefine HAVE_LINUX_COMPILER_H 1 #cmakedefine HAVE_LINUX_COMPILER_H 1
/* Define to 1 if you have the <linux/ethtool.h> header file. */
#cmakedefine HAVE_LINUX_ETHTOOL_H 1
/* define if we have the Linux getnetbyname_r() */ /* define if we have the Linux getnetbyname_r() */
#cmakedefine HAVE_LINUX_GETNETBYNAME_R 1 #cmakedefine HAVE_LINUX_GETNETBYNAME_R 1
/* define if we have the Linux getprotobyname_r() */ /* define if we have the Linux getprotobyname_r() */
#cmakedefine HAVE_LINUX_GETPROTOBYNAME_R 1 #cmakedefine HAVE_LINUX_GETPROTOBYNAME_R 1
/* Define to 1 if you have the <linux/if_bonding.h> header file. */
#cmakedefine HAVE_LINUX_IF_BONDING_H 1
/* Define to 1 if you have the <linux/net_tstamp.h> header file. */ /* Define to 1 if you have the <linux/net_tstamp.h> header file. */
#cmakedefine HAVE_LINUX_NET_TSTAMP_H 1 #cmakedefine HAVE_LINUX_NET_TSTAMP_H 1
/* Define to 1 if you have the <linux/socket.h> header file. */ /* Define to 1 if you have the <linux/socket.h> header file. */
#cmakedefine HAVE_LINUX_SOCKET_H 1 #cmakedefine HAVE_LINUX_SOCKET_H 1
/* Define to 1 if you have the <linux/sockios.h> header file. */
#cmakedefine HAVE_LINUX_SOCKIOS_H 1
/* Define to 1 if you have the <linux/usbdevice_fs.h> header file. */ /* Define to 1 if you have the <linux/usbdevice_fs.h> header file. */
#cmakedefine HAVE_LINUX_USBDEVICE_FS_H 1 #cmakedefine HAVE_LINUX_USBDEVICE_FS_H 1
@@ -141,6 +123,9 @@
/* Define to 1 if you have the <net/raw.h> header file. */ /* Define to 1 if you have the <net/raw.h> header file. */
#cmakedefine HAVE_NET_RAW_H 1 #cmakedefine HAVE_NET_RAW_H 1
/* Use OpenSSL */
#cmakedefine HAVE_OPENSSL 1
/* 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 */
#cmakedefine HAVE_OS_PROTO_H 1 #cmakedefine HAVE_OS_PROTO_H 1
@@ -186,9 +171,6 @@
/* Define to 1 if you have the `strerror' function. */ /* Define to 1 if you have the `strerror' function. */
#cmakedefine HAVE_STRERROR 1 #cmakedefine HAVE_STRERROR 1
/* Define to 1 if you have the `strerror_s' function. */
#cmakedefine HAVE_STRERROR_S 1
/* Define to 1 if you have the <strings.h> header file. */ /* Define to 1 if you have the <strings.h> header file. */
#cmakedefine HAVE_STRINGS_H 1 #cmakedefine HAVE_STRINGS_H 1
@@ -216,6 +198,9 @@
/* Define to 1 if `msg_flags' is a member of `struct msghdr'. */ /* Define to 1 if `msg_flags' is a member of `struct msghdr'. */
#cmakedefine HAVE_STRUCT_MSGHDR_MSG_FLAGS 1 #cmakedefine HAVE_STRUCT_MSGHDR_MSG_FLAGS 1
/* Define to 1 if the system has the type `struct rte_ether_addr'. */
#cmakedefine HAVE_STRUCT_RTE_ETHER_ADDR 1
/* Define to 1 if `hci_channel' is a member of `struct sockaddr_hci'. */ /* Define to 1 if `hci_channel' is a member of `struct sockaddr_hci'. */
#cmakedefine HAVE_STRUCT_SOCKADDR_HCI_HCI_CHANNEL 1 #cmakedefine HAVE_STRUCT_SOCKADDR_HCI_HCI_CHANNEL 1
@@ -228,9 +213,6 @@
/* Define to 1 if `tp_vlan_tci' is a member of `struct tpacket_auxdata'. */ /* Define to 1 if `tp_vlan_tci' is a member of `struct tpacket_auxdata'. */
#cmakedefine HAVE_STRUCT_TPACKET_AUXDATA_TP_VLAN_TCI 1 #cmakedefine HAVE_STRUCT_TPACKET_AUXDATA_TP_VLAN_TCI 1
/* Define to 1 if the system has the type `struct tpacket_stats'. */
#cmakedefine HAVE_STRUCT_TPACKET_STATS 1
/* Define to 1 if `bRequestType' is a member of `struct /* Define to 1 if `bRequestType' is a member of `struct
usbdevfs_ctrltransfer'. */ usbdevfs_ctrltransfer'. */
#cmakedefine HAVE_STRUCT_USBDEVFS_CTRLTRANSFER_BREQUESTTYPE 1 #cmakedefine HAVE_STRUCT_USBDEVFS_CTRLTRANSFER_BREQUESTTYPE 1
@@ -272,7 +254,19 @@
#cmakedefine HAVE_VSNPRINTF 1 #cmakedefine HAVE_VSNPRINTF 1
/* Define to 1 if you have the `vsyslog' function. */ /* Define to 1 if you have the `vsyslog' function. */
#undef HAVE_VSYSLOG #cmakedefine HAVE_VSYSLOG 1
/* Define to 1 if you have the `_wcserror_s' function. */
#cmakedefine HAVE__WCSERROR_S 1
/* define if __atomic_load_n is supported by the compiler */
#cmakedefine HAVE___ATOMIC_LOAD_N 1
/* define if __atomic_store_n is supported by the compiler */
#cmakedefine HAVE___ATOMIC_STORE_N 1
/* Define to 1 if you have the `PacketGetTimestampModes' function. */
#cmakedefine HAVE_PACKET_GET_TIMESTAMP_MODES 1
/* Define to 1 if you have the `PacketIsLoopbackAdapter' function. */ /* Define to 1 if you have the `PacketIsLoopbackAdapter' function. */
#cmakedefine HAVE_PACKET_IS_LOOPBACK_ADAPTER 1 #cmakedefine HAVE_PACKET_IS_LOOPBACK_ADAPTER 1
@@ -280,9 +274,6 @@
/* IPv6 */ /* IPv6 */
#cmakedefine INET6 1 #cmakedefine INET6 1
/* if unaligned access fails */
#cmakedefine LBL_ALIGN 1
/* path for device for USB sniffing */ /* path for device for USB sniffing */
#cmakedefine LINUX_USB_MON_DEV "@LINUX_USB_MON_DEV@" #cmakedefine LINUX_USB_MON_DEV "@LINUX_USB_MON_DEV@"
@@ -301,7 +292,7 @@
/* Define to the address where bug reports for this package should be sent. */ /* Define to the address where bug reports for this package should be sent. */
#cmakedefine PACKAGE_BUGREPORT 1 #cmakedefine PACKAGE_BUGREPORT 1
/* Define to the DLL-preferred version string of of this package. */ /* Define to the DLL-preferred version string of this package. */
#cmakedefine PACKAGE_VERSION_DLL @PACKAGE_VERSION_DLL@ #cmakedefine PACKAGE_VERSION_DLL @PACKAGE_VERSION_DLL@
/* Define to the full name of this package. */ /* Define to the full name of this package. */
@@ -328,24 +319,21 @@
/* support D-Bus sniffing */ /* support D-Bus sniffing */
#cmakedefine PCAP_SUPPORT_DBUS 1 #cmakedefine PCAP_SUPPORT_DBUS 1
/* target host supports DPDK */
#cmakedefine PCAP_SUPPORT_DPDK 1
/* target host supports Linux usbmon for USB sniffing */
#cmakedefine PCAP_SUPPORT_LINUX_USBMON 1
/* target host supports netfilter sniffing */ /* target host supports netfilter sniffing */
#cmakedefine PCAP_SUPPORT_NETFILTER 1 #cmakedefine PCAP_SUPPORT_NETFILTER 1
/* target host supports netmap */ /* target host supports netmap */
#cmakedefine PCAP_SUPPORT_NETMAP 1 #cmakedefine PCAP_SUPPORT_NETMAP 1
/* use packet ring capture support on Linux if available */
#cmakedefine PCAP_SUPPORT_PACKET_RING 1
/* target host supports RDMA sniffing */ /* target host supports RDMA sniffing */
#cmakedefine PCAP_SUPPORT_RDMASNIFF 1 #cmakedefine PCAP_SUPPORT_RDMASNIFF 1
/* target host supports USB sniffing */
#cmakedefine PCAP_SUPPORT_USB 1
/* include ACN support */
#cmakedefine SITA 1
/* Define to 1 if you have the ANSI C header files. */ /* Define to 1 if you have the ANSI C header files. */
#cmakedefine STDC_HEADERS 1 #cmakedefine STDC_HEADERS 1

608
libpcap/config.guess vendored

File diff suppressed because it is too large Load Diff

View File

@@ -18,6 +18,9 @@
/* Define to 1 if you have the `asprintf' function. */ /* Define to 1 if you have the `asprintf' function. */
#undef HAVE_ASPRINTF #undef HAVE_ASPRINTF
/* Define to 1 if you have the <config/HaikuConfig.h> header file. */
#undef HAVE_CONFIG_HAIKUCONFIG_H
/* Define to 1 if you have the <dagapi.h> header file. */ /* Define to 1 if you have the <dagapi.h> header file. */
#undef HAVE_DAGAPI_H #undef HAVE_DAGAPI_H
@@ -78,45 +81,21 @@
/* if libnl exists */ /* if libnl exists */
#undef HAVE_LIBNL #undef HAVE_LIBNL
/* if libnl exists and is version 2.x */
#undef HAVE_LIBNL_2_x
/* if libnl exists and is version 3.x */
#undef HAVE_LIBNL_3_x
/* libnl has NLE_FAILURE */
#undef HAVE_LIBNL_NLE
/* libnl has new-style socket api */
#undef HAVE_LIBNL_SOCKETS
/* Define to 1 if you have the <limits.h> header file. */
#undef HAVE_LIMITS_H
/* Define to 1 if you have the <linux/compiler.h> header file. */ /* Define to 1 if you have the <linux/compiler.h> header file. */
#undef HAVE_LINUX_COMPILER_H #undef HAVE_LINUX_COMPILER_H
/* Define to 1 if you have the <linux/ethtool.h> header file. */
#undef HAVE_LINUX_ETHTOOL_H
/* define if we have the Linux getnetbyname_r() */ /* define if we have the Linux getnetbyname_r() */
#undef HAVE_LINUX_GETNETBYNAME_R #undef HAVE_LINUX_GETNETBYNAME_R
/* define if we have the Linux getprotobyname_r() */ /* define if we have the Linux getprotobyname_r() */
#undef HAVE_LINUX_GETPROTOBYNAME_R #undef HAVE_LINUX_GETPROTOBYNAME_R
/* Define to 1 if you have the <linux/if_bonding.h> header file. */
#undef HAVE_LINUX_IF_BONDING_H
/* Define to 1 if you have the <linux/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/socket.h> header file. */ /* Define to 1 if you have the <linux/socket.h> header file. */
#undef HAVE_LINUX_SOCKET_H #undef HAVE_LINUX_SOCKET_H
/* Define to 1 if you have the <linux/sockios.h> header file. */
#undef HAVE_LINUX_SOCKIOS_H
/* Define to 1 if you have the <linux/usbdevice_fs.h> header file. */ /* Define to 1 if you have the <linux/usbdevice_fs.h> header file. */
#undef HAVE_LINUX_USBDEVICE_FS_H #undef HAVE_LINUX_USBDEVICE_FS_H
@@ -135,9 +114,18 @@
/* Define to 1 if you have the <net/enet.h> header file. */ /* Define to 1 if you have the <net/enet.h> header file. */
#undef HAVE_NET_ENET_H #undef HAVE_NET_ENET_H
/* Define to 1 if you have the <net/if_dl.h> header file. */
#undef HAVE_NET_IF_DL_H
/* Define to 1 if you have the <net/if.h> header file. */
#undef HAVE_NET_IF_H
/* Define to 1 if you have the <net/if_media.h> header file. */ /* Define to 1 if you have the <net/if_media.h> header file. */
#undef HAVE_NET_IF_MEDIA_H #undef HAVE_NET_IF_MEDIA_H
/* Define to 1 if you have the <net/if_types.h> header file. */
#undef HAVE_NET_IF_TYPES_H
/* Define to 1 if you have the <net/nit.h> header file. */ /* Define to 1 if you have the <net/nit.h> header file. */
#undef HAVE_NET_NIT_H #undef HAVE_NET_NIT_H
@@ -150,6 +138,9 @@
/* Define to 1 if you have the <net/raw.h> header file. */ /* Define to 1 if you have the <net/raw.h> header file. */
#undef HAVE_NET_RAW_H #undef HAVE_NET_RAW_H
/* Use OpenSSL */
#undef HAVE_OPENSSL
/* 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
@@ -165,9 +156,6 @@
/* define if you have the 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. */
#undef HAVE_SNPRINTF
/* Define to 1 if the system has the type `socklen_t'. */ /* Define to 1 if the system has the type `socklen_t'. */
#undef HAVE_SOCKLEN_T #undef HAVE_SOCKLEN_T
@@ -189,9 +177,6 @@
/* Define to 1 if you have the `strerror' function. */ /* Define to 1 if you have the `strerror' function. */
#undef HAVE_STRERROR #undef HAVE_STRERROR
/* Define to 1 if you have the `strerror_s' function. */
#undef HAVE_STRERROR_S
/* Define to 1 if you have the <strings.h> header file. */ /* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H #undef HAVE_STRINGS_H
@@ -219,6 +204,9 @@
/* Define to 1 if `msg_flags' is a member of `struct msghdr'. */ /* Define to 1 if `msg_flags' is a member of `struct msghdr'. */
#undef HAVE_STRUCT_MSGHDR_MSG_FLAGS #undef HAVE_STRUCT_MSGHDR_MSG_FLAGS
/* Define to 1 if the system has the type `struct rte_ether_addr'. */
#undef HAVE_STRUCT_RTE_ETHER_ADDR
/* Define to 1 if `hci_channel' is a member of `struct sockaddr_hci'. */ /* Define to 1 if `hci_channel' is a member of `struct sockaddr_hci'. */
#undef HAVE_STRUCT_SOCKADDR_HCI_HCI_CHANNEL #undef HAVE_STRUCT_SOCKADDR_HCI_HCI_CHANNEL
@@ -231,9 +219,6 @@
/* Define to 1 if `tp_vlan_tci' is a member of `struct tpacket_auxdata'. */ /* Define to 1 if `tp_vlan_tci' is a member of `struct tpacket_auxdata'. */
#undef HAVE_STRUCT_TPACKET_AUXDATA_TP_VLAN_TCI #undef HAVE_STRUCT_TPACKET_AUXDATA_TP_VLAN_TCI
/* Define to 1 if the system has the type `struct tpacket_stats'. */
#undef HAVE_STRUCT_TPACKET_STATS
/* Define to 1 if `bRequestType' is a member of `struct /* Define to 1 if `bRequestType' is a member of `struct
usbdevfs_ctrltransfer'. */ usbdevfs_ctrltransfer'. */
#undef HAVE_STRUCT_USBDEVFS_CTRLTRANSFER_BREQUESTTYPE #undef HAVE_STRUCT_USBDEVFS_CTRLTRANSFER_BREQUESTTYPE
@@ -271,18 +256,21 @@
/* Define to 1 if you have the `vasprintf' function. */ /* Define to 1 if you have the `vasprintf' function. */
#undef HAVE_VASPRINTF #undef HAVE_VASPRINTF
/* Define to 1 if you have the `vsnprintf' function. */
#undef HAVE_VSNPRINTF
/* Define to 1 if you have the `vsyslog' function. */ /* Define to 1 if you have the `vsyslog' function. */
#undef HAVE_VSYSLOG #undef HAVE_VSYSLOG
/* Define to 1 if you have the `_wcserror_s' function. */
#undef HAVE__WCSERROR_S
/* define if __atomic_load_n is supported by the compiler */
#undef HAVE___ATOMIC_LOAD_N
/* define if __atomic_store_n is supported by the compiler */
#undef HAVE___ATOMIC_STORE_N
/* IPv6 */ /* IPv6 */
#undef INET6 #undef INET6
/* if unaligned access fails */
#undef LBL_ALIGN
/* path for device for USB sniffing */ /* path for device for USB sniffing */
#undef LINUX_USB_MON_DEV #undef LINUX_USB_MON_DEV
@@ -325,24 +313,21 @@
/* support D-Bus sniffing */ /* support D-Bus sniffing */
#undef PCAP_SUPPORT_DBUS #undef PCAP_SUPPORT_DBUS
/* target host supports DPDK */
#undef PCAP_SUPPORT_DPDK
/* target host supports Linux usbmon for USB sniffing */
#undef PCAP_SUPPORT_LINUX_USBMON
/* target host supports netfilter sniffing */ /* target host supports netfilter sniffing */
#undef PCAP_SUPPORT_NETFILTER #undef PCAP_SUPPORT_NETFILTER
/* target host supports netmap */ /* target host supports netmap */
#undef PCAP_SUPPORT_NETMAP #undef PCAP_SUPPORT_NETMAP
/* use packet ring capture support on Linux if available */
#undef PCAP_SUPPORT_PACKET_RING
/* target host supports RDMA sniffing */ /* target host supports RDMA sniffing */
#undef PCAP_SUPPORT_RDMASNIFF #undef PCAP_SUPPORT_RDMASNIFF
/* target host supports USB sniffing */
#undef PCAP_SUPPORT_USB
/* include ACN support */
#undef SITA
/* Define to 1 if you have the ANSI C header files. */ /* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS #undef STDC_HEADERS

1838
libpcap/config.sub vendored

File diff suppressed because it is too large Load Diff

2224
libpcap/configure vendored

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -48,7 +48,43 @@
#endif #endif
/* /*
* Suppress Flex warnings. * Suppress "enum value not explicitly handled in switch" warnings.
* We may have to build on multiple different Windows SDKs, so we
* may not be able to include all enum values in a switch, as they
* won't necessarily be defined on all the SDKs, and, unlike
* #defines, there's no easy way to test whether a given enum has
* a given value. It *could* be done by the configure script or
* CMake tests.
*/
#if defined(_MSC_VER)
#define DIAG_OFF_ENUM_SWITCH \
__pragma(warning(push)) \
__pragma(warning(disable:4061))
#define DIAG_ON_ENUM_SWITCH \
__pragma(warning(pop))
#else
#define DIAG_OFF_ENUM_SWITCH
#define DIAG_ON_ENUM_SWITCH
#endif
/*
* Suppress "switch statement has only a default case" warnings.
* There's a switch in bpf_filter.c that only has additional
* cases on Linux.
*/
#if defined(_MSC_VER)
#define DIAG_OFF_DEFAULT_ONLY_SWITCH \
__pragma(warning(push)) \
__pragma(warning(disable:4065))
#define DIAG_ON_DEFAULT_ONLY_SWITCH \
__pragma(warning(pop))
#else
#define DIAG_OFF_DEFAULT_ONLY_SWITCH
#define DIAG_ON_DEFAULT_ONLY_SWITCH
#endif
/*
* Suppress Flex, narrowing, and deprecation warnings.
*/ */
#if defined(_MSC_VER) #if defined(_MSC_VER)
/* /*
@@ -64,7 +100,27 @@
__pragma(warning(disable:4242)) \ __pragma(warning(disable:4242)) \
__pragma(warning(disable:4244)) \ __pragma(warning(disable:4244)) \
__pragma(warning(disable:4702)) __pragma(warning(disable:4702))
#define DIAG_ON_FLEX __pragma(warning(pop)) #define DIAG_ON_FLEX \
__pragma(warning(pop))
/*
* Suppress narrowing warnings.
*/
#define DIAG_OFF_NARROWING \
__pragma(warning(push)) \
__pragma(warning(disable:4242)) \
__pragma(warning(disable:4311))
#define DIAG_ON_NARROWING \
__pragma(warning(pop))
/*
* Suppress deprecation warnings.
*/
#define DIAG_OFF_DEPRECATION \
__pragma(warning(push)) \
__pragma(warning(disable:4996))
#define DIAG_ON_DEPRECATION \
__pragma(warning(pop))
#elif PCAP_IS_AT_LEAST_CLANG_VERSION(2,8) #elif PCAP_IS_AT_LEAST_CLANG_VERSION(2,8)
/* /*
* This is Clang 2.8 or later; we can use "clang diagnostic * This is Clang 2.8 or later; we can use "clang diagnostic
@@ -79,11 +135,31 @@
PCAP_DO_PRAGMA(clang diagnostic push) \ PCAP_DO_PRAGMA(clang diagnostic push) \
PCAP_DO_PRAGMA(clang diagnostic ignored "-Wsign-compare") \ PCAP_DO_PRAGMA(clang diagnostic ignored "-Wsign-compare") \
PCAP_DO_PRAGMA(clang diagnostic ignored "-Wdocumentation") \ PCAP_DO_PRAGMA(clang diagnostic ignored "-Wdocumentation") \
PCAP_DO_PRAGMA(clang diagnostic ignored "-Wshorten-64-to-32") \
PCAP_DO_PRAGMA(clang diagnostic ignored "-Wmissing-noreturn") \ PCAP_DO_PRAGMA(clang diagnostic ignored "-Wmissing-noreturn") \
PCAP_DO_PRAGMA(clang diagnostic ignored "-Wunused-parameter") \ PCAP_DO_PRAGMA(clang diagnostic ignored "-Wunused-parameter") \
PCAP_DO_PRAGMA(clang diagnostic ignored "-Wunreachable-code") PCAP_DO_PRAGMA(clang diagnostic ignored "-Wunreachable-code")
#define DIAG_ON_FLEX \ #define DIAG_ON_FLEX \
PCAP_DO_PRAGMA(clang diagnostic pop) PCAP_DO_PRAGMA(clang diagnostic pop)
/*
* Suppress the only narrowing warnings you get from Clang.
*/
#define DIAG_OFF_NARROWING \
PCAP_DO_PRAGMA(clang diagnostic push) \
PCAP_DO_PRAGMA(clang diagnostic ignored "-Wshorten-64-to-32")
#define DIAG_ON_NARROWING \
PCAP_DO_PRAGMA(clang diagnostic pop)
/*
* Suppress deprecation warnings.
*/
#define DIAG_OFF_DEPRECATION \
PCAP_DO_PRAGMA(clang diagnostic push) \
PCAP_DO_PRAGMA(clang diagnostic ignored "-Wdeprecated-declarations")
#define DIAG_ON_DEPRECATION \
PCAP_DO_PRAGMA(clang diagnostic pop)
#elif PCAP_IS_AT_LEAST_GNUC_VERSION(4,6) #elif PCAP_IS_AT_LEAST_GNUC_VERSION(4,6)
/* /*
* This is GCC 4.6 or later, or a compiler claiming to be that. * This is GCC 4.6 or later, or a compiler claiming to be that.
@@ -97,6 +173,21 @@
PCAP_DO_PRAGMA(GCC diagnostic ignored "-Wunreachable-code") PCAP_DO_PRAGMA(GCC diagnostic ignored "-Wunreachable-code")
#define DIAG_ON_FLEX \ #define DIAG_ON_FLEX \
PCAP_DO_PRAGMA(GCC diagnostic pop) PCAP_DO_PRAGMA(GCC diagnostic pop)
/*
* GCC currently doesn't issue any narrowing warnings.
*/
#define DIAG_OFF_NARROWING
#define DIAG_ON_NARROWING
/*
* Suppress deprecation warnings.
*/
#define DIAG_OFF_DEPRECATION \
PCAP_DO_PRAGMA(GCC diagnostic push) \
PCAP_DO_PRAGMA(GCC diagnostic ignored "-Wdeprecated-declarations")
#define DIAG_ON_DEPRECATION \
PCAP_DO_PRAGMA(GCC diagnostic pop)
#else #else
/* /*
* Neither Visual Studio, nor Clang 2.8 or later, nor GCC 4.6 or later * Neither Visual Studio, nor Clang 2.8 or later, nor GCC 4.6 or later
@@ -105,6 +196,10 @@
*/ */
#define DIAG_OFF_FLEX #define DIAG_OFF_FLEX
#define DIAG_ON_FLEX #define DIAG_ON_FLEX
#define DIAG_OFF_NARROWING
#define DIAG_ON_NARROWING
#define DIAG_OFF_DEPRECATION
#define DIAG_ON_DEPRECATION
#endif #endif
#ifdef YYBYACC #ifdef YYBYACC
@@ -127,92 +222,75 @@
#if defined(_MSC_VER) #if defined(_MSC_VER)
/* /*
* This is Microsoft Visual Studio; we can use * This is Microsoft Visual Studio; we can use
* __pragma(warning(disable:XXXX)) and __pragma(warning(push/pop)). * __pragma(warning(disable:XXXX)).
*/ */
#define DIAG_OFF_BISON_BYACC \ #define DIAG_OFF_BISON_BYACC \
__pragma(warning(push)) \
__pragma(warning(disable:4702)) __pragma(warning(disable:4702))
#define DIAG_ON_BISON_BYACC __pragma(warning(pop))
#elif PCAP_IS_AT_LEAST_CLANG_VERSION(2,8) #elif PCAP_IS_AT_LEAST_CLANG_VERSION(2,8)
/* /*
* This is Clang 2.8 or later; we can use "clang diagnostic * This is Clang 2.8 or later; we can use "clang diagnostic
* ignored -Wxxx" and "clang diagnostic push/pop". * ignored -Wxxx".
*/ */
#define DIAG_OFF_BISON_BYACC \ #define DIAG_OFF_BISON_BYACC \
PCAP_DO_PRAGMA(clang diagnostic push) \
PCAP_DO_PRAGMA(clang diagnostic ignored "-Wshadow") \ PCAP_DO_PRAGMA(clang diagnostic ignored "-Wshadow") \
PCAP_DO_PRAGMA(clang diagnostic ignored "-Wunreachable-code") PCAP_DO_PRAGMA(clang diagnostic ignored "-Wunreachable-code")
#define DIAG_ON_BISON_BYACC \
PCAP_DO_PRAGMA(clang diagnostic pop)
#elif PCAP_IS_AT_LEAST_GNUC_VERSION(4,6) #elif PCAP_IS_AT_LEAST_GNUC_VERSION(4,6)
/* /*
* This is GCC 4.6 or later, or a compiler claiming to be that. * This is GCC 4.6 or later, or a compiler claiming to be that.
* We can use "GCC diagnostic ignored -Wxxx" (introduced in 4.2) * We can use "GCC diagnostic ignored -Wxxx" (introduced in 4.2,
* and "GCC diagnostic push/pop" (introduced in 4.6). * but it may not actually work very well prior to 4.6).
*/ */
#define DIAG_OFF_BISON_BYACC \ #define DIAG_OFF_BISON_BYACC \
PCAP_DO_PRAGMA(GCC diagnostic push) \
PCAP_DO_PRAGMA(GCC diagnostic ignored "-Wshadow") \ PCAP_DO_PRAGMA(GCC diagnostic ignored "-Wshadow") \
PCAP_DO_PRAGMA(GCC diagnostic ignored "-Wunreachable-code") PCAP_DO_PRAGMA(GCC diagnostic ignored "-Wunreachable-code")
#define DIAG_ON_BISON_BYACC \
PCAP_DO_PRAGMA(GCC diagnostic pop)
#else #else
/* /*
* Neither Clang 2.8 or later nor GCC 4.6 or later or a compiler * Neither Clang 2.8 or later nor GCC 4.6 or later or a compiler
* claiming to be that; there's nothing we know of that we can do. * claiming to be that; there's nothing we know of that we can do.
*/ */
#define DIAG_OFF_BISON_BYACC #define DIAG_OFF_BISON_BYACC
#define DIAG_ON_BISON_BYACC
#endif #endif
#else #else
/* /*
* Bison. * Bison.
* *
* The generated code may have functions with unreachable code, so * The generated code may have functions with unreachable code and
* suppress warnings about those. * switches with only a default case, so suppress warnings about those.
*/ */
#if defined(_MSC_VER) #if defined(_MSC_VER)
/* /*
* This is Microsoft Visual Studio; we can use * This is Microsoft Visual Studio; we can use
* __pragma(warning(disable:XXXX)) and __pragma(warning(push/pop)). * __pragma(warning(disable:XXXX)).
* *
* Suppress some /Wall warnings. * Suppress some /Wall warnings.
*/ */
#define DIAG_OFF_BISON_BYACC \ #define DIAG_OFF_BISON_BYACC \
__pragma(warning(push)) \ __pragma(warning(disable:4065)) \
__pragma(warning(disable:4127)) \ __pragma(warning(disable:4127)) \
__pragma(warning(disable:4242)) \ __pragma(warning(disable:4242)) \
__pragma(warning(disable:4244)) \ __pragma(warning(disable:4244)) \
__pragma(warning(disable:4702)) __pragma(warning(disable:4702))
#define DIAG_ON_BISON_BYACC __pragma(warning(pop))
#elif PCAP_IS_AT_LEAST_CLANG_VERSION(2,8) #elif PCAP_IS_AT_LEAST_CLANG_VERSION(2,8)
/* /*
* This is Clang 2.8 or later; we can use "clang diagnostic * This is Clang 2.8 or later; we can use "clang diagnostic
* ignored -Wxxx" and "clang diagnostic push/pop". * ignored -Wxxx".
*/ */
#define DIAG_OFF_BISON_BYACC \ #define DIAG_OFF_BISON_BYACC \
PCAP_DO_PRAGMA(clang diagnostic push) \
PCAP_DO_PRAGMA(clang diagnostic ignored "-Wunreachable-code") PCAP_DO_PRAGMA(clang diagnostic ignored "-Wunreachable-code")
#define DIAG_ON_BISON_BYACC \
PCAP_DO_PRAGMA(clang diagnostic pop)
#elif PCAP_IS_AT_LEAST_GNUC_VERSION(4,6) #elif PCAP_IS_AT_LEAST_GNUC_VERSION(4,6)
/* /*
* This is GCC 4.6 or later, or a compiler claiming to be that. * This is GCC 4.6 or later, or a compiler claiming to be that.
* We can use "GCC diagnostic ignored -Wxxx" (introduced in 4.2) * We can use "GCC diagnostic ignored -Wxxx" (introduced in 4.2,
* and "GCC diagnostic push/pop" (introduced in 4.6). * but it may not actually work very well prior to 4.6).
*/ */
#define DIAG_OFF_BISON_BYACC \ #define DIAG_OFF_BISON_BYACC \
PCAP_DO_PRAGMA(GCC diagnostic push) \
PCAP_DO_PRAGMA(GCC diagnostic ignored "-Wunreachable-code") PCAP_DO_PRAGMA(GCC diagnostic ignored "-Wunreachable-code")
#define DIAG_ON_BISON_BYACC \
PCAP_DO_PRAGMA(GCC diagnostic pop)
#else #else
/* /*
* Neither Clang 2.8 or later nor GCC 4.6 or later or a compiler * Neither Clang 2.8 or later nor GCC 4.6 or later or a compiler
* claiming to be that; there's nothing we know of that we can do. * claiming to be that; there's nothing we know of that we can do.
*/ */
#define DIAG_OFF_BISON_BYACC #define DIAG_OFF_BISON_BYACC
#define DIAG_ON_BISON_BYACC
#endif #endif
#endif #endif

View File

@@ -113,6 +113,20 @@ pcap_stats_dlpi(pcap_t *p, struct pcap_stat *ps)
return (0); return (0);
} }
/*
* Does the processor for which we're compiling this support aligned loads?
*/
#if (defined(__i386__) || defined(_M_IX86) || defined(__X86__) || defined(__x86_64__) || defined(_M_X64)) || \
(defined(__arm__) || defined(_M_ARM) || defined(__aarch64__)) || \
(defined(__m68k__) && (!defined(__mc68000__) && !defined(__mc68010__))) || \
(defined(__ppc__) || defined(__ppc64__) || defined(_M_PPC) || defined(_ARCH_PPC) || defined(_ARCH_PPC64)) || \
(defined(__s390__) || defined(__s390x__) || defined(__zarch__))
/* Yes, it does. */
#else
/* No, it doesn't. */
#define REQUIRE_ALIGNMENT
#endif
/* /*
* Loop through the packets and call the callback for each packet. * Loop through the packets and call the callback for each packet.
* Return the number of packets read. * Return the number of packets read.
@@ -127,7 +141,7 @@ pcap_process_pkts(pcap_t *p, pcap_handler callback, u_char *user,
struct pcap_pkthdr pkthdr; struct pcap_pkthdr pkthdr;
#ifdef HAVE_SYS_BUFMOD_H #ifdef HAVE_SYS_BUFMOD_H
struct sb_hdr *sbp; struct sb_hdr *sbp;
#ifdef LBL_ALIGN #ifdef REQUIRE_ALIGNMENT
struct sb_hdr sbhdr; struct sb_hdr sbhdr;
#endif #endif
#endif #endif
@@ -157,7 +171,7 @@ pcap_process_pkts(pcap_t *p, pcap_handler callback, u_char *user,
return (n); return (n);
} }
} }
#ifdef LBL_ALIGN #ifdef REQUIRE_ALIGNMENT
if ((long)bufp & 3) { if ((long)bufp & 3) {
sbp = &sbhdr; sbp = &sbhdr;
memcpy(sbp, bufp, sizeof(*sbp)); memcpy(sbp, bufp, sizeof(*sbp));
@@ -176,7 +190,7 @@ pcap_process_pkts(pcap_t *p, pcap_handler callback, u_char *user,
bufp += caplen; bufp += caplen;
#endif #endif
++pd->stat.ps_recv; ++pd->stat.ps_recv;
if (bpf_filter(p->fcode.bf_insns, pk, origlen, caplen)) { if (pcap_filter(p->fcode.bf_insns, pk, origlen, caplen)) {
#ifdef HAVE_SYS_BUFMOD_H #ifdef HAVE_SYS_BUFMOD_H
pkthdr.ts.tv_sec = sbp->sbh_timestamp.tv_sec; pkthdr.ts.tv_sec = sbp->sbh_timestamp.tv_sec;
pkthdr.ts.tv_usec = sbp->sbh_timestamp.tv_usec; pkthdr.ts.tv_usec = sbp->sbh_timestamp.tv_usec;
@@ -275,7 +289,7 @@ pcap_process_mactype(pcap_t *p, u_int mactype)
* XXX - DL_IPNET devices default to "raw IP" rather than * XXX - DL_IPNET devices default to "raw IP" rather than
* "IPNET header"; see * "IPNET header"; see
* *
* http://seclists.org/tcpdump/2009/q1/202 * https://seclists.org/tcpdump/2009/q1/202
* *
* We'd have to do DL_IOC_IPNET_INFO to enable getting * We'd have to do DL_IOC_IPNET_INFO to enable getting
* the IPNET header. * the IPNET header.
@@ -286,7 +300,7 @@ pcap_process_mactype(pcap_t *p, u_int mactype)
#endif #endif
default: default:
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "unknown mactype 0x%x", snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "unknown mactype 0x%x",
mactype); mactype);
retv = -1; retv = -1;
} }

View File

@@ -25,7 +25,6 @@
#include <pcap-types.h> #include <pcap-types.h>
#include <ctype.h>
#include <memory.h> #include <memory.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@@ -45,14 +44,18 @@ static inline int skip_line(FILE *);
static inline u_char static inline u_char
xdtoi(u_char c) xdtoi(u_char c)
{ {
if (isdigit(c)) if (c >= '0' && c <= '9')
return (u_char)(c - '0'); return (u_char)(c - '0');
else if (islower(c)) else if (c >= 'a' && c <= 'f')
return (u_char)(c - 'a' + 10); return (u_char)(c - 'a' + 10);
else else
return (u_char)(c - 'A' + 10); return (u_char)(c - 'A' + 10);
} }
/*
* Skip linear white space (space and tab) and any CRs before LF.
* Stop when we hit a non-white-space character or an end-of-line LF.
*/
static inline int static inline int
skip_space(FILE *f) skip_space(FILE *f)
{ {
@@ -60,7 +63,7 @@ skip_space(FILE *f)
do { do {
c = getc(f); c = getc(f);
} while (isspace(c) && c != '\n'); } while (c == ' ' || c == '\t' || c == '\r');
return c; return c;
} }
@@ -97,7 +100,7 @@ pcap_next_etherent(FILE *fp)
/* If this is a comment, or first thing on line /* If this is a comment, or first thing on line
cannot be Ethernet address, skip the line. */ cannot be Ethernet address, skip the line. */
if (!isxdigit(c)) { if (!PCAP_ISXDIGIT(c)) {
c = skip_line(fp); c = skip_line(fp);
if (c == EOF) if (c == EOF)
return (NULL); return (NULL);
@@ -110,7 +113,7 @@ pcap_next_etherent(FILE *fp)
c = getc(fp); c = getc(fp);
if (c == EOF) if (c == EOF)
return (NULL); return (NULL);
if (isxdigit(c)) { if (PCAP_ISXDIGIT(c)) {
d <<= 4; d <<= 4;
d |= xdtoi((u_char)c); d |= xdtoi((u_char)c);
c = getc(fp); c = getc(fp);
@@ -126,7 +129,7 @@ pcap_next_etherent(FILE *fp)
} }
/* Must be whitespace */ /* Must be whitespace */
if (!isspace(c)) { if (c != ' ' && c != '\t' && c != '\r' && c != '\n') {
c = skip_line(fp); c = skip_line(fp);
if (c == EOF) if (c == EOF)
return (NULL); return (NULL);
@@ -156,7 +159,8 @@ pcap_next_etherent(FILE *fp)
c = getc(fp); c = getc(fp);
if (c == EOF) if (c == EOF)
return (NULL); return (NULL);
} while (!isspace(c) && --namesize != 0); } while (c != ' ' && c != '\t' && c != '\r' && c != '\n'
&& --namesize != 0);
*bp = '\0'; *bp = '\0';
/* Eat trailing junk */ /* Eat trailing junk */

View File

@@ -32,58 +32,58 @@
*/ */
#ifndef ETHERTYPE_PUP #ifndef ETHERTYPE_PUP
#define ETHERTYPE_PUP 0x0200 /* PUP protocol */ #define ETHERTYPE_PUP 0x0200 /* PUP protocol */
#endif #endif
#ifndef ETHERTYPE_IP #ifndef ETHERTYPE_IP
#define ETHERTYPE_IP 0x0800 /* IP protocol */ #define ETHERTYPE_IP 0x0800 /* IP protocol */
#endif #endif
#ifndef ETHERTYPE_ARP #ifndef ETHERTYPE_ARP
#define ETHERTYPE_ARP 0x0806 /* Addr. resolution protocol */ #define ETHERTYPE_ARP 0x0806 /* Addr. resolution protocol */
#endif #endif
#ifndef ETHERTYPE_REVARP
#define ETHERTYPE_REVARP 0x8035 /* reverse Addr. resolution protocol */
#endif
#ifndef ETHERTYPE_NS #ifndef ETHERTYPE_NS
#define ETHERTYPE_NS 0x0600 #define ETHERTYPE_NS 0x0600
#endif #endif
#ifndef ETHERTYPE_SPRITE #ifndef ETHERTYPE_SPRITE
#define ETHERTYPE_SPRITE 0x0500 #define ETHERTYPE_SPRITE 0x0500
#endif #endif
#ifndef ETHERTYPE_TRAIL #ifndef ETHERTYPE_TRAIL
#define ETHERTYPE_TRAIL 0x1000 #define ETHERTYPE_TRAIL 0x1000
#endif #endif
#ifndef ETHERTYPE_MOPDL #ifndef ETHERTYPE_MOPDL
#define ETHERTYPE_MOPDL 0x6001 #define ETHERTYPE_MOPDL 0x6001
#endif #endif
#ifndef ETHERTYPE_MOPRC #ifndef ETHERTYPE_MOPRC
#define ETHERTYPE_MOPRC 0x6002 #define ETHERTYPE_MOPRC 0x6002
#endif #endif
#ifndef ETHERTYPE_DN #ifndef ETHERTYPE_DN
#define ETHERTYPE_DN 0x6003 #define ETHERTYPE_DN 0x6003
#endif #endif
#ifndef ETHERTYPE_LAT #ifndef ETHERTYPE_LAT
#define ETHERTYPE_LAT 0x6004 #define ETHERTYPE_LAT 0x6004
#endif #endif
#ifndef ETHERTYPE_SCA #ifndef ETHERTYPE_SCA
#define ETHERTYPE_SCA 0x6007 #define ETHERTYPE_SCA 0x6007
#endif #endif
#ifndef ETHERTYPE_TEB
#define ETHERTYPE_TEB 0x6558
#endif
#ifndef ETHERTYPE_REVARP #ifndef ETHERTYPE_REVARP
#define ETHERTYPE_REVARP 0x8035 #define ETHERTYPE_REVARP 0x8035 /* reverse Addr. resolution protocol */
#endif #endif
#ifndef ETHERTYPE_LANBRIDGE #ifndef ETHERTYPE_LANBRIDGE
#define ETHERTYPE_LANBRIDGE 0x8038 #define ETHERTYPE_LANBRIDGE 0x8038
#endif #endif
#ifndef ETHERTYPE_DECDNS #ifndef ETHERTYPE_DECDNS
#define ETHERTYPE_DECDNS 0x803c #define ETHERTYPE_DECDNS 0x803c
#endif #endif
#ifndef ETHERTYPE_DECDTS #ifndef ETHERTYPE_DECDTS
#define ETHERTYPE_DECDTS 0x803e #define ETHERTYPE_DECDTS 0x803e
#endif #endif
#ifndef ETHERTYPE_VEXP #ifndef ETHERTYPE_VEXP
#define ETHERTYPE_VEXP 0x805b #define ETHERTYPE_VEXP 0x805b
#endif #endif
#ifndef ETHERTYPE_VPROD #ifndef ETHERTYPE_VPROD
#define ETHERTYPE_VPROD 0x805c #define ETHERTYPE_VPROD 0x805c
#endif #endif
#ifndef ETHERTYPE_ATALK #ifndef ETHERTYPE_ATALK
#define ETHERTYPE_ATALK 0x809b #define ETHERTYPE_ATALK 0x809b
@@ -101,10 +101,10 @@
#define ETHERTYPE_IPV6 0x86dd #define ETHERTYPE_IPV6 0x86dd
#endif #endif
#ifndef ETHERTYPE_MPLS #ifndef ETHERTYPE_MPLS
#define ETHERTYPE_MPLS 0x8847 #define ETHERTYPE_MPLS 0x8847
#endif #endif
#ifndef ETHERTYPE_MPLS_MULTI #ifndef ETHERTYPE_MPLS_MULTI
#define ETHERTYPE_MPLS_MULTI 0x8848 #define ETHERTYPE_MPLS_MULTI 0x8848
#endif #endif
#ifndef ETHERTYPE_PPPOED #ifndef ETHERTYPE_PPPOED
#define ETHERTYPE_PPPOED 0x8863 #define ETHERTYPE_PPPOED 0x8863
@@ -116,7 +116,7 @@
#define ETHERTYPE_8021AD 0x88a8 #define ETHERTYPE_8021AD 0x88a8
#endif #endif
#ifndef ETHERTYPE_LOOPBACK #ifndef ETHERTYPE_LOOPBACK
#define ETHERTYPE_LOOPBACK 0x9000 #define ETHERTYPE_LOOPBACK 0x9000
#endif #endif
#ifndef ETHERTYPE_8021QINQ #ifndef ETHERTYPE_8021QINQ
#define ETHERTYPE_8021QINQ 0x9100 #define ETHERTYPE_8021QINQ 0x9100

View File

@@ -25,15 +25,94 @@
#include <pcap/pcap-inttypes.h> #include <pcap/pcap-inttypes.h>
#include <pcap/compiler-tests.h> #include <pcap/compiler-tests.h>
#include "portability.h"
/* /*
* Macros to extract possibly-unaligned big-endian integral values. * If we have versions of GCC or Clang that support an __attribute__
* to say "if we're building with unsigned behavior sanitization,
* don't complain about undefined behavior in this function", we
* label these functions with that attribute - we *know* it's undefined
* in the C standard, but we *also* know it does what we want with
* the ISA we're targeting and the compiler we're using.
*
* For GCC 4.9.0 and later, we use __attribute__((no_sanitize_undefined));
* pre-5.0 GCC doesn't have __has_attribute, and I'm not sure whether
* GCC or Clang first had __attribute__((no_sanitize(XXX)).
*
* For Clang, we check for __attribute__((no_sanitize(XXX)) with
* __has_attribute, as there are versions of Clang that support
* __attribute__((no_sanitize("undefined")) but don't support
* __attribute__((no_sanitize_undefined)).
*
* We define this here, rather than in funcattrs.h, because we
* only want it used here, we don't want it to be broadly used.
* (Any printer will get this defined, but this should at least
* make it harder for people to find.)
*/ */
#ifdef LBL_ALIGN #if defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 409)
#define UNALIGNED_OK __attribute__((no_sanitize_undefined))
#elif __has_attribute(no_sanitize)
#define UNALIGNED_OK __attribute__((no_sanitize("undefined")))
#else
#define UNALIGNED_OK
#endif
#if (defined(__i386__) || defined(_M_IX86) || defined(__X86__) || defined(__x86_64__) || defined(_M_X64)) || \
(defined(__m68k__) && (!defined(__mc68000__) && !defined(__mc68010__))) || \
(defined(__ppc__) || defined(__ppc64__) || defined(_M_PPC) || defined(_ARCH_PPC) || defined(_ARCH_PPC64)) || \
(defined(__s390__) || defined(__s390x__) || defined(__zarch__))
/* /*
* The processor doesn't natively handle unaligned loads. * The processor natively handles unaligned loads, so we can just
* cast the pointer and fetch through it.
*
* XXX - are those all the x86 tests we need?
* XXX - are those the only 68k tests we need not to generated
* unaligned accesses if the target is the 68000 or 68010?
* XXX - are there any tests we don't need, because some definitions are for
* compilers that also predefine the GCC symbols?
* XXX - do we need to test for both 32-bit and 64-bit versions of those
* architectures in all cases?
*/ */
#if PCAP_IS_AT_LEAST_GNUC_VERSION(2,0) && \ UNALIGNED_OK static inline uint16_t
EXTRACT_BE_U_2(const void *p)
{
return ((uint16_t)ntohs(*(const uint16_t *)(p)));
}
UNALIGNED_OK static inline int16_t
EXTRACT_BE_S_2(const void *p)
{
return ((int16_t)ntohs(*(const int16_t *)(p)));
}
UNALIGNED_OK static inline uint32_t
EXTRACT_BE_U_4(const void *p)
{
return ((uint32_t)ntohl(*(const uint32_t *)(p)));
}
UNALIGNED_OK static inline int32_t
EXTRACT_BE_S_4(const void *p)
{
return ((int32_t)ntohl(*(const int32_t *)(p)));
}
UNALIGNED_OK static inline uint64_t
EXTRACT_BE_U_8(const void *p)
{
return ((uint64_t)(((uint64_t)ntohl(*((const uint32_t *)(p) + 0))) << 32 |
((uint64_t)ntohl(*((const uint32_t *)(p) + 1))) << 0));
}
UNALIGNED_OK static inline int64_t
EXTRACT_BE_S_8(const void *p)
{
return ((int64_t)(((int64_t)ntohl(*((const uint32_t *)(p) + 0))) << 32 |
((uint64_t)ntohl(*((const uint32_t *)(p) + 1))) << 0));
}
#elif PCAP_IS_AT_LEAST_GNUC_VERSION(2,0) && \
(defined(__alpha) || defined(__alpha__) || \ (defined(__alpha) || defined(__alpha__) || \
defined(__mips) || defined(__mips__)) defined(__mips) || defined(__mips__))
/* /*
@@ -52,7 +131,7 @@
* *
* We do this in case the compiler can generate code using those * We do this in case the compiler can generate code using those
* instructions to do an unaligned load and pass stuff to "ntohs()" or * instructions to do an unaligned load and pass stuff to "ntohs()" or
* "ntohl()", which might be better than than the code to fetch the * "ntohl()", which might be better than the code to fetch the
* bytes one at a time and assemble them. (That might not be 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 * case on a little-endian platform, such as DEC's MIPS machines and
* Alpha machines, where "ntohs()" and "ntohl()" might not be done * Alpha machines, where "ntohs()" and "ntohl()" might not be done
@@ -92,46 +171,91 @@ typedef struct {
uint16_t val; uint16_t val;
} __attribute__((packed)) unaligned_uint16_t; } __attribute__((packed)) unaligned_uint16_t;
typedef struct {
int16_t val;
} __attribute__((packed)) unaligned_int16_t;
typedef struct { typedef struct {
uint32_t val; uint32_t val;
} __attribute__((packed)) unaligned_uint32_t; } __attribute__((packed)) unaligned_uint32_t;
static inline uint16_t typedef struct {
EXTRACT_16BITS(const void *p) int32_t val;
} __attribute__((packed)) unaligned_int32_t;
UNALIGNED_OK static inline uint16_t
EXTRACT_BE_U_2(const void *p)
{ {
return ((uint16_t)ntohs(((const unaligned_uint16_t *)(p))->val)); return ((uint16_t)ntohs(((const unaligned_uint16_t *)(p))->val));
} }
static inline uint32_t UNALIGNED_OK static inline int16_t
EXTRACT_32BITS(const void *p) EXTRACT_BE_S_2(const void *p)
{
return ((int16_t)ntohs(((const unaligned_int16_t *)(p))->val));
}
UNALIGNED_OK static inline uint32_t
EXTRACT_BE_U_4(const void *p)
{ {
return ((uint32_t)ntohl(((const unaligned_uint32_t *)(p))->val)); return ((uint32_t)ntohl(((const unaligned_uint32_t *)(p))->val));
} }
static inline uint64_t UNALIGNED_OK static inline int32_t
EXTRACT_64BITS(const void *p) EXTRACT_BE_S_4(const void *p)
{ {
return ((uint64_t)(((uint64_t)ntohl(((const unaligned_uint32_t *)(p) + 0)->val)) << 32 | \ return ((int32_t)ntohl(((const unaligned_int32_t *)(p))->val));
}
UNALIGNED_OK static inline uint64_t
EXTRACT_BE_U_8(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)); ((uint64_t)ntohl(((const unaligned_uint32_t *)(p) + 1)->val)) << 0));
} }
#else /* have to do it a byte at a time */ UNALIGNED_OK static inline int64_t
EXTRACT_BE_S_8(const void *p)
{
return ((int64_t)(((uint64_t)ntohl(((const unaligned_uint32_t *)(p) + 0)->val)) << 32 |
((uint64_t)ntohl(((const unaligned_uint32_t *)(p) + 1)->val)) << 0));
}
#else
/* /*
* This isn't a GCC-compatible compiler, we don't have __attribute__, * This architecture doesn't natively support unaligned loads, and either
* 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 * 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 * set to do unaligned loads, so do unaligned loads of big-endian
* quantities the hard way - fetch the bytes one at a time and * quantities the hard way - fetch the bytes one at a time and
* assemble them. * assemble them.
*
* XXX - ARM is a special case. ARMv1 through ARMv5 didn't suppory
* unaligned loads; ARMv6 and later support it *but* have a bit in
* the system control register that the OS can set and that causes
* unaligned loads to fault rather than succeeding.
*
* At least some OSes may set that flag, so we do *not* treat ARM
* as supporting unaligned loads. If your OS supports them on ARM,
* and you want to use them, please update the tests in the #if above
* to check for ARM *and* for your OS.
*/ */
#define EXTRACT_16BITS(p) \ #define EXTRACT_BE_U_2(p) \
((uint16_t)(((uint16_t)(*((const uint8_t *)(p) + 0)) << 8) | \ ((uint16_t)(((uint16_t)(*((const uint8_t *)(p) + 0)) << 8) | \
((uint16_t)(*((const uint8_t *)(p) + 1)) << 0))) ((uint16_t)(*((const uint8_t *)(p) + 1)) << 0)))
#define EXTRACT_32BITS(p) \ #define EXTRACT_BE_S_2(p) \
((int16_t)(((uint16_t)(*((const uint8_t *)(p) + 0)) << 8) | \
((uint16_t)(*((const uint8_t *)(p) + 1)) << 0)))
#define EXTRACT_BE_U_4(p) \
((uint32_t)(((uint32_t)(*((const uint8_t *)(p) + 0)) << 24) | \ ((uint32_t)(((uint32_t)(*((const uint8_t *)(p) + 0)) << 24) | \
((uint32_t)(*((const uint8_t *)(p) + 1)) << 16) | \ ((uint32_t)(*((const uint8_t *)(p) + 1)) << 16) | \
((uint32_t)(*((const uint8_t *)(p) + 2)) << 8) | \ ((uint32_t)(*((const uint8_t *)(p) + 2)) << 8) | \
((uint32_t)(*((const uint8_t *)(p) + 3)) << 0))) ((uint32_t)(*((const uint8_t *)(p) + 3)) << 0)))
#define EXTRACT_64BITS(p) \ #define EXTRACT_BE_S_4(p) \
((int32_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_BE_U_8(p) \
((uint64_t)(((uint64_t)(*((const uint8_t *)(p) + 0)) << 56) | \ ((uint64_t)(((uint64_t)(*((const uint8_t *)(p) + 0)) << 56) | \
((uint64_t)(*((const uint8_t *)(p) + 1)) << 48) | \ ((uint64_t)(*((const uint8_t *)(p) + 1)) << 48) | \
((uint64_t)(*((const uint8_t *)(p) + 2)) << 40) | \ ((uint64_t)(*((const uint8_t *)(p) + 2)) << 40) | \
@@ -140,47 +264,67 @@ EXTRACT_64BITS(const void *p)
((uint64_t)(*((const uint8_t *)(p) + 5)) << 16) | \ ((uint64_t)(*((const uint8_t *)(p) + 5)) << 16) | \
((uint64_t)(*((const uint8_t *)(p) + 6)) << 8) | \ ((uint64_t)(*((const uint8_t *)(p) + 6)) << 8) | \
((uint64_t)(*((const uint8_t *)(p) + 7)) << 0))) ((uint64_t)(*((const uint8_t *)(p) + 7)) << 0)))
#endif /* must special-case unaligned accesses */ #define EXTRACT_BE_S_8(p) \
#else /* LBL_ALIGN */ ((int64_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)))
/* /*
* The processor natively handles unaligned loads, so we can just * Extract an IPv4 address, which is in network byte order, and not
* cast the pointer and fetch through it. * necessarily aligned, and provide the result in host byte order.
*/ */
static inline uint16_t #define EXTRACT_IPV4_TO_HOST_ORDER(p) \
EXTRACT_16BITS(const void *p) ((uint32_t)(((uint32_t)(*((const uint8_t *)(p) + 0)) << 24) | \
{ ((uint32_t)(*((const uint8_t *)(p) + 1)) << 16) | \
return ((uint16_t)ntohs(*(const uint16_t *)(p))); ((uint32_t)(*((const uint8_t *)(p) + 2)) << 8) | \
} ((uint32_t)(*((const uint8_t *)(p) + 3)) << 0)))
#endif /* unaligned access checks */
static inline uint32_t /*
EXTRACT_32BITS(const void *p) * Non-power-of-2 sizes.
{ */
return ((uint32_t)ntohl(*(const uint32_t *)(p))); #define EXTRACT_BE_U_3(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)(((uint32_t)(*((const uint8_t *)(p) + 0)) << 16) | \
((uint32_t)(*((const uint8_t *)(p) + 1)) << 8) | \ ((uint32_t)(*((const uint8_t *)(p) + 1)) << 8) | \
((uint32_t)(*((const uint8_t *)(p) + 2)) << 0))) ((uint32_t)(*((const uint8_t *)(p) + 2)) << 0)))
#define EXTRACT_40BITS(p) \ #define EXTRACT_BE_S_3(p) \
(((*((const uint8_t *)(p) + 0)) & 0x80) ? \
((int32_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))) : \
((int32_t)(0xFF000000U | \
((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_BE_U_5(p) \
((uint64_t)(((uint64_t)(*((const uint8_t *)(p) + 0)) << 32) | \ ((uint64_t)(((uint64_t)(*((const uint8_t *)(p) + 0)) << 32) | \
((uint64_t)(*((const uint8_t *)(p) + 1)) << 24) | \ ((uint64_t)(*((const uint8_t *)(p) + 1)) << 24) | \
((uint64_t)(*((const uint8_t *)(p) + 2)) << 16) | \ ((uint64_t)(*((const uint8_t *)(p) + 2)) << 16) | \
((uint64_t)(*((const uint8_t *)(p) + 3)) << 8) | \ ((uint64_t)(*((const uint8_t *)(p) + 3)) << 8) | \
((uint64_t)(*((const uint8_t *)(p) + 4)) << 0))) ((uint64_t)(*((const uint8_t *)(p) + 4)) << 0)))
#define EXTRACT_48BITS(p) \ #define EXTRACT_BE_S_5(p) \
(((*((const uint8_t *)(p) + 0)) & 0x80) ? \
((int64_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))) : \
((int64_t)(INT64_T_CONSTANT(0xFFFFFF0000000000U) | \
((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_BE_U_6(p) \
((uint64_t)(((uint64_t)(*((const uint8_t *)(p) + 0)) << 40) | \ ((uint64_t)(((uint64_t)(*((const uint8_t *)(p) + 0)) << 40) | \
((uint64_t)(*((const uint8_t *)(p) + 1)) << 32) | \ ((uint64_t)(*((const uint8_t *)(p) + 1)) << 32) | \
((uint64_t)(*((const uint8_t *)(p) + 2)) << 24) | \ ((uint64_t)(*((const uint8_t *)(p) + 2)) << 24) | \
@@ -188,7 +332,23 @@ EXTRACT_64BITS(const void *p)
((uint64_t)(*((const uint8_t *)(p) + 4)) << 8) | \ ((uint64_t)(*((const uint8_t *)(p) + 4)) << 8) | \
((uint64_t)(*((const uint8_t *)(p) + 5)) << 0))) ((uint64_t)(*((const uint8_t *)(p) + 5)) << 0)))
#define EXTRACT_56BITS(p) \ #define EXTRACT_BE_S_6(p) \
(((*((const uint8_t *)(p) + 0)) & 0x80) ? \
((int64_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))) : \
((int64_t)(INT64_T_CONSTANT(0xFFFFFFFF00000000U) | \
((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_BE_U_7(p) \
((uint64_t)(((uint64_t)(*((const uint8_t *)(p) + 0)) << 48) | \ ((uint64_t)(((uint64_t)(*((const uint8_t *)(p) + 0)) << 48) | \
((uint64_t)(*((const uint8_t *)(p) + 1)) << 40) | \ ((uint64_t)(*((const uint8_t *)(p) + 1)) << 40) | \
((uint64_t)(*((const uint8_t *)(p) + 2)) << 32) | \ ((uint64_t)(*((const uint8_t *)(p) + 2)) << 32) | \
@@ -197,24 +357,53 @@ EXTRACT_64BITS(const void *p)
((uint64_t)(*((const uint8_t *)(p) + 5)) << 8) | \ ((uint64_t)(*((const uint8_t *)(p) + 5)) << 8) | \
((uint64_t)(*((const uint8_t *)(p) + 6)) << 0))) ((uint64_t)(*((const uint8_t *)(p) + 6)) << 0)))
#define EXTRACT_BE_S_7(p) \
(((*((const uint8_t *)(p) + 0)) & 0x80) ? \
((int64_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))) : \
((int64_t)(INT64_T_CONSTANT(0xFFFFFFFFFF000000U) | \
((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. * Macros to extract possibly-unaligned little-endian integral values.
* XXX - do loads on little-endian machines that support unaligned loads? * XXX - do loads on little-endian machines that support unaligned loads?
*/ */
#define EXTRACT_LE_8BITS(p) (*(p)) #define EXTRACT_LE_U_2(p) \
#define EXTRACT_LE_16BITS(p) \
((uint16_t)(((uint16_t)(*((const uint8_t *)(p) + 1)) << 8) | \ ((uint16_t)(((uint16_t)(*((const uint8_t *)(p) + 1)) << 8) | \
((uint16_t)(*((const uint8_t *)(p) + 0)) << 0))) ((uint16_t)(*((const uint8_t *)(p) + 0)) << 0)))
#define EXTRACT_LE_32BITS(p) \ #define EXTRACT_LE_S_2(p) \
((int16_t)(((uint16_t)(*((const uint8_t *)(p) + 1)) << 8) | \
((uint16_t)(*((const uint8_t *)(p) + 0)) << 0)))
#define EXTRACT_LE_U_4(p) \
((uint32_t)(((uint32_t)(*((const uint8_t *)(p) + 3)) << 24) | \ ((uint32_t)(((uint32_t)(*((const uint8_t *)(p) + 3)) << 24) | \
((uint32_t)(*((const uint8_t *)(p) + 2)) << 16) | \ ((uint32_t)(*((const uint8_t *)(p) + 2)) << 16) | \
((uint32_t)(*((const uint8_t *)(p) + 1)) << 8) | \ ((uint32_t)(*((const uint8_t *)(p) + 1)) << 8) | \
((uint32_t)(*((const uint8_t *)(p) + 0)) << 0))) ((uint32_t)(*((const uint8_t *)(p) + 0)) << 0)))
#define EXTRACT_LE_24BITS(p) \ #define EXTRACT_LE_S_4(p) \
((int32_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_U_3(p) \
((uint32_t)(((uint32_t)(*((const uint8_t *)(p) + 2)) << 16) | \ ((uint32_t)(((uint32_t)(*((const uint8_t *)(p) + 2)) << 16) | \
((uint32_t)(*((const uint8_t *)(p) + 1)) << 8) | \ ((uint32_t)(*((const uint8_t *)(p) + 1)) << 8) | \
((uint32_t)(*((const uint8_t *)(p) + 0)) << 0))) ((uint32_t)(*((const uint8_t *)(p) + 0)) << 0)))
#define EXTRACT_LE_64BITS(p) \ #define EXTRACT_LE_S_3(p) \
((int32_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_U_8(p) \
((uint64_t)(((uint64_t)(*((const uint8_t *)(p) + 7)) << 56) | \ ((uint64_t)(((uint64_t)(*((const uint8_t *)(p) + 7)) << 56) | \
((uint64_t)(*((const uint8_t *)(p) + 6)) << 48) | \ ((uint64_t)(*((const uint8_t *)(p) + 6)) << 48) | \
((uint64_t)(*((const uint8_t *)(p) + 5)) << 40) | \ ((uint64_t)(*((const uint8_t *)(p) + 5)) << 40) | \
@@ -223,3 +412,12 @@ EXTRACT_64BITS(const void *p)
((uint64_t)(*((const uint8_t *)(p) + 2)) << 16) | \ ((uint64_t)(*((const uint8_t *)(p) + 2)) << 16) | \
((uint64_t)(*((const uint8_t *)(p) + 1)) << 8) | \ ((uint64_t)(*((const uint8_t *)(p) + 1)) << 8) | \
((uint64_t)(*((const uint8_t *)(p) + 0)) << 0))) ((uint64_t)(*((const uint8_t *)(p) + 0)) << 0)))
#define EXTRACT_LE_S_8(p) \
((int64_t)(((uint64_t)(*((const uint8_t *)(p) + 7)) << 56) | \
((uint64_t)(*((const uint8_t *)(p) + 6)) << 48) | \
((uint64_t)(*((const uint8_t *)(p) + 5)) << 40) | \
((uint64_t)(*((const uint8_t *)(p) + 4)) << 32) | \
((uint64_t)(*((const uint8_t *)(p) + 3)) << 24) | \
((uint64_t)(*((const uint8_t *)(p) + 2)) << 16) | \
((uint64_t)(*((const uint8_t *)(p) + 1)) << 8) | \
((uint64_t)(*((const uint8_t *)(p) + 0)) << 0)))

View File

@@ -42,7 +42,6 @@
#include <net/if.h> #include <net/if.h>
#include <ctype.h>
#include <errno.h> #include <errno.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@@ -190,7 +189,7 @@ pcap_findalldevs_interfaces(pcap_if_list_t *devlistp, char *errbuf,
* We have a ":"; is it followed by a number? * We have a ":"; is it followed by a number?
*/ */
q = p + 1; q = p + 1;
while (isdigit((unsigned char)*q)) while (PCAP_ISDIGIT(*q))
q++; q++;
if (*q == '\0') { if (*q == '\0') {
/* /*

View File

@@ -49,19 +49,13 @@ struct rtentry; /* declarations in <net/if.h> */
#include <net/if.h> #include <net/if.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <ctype.h>
#include <errno.h> #include <errno.h>
#include <memory.h> #include <memory.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#ifdef HAVE_LIMITS_H
#include <limits.h> #include <limits.h>
#else
#define INT_MAX 2147483647
#endif
#include "pcap-int.h" #include "pcap-int.h"
@@ -178,7 +172,7 @@ pcap_findalldevs_interfaces(pcap_if_list_t *devlistp, char *errbuf,
* Don't let the buffer size get bigger than INT_MAX. * Don't let the buffer size get bigger than INT_MAX.
*/ */
if (buf_size > INT_MAX) { if (buf_size > INT_MAX) {
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"interface information requires more than %u bytes", "interface information requires more than %u bytes",
INT_MAX); INT_MAX);
(void)close(fd); (void)close(fd);
@@ -399,7 +393,7 @@ pcap_findalldevs_interfaces(pcap_if_list_t *devlistp, char *errbuf,
* We have a ":"; is it followed by a number? * We have a ":"; is it followed by a number?
*/ */
q = p + 1; q = p + 1;
while (isdigit((unsigned char)*q)) while (PCAP_ISDIGIT(*q))
q++; q++;
if (*q == '\0') { if (*q == '\0') {
/* /*

View File

@@ -50,7 +50,6 @@ struct rtentry; /* declarations in <net/if.h> */
#include <net/if.h> #include <net/if.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <ctype.h>
#include <errno.h> #include <errno.h>
#include <memory.h> #include <memory.h>
#include <stdio.h> #include <stdio.h>
@@ -311,7 +310,7 @@ pcap_findalldevs_interfaces(pcap_if_list_t *devlistp, char *errbuf,
* We have a ":"; is it followed by a number? * We have a ":"; is it followed by a number?
*/ */
q = p + 1; q = p + 1;
while (isdigit((unsigned char)*q)) while (PCAP_ISDIGIT(*q))
q++; q++;
if (*q == '\0') { if (*q == '\0') {
/* /*

View File

@@ -47,12 +47,220 @@
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <pcap/pcap.h> #include "pcap-int.h"
#include "portability.h" #include "portability.h"
#include "fmtutils.h" #include "fmtutils.h"
#ifdef _WIN32
#include "charconv.h"
#endif
/*
* Set the encoding.
*/
#ifdef _WIN32
/*
* True if we shouold use UTF-8.
*/
static int use_utf_8;
void
pcap_fmt_set_encoding(unsigned int opts)
{
if (opts == PCAP_CHAR_ENC_UTF_8)
use_utf_8 = 1;
}
#else
void
pcap_fmt_set_encoding(unsigned int opts _U_)
{
/*
* Nothing to do here.
*/
}
#endif
#ifdef _WIN32
/*
* Convert a null-terminated UTF-16LE string to UTF-8, putting it into
* a buffer starting at the specified location and stopping if we go
* past the specified size. This will only put out complete UTF-8
* sequences.
*
* We do this ourselves because Microsoft doesn't offer a "convert and
* stop at a UTF-8 character boundary if we run out of space" routine.
*/
#define IS_LEADING_SURROGATE(c) \
((c) >= 0xd800 && (c) < 0xdc00)
#define IS_TRAILING_SURROGATE(c) \
((c) >= 0xdc00 && (c) < 0xe000)
#define SURROGATE_VALUE(leading, trailing) \
(((((leading) - 0xd800) << 10) | ((trailing) - 0xdc00)) + 0x10000)
#define REPLACEMENT_CHARACTER 0x0FFFD
static char *
utf_16le_to_utf_8_truncated(const wchar_t *utf_16, char *utf_8,
size_t utf_8_len)
{
wchar_t c, c2;
uint32_t uc;
if (utf_8_len == 0) {
/*
* Not even enough room for a trailing '\0'.
* Don't put anything into the buffer.
*/
return (utf_8);
}
while ((c = *utf_16++) != '\0') {
if (IS_LEADING_SURROGATE(c)) {
/*
* Leading surrogate. Must be followed by
* a trailing surrogate.
*/
c2 = *utf_16;
if (c2 == '\0') {
/*
* Oops, string ends with a lead
* surrogate. Try to drop in
* a REPLACEMENT CHARACTER, and
* don't move the string pointer,
* so on the next trip through
* the loop we grab the terminating
* '\0' and quit.
*/
uc = REPLACEMENT_CHARACTER;
} else {
/*
* OK, we can consume this 2-octet
* value.
*/
utf_16++;
if (IS_TRAILING_SURROGATE(c2)) {
/*
* Trailing surrogate.
* This calculation will,
* for c being a leading
* surrogate and c2 being
* a trailing surrogate,
* produce a value between
* 0x100000 and 0x10ffff,
* so it's always going to be
* a valid Unicode code point.
*/
uc = SURROGATE_VALUE(c, c2);
} else {
/*
* Not a trailing surroage;
* try to drop in a
* REPLACEMENT CHARACTER.
*/
uc = REPLACEMENT_CHARACTER;
}
}
} else {
/*
* Not a leading surrogate.
*/
if (IS_TRAILING_SURROGATE(c)) {
/*
* Trailing surrogate without
* a preceding leading surrogate.
* Try to drop in a REPLACEMENT
* CHARACTER.
*/
uc = REPLACEMENT_CHARACTER;
} else {
/*
* This is a valid BMP character;
* drop it in.
*/
uc = c;
}
}
/*
* OK, uc is a valid Unicode character; how
* many bytes worth of UTF-8 does it require?
*/
if (uc < 0x0080) {
/* 1 byte. */
if (utf_8_len < 2) {
/*
* Not enough room for that byte
* plus a trailing '\0'.
*/
break;
}
*utf_8++ = (char)uc;
utf_8_len--;
} else if (uc < 0x0800) {
/* 2 bytes. */
if (utf_8_len < 3) {
/*
* Not enough room for those bytes
* plus a trailing '\0'.
*/
break;
}
*utf_8++ = ((uc >> 6) & 0x3F) | 0xC0;
*utf_8++ = ((uc >> 0) & 0x3F) | 0x80;
utf_8_len -= 2;
} else if (uc < 0x010000) {
/* 3 bytes. */
if (utf_8_len < 4) {
/*
* Not enough room for those bytes
* plus a trailing '\0'.
*/
break;
}
*utf_8++ = ((uc >> 12) & 0x0F) | 0xE0;
*utf_8++ = ((uc >> 6) & 0x3F) | 0x80;
*utf_8++ = ((uc >> 0) & 0x3F) | 0x80;
utf_8_len -= 3;
} else {
/* 4 bytes. */
if (utf_8_len < 5) {
/*
* Not enough room for those bytes
* plus a trailing '\0'.
*/
break;
}
*utf_8++ = ((uc >> 18) & 0x03) | 0xF0;
*utf_8++ = ((uc >> 12) & 0x3F) | 0x80;
*utf_8++ = ((uc >> 6) & 0x3F) | 0x80;
*utf_8++ = ((uc >> 0) & 0x3F) | 0x80;
utf_8_len -= 3;
}
}
/*
* OK, we have enough room for (at least) a trailing '\0'.
* (We started out with enough room, thanks to the test
* for a zero-length buffer at the beginning, and if
* there wasn't enough room for any character we wanted
* to put into the buffer *plus* a trailing '\0',
* we'd have quit before putting it into the buffer,
* and thus would have left enough room for the trailing
* '\0'.)
*
* Drop it in.
*/
*utf_8 = '\0';
/*
* Return a pointer to the terminating '\0', in case we
* want to drop something in after that.
*/
return (utf_8);
}
#endif /* _WIN32 */
/* /*
* Generate an error message based on a format, arguments, and an * Generate an error message based on a format, arguments, and an
* errno, with a message for the errno after the formatted output. * errno, with a message for the errno after the formatted output.
@@ -67,7 +275,7 @@ pcap_fmt_errmsg_for_errno(char *errbuf, size_t errbuflen, int errnum,
size_t errbuflen_remaining; size_t errbuflen_remaining;
va_start(ap, fmt); va_start(ap, fmt);
pcap_vsnprintf(errbuf, errbuflen, fmt, ap); vsnprintf(errbuf, errbuflen, fmt, ap);
va_end(ap); va_end(ap);
msglen = strlen(errbuf); msglen = strlen(errbuf);
@@ -84,24 +292,40 @@ pcap_fmt_errmsg_for_errno(char *errbuf, size_t errbuflen, int errnum,
*p++ = ':'; *p++ = ':';
*p++ = ' '; *p++ = ' ';
*p = '\0'; *p = '\0';
msglen += 2;
errbuflen_remaining -= 2; errbuflen_remaining -= 2;
/* /*
* Now append the string for the error code. * Now append the string for the error code.
*/ */
#if defined(HAVE_STRERROR_S) #if defined(HAVE__WCSERROR_S)
/* /*
* We have a Windows-style strerror_s(). * We have a Windows-style _wcserror_s().
* Generate a UTF-16LE error message.
*/ */
errno_t err = strerror_s(p, errbuflen_remaining, errnum); wchar_t utf_16_errbuf[PCAP_ERRBUF_SIZE];
errno_t err = _wcserror_s(utf_16_errbuf, PCAP_ERRBUF_SIZE, errnum);
if (err != 0) { if (err != 0) {
/* /*
* It doesn't appear to be documented anywhere obvious * It doesn't appear to be documented anywhere obvious
* what the error returns from strerror_s(). * what the error returns from _wcserror_s().
*/ */
pcap_snprintf(p, errbuflen_remaining, "Error %d", errnum); snprintf(p, errbuflen_remaining, "Error %d", errnum);
return;
} }
/*
* Now convert it from UTF-16LE to UTF-8, dropping it in the
* remaining space in the buffer, and truncating it - cleanly,
* on a UTF-8 character boundary - if it doesn't fit.
*/
utf_16le_to_utf_8_truncated(utf_16_errbuf, p, errbuflen_remaining);
/*
* Now, if we're not in UTF-8 mode, convert errbuf to the
* local code page.
*/
if (!use_utf_8)
utf_8_to_acp_truncated(errbuf);
#elif defined(HAVE_GNU_STRERROR_R) #elif defined(HAVE_GNU_STRERROR_R)
/* /*
* We have a GNU-style strerror_r(), which is *not* guaranteed to * We have a GNU-style strerror_r(), which is *not* guaranteed to
@@ -113,7 +337,7 @@ pcap_fmt_errmsg_for_errno(char *errbuf, size_t errbuflen, int errnum,
*/ */
char strerror_buf[PCAP_ERRBUF_SIZE]; char strerror_buf[PCAP_ERRBUF_SIZE];
char *errstring = strerror_r(errnum, strerror_buf, PCAP_ERRBUF_SIZE); char *errstring = strerror_r(errnum, strerror_buf, PCAP_ERRBUF_SIZE);
pcap_snprintf(p, errbuflen_remaining, "%s", errstring); snprintf(p, errbuflen_remaining, "%s", errstring);
#elif defined(HAVE_POSIX_STRERROR_R) #elif defined(HAVE_POSIX_STRERROR_R)
/* /*
* We have a POSIX-style strerror_r(), which is guaranteed to fill * We have a POSIX-style strerror_r(), which is guaranteed to fill
@@ -125,22 +349,22 @@ pcap_fmt_errmsg_for_errno(char *errbuf, size_t errbuflen, int errnum,
* UNIX 03 says this isn't guaranteed to produce a * UNIX 03 says this isn't guaranteed to produce a
* fallback error message. * fallback error message.
*/ */
pcap_snprintf(p, errbuflen_remaining, "Unknown error: %d", snprintf(p, errbuflen_remaining, "Unknown error: %d",
errnum); errnum);
} else if (err == ERANGE) { } else if (err == ERANGE) {
/* /*
* UNIX 03 says this isn't guaranteed to produce a * UNIX 03 says this isn't guaranteed to produce a
* fallback error message. * fallback error message.
*/ */
pcap_snprintf(p, errbuflen_remaining, snprintf(p, errbuflen_remaining,
"Message for error %d is too long", errnum); "Message for error %d is too long", errnum);
} }
#else #else
/* /*
* We have neither strerror_s() nor strerror_r(), so we're * We have neither _wcserror_s() nor strerror_r(), so we're
* stuck with using pcap_strerror(). * stuck with using pcap_strerror().
*/ */
pcap_snprintf(p, errbuflen_remaining, "%s", pcap_strerror(errnum)); snprintf(p, errbuflen_remaining, "%s", pcap_strerror(errnum));
#endif #endif
} }
@@ -158,10 +382,11 @@ pcap_fmt_errmsg_for_win32_err(char *errbuf, size_t errbuflen, DWORD errnum,
char *p; char *p;
size_t errbuflen_remaining; size_t errbuflen_remaining;
DWORD retval; DWORD retval;
char win32_errbuf[PCAP_ERRBUF_SIZE+1]; wchar_t utf_16_errbuf[PCAP_ERRBUF_SIZE];
size_t utf_8_len;
va_start(ap, fmt); va_start(ap, fmt);
pcap_vsnprintf(errbuf, errbuflen, fmt, ap); vsnprintf(errbuf, errbuflen, fmt, ap);
va_end(ap); va_end(ap);
msglen = strlen(errbuf); msglen = strlen(errbuf);
@@ -197,18 +422,39 @@ pcap_fmt_errmsg_for_win32_err(char *errbuf, size_t errbuflen, DWORD errnum,
* get the message translated if it's in a language they don't * get the message translated if it's in a language they don't
* happen to understand. * happen to understand.
*/ */
retval = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|FORMAT_MESSAGE_MAX_WIDTH_MASK, retval = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|FORMAT_MESSAGE_MAX_WIDTH_MASK,
NULL, errnum, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), NULL, errnum, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
win32_errbuf, PCAP_ERRBUF_SIZE, NULL); utf_16_errbuf, PCAP_ERRBUF_SIZE, NULL);
if (retval == 0) { if (retval == 0) {
/* /*
* Failed. * Failed.
*/ */
pcap_snprintf(p, errbuflen_remaining, snprintf(p, errbuflen_remaining,
"Couldn't get error message for error (%lu)", errnum); "Couldn't get error message for error (%lu)", errnum);
return; return;
} }
pcap_snprintf(p, errbuflen_remaining, "%s (%lu)", win32_errbuf, errnum); /*
* Now convert it from UTF-16LE to UTF-8.
*/
p = utf_16le_to_utf_8_truncated(utf_16_errbuf, p, errbuflen_remaining);
/*
* Now append the error number, if it fits.
*/
utf_8_len = p - errbuf;
errbuflen_remaining -= utf_8_len;
if (utf_8_len == 0) {
/* The message was empty. */
snprintf(p, errbuflen_remaining, "(%lu)", errnum);
} else
snprintf(p, errbuflen_remaining, " (%lu)", errnum);
/*
* Now, if we're not in UTF-8 mode, convert errbuf to the
* local code page.
*/
if (!use_utf_8)
utf_8_to_acp_truncated(errbuf);
} }
#endif #endif

View File

@@ -40,6 +40,8 @@
extern "C" { extern "C" {
#endif #endif
void pcap_fmt_set_encoding(unsigned int);
void pcap_fmt_errmsg_for_errno(char *, size_t, int, void pcap_fmt_errmsg_for_errno(char *, size_t, int,
PCAP_FORMAT_STRING(const char *), ...) PCAP_PRINTFLIKE(4, 5); PCAP_FORMAT_STRING(const char *), ...) PCAP_PRINTFLIKE(4, 5);

View File

@@ -83,14 +83,18 @@
* least with HP's C compiler; hopefully doing so won't make it * least with HP's C compiler; hopefully doing so won't make it
* *not* work with *un*-threaded code. * *not* work with *un*-threaded code.
*/ */
#elif defined(__linux__) || defined(linux) || defined(__linux) #else
/* /*
* Turn on _GNU_SOURCE to get everything GNU libc has to offer, * Turn on _GNU_SOURCE to get everything GNU libc has to offer,
* including asprintf(). * including asprintf(), if we're using GNU libc.
* *
* Unfortunately, one thing it has to offer is a strerror_r() * Unfortunately, one thing it has to offer is a strerror_r()
* that's not POSIX-compliant, but we deal with that in * that's not POSIX-compliant, but we deal with that in
* pcap_fmt_errmsg_for_errno(). * pcap_fmt_errmsg_for_errno().
*
* We don't limit this to, for example, Linux and Cygwin, because
* this might, for example, be GNU/HURD or one of Debian's kFreeBSD
* OSes ("GNU/FreeBSD").
*/ */
#define _GNU_SOURCE #define _GNU_SOURCE
@@ -101,9 +105,18 @@
* don't whine about _BSD_SOURCE being deprecated; we still have * don't whine about _BSD_SOURCE being deprecated; we still have
* to define _BSD_SOURCE to handle older versions of GNU libc that * to define _BSD_SOURCE to handle older versions of GNU libc that
* don't support _DEFAULT_SOURCE. * don't support _DEFAULT_SOURCE.
*
* But, if it's already defined, don't define it, so that we don't
* get a warning of it being redefined if it's defined as, for
* example, 1.
*/ */
#define _DEFAULT_SOURCE #ifndef _DEFAULT_SOURCE
#define _BSD_SOURCE #define _DEFAULT_SOURCE
#endif
/* Avoid redefining _BSD_SOURCE if it's already defined as for ex. 1 */
#ifndef _BSD_SOURCE
#define _BSD_SOURCE
#endif
#endif #endif
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@@ -200,11 +200,14 @@
struct slist; struct slist;
/*
* A single statement, corresponding to an instruction in a block.
*/
struct stmt { struct stmt {
int code; int code; /* opcode */
struct slist *jt; /*only for relative jump in block*/ struct slist *jt; /* only for relative jump in block */
struct slist *jf; /*only for relative jump in block*/ struct slist *jf; /* only for relative jump in block */
bpf_int32 k; bpf_u_int32 k; /* k field */
}; };
struct slist { struct slist {
@@ -231,17 +234,27 @@ typedef bpf_u_int32 *uset;
*/ */
#define N_ATOMS (BPF_MEMWORDS+2) #define N_ATOMS (BPF_MEMWORDS+2)
/*
* Control flow graph of a program.
* This corresponds to an edge in the CFG.
* It's a directed graph, so an edge has a predecessor and a successor.
*/
struct edge { struct edge {
int id; u_int id;
int code; int code; /* opcode for branch corresponding to this edge */
uset edom; uset edom;
struct block *succ; struct block *succ; /* successor vertex */
struct block *pred; struct block *pred; /* predecessor vertex */
struct edge *next; /* link list of incoming edges for a node */ struct edge *next; /* link list of incoming edges for a node */
}; };
/*
* A block is a vertex in the CFG.
* It has a list of statements, with the final statement being a
* branch to successor blocks.
*/
struct block { struct block {
int id; u_int id;
struct slist *stmts; /* side effect stmts */ struct slist *stmts; /* side effect stmts */
struct stmt s; /* branch stmt */ struct stmt s; /* branch stmt */
int mark; int mark;
@@ -250,18 +263,18 @@ struct block {
int level; int level;
int offset; int offset;
int sense; int sense;
struct edge et; struct edge et; /* edge corresponding to the jt branch */
struct edge ef; struct edge ef; /* edge corresponding to the jf branch */
struct block *head; struct block *head;
struct block *link; /* link field used by optimizer */ struct block *link; /* link field used by optimizer */
uset dom; uset dom;
uset closure; uset closure;
struct edge *in_edges; struct edge *in_edges; /* first edge in the set (linked list) of edges with this as a successor */
atomset def, kill; atomset def, kill;
atomset in_use; atomset in_use;
atomset out_use; atomset out_use;
int oval; int oval; /* value ID for value tested in branch stmt */
int val[N_ATOMS]; bpf_u_int32 val[N_ATOMS];
}; };
/* /*
@@ -286,8 +299,8 @@ struct _compiler_state;
typedef struct _compiler_state compiler_state_t; typedef struct _compiler_state compiler_state_t;
struct arth *gen_loadi(compiler_state_t *, int); struct arth *gen_loadi(compiler_state_t *, bpf_u_int32);
struct arth *gen_load(compiler_state_t *, int, struct arth *, int); struct arth *gen_load(compiler_state_t *, int, struct arth *, bpf_u_int32);
struct arth *gen_loadlen(compiler_state_t *); struct arth *gen_loadlen(compiler_state_t *);
struct arth *gen_neg(compiler_state_t *, struct arth *); struct arth *gen_neg(compiler_state_t *, struct arth *);
struct arth *gen_arth(compiler_state_t *, int, struct arth *, struct arth *); struct arth *gen_arth(compiler_state_t *, int, struct arth *, struct arth *);
@@ -300,10 +313,10 @@ struct block *gen_scode(compiler_state_t *, const char *, struct qual);
struct block *gen_ecode(compiler_state_t *, const char *, struct qual); struct block *gen_ecode(compiler_state_t *, const char *, struct qual);
struct block *gen_acode(compiler_state_t *, const char *, struct qual); struct block *gen_acode(compiler_state_t *, const char *, struct qual);
struct block *gen_mcode(compiler_state_t *, const char *, const char *, struct block *gen_mcode(compiler_state_t *, const char *, const char *,
unsigned int, struct qual); bpf_u_int32, struct qual);
#ifdef INET6 #ifdef INET6
struct block *gen_mcode6(compiler_state_t *, const char *, const char *, struct block *gen_mcode6(compiler_state_t *, const char *, const char *,
unsigned int, struct qual); bpf_u_int32, struct qual);
#endif #endif
struct block *gen_ncode(compiler_state_t *, const char *, bpf_u_int32, struct block *gen_ncode(compiler_state_t *, const char *, bpf_u_int32,
struct qual); struct qual);
@@ -312,9 +325,10 @@ struct block *gen_relation(compiler_state_t *, int, struct arth *,
struct arth *, int); struct arth *, int);
struct block *gen_less(compiler_state_t *, int); struct block *gen_less(compiler_state_t *, int);
struct block *gen_greater(compiler_state_t *, int); struct block *gen_greater(compiler_state_t *, int);
struct block *gen_byteop(compiler_state_t *, int, int, int); struct block *gen_byteop(compiler_state_t *, int, int, bpf_u_int32);
struct block *gen_broadcast(compiler_state_t *, int); struct block *gen_broadcast(compiler_state_t *, int);
struct block *gen_multicast(compiler_state_t *, int); struct block *gen_multicast(compiler_state_t *, int);
struct block *gen_ifindex(compiler_state_t *, int);
struct block *gen_inbound(compiler_state_t *, int); struct block *gen_inbound(compiler_state_t *, int);
struct block *gen_llc(compiler_state_t *); struct block *gen_llc(compiler_state_t *);
@@ -332,14 +346,14 @@ struct block *gen_pppoes(compiler_state_t *, bpf_u_int32, int);
struct block *gen_geneve(compiler_state_t *, bpf_u_int32, int); struct block *gen_geneve(compiler_state_t *, bpf_u_int32, int);
struct block *gen_atmfield_code(compiler_state_t *, int, bpf_int32, struct block *gen_atmfield_code(compiler_state_t *, int, bpf_u_int32,
bpf_u_int32, int); int, int);
struct block *gen_atmtype_abbrev(compiler_state_t *, int type); struct block *gen_atmtype_abbrev(compiler_state_t *, int);
struct block *gen_atmmulti_abbrev(compiler_state_t *, int type); struct block *gen_atmmulti_abbrev(compiler_state_t *, int);
struct block *gen_mtp2type_abbrev(compiler_state_t *, int type); struct block *gen_mtp2type_abbrev(compiler_state_t *, int);
struct block *gen_mtp3field_code(compiler_state_t *, int, bpf_u_int32, struct block *gen_mtp3field_code(compiler_state_t *, int, bpf_u_int32,
bpf_u_int32, int); int, int);
struct block *gen_pf_ifname(compiler_state_t *, const char *); struct block *gen_pf_ifname(compiler_state_t *, const char *);
struct block *gen_pf_rnr(compiler_state_t *, int); struct block *gen_pf_rnr(compiler_state_t *, int);
@@ -348,8 +362,8 @@ struct block *gen_pf_ruleset(compiler_state_t *, char *);
struct block *gen_pf_reason(compiler_state_t *, int); struct block *gen_pf_reason(compiler_state_t *, int);
struct block *gen_pf_action(compiler_state_t *, int); struct block *gen_pf_action(compiler_state_t *, int);
struct block *gen_p80211_type(compiler_state_t *, int, int); struct block *gen_p80211_type(compiler_state_t *, bpf_u_int32, bpf_u_int32);
struct block *gen_p80211_fcdir(compiler_state_t *, int); struct block *gen_p80211_fcdir(compiler_state_t *, bpf_u_int32);
/* /*
* Representation of a program as a tree of blocks, plus current mark. * Representation of a program as a tree of blocks, plus current mark.

File diff suppressed because it is too large Load Diff

View File

@@ -82,219 +82,99 @@ extern int pcap_debug;
NUM = 292, NUM = 292,
INBOUND = 293, INBOUND = 293,
OUTBOUND = 294, OUTBOUND = 294,
PF_IFNAME = 295, IFINDEX = 295,
PF_RSET = 296, PF_IFNAME = 296,
PF_RNR = 297, PF_RSET = 297,
PF_SRNR = 298, PF_RNR = 298,
PF_REASON = 299, PF_SRNR = 299,
PF_ACTION = 300, PF_REASON = 300,
TYPE = 301, PF_ACTION = 301,
SUBTYPE = 302, TYPE = 302,
DIR = 303, SUBTYPE = 303,
ADDR1 = 304, DIR = 304,
ADDR2 = 305, ADDR1 = 305,
ADDR3 = 306, ADDR2 = 306,
ADDR4 = 307, ADDR3 = 307,
RA = 308, ADDR4 = 308,
TA = 309, RA = 309,
LINK = 310, TA = 310,
GEQ = 311, LINK = 311,
LEQ = 312, GEQ = 312,
NEQ = 313, LEQ = 313,
ID = 314, NEQ = 314,
EID = 315, ID = 315,
HID = 316, EID = 316,
HID6 = 317, HID = 317,
AID = 318, HID6 = 318,
LSH = 319, AID = 319,
RSH = 320, LSH = 320,
LEN = 321, RSH = 321,
IPV6 = 322, LEN = 322,
ICMPV6 = 323, IPV6 = 323,
AH = 324, ICMPV6 = 324,
ESP = 325, AH = 325,
VLAN = 326, ESP = 326,
MPLS = 327, VLAN = 327,
PPPOED = 328, MPLS = 328,
PPPOES = 329, PPPOED = 329,
GENEVE = 330, PPPOES = 330,
ISO = 331, GENEVE = 331,
ESIS = 332, ISO = 332,
CLNP = 333, ESIS = 333,
ISIS = 334, CLNP = 334,
L1 = 335, ISIS = 335,
L2 = 336, L1 = 336,
IIH = 337, L2 = 337,
LSP = 338, IIH = 338,
SNP = 339, LSP = 339,
CSNP = 340, SNP = 340,
PSNP = 341, CSNP = 341,
STP = 342, PSNP = 342,
IPX = 343, STP = 343,
NETBEUI = 344, IPX = 344,
LANE = 345, NETBEUI = 345,
LLC = 346, LANE = 346,
METAC = 347, LLC = 347,
BCC = 348, METAC = 348,
SC = 349, BCC = 349,
ILMIC = 350, SC = 350,
OAMF4EC = 351, ILMIC = 351,
OAMF4SC = 352, OAMF4EC = 352,
OAM = 353, OAMF4SC = 353,
OAMF4 = 354, OAM = 354,
CONNECTMSG = 355, OAMF4 = 355,
METACONNECT = 356, CONNECTMSG = 356,
VPI = 357, METACONNECT = 357,
VCI = 358, VPI = 358,
RADIO = 359, VCI = 359,
FISU = 360, RADIO = 360,
LSSU = 361, FISU = 361,
MSU = 362, LSSU = 362,
HFISU = 363, MSU = 363,
HLSSU = 364, HFISU = 364,
HMSU = 365, HLSSU = 365,
SIO = 366, HMSU = 366,
OPC = 367, SIO = 367,
DPC = 368, OPC = 368,
SLS = 369, DPC = 369,
HSIO = 370, SLS = 370,
HOPC = 371, HSIO = 371,
HDPC = 372, HOPC = 372,
HSLS = 373, HDPC = 373,
LEX_ERROR = 374, HSLS = 374,
OR = 375, LEX_ERROR = 375,
AND = 376, OR = 376,
UMINUS = 377 AND = 377,
UMINUS = 378
}; };
#endif #endif
/* Tokens. */
#define DST 258
#define SRC 259
#define HOST 260
#define GATEWAY 261
#define NET 262
#define NETMASK 263
#define PORT 264
#define PORTRANGE 265
#define LESS 266
#define GREATER 267
#define PROTO 268
#define PROTOCHAIN 269
#define CBYTE 270
#define ARP 271
#define RARP 272
#define IP 273
#define SCTP 274
#define TCP 275
#define UDP 276
#define ICMP 277
#define IGMP 278
#define IGRP 279
#define PIM 280
#define VRRP 281
#define CARP 282
#define ATALK 283
#define AARP 284
#define DECNET 285
#define LAT 286
#define SCA 287
#define MOPRC 288
#define MOPDL 289
#define TK_BROADCAST 290
#define TK_MULTICAST 291
#define NUM 292
#define INBOUND 293
#define OUTBOUND 294
#define PF_IFNAME 295
#define PF_RSET 296
#define PF_RNR 297
#define PF_SRNR 298
#define PF_REASON 299
#define PF_ACTION 300
#define TYPE 301
#define SUBTYPE 302
#define DIR 303
#define ADDR1 304
#define ADDR2 305
#define ADDR3 306
#define ADDR4 307
#define RA 308
#define TA 309
#define LINK 310
#define GEQ 311
#define LEQ 312
#define NEQ 313
#define ID 314
#define EID 315
#define HID 316
#define HID6 317
#define AID 318
#define LSH 319
#define RSH 320
#define LEN 321
#define IPV6 322
#define ICMPV6 323
#define AH 324
#define ESP 325
#define VLAN 326
#define MPLS 327
#define PPPOED 328
#define PPPOES 329
#define GENEVE 330
#define ISO 331
#define ESIS 332
#define CLNP 333
#define ISIS 334
#define L1 335
#define L2 336
#define IIH 337
#define LSP 338
#define SNP 339
#define CSNP 340
#define PSNP 341
#define STP 342
#define IPX 343
#define NETBEUI 344
#define LANE 345
#define LLC 346
#define METAC 347
#define BCC 348
#define SC 349
#define ILMIC 350
#define OAMF4EC 351
#define OAMF4SC 352
#define OAM 353
#define OAMF4 354
#define CONNECTMSG 355
#define METACONNECT 356
#define VPI 357
#define VCI 358
#define RADIO 359
#define FISU 360
#define LSSU 361
#define MSU 362
#define HFISU 363
#define HLSSU 364
#define HMSU 365
#define SIO 366
#define OPC 367
#define DPC 368
#define SLS 369
#define HSIO 370
#define HOPC 371
#define HDPC 372
#define HSLS 373
#define LEX_ERROR 374
#define OR 375
#define AND 376
#define UMINUS 377
/* Value type. */ /* Value type. */
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
union YYSTYPE union YYSTYPE
{ {
#line 291 "grammar.y" /* yacc.c:1909 */ #line 321 "grammar.y" /* yacc.c:1909 */
int i; int i;
bpf_u_int32 h; bpf_u_int32 h;
@@ -309,7 +189,7 @@ union YYSTYPE
} blk; } blk;
struct block *rblk; struct block *rblk;
#line 313 "grammar.h" /* yacc.c:1909 */ #line 193 "grammar.h" /* yacc.c:1909 */
}; };
typedef union YYSTYPE YYSTYPE; typedef union YYSTYPE YYSTYPE;

View File

@@ -1,7 +1,7 @@
/* /*
* We want a reentrant parser. * We want a reentrant parser.
*/ */
%pure-parser @REENTRANT_PARSER@
/* /*
* We also want a reentrant scanner, so we have to pass the * We also want a reentrant scanner, so we have to pass the
@@ -18,6 +18,27 @@
%parse-param {void *yyscanner} %parse-param {void *yyscanner}
%lex-param {void *yyscanner} %lex-param {void *yyscanner}
/*
* According to bison documentation, shift/reduce conflicts are not an issue
* in most parsers as long as the number does not evolve over time:
* https://www.gnu.org/software/bison/manual/html_node/Expect-Decl.html
* So, following the advice use %expect to check the amount of shift/reduce
* warnings.
*
* This doesn't appear to work in Berkeley YACC - 1.9 20170709; it still
* warns of 38 shift/reduce conflicts.
*
* The Berkeley YACC documentation:
*
* https://invisible-island.net/byacc/manpage/yacc.html
*
* claims that "Bison's support for "%expect" is broken in more than one
* release.", but doesn't give details. Hopefully, that only means that
* you get warnings even if you have the expected number of shift/reduce
* conflicts, not that anything else fails.
*/
%expect 38
/* /*
* And we need to pass the compiler state to the scanner. * And we need to pass the compiler state to the scanner.
*/ */
@@ -210,8 +231,17 @@ str2tok(const char *str, const struct tok *toks)
int i; int i;
for (i = 0; toks[i].s != NULL; i++) { for (i = 0; toks[i].s != NULL; i++) {
if (pcap_strcasecmp(toks[i].s, str) == 0) if (pcap_strcasecmp(toks[i].s, str) == 0) {
/*
* Just in case somebody is using this to
* generate values of -1/0xFFFFFFFF.
* That won't work, as it's indistinguishable
* from an error.
*/
if (toks[i].v == -1)
abort();
return (toks[i].v); return (toks[i].v);
}
} }
return (-1); return (-1);
} }
@@ -235,7 +265,7 @@ pfreason_to_num(compiler_state_t *cstate, const char *reason)
if (pcap_strcasecmp(reason, reasons[i]) == 0) if (pcap_strcasecmp(reason, reasons[i]) == 0)
return (i); return (i);
} }
bpf_set_error(cstate, "unknown PF reason"); bpf_set_error(cstate, "unknown PF reason \"%s\"", reason);
return (-1); return (-1);
} }
@@ -259,7 +289,7 @@ pfaction_to_num(compiler_state_t *cstate, const char *action)
return (PF_NORDR); return (PF_NORDR);
#endif #endif
else { else {
bpf_set_error(cstate, "unknown PF action"); bpf_set_error(cstate, "unknown PF action \"%s\"", action);
return (-1); return (-1);
} }
} }
@@ -307,7 +337,8 @@ DIAG_OFF_BISON_BYACC
%type <blk> head %type <blk> head
%type <i> pqual dqual aqual ndaqual %type <i> pqual dqual aqual ndaqual
%type <a> arth narth %type <a> arth narth
%type <i> byteop pname pnum relop irelop %type <i> byteop pname relop irelop
%type <h> pnum
%type <blk> and or paren not null prog %type <blk> and or paren not null prog
%type <rblk> other pfvar p80211 pllc %type <rblk> other pfvar p80211 pllc
%type <i> atmtype atmmultitype %type <i> atmtype atmmultitype
@@ -324,6 +355,7 @@ DIAG_OFF_BISON_BYACC
%token ATALK AARP DECNET LAT SCA MOPRC MOPDL %token ATALK AARP DECNET LAT SCA MOPRC MOPDL
%token TK_BROADCAST TK_MULTICAST %token TK_BROADCAST TK_MULTICAST
%token NUM INBOUND OUTBOUND %token NUM INBOUND OUTBOUND
%token IFINDEX
%token PF_IFNAME PF_RSET PF_RNR PF_SRNR PF_REASON PF_ACTION %token PF_IFNAME PF_RSET PF_RNR PF_SRNR PF_REASON PF_ACTION
%token TYPE SUBTYPE DIR ADDR1 ADDR2 ADDR3 ADDR4 RA TA %token TYPE SUBTYPE DIR ADDR1 ADDR2 ADDR3 ADDR4 RA TA
%token LINK %token LINK
@@ -348,7 +380,8 @@ DIAG_OFF_BISON_BYACC
%type <s> ID EID AID %type <s> ID EID AID
%type <s> HID HID6 %type <s> HID HID6
%type <i> NUM action reason type subtype type_subtype dir %type <h> NUM
%type <i> action reason type subtype type_subtype dir
%left OR AND %left OR AND
%nonassoc '!' %nonassoc '!'
@@ -378,7 +411,7 @@ and: AND { $$ = $<blk>0; }
or: OR { $$ = $<blk>0; } or: OR { $$ = $<blk>0; }
; ;
id: nid id: nid
| pnum { CHECK_PTR_VAL(($$.b = gen_ncode(cstate, NULL, (bpf_u_int32)$1, | pnum { CHECK_PTR_VAL(($$.b = gen_ncode(cstate, NULL, $1,
$$.q = $<blk>0.q))); } $$.q = $<blk>0.q))); }
| paren pid ')' { $$ = $2; } | paren pid ')' { $$ = $2; }
; ;
@@ -392,17 +425,17 @@ nid: ID { CHECK_PTR_VAL($1); CHECK_PTR_VAL(($$.b = gen_scode(cstate, $1, $$.
/* 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_set_error(cstate, "'port' modifier applied to ip host"); bpf_set_error(cstate, "'port' modifier applied to ip host");
YYABORT; YYABORT;
} else if ($$.q.addr == Q_PORTRANGE) { } else if ($$.q.addr == Q_PORTRANGE) {
bpf_set_error(cstate, "'portrange' modifier applied to ip host"); bpf_set_error(cstate, "'portrange' modifier applied to ip host");
YYABORT; YYABORT;
} else if ($$.q.addr == Q_PROTO) { } else if ($$.q.addr == Q_PROTO) {
bpf_set_error(cstate, "'proto' modifier applied to ip host"); bpf_set_error(cstate, "'proto' modifier applied to ip host");
YYABORT; YYABORT;
} else if ($$.q.addr == Q_PROTOCHAIN) { } else if ($$.q.addr == Q_PROTOCHAIN) {
bpf_set_error(cstate, "'protochain' modifier applied to ip host"); bpf_set_error(cstate, "'protochain' modifier applied to ip host");
YYABORT; YYABORT;
} }
CHECK_PTR_VAL(($$.b = gen_ncode(cstate, $1, 0, $$.q))); CHECK_PTR_VAL(($$.b = gen_ncode(cstate, $1, 0, $$.q)));
} }
@@ -440,7 +473,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 { CHECK_PTR_VAL(($$.b = gen_ncode(cstate, NULL, (bpf_u_int32)$1, qid: pnum { CHECK_PTR_VAL(($$.b = gen_ncode(cstate, NULL, $1,
$$.q = $<blk>0.q))); } $$.q = $<blk>0.q))); }
| pid | pid
; ;
@@ -514,7 +547,7 @@ pname: LINK { $$ = Q_LINK; }
| IGRP { $$ = Q_IGRP; } | IGRP { $$ = Q_IGRP; }
| PIM { $$ = Q_PIM; } | PIM { $$ = Q_PIM; }
| VRRP { $$ = Q_VRRP; } | VRRP { $$ = Q_VRRP; }
| CARP { $$ = Q_CARP; } | CARP { $$ = Q_CARP; }
| ATALK { $$ = Q_ATALK; } | ATALK { $$ = Q_ATALK; }
| AARP { $$ = Q_AARP; } | AARP { $$ = Q_AARP; }
| DECNET { $$ = Q_DECNET; } | DECNET { $$ = Q_DECNET; }
@@ -549,14 +582,15 @@ other: pqual TK_BROADCAST { CHECK_PTR_VAL(($$ = gen_broadcast(cstate, $1))); }
| CBYTE NUM byteop NUM { CHECK_PTR_VAL(($$ = gen_byteop(cstate, $3, $2, $4))); } | CBYTE NUM byteop NUM { CHECK_PTR_VAL(($$ = gen_byteop(cstate, $3, $2, $4))); }
| INBOUND { CHECK_PTR_VAL(($$ = gen_inbound(cstate, 0))); } | INBOUND { CHECK_PTR_VAL(($$ = gen_inbound(cstate, 0))); }
| OUTBOUND { CHECK_PTR_VAL(($$ = gen_inbound(cstate, 1))); } | OUTBOUND { CHECK_PTR_VAL(($$ = gen_inbound(cstate, 1))); }
| VLAN pnum { CHECK_PTR_VAL(($$ = gen_vlan(cstate, (bpf_u_int32)$2, 1))); } | IFINDEX NUM { CHECK_PTR_VAL(($$ = gen_ifindex(cstate, $2))); }
| VLAN pnum { CHECK_PTR_VAL(($$ = gen_vlan(cstate, $2, 1))); }
| VLAN { CHECK_PTR_VAL(($$ = gen_vlan(cstate, 0, 0))); } | VLAN { CHECK_PTR_VAL(($$ = gen_vlan(cstate, 0, 0))); }
| MPLS pnum { CHECK_PTR_VAL(($$ = gen_mpls(cstate, (bpf_u_int32)$2, 1))); } | MPLS pnum { CHECK_PTR_VAL(($$ = gen_mpls(cstate, $2, 1))); }
| MPLS { CHECK_PTR_VAL(($$ = gen_mpls(cstate, 0, 0))); } | MPLS { CHECK_PTR_VAL(($$ = gen_mpls(cstate, 0, 0))); }
| PPPOED { CHECK_PTR_VAL(($$ = gen_pppoed(cstate))); } | PPPOED { CHECK_PTR_VAL(($$ = gen_pppoed(cstate))); }
| PPPOES pnum { CHECK_PTR_VAL(($$ = gen_pppoes(cstate, (bpf_u_int32)$2, 1))); } | PPPOES pnum { CHECK_PTR_VAL(($$ = gen_pppoes(cstate, $2, 1))); }
| PPPOES { CHECK_PTR_VAL(($$ = gen_pppoes(cstate, 0, 0))); } | PPPOES { CHECK_PTR_VAL(($$ = gen_pppoes(cstate, 0, 0))); }
| GENEVE pnum { CHECK_PTR_VAL(($$ = gen_geneve(cstate, (bpf_u_int32)$2, 1))); } | GENEVE pnum { CHECK_PTR_VAL(($$ = gen_geneve(cstate, $2, 1))); }
| GENEVE { CHECK_PTR_VAL(($$ = gen_geneve(cstate, 0, 0))); } | GENEVE { CHECK_PTR_VAL(($$ = gen_geneve(cstate, 0, 0))); }
| pfvar { $$ = $1; } | pfvar { $$ = $1; }
| pqual p80211 { $$ = $2; } | pqual p80211 { $$ = $2; }
@@ -586,23 +620,33 @@ p80211: TYPE type SUBTYPE subtype
| DIR dir { CHECK_PTR_VAL(($$ = gen_p80211_fcdir(cstate, $2))); } | DIR dir { CHECK_PTR_VAL(($$ = gen_p80211_fcdir(cstate, $2))); }
; ;
type: NUM type: NUM { if (($1 & (~IEEE80211_FC0_TYPE_MASK)) != 0) {
bpf_set_error(cstate, "invalid 802.11 type value 0x%02x", $1);
YYABORT;
}
$$ = (int)$1;
}
| ID { CHECK_PTR_VAL($1); | ID { CHECK_PTR_VAL($1);
$$ = str2tok($1, ieee80211_types); $$ = str2tok($1, ieee80211_types);
if ($$ == -1) { if ($$ == -1) {
bpf_set_error(cstate, "unknown 802.11 type name"); bpf_set_error(cstate, "unknown 802.11 type name \"%s\"", $1);
YYABORT; YYABORT;
} }
} }
; ;
subtype: NUM subtype: NUM { if (($1 & (~IEEE80211_FC0_SUBTYPE_MASK)) != 0) {
bpf_set_error(cstate, "invalid 802.11 subtype value 0x%02x", $1);
YYABORT;
}
$$ = (int)$1;
}
| ID { const struct tok *types = NULL; | ID { const struct tok *types = NULL;
int i; int i;
CHECK_PTR_VAL($1); CHECK_PTR_VAL($1);
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_set_error(cstate, "unknown 802.11 type"); bpf_set_error(cstate, "unknown 802.11 type");
YYABORT; YYABORT;
} }
@@ -614,7 +658,7 @@ subtype: NUM
$$ = str2tok($1, types); $$ = str2tok($1, types);
if ($$ == -1) { if ($$ == -1) {
bpf_set_error(cstate, "unknown 802.11 subtype name"); bpf_set_error(cstate, "unknown 802.11 subtype name \"%s\"", $1);
YYABORT; YYABORT;
} }
} }
@@ -623,8 +667,8 @@ subtype: NUM
type_subtype: ID { int i; type_subtype: ID { int i;
CHECK_PTR_VAL($1); CHECK_PTR_VAL($1);
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_set_error(cstate, "unknown 802.11 type name"); bpf_set_error(cstate, "unknown 802.11 type name");
YYABORT; YYABORT;
} }
@@ -654,9 +698,9 @@ pllc: LLC { CHECK_PTR_VAL(($$ = gen_llc(cstate))); }
} else { } else {
subtype = str2tok($2, llc_u_subtypes); subtype = str2tok($2, llc_u_subtypes);
if (subtype == -1) { if (subtype == -1) {
bpf_set_error(cstate, "unknown LLC type name \"%s\"", $2); bpf_set_error(cstate, "unknown LLC type name \"%s\"", $2);
YYABORT; YYABORT;
} }
CHECK_PTR_VAL(($$ = gen_llc_u_subtype(cstate, subtype))); CHECK_PTR_VAL(($$ = gen_llc_u_subtype(cstate, subtype)));
} }
} }
@@ -665,7 +709,7 @@ pllc: LLC { CHECK_PTR_VAL(($$ = gen_llc(cstate))); }
| LLC PF_RNR { CHECK_PTR_VAL(($$ = gen_llc_s_subtype(cstate, LLC_RNR))); } | LLC PF_RNR { CHECK_PTR_VAL(($$ = gen_llc_s_subtype(cstate, LLC_RNR))); }
; ;
dir: NUM dir: NUM { $$ = (int)$1; }
| ID { CHECK_PTR_VAL($1); | ID { CHECK_PTR_VAL($1);
if (pcap_strcasecmp($1, "nods") == 0) if (pcap_strcasecmp($1, "nods") == 0)
$$ = IEEE80211_FC1_DIR_NODS; $$ = IEEE80211_FC1_DIR_NODS;
@@ -743,15 +787,15 @@ atmfield: VPI { $$.atmfieldtype = A_VPI; }
| VCI { $$.atmfieldtype = A_VCI; } | VCI { $$.atmfieldtype = A_VCI; }
; ;
atmvalue: atmfieldvalue atmvalue: atmfieldvalue
| relop NUM { CHECK_PTR_VAL(($$.b = gen_atmfield_code(cstate, $<blk>0.atmfieldtype, (bpf_int32)$2, (bpf_u_int32)$1, 0))); } | relop NUM { CHECK_PTR_VAL(($$.b = gen_atmfield_code(cstate, $<blk>0.atmfieldtype, $2, $1, 0))); }
| irelop NUM { CHECK_PTR_VAL(($$.b = gen_atmfield_code(cstate, $<blk>0.atmfieldtype, (bpf_int32)$2, (bpf_u_int32)$1, 1))); } | irelop NUM { CHECK_PTR_VAL(($$.b = gen_atmfield_code(cstate, $<blk>0.atmfieldtype, $2, $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)
CHECK_PTR_VAL(($$.b = gen_atmfield_code(cstate, $$.atmfieldtype, (bpf_int32) $1, BPF_JEQ, 0))); CHECK_PTR_VAL(($$.b = gen_atmfield_code(cstate, $$.atmfieldtype, $1, BPF_JEQ, 0)));
} }
; ;
atmlistvalue: atmfieldvalue atmlistvalue: atmfieldvalue
@@ -776,8 +820,8 @@ mtp3field: SIO { $$.mtp3fieldtype = M_SIO; }
| HSLS { $$.mtp3fieldtype = MH_SLS; } | HSLS { $$.mtp3fieldtype = MH_SLS; }
; ;
mtp3value: mtp3fieldvalue mtp3value: mtp3fieldvalue
| relop NUM { CHECK_PTR_VAL(($$.b = gen_mtp3field_code(cstate, $<blk>0.mtp3fieldtype, (u_int)$2, (u_int)$1, 0))); } | relop NUM { CHECK_PTR_VAL(($$.b = gen_mtp3field_code(cstate, $<blk>0.mtp3fieldtype, $2, $1, 0))); }
| irelop NUM { CHECK_PTR_VAL(($$.b = gen_mtp3field_code(cstate, $<blk>0.mtp3fieldtype, (u_int)$2, (u_int)$1, 1))); } | irelop NUM { CHECK_PTR_VAL(($$.b = gen_mtp3field_code(cstate, $<blk>0.mtp3fieldtype, $2, $1, 1))); }
| paren mtp3listvalue ')' { $$.b = $2.b; $$.q = qerr; } | paren mtp3listvalue ')' { $$.b = $2.b; $$.q = qerr; }
; ;
mtp3fieldvalue: NUM { mtp3fieldvalue: NUM {
@@ -790,7 +834,7 @@ mtp3fieldvalue: NUM {
$$.mtp3fieldtype == MH_OPC || $$.mtp3fieldtype == MH_OPC ||
$$.mtp3fieldtype == MH_DPC || $$.mtp3fieldtype == MH_DPC ||
$$.mtp3fieldtype == MH_SLS) $$.mtp3fieldtype == MH_SLS)
CHECK_PTR_VAL(($$.b = gen_mtp3field_code(cstate, $$.mtp3fieldtype, (u_int) $1, BPF_JEQ, 0))); CHECK_PTR_VAL(($$.b = gen_mtp3field_code(cstate, $$.mtp3fieldtype, $1, BPF_JEQ, 0)));
} }
; ;
mtp3listvalue: mtp3fieldvalue mtp3listvalue: mtp3fieldvalue

View File

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

View File

@@ -21,10 +21,10 @@
/* /*
* Prototypes missing in Tru64 UNIX 5.x * Prototypes missing in Tru64 UNIX 5.x
* XXX - "pcap_snprintf()" and "pcap_vsnprintf()" aren't missing, but you have to * XXX - "snprintf()" and "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 pcap_snprintf(char *, size_t, const char *, ...); int snprintf(char *, size_t, const char *, ...);
int pcap_vsnprintf(char *, size_t, const char *, va_list); int vsnprintf(char *, size_t, const char *, va_list);
int pfopen(char *, int); int pfopen(char *, int);

View File

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

View File

@@ -155,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 pcap_snprintf(char *, size_t, const char *, ...); int 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 *);

View File

@@ -80,9 +80,18 @@ getopt(int nargc, char * const *nargv, const char *ostr)
place = EMSG; place = EMSG;
return (-1); return (-1);
} }
} /* option letter okay? */ }
if ((optopt = (int)*place++) == (int)':' || optopt = (int)*place++;
!(oli = strchr(ostr, optopt))) { if (optopt == (int)':') { /* option letter okay? */
if (!*place)
++optind;
if (opterr && *ostr != ':')
(void)fprintf(stderr,
"%s: illegal option -- %c\n", __progname, optopt);
return (BADCH);
}
oli = strchr(ostr, optopt);
if (!oli) {
/* /*
* if the user didn't specify '-' as an option, * if the user didn't specify '-' as an option,
* assume it means -1. * assume it means -1.
@@ -114,7 +123,7 @@ getopt(int nargc, char * const *nargv, const char *ostr)
__progname, optopt); __progname, optopt);
return (BADCH); return (BADCH);
} }
else /* white space */ else /* white space */
optarg = nargv[optind]; optarg = nargv[optind];
place = EMSG; place = EMSG;
++optind; ++optind;

View File

@@ -1,631 +0,0 @@
/*
* Copyright (c) 1995-1999 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* 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 Institute 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 INSTITUTE 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 INSTITUTE 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.
*/
/*
* We use this for platforms that don't have snprintf() at all.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <sys/types.h>
#include "portability.h"
enum format_flags {
minus_flag = 1,
plus_flag = 2,
space_flag = 4,
alternate_flag = 8,
zero_flag = 16
};
/*
* Common state
*/
struct state {
unsigned char *str;
unsigned char *s;
unsigned char *theend;
size_t sz;
size_t max_sz;
int (*append_char)(struct state *, unsigned char);
int (*reserve)(struct state *, size_t);
/* XXX - methods */
};
#ifndef HAVE_VSNPRINTF
static int
sn_reserve (struct state *state, size_t n)
{
return state->s + n > state->theend;
}
static int
sn_append_char (struct state *state, unsigned char c)
{
if (sn_reserve (state, 1)) {
return 1;
} else {
*state->s++ = c;
return 0;
}
}
#endif
#if 0
static int
as_reserve (struct state *state, size_t n)
{
if (state->s + n > state->theend) {
int off = state->s - state->str;
unsigned char *tmp;
if (state->max_sz && state->sz >= state->max_sz)
return 1;
state->sz = max(state->sz * 2, state->sz + n);
if (state->max_sz)
state->sz = min(state->sz, state->max_sz);
tmp = realloc (state->str, state->sz);
if (tmp == NULL)
return 1;
state->str = tmp;
state->s = state->str + off;
state->theend = state->str + state->sz - 1;
}
return 0;
}
static int
as_append_char (struct state *state, unsigned char c)
{
if(as_reserve (state, 1))
return 1;
else {
*state->s++ = c;
return 0;
}
}
#endif
static int
append_number(struct state *state,
unsigned long num, unsigned base, char *rep,
int width, int prec, int flags, int minusp)
{
int len = 0;
int i;
/* given precision, ignore zero flag */
if(prec != -1)
flags &= ~zero_flag;
else
prec = 1;
/* zero value with zero precision -> "" */
if(prec == 0 && num == 0)
return 0;
do{
if((*state->append_char)(state, rep[num % base]))
return 1;
len++;
num /= base;
}while(num);
prec -= len;
/* pad with prec zeros */
while(prec-- > 0){
if((*state->append_char)(state, '0'))
return 1;
len++;
}
/* add length of alternate prefix (added later) to len */
if(flags & alternate_flag && (base == 16 || base == 8))
len += base / 8;
/* pad with zeros */
if(flags & zero_flag){
width -= len;
if(minusp || (flags & space_flag) || (flags & plus_flag))
width--;
while(width-- > 0){
if((*state->append_char)(state, '0'))
return 1;
len++;
}
}
/* add alternate prefix */
if(flags & alternate_flag && (base == 16 || base == 8)){
if(base == 16)
if((*state->append_char)(state, rep[10] + 23)) /* XXX */
return 1;
if((*state->append_char)(state, '0'))
return 1;
}
/* add sign */
if(minusp){
if((*state->append_char)(state, '-'))
return 1;
len++;
} else if(flags & plus_flag) {
if((*state->append_char)(state, '+'))
return 1;
len++;
} else if(flags & space_flag) {
if((*state->append_char)(state, ' '))
return 1;
len++;
}
if(flags & minus_flag)
/* swap before padding with spaces */
for(i = 0; i < len / 2; i++){
char c = state->s[-i-1];
state->s[-i-1] = state->s[-len+i];
state->s[-len+i] = c;
}
width -= len;
while(width-- > 0){
if((*state->append_char)(state, ' '))
return 1;
len++;
}
if(!(flags & minus_flag))
/* swap after padding with spaces */
for(i = 0; i < len / 2; i++){
char c = state->s[-i-1];
state->s[-i-1] = state->s[-len+i];
state->s[-len+i] = c;
}
return 0;
}
static int
append_string (struct state *state,
unsigned char *arg,
int width,
int prec,
int flags)
{
if(prec != -1)
width -= prec;
else
width -= strlen((char *)arg);
if(!(flags & minus_flag))
while(width-- > 0)
if((*state->append_char) (state, ' '))
return 1;
if (prec != -1) {
while (*arg && prec--)
if ((*state->append_char) (state, *arg++))
return 1;
} else {
while (*arg)
if ((*state->append_char) (state, *arg++))
return 1;
}
if(flags & minus_flag)
while(width-- > 0)
if((*state->append_char) (state, ' '))
return 1;
return 0;
}
static int
append_char(struct state *state,
unsigned char arg,
int width,
int flags)
{
while(!(flags & minus_flag) && --width > 0)
if((*state->append_char) (state, ' '))
return 1;
if((*state->append_char) (state, arg))
return 1;
while((flags & minus_flag) && --width > 0)
if((*state->append_char) (state, ' '))
return 1;
return 0;
}
/*
* This can't be made into a function...
*/
#define PARSE_INT_FORMAT(res, arg, unsig) \
if (long_flag) \
res = (unsig long)va_arg(arg, unsig long); \
else if (short_flag) \
res = (unsig short)va_arg(arg, unsig int); \
else \
res = (unsig int)va_arg(arg, unsig int)
/*
* zyxprintf - return 0 or -1
*/
static int
xyzprintf (struct state *state, const char *char_format, va_list ap)
{
const unsigned char *format = (const unsigned char *)char_format;
unsigned char c;
while((c = *format++)) {
if (c == '%') {
int flags = 0;
int width = 0;
int prec = -1;
int long_flag = 0;
int short_flag = 0;
/* flags */
while((c = *format++)){
if(c == '-')
flags |= minus_flag;
else if(c == '+')
flags |= plus_flag;
else if(c == ' ')
flags |= space_flag;
else if(c == '#')
flags |= alternate_flag;
else if(c == '0')
flags |= zero_flag;
else
break;
}
if((flags & space_flag) && (flags & plus_flag))
flags ^= space_flag;
if((flags & minus_flag) && (flags & zero_flag))
flags ^= zero_flag;
/* width */
if (isdigit(c))
do {
width = width * 10 + c - '0';
c = *format++;
} while(isdigit(c));
else if(c == '*') {
width = va_arg(ap, int);
c = *format++;
}
/* precision */
if (c == '.') {
prec = 0;
c = *format++;
if (isdigit(c))
do {
prec = prec * 10 + c - '0';
c = *format++;
} while(isdigit(c));
else if (c == '*') {
prec = va_arg(ap, int);
c = *format++;
}
}
/* size */
if (c == 'h') {
short_flag = 1;
c = *format++;
} else if (c == 'l') {
long_flag = 1;
c = *format++;
}
switch (c) {
case 'c' :
if(append_char(state, va_arg(ap, int), width, flags))
return -1;
break;
case 's' :
if (append_string(state,
va_arg(ap, unsigned char*),
width,
prec,
flags))
return -1;
break;
case 'd' :
case 'i' : {
long arg;
unsigned long num;
int minusp = 0;
PARSE_INT_FORMAT(arg, ap, signed);
if (arg < 0) {
minusp = 1;
num = -arg;
} else
num = arg;
if (append_number (state, num, 10, "0123456789",
width, prec, flags, minusp))
return -1;
break;
}
case 'u' : {
unsigned long arg;
PARSE_INT_FORMAT(arg, ap, unsigned);
if (append_number (state, arg, 10, "0123456789",
width, prec, flags, 0))
return -1;
break;
}
case 'o' : {
unsigned long arg;
PARSE_INT_FORMAT(arg, ap, unsigned);
if (append_number (state, arg, 010, "01234567",
width, prec, flags, 0))
return -1;
break;
}
case 'x' : {
unsigned long arg;
PARSE_INT_FORMAT(arg, ap, unsigned);
if (append_number (state, arg, 0x10, "0123456789abcdef",
width, prec, flags, 0))
return -1;
break;
}
case 'X' :{
unsigned long arg;
PARSE_INT_FORMAT(arg, ap, unsigned);
if (append_number (state, arg, 0x10, "0123456789ABCDEF",
width, prec, flags, 0))
return -1;
break;
}
case 'p' : {
unsigned long arg = (unsigned long)va_arg(ap, void*);
if (append_number (state, arg, 0x10, "0123456789ABCDEF",
width, prec, flags, 0))
return -1;
break;
}
case 'n' : {
int *arg = va_arg(ap, int*);
*arg = state->s - state->str;
break;
}
case '\0' :
--format;
/* FALLTHROUGH */
case '%' :
if ((*state->append_char)(state, c))
return -1;
break;
default :
if ( (*state->append_char)(state, '%')
|| (*state->append_char)(state, c))
return -1;
break;
}
} else
if ((*state->append_char) (state, c))
return -1;
}
return 0;
}
#ifndef HAVE_SNPRINTF
int
pcap_snprintf (char *str, size_t sz, const char *format, ...)
{
va_list args;
int ret;
va_start(args, format);
ret = pcap_vsnprintf (str, sz, format, args);
#ifdef PARANOIA
{
int ret2;
char *tmp;
tmp = malloc (sz);
if (tmp == NULL)
abort ();
ret2 = pcap_vsprintf (tmp, format, args);
if (ret != ret2 || strcmp(str, tmp))
abort ();
free (tmp);
}
#endif
va_end(args);
return ret;
}
#endif
#if 0
#ifndef HAVE_ASPRINTF
int
asprintf (char **ret, const char *format, ...)
{
va_list args;
int val;
va_start(args, format);
val = vasprintf (ret, format, args);
#ifdef PARANOIA
{
int ret2;
char *tmp;
tmp = malloc (val + 1);
if (tmp == NULL)
abort ();
ret2 = vsprintf (tmp, format, args);
if (val != ret2 || strcmp(*ret, tmp))
abort ();
free (tmp);
}
#endif
va_end(args);
return val;
}
#endif
#ifndef HAVE_ASNPRINTF
int
pcap_asnprintf (char **ret, size_t max_sz, const char *format, ...)
{
va_list args;
int val;
va_start(args, format);
val = pcap_vasnprintf (ret, max_sz, format, args);
va_end(args);
#ifdef PARANOIA
{
int ret2;
char *tmp;
tmp = malloc (val + 1);
if (tmp == NULL)
abort ();
va_start(args, format);
ret2 = pcap_vsprintf (tmp, format, args);
va_end(args);
if (val != ret2 || strcmp(*ret, tmp))
abort ();
free (tmp);
}
#endif
return val;
}
#endif
#ifndef HAVE_VASPRINTF
int
pcap_vasprintf (char **ret, const char *format, va_list args)
{
return pcap_vasnprintf (ret, 0, format, args);
}
#endif
#ifndef HAVE_VASNPRINTF
int
pcap_vasnprintf (char **ret, size_t max_sz, const char *format, va_list args)
{
int st;
size_t len;
struct state state;
state.max_sz = max_sz;
state.sz = 1;
state.str = malloc(state.sz);
if (state.str == NULL) {
*ret = NULL;
return -1;
}
state.s = state.str;
state.theend = state.s + state.sz - 1;
state.append_char = as_append_char;
state.reserve = as_reserve;
st = xyzprintf (&state, format, args);
if (st) {
free (state.str);
*ret = NULL;
return -1;
} else {
char *tmp;
*state.s = '\0';
len = state.s - state.str;
tmp = realloc (state.str, len+1);
if (tmp == NULL) {
free (state.str);
*ret = NULL;
return -1;
}
*ret = tmp;
return len;
}
}
#endif
#endif
#ifndef HAVE_VSNPRINTF
int
pcap_vsnprintf (char *str, size_t sz, const char *format, va_list args)
{
struct state state;
int ret;
unsigned char *ustr = (unsigned char *)str;
state.max_sz = 0;
state.sz = sz;
state.str = ustr;
state.s = ustr;
state.theend = ustr + sz - 1;
state.append_char = sn_append_char;
state.reserve = sn_reserve;
ret = xyzprintf (&state, format, args);
*state.s = '\0';
if (ret)
return sz;
else
return state.s - state.str;
}
#endif

View File

@@ -23,7 +23,7 @@ pcap_vasprintf(char **strp, const char *format, va_list args)
*strp = NULL; *strp = NULL;
return (-1); return (-1);
} }
ret = pcap_vsnprintf(str, str_size, format, args); ret = vsnprintf(str, str_size, format, args);
if (ret == -1) { if (ret == -1) {
free(str); free(str);
*strp = NULL; *strp = NULL;
@@ -31,7 +31,7 @@ pcap_vasprintf(char **strp, const char *format, va_list args)
} }
*strp = str; *strp = str;
/* /*
* pcap_vsnprintf() shouldn't truncate the string, as we have * vsnprintf() shouldn't truncate the string, as we have
* allocated a buffer large enough to hold the string, so its * allocated a buffer large enough to hold the string, so its
* return value should be the number of characters printed. * return value should be the number of characters printed.
*/ */

View File

@@ -1,43 +0,0 @@
#include <stdio.h>
#include <stdarg.h>
#include "portability.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.
*
* We don't, however, offer C99 behavior for the return
* value; _vsnprintf_s() returns -1, not the number of
* characters that would have been put into the buffer
* had it been large enough, if the string is truncated.
* The only way to get that value is to use _vscprintf();
* getting that count isn't worth the re-formatting.
*
* XXX - does _vsnprintf_s() return -1 on a formatting
* error?
*/
str[str_size - 1] = '\0';
return (ret);
}
int
pcap_snprintf(char *str, size_t str_size, const char *format, ...)
{
va_list args;
int ret;
va_start(args, format);
ret = pcap_vsnprintf(str, str_size, format, args);
va_end(args);
return (ret);
}

View File

@@ -16,7 +16,10 @@
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
SOURCE_DIRECTORY=. # default source directory is the current directory
# No command-line flags seen yet.
flags=""
while : while :
do case "$1" in do case "$1" in
# -c allows you to specify the C compiler # -c allows you to specify the C compiler
@@ -39,13 +42,29 @@ while :
-p) -p)
SED='s;\.o;;' SED='s;\.o;;'
shift ;; shift ;;
# -s allows you to specify the source directory
-s)
SOURCE_DIRECTORY=$2
shift; shift ;;
# -include takes an argument
-include)
flags="$flags $1 $2"
shift; shift ;;
# other command-line flag
-*)
flags="$flags $1"
shift ;;
*) *)
break ;; break ;;
esac esac
done done
if [ $# = 0 ] ; then if [ $# = 0 ] ; then
echo 'usage: mkdep [-p] [-c cc] [-f makefile] [-m dependency-cflag] [flags] file ...' echo 'usage: mkdep [-p] [-c cc] [-f makefile] [-m dependency-cflag] [-s source-directory] [flags] file ...'
exit 1 exit 1
fi fi
@@ -76,8 +95,17 @@ _EOF_
# egrep '^#include[ ]*".*"' /dev/null $* | # egrep '^#include[ ]*".*"' /dev/null $* |
# sed -e 's/:[^"]*"\([^"]*\)".*/: \1/' -e 's/\.c/.o/' | # sed -e 's/:[^"]*"\([^"]*\)".*/: \1/' -e 's/\.c/.o/' |
#
# Construct a list of source files with paths relative to the source directory.
#
sources=""
for srcfile in $*
do
sources="$sources $SOURCE_DIRECTORY/$srcfile"
done
# XXX this doesn't work with things like "-DDECLWAITSTATUS=union\ wait" # XXX this doesn't work with things like "-DDECLWAITSTATUS=union\ wait"
$CC $DEPENDENCY_CFLAG $* | $CC $DEPENDENCY_CFLAG $flags $sources |
sed " sed "
s; \./; ;g s; \./; ;g
$SED" | $SED" |

View File

@@ -24,7 +24,7 @@ Note for djgpp users:
If you got the libpcap from the official site www.tcpdump, then that If you got the libpcap from the official site www.tcpdump, then that
distribution does NOT contain any sources for building 32-bit drivers. distribution does NOT contain any sources for building 32-bit drivers.
Instead get the full version at Instead get the full version at
http://www.watt-32.net/pcap/libpcap.zip https://www.watt-32.net/pcap/libpcap.zip
and set "USE_32BIT_DRIVERS = 1" in msdos\common.dj. and set "USE_32BIT_DRIVERS = 1" in msdos\common.dj.
@@ -51,12 +51,12 @@ The following packages and tools must be present for all targets.
receive network data. It's mostly used to access the 'hosts' receive network data. It's mostly used to access the 'hosts'
file and other <netdb.h> features. Get 'watt32s*.zip' at: file and other <netdb.h> features. Get 'watt32s*.zip' at:
http://www.watt-32.net https://www.watt-32.net
2. Exception handler and disassember library (libexc.a) is needed if 2. Exception handler and disassember library (libexc.a) is needed if
"USE_EXCEPT = 1" in common.dj. Available at: "USE_EXCEPT = 1" in common.dj. Available at:
http://www.watt-32.net/misc/exc_dx07.zip https://www.watt-32.net/misc/exc_dx07.zip
3. Flex & Bison is used to generate parser for the filter handler 3. Flex & Bison is used to generate parser for the filter handler
pcap_compile: pcap_compile:
@@ -65,7 +65,7 @@ The following packages and tools must be present for all targets.
4. NASM assembler v 0.98 or later is required when building djgpp and 4. NASM assembler v 0.98 or later is required when building djgpp and
Watcom targets: Watcom targets:
http://www.nasm.us/ https://www.nasm.us/
5. sed (Stream Editor) is required for doing `make depend'. 5. sed (Stream Editor) is required for doing `make depend'.
It's available at: It's available at:

View File

@@ -127,7 +127,6 @@
#include <netdb.h> #include <netdb.h>
#endif /* _WIN32 */ #endif /* _WIN32 */
#include <ctype.h>
#include <errno.h> #include <errno.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@@ -135,6 +134,8 @@
#include "pcap-int.h" #include "pcap-int.h"
#include "diag-control.h"
#include "gencode.h" #include "gencode.h"
#include <pcap/namedb.h> #include <pcap/namedb.h>
#include "nametoaddr.h" #include "nametoaddr.h"
@@ -162,7 +163,23 @@ pcap_nametoaddr(const char *name)
bpf_u_int32 **p; bpf_u_int32 **p;
struct hostent *hp; struct hostent *hp;
/*
* gethostbyname() is deprecated on Windows, perhaps because
* it's not thread-safe, or because it doesn't support IPv6,
* or both.
*
* We deprecate pcap_nametoaddr() on all platforms because
* it's not thread-safe; we supply it for backwards compatibility,
* so suppress the deprecation warning. We could, I guess,
* use getaddrinfo() and construct the array ourselves, but
* that's probably not worth the effort, as that wouldn't make
* this thread-safe - we can't change the API to require that
* our caller free the address array, so we still have to reuse
* a local array.
*/
DIAG_OFF_DEPRECATION
if ((hp = gethostbyname(name)) != NULL) { if ((hp = gethostbyname(name)) != NULL) {
DIAG_ON_DEPRECATION
#ifndef h_addr #ifndef h_addr
hlist[0] = (bpf_u_int32 *)hp->h_addr; hlist[0] = (bpf_u_int32 *)hp->h_addr;
NTOHL(hp->h_addr); NTOHL(hp->h_addr);
@@ -200,10 +217,10 @@ pcap_nametoaddrinfo(const char *name)
* XXX - not guaranteed to be thread-safe! See below for platforms * XXX - not guaranteed to be thread-safe! See below for platforms
* on which it is thread-safe and on which it isn't. * on which it is thread-safe and on which it isn't.
*/ */
#if defined(_WIN32) || defined(__CYGWIN__)
bpf_u_int32 bpf_u_int32
pcap_nametonetaddr(const char *name) pcap_nametonetaddr(const char *name _U_)
{ {
#ifdef _WIN32
/* /*
* There's no "getnetbyname()" on Windows. * There's no "getnetbyname()" on Windows.
* *
@@ -217,7 +234,11 @@ pcap_nametonetaddr(const char *name)
* of *UN*X* machines.) * of *UN*X* machines.)
*/ */
return 0; return 0;
#else }
#else /* _WIN32 */
bpf_u_int32
pcap_nametonetaddr(const char *name)
{
/* /*
* UN*X. * UN*X.
*/ */
@@ -291,8 +312,8 @@ pcap_nametonetaddr(const char *name)
return np->n_net; return np->n_net;
else else
return 0; return 0;
#endif /* _WIN32 */
} }
#endif /* _WIN32 */
/* /*
* Convert a port name to its port and protocol numbers. * Convert a port name to its port and protocol numbers.
@@ -569,28 +590,20 @@ struct eproto {
*/ */
PCAP_API struct eproto eproto_db[]; PCAP_API struct eproto eproto_db[];
PCAP_API_DEF struct eproto eproto_db[] = { PCAP_API_DEF struct eproto eproto_db[] = {
{ "pup", ETHERTYPE_PUP }, { "aarp", ETHERTYPE_AARP },
{ "xns", ETHERTYPE_NS }, { "arp", ETHERTYPE_ARP },
{ "atalk", ETHERTYPE_ATALK },
{ "decnet", ETHERTYPE_DN },
{ "ip", ETHERTYPE_IP }, { "ip", ETHERTYPE_IP },
#ifdef INET6 #ifdef INET6
{ "ip6", ETHERTYPE_IPV6 }, { "ip6", ETHERTYPE_IPV6 },
#endif #endif
{ "arp", ETHERTYPE_ARP }, { "lat", ETHERTYPE_LAT },
{ "rarp", ETHERTYPE_REVARP }, { "loopback", ETHERTYPE_LOOPBACK },
{ "sprite", ETHERTYPE_SPRITE },
{ "mopdl", ETHERTYPE_MOPDL }, { "mopdl", ETHERTYPE_MOPDL },
{ "moprc", ETHERTYPE_MOPRC }, { "moprc", ETHERTYPE_MOPRC },
{ "decnet", ETHERTYPE_DN }, { "rarp", ETHERTYPE_REVARP },
{ "lat", ETHERTYPE_LAT },
{ "sca", ETHERTYPE_SCA }, { "sca", ETHERTYPE_SCA },
{ "lanbridge", ETHERTYPE_LANBRIDGE },
{ "vexp", ETHERTYPE_VEXP },
{ "vprod", ETHERTYPE_VPROD },
{ "atalk", ETHERTYPE_ATALK },
{ "atalkarp", ETHERTYPE_AARP },
{ "loopback", ETHERTYPE_LOOPBACK },
{ "decdts", ETHERTYPE_DECDTS },
{ "decdns", ETHERTYPE_DECDNS },
{ (char *)0, 0 } { (char *)0, 0 }
}; };
@@ -635,9 +648,9 @@ pcap_nametollc(const char *s)
static inline u_char static inline u_char
xdtoi(u_char c) xdtoi(u_char c)
{ {
if (isdigit(c)) if (c >= '0' && c <= '9')
return (u_char)(c - '0'); return (u_char)(c - '0');
else if (islower(c)) else if (c >= 'a' && c <= 'f')
return (u_char)(c - 'a' + 10); return (u_char)(c - 'a' + 10);
else else
return (u_char)(c - 'A' + 10); return (u_char)(c - 'A' + 10);
@@ -653,8 +666,15 @@ __pcap_atoin(const char *s, bpf_u_int32 *addr)
len = 0; len = 0;
for (;;) { for (;;) {
n = 0; n = 0;
while (*s && *s != '.') while (*s && *s != '.') {
if (n > 25) {
/* The result will be > 255 */
return -1;
}
n = n * 10 + *s++ - '0'; n = n * 10 + *s++ - '0';
}
if (n > 255)
return -1;
*addr <<= 8; *addr <<= 8;
*addr |= n & 0xff; *addr |= n & 0xff;
len += 8; len += 8;
@@ -709,7 +729,7 @@ pcap_ether_aton(const char *s)
if (*s == ':' || *s == '.' || *s == '-') if (*s == ':' || *s == '.' || *s == '-')
s += 1; s += 1;
d = xdtoi(*s++); d = xdtoi(*s++);
if (isxdigit((unsigned char)*s)) { if (PCAP_ISXDIGIT(*s)) {
d <<= 4; d <<= 4;
d |= xdtoi(*s++); d |= xdtoi(*s++);
} }

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "https://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"> <plist version="1.0">
<dict> <dict>
<key>Label</key> <key>Label</key>

1051
libpcap/pcap-airpcap.c Normal file

File diff suppressed because it is too large Load Diff

36
libpcap/pcap-airpcap.h Normal file
View File

@@ -0,0 +1,36 @@
/*
* Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy)
* Copyright (c) 2005 - 2010 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.
*
*/
pcap_t *airpcap_create(const char *, char *, int *);
int airpcap_findalldevs(pcap_if_list_t *devlistp, char *errbuf);
int device_is_airpcap(const char *device, char *ebuf);

File diff suppressed because it is too large Load Diff

View File

@@ -58,7 +58,7 @@
/* forward declaration */ /* forward declaration */
static int bt_activate(pcap_t *); static int bt_activate(pcap_t *);
static int bt_read_linux(pcap_t *, int , pcap_handler , u_char *); static int bt_read_linux(pcap_t *, int , pcap_handler , u_char *);
static int bt_inject_linux(pcap_t *, const void *, size_t); static int bt_inject_linux(pcap_t *, const void *, int);
static int bt_setdirection_linux(pcap_t *, pcap_direction_t); static int bt_setdirection_linux(pcap_t *, pcap_direction_t);
static int bt_stats_linux(pcap_t *, struct pcap_stat *); static int bt_stats_linux(pcap_t *, struct pcap_stat *);
@@ -92,7 +92,7 @@ bt_findalldevs(pcap_if_list_t *devlistp, char *err_str)
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)
{ {
pcap_snprintf(err_str, PCAP_ERRBUF_SIZE, "Can't allocate %zu bytes for Bluetooth device list", 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;
@@ -112,8 +112,8 @@ bt_findalldevs(pcap_if_list_t *devlistp, char *err_str)
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[40]; char dev_name[20], dev_descr[40];
pcap_snprintf(dev_name, sizeof(dev_name), BT_IFACE"%u", dev_req->dev_id); snprintf(dev_name, sizeof(dev_name), BT_IFACE"%u", dev_req->dev_id);
pcap_snprintf(dev_descr, sizeof(dev_descr), "Bluetooth adapter number %u", i); snprintf(dev_descr, sizeof(dev_descr), "Bluetooth adapter number %u", i);
/* /*
* Bluetooth is a wireless technology. * Bluetooth is a wireless technology.
@@ -173,7 +173,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(ebuf, sizeof (struct pcap_bt)); p = PCAP_CREATE_COMMON(ebuf, struct pcap_bt);
if (p == NULL) if (p == NULL)
return (NULL); return (NULL);
@@ -194,7 +194,7 @@ bt_activate(pcap_t* handle)
/* get bt interface id */ /* get bt interface id */
if (sscanf(handle->opt.device, BT_IFACE"%d", &dev_id) != 1) if (sscanf(handle->opt.device, BT_IFACE"%d", &dev_id) != 1)
{ {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't get Bluetooth device index from %s", "Can't get Bluetooth device index from %s",
handle->opt.device); handle->opt.device);
return PCAP_ERROR; return PCAP_ERROR;
@@ -341,12 +341,16 @@ bt_read_linux(pcap_t *handle, int max_packets _U_, pcap_handler callback, u_char
} while ((ret == -1) && (errno == EINTR)); } while ((ret == -1) && (errno == EINTR));
if (ret < 0) { if (ret < 0) {
if (errno == EAGAIN || errno == EWOULDBLOCK) {
/* Nonblocking mode, no data */
return 0;
}
pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE, pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
errno, "Can't receive packet"); errno, "Can't receive packet");
return -1; return -1;
} }
pkth.caplen = ret; pkth.caplen = (bpf_u_int32)ret;
/* get direction and timestamp*/ /* get direction and timestamp*/
cmsg = CMSG_FIRSTHDR(&msg); cmsg = CMSG_FIRSTHDR(&msg);
@@ -362,15 +366,27 @@ bt_read_linux(pcap_t *handle, int max_packets _U_, pcap_handler callback, u_char
} }
cmsg = CMSG_NXTHDR(&msg, cmsg); cmsg = CMSG_NXTHDR(&msg, cmsg);
} }
if ((in && (handle->direction == PCAP_D_OUT)) || switch (handle->direction) {
((!in) && (handle->direction == PCAP_D_IN)))
return 0; case PCAP_D_IN:
if (!in)
return 0;
break;
case PCAP_D_OUT:
if (in)
return 0;
break;
default:
break;
}
bthdr->direction = htonl(in != 0); bthdr->direction = htonl(in != 0);
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, pktd, pkth.len, pkth.caplen)) { pcap_filter(handle->fcode.bf_insns, pktd, pkth.len, pkth.caplen)) {
callback(user, &pkth, pktd); callback(user, &pkth, pktd);
return 1; return 1;
} }
@@ -378,9 +394,9 @@ bt_read_linux(pcap_t *handle, int max_packets _U_, pcap_handler callback, u_char
} }
static int static int
bt_inject_linux(pcap_t *handle, const void *buf _U_, size_t size _U_) bt_inject_linux(pcap_t *handle, const void *buf _U_, int size _U_)
{ {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Packet injection is not supported on Bluetooth devices"); "Packet injection is not supported on Bluetooth devices");
return (-1); return (-1);
} }
@@ -418,6 +434,10 @@ bt_stats_linux(pcap_t *handle, struct pcap_stat *stats)
static int static int
bt_setdirection_linux(pcap_t *p, pcap_direction_t d) bt_setdirection_linux(pcap_t *p, pcap_direction_t d)
{ {
/*
* It's guaranteed, at this point, that d is a valid
* direction value.
*/
p->direction = d; p->direction = d;
return 0; return 0;
} }

View File

@@ -49,6 +49,14 @@
#define BT_CONTROL_SIZE 32 #define BT_CONTROL_SIZE 32
#define INTERFACE_NAME "bluetooth-monitor" #define INTERFACE_NAME "bluetooth-monitor"
/*
* Private data.
* Currently contains nothing.
*/
struct pcap_bt_monitor {
int dummy;
};
/* /*
* Fields and alignment must match the declaration in the Linux kernel 3.4+. * 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. * See struct hci_mon_hdr in include/net/bluetooth/hci_mon.h.
@@ -119,12 +127,16 @@ 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) {
if (errno == EAGAIN || errno == EWOULDBLOCK) {
/* Nonblocking mode, no data */
return 0;
}
pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE, pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
errno, "Can't receive packet"); errno, "Can't receive packet");
return -1; return -1;
} }
pkth.caplen = ret - sizeof(hdr) + sizeof(pcap_bluetooth_linux_monitor_header); pkth.caplen = (bpf_u_int32)(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)) {
@@ -139,7 +151,7 @@ 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, pktd, pkth.len, pkth.caplen)) { pcap_filter(handle->fcode.bf_insns, pktd, pkth.len, pkth.caplen)) {
callback(user, &pkth, pktd); callback(user, &pkth, pktd);
return 1; return 1;
} }
@@ -147,20 +159,13 @@ 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_, int size _U_)
{ {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Packet injection is not supported yet on Bluetooth monitor devices"); "Packet injection is not supported yet on Bluetooth monitor devices");
return -1; return -1;
} }
static int
bt_monitor_setdirection(pcap_t *p, pcap_direction_t d)
{
p->direction = d;
return 0;
}
static int static int
bt_monitor_stats(pcap_t *handle _U_, struct pcap_stat *stats) bt_monitor_stats(pcap_t *handle _U_, struct pcap_stat *stats)
{ {
@@ -200,7 +205,7 @@ bt_monitor_activate(pcap_t* handle)
handle->read_op = bt_monitor_read; handle->read_op = bt_monitor_read;
handle->inject_op = bt_monitor_inject; handle->inject_op = bt_monitor_inject;
handle->setfilter_op = install_bpf_program; /* no kernel filtering */ handle->setfilter_op = install_bpf_program; /* no kernel filtering */
handle->setdirection_op = bt_monitor_setdirection; handle->setdirection_op = NULL; /* Not implemented */
handle->set_datalink_op = NULL; /* can't change data link type */ handle->set_datalink_op = NULL; /* can't change data link type */
handle->getnonblock_op = pcap_getnonblock_fd; handle->getnonblock_op = pcap_getnonblock_fd;
handle->setnonblock_op = pcap_setnonblock_fd; handle->setnonblock_op = pcap_setnonblock_fd;
@@ -263,7 +268,7 @@ bt_monitor_create(const char *device, char *ebuf, int *is_ours)
} }
*is_ours = 1; *is_ours = 1;
p = pcap_create_common(ebuf, 0); p = PCAP_CREATE_COMMON(ebuf, struct pcap_bt_monitor);
if (p == NULL) if (p == NULL)
return NULL; return NULL;

View File

@@ -326,7 +326,7 @@
* input packets such as port scans, packets from old lost connections, * input packets such as port scans, packets from old lost connections,
* etc. to force the connection to stay up). * etc. to force the connection to stay up).
* *
* The first byte of the PPP header (0xff03) is modified to accomodate * The first byte of the PPP header (0xff03) is modified to accommodate
* the direction - 0x00 = IN, 0x01 = OUT. * the direction - 0x00 = IN, 0x01 = OUT.
*/ */
#define LINKTYPE_PPP_PPPD 166 #define LINKTYPE_PPP_PPPD 166
@@ -361,7 +361,7 @@
/* /*
* Link types requested by Gregor Maier <gregor@endace.com> of Endace * Link types requested by Gregor Maier <gregor@endace.com> of Endace
* Measurement Systems. They add an ERF header (see * Measurement Systems. They add an ERF header (see
* http://www.endace.com/support/EndaceRecordFormat.pdf) in front of * https://www.endace.com/support/EndaceRecordFormat.pdf) in front of
* the link-layer header. * the link-layer header.
*/ */
#define LINKTYPE_ERF_ETH 175 /* Ethernet */ #define LINKTYPE_ERF_ETH 175 /* Ethernet */
@@ -495,7 +495,7 @@
/* /*
* Various link-layer types, with a pseudo-header, for SITA * Various link-layer types, with a pseudo-header, for SITA
* (http://www.sita.aero/); requested by Fulko Hew (fulko.hew@gmail.com). * (https://www.sita.aero/); requested by Fulko Hew (fulko.hew@gmail.com).
*/ */
#define LINKTYPE_SITA 196 #define LINKTYPE_SITA 196
@@ -558,7 +558,6 @@
*/ */
#define LINKTYPE_LAPD 203 #define LINKTYPE_LAPD 203
/* /*
* PPP, with a one-byte direction pseudo-header prepended - zero means * PPP, with a one-byte direction pseudo-header prepended - zero means
* "received by this host", non-zero (any non-zero value) means "sent by * "received by this host", non-zero (any non-zero value) means "sent by
@@ -608,7 +607,7 @@
/* /*
* Media Oriented Systems Transport (MOST) bus for multimedia * Media Oriented Systems Transport (MOST) bus for multimedia
* transport - http://www.mostcooperation.com/ - as requested * transport - https://www.mostcooperation.com/ - as requested
* by Hannes Kaelber <hannes.kaelber@x2e.de>. * by Hannes Kaelber <hannes.kaelber@x2e.de>.
*/ */
#define LINKTYPE_MOST 211 #define LINKTYPE_MOST 211
@@ -794,16 +793,16 @@
/* /*
* Raw D-Bus: * Raw D-Bus:
* *
* http://www.freedesktop.org/wiki/Software/dbus * https://www.freedesktop.org/wiki/Software/dbus
* *
* messages: * messages:
* *
* http://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-messages * https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-messages
* *
* starting with the endianness flag, followed by the message type, etc., * starting with the endianness flag, followed by the message type, etc.,
* but without the authentication handshake before the message sequence: * but without the authentication handshake before the message sequence:
* *
* http://dbus.freedesktop.org/doc/dbus-specification.html#auth-protocol * https://dbus.freedesktop.org/doc/dbus-specification.html#auth-protocol
* *
* Requested by Martin Vidner <martin@vidner.net>. * Requested by Martin Vidner <martin@vidner.net>.
*/ */
@@ -821,7 +820,7 @@
* DVB-CI (DVB Common Interface for communication between a PC Card * DVB-CI (DVB Common Interface for communication between a PC Card
* module and a DVB receiver). See * module and a DVB receiver). See
* *
* http://www.kaiser.cx/pcap-dvbci.html * https://www.kaiser.cx/pcap-dvbci.html
* *
* for the specification. * for the specification.
* *
@@ -945,7 +944,7 @@
* *
* Requested by Chris Bontje <chris_bontje@selinc.com>. * Requested by Chris Bontje <chris_bontje@selinc.com>.
*/ */
#define DLT_RTAC_SERIAL 250 #define LINKTYPE_RTAC_SERIAL 250
/* /*
* Bluetooth Low Energy air interface link-layer packets. * Bluetooth Low Energy air interface link-layer packets.
@@ -1079,9 +1078,9 @@
/* /*
* per: Stefanha at gmail.com for * per: Stefanha at gmail.com for
* http://lists.sandelman.ca/pipermail/tcpdump-workers/2017-May/000772.html * https://lists.sandelman.ca/pipermail/tcpdump-workers/2017-May/000772.html
* and: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/vsockmon.h * and: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/vsockmon.h
* for: http://qemu-project.org/Features/VirtioVsock * for: https://qemu-project.org/Features/VirtioVsock
*/ */
#define LINKTYPE_VSOCK 271 #define LINKTYPE_VSOCK 271
@@ -1093,7 +1092,7 @@
/* /*
* Excentis DOCSIS 3.1 RF sniffer (XRA-31) * Excentis DOCSIS 3.1 RF sniffer (XRA-31)
* per: bruno.verstuyft at excentis.com * per: bruno.verstuyft at excentis.com
* http://www.xra31.com/xra-header * https://www.xra31.com/xra-header
*/ */
#define LINKTYPE_DOCSIS31_XRA31 273 #define LINKTYPE_DOCSIS31_XRA31 273
@@ -1105,7 +1104,7 @@
/* /*
* DisplayPort AUX channel monitoring data as specified by VESA * DisplayPort AUX channel monitoring data as specified by VESA
* DisplayPort(DP) Standard preceeded by a pseudo-header. * DisplayPort(DP) Standard preceded by a pseudo-header.
* per dirk.eibach at gdsys.cc * per dirk.eibach at gdsys.cc
*/ */
#define LINKTYPE_DISPLAYPORT_AUX 275 #define LINKTYPE_DISPLAYPORT_AUX 275
@@ -1115,7 +1114,84 @@
*/ */
#define LINKTYPE_LINUX_SLL2 276 #define LINKTYPE_LINUX_SLL2 276
#define LINKTYPE_MATCHING_MAX 276 /* highest value in the "matching" range */ /*
* Sercos Monitor, per Manuel Jacob <manuel.jacob at steinbeis-stg.de>
*/
#define LINKTYPE_SERCOS_MONITOR 277
/*
* OpenVizsla http://openvizsla.org is open source USB analyzer hardware.
* It consists of FPGA with attached USB phy and FTDI chip for streaming
* the data to the host PC.
*
* Current OpenVizsla data encapsulation format is described here:
* https://github.com/matwey/libopenvizsla/wiki/OpenVizsla-protocol-description
*
*/
#define LINKTYPE_OPENVIZSLA 278
/*
* The Elektrobit High Speed Capture and Replay (EBHSCR) protocol is produced
* by a PCIe Card for interfacing high speed automotive interfaces.
*
* The specification for this frame format can be found at:
* https://www.elektrobit.com/ebhscr
*
* for Guenter.Ebermann at elektrobit.com
*
*/
#define LINKTYPE_EBHSCR 279
/*
* The https://fd.io vpp graph dispatch tracer produces pcap trace files
* in the format documented here:
* https://fdio-vpp.readthedocs.io/en/latest/gettingstarted/developers/vnet.html#graph-dispatcher-pcap-tracing
*/
#define LINKTYPE_VPP_DISPATCH 280
/*
* Broadcom Ethernet switches (ROBO switch) 4 bytes proprietary tagging format.
*/
#define LINKTYPE_DSA_TAG_BRCM 281
#define LINKTYPE_DSA_TAG_BRCM_PREPEND 282
/*
* IEEE 802.15.4 with pseudo-header and optional meta-data TLVs, PHY payload
* exactly as it appears in the spec (no padding, no nothing), and FCS if
* specified by FCS Type TLV; requested by James Ko <jck@exegin.com>.
* Specification at https://github.com/jkcko/ieee802.15.4-tap
*/
#define LINKTYPE_IEEE802_15_4_TAP 283
/*
* Marvell (Ethertype) Distributed Switch Architecture proprietary tagging format.
*/
#define LINKTYPE_DSA_TAG_DSA 284
#define LINKTYPE_DSA_TAG_EDSA 285
/*
* Payload of lawful intercept packets using the ELEE protocol;
* https://socket.hr/draft-dfranusic-opsawg-elee-00.xml
* https://xml2rfc.tools.ietf.org/cgi-bin/xml2rfc.cgi?url=https://socket.hr/draft-dfranusic-opsawg-elee-00.xml&modeAsFormat=html/ascii
*/
#define LINKTYPE_ELEE 286
/*
* Serial frames transmitted between a host and a Z-Wave chip.
*/
#define LINKTYPE_Z_WAVE_SERIAL 287
/*
* USB 2.0, 1.1, and 1.0 packets as transmitted over the cable.
*/
#define LINKTYPE_USB_2_0 288
/*
* ATSC Link-Layer Protocol (A/330) packets.
*/
#define LINKTYPE_ATSC_ALP 289
#define LINKTYPE_MATCHING_MAX 289 /* highest value in the "matching" range */
/* /*
* The DLT_ and LINKTYPE_ values in the "matching" range should be the * The DLT_ and LINKTYPE_ values in the "matching" range should be the
@@ -1144,7 +1220,7 @@ static struct linktype_map {
{ DLT_ARCNET, LINKTYPE_ARCNET_BSD }, { DLT_ARCNET, LINKTYPE_ARCNET_BSD },
{ DLT_SLIP, LINKTYPE_SLIP }, { DLT_SLIP, LINKTYPE_SLIP },
{ DLT_PPP, LINKTYPE_PPP }, { DLT_PPP, LINKTYPE_PPP },
{ DLT_FDDI, LINKTYPE_FDDI }, { DLT_FDDI, LINKTYPE_FDDI },
{ DLT_SYMANTEC_FIREWALL, LINKTYPE_SYMANTEC_FIREWALL }, { DLT_SYMANTEC_FIREWALL, LINKTYPE_SYMANTEC_FIREWALL },
/* /*
@@ -1248,11 +1324,20 @@ linktype_to_dlt(int linktype)
return (DLT_PKTAP); return (DLT_PKTAP);
/* /*
* For all other values in the matching range, the LINKTYPE * For all other values in the matching range, except for
* value is the same as the DLT value. * LINKTYPE_ATM_CLIP, the LINKTYPE value is the same as
* the DLT value.
*
* LINKTYPE_ATM_CLIP is a special case. DLT_ATM_CLIP is
* not on all platforms, but, so far, there don't appear
* to be any platforms that define it as anything other
* than 19; we define LINKTYPE_ATM_CLIP as something
* other than 19, just in case. That value is in the
* matching range, so we have to check for it.
*/ */
if (linktype >= LINKTYPE_MATCHING_MIN && if (linktype >= LINKTYPE_MATCHING_MIN &&
linktype <= LINKTYPE_MATCHING_MAX) linktype <= LINKTYPE_MATCHING_MAX &&
linktype != LINKTYPE_ATM_CLIP)
return (linktype); return (linktype);
/* /*
@@ -1265,7 +1350,7 @@ linktype_to_dlt(int linktype)
/* /*
* If we don't have an entry for this LINKTYPE, return * If we don't have an entry for this LINKTYPE, return
* the link type value; it may be a DLT from an older * the link type value; it may be a DLT from an newer
* version of libpcap. * version of libpcap.
*/ */
return linktype; return linktype;
@@ -1280,6 +1365,10 @@ linktype_to_dlt(int linktype)
* *
* https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-messages * https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-messages
* *
* For DLT_EBHSCR, the maximum is 8MiB, as per
*
* https://www.elektrobit.com/ebhscr
*
* For DLT_USBPCAP, the maximum is 1MiB, as per * For DLT_USBPCAP, the maximum is 1MiB, as per
* *
* https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=15985 * https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=15985
@@ -1292,6 +1381,9 @@ max_snaplen_for_dlt(int dlt)
case DLT_DBUS: case DLT_DBUS:
return 128*1024*1024; return 128*1024*1024;
case DLT_EBHSCR:
return 8*1024*1024;
case DLT_USBPCAP: case DLT_USBPCAP:
return 1024*1024; return 1024*1024;
@@ -1324,7 +1416,7 @@ swap_linux_sll_header(const struct pcap_pkthdr *hdr, u_char *buf)
return; return;
} }
protocol = EXTRACT_16BITS(&shdr->sll_protocol); protocol = EXTRACT_BE_U_2(&shdr->sll_protocol);
if (protocol != LINUX_SLL_P_CAN && protocol != LINUX_SLL_P_CANFD) if (protocol != LINUX_SLL_P_CAN && protocol != LINUX_SLL_P_CANFD)
return; return;

View File

@@ -69,4 +69,4 @@ dynamically-linked version of libpcap; the
flag causes it to write flags appropriate for compiling with a flag causes it to write flags appropriate for compiling with a
statically-linked version of libpcap. statically-linked version of libpcap.
.SH "SEE ALSO" .SH "SEE ALSO"
pcap(3PCAP) .BR pcap (3PCAP)

View File

@@ -19,7 +19,6 @@
#include "pcap-int.h" #include "pcap-int.h"
#include <ctype.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/socket.h> #include <sys/socket.h>
@@ -208,7 +207,6 @@ static unsigned char TempPkt[MAX_DAG_PACKET];
#define dag_size_t uint32_t #define dag_size_t uint32_t
#endif #endif
static int dag_setfilter(pcap_t *p, struct bpf_program *fp);
static int dag_stats(pcap_t *p, struct pcap_stat *ps); static int dag_stats(pcap_t *p, struct pcap_stat *ps);
static int dag_set_datalink(pcap_t *p, int dlt); static int dag_set_datalink(pcap_t *p, int dlt);
static int dag_get_datalink(pcap_t *p); static int dag_get_datalink(pcap_t *p);
@@ -335,7 +333,7 @@ dag_erf_ext_header_count(uint8_t * erf, size_t len)
/* /*
* Read at most max_packets from the capture stream and call the callback * Read at most max_packets from the capture stream and call the callback
* for each of them. Returns the number of packets handled, -1 if an * for each of them. Returns the number of packets handled, -1 if an
* error occured, or -2 if we were told to break out of the loop. * error occurred, or -2 if we were told to break out of the loop.
*/ */
static int static int
dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
@@ -421,7 +419,8 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
rlen = ntohs(header->rlen); rlen = ntohs(header->rlen);
if (rlen < dag_record_size) if (rlen < dag_record_size)
{ {
strncpy(p->errbuf, "dag_read: record too small", PCAP_ERRBUF_SIZE); pcap_strlcpy(p->errbuf, "dag_read: record too small",
PCAP_ERRBUF_SIZE);
return -1; return -1;
} }
pd->dag_mem_bottom += rlen; pd->dag_mem_bottom += rlen;
@@ -664,7 +663,7 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
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) || pcap_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;
@@ -718,7 +717,7 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
} }
static int static int
dag_inject(pcap_t *p, const void *buf _U_, size_t size _U_) dag_inject(pcap_t *p, const void *buf _U_, int size _U_)
{ {
pcap_strlcpy(p->errbuf, "Sending packets isn't supported on DAG cards", pcap_strlcpy(p->errbuf, "Sending packets isn't supported on DAG cards",
PCAP_ERRBUF_SIZE); PCAP_ERRBUF_SIZE);
@@ -750,7 +749,7 @@ static int dag_activate(pcap_t* p)
struct timeval poll; struct timeval poll;
if (device == NULL) { if (device == NULL) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "device is NULL"); snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "device is NULL");
return PCAP_ERROR; return PCAP_ERROR;
} }
@@ -780,7 +779,7 @@ static int dag_activate(pcap_t* p)
if (pd->dag_stream%2) { if (pd->dag_stream%2) {
ret = PCAP_ERROR; ret = PCAP_ERROR;
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "dag_parse_name: tx (even numbered) streams not supported for capture"); snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "dag_parse_name: tx (even numbered) streams not supported for capture");
goto fail; goto fail;
} }
@@ -936,7 +935,7 @@ static int dag_activate(pcap_t* p)
pd->dag_fcs_bits = n; pd->dag_fcs_bits = n;
} else { } else {
ret = PCAP_ERROR; ret = PCAP_ERROR;
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"pcap_activate %s: bad ERF_FCS_BITS value (%d) in environment", device, n); "pcap_activate %s: bad ERF_FCS_BITS value (%d) in environment", device, n);
goto failstop; goto failstop;
} }
@@ -983,7 +982,7 @@ static int dag_activate(pcap_t* p)
p->read_op = dag_read; p->read_op = dag_read;
p->inject_op = dag_inject; p->inject_op = dag_inject;
p->setfilter_op = dag_setfilter; p->setfilter_op = install_bpf_program;
p->setdirection_op = NULL; /* Not implemented.*/ p->setdirection_op = NULL; /* Not implemented.*/
p->set_datalink_op = dag_set_datalink; p->set_datalink_op = dag_set_datalink;
p->getnonblock_op = pcap_getnonblock_fd; p->getnonblock_op = pcap_getnonblock_fd;
@@ -1072,7 +1071,7 @@ 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(ebuf, sizeof (struct pcap_dag)); p = PCAP_CREATE_COMMON(ebuf, struct pcap_dag);
if (p == NULL) if (p == NULL)
return NULL; return NULL;
@@ -1085,7 +1084,6 @@ pcap_t *dag_create(const char *device, char *ebuf, int *is_ours)
* XXX Our native precision is 2^-32s, but libpcap doesn't support * 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. * 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)); p->tstamp_precision_list = malloc(2 * sizeof(u_int));
if (p->tstamp_precision_list == NULL) { if (p->tstamp_precision_list == NULL) {
pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE, pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
@@ -1095,6 +1093,7 @@ pcap_t *dag_create(const char *device, char *ebuf, int *is_ours)
} }
p->tstamp_precision_list[0] = PCAP_TSTAMP_PRECISION_MICRO; p->tstamp_precision_list[0] = PCAP_TSTAMP_PRECISION_MICRO;
p->tstamp_precision_list[1] = PCAP_TSTAMP_PRECISION_NANO; p->tstamp_precision_list[1] = PCAP_TSTAMP_PRECISION_NANO;
p->tstamp_precision_count = 2;
return p; return p;
} }
@@ -1115,10 +1114,10 @@ dag_stats(pcap_t *p, struct pcap_stat *ps) {
/* Note this counter is cleared at start of capture and will wrap at UINT_MAX. /* Note this counter is cleared at start of capture and will wrap at UINT_MAX.
* The application is responsible for polling ps_drop frequently enough * The application is responsible for polling ps_drop frequently enough
* to detect each wrap and integrate total drop with a wider counter */ * to detect each wrap and integrate total drop with a wider counter */
if ((dag_error = dag_config_get_uint32_attribute_ex(pd->dag_ref, pd->drop_attr, &stream_drop) == kDagErrNone)) { if ((dag_error = dag_config_get_uint32_attribute_ex(pd->dag_ref, pd->drop_attr, &stream_drop)) == kDagErrNone) {
pd->stat.ps_drop = stream_drop; pd->stat.ps_drop = stream_drop;
} else { } else {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "reading stream drop attribute: %s", snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "reading stream drop attribute: %s",
dag_config_strerror(dag_error)); dag_config_strerror(dag_error));
return -1; return -1;
} }
@@ -1146,10 +1145,10 @@ dag_findalldevs(pcap_if_list_t *devlistp, char *errbuf)
/* 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++) {
pcap_snprintf(name, 12, "dag%d", c); 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))
{ {
(void) pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, (void) snprintf(errbuf, PCAP_ERRBUF_SIZE,
"dag: device name %s can't be parsed", name); "dag: device name %s can't be parsed", name);
return (-1); return (-1);
} }
@@ -1177,7 +1176,7 @@ dag_findalldevs(pcap_if_list_t *devlistp, char *errbuf)
if (0 == dag_attach_stream64(dagfd, stream, 0, 0)) { if (0 == dag_attach_stream64(dagfd, stream, 0, 0)) {
dag_detach_stream(dagfd, stream); dag_detach_stream(dagfd, stream);
pcap_snprintf(name, 10, "dag%d:%d", c, stream); snprintf(name, 10, "dag%d:%d", c, stream);
if (add_dev(devlistp, name, 0, description, errbuf) == NULL) { if (add_dev(devlistp, name, 0, description, errbuf) == NULL) {
/* /*
* Failure. * Failure.
@@ -1198,30 +1197,6 @@ dag_findalldevs(pcap_if_list_t *devlistp, char *errbuf)
return (0); return (0);
} }
/*
* Installs the given bpf filter program in the given pcap structure. There is
* no attempt to store the filter in kernel memory as that is not supported
* with DAG cards.
*/
static int
dag_setfilter(pcap_t *p, struct bpf_program *fp)
{
if (!p)
return -1;
if (!fp) {
strncpy(p->errbuf, "setfilter: No filter specified",
sizeof(p->errbuf));
return -1;
}
/* Make our private copy of the filter */
if (install_bpf_program(p, fp) < 0)
return -1;
return (0);
}
static int static int
dag_set_datalink(pcap_t *p, int dlt) dag_set_datalink(pcap_t *p, int dlt)
{ {
@@ -1451,7 +1426,7 @@ pcap_platform_finddevs(pcap_if_list_t *devlistp _U_, char *errbuf)
pcap_t * pcap_t *
pcap_create_interface(const char *device, char *errbuf) pcap_create_interface(const char *device, char *errbuf)
{ {
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, snprintf(errbuf, PCAP_ERRBUF_SIZE,
"This version of libpcap only supports DAG cards"); "This version of libpcap only supports DAG cards");
return NULL; return NULL;
} }

View File

@@ -68,7 +68,7 @@ dbus_read(pcap_t *handle, int max_packets _U_, pcap_handler callback, u_char *us
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)) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Connection closed"); snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Connection closed");
return -1; return -1;
} }
@@ -81,7 +81,7 @@ dbus_read(pcap_t *handle, int max_packets _U_, pcap_handler callback, u_char *us
} }
if (dbus_message_is_signal(message, DBUS_INTERFACE_LOCAL, "Disconnected")) { if (dbus_message_is_signal(message, DBUS_INTERFACE_LOCAL, "Disconnected")) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Disconnected"); snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Disconnected");
return -1; return -1;
} }
@@ -91,7 +91,7 @@ dbus_read(pcap_t *handle, int max_packets _U_, pcap_handler callback, u_char *us
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, (u_char *)raw_msg, pkth.len, pkth.caplen)) { pcap_filter(handle->fcode.bf_insns, (u_char *)raw_msg, pkth.len, pkth.caplen)) {
handlep->packets_read++; handlep->packets_read++;
callback(user, &pkth, (u_char *)raw_msg); callback(user, &pkth, (u_char *)raw_msg);
count++; count++;
@@ -103,7 +103,7 @@ dbus_read(pcap_t *handle, int max_packets _U_, pcap_handler callback, u_char *us
} }
static int static int
dbus_write(pcap_t *handle, const void *buf, size_t size) dbus_write(pcap_t *handle, const void *buf, int size)
{ {
/* XXX, not tested */ /* XXX, not tested */
struct pcap_dbus *handlep = handle->priv; struct pcap_dbus *handlep = handle->priv;
@@ -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))) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dbus_message_demarshal() failed: %s", error.message); 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;
} }
@@ -154,7 +154,7 @@ dbus_cleanup(pcap_t *handle)
static int static int
dbus_getnonblock(pcap_t *p) dbus_getnonblock(pcap_t *p)
{ {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"Non-blocking mode isn't supported for capturing on D-Bus"); "Non-blocking mode isn't supported for capturing on D-Bus");
return (-1); return (-1);
} }
@@ -162,7 +162,7 @@ dbus_getnonblock(pcap_t *p)
static int static int
dbus_setnonblock(pcap_t *p, int nonblock _U_) dbus_setnonblock(pcap_t *p, int nonblock _U_)
{ {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"Non-blocking mode isn't supported for capturing on D-Bus"); "Non-blocking mode isn't supported for capturing on D-Bus");
return (-1); return (-1);
} }
@@ -189,14 +189,14 @@ dbus_activate(pcap_t *handle)
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))) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Failed to get system bus: %s", error.message); 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))) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Failed to get session bus: %s", error.message); 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;
} }
@@ -205,19 +205,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))) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Failed to open connection to: %s: %s", addr, error.message); 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)) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Failed to register bus %s: %s\n", addr, error.message); 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 {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't get bus address from %s", handle->opt.device); snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't get bus address from %s", handle->opt.device);
return PCAP_ERROR; return PCAP_ERROR;
} }
@@ -289,7 +289,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)) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Failed to add bus match: %s\n", error.message); 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;
@@ -314,7 +314,7 @@ dbus_create(const char *device, char *ebuf, int *is_ours)
} }
*is_ours = 1; *is_ours = 1;
p = pcap_create_common(ebuf, sizeof (struct pcap_dbus)); p = PCAP_CREATE_COMMON(ebuf, struct pcap_dbus);
if (p == NULL) if (p == NULL)
return (NULL); return (NULL);

View File

@@ -96,7 +96,6 @@
#include <net/if.h> #include <net/if.h>
#endif #endif
#include <ctype.h>
#ifdef HAVE_HPUX9 #ifdef HAVE_HPUX9
#include <nlist.h> #include <nlist.h>
#endif #endif
@@ -108,12 +107,7 @@
#include <string.h> #include <string.h>
#include <stropts.h> #include <stropts.h>
#include <unistd.h> #include <unistd.h>
#ifdef HAVE_LIMITS_H
#include <limits.h> #include <limits.h>
#else
#define INT_MAX 2147483647
#endif
#include "pcap-int.h" #include "pcap-int.h"
#include "dlpisubs.h" #include "dlpisubs.h"
@@ -252,7 +246,7 @@ pcap_read_dlpi(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
} }
static int static int
pcap_inject_dlpi(pcap_t *p, const void *buf, size_t size) pcap_inject_dlpi(pcap_t *p, const void *buf, int size)
{ {
#ifdef DL_HP_RAWDLS #ifdef DL_HP_RAWDLS
struct pcap_dlpi *pd = p->priv; struct pcap_dlpi *pd = p->priv;
@@ -268,7 +262,7 @@ pcap_inject_dlpi(pcap_t *p, const void *buf, size_t size)
} }
#elif defined(DL_HP_RAWDLS) #elif defined(DL_HP_RAWDLS)
if (pd->send_fd < 0) { if (pd->send_fd < 0) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"send: Output FD couldn't be opened"); "send: Output FD couldn't be opened");
return (-1); return (-1);
} }
@@ -417,7 +411,7 @@ open_dlpi_device(const char *name, u_int *ppa, char *errbuf)
if (*name == '/') if (*name == '/')
pcap_strlcpy(dname, name, sizeof(dname)); pcap_strlcpy(dname, name, sizeof(dname));
else else
pcap_snprintf(dname, sizeof(dname), "%s/%s", PCAP_DEV_PREFIX, snprintf(dname, sizeof(dname), "%s/%s", PCAP_DEV_PREFIX,
name); name);
/* /*
@@ -475,7 +469,7 @@ open_dlpi_device(const char *name, u_int *ppa, char *errbuf)
* interface is just a symptom of that * interface is just a symptom of that
* inability. * inability.
*/ */
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, snprintf(errbuf, PCAP_ERRBUF_SIZE,
"%s: No DLPI device found", name); "%s: No DLPI device found", name);
} else { } else {
if (errno == EPERM || errno == EACCES) if (errno == EPERM || errno == EACCES)
@@ -639,7 +633,7 @@ pcap_activate_dlpi(pcap_t *p)
**/ **/
if (dlbindreq(p->fd, 0, p->errbuf) < 0 || if (dlbindreq(p->fd, 0, p->errbuf) < 0 ||
dlbindack(p->fd, (char *)buf, p->errbuf, NULL) < 0) { dlbindack(p->fd, (char *)buf, p->errbuf, NULL) < 0) {
status = PCAP_ERROR; status = PCAP_ERROR;
goto bad; goto bad;
} }
#endif /* AIX vs. HP-UX vs. other */ #endif /* AIX vs. HP-UX vs. other */
@@ -767,7 +761,7 @@ pcap_activate_dlpi(pcap_t *p)
*/ */
if (dlinforeq(p->fd, p->errbuf) < 0 || if (dlinforeq(p->fd, p->errbuf) < 0 ||
dlinfoack(p->fd, (char *)buf, p->errbuf) < 0) { dlinfoack(p->fd, (char *)buf, p->errbuf) < 0) {
status = PCAP_ERROR; status = PCAP_ERROR;
goto bad; goto bad;
} }
@@ -805,7 +799,7 @@ pcap_activate_dlpi(pcap_t *p)
get_release(release, sizeof (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) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 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;
@@ -880,7 +874,7 @@ split_dname(char *device, u_int *unitp, char *ebuf)
*/ */
cp = device + strlen(device) - 1; cp = device + strlen(device) - 1;
if (*cp < '0' || *cp > '9') { if (*cp < '0' || *cp > '9') {
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s missing unit number", snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s missing unit number",
device); device);
return (NULL); return (NULL);
} }
@@ -892,16 +886,16 @@ split_dname(char *device, u_int *unitp, char *ebuf)
errno = 0; errno = 0;
unit = strtol(cp, &eos, 10); unit = strtol(cp, &eos, 10);
if (*eos != '\0') { if (*eos != '\0') {
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s bad unit number", device); 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) {
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s unit number too large", snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s unit number too large",
device); device);
return (NULL); return (NULL);
} }
if (unit < 0) { if (unit < 0) {
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s unit number is negative", snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s unit number is negative",
device); device);
return (NULL); return (NULL);
} }
@@ -1115,7 +1109,7 @@ pcap_platform_finddevs(pcap_if_list_t *devlistp, char *errbuf)
return (-1); return (-1);
} }
for (i = 0; i < buf.nunits; i++) { for (i = 0; i < buf.nunits; i++) {
pcap_snprintf(baname, sizeof baname, "ba%u", i); snprintf(baname, sizeof baname, "ba%u", i);
/* /*
* XXX - is there a notion of "up" and "running"? * XXX - is there a notion of "up" and "running"?
* And is there a way to determine whether the * And is there a way to determine whether the
@@ -1202,7 +1196,7 @@ recv_ack(int fd, int size, const char *what, char *bufp, char *ebuf, int *uerror
break; break;
default: default:
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, snprintf(ebuf, PCAP_ERRBUF_SIZE,
"recv_ack: %s: %s", what, "recv_ack: %s: %s", what,
dlstrerror(errmsgbuf, sizeof (errmsgbuf), dlp->error_ack.dl_errno)); 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)
@@ -1214,14 +1208,14 @@ recv_ack(int fd, int size, const char *what, char *bufp, char *ebuf, int *uerror
return (PCAP_ERROR); return (PCAP_ERROR);
default: default:
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, snprintf(ebuf, PCAP_ERRBUF_SIZE,
"recv_ack: %s: Unexpected primitive ack %s", "recv_ack: %s: Unexpected primitive ack %s",
what, dlprim(dlprimbuf, sizeof (dlprimbuf), 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) {
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, 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);
@@ -1332,7 +1326,7 @@ dlstrerror(char *errbuf, size_t errbufsize, bpf_u_int32 dl_errno)
return ("Pending outstanding connect indications"); return ("Pending outstanding connect indications");
default: default:
pcap_snprintf(errbuf, errbufsize, "Error %02x", dl_errno); snprintf(errbuf, errbufsize, "Error %02x", dl_errno);
return (errbuf); return (errbuf);
} }
} }
@@ -1424,7 +1418,7 @@ dlprim(char *primbuf, size_t primbufsize, bpf_u_int32 prim)
return ("DL_RESET_CON"); return ("DL_RESET_CON");
default: default:
pcap_snprintf(primbuf, primbufsize, "unknown primitive 0x%x", snprintf(primbuf, primbufsize, "unknown primitive 0x%x",
prim); prim);
return (primbuf); return (primbuf);
} }
@@ -1551,7 +1545,7 @@ get_release(char *buf, size_t bufsize, bpf_u_int32 *majorp,
return; return;
} }
cp = buf; cp = buf;
if (!isdigit((unsigned char)*cp)) if (!PCAP_ISDIGIT((unsigned char)*cp))
return; return;
*majorp = strtol(cp, &cp, 10); *majorp = strtol(cp, &cp, 10);
if (*cp++ != '.') if (*cp++ != '.')
@@ -1651,21 +1645,21 @@ get_dlpi_ppa(register int fd, register const char *device, register u_int unit,
return (PCAP_ERROR); return (PCAP_ERROR);
} }
if (ctl.len == -1) { if (ctl.len == -1) {
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, snprintf(ebuf, PCAP_ERRBUF_SIZE,
"get_dlpi_ppa: hpppa getmsg: control buffer has no data"); "get_dlpi_ppa: hpppa getmsg: control buffer has no data");
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) {
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, 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 ((size_t)ctl.len < DL_HP_PPA_ACK_SIZE) { if ((size_t)ctl.len < DL_HP_PPA_ACK_SIZE) {
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, 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);
@@ -1688,12 +1682,12 @@ get_dlpi_ppa(register int fd, register const char *device, register u_int unit,
return (PCAP_ERROR); return (PCAP_ERROR);
} }
if (ctl.len == -1) { if (ctl.len == -1) {
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, snprintf(ebuf, PCAP_ERRBUF_SIZE,
"get_dlpi_ppa: hpppa getmsg: control buffer has no data"); "get_dlpi_ppa: hpppa getmsg: control buffer has no data");
return (PCAP_ERROR); return (PCAP_ERROR);
} }
if ((u_int)ctl.len < dlp->dl_length) { if ((u_int)ctl.len < dlp->dl_length) {
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, 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);
@@ -1750,7 +1744,7 @@ get_dlpi_ppa(register int fd, register const char *device, register u_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.
*/ */
pcap_snprintf(dname, sizeof(dname), "/dev/%s%u", device, unit); snprintf(dname, sizeof(dname), "/dev/%s%u", device, unit);
if (stat(dname, &statbuf) < 0) { if (stat(dname, &statbuf) < 0) {
pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE, pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
errno, "stat: %s", dname); errno, "stat: %s", dname);
@@ -1769,12 +1763,12 @@ get_dlpi_ppa(register int fd, register const char *device, register u_int unit,
} }
} }
if (i == ap->dl_count) { if (i == ap->dl_count) {
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, snprintf(ebuf, PCAP_ERRBUF_SIZE,
"can't find /dev/dlpi PPA for %s%u", device, unit); "can't find /dev/dlpi PPA for %s%u", 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) {
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, 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);
@@ -1813,13 +1807,13 @@ get_dlpi_ppa(register int fd, register const char *ifname, register u_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) {
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "nlist %s failed", snprintf(ebuf, PCAP_ERRBUF_SIZE, "nlist %s failed",
path_vmunix); path_vmunix);
return (PCAP_ERROR); return (PCAP_ERROR);
} }
if (nl[NL_IFNET].n_value == 0) { if (nl[NL_IFNET].n_value == 0) {
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, snprintf(ebuf, PCAP_ERRBUF_SIZE,
"could't find %s kernel symbol", "couldn't find %s kernel symbol",
nl[NL_IFNET].n_name); nl[NL_IFNET].n_name);
return (PCAP_ERROR); return (PCAP_ERROR);
} }
@@ -1849,7 +1843,7 @@ get_dlpi_ppa(register int fd, register const char *ifname, register u_int unit,
} }
} }
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "Can't find %s", ifname); snprintf(ebuf, PCAP_ERRBUF_SIZE, "Can't find %s", ifname);
return (PCAP_ERROR_NO_SUCH_DEVICE); return (PCAP_ERROR_NO_SUCH_DEVICE);
} }
@@ -1870,7 +1864,7 @@ dlpi_kread(register int fd, register off_t addr,
errno, "read"); errno, "read");
return (-1); return (-1);
} else if (cc != len) { } else if (cc != len) {
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "short read (%d != %d)", cc, snprintf(ebuf, PCAP_ERRBUF_SIZE, "short read (%d != %d)", cc,
len); len);
return (-1); return (-1);
} }
@@ -1886,7 +1880,7 @@ pcap_create_interface(const char *device _U_, char *ebuf)
struct pcap_dlpi *pd; struct pcap_dlpi *pd;
#endif #endif
p = pcap_create_common(ebuf, sizeof (struct pcap_dlpi)); p = PCAP_CREATE_COMMON(ebuf, struct pcap_dlpi);
if (p == NULL) if (p == NULL)
return (NULL); return (NULL);

View File

@@ -153,7 +153,7 @@ pcap_t *pcap_create_interface (const char *device _U_, char *ebuf)
{ {
pcap_t *p; pcap_t *p;
p = pcap_create_common(ebuf, sizeof (struct pcap_dos)); p = PCAP_CREATE_COMMON(ebuf, struct pcap_dos);
if (p == NULL) if (p == NULL)
return (NULL); return (NULL);
@@ -215,7 +215,7 @@ static int pcap_activate_dos (pcap_t *pcap)
} }
else if (stricmp(active_dev->name,pcap->opt.device)) else if (stricmp(active_dev->name,pcap->opt.device))
{ {
pcap_snprintf (pcap->errbuf, PCAP_ERRBUF_SIZE, snprintf (pcap->errbuf, PCAP_ERRBUF_SIZE,
"Cannot use different devices simultaneously " "Cannot use different devices simultaneously "
"(`%s' vs. `%s')", active_dev->name, pcap->opt.device); "(`%s' vs. `%s')", active_dev->name, pcap->opt.device);
/* XXX - free pcap->buffer? */ /* XXX - free pcap->buffer? */
@@ -283,7 +283,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, p->buffer, pcap.len, pcap.caplen))) (!p->fcode.bf_insns || pcap_filter(p->fcode.bf_insns, p->buffer, pcap.len, pcap.caplen)))
{ {
filter_count++; filter_count++;
@@ -539,7 +539,7 @@ int pcap_lookupnet (const char *device, bpf_u_int32 *localnet,
net = IN_CLASSC_NET; net = IN_CLASSC_NET;
else else
{ {
pcap_snprintf (errbuf, PCAP_ERRBUF_SIZE, "inet class for 0x%lx unknown", mask); snprintf (errbuf, PCAP_ERRBUF_SIZE, "inet class for 0x%lx unknown", mask);
return (-1); return (-1);
} }
} }
@@ -667,7 +667,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 */
{ {
pcap_snprintf (ebuf, PCAP_ERRBUF_SIZE, "failed to detect device `%s'", dev_name); 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 */
@@ -689,7 +689,7 @@ open_driver (const char *dev_name, char *ebuf, int promisc)
if (!(*dev->open)(dev)) if (!(*dev->open)(dev))
{ {
pcap_snprintf (ebuf, PCAP_ERRBUF_SIZE, "failed to activate device `%s'", dev_name); 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, ": ");
@@ -698,7 +698,7 @@ open_driver (const char *dev_name, char *ebuf, int promisc)
return (NULL); return (NULL);
} }
/* Some devices need this to operate in promiscous mode /* Some devices need this to operate in promiscuous mode
*/ */
if (promisc && dev->set_multicast_list) if (promisc && dev->set_multicast_list)
(*dev->set_multicast_list) (dev); (*dev->set_multicast_list) (dev);
@@ -711,14 +711,14 @@ open_driver (const char *dev_name, char *ebuf, int promisc)
*/ */
if (!dev) if (!dev)
{ {
pcap_snprintf (ebuf, PCAP_ERRBUF_SIZE, "device `%s' not supported", dev_name); 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)
{ {
pcap_snprintf (ebuf, PCAP_ERRBUF_SIZE, "device `%s' not probed", dev_name); snprintf (ebuf, PCAP_ERRBUF_SIZE, "device `%s' not probed", dev_name);
return (NULL); return (NULL);
} }
return (dev); return (dev);
@@ -943,7 +943,7 @@ static void pcap_init_hook (void)
} }
/* /*
* Supress PRINT message from Watt-32's sock_init() * Suppress PRINT message from Watt-32's sock_init()
*/ */
static void null_print (void) {} static void null_print (void) {}
@@ -1005,7 +1005,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)
{ {
pcap_snprintf (err_buf, PCAP_ERRBUF_SIZE, "sock_init() failed, code %d", rc); snprintf (err_buf, PCAP_ERRBUF_SIZE, "sock_init() failed, code %d", rc);
return (0); return (0);
} }
@@ -1031,11 +1031,9 @@ static int init_watt32 (struct pcap *pcap, const char *dev_name, char *err_buf)
pcap_save.linktype = _eth_get_hwtype (NULL, NULL); pcap_save.linktype = _eth_get_hwtype (NULL, NULL);
pcap_save.snapshot = MTU > 0 ? MTU : ETH_MAX; /* assume 1514 */ pcap_save.snapshot = MTU > 0 ? MTU : ETH_MAX; /* assume 1514 */
#if 1
/* prevent use of resolve() and resolve_ip() /* prevent use of resolve() and resolve_ip()
*/ */
last_nameserver = 0; last_nameserver = 0;
#endif
return (1); return (1);
} }

1070
libpcap/pcap-dpdk.c Normal file

File diff suppressed because it is too large Load Diff

28
libpcap/pcap-dpdk.h Normal file
View File

@@ -0,0 +1,28 @@
/*
* Copyright (C) 2018 jingle YANG. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS''AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
pcap_t *pcap_dpdk_create(const char *, char *, int *);
int pcap_dpdk_findalldevs(pcap_if_list_t *devlistp, char *errbuf);

View File

@@ -75,7 +75,7 @@ readloop(int cnt, int if_fd, struct bpf_program *fp, printfunc printit)
ph = (struct packet_header *)bp; ph = (struct packet_header *)bp;
caplen = ph->tap.th_wirelen > snaplen ? snaplen : ph->tap caplen = ph->tap.th_wirelen > snaplen ? snaplen : ph->tap
.th_wirelen ; .th_wirelen ;
if (bpf_filter(fcode, (char *)ph->packet, if (pcap_filter(fcode, (char *)ph->packet,
ph->tap.th_wirelen, caplen)) { ph->tap.th_wirelen, caplen)) {
if (cnt >= 0 && --cnt < 0) if (cnt >= 0 && --cnt < 0)
goto out; goto out;
@@ -89,7 +89,7 @@ readloop(int cnt, int if_fd, struct bpf_program *fp, printfunc printit)
} }
#else /* !IBMRTPC */ #else /* !IBMRTPC */
caplen = cc > snaplen ? snaplen : cc ; caplen = cc > snaplen ? snaplen : cc ;
if (bpf_filter(fcode, buf.hdr.packet, cc, caplen)) { if (pcap_filter(fcode, buf.hdr.packet, cc, caplen)) {
if (cnt >= 0 && --cnt < 0) if (cnt >= 0 && --cnt < 0)
goto out; goto out;
(*printit)(buf.hdr.packet, &tv, cc, caplen); (*printit)(buf.hdr.packet, &tv, cc, caplen);

View File

@@ -18,22 +18,22 @@
.\" 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@ "5 November 2017" .TH PCAP-FILTER @MAN_MISC_INFO@ "6 February 2021"
.SH NAME .SH NAME
pcap-filter \- packet filter syntax pcap-filter \- packet filter syntax
.br .br
.ad .ad
.SH DESCRIPTION .SH DESCRIPTION
.LP .LP
.B pcap_compile() .BR pcap_compile ()
is used to compile a string into a filter program. is used to compile a string into a filter program.
The resulting filter program can then be applied to The resulting filter program can then be applied to
some stream of packets to determine which packets will be supplied to some stream of packets to determine which packets will be supplied to
.BR pcap_loop(3PCAP) , .BR pcap_loop (3PCAP),
.BR pcap_dispatch(3PCAP) , .BR pcap_dispatch (3PCAP),
.BR pcap_next(3PCAP) , .BR pcap_next (3PCAP),
or or
.BR pcap_next_ex(3PCAP) . .BR pcap_next_ex (3PCAP).
.LP .LP
The \fIfilter expression\fP consists of one or more The \fIfilter expression\fP consists of one or more
.IR primitives . .IR primitives .
@@ -47,11 +47,11 @@ different kinds of qualifier:
qualifiers say what kind of thing the id name or number refers to. qualifiers say what kind of thing the id name or number refers to.
Possible types are Possible types are
.BR host , .BR host ,
.B net , .BR net ,
.B port .B port
and and
.BR portrange . .BR portrange .
E.g., `host foo', `net 128.3', `port 20', `portrange 6000-6008'. E.g., `\fBhost\fP foo', `\fBnet\fP 128.3', `\fBport\fP 20', `\fBportrange\fP 6000-6008'.
If there is no type If there is no type
qualifier, qualifier,
.B host .B host
@@ -72,11 +72,9 @@ Possible directions are
.BR addr3 , .BR addr3 ,
and and
.BR addr4 . .BR addr4 .
E.g., `src foo', `dst net 128.3', `src or dst port ftp-data'. E.g., `\fBsrc\fP foo', `\fBdst net\fP 128.3', `\fBsrc or dst port\fP ftp-data'.
If If
there is no dir qualifier, there is no dir qualifier, `\fBsrc or dst\fP' is assumed.
.B "src or dst"
is assumed.
The The
.BR ra , .BR ra ,
.BR ta , .BR ta ,
@@ -103,25 +101,26 @@ protos are:
.B tcp .B tcp
and and
.BR udp . .BR udp .
E.g., `ether src foo', `arp net 128.3', `tcp port 21', `udp portrange E.g., `\fBether src\fP foo', `\fBarp net\fP 128.3', `\fBtcp port\fP 21',
7000-7009', `wlan addr2 0:2:3:4:5:6'. `\fBudp portrange\fP 7000-7009', `\fBwlan addr2\fP 0:2:3:4:5:6'.
If there is If there is
no proto qualifier, all protocols consistent with the type are no proto qualifier, all protocols consistent with the type are
assumed. assumed.
E.g., `src foo' means `(ip or arp or rarp) src foo' E.g., `\fBsrc\fP foo' means `\fB(ip or arp or rarp) src\fP foo'
(except the latter is not legal syntax), `net bar' means `(ip or (except the latter is not legal syntax), `\fBnet\fP bar' means `\fB(ip or
arp or rarp) net bar' and `port 53' means `(tcp or udp) port 53'. arp or rarp) net\fP bar' and `\fBport\fP 53' means `\fB(tcp or udp)
port\fP 53'.
.LP .LP
[`fddi' is actually an alias for `ether'; the parser treats them [\fBfddi\fP is actually an alias for \fBether\fP; the parser treats them
identically as meaning ``the data link level used on the specified identically as meaning ``the data link level used on the specified
network interface.'' FDDI headers contain Ethernet-like source network interface''. FDDI headers contain Ethernet-like source
and destination addresses, and often contain Ethernet-like packet and destination addresses, and often contain Ethernet-like packet
types, so you can filter on these FDDI fields just as with the types, so you can filter on these FDDI fields just as with the
analogous Ethernet fields. analogous Ethernet fields.
FDDI headers also contain other fields, FDDI headers also contain other fields,
but you cannot name them explicitly in a filter expression. but you cannot name them explicitly in a filter expression.
.LP .LP
Similarly, `tr' and `wlan' are aliases for `ether'; the previous Similarly, \fBtr\fP and \fBwlan\fP are aliases for \fBether\fP; the previous
paragraph's statements about FDDI headers also apply to Token Ring paragraph's statements about FDDI headers also apply to Token Ring
and 802.11 wireless LAN headers. For 802.11 headers, the destination and 802.11 wireless LAN headers. For 802.11 headers, the destination
address is the DA field and the source address is the SA field; the address is the DA field and the source address is the SA field; the
@@ -141,12 +140,13 @@ More complex filter expressions are built up by using the words
.B or .B or
and and
.B not .B not
(or equivalently: `\fB&&\fP', `\fB||\fP' and `\fB!\fP' respectively)
to combine primitives. to combine primitives.
E.g., `host foo and not port ftp and not port ftp-data'. E.g., `\fBhost\fP foo \fBand not port\fP ftp \fBand not port\fP ftp-data'.
To save typing, identical qualifier lists can be omitted. To save typing, identical qualifier lists can be omitted.
E.g., E.g.,
`tcp dst port ftp or ftp-data or domain' is exactly the same as `\fBtcp dst port\fP ftp \fBor\fP ftp-data \fBor\fP domain' is exactly the same as
`tcp dst port ftp or tcp dst port ftp-data or tcp dst port domain'. `\fBtcp dst port\fP ftp \fBor tcp dst port\fP ftp-data \fBor tcp dst port\fP domain'.
.LP .LP
Allowable primitives are: Allowable primitives are:
.IP "\fBdst host \fIhost\fR" .IP "\fBdst host \fIhost\fR"
@@ -167,10 +167,10 @@ Any of the above host expressions can be prepended with the keywords,
which is equivalent to: which is equivalent to:
.in +.5i .in +.5i
.nf .nf
\fBether proto \fI\\ip\fB and host \fIhost\fR \fBether proto \\ip and host \fIhost\fR
.fi .fi
.in -.5i .in -.5i
If \fIhost\fR is a name with multiple IP addresses, each address will If \fIhost\fR is a name with multiple IPv4 addresses, each address will
be checked for a match. be checked for a match.
.IP "\fBether dst \fIehost\fP" .IP "\fBether dst \fIehost\fP"
True if the Ethernet destination address is \fIehost\fP. True if the Ethernet destination address is \fIehost\fP.
@@ -228,25 +228,25 @@ True if the IPv4/v6 address matches \fInet\fR with a netmask \fIlen\fR
bits wide. bits wide.
May be qualified with \fBsrc\fR or \fBdst\fR. May be qualified with \fBsrc\fR or \fBdst\fR.
.IP "\fBdst port \fIport\fR" .IP "\fBdst port \fIport\fR"
True if the packet is ip/tcp, ip/udp, ip6/tcp or ip6/udp and has a True if the packet is IPv4 TCP, IPv4 UDP, IPv6 TCP or IPv6 UDP and has a
destination port value of \fIport\fP. destination port value of \fIport\fP.
The \fIport\fP can be a number or a name used in /etc/services (see The \fIport\fP can be a number or a name used in /etc/services (see
.IR tcp (4P) .BR tcp (4P)
and and
.IR udp (4P)). .BR udp (4P)).
If a name is used, both the port If a name is used, both the port
number and protocol are checked. number and protocol are checked.
If a number or ambiguous name is used, If a number or ambiguous name is used,
only the port number is checked (e.g., \fBdst port 513\fR will print both only the port number is checked (e.g., `\fBdst port\fR 513' will print both
tcp/login traffic and udp/who traffic, and \fBport domain\fR will print tcp/login traffic and udp/who traffic, and `\fBport domain\fR' will print
both tcp/domain and udp/domain traffic). both tcp/domain and udp/domain traffic).
.IP "\fBsrc port \fIport\fR" .IP "\fBsrc port \fIport\fR"
True if the packet has a source port value of \fIport\fP. True if the packet has a source port value of \fIport\fP.
.IP "\fBport \fIport\fR" .IP "\fBport \fIport\fR"
True if either the source or destination port of the packet is \fIport\fP. True if either the source or destination port of the packet is \fIport\fP.
.IP "\fBdst portrange \fIport1\fB-\fIport2\fR" .IP "\fBdst portrange \fIport1-port2\fR"
True if the packet is ip/tcp, ip/udp, ip6/tcp or ip6/udp and has a True if the packet is IPv4 TCP, IPv4 UDP, IPv6 TCP or IPv6 UDP and has a
destination port value between \fIport1\fP and \fIport2\fP. destination port value between \fIport1\fP and \fIport2\fP (both inclusive).
.I port1 .I port1
and and
.I port2 .I port2
@@ -254,12 +254,12 @@ are interpreted in the same fashion as the
.I port .I port
parameter for parameter for
.BR port . .BR port .
.IP "\fBsrc portrange \fIport1\fB-\fIport2\fR" .IP "\fBsrc portrange \fIport1-port2\fR"
True if the packet has a source port value between \fIport1\fP and True if the packet has a source port value between \fIport1\fP and
\fIport2\fP. \fIport2\fP (both inclusive).
.IP "\fBportrange \fIport1\fB-\fIport2\fR" .IP "\fBportrange \fIport1-port2\fR"
True if either the source or destination port of the packet is between True if either the source or destination port of the packet is between
\fIport1\fP and \fIport2\fP. \fIport1\fP and \fIport2\fP (both inclusive).
.IP .IP
Any of the above port or port range expressions can be prepended with Any of the above port or port range expressions can be prepended with
the keywords, \fBtcp\fP or \fBudp\fP, as in: the keywords, \fBtcp\fP or \fBudp\fP, as in:
@@ -268,13 +268,13 @@ the keywords, \fBtcp\fP or \fBudp\fP, as in:
\fBtcp src port \fIport\fR \fBtcp src port \fIport\fR
.fi .fi
.in -.5i .in -.5i
which matches only tcp packets whose source port is \fIport\fP. which matches only TCP packets whose source port is \fIport\fP.
.IP "\fBless \fIlength\fR" .IP "\fBless \fIlength\fR"
True if the packet has a length less than or equal to \fIlength\fP. True if the packet has a length less than or equal to \fIlength\fP.
This is equivalent to: This is equivalent to:
.in +.5i .in +.5i
.nf .nf
\fBlen <= \fIlength\fP. \fBlen <= \fIlength\fP
.fi .fi
.in -.5i .in -.5i
.IP "\fBgreater \fIlength\fR" .IP "\fBgreater \fIlength\fR"
@@ -282,12 +282,12 @@ True if the packet has a length greater than or equal to \fIlength\fP.
This is equivalent to: This is equivalent to:
.in +.5i .in +.5i
.nf .nf
\fBlen >= \fIlength\fP. \fBlen >= \fIlength\fP
.fi .fi
.in -.5i .in -.5i
.IP "\fBip proto \fIprotocol\fR" .IP "\fBip proto \fIprotocol\fR"
True if the packet is an IPv4 packet (see True if the packet is an IPv4 packet (see
.IR ip (4P)) .BR ip (4P))
of protocol type \fIprotocol\fP. 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
\fBicmp\fP, \fBicmp6\fP, \fBigmp\fP, \fBigrp\fP, \fBpim\fP, \fBah\fP, \fBicmp\fP, \fBicmp6\fP, \fBigmp\fP, \fBigrp\fP, \fBpim\fP, \fBah\fP,
@@ -306,10 +306,10 @@ header chain.
Abbreviations for: Abbreviations for:
.in +.5i .in +.5i
.nf .nf
\fBproto \fIp\fR\fB \fBproto \\\fIprotocol\fR\fB
.fi .fi
.in -.5i .in -.5i
where \fIp\fR is one of the above protocols. where \fIprotocol\fR is one of the above protocols.
.IP "\fBip6 protochain \fIprotocol\fR" .IP "\fBip6 protochain \fIprotocol\fR"
True if the packet is IPv6 packet, True if the packet is IPv6 packet,
and contains protocol header with type \fIprotocol\fR and contains protocol header with type \fIprotocol\fR
@@ -317,7 +317,7 @@ in its protocol header chain.
For example, For example,
.in +.5i .in +.5i
.nf .nf
\fBip6 protochain 6\fR \fBip6 protochain\fR 6
.fi .fi
.in -.5i .in -.5i
matches any IPv6 packet with TCP protocol header in the protocol header chain. matches any IPv6 packet with TCP protocol header in the protocol header chain.
@@ -336,7 +336,7 @@ True if the packet is an IPv4 or IPv6 packet of protocol type
header chain. header chain.
.IP "\fBether broadcast\fR" .IP "\fBether broadcast\fR"
True if the packet is an Ethernet broadcast packet. True if the packet is an Ethernet broadcast packet.
The \fIether\fP The \fBether\fP
keyword is optional. keyword is optional.
.IP "\fBip broadcast\fR" .IP "\fBip broadcast\fR"
True if the packet is an IPv4 broadcast packet. True if the packet is an IPv4 broadcast packet.
@@ -353,7 +353,7 @@ check will not work correctly.
True if the packet is an Ethernet multicast packet. True if the packet is an Ethernet multicast packet.
The \fBether\fP The \fBether\fP
keyword is optional. keyword is optional.
This is shorthand for `\fBether[0] & 1 != 0\fP'. This is shorthand for `\fBether[\fP0\fB] & \fP1\fB != \fP0'.
.IP "\fBip multicast\fR" .IP "\fBip multicast\fR"
True if the packet is an IPv4 multicast packet. True if the packet is an IPv4 multicast packet.
.IP "\fBip6 multicast\fR" .IP "\fBip6 multicast\fR"
@@ -361,15 +361,15 @@ True if the packet is an IPv6 multicast packet.
.IP "\fBether proto \fIprotocol\fR" .IP "\fBether proto \fIprotocol\fR"
True if the packet is of ether type \fIprotocol\fR. True if the packet is of ether type \fIprotocol\fR.
\fIProtocol\fP can be a number or one of the names \fIProtocol\fP can be a number or one of the names
\fBip\fP, \fBip6\fP, \fBarp\fP, \fBrarp\fP, \fBatalk\fP, \fBaarp\fP, \fBaarp\fP, \fBarp\fP, \fBatalk\fP, \fBdecnet\fP, \fBip\fP, \fBip6\fP,
\fBdecnet\fP, \fBsca\fP, \fBlat\fP, \fBmopdl\fP, \fBmoprc\fP, \fBipx\fP, \fBiso\fP, \fBlat\fP, \fBloopback\fP, \fBmopdl\fP, \fBmoprc\fP, \fBnetbeui\fP,
\fBiso\fP, \fBstp\fP, \fBipx\fP, or \fBnetbeui\fP. \fBrarp\fP, \fBsca\fP or \fBstp\fP.
Note these identifiers are also keywords Note these identifiers (except \fBloopback\fP) 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 proto arp\fR'), Token Ring [In the case of FDDI (e.g., `\fBfddi proto \\arp\fR'), Token Ring
(e.g., `\fBtr proto arp\fR'), and IEEE 802.11 wireless LANS (e.g., (e.g., `\fBtr proto \\arp\fR'), and IEEE 802.11 wireless LANs (e.g.,
`\fBwlan proto 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.
@@ -419,33 +419,33 @@ IPX, and the IPX etype in a SNAP frame.
Abbreviations for: Abbreviations for:
.in +.5i .in +.5i
.nf .nf
\fBether proto \fIp\fR \fBether proto \\\fIprotocol\fR
.fi .fi
.in -.5i .in -.5i
where \fIp\fR is one of the above protocols. where \fIprotocol\fR is one of the above protocols.
.IP "\fBlat\fR, \fBmoprc\fR, \fBmopdl\fR" .IP "\fBlat\fR, \fBmoprc\fR, \fBmopdl\fR"
Abbreviations for: Abbreviations for:
.in +.5i .in +.5i
.nf .nf
\fBether proto \fIp\fR \fBether proto \\\fIprotocol\fR
.fi .fi
.in -.5i .in -.5i
where \fIp\fR is one of the above protocols. where \fIprotocol\fR is one of the above protocols.
Note that not all applications using Note that not all applications using
.BR pcap (3PCAP) .BR pcap (3PCAP)
currently know how to parse these protocols. currently know how to parse these protocols.
.IP "\fBdecnet src \fIhost\fR" .IP "\fBdecnet src \fIhost\fR"
True if the DECNET source address is True if the DECnet source address is
.IR host , .IR host ,
which may be an address of the form ``10.123'', or a DECNET host which may be an address of the form ``10.123'', or a DECnet host
name. name.
[DECNET host name support is only available on ULTRIX systems [DECnet host name support is only available on ULTRIX systems
that are configured to run DECNET.] that are configured to run DECnet.]
.IP "\fBdecnet dst \fIhost\fR" .IP "\fBdecnet dst \fIhost\fR"
True if the DECNET destination address is True if the DECnet destination address is
.IR host . .IR host .
.IP "\fBdecnet host \fIhost\fR" .IP "\fBdecnet host \fIhost\fR"
True if either the DECNET source or destination address is True if either the DECnet source or destination address is
.IR host . .IR host .
.IP \fBllc\fP .IP \fBllc\fP
True if the packet has an 802.2 LLC header. This includes: True if the packet has an 802.2 LLC header. This includes:
@@ -460,7 +460,7 @@ Token Ring packets (no check is done for LLC frames);
FDDI packets (no check is done for LLC frames); FDDI packets (no check is done for LLC frames);
.IP .IP
LLC-encapsulated ATM packets, for SunATM on Solaris. LLC-encapsulated ATM packets, for SunATM on Solaris.
.IP "\fBllc\fP \Fitype\fR" .IP "\fBllc\fP \fItype\fR"
True if the packet has an 802.2 LLC header and has the specified True if the packet has an 802.2 LLC header and has the specified
.IR type . .IR type .
.I type .I type
@@ -668,51 +668,51 @@ Valid directions are:
or a numeric value. or a numeric value.
.IP "\fBvlan \fI[vlan_id]\fR" .IP "\fBvlan \fI[vlan_id]\fR"
True if the packet is an IEEE 802.1Q VLAN packet. True if the packet is an IEEE 802.1Q VLAN packet.
If \fI[vlan_id]\fR is specified, only true if the packet has the specified If the optional \fIvlan_id\fR is specified, only true if the packet has the specified
\fIvlan_id\fR. \fIvlan_id\fR.
Note that the first \fBvlan\fR keyword encountered in \fIexpression\fR Note that the first \fBvlan\fR keyword encountered in an expression
changes the decoding offsets for the remainder of \fIexpression\fR on changes the decoding offsets for the remainder of the expression on
the assumption that the packet is a VLAN packet. The \fBvlan the assumption that the packet is a VLAN packet. The `\fBvlan
\fI[vlan_id]\fR expression may be used more than once, to filter on VLAN \fI[vlan_id]\fR` keyword may be used more than once, to filter on VLAN
hierarchies. Each use of that expression increments the filter offsets hierarchies. Each use of that keyword increments the filter offsets
by 4. by 4.
.IP .IP
For example: For example:
.in +.5i .in +.5i
.nf .nf
\fBvlan 100 && vlan 200\fR \fBvlan\fP 100 \fB&& vlan\fR 200
.fi .fi
.in -.5i .in -.5i
filters on VLAN 200 encapsulated within VLAN 100, and filters on VLAN 200 encapsulated within VLAN 100, and
.in +.5i .in +.5i
.nf .nf
\fBvlan && vlan 300 && ip\fR \fBvlan && vlan \fP300 \fB&& ip\fR
.fi .fi
.in -.5i .in -.5i
filters IPv4 protocols encapsulated in VLAN 300 encapsulated within any filters IPv4 protocol encapsulated in VLAN 300 encapsulated within any
higher order VLAN. higher order VLAN.
.IP "\fBmpls \fI[label_num]\fR" .IP "\fBmpls \fI[label_num]\fR"
True if the packet is an MPLS packet. True if the packet is an MPLS packet.
If \fI[label_num]\fR is specified, only true is the packet has the specified If the optional \fIlabel_num\fR is specified, only true if the packet has the specified
\fIlabel_num\fR. \fIlabel_num\fR.
Note that the first \fBmpls\fR keyword encountered in \fIexpression\fR Note that the first \fBmpls\fR keyword encountered in an expression
changes the decoding offsets for the remainder of \fIexpression\fR on changes the decoding offsets for the remainder of the expression 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` keyword 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 keyword increments the
filter offsets by 4. filter offsets by 4.
.IP .IP
For example: For example:
.in +.5i .in +.5i
.nf .nf
\fBmpls 100000 && mpls 1024\fR \fBmpls\fP 100000 \fB&& mpls\fR 1024
.fi .fi
.in -.5i .in -.5i
filters packets with an outer label of 100000 and an inner label of filters packets with an outer label of 100000 and an inner label of
1024, and 1024, and
.in +.5i .in +.5i
.nf .nf
\fBmpls && mpls 1024 && host 192.9.200.1\fR \fBmpls && mpls\fP 1024 \fB&& host\fR 192.9.200.1
.fi .fi
.in -.5i .in -.5i
filters packets to or from 192.9.200.1 with an inner label of 1024 and filters packets to or from 192.9.200.1 with an inner label of 1024 and
@@ -723,34 +723,34 @@ type 0x8863).
.IP "\fBpppoes \fI[session_id]\fR" .IP "\fBpppoes \fI[session_id]\fR"
True if the packet is a PPP-over-Ethernet Session packet (Ethernet True if the packet is a PPP-over-Ethernet Session packet (Ethernet
type 0x8864). type 0x8864).
If \fI[session_id]\fR is specified, only true if the packet has the specified If the optional \fIsession_id\fR is specified, only true if the packet has the specified
\fIsession_id\fR. \fIsession_id\fR.
Note that the first \fBpppoes\fR keyword encountered in \fIexpression\fR Note that the first \fBpppoes\fR keyword encountered in an expression
changes the decoding offsets for the remainder of \fIexpression\fR on changes the decoding offsets for the remainder of the expression on
the assumption that the packet is a PPPoE session packet. the assumption that the packet is a PPPoE session packet.
.IP .IP
For example: For example:
.in +.5i .in +.5i
.nf .nf
\fBpppoes 0x27 && ip\fR \fBpppoes\fP 0x27 \fB&& ip\fR
.fi .fi
.in -.5i .in -.5i
filters IPv4 protocols encapsulated in PPPoE session id 0x27. filters IPv4 protocol encapsulated in PPPoE session id 0x27.
.IP "\fBgeneve \fI[vni]\fR" .IP "\fBgeneve \fI[vni]\fR"
True if the packet is a Geneve packet (UDP port 6081). If \fI[vni]\fR True if the packet is a Geneve packet (UDP port 6081). If the optional \fIvni\fR
is specified, only true if the packet has the specified \fIvni\fR. is specified, only true if the packet has the specified \fIvni\fR.
Note that when the \fBgeneve\fR keyword is encountered in Note that when the \fBgeneve\fR keyword is encountered in
\fIexpression\fR, it changes the decoding offsets for the remainder of an expression, it changes the decoding offsets for the remainder of
\fIexpression\fR on the assumption that the packet is a Geneve packet. the expression on the assumption that the packet is a Geneve packet.
.IP .IP
For example: For example:
.in +.5i .in +.5i
.nf .nf
\fBgeneve 0xb && ip\fR \fBgeneve\fP 0xb \fB&& ip\fR
.fi .fi
.in -.5i .in -.5i
filters IPv4 protocols encapsulated in Geneve with VNI 0xb. This will filters IPv4 protocol encapsulated in Geneve with VNI 0xb. This will
match both IP directly encapsulated in Geneve as well as IP contained match both IPv4 directly encapsulated in Geneve as well as IPv4 contained
inside an Ethernet frame. 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.
@@ -760,10 +760,10 @@ True if the packet is an OSI packet of protocol type \fIprotocol\fP.
Abbreviations for: Abbreviations for:
.in +.5i .in +.5i
.nf .nf
\fBiso proto \fIp\fR \fBiso proto \\\fIprotocol\fR
.fi .fi
.in -.5i .in -.5i
where \fIp\fR is one of the above protocols. where \fIprotocol\fR is one of the above protocols.
.IP "\fBl1\fR, \fBl2\fR, \fBiih\fR, \fBlsp\fR, \fBsnp\fR, \fBcsnp\fR, \fBpsnp\fR" .IP "\fBl1\fR, \fBl2\fR, \fBiih\fR, \fBlsp\fR, \fBsnp\fR, \fBcsnp\fR, \fBpsnp\fR"
Abbreviations for IS-IS PDU types. Abbreviations for IS-IS PDU types.
.IP "\fBvpi\fP \fIn\fR" .IP "\fBvpi\fP \fIn\fR"
@@ -777,8 +777,8 @@ virtual channel identifier of
.IP \fBlane\fP .IP \fBlane\fP
True if the packet is an ATM packet, for SunATM on Solaris, and is True if the packet is an ATM packet, for SunATM on Solaris, and is
an ATM LANE packet. an ATM LANE packet.
Note that the first \fBlane\fR keyword encountered in \fIexpression\fR Note that the first \fBlane\fR keyword encountered in an expression
changes the tests done in the remainder of \fIexpression\fR changes the tests done in the remainder of the expression
on the assumption that the packet is either a LANE emulated Ethernet on the assumption that the packet is either a LANE emulated Ethernet
packet or a LANE LE Control packet. If \fBlane\fR isn't specified, the packet or a LANE LE Control packet. If \fBlane\fR isn't specified, the
tests are done under the assumption that the packet is an tests are done under the assumption that the packet is an
@@ -841,7 +841,7 @@ indicates the protocol layer for the index operation.
(\fBether, fddi, wlan, tr, ppp, slip\fR and \fBlink\fR all refer to the (\fBether, fddi, wlan, tr, ppp, slip\fR and \fBlink\fR all refer to the
link layer. \fBradio\fR refers to the "radio header" added to some link layer. \fBradio\fR refers to the "radio header" added to some
802.11 captures.) 802.11 captures.)
Note that \fItcp, udp\fR and other upper-layer protocol types only Note that \fBtcp\fR, \fBudp\fR and other upper-layer protocol types only
apply to IPv4, not IPv6 (this will be fixed in the future). apply to IPv4, not IPv6 (this will be fixed in the future).
The byte offset, relative to the indicated protocol layer, is The byte offset, relative to the indicated protocol layer, is
given by \fIexpr\fR. given by \fIexpr\fR.
@@ -850,24 +850,24 @@ field of interest; it can be either one, two, or four, and defaults to one.
The length operator, indicated by the keyword \fBlen\fP, gives the The length operator, indicated by the keyword \fBlen\fP, gives the
length of the packet. length of the packet.
For example, `\fBether[0] & 1 != 0\fP' catches all multicast traffic. For example, `\fBether[\fP0\fB] &\fP 1 \fB!=\fP 0' catches all multicast traffic.
The expression `\fBip[0] & 0xf != 5\fP' The expression `\fBip[\fP0\fB] &\fP 0xf \fB!=\fP 5'
catches all IPv4 packets with options. catches all IPv4 packets with options.
The expression The expression
`\fBip[6:2] & 0x1fff = 0\fP' `\fBip[\fP6:2\fB] &\fP 0x1fff \fB=\fP 0'
catches only unfragmented IPv4 datagrams and frag zero of fragmented catches only unfragmented IPv4 datagrams and frag zero of fragmented
IPv4 datagrams. IPv4 datagrams.
This check is implicitly applied to the \fBtcp\fP and \fBudp\fP This check is implicitly applied to the \fBtcp\fP and \fBudp\fP
index operations. index operations.
For instance, \fBtcp[0]\fP always means the first For instance, \fBtcp[\fP0\fB]\fP always means the first
byte of the TCP \fIheader\fP, and never means the first byte of an byte of the TCP \fIheader\fP, and never means the first byte of an
intervening fragment. intervening fragment.
Some offsets and field values may be expressed as names rather than Some offsets and field values may be expressed as names rather than
as numeric values. as numeric values.
The following protocol header field offsets are The following protocol header field offsets are
available: \fBicmptype\fP (ICMP type field), \fBicmp6type (ICMP v6 type field) available: \fBicmptype\fP (ICMP type field), \fBicmp6type\fP (ICMPv6 type field),
\fBicmpcode\fP (ICMP code field), \fBicmp6code\fP (ICMP v6 code field), and \fBicmpcode\fP (ICMP code field), \fBicmp6code\fP (ICMPv6 code field) and
\fBtcpflags\fP (TCP flags field). \fBtcpflags\fP (TCP flags field).
The following ICMP type field values are available: \fBicmp-echoreply\fP, The following ICMP type field values are available: \fBicmp-echoreply\fP,
@@ -877,7 +877,9 @@ The following ICMP type field values are available: \fBicmp-echoreply\fP,
\fBicmp-tstampreply\fP, \fBicmp-ireq\fP, \fBicmp-ireqreply\fP, \fBicmp-tstampreply\fP, \fBicmp-ireq\fP, \fBicmp-ireqreply\fP,
\fBicmp-maskreq\fP, \fBicmp-maskreply\fP. \fBicmp-maskreq\fP, \fBicmp-maskreply\fP.
The following ICMPv6 type fields are available: \fBicmp6-echo\fP, The following ICMPv6 type fields are available: \fBicmp6-destinationrunreach\fP,
\fBicmp6-packettoobig\fP, \fBicmp6-timeexceeded\fP,
\fBicmp6-parameterproblem\fP, \fBicmp6-echo\fP,
\fBicmp6-echoreply\fP, \fBicmp6-multicastlistenerquery\fP, \fBicmp6-echoreply\fP, \fBicmp6-multicastlistenerquery\fP,
\fBicmp6-multicastlistenerreportv1\fP, \fBicmp6-multicastlistenerdone\fP, \fBicmp6-multicastlistenerreportv1\fP, \fBicmp6-multicastlistenerdone\fP,
\fBicmp6-routersolicit\fP, \fBicmp6-routeradvert\fP, \fBicmp6-routersolicit\fP, \fBicmp6-routeradvert\fP,
@@ -906,7 +908,7 @@ Concatenation (`\fB&&\fP' or `\fBand\fP').
.IP .IP
Alternation (`\fB||\fP' or `\fBor\fP'). Alternation (`\fB||\fP' or `\fBor\fP').
.LP .LP
Negation has highest precedence. Negation has the highest precedence.
Alternation and concatenation have equal precedence and associate Alternation and concatenation have equal precedence and associate
left to right. left to right.
Note that explicit \fBand\fR tokens, not juxtaposition, Note that explicit \fBand\fR tokens, not juxtaposition,
@@ -917,67 +919,64 @@ is assumed.
For example, For example,
.in +.5i .in +.5i
.nf .nf
\fBnot host vs and ace\fR \fBnot host\fP vs \fBand\fR ace
.fi .fi
.in -.5i .in -.5i
is short for is short for
.in +.5i .in +.5i
.nf .nf
\fBnot host vs and host ace\fR \fBnot host\fP vs \fBand host\fR ace
.fi .fi
.in -.5i .in -.5i
which should not be confused with which should not be confused with
.in +.5i .in +.5i
.nf .nf
\fBnot ( host vs or ace )\fR \fBnot (host \fPvs\fB or \fPace\fB)\fR
.fi .fi
.in -.5i .in -.5i
.SH EXAMPLES .SH EXAMPLES
.LP .LP
To select all packets arriving at or departing from \fIsundown\fP: To select all packets arriving at or departing from `sundown':
.RS .RS
.nf .nf
\fBhost sundown\fP \fBhost\fP sundown
.fi .fi
.RE .RE
.LP .LP
To select traffic between \fIhelios\fR and either \fIhot\fR or \fIace\fR: To select traffic between `helios' and either `hot' or `ace':
.RS .RS
.nf .nf
\fBhost helios and \\( hot or ace \\)\fP \fBhost\fP helios \fBand (\fPhot \fBor\fP ace\fB)\fP
.fi .fi
.RE .RE
.LP .LP
To select all IP packets between \fIace\fR and any host except \fIhelios\fR: To select all IPv4 packets between `ace' and any host except `helios':
.RS .RS
.nf .nf
\fBip host ace and not helios\fP \fBip host\fP ace \fBand not\fP helios
.fi .fi
.RE .RE
.LP .LP
To select all traffic between local hosts and hosts at Berkeley: To select all traffic between local hosts and hosts at Berkeley:
.RS .RS
.nf .nf
.B \fBnet\fP ucb-ether
net ucb-ether
.fi .fi
.RE .RE
.LP .LP
To select all ftp traffic through internet gateway \fIsnup\fP: To select all FTP traffic through Internet gateway `snup':
.RS .RS
.nf .nf
.B \fBgateway\fP snup \fBand (port\fP ftp \fBor\fP ftp-data\fB)\fP
gateway snup and (port ftp or ftp-data)
.fi .fi
.RE .RE
.LP .LP
To select traffic neither sourced from nor destined for local hosts To select IPv4 traffic neither sourced from nor destined for local hosts
(if you gateway to one other net, this stuff should never make it (if you gateway to one other net, this stuff should never make it
onto your local net). onto your local net).
.RS .RS
.nf .nf
.B \fBip and not net \fPlocalnet
ip and not net \fIlocalnet\fP
.fi .fi
.RE .RE
.LP .LP
@@ -985,8 +984,17 @@ To select the start and end packets (the SYN and FIN packets) of each
TCP conversation that involves a non-local host. TCP conversation that involves a non-local host.
.RS .RS
.nf .nf
\fBtcp[tcpflags] & (tcp-syn|tcp-fin) !=\fP 0 \fBand not src and dst net\fP localnet
.fi
.RE
.LP
To select the TCP packets with flags RST and ACK both set.
(i.e. select only the RST and ACK flags in the flags field, and if the result
is "RST and ACK both set", match)
.RS
.nf
.B .B
tcp[tcpflags] & (tcp-syn|tcp-fin) != 0 and not src and dst net \fIlocalnet\fP tcp[tcpflags] & (tcp-rst|tcp-ack) == (tcp-rst|tcp-ack)
.fi .fi
.RE .RE
.LP .LP
@@ -995,26 +1003,23 @@ packets that contain data, not, for example, SYN and FIN packets and
ACK-only packets. (IPv6 is left as an exercise for the reader.) ACK-only packets. (IPv6 is left as an exercise for the reader.)
.RS .RS
.nf .nf
.B \fBtcp port\fP 80 \fBand (((ip[\fP2:2\fB] - ((ip[\fP0\fB]&\fP0xf\fB)<<\fP2\fB)) - ((tcp[\fP12\fB]&\fP0xf0\fB)>>\fP2\fB)) != \fP0\fB)
tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)
.fi .fi
.RE .RE
.LP .LP
To select IP packets longer than 576 bytes sent through gateway \fIsnup\fP: To select IPv4 packets longer than 576 bytes sent through gateway `snup':
.RS .RS
.nf .nf
.B \fBgateway\fP snup \fBand ip[\fP2:2\fB] >\fP 576
gateway snup and ip[2:2] > 576
.fi .fi
.RE .RE
.LP .LP
To select IP broadcast or multicast packets that were To select IPv4 broadcast or multicast packets that were
.I not .I not
sent via Ethernet broadcast or multicast: sent via Ethernet broadcast or multicast:
.RS .RS
.nf .nf
.B \fBether[\fP0\fB] &\fP 1 \fB=\fP 0 \fBand ip[\fP16\fB] >=\fP 224
ether[0] & 1 = 0 and ip[16] >= 224
.fi .fi
.RE .RE
.LP .LP
@@ -1024,16 +1029,18 @@ ping packets):
.nf .nf
.B .B
icmp[icmptype] != icmp-echo and icmp[icmptype] != icmp-echoreply icmp[icmptype] != icmp-echo and icmp[icmptype] != icmp-echoreply
.B
icmp6[icmp6type] != icmp6-echo and icmp6[icmp6type] != icmp6-echoreply
.fi .fi
.RE .RE
.SH "SEE ALSO" .SH "SEE ALSO"
pcap(3PCAP) .BR pcap (3PCAP)
.SH BUGS .SH BUGS
To report a security issue please send an e-mail to security@tcpdump.org. To report a security issue please send an e-mail to security@tcpdump.org.
.LP .LP
To report bugs and other problems, contribute patches, request a To report bugs and other problems, contribute patches, request a
feature, provide generic feedback etc please see the file feature, provide generic feedback etc please see the file
.I CONTRIBUTING .I CONTRIBUTING.md
in the libpcap source tree root. in the libpcap source tree root.
.LP .LP
Filter expressions on fields other than those in Token Ring headers will Filter expressions on fields other than those in Token Ring headers will
@@ -1042,10 +1049,11 @@ not correctly handle source-routed Token Ring packets.
Filter expressions on fields other than those in 802.11 headers will not Filter expressions on fields other than those in 802.11 headers will not
correctly handle 802.11 data packets with both To DS and From DS set. correctly handle 802.11 data packets with both To DS and From DS set.
.LP .LP
.BR "ip6 proto" `\fBip6 proto\fP'
should chase header chain, but at this moment it does not. should chase header chain, but at this moment it does not.
.BR "ip6 protochain" `\fBip6 protochain\fP'
is supplied for this behavior. is supplied for this behavior. For example, to match IPv6 fragments:
`\fBip6 protochain\fP 44'
.LP .LP
Arithmetic expression against transport layer headers, like \fBtcp[0]\fP, Arithmetic expression against transport layer headers, like \fBtcp[0]\fP,
does not work against IPv6 packets. does not work against IPv6 packets.

282
libpcap/pcap-haiku.cpp Normal file
View File

@@ -0,0 +1,282 @@
/*
* Copyright 2006-2010, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Axel Dörfler, axeld@pinc-software.de
* James Woodcock
*/
#include "config.h"
#include "pcap-int.h"
#include <OS.h>
#include <sys/socket.h>
#include <sys/sockio.h>
#include <net/if.h>
#include <net/if_dl.h>
#include <net/if_types.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
* Private data for capturing on Haiku sockets.
*/
struct pcap_haiku {
struct pcap_stat stat;
char *device; /* device name */
};
bool
prepare_request(struct ifreq& request, const char* name)
{
if (strlen(name) >= IF_NAMESIZE)
return false;
strcpy(request.ifr_name, name);
return true;
}
static int
pcap_read_haiku(pcap_t* handle, int maxPackets, pcap_handler callback,
u_char* userdata)
{
// Receive a single packet
struct pcap_haiku* handlep = (struct pcap_haiku*)handle->priv;
u_char* buffer = (u_char*)handle->buffer + handle->offset;
struct sockaddr_dl from;
ssize_t bytesReceived;
do {
if (handle->break_loop) {
// Clear the break loop flag, and return -2 to indicate our
// reasoning
handle->break_loop = 0;
return -2;
}
socklen_t fromLength = sizeof(from);
bytesReceived = recvfrom(handle->fd, buffer, handle->bufsize, MSG_TRUNC,
(struct sockaddr*)&from, &fromLength);
} while (bytesReceived < 0 && errno == B_INTERRUPTED);
if (bytesReceived < 0) {
if (errno == B_WOULD_BLOCK) {
// there is no packet for us
return 0;
}
snprintf(handle->errbuf, sizeof(handle->errbuf),
"recvfrom: %s", strerror(errno));
return -1;
}
int32 captureLength = bytesReceived;
if (captureLength > handle->snapshot)
captureLength = handle->snapshot;
// run the packet filter
if (handle->fcode.bf_insns) {
if (pcap_filter(handle->fcode.bf_insns, buffer, bytesReceived,
captureLength) == 0) {
// packet got rejected
return 0;
}
}
// fill in pcap_header
pcap_pkthdr header;
header.caplen = captureLength;
header.len = bytesReceived;
header.ts.tv_usec = system_time() % 1000000;
header.ts.tv_sec = system_time() / 1000000;
// TODO: get timing from packet!!!
/* Call the user supplied callback function */
callback(userdata, &header, buffer);
return 1;
}
static int
pcap_inject_haiku(pcap_t *handle, const void *buffer, int size)
{
// we don't support injecting packets yet
// TODO: use the AF_LINK protocol (we need another socket for this) to
// inject the packets
strlcpy(handle->errbuf, "Sending packets isn't supported yet",
PCAP_ERRBUF_SIZE);
return -1;
}
static int
pcap_stats_haiku(pcap_t *handle, struct pcap_stat *stats)
{
struct pcap_haiku* handlep = (struct pcap_haiku*)handle->priv;
ifreq request;
int socket = ::socket(AF_INET, SOCK_DGRAM, 0);
if (socket < 0) {
return -1;
}
prepare_request(request, handlep->device);
if (ioctl(socket, SIOCGIFSTATS, &request, sizeof(struct ifreq)) < 0) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "pcap_stats: %s",
strerror(errno));
close(socket);
return -1;
}
close(socket);
handlep->stat.ps_recv += request.ifr_stats.receive.packets;
handlep->stat.ps_drop += request.ifr_stats.receive.dropped;
*stats = handlep->stat;
return 0;
}
static int
pcap_activate_haiku(pcap_t *handle)
{
struct pcap_haiku* handlep = (struct pcap_haiku*)handle->priv;
const char* device = handle->opt.device;
handle->read_op = pcap_read_haiku;
handle->setfilter_op = install_bpf_program; /* no kernel filtering */
handle->inject_op = pcap_inject_haiku;
handle->stats_op = pcap_stats_haiku;
// use default hooks where possible
handle->getnonblock_op = pcap_getnonblock_fd;
handle->setnonblock_op = pcap_setnonblock_fd;
handlep->device = strdup(device);
if (handlep->device == NULL) {
pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
errno, "strdup");
return PCAP_ERROR;
}
handle->bufsize = 65536;
// TODO: should be determined by interface MTU
// allocate buffer for monitoring the device
handle->buffer = (u_char*)malloc(handle->bufsize);
if (handle->buffer == NULL) {
pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
errno, "buffer malloc");
return PCAP_ERROR;
}
handle->offset = 0;
handle->linktype = DLT_EN10MB;
// TODO: check interface type!
return 0;
}
// #pragma mark - pcap API
extern "C" pcap_t *
pcap_create_interface(const char *device, char *errorBuffer)
{
// TODO: handle promiscuous mode!
// we need a socket to talk to the networking stack
int socket = ::socket(AF_INET, SOCK_DGRAM, 0);
if (socket < 0) {
snprintf(errorBuffer, PCAP_ERRBUF_SIZE,
"The networking stack doesn't seem to be available.\n");
return NULL;
}
struct ifreq request;
if (!prepare_request(request, device)) {
snprintf(errorBuffer, PCAP_ERRBUF_SIZE,
"Interface name \"%s\" is too long.", device);
close(socket);
return NULL;
}
// check if the interface exist
if (ioctl(socket, SIOCGIFINDEX, &request, sizeof(request)) < 0) {
snprintf(errorBuffer, PCAP_ERRBUF_SIZE,
"Interface \"%s\" does not exist.\n", device);
close(socket);
return NULL;
}
close(socket);
// no longer needed after this point
// get link level interface for this interface
socket = ::socket(AF_LINK, SOCK_DGRAM, 0);
if (socket < 0) {
snprintf(errorBuffer, PCAP_ERRBUF_SIZE, "No link level: %s\n",
strerror(errno));
return NULL;
}
// start monitoring
if (ioctl(socket, SIOCSPACKETCAP, &request, sizeof(struct ifreq)) < 0) {
snprintf(errorBuffer, PCAP_ERRBUF_SIZE, "Cannot start monitoring: %s\n",
strerror(errno));
close(socket);
return NULL;
}
pcap_t* handle = PCAP_CREATE_COMMON(errorBuffer, struct pcap_haiku);
if (handle == NULL) {
snprintf(errorBuffer, PCAP_ERRBUF_SIZE, "malloc: %s", strerror(errno));
close(socket);
return NULL;
}
handle->selectable_fd = socket;
handle->fd = socket;
handle->activate_op = pcap_activate_haiku;
return handle;
}
static int
can_be_bound(const char *name)
{
return 1;
}
static int
get_if_flags(const char *name, bpf_u_int32 *flags, char *errbuf)
{
/* TODO */
if (*flags & PCAP_IF_LOOPBACK) {
/*
* Loopback devices aren't wireless, and "connected"/
* "disconnected" doesn't apply to them.
*/
*flags |= PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE;
return (0);
}
return (0);
}
extern "C" int
pcap_platform_finddevs(pcap_if_list_t* _allDevices, char* errorBuffer)
{
return pcap_findalldevs_interfaces(_allDevices, errorBuffer, can_be_bound,
get_if_flags);
}

View File

@@ -34,13 +34,24 @@
#ifndef pcap_int_h #ifndef pcap_int_h
#define pcap_int_h #define pcap_int_h
#include <stddef.h>
#include <signal.h> #include <signal.h>
#include <pcap/pcap.h> #include <pcap/pcap.h>
#ifdef MSDOS
#include <fcntl.h>
#include <io.h>
#endif
#include "varattrs.h" #include "varattrs.h"
#include "fmtutils.h" #include "fmtutils.h"
#include <stdarg.h>
#include "portability.h"
/* /*
* Version string. * Version string.
* Uses PACKAGE_VERSION from config.h. * Uses PACKAGE_VERSION from config.h.
@@ -51,10 +62,32 @@
extern "C" { extern "C" {
#endif #endif
#ifdef MSDOS /*
#include <fcntl.h> * If pcap_new_api is set, we disable pcap_lookupdev(), because:
#include <io.h> *
#endif * it's not thread-safe, and is marked as deprecated, on all
* platforms;
*
* on Windows, it may return UTF-16LE strings, which the program
* might then pass to pcap_create() (or to pcap_open_live(), which
* then passes them to pcap_create()), requiring pcap_create() to
* check for UTF-16LE strings using a hack, and that hack 1)
* *cannot* be 100% reliable and 2) runs the risk of going past the
* end of the string.
*
* We keep it around in legacy mode for compatibility.
*
* We also disable the aforementioned hack in pcap_create().
*/
extern int pcap_new_api;
/*
* If pcap_utf_8_mode is set, on Windows we treat strings as UTF-8.
*
* On UN*Xes, we assume all strings are and should be in UTF-8, regardless
* of the setting of this flag.
*/
extern int pcap_utf_8_mode;
/* /*
* Swap byte ordering of unsigned long long timestamp on a big endian * Swap byte ordering of unsigned long long timestamp on a big endian
@@ -77,7 +110,7 @@ extern "C" {
* 1) big enough for maximum-size Linux loopback packets (65549) * 1) big enough for maximum-size Linux loopback packets (65549)
* and some USB packets captured with USBPcap: * and some USB packets captured with USBPcap:
* *
* http://desowin.org/usbpcap/ * https://desowin.org/usbpcap/
* *
* (> 131072, < 262144) * (> 131072, < 262144)
* *
@@ -97,6 +130,18 @@ extern "C" {
*/ */
#define MAXIMUM_SNAPLEN 262144 #define MAXIMUM_SNAPLEN 262144
/*
* Locale-independent macros for testing character types.
* These can be passed any integral value, without worrying about, for
* example, sign-extending char values, unlike the C macros.
*/
#define PCAP_ISDIGIT(c) \
((c) >= '0' && (c) <= '9')
#define PCAP_ISXDIGIT(c) \
(((c) >= '0' && (c) <= '9') || \
((c) >= 'A' && (c) <= 'F') || \
((c) >= 'a' && (c) <= 'f'))
struct pcap_opt { struct pcap_opt {
char *device; char *device;
int timeout; /* timeout for buffering */ int timeout; /* timeout for buffering */
@@ -123,7 +168,7 @@ typedef int (*activate_op_t)(pcap_t *);
typedef int (*can_set_rfmon_op_t)(pcap_t *); typedef int (*can_set_rfmon_op_t)(pcap_t *);
typedef int (*read_op_t)(pcap_t *, int cnt, pcap_handler, u_char *); typedef int (*read_op_t)(pcap_t *, int cnt, pcap_handler, u_char *);
typedef int (*next_packet_op_t)(pcap_t *, struct pcap_pkthdr *, u_char **); typedef int (*next_packet_op_t)(pcap_t *, struct pcap_pkthdr *, u_char **);
typedef int (*inject_op_t)(pcap_t *, const void *, size_t); typedef int (*inject_op_t)(pcap_t *, const void *, int);
typedef void (*save_current_filter_op_t)(pcap_t *, const char *); typedef void (*save_current_filter_op_t)(pcap_t *, const char *);
typedef int (*setfilter_op_t)(pcap_t *, struct bpf_program *); typedef int (*setfilter_op_t)(pcap_t *, struct bpf_program *);
typedef int (*setdirection_op_t)(pcap_t *, pcap_direction_t); typedef int (*setdirection_op_t)(pcap_t *, pcap_direction_t);
@@ -131,6 +176,7 @@ typedef int (*set_datalink_op_t)(pcap_t *, int);
typedef int (*getnonblock_op_t)(pcap_t *); typedef int (*getnonblock_op_t)(pcap_t *);
typedef int (*setnonblock_op_t)(pcap_t *, int); typedef int (*setnonblock_op_t)(pcap_t *, int);
typedef int (*stats_op_t)(pcap_t *, struct pcap_stat *); typedef int (*stats_op_t)(pcap_t *, struct pcap_stat *);
typedef void (*breakloop_op_t)(pcap_t *);
#ifdef _WIN32 #ifdef _WIN32
typedef struct pcap_stat *(*stats_ex_op_t)(pcap_t *, int *); 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);
@@ -200,8 +246,7 @@ struct pcap {
int snapshot; int snapshot;
int linktype; /* Network linktype */ int linktype; /* Network linktype */
int linktype_ext; /* Extended information stored in the linktype field of a file */ int linktype_ext; /* Extended information stored in the linktype field of a file */
int tzoff; /* timezone offset */
int offset; /* offset for proper alignment */ int offset; /* offset for proper alignment */
int activated; /* true if the capture is really started */ int activated; /* true if the capture is really started */
int oldstyle; /* if we're opening with pcap_open_live() */ int oldstyle; /* if we're opening with pcap_open_live() */
@@ -239,7 +284,7 @@ struct pcap {
* pcap_t's with a required timeout, and the code must be * pcap_t's with a required timeout, and the code must be
* prepared not to see any packets from the attempt. * prepared not to see any packets from the attempt.
*/ */
struct timeval *required_select_timeout; const struct timeval *required_select_timeout;
#endif #endif
/* /*
@@ -248,6 +293,9 @@ struct pcap {
struct bpf_program fcode; struct bpf_program fcode;
char errbuf[PCAP_ERRBUF_SIZE + 1]; char errbuf[PCAP_ERRBUF_SIZE + 1];
#ifdef _WIN32
char acp_errbuf[PCAP_ERRBUF_SIZE + 1]; /* buffer for local code page error strings */
#endif
int dlt_count; int dlt_count;
u_int *dlt_list; u_int *dlt_list;
int tstamp_type_count; int tstamp_type_count;
@@ -270,6 +318,7 @@ struct pcap {
getnonblock_op_t getnonblock_op; getnonblock_op_t getnonblock_op;
setnonblock_op_t setnonblock_op; setnonblock_op_t setnonblock_op;
stats_op_t stats_op; stats_op_t stats_op;
breakloop_op_t breakloop_op;
/* /*
* Routine to use as callback for pcap_next()/pcap_next_ex(). * Routine to use as callback for pcap_next()/pcap_next_ex().
@@ -340,7 +389,7 @@ struct pcap_timeval {
* *
* Then supply the changes by forking the branch at * Then supply the changes by forking the branch at
* *
* https://github.com/the-tcpdump-group/libpcap/issues * https://github.com/the-tcpdump-group/libpcap/tree/master
* *
* and issuing a pull request, so that future versions of libpcap and * and issuing a pull request, so that future versions of libpcap and
* programs that use it (such as tcpdump) will be able to read your new * programs that use it (such as tcpdump) will be able to read your new
@@ -350,7 +399,7 @@ struct pcap_timeval {
struct pcap_sf_pkthdr { struct pcap_sf_pkthdr {
struct pcap_timeval ts; /* time stamp */ struct pcap_timeval ts; /* time stamp */
bpf_u_int32 caplen; /* length of portion present */ bpf_u_int32 caplen; /* length of portion present */
bpf_u_int32 len; /* length this packet (off wire) */ bpf_u_int32 len; /* length of this packet (off wire) */
}; };
/* /*
@@ -366,7 +415,7 @@ struct pcap_sf_pkthdr {
struct pcap_sf_patched_pkthdr { struct pcap_sf_patched_pkthdr {
struct pcap_timeval ts; /* time stamp */ struct pcap_timeval ts; /* time stamp */
bpf_u_int32 caplen; /* length of portion present */ bpf_u_int32 caplen; /* length of portion present */
bpf_u_int32 len; /* length this packet (off wire) */ bpf_u_int32 len; /* length of this packet (off wire) */
int index; int index;
unsigned short protocol; unsigned short protocol;
unsigned char pkt_type; unsigned char pkt_type;
@@ -388,10 +437,6 @@ struct oneshot_userdata {
int pcap_offline_read(pcap_t *, int, pcap_handler, u_char *); int pcap_offline_read(pcap_t *, int, pcap_handler, u_char *);
#include <stdarg.h>
#include "portability.h"
/* /*
* Does the packet count argument to a module's read routine say * Does the packet count argument to a module's read routine say
* "supply packets until you run out of packets"? * "supply packets until you run out of packets"?
@@ -418,12 +463,25 @@ int pcap_setnonblock_fd(pcap_t *p, int);
* 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(char *, size_t);
/*
* This wrapper takes an error buffer pointer and a type to use for the
* private data, and calls pcap_create_common(), passing it the error
* buffer pointer, the size fo the private data type, in bytes, and the
* offset of the private data from the beginning of the structure, in
* bytes.
*/
#define PCAP_CREATE_COMMON(ebuf, type) \
pcap_create_common(ebuf, \
sizeof (struct { pcap_t __common; type __private; }), \
offsetof (struct { pcap_t __common; type __private; }, __private))
pcap_t *pcap_create_common(char *, size_t, 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_check_activated(pcap_t *); int pcap_check_activated(pcap_t *);
void pcap_breakloop_common(pcap_t *);
/* /*
* Internal interfaces for "pcap_findalldevs()". * Internal interfaces for "pcap_findalldevs()".
@@ -472,7 +530,8 @@ int add_addr_to_if(pcap_if_list_t *, const char *, bpf_u_int32,
#endif #endif
/* /*
* Internal interfaces for "pcap_open_offline()". * Internal interfaces for "pcap_open_offline()" and other savefile
* I/O routines.
* *
* "pcap_open_offline_common()" allocates and fills in a pcap_t, for use * "pcap_open_offline_common()" allocates and fills in a pcap_t, for use
* by pcap_open_offline routines. * by pcap_open_offline routines.
@@ -483,10 +542,46 @@ int add_addr_to_if(pcap_if_list_t *, const char *, bpf_u_int32,
* "sf_cleanup()" closes the file handle associated with a pcap_t, if * "sf_cleanup()" closes the file handle associated with a pcap_t, if
* appropriate, and frees all data common to all modules for handling * appropriate, and frees all data common to all modules for handling
* savefile types. * savefile types.
*
* "charset_fopen()", in UTF-8 mode on Windows, does an fopen() that
* treats the pathname as being in UTF-8, rather than the local
* code page, on Windows.
*/ */
pcap_t *pcap_open_offline_common(char *ebuf, size_t size);
/*
* This wrapper takes an error buffer pointer and a type to use for the
* private data, and calls pcap_create_common(), passing it the error
* buffer pointer, the size fo the private data type, in bytes, and the
* offset of the private data from the beginning of the structure, in
* bytes.
*/
#define PCAP_OPEN_OFFLINE_COMMON(ebuf, type) \
pcap_open_offline_common(ebuf, \
sizeof (struct { pcap_t __common; type __private; }), \
offsetof (struct { pcap_t __common; type __private; }, __private))
pcap_t *pcap_open_offline_common(char *ebuf, size_t total_size,
size_t private_data);
bpf_u_int32 pcap_adjust_snapshot(bpf_u_int32 linktype, bpf_u_int32 snaplen); bpf_u_int32 pcap_adjust_snapshot(bpf_u_int32 linktype, bpf_u_int32 snaplen);
void sf_cleanup(pcap_t *p); void sf_cleanup(pcap_t *p);
#ifdef _WIN32
FILE *charset_fopen(const char *path, const char *mode);
#else
/*
* On other OSes, just use Boring Old fopen().
*/
#define charset_fopen(path, mode) fopen((path), (mode))
#endif
/*
* Internal interfaces for loading code at run time.
*/
#ifdef _WIN32
#define pcap_code_handle_t HMODULE
#define pcap_funcptr_t FARPROC
pcap_code_handle_t pcap_load_code(const char *);
pcap_funcptr_t pcap_find_function(pcap_code_handle_t, const char *);
#endif
/* /*
* Internal interfaces for doing user-mode filtering of packets and * Internal interfaces for doing user-mode filtering of packets and
@@ -497,7 +592,7 @@ void sf_cleanup(pcap_t *p);
* Linux kernel when the kernel rejects the filter (requiring us to * Linux kernel when the kernel rejects the filter (requiring us to
* run it in userland). It contains VLAN tag information. * run it in userland). It contains VLAN tag information.
*/ */
struct bpf_aux_data { struct pcap_bpf_aux_data {
u_short vlan_tag_present; u_short vlan_tag_present;
u_short vlan_tag; u_short vlan_tag;
}; };
@@ -506,8 +601,18 @@ struct bpf_aux_data {
* Filtering routine that takes the auxiliary data as an additional * Filtering routine that takes the auxiliary data as an additional
* argument. * argument.
*/ */
u_int bpf_filter_with_aux_data(const struct bpf_insn *, u_int pcap_filter_with_aux_data(const struct bpf_insn *,
const u_char *, u_int, u_int, const struct bpf_aux_data *); const u_char *, u_int, u_int, const struct pcap_bpf_aux_data *);
/*
* Filtering routine that doesn't.
*/
u_int pcap_filter(const struct bpf_insn *, const u_char *, u_int, u_int);
/*
* Routine to validate a BPF program.
*/
int pcap_validate_filter(const struct bpf_insn *, int);
/* /*
* Internal interfaces for both "pcap_create()" and routines that * Internal interfaces for both "pcap_create()" and routines that
@@ -522,6 +627,16 @@ int install_bpf_program(pcap_t *, struct bpf_program *);
int pcap_strcasecmp(const char *, const char *); int pcap_strcasecmp(const char *, const char *);
/*
* Internal interfaces for pcap_createsrcstr and pcap_parsesrcstr with
* the additional bit of information regarding SSL support (rpcap:// vs.
* rpcaps://).
*/
int pcap_createsrcstr_ex(char *, int, const char *, const char *,
const char *, unsigned char, char *);
int pcap_parsesrcstr_ex(const char *, int *, char *, char *,
char *, unsigned char *, char *);
#ifdef YYDEBUG #ifdef YYDEBUG
extern int pcap_debug; extern int pcap_debug;
#endif #endif

View File

@@ -46,7 +46,7 @@
/* Forwards. */ /* Forwards. */
static int dlpromiscon(pcap_t *, bpf_u_int32); static int dlpromiscon(pcap_t *, bpf_u_int32);
static int pcap_read_libdlpi(pcap_t *, int, pcap_handler, u_char *); static int pcap_read_libdlpi(pcap_t *, int, pcap_handler, u_char *);
static int pcap_inject_libdlpi(pcap_t *, const void *, size_t); static int pcap_inject_libdlpi(pcap_t *, const void *, int);
static void pcap_libdlpi_err(const char *, const char *, int, char *); static void pcap_libdlpi_err(const char *, const char *, int, char *);
static void pcap_cleanup_libdlpi(pcap_t *); static void pcap_cleanup_libdlpi(pcap_t *);
@@ -427,7 +427,7 @@ process_pkts:
} }
static int static int
pcap_inject_libdlpi(pcap_t *p, const void *buf, size_t size) pcap_inject_libdlpi(pcap_t *p, const void *buf, int size)
{ {
struct pcap_dlpi *pd = p->priv; struct pcap_dlpi *pd = p->priv;
int retv; int retv;
@@ -468,7 +468,7 @@ 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)
{ {
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "libpcap: %s failed on %s: %s", snprintf(errbuf, PCAP_ERRBUF_SIZE, "libpcap: %s failed on %s: %s",
func, linkname, dlpi_strerror(err)); func, linkname, dlpi_strerror(err));
} }
@@ -477,7 +477,7 @@ pcap_create_interface(const char *device _U_, char *ebuf)
{ {
pcap_t *p; pcap_t *p;
p = pcap_create_common(ebuf, sizeof (struct pcap_dlpi)); p = PCAP_CREATE_COMMON(ebuf, struct pcap_dlpi);
if (p == NULL) if (p == NULL)
return (NULL); return (NULL);

View File

@@ -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@ "7 April 2014" .TH PCAP-LINKTYPE @MAN_MISC_INFO@ "6 April 2020"
.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
@@ -38,11 +38,11 @@ so they are sometimes called "DLT_ values".
The values stored in the link-layer header type field in the savefile The values stored in the link-layer header type field in the savefile
header are, in most but not all cases, the same as the values returned header are, in most but not all cases, the same as the values returned
by by
.BR pcap_datalink() . .BR pcap_datalink ().
The names for those values begin with The names for those values begin with
.BR LINKTYPE_ . .BR LINKTYPE_ .
.PP .PP
The link-layer header types supported by libpcap are described at The link-layer header types supported by libpcap are described at
https://www.tcpdump.org/linktypes.html. https://www.tcpdump.org/linktypes.html .
.SH SEE ALSO .SH SEE ALSO
pcap(3PCAP) .BR pcap (3PCAP)

File diff suppressed because it is too large Load Diff

View File

@@ -56,13 +56,13 @@
#include <linux/netfilter/nfnetlink_log.h> #include <linux/netfilter/nfnetlink_log.h>
#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 privileges 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 privileges,
* 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 privileges with -Z root
*/ */
#include "pcap-netfilter-linux.h" #include "pcap-netfilter-linux.h"
@@ -91,7 +91,7 @@ netfilter_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_c
struct pcap_netfilter *handlep = handle->priv; struct pcap_netfilter *handlep = handle->priv;
register u_char *bp, *ep; register u_char *bp, *ep;
int count = 0; int count = 0;
int len; ssize_t len;
/* /*
* Has "pcap_breakloop()" been called? * Has "pcap_breakloop()" been called?
@@ -152,14 +152,25 @@ netfilter_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_c
*/ */
if (handle->break_loop) { if (handle->break_loop) {
handle->bp = bp; handle->bp = bp;
handle->cc = ep - bp; handle->cc = (int)(ep - bp);
if (count == 0) { if (count == 0) {
handle->break_loop = 0; handle->break_loop = 0;
return PCAP_ERROR_BREAK; return PCAP_ERROR_BREAK;
} else } else
return count; return count;
} }
if (ep - bp < NLMSG_SPACE(0)) { /*
* NLMSG_SPACE(0) might be signed or might be unsigned,
* depending on whether the kernel defines NLMSG_ALIGNTO
* as 4, which older kernels do, or as 4U, which newer
* kernels do.
*
* ep - bp is of type ptrdiff_t, which is signed.
*
* To squelch warnings, we cast both to size_t, which
* is unsigned; ep >= bp, so the cast is safe.
*/
if ((size_t)(ep - bp) < (size_t)NLMSG_SPACE(0)) {
/* /*
* There's less than one netlink message left * There's less than one netlink message left
* in the buffer. Give up. * in the buffer. Give up.
@@ -168,7 +179,7 @@ netfilter_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_c
} }
if (nlh->nlmsg_len < sizeof(struct nlmsghdr) || (u_int)len < nlh->nlmsg_len) { if (nlh->nlmsg_len < sizeof(struct nlmsghdr) || (u_int)len < nlh->nlmsg_len) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Message truncated: (got: %d) (nlmsg_len: %u)", len, nlh->nlmsg_len); snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Message truncated: (got: %zd) (nlmsg_len: %u)", len, nlh->nlmsg_len);
return -1; return -1;
} }
@@ -190,7 +201,7 @@ netfilter_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_c
const struct nfattr *payload_attr = NULL; const struct nfattr *payload_attr = NULL;
if (nlh->nlmsg_len < HDR_LENGTH) { if (nlh->nlmsg_len < HDR_LENGTH) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Malformed message: (nlmsg_len: %u)", nlh->nlmsg_len); snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Malformed message: (nlmsg_len: %u)", nlh->nlmsg_len);
return -1; return -1;
} }
@@ -240,7 +251,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)) pcap_filter(handle->fcode.bf_insns, payload, pkth.len, pkth.caplen))
{ {
handlep->packets_read++; handlep->packets_read++;
callback(user, &pkth, payload); callback(user, &pkth, payload);
@@ -262,14 +273,21 @@ netfilter_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_c
* If the message length would run past the end of the * If the message length would run past the end of the
* buffer, truncate it to the remaining space in the * buffer, truncate it to the remaining space in the
* buffer. * buffer.
*
* To squelch warnings, we cast ep - bp to uint32_t, which
* is unsigned and is the type of msg_len; ep >= bp, and
* len should fit in 32 bits (either it's set from an int
* or it's set from a recv() call with a buffer size that's
* an int, and we're assuming either ILP32 or LP64), so
* the cast is safe.
*/ */
if (msg_len > ep - bp) if (msg_len > (uint32_t)(ep - bp))
msg_len = ep - bp; msg_len = (uint32_t)(ep - bp);
bp += msg_len; bp += msg_len;
if (count >= max_packets && !PACKET_COUNT_IS_UNLIMITED(max_packets)) { if (count >= max_packets && !PACKET_COUNT_IS_UNLIMITED(max_packets)) {
handle->bp = bp; handle->bp = bp;
handle->cc = ep - bp; handle->cc = (int)(ep - bp);
if (handle->cc < 0) if (handle->cc < 0)
handle->cc = 0; handle->cc = 0;
return count; return count;
@@ -299,9 +317,9 @@ netfilter_stats_linux(pcap_t *handle, struct pcap_stat *stats)
} }
static int static int
netfilter_inject_linux(pcap_t *handle, const void *buf _U_, size_t size _U_) netfilter_inject_linux(pcap_t *handle, const void *buf _U_, int size _U_)
{ {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Packet injection is not supported on netfilter devices"); "Packet injection is not supported on netfilter devices");
return (-1); return (-1);
} }
@@ -363,7 +381,11 @@ netfilter_send_config_msg(const pcap_t *handle, uint16_t msg_type, int ack, u_in
/* ignore interrupt system call error */ /* ignore interrupt system call error */
do { do {
len = recvfrom(handle->fd, buf, sizeof(buf), 0, (struct sockaddr *) &snl, &addrlen); /*
* The buffer is not so big that its size won't
* fit into an int.
*/
len = (int)recvfrom(handle->fd, buf, sizeof(buf), 0, (struct sockaddr *) &snl, &addrlen);
} while ((len == -1) && (errno == EINTR)); } while ((len == -1) && (errno == EINTR));
if (len <= 0) if (len <= 0)
@@ -510,7 +532,7 @@ netfilter_activate(pcap_t* handle)
char *end_dev; char *end_dev;
if (group_count == 32) { if (group_count == 32) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Maximum 32 netfilter groups! dev: %s", "Maximum 32 netfilter groups! dev: %s",
handle->opt.device); handle->opt.device);
return PCAP_ERROR; return PCAP_ERROR;
@@ -519,7 +541,7 @@ netfilter_activate(pcap_t* handle)
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) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 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;
@@ -535,7 +557,7 @@ netfilter_activate(pcap_t* handle)
} }
if (type == OTHER || *dev) { if (type == OTHER || *dev) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 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.device); handle->opt.device);
return PCAP_ERROR; return PCAP_ERROR;
@@ -616,7 +638,7 @@ netfilter_activate(pcap_t* handle)
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) {
pcap_fmt_errmsg_for_errno(handle->errbuf, pcap_fmt_errmsg_for_errno(handle->errbuf,
PCAP_ERRBUF_SIZE, errno, PCAP_ERRBUF_SIZE, errno,
"Can't listen on group group index"); "Can't listen on group index");
goto close_fail; goto close_fail;
} }
@@ -646,7 +668,7 @@ netfilter_activate(pcap_t* handle)
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) {
pcap_fmt_errmsg_for_errno(handle->errbuf, pcap_fmt_errmsg_for_errno(handle->errbuf,
PCAP_ERRBUF_SIZE, errno, PCAP_ERRBUF_SIZE, errno,
"Can't listen on group group index"); "Can't listen on group index");
goto close_fail; goto close_fail;
} }
@@ -721,7 +743,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(ebuf, sizeof (struct pcap_netfilter)); p = PCAP_CREATE_COMMON(ebuf, struct pcap_netfilter);
if (p == NULL) if (p == NULL)
return (NULL); return (NULL);

View File

@@ -29,7 +29,6 @@
#endif #endif
#include <poll.h> #include <poll.h>
#include <ctype.h>
#include <errno.h> #include <errno.h>
#include <netdb.h> #include <netdb.h>
#include <stdio.h> #include <stdio.h>
@@ -82,7 +81,7 @@ pcap_netmap_filter(u_char *arg, struct pcap_pkthdr *h, const u_char *buf)
const struct bpf_insn *pc = p->fcode.bf_insns; const struct bpf_insn *pc = p->fcode.bf_insns;
++pn->rx_pkts; ++pn->rx_pkts;
if (pc == NULL || bpf_filter(pc, buf, h->len, h->caplen)) if (pc == NULL || pcap_filter(pc, buf, h->len, h->caplen))
pn->cb(pn->cb_arg, h, buf); pn->cb(pn->cb_arg, h, buf);
} }
@@ -117,7 +116,7 @@ pcap_netmap_dispatch(pcap_t *p, int cnt, pcap_handler cb, u_char *user)
/* XXX need to check the NIOCTXSYNC/poll */ /* XXX need to check the NIOCTXSYNC/poll */
static int static int
pcap_netmap_inject(pcap_t *p, const void *buf, size_t size) pcap_netmap_inject(pcap_t *p, const void *buf, int size)
{ {
struct pcap_netmap *pn = p->priv; struct pcap_netmap *pn = p->priv;
struct nm_desc *d = pn->d; struct nm_desc *d = pn->d;
@@ -287,7 +286,7 @@ pcap_netmap_create(const char *device, char *ebuf, int *is_ours)
*is_ours = (!strncmp(device, "netmap:", 7) || !strncmp(device, "vale", 4)); *is_ours = (!strncmp(device, "netmap:", 7) || !strncmp(device, "vale", 4));
if (! *is_ours) if (! *is_ours)
return NULL; return NULL;
p = pcap_create_common(ebuf, sizeof (struct pcap_netmap)); p = PCAP_CREATE_COMMON(ebuf, struct pcap_netmap);
if (p == NULL) if (p == NULL)
return (NULL); return (NULL);
p->activate_op = pcap_netmap_activate; p->activate_op = pcap_netmap_activate;

View File

@@ -88,7 +88,7 @@ int pcap_findalldevs_ex(const char *source, struct pcap_rmtauth *auth, pcap_if_t
if (strlen(source) > PCAP_BUF_SIZE) if (strlen(source) > PCAP_BUF_SIZE)
{ {
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "The source string is too long. Cannot handle it correctly."); snprintf(errbuf, PCAP_ERRBUF_SIZE, "The source string is too long. Cannot handle it correctly.");
return -1; return -1;
} }
@@ -119,7 +119,7 @@ int pcap_findalldevs_ex(const char *source, struct pcap_rmtauth *auth, pcap_if_t
if (*alldevs == NULL) if (*alldevs == NULL)
{ {
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, snprintf(errbuf, PCAP_ERRBUF_SIZE,
"No interfaces found! Make sure libpcap/Npcap is properly installed" "No interfaces found! Make sure libpcap/Npcap is properly installed"
" on the local machine."); " on the local machine.");
return -1; return -1;
@@ -209,7 +209,7 @@ int pcap_findalldevs_ex(const char *source, struct pcap_rmtauth *auth, pcap_if_t
} }
/* Save the path for future reference */ /* Save the path for future reference */
pcap_snprintf(path, sizeof(path), "%s", name); snprintf(path, sizeof(path), "%s", name);
pathlen = strlen(path); pathlen = strlen(path);
#ifdef _WIN32 #ifdef _WIN32
@@ -224,7 +224,7 @@ int pcap_findalldevs_ex(const char *source, struct pcap_rmtauth *auth, pcap_if_t
if (filehandle == INVALID_HANDLE_VALUE) if (filehandle == INVALID_HANDLE_VALUE)
{ {
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Error when listing files: does folder '%s' exist?", path); snprintf(errbuf, PCAP_ERRBUF_SIZE, "Error when listing files: does folder '%s' exist?", path);
return -1; return -1;
} }
@@ -237,7 +237,7 @@ int pcap_findalldevs_ex(const char *source, struct pcap_rmtauth *auth, pcap_if_t
if (filedata == NULL) if (filedata == NULL)
{ {
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Error when listing files: does folder '%s' exist?", path); snprintf(errbuf, PCAP_ERRBUF_SIZE, "Error when listing files: does folder '%s' exist?", path);
return -1; return -1;
} }
#endif #endif
@@ -249,11 +249,11 @@ int pcap_findalldevs_ex(const char *source, struct pcap_rmtauth *auth, pcap_if_t
/* Skip the file if the pathname won't fit in the buffer */ /* Skip the file if the pathname won't fit in the buffer */
if (pathlen + strlen(filedata.cFileName) >= sizeof(filename)) if (pathlen + strlen(filedata.cFileName) >= sizeof(filename))
continue; continue;
pcap_snprintf(filename, sizeof(filename), "%s%s", path, filedata.cFileName); snprintf(filename, sizeof(filename), "%s%s", path, filedata.cFileName);
#else #else
if (pathlen + strlen(filedata->d_name) >= sizeof(filename)) if (pathlen + strlen(filedata->d_name) >= sizeof(filename))
continue; continue;
pcap_snprintf(filename, sizeof(filename), "%s%s", path, filedata->d_name); snprintf(filename, sizeof(filename), "%s%s", path, filedata->d_name);
#endif #endif
fp = pcap_open_offline(filename, errbuf); fp = pcap_open_offline(filename, errbuf);
@@ -370,7 +370,7 @@ pcap_t *pcap_open(const char *source, int snaplen, int flags, int read_timeout,
if (strlen(source) > PCAP_BUF_SIZE) if (strlen(source) > PCAP_BUF_SIZE)
{ {
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "The source string is too long. Cannot handle it correctly."); snprintf(errbuf, PCAP_ERRBUF_SIZE, "The source string is too long. Cannot handle it correctly.");
return NULL; return NULL;
} }
@@ -445,15 +445,15 @@ pcap_t *pcap_open(const char *source, int snaplen, int flags, int read_timeout,
fail: fail:
if (status == PCAP_ERROR) if (status == PCAP_ERROR)
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s",
name, fp->errbuf); name, fp->errbuf);
else if (status == PCAP_ERROR_NO_SUCH_DEVICE || else if (status == PCAP_ERROR_NO_SUCH_DEVICE ||
status == PCAP_ERROR_PERM_DENIED || status == PCAP_ERROR_PERM_DENIED ||
status == PCAP_ERROR_PROMISC_PERM_DENIED) status == PCAP_ERROR_PROMISC_PERM_DENIED)
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s (%s)", snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s (%s)",
name, pcap_statustostr(status), fp->errbuf); name, pcap_statustostr(status), fp->errbuf);
else else
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s",
name, pcap_statustostr(status)); name, pcap_statustostr(status));
pcap_close(fp); pcap_close(fp);
return NULL; return NULL;

View File

@@ -43,7 +43,6 @@
#include <netinet/tcp.h> #include <netinet/tcp.h>
#include <netinet/tcpip.h> #include <netinet/tcpip.h>
#include <ctype.h>
#include <errno.h> #include <errno.h>
#include <stdio.h> #include <stdio.h>
@@ -168,7 +167,7 @@ pcap_read_nit(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
continue; continue;
default: default:
pcap_snprintf(p->errbuf, sizeof(p->errbuf), snprintf(p->errbuf, sizeof(p->errbuf),
"bad nit state %d", nh->nh_state); "bad nit state %d", nh->nh_state);
return (-1); return (-1);
} }
@@ -179,7 +178,7 @@ pcap_read_nit(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
caplen = nh->nh_wirelen; caplen = nh->nh_wirelen;
if (caplen > p->snapshot) if (caplen > p->snapshot)
caplen = p->snapshot; caplen = p->snapshot;
if (bpf_filter(p->fcode.bf_insns, cp, nh->nh_wirelen, caplen)) { if (pcap_filter(p->fcode.bf_insns, cp, nh->nh_wirelen, caplen)) {
struct pcap_pkthdr h; struct pcap_pkthdr h;
h.ts = nh->nh_timestamp; h.ts = nh->nh_timestamp;
h.len = nh->nh_wirelen; h.len = nh->nh_wirelen;
@@ -197,7 +196,7 @@ pcap_read_nit(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
} }
static int static int
pcap_inject_nit(pcap_t *p, const void *buf, size_t size) pcap_inject_nit(pcap_t *p, const void *buf, int size)
{ {
struct sockaddr sa; struct sockaddr sa;
int ret; int ret;
@@ -371,7 +370,7 @@ pcap_create_interface(const char *device _U_, char *ebuf)
{ {
pcap_t *p; pcap_t *p;
p = pcap_create_common(ebuf, sizeof (struct pcap_nit)); p = PCAP_CREATE_COMMON(ebuf, struct pcap_nit);
if (p == NULL) if (p == NULL)
return (NULL); return (NULL);

View File

@@ -41,6 +41,17 @@
#include <pcap-int.h> #include <pcap-int.h>
#include <pcap/dlt.h> #include <pcap/dlt.h>
/*
* XXX - Packet32.h defines bpf_program, so we can't include
* <pcap/bpf.h>, which also defines it; that's why we define
* PCAP_DONT_INCLUDE_PCAP_BPF_H,
*
* However, no header in the WinPcap or Npcap SDKs defines the
* macros for BPF code, so we have to define them ourselves.
*/
#define BPF_RET 0x06
#define BPF_K 0x00
/* Old-school MinGW have these headers in a different place. /* Old-school MinGW have these headers in a different place.
*/ */
#if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR) #if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)
@@ -55,6 +66,10 @@
#include <dagapi.h> #include <dagapi.h>
#endif /* HAVE_DAG_API */ #endif /* HAVE_DAG_API */
#include "diag-control.h"
#include "pcap-airpcap.h"
static int pcap_setfilter_npf(pcap_t *, struct bpf_program *); static int pcap_setfilter_npf(pcap_t *, struct bpf_program *);
static int pcap_setfilter_win32_dag(pcap_t *, struct bpf_program *); static int pcap_setfilter_win32_dag(pcap_t *, struct bpf_program *);
static int pcap_getnonblock_npf(pcap_t *); static int pcap_getnonblock_npf(pcap_t *);
@@ -155,7 +170,7 @@ oid_get_request(ADAPTER *adapter, bpf_u_int32 oid, void *data, size_t *lenp,
*/ */
oid_data_arg = malloc(sizeof (PACKET_OID_DATA) + *lenp); oid_data_arg = malloc(sizeof (PACKET_OID_DATA) + *lenp);
if (oid_data_arg == NULL) { if (oid_data_arg == NULL) {
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, snprintf(errbuf, PCAP_ERRBUF_SIZE,
"Couldn't allocate argument buffer for PacketRequest"); "Couldn't allocate argument buffer for PacketRequest");
return (PCAP_ERROR); return (PCAP_ERROR);
} }
@@ -240,13 +255,13 @@ pcap_stats_npf(pcap_t *p, struct pcap_stat *ps)
* have an API that returns data in a form like the Options section of a * have an API that returns data in a form like the Options section of a
* pcapng Interface Statistics Block: * pcapng Interface Statistics Block:
* *
* http://xml2rfc.tools.ietf.org/cgi-bin/xml2rfc.cgi?url=https://raw.githubusercontent.com/pcapng/pcapng/master/draft-tuexen-opsawg-pcapng.xml&modeAsFormat=html/ascii&type=ascii#rfc.section.4.6 * https://xml2rfc.tools.ietf.org/cgi-bin/xml2rfc.cgi?url=https://raw.githubusercontent.com/pcapng/pcapng/master/draft-tuexen-opsawg-pcapng.xml&modeAsFormat=html/ascii&type=ascii#rfc.section.4.6
* *
* which would let us add new statistics straightforwardly and indicate which * which would let us add new statistics straightforwardly and indicate which
* statistics we are and are *not* providing, rather than having to provide * statistics we are and are *not* providing, rather than having to provide
* possibly-bogus values for statistics we can't provide. * possibly-bogus values for statistics we can't provide.
*/ */
struct pcap_stat * static struct pcap_stat *
pcap_stats_ex_npf(pcap_t *p, int *pcap_stat_size) pcap_stats_ex_npf(pcap_t *p, int *pcap_stat_size)
{ {
struct pcap_win *pw = p->priv; struct pcap_win *pw = p->priv;
@@ -269,7 +284,12 @@ pcap_stats_ex_npf(pcap_t *p, int *pcap_stat_size)
p->stat.ps_recv = bstats.bs_recv; p->stat.ps_recv = bstats.bs_recv;
p->stat.ps_drop = bstats.bs_drop; p->stat.ps_drop = bstats.bs_drop;
p->stat.ps_ifdrop = bstats.ps_ifdrop; p->stat.ps_ifdrop = bstats.ps_ifdrop;
#ifdef ENABLE_REMOTE /*
* Just in case this is ever compiled for a target other than
* Windows, which is somewhere between extremely unlikely and
* impossible.
*/
#ifdef _WIN32
p->stat.ps_capt = bstats.bs_capt; p->stat.ps_capt = bstats.bs_capt;
#endif #endif
return (&p->stat); return (&p->stat);
@@ -283,7 +303,7 @@ pcap_setbuff_npf(pcap_t *p, int dim)
if(PacketSetBuff(pw->adapter,dim)==FALSE) if(PacketSetBuff(pw->adapter,dim)==FALSE)
{ {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: not enough memory to allocate the kernel buffer"); snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: not enough memory to allocate the kernel buffer");
return (-1); return (-1);
} }
return (0); return (0);
@@ -297,7 +317,7 @@ pcap_setmode_npf(pcap_t *p, int mode)
if(PacketSetMode(pw->adapter,mode)==FALSE) if(PacketSetMode(pw->adapter,mode)==FALSE)
{ {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: working mode not recognized"); snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: working mode not recognized");
return (-1); return (-1);
} }
@@ -312,7 +332,7 @@ pcap_setmintocopy_npf(pcap_t *p, int size)
if(PacketSetMinToCopy(pw->adapter, size)==FALSE) if(PacketSetMinToCopy(pw->adapter, size)==FALSE)
{ {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: unable to set the requested mintocopy size"); snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: unable to set the requested mintocopy size");
return (-1); return (-1);
} }
return (0); return (0);
@@ -350,7 +370,7 @@ pcap_oid_set_request_npf(pcap_t *p, bpf_u_int32 oid, const void *data,
*/ */
oid_data_arg = malloc(sizeof (PACKET_OID_DATA) + *lenp); oid_data_arg = malloc(sizeof (PACKET_OID_DATA) + *lenp);
if (oid_data_arg == NULL) { if (oid_data_arg == NULL) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"Couldn't allocate argument buffer for PacketRequest"); "Couldn't allocate argument buffer for PacketRequest");
return (PCAP_ERROR); return (PCAP_ERROR);
} }
@@ -383,12 +403,6 @@ pcap_sendqueue_transmit_npf(pcap_t *p, pcap_send_queue *queue, int sync)
struct pcap_win *pw = p->priv; struct pcap_win *pw = p->priv;
u_int res; u_int res;
if (pw->adapter==NULL) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"Cannot transmit a queue to an offline capture or to a TurboCap port");
return (0);
}
res = PacketSendPackets(pw->adapter, res = PacketSendPackets(pw->adapter,
queue->buffer, queue->buffer,
queue->len, queue->len,
@@ -396,7 +410,7 @@ pcap_sendqueue_transmit_npf(pcap_t *p, pcap_send_queue *queue, int sync)
if(res != queue->len){ if(res != queue->len){
pcap_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE, pcap_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE,
GetLastError(), "Error opening adapter"); GetLastError(), "Error queueing packets");
} }
return (res); return (res);
@@ -409,7 +423,7 @@ pcap_setuserbuffer_npf(pcap_t *p, int size)
if (size<=0) { if (size<=0) {
/* Bogus parameter */ /* Bogus parameter */
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"Error: invalid size %d",size); "Error: invalid size %d",size);
return (-1); return (-1);
} }
@@ -418,7 +432,7 @@ pcap_setuserbuffer_npf(pcap_t *p, int size)
new_buff=(unsigned char*)malloc(sizeof(char)*size); new_buff=(unsigned char*)malloc(sizeof(char)*size);
if (!new_buff) { if (!new_buff) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"Error: not enough memory"); "Error: not enough memory");
return (-1); return (-1);
} }
@@ -440,7 +454,7 @@ pcap_live_dump_npf(pcap_t *p, char *filename, int maxsize, int maxpacks)
/* Set the packet driver in dump mode */ /* Set the packet driver in dump mode */
res = PacketSetMode(pw->adapter, PACKET_MODE_DUMP); res = PacketSetMode(pw->adapter, PACKET_MODE_DUMP);
if(res == FALSE){ if(res == FALSE){
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"Error setting dump mode"); "Error setting dump mode");
return (-1); return (-1);
} }
@@ -448,7 +462,7 @@ pcap_live_dump_npf(pcap_t *p, char *filename, int maxsize, int maxpacks)
/* Set the name of the dump file */ /* Set the name of the dump file */
res = PacketSetDumpName(pw->adapter, filename, (int)strlen(filename)); res = PacketSetDumpName(pw->adapter, filename, (int)strlen(filename));
if(res == FALSE){ if(res == FALSE){
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"Error setting kernel dump file name"); "Error setting kernel dump file name");
return (-1); return (-1);
} }
@@ -456,8 +470,8 @@ pcap_live_dump_npf(pcap_t *p, char *filename, int maxsize, int maxpacks)
/* Set the limits of the dump file */ /* Set the limits of the dump file */
res = PacketSetDumpLimits(pw->adapter, maxsize, maxpacks); res = PacketSetDumpLimits(pw->adapter, maxsize, maxpacks);
if(res == FALSE) { if(res == FALSE) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"Error setting dump limit"); "Error setting dump limit");
return (-1); return (-1);
} }
@@ -472,30 +486,34 @@ pcap_live_dump_ended_npf(pcap_t *p, int sync)
return (PacketIsDumpEnded(pw->adapter, (BOOLEAN)sync)); return (PacketIsDumpEnded(pw->adapter, (BOOLEAN)sync));
} }
#ifdef HAVE_AIRPCAP_API
static PAirpcapHandle static PAirpcapHandle
pcap_get_airpcap_handle_npf(pcap_t *p) pcap_get_airpcap_handle_npf(pcap_t *p)
{ {
#ifdef HAVE_AIRPCAP_API
struct pcap_win *pw = p->priv; struct pcap_win *pw = p->priv;
return (PacketGetAirPcapHandle(pw->adapter)); return (PacketGetAirPcapHandle(pw->adapter));
#else
return (NULL);
#endif /* HAVE_AIRPCAP_API */
} }
#else /* HAVE_AIRPCAP_API */
static PAirpcapHandle
pcap_get_airpcap_handle_npf(pcap_t *p _U_)
{
return (NULL);
}
#endif /* HAVE_AIRPCAP_API */
static int static int
pcap_read_npf(pcap_t *p, int cnt, pcap_handler callback, u_char *user) pcap_read_npf(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
{ {
PACKET Packet; PACKET Packet;
int cc; int cc;
int n = 0; int n;
register u_char *bp, *ep; register u_char *bp, *ep;
u_char *datap; u_char *datap;
struct pcap_win *pw = p->priv; struct pcap_win *pw = p->priv;
cc = p->cc; cc = p->cc;
if (p->cc == 0) { if (cc == 0) {
/* /*
* Has "pcap_breakloop()" been called? * Has "pcap_breakloop()" been called?
*/ */
@@ -525,27 +543,53 @@ pcap_read_npf(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
if (!PacketReceivePacket(pw->adapter, &Packet, TRUE)) { if (!PacketReceivePacket(pw->adapter, &Packet, TRUE)) {
/* /*
* Did the device go away? * Did the device go away?
* If so, the error we get is ERROR_GEN_FAILURE. * If so, the error we get can either be
* ERROR_GEN_FAILURE or ERROR_DEVICE_REMOVED.
*/ */
DWORD errcode = GetLastError(); DWORD errcode = GetLastError();
if (errcode == ERROR_GEN_FAILURE) { if (errcode == ERROR_GEN_FAILURE ||
errcode == ERROR_DEVICE_REMOVED) {
/* /*
* The device on which we're capturing * The device on which we're capturing
* went away, or it became unusable * went away, or it became unusable
* by NPF due to a suspend/resume. * by NPF due to a suspend/resume.
* *
* ERROR_GEN_FAILURE comes from
* STATUS_UNSUCCESSFUL, as well as some
* other NT status codes that the Npcap
* driver is unlikely to return.
* XXX - hopefully no other error * XXX - hopefully no other error
* conditions are indicated by this. * conditions are indicated by this.
* *
* ERROR_DEVICE_REMOVED comes from
* STATUS_DEVICE_REMOVED.
*
* We report the Windows status code
* name and the corresponding NT status
* code name, for the benefit of attempts
* to debug cases where this error is
* reported when the device *wasn't*
* removed, either because it's not
* removable, it's removable but wasn't
* removed, or it's a device that doesn't
* correspond to a physical device.
*
* XXX - we really should return an * XXX - we really should return an
* appropriate error for that, but * appropriate error for that, but
* pcap_dispatch() etc. aren't * pcap_dispatch() etc. aren't
* documented as having error returns * documented as having error returns
* other than PCAP_ERROR or PCAP_ERROR_BREAK. * other than PCAP_ERROR or PCAP_ERROR_BREAK.
*/ */
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, const char *errcode_msg;
"The interface disappeared");
if (errcode == ERROR_GEN_FAILURE)
errcode_msg = "ERROR_GEN_FAILURE/STATUS_UNSUCCESSFUL";
else
errcode_msg = "ERROR_DEVICE_REMOVED/STATUS_DEVICE_REMOVED";
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"The interface disappeared (error code %s)",
errcode_msg);
} else { } else {
pcap_fmt_errmsg_for_win32_err(p->errbuf, pcap_fmt_errmsg_for_win32_err(p->errbuf,
PCAP_ERRBUF_SIZE, errcode, PCAP_ERRBUF_SIZE, errcode,
@@ -565,9 +609,10 @@ pcap_read_npf(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
* Loop through each packet. * Loop through each packet.
*/ */
#define bhp ((struct bpf_hdr *)bp) #define bhp ((struct bpf_hdr *)bp)
n = 0;
ep = bp + cc; ep = bp + cc;
for (;;) { for (;;) {
register int caplen, hdrlen; register u_int caplen, hdrlen;
/* /*
* Has "pcap_breakloop()" been called? * Has "pcap_breakloop()" been called?
@@ -601,13 +646,13 @@ pcap_read_npf(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
* in kernel, no need to do it now - we already know * in kernel, no need to do it now - we already know
* the packet passed the filter. * the packet passed the filter.
* *
* XXX - bpf_filter() should always return TRUE if * XXX - pcap_filter() should always return TRUE if
* handed a null pointer for the program, but it might * handed a null pointer for the program, but it might
* just try to "run" the filter, so we check here. * just try to "run" the filter, so we check here.
*/ */
if (pw->filtering_in_kernel || if (pw->filtering_in_kernel ||
p->fcode.bf_insns == NULL || p->fcode.bf_insns == NULL ||
bpf_filter(p->fcode.bf_insns, datap, bhp->bh_datalen, caplen)) { pcap_filter(p->fcode.bf_insns, datap, bhp->bh_datalen, caplen)) {
#ifdef ENABLE_REMOTE #ifdef ENABLE_REMOTE
switch (p->rmt_samp.method) { switch (p->rmt_samp.method) {
@@ -706,7 +751,7 @@ pcap_read_win32_dag(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
*/ */
PacketInitPacket(&Packet, (BYTE *)p->buffer, p->bufsize); PacketInitPacket(&Packet, (BYTE *)p->buffer, p->bufsize);
if (!PacketReceivePacket(pw->adapter, &Packet, TRUE)) { if (!PacketReceivePacket(pw->adapter, &Packet, TRUE)) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read error: PacketReceivePacket failed"); snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read error: PacketReceivePacket failed");
return (-1); return (-1);
} }
@@ -814,7 +859,7 @@ pcap_read_win32_dag(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
/* No underlaying filtering system. We need to filter on our own */ /* No underlaying filtering system. We need to filter on our own */
if (p->fcode.bf_insns) if (p->fcode.bf_insns)
{ {
if (bpf_filter(p->fcode.bf_insns, dp, packet_len, caplen) == 0) if (pcap_filter(p->fcode.bf_insns, dp, packet_len, caplen) == 0)
{ {
/* Move to next packet */ /* Move to next packet */
header = (dag_record_t*)((char*)header + erf_record_len); header = (dag_record_t*)((char*)header + erf_record_len);
@@ -848,14 +893,15 @@ pcap_read_win32_dag(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
/* Send a packet to the network */ /* Send a packet to the network */
static int static int
pcap_inject_npf(pcap_t *p, const void *buf, size_t size) pcap_inject_npf(pcap_t *p, const void *buf, int size)
{ {
struct pcap_win *pw = p->priv; struct pcap_win *pw = p->priv;
PACKET pkt; PACKET pkt;
PacketInitPacket(&pkt, (PVOID)buf, size); PacketInitPacket(&pkt, (PVOID)buf, size);
if(PacketSendPacket(pw->adapter,&pkt,TRUE) == FALSE) { if(PacketSendPacket(pw->adapter,&pkt,TRUE) == FALSE) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send error: PacketSendPacket failed"); pcap_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE,
GetLastError(), "send error: PacketSendPacket failed");
return (-1); return (-1);
} }
@@ -864,7 +910,7 @@ pcap_inject_npf(pcap_t *p, const void *buf, size_t size)
* "pcap_inject()" is expected to return the number of bytes * "pcap_inject()" is expected to return the number of bytes
* sent. * sent.
*/ */
return ((int)size); return (size);
} }
static void static void
@@ -883,6 +929,37 @@ pcap_cleanup_npf(pcap_t *p)
pcap_cleanup_live_common(p); pcap_cleanup_live_common(p);
} }
static void
pcap_breakloop_npf(pcap_t *p)
{
pcap_breakloop_common(p);
struct pcap_win *pw = p->priv;
/* XXX - what if this fails? */
SetEvent(PacketGetReadEvent(pw->adapter));
}
/*
* Vendor-specific error codes.
*
* These are NTSTATUS values:
*
* https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-erref/87fba13e-bf06-450e-83b1-9241dc81e781
*
* with the "Customer" bit set. If a driver returns them, they are not
* mapped to Windows error values in userland; they're returned by
* GetLastError().
*
* Attempting to set non-promiscuous mode on a Microsoft Surface Pro's
* Mobile Broadband Adapter returns an error; that error can safely be
* ignored, as it's always in non-promiscuous mode.
*
* It is likely that there are other devices which throw spurious errors,
* at which point this will need refactoring to efficiently check against
* a list, but for now we can just check this one value.
*/
#define NPF_SURFACE_MOBILE_NONPROMISC 0xe00000bb
static int static int
pcap_activate_npf(pcap_t *p) pcap_activate_npf(pcap_t *p)
{ {
@@ -890,6 +967,8 @@ pcap_activate_npf(pcap_t *p)
NetType type; NetType type;
int res; int res;
int status = 0; int status = 0;
struct bpf_insn total_insn;
struct bpf_program total_prog;
if (p->opt.rfmon) { if (p->opt.rfmon) {
/* /*
@@ -921,7 +1000,7 @@ pcap_activate_npf(pcap_t *p)
} }
} }
/* Init WinSock */ /* Init Winsock if it hasn't already been initialized */
pcap_wsockinit(); pcap_wsockinit();
pw->adapter = PacketOpenAdapter(p->opt.device); pw->adapter = PacketOpenAdapter(p->opt.device);
@@ -933,12 +1012,22 @@ pcap_activate_npf(pcap_t *p)
/* /*
* What error did we get when trying to open the adapter? * What error did we get when trying to open the adapter?
*/ */
if (errcode == ERROR_BAD_UNIT) { switch (errcode) {
case ERROR_BAD_UNIT:
/* /*
* There's no such device. * There's no such device.
*/ */
return (PCAP_ERROR_NO_SUCH_DEVICE); return (PCAP_ERROR_NO_SUCH_DEVICE);
} else {
case ERROR_ACCESS_DENIED:
/*
* There is, but we don't have permission to
* use it.
*/
return (PCAP_ERROR_PERM_DENIED);
default:
/* /*
* Unknown - report details. * Unknown - report details.
*/ */
@@ -1034,11 +1123,9 @@ pcap_activate_npf(pcap_t *p)
p->linktype = DLT_PPI; p->linktype = DLT_PPI;
break; break;
#ifdef NdisMediumWirelessWan
case NdisMediumWirelessWan: case NdisMediumWirelessWan:
p->linktype = DLT_RAW; p->linktype = DLT_RAW;
break; break;
#endif
default: default:
/* /*
@@ -1053,13 +1140,72 @@ pcap_activate_npf(pcap_t *p)
* some programs will report the warning. * some programs will report the warning.
*/ */
p->linktype = DLT_EN10MB; p->linktype = DLT_EN10MB;
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"Unknown NdisMedium value %d, defaulting to DLT_EN10MB", "Unknown NdisMedium value %d, defaulting to DLT_EN10MB",
type.LinkType); type.LinkType);
status = PCAP_WARNING; status = PCAP_WARNING;
break; break;
} }
#ifdef HAVE_PACKET_GET_TIMESTAMP_MODES
/*
* Set the timestamp type.
* (Yes, we require PacketGetTimestampModes(), not just
* PacketSetTimestampMode(). If we have the former, we
* have the latter, unless somebody's using a version
* of Npcap that they've hacked to provide the former
* but not the latter; if they've done that, either
* they're confused or they're trolling us.)
*/
switch (p->opt.tstamp_type) {
case PCAP_TSTAMP_HOST_HIPREC_UNSYNCED:
/*
* Better than low-res, but *not* synchronized with
* the OS clock.
*/
if (!PacketSetTimestampMode(pw->adapter, TIMESTAMPMODE_SINGLE_SYNCHRONIZATION))
{
pcap_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE,
GetLastError(), "Cannot set the time stamp mode to TIMESTAMPMODE_SINGLE_SYNCHRONIZATION");
goto bad;
}
break;
case PCAP_TSTAMP_HOST_LOWPREC:
/*
* Low-res, but synchronized with the OS clock.
*/
if (!PacketSetTimestampMode(pw->adapter, TIMESTAMPMODE_QUERYSYSTEMTIME))
{
pcap_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE,
GetLastError(), "Cannot set the time stamp mode to TIMESTAMPMODE_QUERYSYSTEMTIME");
goto bad;
}
break;
case PCAP_TSTAMP_HOST_HIPREC:
/*
* High-res, and synchronized with the OS clock.
*/
if (!PacketSetTimestampMode(pw->adapter, TIMESTAMPMODE_QUERYSYSTEMTIME_PRECISE))
{
pcap_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE,
GetLastError(), "Cannot set the time stamp mode to TIMESTAMPMODE_QUERYSYSTEMTIME_PRECISE");
goto bad;
}
break;
case PCAP_TSTAMP_HOST:
/*
* XXX - do whatever the default is, for now.
* Set to the highest resolution that's synchronized
* with the system clock?
*/
break;
}
#endif /* HAVE_PACKET_GET_TIMESTAMP_MODES */
/* /*
* Turn a negative snapshot value (invalid), a snapshot value of * Turn a negative snapshot value (invalid), a snapshot value of
* 0 (unspecified), or a value bigger than the normal maximum * 0 (unspecified), or a value bigger than the normal maximum
@@ -1077,17 +1223,51 @@ pcap_activate_npf(pcap_t *p)
if (PacketSetHwFilter(pw->adapter,NDIS_PACKET_TYPE_PROMISCUOUS) == FALSE) if (PacketSetHwFilter(pw->adapter,NDIS_PACKET_TYPE_PROMISCUOUS) == FALSE)
{ {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "failed to set hardware filter to promiscuous mode"); DWORD errcode = GetLastError();
goto bad;
/*
* Suppress spurious error generated by non-compiant
* MS Surface mobile adapters.
*
* If we knew that this meant "promiscuous mode
* isn't supported", we could add a "promiscuous
* mode isn't supported" error code and return
* that, but:
*
* 1) we don't know that it means that
* rather than meaning "we reject attempts
* to set the filter, even though the NDIS
* specifications say you shouldn't do that"
*
* and
*
* 2) other interface types that don't
* support promiscuous mode, at least
* on UN*Xes, just silently ignore
* attempts to set promiscuous mode
*
* and rejecting it with an error could disrupt
* attempts to capture, as many programs (tcpdump,
* *shark) default to promiscuous mode.
*/
if (errcode != NPF_SURFACE_MOBILE_NONPROMISC)
{
pcap_fmt_errmsg_for_win32_err(p->errbuf,
PCAP_ERRBUF_SIZE, errcode,
"failed to set hardware filter to promiscuous mode");
goto bad;
}
} }
} }
else else
{ {
/* NDIS_PACKET_TYPE_ALL_LOCAL selects "All packets sent by installed /*
* protocols and all packets indicated by the NIC" but if no protocol * NDIS_PACKET_TYPE_ALL_LOCAL selects "All packets sent by
* drivers (like TCP/IP) are installed, NDIS_PACKET_TYPE_DIRECTED, * installed protocols and all packets indicated by the NIC",
* NDIS_PACKET_TYPE_BROADCAST, and NDIS_PACKET_TYPE_MULTICAST are needed to * but if no protocol drivers (like TCP/IP) are installed,
* capture incoming frames. * NDIS_PACKET_TYPE_DIRECTED, NDIS_PACKET_TYPE_BROADCAST,
* and NDIS_PACKET_TYPE_MULTICAST are needed to capture
* incoming frames.
*/ */
if (PacketSetHwFilter(pw->adapter, if (PacketSetHwFilter(pw->adapter,
NDIS_PACKET_TYPE_ALL_LOCAL | NDIS_PACKET_TYPE_ALL_LOCAL |
@@ -1095,8 +1275,19 @@ pcap_activate_npf(pcap_t *p)
NDIS_PACKET_TYPE_BROADCAST | NDIS_PACKET_TYPE_BROADCAST |
NDIS_PACKET_TYPE_MULTICAST) == FALSE) NDIS_PACKET_TYPE_MULTICAST) == FALSE)
{ {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "failed to set hardware filter to non-promiscuous mode"); DWORD errcode = GetLastError();
goto bad;
/*
* Suppress spurious error generated by non-compiant
* MS Surface mobile adapters.
*/
if (errcode != NPF_SURFACE_MOBILE_NONPROMISC)
{
pcap_fmt_errmsg_for_win32_err(p->errbuf,
PCAP_ERRBUF_SIZE, errcode,
"failed to set hardware filter to non-promiscuous mode");
goto bad;
}
} }
} }
@@ -1112,12 +1303,12 @@ pcap_activate_npf(pcap_t *p)
* If the buffer size wasn't explicitly set, default to * If the buffer size wasn't explicitly set, default to
* WIN32_DEFAULT_KERNEL_BUFFER_SIZE. * WIN32_DEFAULT_KERNEL_BUFFER_SIZE.
*/ */
if (p->opt.buffer_size == 0) if (p->opt.buffer_size == 0)
p->opt.buffer_size = WIN32_DEFAULT_KERNEL_BUFFER_SIZE; p->opt.buffer_size = WIN32_DEFAULT_KERNEL_BUFFER_SIZE;
if(PacketSetBuff(pw->adapter,p->opt.buffer_size)==FALSE) if(PacketSetBuff(pw->adapter,p->opt.buffer_size)==FALSE)
{ {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: not enough memory to allocate the kernel buffer"); snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: not enough memory to allocate the kernel buffer");
goto bad; goto bad;
} }
@@ -1166,7 +1357,7 @@ pcap_activate_npf(pcap_t *p)
int postype = 0; int postype = 0;
char keyname[512]; char keyname[512];
pcap_snprintf(keyname, sizeof(keyname), "%s\\CardParams\\%s", snprintf(keyname, sizeof(keyname), "%s\\CardParams\\%s",
"SYSTEM\\CurrentControlSet\\Services\\DAG", "SYSTEM\\CurrentControlSet\\Services\\DAG",
strstr(_strlwr(p->opt.device), "dag")); strstr(_strlwr(p->opt.device), "dag"));
do do
@@ -1205,6 +1396,29 @@ pcap_activate_npf(pcap_t *p)
#endif /* HAVE_DAG_API */ #endif /* HAVE_DAG_API */
} }
/*
* If there's no filter program installed, there's
* no indication to the kernel of what the snapshot
* length should be, so no snapshotting is done.
*
* Therefore, when we open the device, we install
* an "accept everything" filter with the specified
* snapshot length.
*/
total_insn.code = (u_short)(BPF_RET | BPF_K);
total_insn.jt = 0;
total_insn.jf = 0;
total_insn.k = p->snapshot;
total_prog.bf_len = 1;
total_prog.bf_insns = &total_insn;
if (!PacketSetBpf(pw->adapter, &total_prog)) {
pcap_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE,
GetLastError(), "PacketSetBpf");
status = PCAP_ERROR;
goto bad;
}
PacketSetReadTimeout(pw->adapter, p->opt.timeout); PacketSetReadTimeout(pw->adapter, p->opt.timeout);
/* disable loopback capture if requested */ /* disable loopback capture if requested */
@@ -1212,7 +1426,7 @@ pcap_activate_npf(pcap_t *p)
{ {
if (!PacketSetLoopbackBehavior(pw->adapter, NPF_DISABLE_LOOPBACK)) if (!PacketSetLoopbackBehavior(pw->adapter, NPF_DISABLE_LOOPBACK))
{ {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"Unable to disable the capture of loopback packets."); "Unable to disable the capture of loopback packets.");
goto bad; goto bad;
} }
@@ -1241,6 +1455,7 @@ pcap_activate_npf(pcap_t *p)
p->getnonblock_op = pcap_getnonblock_npf; p->getnonblock_op = pcap_getnonblock_npf;
p->setnonblock_op = pcap_setnonblock_npf; p->setnonblock_op = pcap_setnonblock_npf;
p->stats_op = pcap_stats_npf; p->stats_op = pcap_stats_npf;
p->breakloop_op = pcap_breakloop_npf;
p->stats_ex_op = pcap_stats_ex_npf; p->stats_ex_op = pcap_stats_ex_npf;
p->setbuff_op = pcap_setbuff_npf; p->setbuff_op = pcap_setbuff_npf;
p->setmode_op = pcap_setmode_npf; p->setmode_op = pcap_setmode_npf;
@@ -1287,13 +1502,177 @@ pcap_t *
pcap_create_interface(const char *device _U_, char *ebuf) pcap_create_interface(const char *device _U_, char *ebuf)
{ {
pcap_t *p; pcap_t *p;
#ifdef HAVE_PACKET_GET_TIMESTAMP_MODES
char *device_copy;
ADAPTER *adapter;
ULONG num_ts_modes;
BOOL ret;
DWORD error;
ULONG *modes;
#endif
p = pcap_create_common(ebuf, sizeof(struct pcap_win)); p = PCAP_CREATE_COMMON(ebuf, struct pcap_win);
if (p == NULL) if (p == NULL)
return (NULL); return (NULL);
p->activate_op = pcap_activate_npf; p->activate_op = pcap_activate_npf;
p->can_set_rfmon_op = pcap_can_set_rfmon_npf; p->can_set_rfmon_op = pcap_can_set_rfmon_npf;
#ifdef HAVE_PACKET_GET_TIMESTAMP_MODES
/*
* First, find out how many time stamp modes we have.
* To do that, we have to open the adapter.
*
* XXX - PacketOpenAdapter() takes a non-const pointer
* as an argument, so we make a copy of the argument and
* pass that to it.
*/
device_copy = strdup(device);
adapter = PacketOpenAdapter(device_copy);
free(device_copy);
if (adapter != NULL)
{
/*
* Get the total number of time stamp modes.
*
* The buffer for PacketGetTimestampModes() is
* a sequence of 1 or more ULONGs. What's
* passed to PacketGetTimestampModes() should have
* the total number of ULONGs in the first ULONG;
* what's returned *from* PacketGetTimestampModes()
* has the total number of time stamp modes in
* the first ULONG.
*
* Yes, that means if there are N time stamp
* modes, the first ULONG should be set to N+1
* on input, and will be set to N on output.
*
* We first make a call to PacketGetTimestampModes()
* with a pointer to a single ULONG set to 1; the
* call should fail with ERROR_MORE_DATA (unless
* there are *no* modes, but that should never
* happen), and that ULONG should be set to the
* number of modes.
*/
num_ts_modes = 1;
ret = PacketGetTimestampModes(adapter, &num_ts_modes);
if (!ret) {
/*
* OK, it failed. Did it fail with
* ERROR_MORE_DATA?
*/
error = GetLastError();
if (error != ERROR_MORE_DATA) {
/*
* No, some other error. Fail.
*/
pcap_fmt_errmsg_for_win32_err(ebuf,
PCAP_ERRBUF_SIZE, GetLastError(),
"Error calling PacketGetTimestampModes");
pcap_close(p);
return (NULL);
}
/*
* Yes, so we now know how many types to fetch.
*
* The buffer needs to have one ULONG for the
* count and num_ts_modes ULONGs for the
* num_ts_modes time stamp types.
*/
modes = (ULONG *)malloc((1 + num_ts_modes) * sizeof(ULONG));
if (modes == NULL) {
/* Out of memory. */
/* XXX SET ebuf */
pcap_close(p);
return (NULL);
}
modes[0] = 1 + num_ts_modes;
if (!PacketGetTimestampModes(adapter, modes)) {
pcap_fmt_errmsg_for_win32_err(ebuf,
PCAP_ERRBUF_SIZE, GetLastError(),
"Error calling PacketGetTimestampModes");
free(modes);
pcap_close(p);
return (NULL);
}
if (modes[0] != num_ts_modes) {
snprintf(ebuf, PCAP_ERRBUF_SIZE,
"First PacketGetTimestampModes() call gives %lu modes, second call gives %lu modes",
num_ts_modes, modes[0]);
free(modes);
pcap_close(p);
return (NULL);
}
if (num_ts_modes != 0) {
u_int num_ts_types;
/*
* Allocate a buffer big enough for
* PCAP_TSTAMP_HOST (default) plus
* the explicitly specified modes.
*/
p->tstamp_type_list = malloc((1 + modes[0]) * sizeof(u_int));
if (p->tstamp_type_list == NULL) {
/* XXX SET ebuf */
free(modes);
pcap_close(p);
return (NULL);
}
num_ts_types = 0;
p->tstamp_type_list[num_ts_types] =
PCAP_TSTAMP_HOST;
num_ts_types++;
for (ULONG i = 0; i < modes[0]; i++) {
switch (modes[i + 1]) {
case TIMESTAMPMODE_SINGLE_SYNCHRONIZATION:
/*
* Better than low-res,
* but *not* synchronized
* with the OS clock.
*/
p->tstamp_type_list[num_ts_types] =
PCAP_TSTAMP_HOST_HIPREC_UNSYNCED;
num_ts_types++;
break;
case TIMESTAMPMODE_QUERYSYSTEMTIME:
/*
* Low-res, but synchronized
* with the OS clock.
*/
p->tstamp_type_list[num_ts_types] =
PCAP_TSTAMP_HOST_LOWPREC;
num_ts_types++;
break;
case TIMESTAMPMODE_QUERYSYSTEMTIME_PRECISE:
/*
* High-res, and synchronized
* with the OS clock.
*/
p->tstamp_type_list[num_ts_types] =
PCAP_TSTAMP_HOST_HIPREC;
num_ts_types++;
break;
default:
/*
* Unknown, so we can't
* report it.
*/
break;
}
}
p->tstamp_type_count = num_ts_types;
free(modes);
}
}
PacketCloseAdapter(adapter);
}
#endif /* HAVE_PACKET_GET_TIMESTAMP_MODES */
return (p); return (p);
} }
@@ -1356,7 +1735,7 @@ pcap_setfilter_npf(pcap_t *p, struct bpf_program *fp)
} }
/* /*
* We filter at user level, since the kernel driver does't process the packets * We filter at user level, since the kernel driver doesn't process the packets
*/ */
static int static int
pcap_setfilter_win32_dag(pcap_t *p, struct bpf_program *fp) { pcap_setfilter_win32_dag(pcap_t *p, struct bpf_program *fp) {
@@ -1596,6 +1975,12 @@ get_if_flags(const char *name, bpf_u_int32 *flags, char *errbuf)
* running. * running.
*/ */
break; break;
default:
/*
* Unknown.
*/
break;
} }
} else { } else {
/* /*
@@ -1632,7 +2017,13 @@ get_if_flags(const char *name, bpf_u_int32 *flags, char *errbuf)
if (status == 0) { if (status == 0) {
/* /*
* We got the physical medium. * We got the physical medium.
*
* XXX - we might want to check for NdisPhysicalMediumWiMax
* and NdisPhysicalMediumNative802_15_4 being
* part of the enum, and check for those in the "wireless"
* case.
*/ */
DIAG_OFF_ENUM_SWITCH
switch (phys_medium) { switch (phys_medium) {
case NdisPhysicalMediumWirelessLan: case NdisPhysicalMediumWirelessLan:
@@ -1649,10 +2040,11 @@ get_if_flags(const char *name, bpf_u_int32 *flags, char *errbuf)
default: default:
/* /*
* Not wireless. * Not wireless or unknown
*/ */
break; break;
} }
DIAG_ON_ENUM_SWITCH
} }
#endif #endif
@@ -1683,6 +2075,13 @@ get_if_flags(const char *name, bpf_u_int32 *flags, char *errbuf)
*/ */
*flags |= PCAP_IF_CONNECTION_STATUS_DISCONNECTED; *flags |= PCAP_IF_CONNECTION_STATUS_DISCONNECTED;
break; break;
case MediaConnectStateUnknown:
default:
/*
* It's unknown whether it's connected or not.
*/
break;
} }
} }
#else #else
@@ -1765,7 +2164,7 @@ pcap_platform_finddevs(pcap_if_list_t *devlistp, char *errbuf)
AdaptersName = (char*) malloc(NameLength); AdaptersName = (char*) malloc(NameLength);
if (AdaptersName == NULL) if (AdaptersName == NULL)
{ {
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Cannot allocate enough memory to list the adapters."); snprintf(errbuf, PCAP_ERRBUF_SIZE, "Cannot allocate enough memory to list the adapters.");
return (-1); return (-1);
} }
@@ -1806,6 +2205,20 @@ pcap_platform_finddevs(pcap_if_list_t *devlistp, char *errbuf)
name = &AdaptersName[0]; name = &AdaptersName[0];
while (*name != '\0') { while (*name != '\0') {
bpf_u_int32 flags = 0; bpf_u_int32 flags = 0;
#ifdef HAVE_AIRPCAP_API
/*
* Is this an AirPcap device?
* If so, ignore it; it'll get added later, by the
* AirPcap code.
*/
if (device_is_airpcap(name, errbuf) == 1) {
name += strlen(name) + 1;
desc += strlen(desc) + 1;
continue;
}
#endif
#ifdef HAVE_PACKET_IS_LOOPBACK_ADAPTER #ifdef HAVE_PACKET_IS_LOOPBACK_ADAPTER
/* /*
* Is this a loopback interface? * Is this a loopback interface?
@@ -1861,10 +2274,26 @@ pcap_lookupdev(char *errbuf)
DWORD dwVersion; DWORD dwVersion;
DWORD dwWindowsMajorVersion; DWORD dwWindowsMajorVersion;
#pragma warning (push) /*
#pragma warning (disable: 4996) /* disable MSVC's GetVersion() deprecated warning here */ * We disable this in "new API" mode, because 1) in WinPcap/Npcap,
* it may return UTF-16 strings, for backwards-compatibility
* reasons, and we're also disabling the hack to make that work,
* for not-going-past-the-end-of-a-string reasons, and 2) we
* want its behavior to be consistent.
*
* In addition, it's not thread-safe, so we've marked it as
* deprecated.
*/
if (pcap_new_api) {
snprintf(errbuf, PCAP_ERRBUF_SIZE,
"pcap_lookupdev() is deprecated and is not supported in programs calling pcap_init()");
return (NULL);
}
/* disable MSVC's GetVersion() deprecated warning here */
DIAG_OFF_DEPRECATION
dwVersion = GetVersion(); /* get the OS version */ dwVersion = GetVersion(); /* get the OS version */
#pragma warning (pop) DIAG_ON_DEPRECATION
dwWindowsMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion))); dwWindowsMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
if (dwVersion >= 0x80000000 && dwWindowsMajorVersion >= 4) { if (dwVersion >= 0x80000000 && dwWindowsMajorVersion >= 4) {
@@ -1895,7 +2324,7 @@ pcap_lookupdev(char *errbuf)
if(TAdaptersName == NULL) if(TAdaptersName == NULL)
{ {
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "memory allocation failure"); (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, "memory allocation failure");
return NULL; return NULL;
} }
@@ -2056,7 +2485,7 @@ pcap_lib_version(void)
/* /*
* Generate the version string. * Generate the version string.
*/ */
char *packet_version_string = PacketGetVersion(); const char *packet_version_string = PacketGetVersion();
if (strcmp(WINPCAP_VER_STRING, packet_version_string) == 0) { if (strcmp(WINPCAP_VER_STRING, packet_version_string) == 0) {
/* /*

View File

@@ -48,7 +48,6 @@ struct rtentry;
#include <netinet/tcp.h> #include <netinet/tcp.h>
#include <netinet/tcpip.h> #include <netinet/tcpip.h>
#include <ctype.h>
#include <errno.h> #include <errno.h>
#include <netdb.h> #include <netdb.h>
#include <stdio.h> #include <stdio.h>
@@ -104,9 +103,7 @@ pcap_read_pf(pcap_t *pc, int cnt, pcap_handler callback, u_char *user)
register u_char *p, *bp; register u_char *p, *bp;
register int cc, n, buflen, inc; register int cc, n, buflen, inc;
register struct enstamp *sp; register struct enstamp *sp;
#ifdef LBL_ALIGN
struct enstamp stamp; struct enstamp stamp;
#endif
register u_int pad; register u_int pad;
again: again:
@@ -160,19 +157,17 @@ pcap_read_pf(pcap_t *pc, int cnt, pcap_handler callback, u_char *user)
} }
} }
if (cc < sizeof(*sp)) { if (cc < sizeof(*sp)) {
pcap_snprintf(pc->errbuf, sizeof(pc->errbuf), snprintf(pc->errbuf, sizeof(pc->errbuf),
"pf short read (%d)", cc); "pf short read (%d)", cc);
return (-1); return (-1);
} }
#ifdef LBL_ALIGN
if ((long)bp & 3) { if ((long)bp & 3) {
sp = &stamp; sp = &stamp;
memcpy((char *)sp, (char *)bp, sizeof(*sp)); memcpy((char *)sp, (char *)bp, sizeof(*sp));
} else } else
#endif
sp = (struct enstamp *)bp; sp = (struct enstamp *)bp;
if (sp->ens_stamplen != sizeof(*sp)) { if (sp->ens_stamplen != sizeof(*sp)) {
pcap_snprintf(pc->errbuf, sizeof(pc->errbuf), snprintf(pc->errbuf, sizeof(pc->errbuf),
"pf short stamplen (%d)", "pf short stamplen (%d)",
sp->ens_stamplen); sp->ens_stamplen);
return (-1); return (-1);
@@ -205,7 +200,7 @@ pcap_read_pf(pcap_t *pc, int cnt, pcap_handler callback, u_char *user)
* skipping that padding. * skipping that padding.
*/ */
if (pf->filtering_in_kernel || if (pf->filtering_in_kernel ||
bpf_filter(pc->fcode.bf_insns, p, sp->ens_count, buflen)) { pcap_filter(pc->fcode.bf_insns, p, sp->ens_count, buflen)) {
struct pcap_pkthdr h; struct pcap_pkthdr h;
pf->TotAccepted++; pf->TotAccepted++;
h.ts = sp->ens_tstamp; h.ts = sp->ens_tstamp;
@@ -226,7 +221,7 @@ pcap_read_pf(pcap_t *pc, int cnt, pcap_handler callback, u_char *user)
} }
static int static int
pcap_inject_pf(pcap_t *p, const void *buf, size_t size) pcap_inject_pf(pcap_t *p, const void *buf, int size)
{ {
int ret; int ret;
@@ -261,7 +256,7 @@ pcap_stats_pf(pcap_t *p, struct pcap_stat *ps)
* full. * full.
* *
* "ps_ifdrop" counts packets dropped by the network * "ps_ifdrop" counts packets dropped by the network
* inteface (regardless of whether they would have passed * interface (regardless of whether they would have passed
* the input filter, of course). * the input filter, of course).
* *
* If packet filtering is not being done in the kernel: * If packet filtering is not being done in the kernel:
@@ -273,7 +268,7 @@ pcap_stats_pf(pcap_t *p, struct pcap_stat *ps)
* the userland filter. * the userland filter.
* *
* "ps_ifdrop" counts packets dropped by the network * "ps_ifdrop" counts packets dropped by the network
* inteface (regardless of whether they would have passed * interface (regardless of whether they would have passed
* the input filter, of course). * the input filter, of course).
* *
* These statistics don't include packets not yet read from * These statistics don't include packets not yet read from
@@ -331,7 +326,7 @@ pcap_activate_pf(pcap_t *p)
p->fd = pfopen(p->opt.device, O_RDONLY); p->fd = pfopen(p->opt.device, O_RDONLY);
if (p->fd < 0) { if (p->fd < 0) {
if (errno == EACCES) { if (errno == EACCES) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"pf open: %s: Permission denied\n" "pf open: %s: Permission denied\n"
"your system may not be properly configured; see the packetfilter(4) man page", "your system may not be properly configured; see the packetfilter(4) man page",
p->opt.device); p->opt.device);
@@ -464,7 +459,7 @@ pcap_activate_pf(pcap_t *p)
* 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.
*/ */
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"unknown data-link type %u", devparams.end_dev_type); "unknown data-link type %u", devparams.end_dev_type);
err = PCAP_ERROR; err = PCAP_ERROR;
goto bad; goto bad;
@@ -540,7 +535,7 @@ pcap_create_interface(const char *device _U_, char *ebuf)
{ {
pcap_t *p; pcap_t *p;
p = pcap_create_common(ebuf, sizeof (struct pcap_pf)); p = PCAP_CREATE_COMMON(ebuf, struct pcap_pf);
if (p == NULL) if (p == NULL)
return (NULL); return (NULL);

View File

@@ -57,7 +57,7 @@ struct pcap_rdmasniff {
struct ibv_flow * flow; struct ibv_flow * flow;
struct ibv_mr * mr; struct ibv_mr * mr;
u_char * oneshot_buffer; u_char * oneshot_buffer;
unsigned port_num; unsigned long port_num;
int cq_event; int cq_event;
u_int packets_recv; u_int packets_recv;
}; };
@@ -156,7 +156,7 @@ rdmasniff_read(pcap_t *handle, int max_packets, pcap_handler callback, u_char *u
pktd = (u_char *) handle->buffer + wc.wr_id * RDMASNIFF_RECEIVE_SIZE; pktd = (u_char *) handle->buffer + wc.wr_id * RDMASNIFF_RECEIVE_SIZE;
if (handle->fcode.bf_insns == NULL || if (handle->fcode.bf_insns == NULL ||
bpf_filter(handle->fcode.bf_insns, pktd, pkth.len, pkth.caplen)) { pcap_filter(handle->fcode.bf_insns, pktd, pkth.len, pkth.caplen)) {
callback(user, &pkth, pktd); callback(user, &pkth, pktd);
++priv->packets_recv; ++priv->packets_recv;
++count; ++count;
@@ -197,21 +197,21 @@ rdmasniff_activate(pcap_t *handle)
priv->context = ibv_open_device(priv->rdma_device); priv->context = ibv_open_device(priv->rdma_device);
if (!priv->context) { if (!priv->context) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Failed to open device %s", handle->opt.device); "Failed to open device %s", handle->opt.device);
goto error; goto error;
} }
priv->pd = ibv_alloc_pd(priv->context); priv->pd = ibv_alloc_pd(priv->context);
if (!priv->pd) { if (!priv->pd) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Failed to alloc PD for device %s", handle->opt.device); "Failed to alloc PD for device %s", handle->opt.device);
goto error; goto error;
} }
priv->channel = ibv_create_comp_channel(priv->context); priv->channel = ibv_create_comp_channel(priv->context);
if (!priv->channel) { if (!priv->channel) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Failed to create comp channel for device %s", handle->opt.device); "Failed to create comp channel for device %s", handle->opt.device);
goto error; goto error;
} }
@@ -219,7 +219,7 @@ rdmasniff_activate(pcap_t *handle)
priv->cq = ibv_create_cq(priv->context, RDMASNIFF_NUM_RECEIVES, priv->cq = ibv_create_cq(priv->context, RDMASNIFF_NUM_RECEIVES,
NULL, priv->channel, 0); NULL, priv->channel, 0);
if (!priv->cq) { if (!priv->cq) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Failed to create CQ for device %s", handle->opt.device); "Failed to create CQ for device %s", handle->opt.device);
goto error; goto error;
} }
@@ -233,7 +233,7 @@ rdmasniff_activate(pcap_t *handle)
qp_init_attr.qp_type = IBV_QPT_RAW_PACKET; qp_init_attr.qp_type = IBV_QPT_RAW_PACKET;
priv->qp = ibv_create_qp(priv->pd, &qp_init_attr); priv->qp = ibv_create_qp(priv->pd, &qp_init_attr);
if (!priv->qp) { if (!priv->qp) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Failed to create QP for device %s", handle->opt.device); "Failed to create QP for device %s", handle->opt.device);
goto error; goto error;
} }
@@ -242,7 +242,7 @@ rdmasniff_activate(pcap_t *handle)
qp_attr.qp_state = IBV_QPS_INIT; qp_attr.qp_state = IBV_QPS_INIT;
qp_attr.port_num = priv->port_num; qp_attr.port_num = priv->port_num;
if (ibv_modify_qp(priv->qp, &qp_attr, IBV_QP_STATE | IBV_QP_PORT)) { if (ibv_modify_qp(priv->qp, &qp_attr, IBV_QP_STATE | IBV_QP_PORT)) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Failed to modify QP to INIT for device %s", handle->opt.device); "Failed to modify QP to INIT for device %s", handle->opt.device);
goto error; goto error;
} }
@@ -250,7 +250,7 @@ rdmasniff_activate(pcap_t *handle)
memset(&qp_attr, 0, sizeof qp_attr); memset(&qp_attr, 0, sizeof qp_attr);
qp_attr.qp_state = IBV_QPS_RTR; qp_attr.qp_state = IBV_QPS_RTR;
if (ibv_modify_qp(priv->qp, &qp_attr, IBV_QP_STATE)) { if (ibv_modify_qp(priv->qp, &qp_attr, IBV_QP_STATE)) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Failed to modify QP to RTR for device %s", handle->opt.device); "Failed to modify QP to RTR for device %s", handle->opt.device);
goto error; goto error;
} }
@@ -261,7 +261,7 @@ rdmasniff_activate(pcap_t *handle)
flow_attr.port = priv->port_num; flow_attr.port = priv->port_num;
priv->flow = ibv_create_flow(priv->qp, &flow_attr); priv->flow = ibv_create_flow(priv->qp, &flow_attr);
if (!priv->flow) { if (!priv->flow) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Failed to create flow for device %s", handle->opt.device); "Failed to create flow for device %s", handle->opt.device);
goto error; goto error;
} }
@@ -269,21 +269,21 @@ rdmasniff_activate(pcap_t *handle)
handle->bufsize = RDMASNIFF_NUM_RECEIVES * RDMASNIFF_RECEIVE_SIZE; handle->bufsize = RDMASNIFF_NUM_RECEIVES * RDMASNIFF_RECEIVE_SIZE;
handle->buffer = malloc(handle->bufsize); handle->buffer = malloc(handle->bufsize);
if (!handle->buffer) { if (!handle->buffer) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Failed to allocate receive buffer for device %s", handle->opt.device); "Failed to allocate receive buffer for device %s", handle->opt.device);
goto error; goto error;
} }
priv->oneshot_buffer = malloc(RDMASNIFF_RECEIVE_SIZE); priv->oneshot_buffer = malloc(RDMASNIFF_RECEIVE_SIZE);
if (!priv->oneshot_buffer) { if (!priv->oneshot_buffer) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Failed to allocate oneshot buffer for device %s", handle->opt.device); "Failed to allocate oneshot buffer for device %s", handle->opt.device);
goto error; goto error;
} }
priv->mr = ibv_reg_mr(priv->pd, handle->buffer, handle->bufsize, IBV_ACCESS_LOCAL_WRITE); priv->mr = ibv_reg_mr(priv->pd, handle->buffer, handle->bufsize, IBV_ACCESS_LOCAL_WRITE);
if (!priv->mr) { if (!priv->mr) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Failed to register MR for device %s", handle->opt.device); "Failed to register MR for device %s", handle->opt.device);
goto error; goto error;
} }
@@ -361,14 +361,18 @@ rdmasniff_create(const char *device, char *ebuf, int *is_ours)
int numdev; int numdev;
size_t namelen; size_t namelen;
const char *port; const char *port;
unsigned port_num; unsigned long port_num;
int i; int i;
pcap_t *p = NULL; pcap_t *p = NULL;
*is_ours = 0; *is_ours = 0;
dev_list = ibv_get_device_list(&numdev); dev_list = ibv_get_device_list(&numdev);
if (!dev_list || !numdev) { if (!dev_list) {
return NULL;
}
if (!numdev) {
ibv_free_device_list(dev_list);
return NULL; return NULL;
} }
@@ -391,7 +395,7 @@ rdmasniff_create(const char *device, char *ebuf, int *is_ours)
!strncmp(device, dev_list[i]->name, namelen)) { !strncmp(device, dev_list[i]->name, namelen)) {
*is_ours = 1; *is_ours = 1;
p = pcap_create_common(ebuf, sizeof (struct pcap_rdmasniff)); p = PCAP_CREATE_COMMON(ebuf, struct pcap_rdmasniff);
if (p) { if (p) {
p->activate_op = rdmasniff_activate; p->activate_op = rdmasniff_activate;
priv = p->priv; priv = p->priv;
@@ -415,7 +419,7 @@ rdmasniff_findalldevs(pcap_if_list_t *devlistp, char *err_str)
int ret = 0; int ret = 0;
dev_list = ibv_get_device_list(&numdev); dev_list = ibv_get_device_list(&numdev);
if (!dev_list || !numdev) { if (!dev_list) {
return 0; return 0;
} }
@@ -426,11 +430,10 @@ rdmasniff_findalldevs(pcap_if_list_t *devlistp, char *err_str)
*/ */
if (!add_dev(devlistp, dev_list[i]->name, 0, "RDMA sniffer", err_str)) { if (!add_dev(devlistp, dev_list[i]->name, 0, "RDMA sniffer", err_str)) {
ret = -1; ret = -1;
goto out; break;
} }
} }
out:
ibv_free_device_list(dev_list); ibv_free_device_list(dev_list);
return ret; return ret;
} }

File diff suppressed because it is too large Load Diff

View File

@@ -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-SAVEFILE @MAN_FILE_FORMATS@ "8 March 2015" .TH PCAP-SAVEFILE @MAN_FILE_FORMATS@ "24 April 2020"
.SH NAME .SH NAME
pcap-savefile \- libpcap savefile format pcap-savefile \- libpcap savefile format
.SH DESCRIPTION .SH DESCRIPTION
@@ -51,6 +51,8 @@ Link-layer header type
.TE .TE
.RE .RE
.PP .PP
The per-file header length is 24 octets.
.PP
All fields in the per-file header are in the byte order of the host All fields in the per-file header are in the byte order of the host
writing the file. Normally, the first field in the per-file header is a writing the file. Normally, the first field in the per-file header is a
4-byte magic number, with the value 0xa1b2c3d4. The magic number, when 4-byte magic number, with the value 0xa1b2c3d4. The magic number, when
@@ -117,6 +119,8 @@ Un-truncated length of the packet data
.TE .TE
.RE .RE
.PP .PP
The per-packet header length is 16 octets.
.PP
All fields in the per-packet header are in the byte order of the host All fields in the per-packet header are in the byte order of the host
writing the file. The per-packet header begins with a time stamp giving writing the file. The per-packet header begins with a time stamp giving
the approximate time the packet was captured; the time stamp consists of the approximate time the packet was captured; the time stamp consists of
@@ -130,4 +134,4 @@ the packet not been truncated by the snapshot length. The two lengths
will be equal if the number of bytes of packet data are less than or will be equal if the number of bytes of packet data are less than or
equal to the snapshot length. equal to the snapshot length.
.SH SEE ALSO .SH SEE ALSO
pcap(3PCAP) .BR pcap (3PCAP)

View File

@@ -17,7 +17,6 @@
#include "pcap-int.h" #include "pcap-int.h"
#include <ctype.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/socket.h> #include <sys/socket.h>
@@ -32,7 +31,6 @@
#include "pcap-septel.h" #include "pcap-septel.h"
static int septel_setfilter(pcap_t *p, struct bpf_program *fp);
static int septel_stats(pcap_t *p, struct pcap_stat *ps); static int septel_stats(pcap_t *p, struct pcap_stat *ps);
static int septel_getnonblock(pcap_t *p); static int septel_getnonblock(pcap_t *p);
static int septel_setnonblock(pcap_t *p, int nonblock); static int septel_setnonblock(pcap_t *p, int nonblock);
@@ -47,7 +45,7 @@ struct pcap_septel {
/* /*
* Read at most max_packets from the capture queue and call the callback * Read at most max_packets from the capture queue and call the callback
* for each of them. Returns the number of packets handled, -1 if an * for each of them. Returns the number of packets handled, -1 if an
* error occured, or -2 if we were told to break out of the loop. * error occurred, or -2 if we were told to break out of the loop.
*/ */
static int septel_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) { static int septel_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) {
@@ -126,7 +124,7 @@ loop:
caplen = packet_len; caplen = packet_len;
} }
/* 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) || pcap_filter(p->fcode.bf_insns, dp, packet_len, caplen)) {
/* get a time stamp , consisting of : /* get a time stamp , consisting of :
@@ -171,7 +169,7 @@ loop:
static int static int
septel_inject(pcap_t *handle, const void *buf _U_, size_t size _U_) septel_inject(pcap_t *handle, const void *buf _U_, int size _U_)
{ {
pcap_strlcpy(handle->errbuf, "Sending packets isn't supported on Septel cards", pcap_strlcpy(handle->errbuf, "Sending packets isn't supported on Septel cards",
PCAP_ERRBUF_SIZE); PCAP_ERRBUF_SIZE);
@@ -209,7 +207,7 @@ static pcap_t *septel_activate(pcap_t* handle) {
handle->read_op = septel_read; handle->read_op = septel_read;
handle->inject_op = septel_inject; handle->inject_op = septel_inject;
handle->setfilter_op = septel_setfilter; handle->setfilter_op = install_bpf_program;
handle->set_datalink_op = NULL; /* can't change data link type */ handle->set_datalink_op = NULL; /* can't change data link type */
handle->getnonblock_op = septel_getnonblock; handle->getnonblock_op = septel_getnonblock;
handle->setnonblock_op = septel_setnonblock; handle->setnonblock_op = septel_setnonblock;
@@ -235,7 +233,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(ebuf, sizeof (struct pcap_septel)); p = PCAP_CREATE_COMMON(ebuf, struct pcap_septel);
if (p == NULL) if (p == NULL)
return NULL; return NULL;
@@ -275,28 +273,6 @@ septel_findalldevs(pcap_if_list_t *devlistp, char *errbuf)
} }
/*
* Installs the given bpf filter program in the given pcap structure. There is
* no attempt to store the filter in kernel memory as that is not supported
* with Septel cards.
*/
static int septel_setfilter(pcap_t *p, struct bpf_program *fp) {
if (!p)
return -1;
if (!fp) {
strncpy(p->errbuf, "setfilter: No filter specified",
sizeof(p->errbuf));
return -1;
}
/* Make our private copy of the filter */
if (install_bpf_program(p, fp) < 0)
return -1;
return (0);
}
/* /*
* We don't support non-blocking mode. I'm not sure what we'd * We don't support non-blocking mode. I'm not sure what we'd
* do to support it and, given that we don't support select()/ * do to support it and, given that we don't support select()/
@@ -338,7 +314,7 @@ pcap_platform_finddevs(pcap_if_list_t *devlistp, char *errbuf)
pcap_t * pcap_t *
pcap_create_interface(const char *device, char *errbuf) pcap_create_interface(const char *device, char *errbuf)
{ {
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, snprintf(errbuf, PCAP_ERRBUF_SIZE,
"This version of libpcap only supports Septel cards"); "This version of libpcap only supports Septel cards");
return (NULL); return (NULL);
} }

View File

@@ -72,6 +72,14 @@ typedef struct unit {
int len; /* the current size of the inbound message */ int len; /* the current size of the inbound message */
} unit_t; } unit_t;
/*
* Private data.
* Currently contains nothing.
*/
struct pcap_sita {
int dummy;
};
static unit_t units[MAX_CHASSIS+1][MAX_GEOSLOT+1]; /* we use indexes of 1 through 8, but we reserve/waste index 0 */ static unit_t units[MAX_CHASSIS+1][MAX_GEOSLOT+1]; /* we use indexes of 1 through 8, but we reserve/waste index 0 */
static fd_set readfds; /* a place to store the file descriptors for the connections to the IOPs */ static fd_set readfds; /* a place to store the file descriptors for the connections to the IOPs */
static int max_fs; static int max_fs;
@@ -266,7 +274,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 */
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Cannot open '/etc/hosts' for reading."); /* return the nohostsfile error response */ 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 */
@@ -289,15 +297,15 @@ 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... */
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Invalid ACN name in '/etc/hosts'."); /* warn the user */ 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) { ptr2 = strdup(ptr); /* copy the IP address into our malloc'ed memory */
if (ptr2 == NULL) {
pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
errno, "malloc"); errno, "malloc");
continue; continue;
} }
strcpy(ptr2, ptr); /* copy the IP address into our malloc'ed memory */
u = &units[chassis][geoslot]; u = &units[chassis][geoslot];
u->ip = ptr2; /* and remember the whole shebang */ u->ip = ptr2; /* and remember the whole shebang */
u->chassis = chassis; u->chassis = chassis;
@@ -407,19 +415,18 @@ 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) {
pcap_snprintf(buf, bufsize, "%s_%d_%d", proto, u->chassis, u->geoslot); 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;
pcap_snprintf(buf, bufsize, "%s_%d", proto, portnum); 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) {
iface_t *iface_ptr, *iface; iface_t *iface_ptr, *iface;
char *name;
char buf[32]; char buf[32];
char *proto; char *proto;
char *port; char *port;
@@ -434,15 +441,12 @@ static char *translate_IOP_to_pcap_name(unit_t *u, char *IOPname, bpf_u_int32 if
iface->iftype = iftype; /* remember the interface type of this interface */ iface->iftype = iftype; /* remember the interface type of this interface */
name = malloc(strlen(IOPname) + 1); /* get memory for the IOP's name */ iface->IOPname = strdup(IOPnam); /* copy it and stick it into the structure */
if (name == NULL) { /* oops, we didn't get the memory requested */ if (iface->IOPname == NULL) { /* oops, we didn't get the memory requested */
fprintf(stderr, "Error...couldn't allocate memory for IOPname...value of errno is: %d\n", errno); fprintf(stderr, "Error...couldn't allocate memory for IOPname...value of errno is: %d\n", errno);
return NULL; return NULL;
} }
strcpy(name, IOPname); /* and copy it in */
iface->IOPname = name; /* and stick it into the structure */
if (strncmp(IOPname, "lo", 2) == 0) { if (strncmp(IOPname, "lo", 2) == 0) {
IOPportnum = atoi(&IOPname[2]); IOPportnum = atoi(&IOPname[2]);
switch (iftype) { switch (iftype) {
@@ -478,15 +482,12 @@ static char *translate_IOP_to_pcap_name(unit_t *u, char *IOPname, bpf_u_int32 if
return NULL; return NULL;
} }
name = malloc(strlen(buf) + 1); /* get memory for that name */ iface->name = strdup(buf); /* make a copy and stick it into the structure */
if (name == NULL) { /* oops, we didn't get the memory requested */ if (iface->name == NULL) { /* oops, we didn't get the memory requested */
fprintf(stderr, "Error...couldn't allocate memory for IOP port name...value of errno is: %d\n", errno); fprintf(stderr, "Error...couldn't allocate memory for IOP port name...value of errno is: %d\n", errno);
return NULL; return NULL;
} }
strcpy(name, buf); /* and copy it in */
iface->name = name; /* and stick it into the structure */
if (u->iface == 0) { /* if this is the first name */ if (u->iface == 0) { /* if this is the first name */
u->iface = iface; /* stick this entry at the head of the list */ u->iface = iface; /* stick this entry at the head of the list */
} else { } else {
@@ -703,7 +704,7 @@ 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 */
bigger_buffer = realloc(iff->name, strlen(newname) + 1)); bigger_buffer = realloc(iff->name, strlen(newname) + 1);
if (bigger_buffer == NULL) { /* we now re-write the name stored in the interface list */ if (bigger_buffer == NULL) { /* we now re-write the name stored in the interface list */
pcap_fmt_errmsg_for_errno(errbuf, pcap_fmt_errmsg_for_errno(errbuf,
PCAP_ERRBUF_SIZE, errno, "realloc"); PCAP_ERRBUF_SIZE, errno, "realloc");
@@ -754,9 +755,9 @@ static void wait_for_all_answers(void) {
memcpy(&working_set, &readfds, sizeof(readfds)); /* otherwise, we still have to listen for more stuff, till we timeout */ memcpy(&working_set, &readfds, sizeof(readfds)); /* otherwise, we still have to listen for more stuff, till we timeout */
retval = select(max_fs + 1, &working_set, NULL, NULL, &tv); retval = select(max_fs + 1, &working_set, NULL, NULL, &tv);
if (retval == -1) { /* an error occured !!!!! */ if (retval == -1) { /* an error occurred !!!!! */
return; return;
} else if (retval == 0) { /* timeout occured, so process what we've got sofar and return */ } else if (retval == 0) { /* timeout occurred, so process what we've got sofar and return */
printf("timeout\n"); printf("timeout\n");
return; return;
} else { } else {
@@ -883,7 +884,7 @@ static void acn_start_monitor(int fd, int snaplen, int timeout, int promiscuous,
//printf("acn_start_monitor() complete\n"); // fulko //printf("acn_start_monitor() complete\n"); // fulko
} }
static int pcap_inject_acn(pcap_t *p, const void *buf _U_, size_t size _U_) { static int pcap_inject_acn(pcap_t *p, const void *buf _U_, int size _U_) {
pcap_strlcpy(p->errbuf, "Sending packets isn't supported on ACN adapters", pcap_strlcpy(p->errbuf, "Sending packets isn't supported on ACN adapters",
PCAP_ERRBUF_SIZE); PCAP_ERRBUF_SIZE);
return (-1); return (-1);
@@ -915,12 +916,6 @@ static int pcap_setfilter_acn(pcap_t *handle, struct bpf_program *bpf) {
return 0; return 0;
} }
static int pcap_setdirection_acn(pcap_t *handle, pcap_direction_t d) {
pcap_snprintf(handle->errbuf, sizeof(handle->errbuf),
"Setting direction is not supported on ACN adapters");
return -1;
}
static int acn_read_n_bytes_with_timeout(pcap_t *handle, int count) { static int acn_read_n_bytes_with_timeout(pcap_t *handle, int count) {
struct timeval tv; struct timeval tv;
int retval, fd; int retval, fd;
@@ -940,10 +935,10 @@ static int acn_read_n_bytes_with_timeout(pcap_t *handle, int count) {
bp = handle->bp; bp = handle->bp;
while (count) { while (count) {
retval = select(fd + 1, &w_fds, NULL, NULL, &tv); retval = select(fd + 1, &w_fds, NULL, NULL, &tv);
if (retval == -1) { /* an error occured !!!!! */ if (retval == -1) { /* an error occurred !!!!! */
// fprintf(stderr, "error during packet data read\n"); // fprintf(stderr, "error during packet data read\n");
return -1; /* but we need to return a good indication to prevent unneccessary popups */ return -1; /* but we need to return a good indication to prevent unnecessary popups */
} else if (retval == 0) { /* timeout occured, so process what we've got sofar and return */ } else if (retval == 0) { /* timeout occurred, so process what we've got sofar and return */
// fprintf(stderr, "timeout during packet data read\n"); // fprintf(stderr, "timeout during packet data read\n");
return -1; return -1;
} else { } else {
@@ -997,7 +992,7 @@ static int pcap_activate_sita(pcap_t *handle) {
handle->inject_op = pcap_inject_acn; handle->inject_op = pcap_inject_acn;
handle->setfilter_op = pcap_setfilter_acn; handle->setfilter_op = pcap_setfilter_acn;
handle->setdirection_op = pcap_setdirection_acn; handle->setdirection_op = NULL; /* Not implemented */
handle->set_datalink_op = NULL; /* can't change data link type */ handle->set_datalink_op = NULL; /* can't change data link type */
handle->getnonblock_op = pcap_getnonblock_fd; handle->getnonblock_op = pcap_getnonblock_fd;
handle->setnonblock_op = pcap_setnonblock_fd; handle->setnonblock_op = pcap_setnonblock_fd;
@@ -1046,7 +1041,7 @@ static int pcap_activate_sita(pcap_t *handle) {
pcap_t *pcap_create_interface(const char *device _U_, char *ebuf) { pcap_t *pcap_create_interface(const char *device _U_, char *ebuf) {
pcap_t *p; pcap_t *p;
p = pcap_create_common(ebuf, 0); p = PCAP_CREATE_COMMON(ebuf, struct pcap_sita);
if (p == NULL) if (p == NULL)
return (NULL); return (NULL);

View File

@@ -22,7 +22,7 @@ A { text-decoration:none }
<UL> <UL>
<STRONG>Note:</STRONG> This document is part of the libpcap Git and was derived from 'pcap.3' (circa Aug/07). <STRONG>Note:</STRONG> This document is part of the libpcap Git and was derived from 'pcap.3' (circa Aug/07).
<P> <P>
The ACN provides a customized/distributed version of this library that alows SMPs to The ACN provides a customized/distributed version of this library that allows SMPs to
interact with the various IOPs within the site providing a standard mechanism interact with the various IOPs within the site providing a standard mechanism
to capture LAN and WAN message traffic. to capture LAN and WAN message traffic.
<P> <P>
@@ -31,7 +31,7 @@ A { text-decoration:none }
<TR> <TR>
<TH VALIGN=TOP>SMP</TH> <TH VALIGN=TOP>SMP</TH>
<TD VALIGN=TOP>The Supervisory Management Processor where Wireshark (or equivalent) <TD VALIGN=TOP>The Supervisory Management Processor where Wireshark (or equivalent)
runs in conjuction with a libpcap front-end.</TD> runs in conjunction with a libpcap front-end.</TD>
</TR> </TR>
<TR> <TR>
<TH VALIGN=TOP>IOP</TH> <TH VALIGN=TOP>IOP</TH>
@@ -43,7 +43,7 @@ A { text-decoration:none }
<P> <P>
Each IOP will be capable of supporting multiple connections from an SMP Each IOP will be capable of supporting multiple connections from an SMP
enabling monitoring of more than one interface at a time, each through enabling monitoring of more than one interface at a time, each through
its own seperate connection. The IOP is responsible to ensure and report its own separate connection. The IOP is responsible to ensure and report
an error if any attempt is made to monitor the same interface more than once. an error if any attempt is made to monitor the same interface more than once.
<P> <P>
There are three applications that will be supported by the ACN version of libpcap. There are three applications that will be supported by the ACN version of libpcap.
@@ -121,8 +121,8 @@ A { text-decoration:none }
<TR><TH VALIGN=TOP NOWRAP>IOP -> SMP</TH> <TR><TH VALIGN=TOP NOWRAP>IOP -> SMP</TH>
<TD> <TD>
After any required processing is complete, the IOP will return a After any required processing is complete, the IOP will return a
null terminated string containing an error message if one occured. null terminated string containing an error message if one occurred.
If no error occured, a empty string is still returned. If no error occurred, a empty string is still returned.
Errors are: Errors are:
<UL> <UL>
<LI>"Interface (xxx) does not exist." <LI>"Interface (xxx) does not exist."
@@ -298,7 +298,7 @@ A { text-decoration:none }
<TD> <TD>
The SMP reads only the next packet from the reverse channel of the connection The SMP reads only the next packet from the reverse channel of the connection
between the SMP and the IOP that provides the captured data (via calling pcap_dispatch() between the SMP and the IOP that provides the captured data (via calling pcap_dispatch()
with a count of 1) and returns seperate pointers to both the with a count of 1) and returns separate pointers to both the
packet header and packet data by invoking an internal callback. packet header and packet data by invoking an internal callback.
</TD> </TD>
</TR> </TR>
@@ -322,7 +322,7 @@ A { text-decoration:none }
<TR><TH VALIGN=TOP NOWRAP>IOP -> SMP</TH> <TR><TH VALIGN=TOP NOWRAP>IOP -> SMP</TH>
<TD> <TD>
The IOP returns a null terminated error string if it failed to accept the filter. The IOP returns a null terminated error string if it failed to accept the filter.
If no error occured, then a NULL terminated empty string is returned instead. If no error occurred, then a NULL terminated empty string is returned instead.
Errors are: Errors are:
<UL> <UL>
<LI>"Invalid BPF." <LI>"Invalid BPF."
@@ -362,7 +362,7 @@ A { text-decoration:none }
<TR><TH VALIGN=TOP NOWRAP>SMP -> IOP</TH> <TR><TH VALIGN=TOP NOWRAP>SMP -> IOP</TH>
<TD> <TD>
The SMP closes the file descriptor, and if the descriptor is that of The SMP closes the file descriptor, and if the descriptor is that of
the comminucation session with an IOP, it too is terminated. the communication session with an IOP, it too is terminated.
</TD> </TD>
</TR> </TR>
<TR><TH VALIGN=TOP NOWRAP>IOP</TH> <TR><TH VALIGN=TOP NOWRAP>IOP</TH>
@@ -370,7 +370,7 @@ A { text-decoration:none }
If the IOP detects that its communication session with an SMP If the IOP detects that its communication session with an SMP
has closed, it will terminate any monitoring in progress, has closed, it will terminate any monitoring in progress,
release any resources and close its end of the session. release any resources and close its end of the session.
It will not maintain persistance of any information or prior mode of operation. It will not maintain persistence of any information or prior mode of operation.
</TD> </TD>
</TR> </TR>
</TABLE></TD></TR> </TABLE></TD></TR>
@@ -442,7 +442,7 @@ A { text-decoration:none }
<TD VALIGN=TOP ALIGN=CENTER NOWRAP>IOP -> SMP</TD> <TD VALIGN=TOP ALIGN=CENTER NOWRAP>IOP -> SMP</TD>
<TD VALIGN=TOP>The IOP returns a list of sequences of information as <TD VALIGN=TOP>The IOP returns a list of sequences of information as
defined by the return parameter of this function call (as shown in the following table). defined by the return parameter of this function call (as shown in the following table).
Elements are specified by providing an unsigned byte preceeding the actual data that contains length information. Elements are specified by providing an unsigned byte preceding the actual data that contains length information.
<P> <P>
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=3> <TABLE BORDER=1 CELLSPACING=0 CELLPADDING=3>
<TR> <TR>
@@ -635,7 +635,7 @@ A { text-decoration:none }
<TD VALIGN=TOP>BPF program</TD> <TD VALIGN=TOP>BPF program</TD>
<TD VALIGN=TOP ALIGN=CENTER>'n'</TD> <TD VALIGN=TOP ALIGN=CENTER>'n'</TD>
<TD VALIGN=TOP>8 bytes of each command (repeated 'n' times).<BR> <TD VALIGN=TOP>8 bytes of each command (repeated 'n' times).<BR>
Each command consists of that C-style structure which contains: Each command consists of that C-style structure which contains:
<P> <P>
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=3> <TABLE BORDER=1 CELLSPACING=0 CELLPADDING=3>
<TR> <TR>
@@ -719,7 +719,7 @@ A { text-decoration:none }
<TR> <TR>
<TD VALIGN=TOP>ps_ifdrop</TD> <TD VALIGN=TOP>ps_ifdrop</TD>
<TD VALIGN=TOP ALIGN=CENTER>4</TD> <TD VALIGN=TOP ALIGN=CENTER>4</TD>
<TD VALIGN=TOP>The number of packets dropped by the network inteface <TD VALIGN=TOP>The number of packets dropped by the network interface
(regardless of whether they would have passed the input filter).</TD> (regardless of whether they would have passed the input filter).</TD>
</TR> </TR>
</TABLE> </TABLE>
@@ -839,7 +839,7 @@ A { text-decoration:none }
<UL> <UL>
PCAP, Wireshark and Tcpdump enhancements have been added to the ACN to support PCAP, Wireshark and Tcpdump enhancements have been added to the ACN to support
monitoring of its ports, however each of these facilities were focused on capturing monitoring of its ports, however each of these facilities were focused on capturing
and displaying traffic from LAN interfaces. The SITA extentions to these facilities and displaying traffic from LAN interfaces. The SITA extensions to these facilities
are used to also provide the ability to capture, filter, and display information from are used to also provide the ability to capture, filter, and display information from
an ACN's WAN ports. an ACN's WAN ports.
<P> <P>
@@ -849,7 +849,7 @@ A { text-decoration:none }
<P> <P>
<UL TYPE=DISC> <UL TYPE=DISC>
<LI>For Ethernet (like) devices, the packet format is unchanged from the standard Pcap format. <LI>For Ethernet (like) devices, the packet format is unchanged from the standard Pcap format.
<LI>For WAN devices, the packet contains a 5 byte header that preceeds the actual captured data <LI>For WAN devices, the packet contains a 5 byte header that precedes the actual captured data
described by the following table: described by the following table:
</UL> </UL>
<P> <P>

View File

@@ -10,7 +10,6 @@
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <ctype.h>
#ifndef _WIN32 #ifndef _WIN32
#include <netinet/in.h> #include <netinet/in.h>
#include <sys/mman.h> #include <sys/mman.h>
@@ -177,7 +176,7 @@ snf_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
caplen = p->snapshot; caplen = p->snapshot;
if ((p->fcode.bf_insns == NULL) || if ((p->fcode.bf_insns == NULL) ||
bpf_filter(p->fcode.bf_insns, req.pkt_addr, req.length, caplen)) { pcap_filter(p->fcode.bf_insns, req.pkt_addr, req.length, caplen)) {
hdr.ts = snf_timestamp_to_timeval(req.timestamp, p->opt.tstamp_precision); 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;
@@ -194,26 +193,7 @@ snf_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
} }
static int static int
snf_setfilter(pcap_t *p, struct bpf_program *fp) snf_inject(pcap_t *p, const void *buf _U_, int size _U_)
{
if (!p)
return -1;
if (!fp) {
strncpy(p->errbuf, "setfilter: No filter specified",
sizeof(p->errbuf));
return -1;
}
/* Make our private copy of the filter */
if (install_bpf_program(p, fp) < 0)
return -1;
return (0);
}
static int
snf_inject(pcap_t *p, const void *buf _U_, size_t size _U_)
{ {
#ifdef SNF_HAVE_INJECT_API #ifdef SNF_HAVE_INJECT_API
struct pcap_snf *ps = p->priv; struct pcap_snf *ps = p->priv;
@@ -253,7 +233,7 @@ snf_activate(pcap_t* p)
int flags = -1, ring_id = -1; int flags = -1, ring_id = -1;
if (device == NULL) { if (device == NULL) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "device is NULL"); snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "device is NULL");
return -1; return -1;
} }
@@ -327,7 +307,7 @@ snf_activate(pcap_t* p)
p->linktype = DLT_EN10MB; p->linktype = DLT_EN10MB;
p->read_op = snf_read; p->read_op = snf_read;
p->inject_op = snf_inject; p->inject_op = snf_inject;
p->setfilter_op = snf_setfilter; p->setfilter_op = install_bpf_program;
p->setdirection_op = NULL; /* Not implemented.*/ p->setdirection_op = NULL; /* Not implemented.*/
p->set_datalink_op = snf_set_datalink; p->set_datalink_op = snf_set_datalink;
p->getnonblock_op = snf_getnonblock; p->getnonblock_op = snf_getnonblock;
@@ -355,7 +335,7 @@ snf_findalldevs(pcap_if_list_t *devlistp, char *errbuf)
const char *nr = NULL; const char *nr = NULL;
if (snf_init(SNF_VERSION_API)) { if (snf_init(SNF_VERSION_API)) {
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"snf_getifaddrs: snf_init failed"); "snf_getifaddrs: snf_init failed");
return (-1); return (-1);
} }
@@ -370,7 +350,7 @@ snf_findalldevs(pcap_if_list_t *devlistp, char *errbuf)
errno = 0; errno = 0;
merge = strtol(nr, NULL, 0); merge = strtol(nr, NULL, 0);
if (errno) { if (errno) {
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"snf_getifaddrs: SNF_FLAGS is not a valid number"); "snf_getifaddrs: SNF_FLAGS is not a valid number");
return (-1); return (-1);
} }
@@ -408,7 +388,7 @@ snf_findalldevs(pcap_if_list_t *devlistp, char *errbuf)
* entry for the device, if they're not already in the * entry for the device, if they're not already in the
* list of IP addresses for the device? * list of IP addresses for the device?
*/ */
(void)pcap_snprintf(desc,MAX_DESC_LENGTH,"Myricom %ssnf%d", (void)snprintf(desc,MAX_DESC_LENGTH,"Myricom %ssnf%d",
merge ? "Merge Bitmask Port " : "", merge ? "Merge Bitmask Port " : "",
merge ? 1 << ifa->snf_ifa_portnum : ifa->snf_ifa_portnum); merge ? 1 << ifa->snf_ifa_portnum : ifa->snf_ifa_portnum);
/* /*
@@ -484,8 +464,8 @@ snf_findalldevs(pcap_if_list_t *devlistp, char *errbuf)
/* /*
* Add a new entry with all ports bitmask * Add a new entry with all ports bitmask
*/ */
(void)pcap_snprintf(name,MAX_DESC_LENGTH,"snf%d",allports); (void)snprintf(name,MAX_DESC_LENGTH,"snf%d",allports);
(void)pcap_snprintf(desc,MAX_DESC_LENGTH,"Myricom Merge Bitmask All Ports snf%d", (void)snprintf(desc,MAX_DESC_LENGTH,"Myricom Merge Bitmask All Ports snf%d",
allports); allports);
/* /*
* XXX - is there any notion of "up" and "running" that * XXX - is there any notion of "up" and "running" that
@@ -560,7 +540,7 @@ 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(ebuf, sizeof (struct pcap_snf)); p = PCAP_CREATE_COMMON(ebuf, struct pcap_snf);
if (p == NULL) if (p == NULL)
return NULL; return NULL;
ps = p->priv; ps = p->priv;
@@ -568,7 +548,6 @@ snf_create(const char *device, char *ebuf, int *is_ours)
/* /*
* We support microsecond and nanosecond time stamps. * We support microsecond and nanosecond time stamps.
*/ */
p->tstamp_precision_count = 2;
p->tstamp_precision_list = malloc(2 * sizeof(u_int)); p->tstamp_precision_list = malloc(2 * sizeof(u_int));
if (p->tstamp_precision_list == NULL) { if (p->tstamp_precision_list == NULL) {
pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE, errno, pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE, errno,
@@ -578,6 +557,7 @@ snf_create(const char *device, char *ebuf, int *is_ours)
} }
p->tstamp_precision_list[0] = PCAP_TSTAMP_PRECISION_MICRO; p->tstamp_precision_list[0] = PCAP_TSTAMP_PRECISION_MICRO;
p->tstamp_precision_list[1] = PCAP_TSTAMP_PRECISION_NANO; p->tstamp_precision_list[1] = PCAP_TSTAMP_PRECISION_NANO;
p->tstamp_precision_count = 2;
p->activate_op = snf_activate; p->activate_op = snf_activate;
ps->snf_boardnum = boardnum; ps->snf_boardnum = boardnum;
@@ -605,7 +585,7 @@ pcap_platform_finddevs(pcap_if_list_t *devlistp, char *errbuf)
pcap_t * pcap_t *
pcap_create_interface(const char *device, char *errbuf) pcap_create_interface(const char *device, char *errbuf)
{ {
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, snprintf(errbuf, PCAP_ERRBUF_SIZE,
"This version of libpcap only supports SNF cards"); "This version of libpcap only supports SNF cards");
return NULL; return NULL;
} }

View File

@@ -53,7 +53,6 @@
#include <netinet/tcp.h> #include <netinet/tcp.h>
#include <netinet/tcpip.h> #include <netinet/tcpip.h>
#include <ctype.h>
#include <errno.h> #include <errno.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@@ -190,7 +189,7 @@ pcap_read_snit(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
if (caplen > p->snapshot) if (caplen > p->snapshot)
caplen = p->snapshot; caplen = p->snapshot;
if (bpf_filter(p->fcode.bf_insns, cp, nlp->nh_pktlen, caplen)) { if (pcap_filter(p->fcode.bf_insns, cp, nlp->nh_pktlen, caplen)) {
struct pcap_pkthdr h; struct pcap_pkthdr h;
h.ts = ntp->nh_timestamp; h.ts = ntp->nh_timestamp;
h.len = nlp->nh_pktlen; h.len = nlp->nh_pktlen;
@@ -208,7 +207,7 @@ pcap_read_snit(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
} }
static int static int
pcap_inject_snit(pcap_t *p, const void *buf, size_t size) pcap_inject_snit(pcap_t *p, const void *buf, int size)
{ {
struct strbuf ctl, data; struct strbuf ctl, data;
@@ -460,7 +459,7 @@ pcap_create_interface(const char *device _U_, char *ebuf)
{ {
pcap_t *p; pcap_t *p;
p = pcap_create_common(ebuf, sizeof (struct pcap_snit)); p = PCAP_CREATE_COMMON(ebuf, struct pcap_snit);
if (p == NULL) if (p == NULL)
return (NULL); return (NULL);

View File

@@ -126,7 +126,7 @@ again:
} }
if (p->fcode.bf_insns == NULL || if (p->fcode.bf_insns == NULL ||
bpf_filter(p->fcode.bf_insns, cp, datalen, caplen)) { pcap_filter(p->fcode.bf_insns, cp, datalen, caplen)) {
struct pcap_pkthdr h; struct pcap_pkthdr h;
++psn->stat.ps_recv; ++psn->stat.ps_recv;
h.ts.tv_sec = sh->snoop_timestamp.tv_sec; h.ts.tv_sec = sh->snoop_timestamp.tv_sec;
@@ -140,7 +140,7 @@ again:
} }
static int static int
pcap_inject_snoop(pcap_t *p, const void *buf, size_t size) pcap_inject_snoop(pcap_t *p, const void *buf, int size)
{ {
int ret; int ret;
@@ -310,7 +310,7 @@ pcap_activate_snoop(pcap_t *p)
p->linktype = DLT_NULL; p->linktype = DLT_NULL;
ll_hdrlen = 4; ll_hdrlen = 4;
} else { } else {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"snoop: unknown physical layer type"); "snoop: unknown physical layer type");
goto bad; goto bad;
} }
@@ -421,7 +421,7 @@ pcap_create_interface(const char *device _U_, char *ebuf)
{ {
pcap_t *p; pcap_t *p;
p = pcap_create_common(ebuf, sizeof (struct pcap_snoop)); p = PCAP_CREATE_COMMON(ebuf, struct pcap_snoop);
if (p == NULL) if (p == NULL)
return (NULL); return (NULL);

View File

@@ -126,7 +126,6 @@ static void TcCleanup(pcap_t *p);
static int TcInject(pcap_t *p, const void *buf, int size); static int TcInject(pcap_t *p, const void *buf, int size);
static int TcRead(pcap_t *p, int cnt, pcap_handler callback, u_char *user); static int TcRead(pcap_t *p, int cnt, pcap_handler callback, u_char *user);
static int TcStats(pcap_t *p, struct pcap_stat *ps); static int TcStats(pcap_t *p, struct pcap_stat *ps);
static int TcSetFilter(pcap_t *p, struct bpf_program *fp);
#ifdef _WIN32 #ifdef _WIN32
static struct pcap_stat *TcStatsEx(pcap_t *p, int *pcap_stat_size); static struct pcap_stat *TcStatsEx(pcap_t *p, int *pcap_stat_size);
static int TcSetBuff(pcap_t *p, int dim); static int TcSetBuff(pcap_t *p, int dim);
@@ -253,58 +252,6 @@ typedef struct _PPI_HEADER
#pragma pack(pop) #pragma pack(pop)
#ifdef _WIN32 #ifdef _WIN32
//
// This wrapper around loadlibrary appends the system folder (usually c:\windows\system32)
// to the relative path of the DLL, so that the DLL is always loaded from an absolute path
// (It's no longer possible to load airpcap.dll from the application folder).
// This solves the DLL Hijacking issue discovered in August 2010
// http://blog.metasploit.com/2010/08/exploiting-dll-hijacking-flaws.html
//
HMODULE LoadLibrarySafe(LPCTSTR lpFileName)
{
TCHAR path[MAX_PATH];
TCHAR fullFileName[MAX_PATH];
UINT res;
HMODULE hModule = NULL;
do
{
res = GetSystemDirectory(path, MAX_PATH);
if (res == 0)
{
//
// some bad failure occurred;
//
break;
}
if (res > MAX_PATH)
{
//
// the buffer was not big enough
//
SetLastError(ERROR_INSUFFICIENT_BUFFER);
break;
}
if (res + 1 + _tcslen(lpFileName) + 1 < MAX_PATH)
{
memcpy(fullFileName, path, res * sizeof(TCHAR));
fullFileName[res] = _T('\\');
memcpy(&fullFileName[res + 1], lpFileName, (_tcslen(lpFileName) + 1) * sizeof(TCHAR));
hModule = LoadLibrary(fullFileName);
}
else
{
SetLastError(ERROR_INSUFFICIENT_BUFFER);
}
}while(FALSE);
return hModule;
}
/* /*
* NOTE: this function should be called by the pcap functions that can theoretically * NOTE: this function should be called by the pcap functions that can theoretically
* deal with the Tc library for the first time, namely listing the adapters and * deal with the Tc library for the first time, namely listing the adapters and
@@ -341,34 +288,34 @@ TC_API_LOAD_STATUS LoadTcFunctions(void)
currentStatus = TC_API_CANNOT_LOAD; currentStatus = TC_API_CANNOT_LOAD;
g_TcFunctions.hTcApiDllHandle = LoadLibrarySafe("TcApi.dll"); g_TcFunctions.hTcApiDllHandle = pcap_load_code("TcApi.dll");
if (g_TcFunctions.hTcApiDllHandle == NULL) break; if (g_TcFunctions.hTcApiDllHandle == NULL) break;
g_TcFunctions.QueryPortList = (TcFcnQueryPortList) GetProcAddress(g_TcFunctions.hTcApiDllHandle, "TcQueryPortList"); g_TcFunctions.QueryPortList = (TcFcnQueryPortList) pcap_find_function(g_TcFunctions.hTcApiDllHandle, "TcQueryPortList");
g_TcFunctions.FreePortList = (TcFcnFreePortList) GetProcAddress(g_TcFunctions.hTcApiDllHandle, "TcFreePortList"); g_TcFunctions.FreePortList = (TcFcnFreePortList) pcap_find_function(g_TcFunctions.hTcApiDllHandle, "TcFreePortList");
g_TcFunctions.StatusGetString = (TcFcnStatusGetString) GetProcAddress(g_TcFunctions.hTcApiDllHandle, "TcStatusGetString"); g_TcFunctions.StatusGetString = (TcFcnStatusGetString) pcap_find_function(g_TcFunctions.hTcApiDllHandle, "TcStatusGetString");
g_TcFunctions.PortGetName = (TcFcnPortGetName) GetProcAddress(g_TcFunctions.hTcApiDllHandle, "TcPortGetName"); g_TcFunctions.PortGetName = (TcFcnPortGetName) pcap_find_function(g_TcFunctions.hTcApiDllHandle, "TcPortGetName");
g_TcFunctions.PortGetDescription = (TcFcnPortGetDescription) GetProcAddress(g_TcFunctions.hTcApiDllHandle, "TcPortGetDescription"); g_TcFunctions.PortGetDescription = (TcFcnPortGetDescription) pcap_find_function(g_TcFunctions.hTcApiDllHandle, "TcPortGetDescription");
g_TcFunctions.InstanceOpenByName = (TcFcnInstanceOpenByName) GetProcAddress(g_TcFunctions.hTcApiDllHandle, "TcInstanceOpenByName"); g_TcFunctions.InstanceOpenByName = (TcFcnInstanceOpenByName) pcap_find_function(g_TcFunctions.hTcApiDllHandle, "TcInstanceOpenByName");
g_TcFunctions.InstanceClose = (TcFcnInstanceClose) GetProcAddress(g_TcFunctions.hTcApiDllHandle, "TcInstanceClose"); g_TcFunctions.InstanceClose = (TcFcnInstanceClose) pcap_find_function(g_TcFunctions.hTcApiDllHandle, "TcInstanceClose");
g_TcFunctions.InstanceSetFeature = (TcFcnInstanceSetFeature) GetProcAddress(g_TcFunctions.hTcApiDllHandle, "TcInstanceSetFeature"); g_TcFunctions.InstanceSetFeature = (TcFcnInstanceSetFeature) pcap_find_function(g_TcFunctions.hTcApiDllHandle, "TcInstanceSetFeature");
g_TcFunctions.InstanceQueryFeature = (TcFcnInstanceQueryFeature) GetProcAddress(g_TcFunctions.hTcApiDllHandle, "TcInstanceQueryFeature"); g_TcFunctions.InstanceQueryFeature = (TcFcnInstanceQueryFeature) pcap_find_function(g_TcFunctions.hTcApiDllHandle, "TcInstanceQueryFeature");
g_TcFunctions.InstanceReceivePackets = (TcFcnInstanceReceivePackets) GetProcAddress(g_TcFunctions.hTcApiDllHandle, "TcInstanceReceivePackets"); g_TcFunctions.InstanceReceivePackets = (TcFcnInstanceReceivePackets) pcap_find_function(g_TcFunctions.hTcApiDllHandle, "TcInstanceReceivePackets");
g_TcFunctions.InstanceGetReceiveWaitHandle = (TcFcnInstanceGetReceiveWaitHandle)GetProcAddress(g_TcFunctions.hTcApiDllHandle, "TcInstanceGetReceiveWaitHandle"); g_TcFunctions.InstanceGetReceiveWaitHandle = (TcFcnInstanceGetReceiveWaitHandle)pcap_find_function(g_TcFunctions.hTcApiDllHandle, "TcInstanceGetReceiveWaitHandle");
g_TcFunctions.InstanceTransmitPackets = (TcFcnInstanceTransmitPackets)GetProcAddress(g_TcFunctions.hTcApiDllHandle, "TcInstanceTransmitPackets"); g_TcFunctions.InstanceTransmitPackets = (TcFcnInstanceTransmitPackets)pcap_find_function(g_TcFunctions.hTcApiDllHandle, "TcInstanceTransmitPackets");
g_TcFunctions.InstanceQueryStatistics = (TcFcnInstanceQueryStatistics)GetProcAddress(g_TcFunctions.hTcApiDllHandle, "TcInstanceQueryStatistics"); g_TcFunctions.InstanceQueryStatistics = (TcFcnInstanceQueryStatistics)pcap_find_function(g_TcFunctions.hTcApiDllHandle, "TcInstanceQueryStatistics");
g_TcFunctions.PacketsBufferCreate = (TcFcnPacketsBufferCreate) GetProcAddress(g_TcFunctions.hTcApiDllHandle, "TcPacketsBufferCreate"); g_TcFunctions.PacketsBufferCreate = (TcFcnPacketsBufferCreate) pcap_find_function(g_TcFunctions.hTcApiDllHandle, "TcPacketsBufferCreate");
g_TcFunctions.PacketsBufferDestroy = (TcFcnPacketsBufferDestroy) GetProcAddress(g_TcFunctions.hTcApiDllHandle, "TcPacketsBufferDestroy"); g_TcFunctions.PacketsBufferDestroy = (TcFcnPacketsBufferDestroy) pcap_find_function(g_TcFunctions.hTcApiDllHandle, "TcPacketsBufferDestroy");
g_TcFunctions.PacketsBufferQueryNextPacket = (TcFcnPacketsBufferQueryNextPacket)GetProcAddress(g_TcFunctions.hTcApiDllHandle, "TcPacketsBufferQueryNextPacket"); g_TcFunctions.PacketsBufferQueryNextPacket = (TcFcnPacketsBufferQueryNextPacket)pcap_find_function(g_TcFunctions.hTcApiDllHandle, "TcPacketsBufferQueryNextPacket");
g_TcFunctions.PacketsBufferCommitNextPacket = (TcFcnPacketsBufferCommitNextPacket)GetProcAddress(g_TcFunctions.hTcApiDllHandle, "TcPacketsBufferCommitNextPacket"); g_TcFunctions.PacketsBufferCommitNextPacket = (TcFcnPacketsBufferCommitNextPacket)pcap_find_function(g_TcFunctions.hTcApiDllHandle, "TcPacketsBufferCommitNextPacket");
g_TcFunctions.StatisticsDestroy = (TcFcnStatisticsDestroy) GetProcAddress(g_TcFunctions.hTcApiDllHandle, "TcStatisticsDestroy"); g_TcFunctions.StatisticsDestroy = (TcFcnStatisticsDestroy) pcap_find_function(g_TcFunctions.hTcApiDllHandle, "TcStatisticsDestroy");
g_TcFunctions.StatisticsUpdate = (TcFcnStatisticsUpdate) GetProcAddress(g_TcFunctions.hTcApiDllHandle, "TcStatisticsUpdate"); g_TcFunctions.StatisticsUpdate = (TcFcnStatisticsUpdate) pcap_find_function(g_TcFunctions.hTcApiDllHandle, "TcStatisticsUpdate");
g_TcFunctions.StatisticsQueryValue = (TcFcnStatisticsQueryValue) GetProcAddress(g_TcFunctions.hTcApiDllHandle, "TcStatisticsQueryValue"); g_TcFunctions.StatisticsQueryValue = (TcFcnStatisticsQueryValue) pcap_find_function(g_TcFunctions.hTcApiDllHandle, "TcStatisticsQueryValue");
if ( g_TcFunctions.QueryPortList == NULL if ( g_TcFunctions.QueryPortList == NULL
|| g_TcFunctions.FreePortList == NULL || g_TcFunctions.FreePortList == NULL
@@ -552,7 +499,7 @@ TcActivate(pcap_t *p)
if (pt->PpiPacket == NULL) if (pt->PpiPacket == NULL)
{ {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Error allocating memory"); snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Error allocating memory");
return PCAP_ERROR; return PCAP_ERROR;
} }
@@ -587,7 +534,7 @@ TcActivate(pcap_t *p)
if (status != TC_SUCCESS) if (status != TC_SUCCESS)
{ {
/* Adapter detected but we are not able to open it. Return failure. */ /* Adapter detected but we are not able to open it. Return failure. */
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Error opening TurboCap adapter: %s", g_TcFunctions.StatusGetString(status)); snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Error opening TurboCap adapter: %s", g_TcFunctions.StatusGetString(status));
return PCAP_ERROR; return PCAP_ERROR;
} }
@@ -619,7 +566,7 @@ TcActivate(pcap_t *p)
if (status != TC_SUCCESS) if (status != TC_SUCCESS)
{ {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,"Error enabling reception on a TurboCap instance: %s", g_TcFunctions.StatusGetString(status)); snprintf(p->errbuf, PCAP_ERRBUF_SIZE,"Error enabling reception on a TurboCap instance: %s", g_TcFunctions.StatusGetString(status));
goto bad; goto bad;
} }
@@ -658,12 +605,12 @@ TcActivate(pcap_t *p)
if (status != TC_SUCCESS) if (status != TC_SUCCESS)
{ {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,"Error setting the read timeout a TurboCap instance: %s", g_TcFunctions.StatusGetString(status)); snprintf(p->errbuf, PCAP_ERRBUF_SIZE,"Error setting the read timeout a TurboCap instance: %s", g_TcFunctions.StatusGetString(status));
goto bad; goto bad;
} }
p->read_op = TcRead; p->read_op = TcRead;
p->setfilter_op = TcSetFilter; p->setfilter_op = install_bpf_program;
p->setdirection_op = NULL; /* Not implemented. */ p->setdirection_op = NULL; /* Not implemented. */
p->set_datalink_op = TcSetDatalink; p->set_datalink_op = TcSetDatalink;
p->getnonblock_op = TcGetNonBlock; p->getnonblock_op = TcGetNonBlock;
@@ -756,7 +703,7 @@ TcCreate(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(ebuf, sizeof (struct pcap_tc)); p = PCAP_CREATE_COMMON(ebuf, struct pcap_tc);
if (p == NULL) if (p == NULL)
return NULL; return NULL;
@@ -791,14 +738,14 @@ static int TcSetDatalink(pcap_t *p, int dlt)
static int TcGetNonBlock(pcap_t *p) static int TcGetNonBlock(pcap_t *p)
{ {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"Non-blocking mode isn't supported for TurboCap ports"); "Non-blocking mode isn't supported for TurboCap ports");
return -1; return -1;
} }
static int TcSetNonBlock(pcap_t *p, int nonblock) static int TcSetNonBlock(pcap_t *p, int nonblock)
{ {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"Non-blocking mode isn't supported for TurboCap ports"); "Non-blocking mode isn't supported for TurboCap ports");
return -1; return -1;
} }
@@ -840,7 +787,7 @@ static int TcInject(pcap_t *p, const void *buf, int size)
if (size >= 0xFFFF) if (size >= 0xFFFF)
{ {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send error: the TurboCap API does not support packets larger than 64k"); snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send error: the TurboCap API does not support packets larger than 64k");
return -1; return -1;
} }
@@ -848,7 +795,7 @@ static int TcInject(pcap_t *p, const void *buf, int size)
if (status != TC_SUCCESS) if (status != TC_SUCCESS)
{ {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send error: TcPacketsBufferCreate failure: %s (%08x)", g_TcFunctions.StatusGetString(status), status); snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send error: TcPacketsBufferCreate failure: %s (%08x)", g_TcFunctions.StatusGetString(status), status);
return -1; return -1;
} }
@@ -868,12 +815,12 @@ static int TcInject(pcap_t *p, const void *buf, int size)
if (status != TC_SUCCESS) if (status != TC_SUCCESS)
{ {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send error: TcInstanceTransmitPackets failure: %s (%08x)", g_TcFunctions.StatusGetString(status), status); snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send error: TcInstanceTransmitPackets failure: %s (%08x)", g_TcFunctions.StatusGetString(status), status);
} }
} }
else else
{ {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send error: TcPacketsBufferCommitNextPacket failure: %s (%08x)", g_TcFunctions.StatusGetString(status), status); snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send error: TcPacketsBufferCommitNextPacket failure: %s (%08x)", g_TcFunctions.StatusGetString(status), status);
} }
g_TcFunctions.PacketsBufferDestroy(buffer); g_TcFunctions.PacketsBufferDestroy(buffer);
@@ -913,7 +860,7 @@ static int TcRead(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
status = g_TcFunctions.InstanceReceivePackets(pt->TcInstance, &pt->TcPacketsBuffer); status = g_TcFunctions.InstanceReceivePackets(pt->TcInstance, &pt->TcPacketsBuffer);
if (status != TC_SUCCESS) if (status != TC_SUCCESS)
{ {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read error, TcInstanceReceivePackets failure: %s (%08x)", g_TcFunctions.StatusGetString(status), status); snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read error, TcInstanceReceivePackets failure: %s (%08x)", g_TcFunctions.StatusGetString(status), status);
return -1; return -1;
} }
} }
@@ -963,14 +910,14 @@ static int TcRead(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
if (status != TC_SUCCESS) if (status != TC_SUCCESS)
{ {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read error, TcPacketsBufferQueryNextPacket failure: %s (%08x)", g_TcFunctions.StatusGetString(status), status); snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read error, TcPacketsBufferQueryNextPacket failure: %s (%08x)", g_TcFunctions.StatusGetString(status), status);
return -1; return -1;
} }
/* No underlaying filtering system. We need to filter on our own */ /* No underlaying filtering system. We need to filter on our own */
if (p->fcode.bf_insns) if (p->fcode.bf_insns)
{ {
filterResult = bpf_filter(p->fcode.bf_insns, data, tcHeader.Length, tcHeader.CapturedLength); filterResult = pcap_filter(p->fcode.bf_insns, data, tcHeader.Length, tcHeader.CapturedLength);
if (filterResult == 0) if (filterResult == 0)
{ {
@@ -1053,7 +1000,7 @@ TcStats(pcap_t *p, struct pcap_stat *ps)
if (status != TC_SUCCESS) if (status != TC_SUCCESS)
{ {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "TurboCap error in TcInstanceQueryStatistics: %s (%08x)", g_TcFunctions.StatusGetString(status), status); snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "TurboCap error in TcInstanceQueryStatistics: %s (%08x)", g_TcFunctions.StatusGetString(status), status);
return -1; return -1;
} }
@@ -1062,7 +1009,7 @@ TcStats(pcap_t *p, struct pcap_stat *ps)
status = g_TcFunctions.StatisticsQueryValue(statistics, TC_COUNTER_INSTANCE_TOTAL_RX_PACKETS, &counter); status = g_TcFunctions.StatisticsQueryValue(statistics, TC_COUNTER_INSTANCE_TOTAL_RX_PACKETS, &counter);
if (status != TC_SUCCESS) if (status != TC_SUCCESS)
{ {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "TurboCap error in TcStatisticsQueryValue: %s (%08x)", g_TcFunctions.StatusGetString(status), status); snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "TurboCap error in TcStatisticsQueryValue: %s (%08x)", g_TcFunctions.StatusGetString(status), status);
return -1; return -1;
} }
if (counter <= (ULONGLONG)0xFFFFFFFF) if (counter <= (ULONGLONG)0xFFFFFFFF)
@@ -1077,7 +1024,7 @@ TcStats(pcap_t *p, struct pcap_stat *ps)
status = g_TcFunctions.StatisticsQueryValue(statistics, TC_COUNTER_INSTANCE_RX_DROPPED_PACKETS, &counter); status = g_TcFunctions.StatisticsQueryValue(statistics, TC_COUNTER_INSTANCE_RX_DROPPED_PACKETS, &counter);
if (status != TC_SUCCESS) if (status != TC_SUCCESS)
{ {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "TurboCap error in TcStatisticsQueryValue: %s (%08x)", g_TcFunctions.StatusGetString(status), status); snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "TurboCap error in TcStatisticsQueryValue: %s (%08x)", g_TcFunctions.StatusGetString(status), status);
return -1; return -1;
} }
if (counter <= (ULONGLONG)0xFFFFFFFF) if (counter <= (ULONGLONG)0xFFFFFFFF)
@@ -1100,27 +1047,6 @@ TcStats(pcap_t *p, struct pcap_stat *ps)
} }
/*
* We filter at user level, since the kernel driver does't process the packets
*/
static int
TcSetFilter(pcap_t *p, struct bpf_program *fp)
{
if(!fp)
{
strncpy(p->errbuf, "setfilter: No filter specified", sizeof(p->errbuf));
return -1;
}
/* Install a user level filter */
if (install_bpf_program(p, fp) < 0)
{
return -1;
}
return 0;
}
#ifdef _WIN32 #ifdef _WIN32
static struct pcap_stat * static struct pcap_stat *
TcStatsEx(pcap_t *p, int *pcap_stat_size) TcStatsEx(pcap_t *p, int *pcap_stat_size)
@@ -1136,7 +1062,7 @@ TcStatsEx(pcap_t *p, int *pcap_stat_size)
if (status != TC_SUCCESS) if (status != TC_SUCCESS)
{ {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "TurboCap error in TcInstanceQueryStatistics: %s (%08x)", g_TcFunctions.StatusGetString(status), status); snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "TurboCap error in TcInstanceQueryStatistics: %s (%08x)", g_TcFunctions.StatusGetString(status), status);
return NULL; return NULL;
} }
@@ -1145,7 +1071,7 @@ TcStatsEx(pcap_t *p, int *pcap_stat_size)
status = g_TcFunctions.StatisticsQueryValue(statistics, TC_COUNTER_INSTANCE_TOTAL_RX_PACKETS, &counter); status = g_TcFunctions.StatisticsQueryValue(statistics, TC_COUNTER_INSTANCE_TOTAL_RX_PACKETS, &counter);
if (status != TC_SUCCESS) if (status != TC_SUCCESS)
{ {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "TurboCap error in TcStatisticsQueryValue: %s (%08x)", g_TcFunctions.StatusGetString(status), status); snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "TurboCap error in TcStatisticsQueryValue: %s (%08x)", g_TcFunctions.StatusGetString(status), status);
return NULL; return NULL;
} }
if (counter <= (ULONGLONG)0xFFFFFFFF) if (counter <= (ULONGLONG)0xFFFFFFFF)
@@ -1160,7 +1086,7 @@ TcStatsEx(pcap_t *p, int *pcap_stat_size)
status = g_TcFunctions.StatisticsQueryValue(statistics, TC_COUNTER_INSTANCE_RX_DROPPED_PACKETS, &counter); status = g_TcFunctions.StatisticsQueryValue(statistics, TC_COUNTER_INSTANCE_RX_DROPPED_PACKETS, &counter);
if (status != TC_SUCCESS) if (status != TC_SUCCESS)
{ {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "TurboCap error in TcStatisticsQueryValue: %s (%08x)", g_TcFunctions.StatusGetString(status), status); snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "TurboCap error in TcStatisticsQueryValue: %s (%08x)", g_TcFunctions.StatusGetString(status), status);
return NULL; return NULL;
} }
if (counter <= (ULONGLONG)0xFFFFFFFF) if (counter <= (ULONGLONG)0xFFFFFFFF)
@@ -1198,7 +1124,7 @@ TcSetMode(pcap_t *p, int mode)
{ {
if (mode != MODE_CAPT) if (mode != MODE_CAPT)
{ {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Mode %u not supported by TurboCap devices. TurboCap only supports capture.", mode); snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Mode %u not supported by TurboCap devices. TurboCap only supports capture.", mode);
return -1; return -1;
} }
@@ -1213,7 +1139,7 @@ TcSetMinToCopy(pcap_t *p, int size)
if (size < 0) if (size < 0)
{ {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Mintocopy cannot be less than 0."); snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Mintocopy cannot be less than 0.");
return -1; return -1;
} }
@@ -1221,7 +1147,7 @@ TcSetMinToCopy(pcap_t *p, int size)
if (status != TC_SUCCESS) if (status != TC_SUCCESS)
{ {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "TurboCap error setting the mintocopy: %s (%08x)", g_TcFunctions.StatusGetString(status), status); snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "TurboCap error setting the mintocopy: %s (%08x)", g_TcFunctions.StatusGetString(status), status);
} }
return 0; return 0;
@@ -1238,7 +1164,7 @@ TcGetReceiveWaitHandle(pcap_t *p)
static int static int
TcOidGetRequest(pcap_t *p, bpf_u_int32 oid _U_, void *data _U_, size_t *lenp _U_) TcOidGetRequest(pcap_t *p, bpf_u_int32 oid _U_, void *data _U_, size_t *lenp _U_)
{ {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"An OID get request cannot be performed on a TurboCap device"); "An OID get request cannot be performed on a TurboCap device");
return PCAP_ERROR; return PCAP_ERROR;
} }
@@ -1247,7 +1173,7 @@ static int
TcOidSetRequest(pcap_t *p, bpf_u_int32 oid _U_, const void *data _U_, TcOidSetRequest(pcap_t *p, bpf_u_int32 oid _U_, const void *data _U_,
size_t *lenp _U_) size_t *lenp _U_)
{ {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"An OID set request cannot be performed on a TurboCap device"); "An OID set request cannot be performed on a TurboCap device");
return PCAP_ERROR; return PCAP_ERROR;
} }
@@ -1255,7 +1181,7 @@ TcOidSetRequest(pcap_t *p, bpf_u_int32 oid _U_, const void *data _U_,
static u_int static u_int
TcSendqueueTransmit(pcap_t *p, pcap_send_queue *queue _U_, int sync _U_) TcSendqueueTransmit(pcap_t *p, pcap_send_queue *queue _U_, int sync _U_)
{ {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"Packets cannot be bulk transmitted on a TurboCap device"); "Packets cannot be bulk transmitted on a TurboCap device");
return 0; return 0;
} }
@@ -1263,7 +1189,7 @@ TcSendqueueTransmit(pcap_t *p, pcap_send_queue *queue _U_, int sync _U_)
static int static int
TcSetUserBuffer(pcap_t *p, int size _U_) TcSetUserBuffer(pcap_t *p, int size _U_)
{ {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"The user buffer cannot be set on a TurboCap device"); "The user buffer cannot be set on a TurboCap device");
return -1; return -1;
} }
@@ -1271,7 +1197,7 @@ TcSetUserBuffer(pcap_t *p, int size _U_)
static int static int
TcLiveDump(pcap_t *p, char *filename _U_, int maxsize _U_, int maxpacks _U_) TcLiveDump(pcap_t *p, char *filename _U_, int maxsize _U_, int maxpacks _U_)
{ {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"Live packet dumping cannot be performed on a TurboCap device"); "Live packet dumping cannot be performed on a TurboCap device");
return -1; return -1;
} }
@@ -1279,7 +1205,7 @@ TcLiveDump(pcap_t *p, char *filename _U_, int maxsize _U_, int maxpacks _U_)
static int static int
TcLiveDumpEnded(pcap_t *p, int sync _U_) TcLiveDumpEnded(pcap_t *p, int sync _U_)
{ {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"Live packet dumping cannot be performed on a TurboCap device"); "Live packet dumping cannot be performed on a TurboCap device");
return -1; return -1;
} }

View File

@@ -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@ "8 March 2015" .TH PCAP-TSTAMP @MAN_MISC_INFO@ "14 July 2020"
.SH NAME .SH NAME
pcap-tstamp \- packet time stamps in libpcap pcap-tstamp \- packet time stamps in libpcap
.SH DESCRIPTION .SH DESCRIPTION
@@ -58,7 +58,20 @@ single adjustment;
different CPU cores on a multi-core or multi-processor system might be different CPU cores on a multi-core or multi-processor system might be
running at different speeds, or might not have time counters all running at different speeds, or might not have time counters all
synchronized, so packets time-stamped by different cores might not have synchronized, so packets time-stamped by different cores might not have
consistent time stamps. consistent time stamps;
.IP
some time sources, such as those that supply POSIX "seconds since the
Epoch" time, do not count leap seconds, meaning that the seconds
portion
.RB ( tv_sec )
of the time stamp might not be incremented for a leap second, so that
the fraction-of-a-second part of the time stamp might roll over past
zero but the second part would not change, or the clock might run
slightly more slowly for a period before the leap second.
.LP
For these reasons, time differences between packet time stamps will not
necessarily accurately reflect the time differences between the receipt
or transmission times of the packets.
.LP .LP
In addition, packets time-stamped by different cores might be In addition, packets time-stamped by different cores might be
time-stamped in one order and added to the queue of packets for libpcap time-stamped in one order and added to the queue of packets for libpcap
@@ -73,6 +86,9 @@ the host operating system. Those time stamps might not, however, be
synchronized with the host operating system's clock, so that, for synchronized with the host operating system's clock, so that, for
example, the time stamp of a packet might not correspond to the time example, the time stamp of a packet might not correspond to the time
stamp of an event on the host triggered by the arrival of that packet. stamp of an event on the host triggered by the arrival of that packet.
If they are synchronized with the host operating system's clock, some of
the issues listed above with time stamps supplied by the host operating
system may also apply to time stamps supplied by the capture device.
.LP .LP
Depending on the capture device and the software on the host, libpcap Depending on the capture device and the software on the host, libpcap
might allow different types of time stamp to be used. The might allow different types of time stamp to be used. The
@@ -87,15 +103,15 @@ The list might be empty, in which case no choice of time stamp type is
offered for that capture device. If the list is not empty, the offered for that capture device. If the list is not empty, the
.BR pcap_set_tstamp_type (3PCAP) .BR pcap_set_tstamp_type (3PCAP)
routine can be used after a routine can be used after a
.B pcap_create() .BR pcap_create ()
call and before a call and before a
.B pcap_activate() .BR pcap_activate ()
call to specify the type of time stamp to be used on the device. call to specify the type of time stamp to be used on the device.
The time stamp types are listed here; the first value is the #define to The time stamp types are listed here; the first value is the #define to
use in code, the second value is the value returned by use in code, the second value is the value returned by
.B pcap_tstamp_type_val_to_name(3PCAP) .BR pcap_tstamp_type_val_to_name (3PCAP)
and accepted by and accepted by
.BR pcap_tstamp_type_name_to_val(3PCAP) . .BR pcap_tstamp_type_name_to_val (3PCAP) .
.RS 5 .RS 5
.TP 5 .TP 5
.BR PCAP_TSTAMP_HOST " - " host .BR PCAP_TSTAMP_HOST " - " host
@@ -110,9 +126,14 @@ 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, synchronized with the host
synchronized with the host operating system's clock. It might be more operating system's clock. It might be more expensive to fetch than
expensive to fetch than .BR PCAP_TSTAMP_HOST_LOWPREC .
.TP 5
.BR PCAP_TSTAMP_HOST_HIPREC_UNSYNCED " - " host_hiprec_unsynced
Time stamp provided by the host on which the capture is being done.
This is a high-precision time stamp, not synchronized with the host
operating system's clock. It might be more expensive to fetch than
.BR PCAP_TSTAMP_HOST_LOWPREC . .BR PCAP_TSTAMP_HOST_LOWPREC .
.TP 5 .TP 5
.BR PCAP_TSTAMP_ADAPTER " - " adapter .BR PCAP_TSTAMP_ADAPTER " - " adapter
@@ -126,6 +147,18 @@ 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 .LP
Time stamps synchronized with the system clock can go backwards, as the
system clock can go backwards. If a clock is not in sync with the
system clock, that could be because the system clock isn't keeping
accurate time, because the other clock isn't keeping accurate time, or
both.
.LP
Host-provided time stamps generally correspond to the time when the
time-stamping code sees the packet; this could be some unknown amount of
time after the first or last bit of the packet is received by the
network adapter, due to batching of interrupts for packet arrival,
queueing delays, etc..
.LP
By default, when performing a live capture or reading from a savefile, 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, time stamps are supplied as seconds since January 1, 1970, 00:00:00 UTC,
and microseconds since that seconds value, even if higher-resolution and microseconds since that seconds value, even if higher-resolution
@@ -137,15 +170,15 @@ discarded.
The The
.BR pcap_set_tstamp_precision (3PCAP) .BR pcap_set_tstamp_precision (3PCAP)
routine can be used after a routine can be used after a
.B pcap_create() .BR pcap_create ()
call and after a call and after a
.B pcap_activate() .BR pcap_activate ()
call to specify the resolution of the time stamps to get for the device. 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 If the hardware or software cannot supply a higher-resolution time
stamp, the stamp, the
.B pcap_set_tstamp_precision() .BR pcap_set_tstamp_precision ()
call will fail, and the time stamps supplied after the call will fail, and the time stamps supplied after the
.B pcap_activate() .BR pcap_activate ()
call will have microsecond resolution. call will have microsecond resolution.
.LP .LP
When opening a savefile, the When opening a savefile, the
@@ -165,4 +198,4 @@ the time stamp supplied by the hardware or operating system and, when
reading a savefile, this does not indicate the actual precision of time reading a savefile, this does not indicate the actual precision of time
stamps in the file. stamps in the file.
.SH SEE ALSO .SH SEE ALSO
pcap(3PCAP) .BR pcap (3PCAP)

View File

@@ -35,7 +35,6 @@
* Get u_int defined, by hook or by crook. * Get u_int defined, by hook or by crook.
*/ */
#ifdef _WIN32 #ifdef _WIN32
/* /*
* This defines u_int. * This defines u_int.
*/ */

View File

@@ -41,11 +41,12 @@
#include "pcap-usb-linux.h" #include "pcap-usb-linux.h"
#include "pcap/usb.h" #include "pcap/usb.h"
#include "extract.h"
#ifdef NEED_STRERROR_H #ifdef NEED_STRERROR_H
#include "strerror.h" #include "strerror.h"
#endif #endif
#include <ctype.h>
#include <errno.h> #include <errno.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
@@ -70,10 +71,6 @@
#endif /* HAVE_LINUX_USBDEVICE_FS_H */ #endif /* HAVE_LINUX_USBDEVICE_FS_H */
#define USB_IFACE "usbmon" #define USB_IFACE "usbmon"
#define USB_TEXT_DIR_OLD "/sys/kernel/debug/usbmon"
#define USB_TEXT_DIR "/sys/kernel/debug/usb/usbmon"
#define SYS_USB_BUS_DIR "/sys/bus/usb/devices"
#define PROC_USB_BUS_DIR "/proc/bus/usb"
#define USB_LINE_LEN 4096 #define USB_LINE_LEN 4096
#if __BYTE_ORDER == __LITTLE_ENDIAN #if __BYTE_ORDER == __LITTLE_ENDIAN
@@ -131,106 +128,20 @@ struct pcap_usb_linux {
/* forward declaration */ /* forward declaration */
static int usb_activate(pcap_t *); static int usb_activate(pcap_t *);
static int usb_stats_linux(pcap_t *, struct pcap_stat *);
static int usb_stats_linux_bin(pcap_t *, struct pcap_stat *); static int usb_stats_linux_bin(pcap_t *, struct pcap_stat *);
static int usb_read_linux(pcap_t *, int , pcap_handler , u_char *);
static int usb_read_linux_bin(pcap_t *, int , pcap_handler , u_char *); static int usb_read_linux_bin(pcap_t *, int , pcap_handler , u_char *);
static int usb_read_linux_mmap(pcap_t *, int , pcap_handler , u_char *); static int usb_read_linux_mmap(pcap_t *, int , pcap_handler , u_char *);
static int usb_inject_linux(pcap_t *, const void *, size_t); static int usb_inject_linux(pcap_t *, const void *, int);
static int usb_setdirection_linux(pcap_t *, pcap_direction_t); 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 *);
static int
have_binary_usbmon(void)
{
struct utsname utsname;
char *version_component, *endp;
int major, minor, subminor;
if (uname(&utsname) == 0) {
/*
* 2.6.21 is the first release with the binary-mode
* USB monitoring.
*/
version_component = utsname.release;
major = strtol(version_component, &endp, 10);
if (endp != version_component && *endp == '.') {
/*
* OK, that was a valid major version.
* Is it 3 or greater? If so, we have binary
* mode support.
*/
if (major >= 3)
return 1;
/*
* Is it 1 or less? If so, we don't have binary
* mode support. (In fact, we don't have any
* USB monitoring....)
*/
if (major <= 1)
return 0;
}
/*
* OK, this is a 2.x kernel.
* What's the minor version?
*/
version_component = endp + 1;
minor = strtol(version_component, &endp, 10);
if (endp != version_component &&
(*endp == '.' || *endp == '\0')) {
/*
* OK, that was a valid minor version.
* Is is 2.6 or later? (There shouldn't be a
* "later", as 2.6.x went to 3.x, but we'll
* check anyway.)
*/
if (minor < 6) {
/*
* No, so no binary support (did 2.4 have
* any USB monitoring at all?)
*/
return 0;
}
/*
* OK, this is a 2.6.x kernel.
* What's the subminor version?
*/
version_component = endp + 1;
subminor = strtol(version_component, &endp, 10);
if (endp != version_component &&
(*endp == '.' || *endp == '\0')) {
/*
* OK, that was a valid subminor version.
* Is it 21 or greater?
*/
if (subminor >= 21) {
/*
* Yes - we have binary mode
* support.
*/
return 1;
}
}
}
}
/*
* Either uname() failed, in which case we just say "no binary
* mode support", or we don't have binary mode support.
*/
return 0;
}
/* 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_list_t *devlistp, int n, char *err_str) usb_dev_add(pcap_if_list_t *devlistp, int n, char *err_str)
{ {
char dev_name[10]; char dev_name[10];
char dev_descr[30]; char dev_descr[30];
pcap_snprintf(dev_name, 10, USB_IFACE"%d", n); snprintf(dev_name, 10, USB_IFACE"%d", n);
/* /*
* XXX - is there any notion of "up" and "running"? * XXX - is there any notion of "up" and "running"?
*/ */
@@ -251,7 +162,7 @@ usb_dev_add(pcap_if_list_t *devlistp, int n, char *err_str)
* PCAP_IF_CONNECTION_STATUS_CONNECTED or * PCAP_IF_CONNECTION_STATUS_CONNECTED or
* PCAP_IF_CONNECTION_STATUS_DISCONNECTED? * PCAP_IF_CONNECTION_STATUS_DISCONNECTED?
*/ */
pcap_snprintf(dev_descr, 30, "Raw USB traffic, bus number %d", n); snprintf(dev_descr, 30, "Raw USB traffic, bus number %d", n);
if (add_dev(devlistp, dev_name, 0, dev_descr, err_str) == NULL) if (add_dev(devlistp, dev_name, 0, dev_descr, err_str) == NULL)
return -1; return -1;
} }
@@ -270,115 +181,51 @@ usb_findalldevs(pcap_if_list_t *devlistp, char *err_str)
DIR* dir; DIR* dir;
int n; int n;
char* name; char* name;
size_t len;
if (have_binary_usbmon()) { /*
* We require 2.6.27 or later kernels, so we have binary-mode support.
* What do the device names look like?
* Split LINUX_USB_MON_DEV into a directory that we'll
* scan and a file name prefix that we'll check for.
*/
pcap_strlcpy(usb_mon_dir, LINUX_USB_MON_DEV, sizeof usb_mon_dir);
usb_mon_prefix = strrchr(usb_mon_dir, '/');
if (usb_mon_prefix == NULL) {
/* /*
* We have binary-mode support. * This "shouldn't happen". Just give up if it
* What do the device names look like? * does.
* Split LINUX_USB_MON_DEV into a directory that we'll
* scan and a file name prefix that we'll check for.
*/ */
pcap_strlcpy(usb_mon_dir, LINUX_USB_MON_DEV, sizeof usb_mon_dir);
usb_mon_prefix = strrchr(usb_mon_dir, '/');
if (usb_mon_prefix == NULL) {
/*
* This "shouldn't happen". Just give up if it
* does.
*/
return 0;
}
*usb_mon_prefix++ = '\0';
usb_mon_prefix_len = strlen(usb_mon_prefix);
/*
* Open the directory and scan it.
*/
dir = opendir(usb_mon_dir);
if (dir != NULL) {
while ((ret == 0) && ((data = readdir(dir)) != 0)) {
name = data->d_name;
/*
* Is this a usbmon device?
*/
if (strncmp(name, usb_mon_prefix, usb_mon_prefix_len) != 0)
continue; /* no */
/*
* What's the device number?
*/
if (sscanf(&name[usb_mon_prefix_len], "%d", &n) == 0)
continue; /* failed */
ret = usb_dev_add(devlistp, n, err_str);
}
closedir(dir);
}
return 0;
} else {
/*
* We have only text mode support.
* We don't look for the text devices because we can't
* look for them without root privileges, and we don't
* want to require root privileges to enumerate devices
* (we want to let the user to try a device and get
* an error, rather than seeing no devices and asking
* "why am I not seeing devices" and forcing a long
* process of poking to figure out whether it's "no
* privileges" or "your kernel is too old" or "the
* usbmon module isn't loaded" or...).
*
* Instead, we look to see what buses we have.
* If the kernel is so old that it doesn't have
* binary-mode support, it's also so old that
* it doesn't have a "scan all buses" device.
*
* First, try scanning sysfs USB bus directory.
*/
dir = opendir(SYS_USB_BUS_DIR);
if (dir != NULL) {
while ((ret == 0) && ((data = readdir(dir)) != 0)) {
name = data->d_name;
if (strncmp(name, "usb", 3) != 0)
continue;
if (sscanf(&name[3], "%d", &n) == 0)
continue;
ret = usb_dev_add(devlistp, n, err_str);
}
closedir(dir);
return 0;
}
/* That didn't work; try scanning procfs USB bus directory. */
dir = opendir(PROC_USB_BUS_DIR);
if (dir != NULL) {
while ((ret == 0) && ((data = readdir(dir)) != 0)) {
name = data->d_name;
len = strlen(name);
/* if this file name does not end with a number it's not of our interest */
if ((len < 1) || !isdigit(name[--len]))
continue;
while (isdigit(name[--len]));
if (sscanf(&name[len+1], "%d", &n) != 1)
continue;
ret = usb_dev_add(devlistp, n, err_str);
}
closedir(dir);
return ret;
}
/* neither of them worked */
return 0; return 0;
} }
*usb_mon_prefix++ = '\0';
usb_mon_prefix_len = strlen(usb_mon_prefix);
/*
* Open the directory and scan it.
*/
dir = opendir(usb_mon_dir);
if (dir != NULL) {
while ((ret == 0) && ((data = readdir(dir)) != 0)) {
name = data->d_name;
/*
* Is this a usbmon device?
*/
if (strncmp(name, usb_mon_prefix, usb_mon_prefix_len) != 0)
continue; /* no */
/*
* What's the device number?
*/
if (sscanf(&name[usb_mon_prefix_len], "%d", &n) == 0)
continue; /* failed */
ret = usb_dev_add(devlistp, n, err_str);
}
closedir(dir);
}
return 0;
} }
/* /*
@@ -490,6 +337,10 @@ int usb_mmap(pcap_t* handle)
#define USB_REQ_GET_DESCRIPTOR 6 #define USB_REQ_GET_DESCRIPTOR 6
#define USB_DT_DEVICE 1 #define USB_DT_DEVICE 1
#define USB_DT_CONFIG 2
#define USB_DEVICE_DESCRIPTOR_SIZE 18
#define USB_CONFIG_DESCRIPTOR_SIZE 9
/* probe the descriptors of the devices attached to the bus */ /* probe the descriptors of the devices attached to the bus */
/* the descriptors will end up in the captured packet stream */ /* the descriptors will end up in the captured packet stream */
@@ -501,12 +352,14 @@ probe_devices(int bus)
struct usbdevfs_ctrltransfer ctrl; struct usbdevfs_ctrltransfer ctrl;
struct dirent* data; struct dirent* data;
int ret = 0; int ret = 0;
char buf[sizeof("/dev/bus/usb/000/") + NAME_MAX]; char busdevpath[sizeof("/dev/bus/usb/000/") + NAME_MAX];
DIR* dir; DIR* dir;
uint8_t descriptor[USB_DEVICE_DESCRIPTOR_SIZE];
uint8_t configdesc[USB_CONFIG_DESCRIPTOR_SIZE];
/* scan usb bus directories for device nodes */ /* scan usb bus directories for device nodes */
pcap_snprintf(buf, sizeof(buf), "/dev/bus/usb/%03d", bus); snprintf(busdevpath, sizeof(busdevpath), "/dev/bus/usb/%03d", bus);
dir = opendir(buf); dir = opendir(busdevpath);
if (!dir) if (!dir)
return; return;
@@ -517,9 +370,9 @@ probe_devices(int bus)
if (name[0] == '.') if (name[0] == '.')
continue; continue;
pcap_snprintf(buf, sizeof(buf), "/dev/bus/usb/%03d/%s", bus, data->d_name); snprintf(busdevpath, sizeof(busdevpath), "/dev/bus/usb/%03d/%s", bus, data->d_name);
fd = open(buf, O_RDWR); fd = open(busdevpath, O_RDWR);
if (fd == -1) if (fd == -1)
continue; continue;
@@ -532,19 +385,43 @@ probe_devices(int bus)
ctrl.bRequest = USB_REQ_GET_DESCRIPTOR; ctrl.bRequest = USB_REQ_GET_DESCRIPTOR;
ctrl.wValue = USB_DT_DEVICE << 8; ctrl.wValue = USB_DT_DEVICE << 8;
ctrl.wIndex = 0; ctrl.wIndex = 0;
ctrl.wLength = sizeof(buf); ctrl.wLength = sizeof(descriptor);
#else #else
ctrl.requesttype = USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE; ctrl.requesttype = USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE;
ctrl.request = USB_REQ_GET_DESCRIPTOR; ctrl.request = USB_REQ_GET_DESCRIPTOR;
ctrl.value = USB_DT_DEVICE << 8; ctrl.value = USB_DT_DEVICE << 8;
ctrl.index = 0; ctrl.index = 0;
ctrl.length = sizeof(buf); ctrl.length = sizeof(descriptor);
#endif #endif
ctrl.data = buf; ctrl.data = descriptor;
ctrl.timeout = CTRL_TIMEOUT; ctrl.timeout = CTRL_TIMEOUT;
ret = ioctl(fd, USBDEVFS_CONTROL, &ctrl); ret = ioctl(fd, USBDEVFS_CONTROL, &ctrl);
/* Request CONFIGURATION descriptor alone to know wTotalLength */
#ifdef HAVE_STRUCT_USBDEVFS_CTRLTRANSFER_BREQUESTTYPE
ctrl.wValue = USB_DT_CONFIG << 8;
ctrl.wLength = sizeof(configdesc);
#else
ctrl.value = USB_DT_CONFIG << 8;
ctrl.length = sizeof(configdesc);
#endif
ctrl.data = configdesc;
ret = ioctl(fd, USBDEVFS_CONTROL, &ctrl);
if (ret >= 0) {
uint16_t wtotallength;
wtotallength = EXTRACT_LE_U_2(&configdesc[2]);
#ifdef HAVE_STRUCT_USBDEVFS_CTRLTRANSFER_BREQUESTTYPE
ctrl.wLength = wtotallength;
#else
ctrl.length = wtotallength;
#endif
ctrl.data = malloc(wtotallength);
if (ctrl.data) {
ret = ioctl(fd, USBDEVFS_CONTROL, &ctrl);
free(ctrl.data);
}
}
close(fd); close(fd);
} }
closedir(dir); closedir(dir);
@@ -586,7 +463,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(ebuf, sizeof (struct pcap_usb_linux)); p = PCAP_CREATE_COMMON(ebuf, struct pcap_usb_linux);
if (p == NULL) if (p == NULL)
return (NULL); return (NULL);
@@ -599,7 +476,6 @@ usb_activate(pcap_t* handle)
{ {
struct pcap_usb_linux *handlep = handle->priv; struct pcap_usb_linux *handlep = handle->priv;
char full_path[USB_LINE_LEN]; char full_path[USB_LINE_LEN];
int ret;
/* /*
* Turn a negative snapshot value (invalid), a snapshot value of * Turn a negative snapshot value (invalid), a snapshot value of
@@ -627,172 +503,103 @@ usb_activate(pcap_t* handle)
/*get usb bus index from device name */ /*get usb bus index from device name */
if (sscanf(handle->opt.device, USB_IFACE"%d", &handlep->bus_index) != 1) if (sscanf(handle->opt.device, USB_IFACE"%d", &handlep->bus_index) != 1)
{ {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't get USB bus index from %s", handle->opt.device); "Can't get USB bus index from %s", handle->opt.device);
return PCAP_ERROR; return PCAP_ERROR;
} }
if (have_binary_usbmon()) /*
* We require 2.6.27 or later kernels, so we have binary-mode support.
* Try to open the binary interface.
*/
snprintf(full_path, USB_LINE_LEN, LINUX_USB_MON_DEV"%d", handlep->bus_index);
handle->fd = open(full_path, O_RDONLY, 0);
if (handle->fd < 0)
{ {
/* /*
* We have binary-mode support. * The attempt failed; why?
* Try to open the binary interface.
*/ */
pcap_snprintf(full_path, USB_LINE_LEN, LINUX_USB_MON_DEV"%d", handlep->bus_index); switch (errno) {
handle->fd = open(full_path, O_RDONLY, 0);
if (handle->fd < 0) case ENOENT:
{
/* /*
* The attempt failed; why? * The device doesn't exist.
* That could either mean that there's
* no support for monitoring USB buses
* (which probably means "the usbmon
* module isn't loaded") or that there
* is but that *particular* device
* doesn't exist (no "scan all buses"
* device if the bus index is 0, no
* such bus if the bus index isn't 0).
*/ */
switch (errno) { return PCAP_ERROR_NO_SUCH_DEVICE;
case ENOENT: case EACCES:
/*
* The device doesn't exist.
* That could either mean that there's
* no support for monitoring USB buses
* (which probably means "the usbmon
* module isn't loaded") or that there
* is but that *particular* device
* doesn't exist (no "scan all buses"
* device if the bus index is 0, no
* such bus if the bus index isn't 0).
*/
return PCAP_ERROR_NO_SUCH_DEVICE;
case EACCES:
/*
* We didn't have permission to open it.
*/
return PCAP_ERROR_PERM_DENIED;
default:
/*
* Something went wrong.
*/
pcap_fmt_errmsg_for_errno(handle->errbuf,
PCAP_ERRBUF_SIZE, errno,
"Can't open USB bus file %s", full_path);
return PCAP_ERROR;
}
}
if (handle->opt.rfmon)
{
/* /*
* Monitor mode doesn't apply to USB devices. * We didn't have permission to open it.
*/ */
close(handle->fd); return PCAP_ERROR_PERM_DENIED;
return PCAP_ERROR_RFMON_NOTSUP;
}
/* try to use fast mmap access */
if (usb_mmap(handle))
{
/* We succeeded. */
handle->linktype = DLT_USB_LINUX_MMAPPED;
handle->stats_op = usb_stats_linux_bin;
handle->read_op = usb_read_linux_mmap;
handle->cleanup_op = usb_cleanup_linux_mmap;
#ifdef HAVE_LINUX_USBDEVICE_FS_H
probe_devices(handlep->bus_index);
#endif
default:
/* /*
* "handle->fd" is a real file, so * Something went wrong.
* "select()" and "poll()" work on it.
*/ */
handle->selectable_fd = handle->fd; pcap_fmt_errmsg_for_errno(handle->errbuf,
return 0; PCAP_ERRBUF_SIZE, errno,
} "Can't open USB bus file %s", full_path);
/*
* We failed; try plain binary interface access.
*
* Attempt to set the ring size as appropriate for
* the snapshot length, reducing the snapshot length
* if that'd make the ring bigger than the kernel
* supports.
*/
if (usb_set_ring_size(handle, (int)sizeof(pcap_usb_header)) == -1) {
/* Failed. */
close(handle->fd);
return PCAP_ERROR; return PCAP_ERROR;
} }
}
if (handle->opt.rfmon)
{
/*
* Monitor mode doesn't apply to USB devices.
*/
close(handle->fd);
return PCAP_ERROR_RFMON_NOTSUP;
}
/* try to use fast mmap access */
if (usb_mmap(handle))
{
/* We succeeded. */
handle->linktype = DLT_USB_LINUX_MMAPPED;
handle->stats_op = usb_stats_linux_bin; handle->stats_op = usb_stats_linux_bin;
handle->read_op = usb_read_linux_bin; handle->read_op = usb_read_linux_mmap;
handle->cleanup_op = usb_cleanup_linux_mmap;
#ifdef HAVE_LINUX_USBDEVICE_FS_H #ifdef HAVE_LINUX_USBDEVICE_FS_H
probe_devices(handlep->bus_index); probe_devices(handlep->bus_index);
#endif #endif
}
else {
/* /*
* We don't have binary mode support. * "handle->fd" is a real file, so
* Try opening the text-mode device. * "select()" and "poll()" work on it.
*/ */
pcap_snprintf(full_path, USB_LINE_LEN, USB_TEXT_DIR"/%dt", handlep->bus_index); handle->selectable_fd = handle->fd;
handle->fd = open(full_path, O_RDONLY, 0); return 0;
if (handle->fd < 0)
{
if (errno == ENOENT)
{
/*
* Not found at the new location; try
* the old location.
*/
pcap_snprintf(full_path, USB_LINE_LEN, USB_TEXT_DIR_OLD"/%dt", handlep->bus_index);
handle->fd = open(full_path, O_RDONLY, 0);
}
if (handle->fd < 0) {
if (errno == ENOENT)
{
/*
* The problem is that the file
* doesn't exist. Report that as
* "no such device". (That could
* mean "no such USB bus" or
* "monitoring not supported".)
*/
ret = PCAP_ERROR_NO_SUCH_DEVICE;
}
else if (errno == EACCES)
{
/*
* The problem is that we don't
* have sufficient permission to
* open the file. Report that.
*/
ret = PCAP_ERROR_PERM_DENIED;
}
else
{
/*
* Some other error.
*/
ret = PCAP_ERROR;
}
pcap_fmt_errmsg_for_errno(handle->errbuf,
PCAP_ERRBUF_SIZE, errno,
"Can't open USB bus file %s",
full_path);
return ret;
}
}
if (handle->opt.rfmon)
{
/*
* Monitor mode doesn't apply to USB devices.
*/
close(handle->fd);
return PCAP_ERROR_RFMON_NOTSUP;
}
handle->stats_op = usb_stats_linux;
handle->read_op = usb_read_linux;
} }
/*
* We failed; try plain binary interface access.
*
* Attempt to set the ring size as appropriate for
* the snapshot length, reducing the snapshot length
* if that'd make the ring bigger than the kernel
* supports.
*/
if (usb_set_ring_size(handle, (int)sizeof(pcap_usb_header)) == -1) {
/* Failed. */
close(handle->fd);
return PCAP_ERROR;
}
handle->stats_op = usb_stats_linux_bin;
handle->read_op = usb_read_linux_bin;
#ifdef HAVE_LINUX_USBDEVICE_FS_H
probe_devices(handlep->bus_index);
#endif
/* /*
* "handle->fd" is a real file, so "select()" and "poll()" * "handle->fd" is a real file, so "select()" and "poll()"
* work on it. * work on it.
@@ -811,308 +618,25 @@ usb_activate(pcap_t* handle)
return 0; return 0;
} }
static inline int
ascii_to_int(char c)
{
return c < 'A' ? c- '0': ((c<'a') ? c - 'A' + 10: c-'a'+10);
}
/*
* see <linux-kernel-source>/Documentation/usb/usbmon.txt and
* <linux-kernel-source>/drivers/usb/mon/mon_text.c for urb string
* format description
*/
static int static int
usb_read_linux(pcap_t *handle, int max_packets _U_, pcap_handler callback, u_char *user) usb_inject_linux(pcap_t *handle, const void *buf _U_, int size _U_)
{ {
/* see: snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
* /usr/src/linux/Documentation/usb/usbmon.txt
* for message format
*/
struct pcap_usb_linux *handlep = handle->priv;
unsigned timestamp;
int tag, cnt, ep_num, dev_addr, dummy, ret, urb_len, data_len;
char etype, pipeid1, pipeid2, status[16], urb_tag, line[USB_LINE_LEN];
char *string = line;
u_char * rawdata = handle->buffer;
struct pcap_pkthdr pkth;
pcap_usb_header* uhdr = (pcap_usb_header*)handle->buffer;
u_char urb_transfer=0;
int incoming=0;
/* ignore interrupt system call errors */
do {
ret = read(handle->fd, line, USB_LINE_LEN - 1);
if (handle->break_loop)
{
handle->break_loop = 0;
return -2;
}
} while ((ret == -1) && (errno == EINTR));
if (ret < 0)
{
if (errno == EAGAIN)
return 0; /* no data there */
pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
errno, "Can't read from fd %d", handle->fd);
return -1;
}
/* read urb header; %n argument may increment return value, but it's
* not mandatory, so does not count on it*/
string[ret] = 0;
ret = sscanf(string, "%x %d %c %c%c:%d:%d %s%n", &tag, &timestamp, &etype,
&pipeid1, &pipeid2, &dev_addr, &ep_num, status,
&cnt);
if (ret < 8)
{
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't parse USB bus message '%s', too few tokens (expected 8 got %d)",
string, ret);
return -1;
}
uhdr->id = tag;
uhdr->device_address = dev_addr;
uhdr->bus_id = handlep->bus_index;
uhdr->status = 0;
string += cnt;
/* don't use usbmon provided timestamp, since it have low precision*/
if (gettimeofday(&pkth.ts, NULL) < 0)
{
pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
errno, "Can't get timestamp for message '%s'", string);
return -1;
}
uhdr->ts_sec = pkth.ts.tv_sec;
uhdr->ts_usec = pkth.ts.tv_usec;
/* parse endpoint information */
if (pipeid1 == 'C')
urb_transfer = URB_CONTROL;
else if (pipeid1 == 'Z')
urb_transfer = URB_ISOCHRONOUS;
else if (pipeid1 == 'I')
urb_transfer = URB_INTERRUPT;
else if (pipeid1 == 'B')
urb_transfer = URB_BULK;
if (pipeid2 == 'i') {
ep_num |= URB_TRANSFER_IN;
incoming = 1;
}
if (etype == 'C')
incoming = !incoming;
/* direction check*/
if (incoming)
{
if (handle->direction == PCAP_D_OUT)
return 0;
}
else
if (handle->direction == PCAP_D_IN)
return 0;
uhdr->event_type = etype;
uhdr->transfer_type = urb_transfer;
uhdr->endpoint_number = ep_num;
pkth.caplen = sizeof(pcap_usb_header);
rawdata += sizeof(pcap_usb_header);
/* check if this is a setup packet */
ret = sscanf(status, "%d", &dummy);
if (ret != 1)
{
/* this a setup packet, setup data can be filled with underscore if
* usbmon has not been able to read them, so we must parse this fields as
* strings */
pcap_usb_setup* shdr;
char str1[3], str2[3], str3[5], str4[5], str5[5];
ret = sscanf(string, "%s %s %s %s %s%n", str1, str2, str3, str4,
str5, &cnt);
if (ret < 5)
{
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't parse USB bus message '%s', too few tokens (expected 5 got %d)",
string, ret);
return -1;
}
string += cnt;
/* try to convert to corresponding integer */
shdr = &uhdr->setup;
shdr->bmRequestType = strtoul(str1, 0, 16);
shdr->bRequest = strtoul(str2, 0, 16);
shdr->wValue = htols(strtoul(str3, 0, 16));
shdr->wIndex = htols(strtoul(str4, 0, 16));
shdr->wLength = htols(strtoul(str5, 0, 16));
uhdr->setup_flag = 0;
}
else
uhdr->setup_flag = 1;
/* read urb data */
ret = sscanf(string, " %d%n", &urb_len, &cnt);
if (ret < 1)
{
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't parse urb length from '%s'", string);
return -1;
}
string += cnt;
/* urb tag is not present if urb length is 0, so we can stop here
* text parsing */
pkth.len = urb_len+pkth.caplen;
uhdr->urb_len = urb_len;
uhdr->data_flag = 1;
data_len = 0;
if (uhdr->urb_len == 0)
goto got;
/* check for data presence; data is present if and only if urb tag is '=' */
if (sscanf(string, " %c", &urb_tag) != 1)
{
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't parse urb tag from '%s'", string);
return -1;
}
if (urb_tag != '=')
goto got;
/* skip urb tag and following space */
string += 3;
/* if we reach this point we got some urb data*/
uhdr->data_flag = 0;
/* read all urb data; if urb length is greater then the usbmon internal
* buffer length used by the kernel to spool the URB, we get only
* a partial information.
* At least until linux 2.6.17 there is no way to set usbmon intenal buffer
* length and default value is 130. */
while ((string[0] != 0) && (string[1] != 0) && (pkth.caplen < (bpf_u_int32)handle->snapshot))
{
rawdata[0] = ascii_to_int(string[0]) * 16 + ascii_to_int(string[1]);
rawdata++;
string+=2;
if (string[0] == ' ')
string++;
pkth.caplen++;
data_len++;
}
got:
uhdr->data_len = data_len;
if (pkth.caplen > (bpf_u_int32)handle->snapshot)
pkth.caplen = (bpf_u_int32)handle->snapshot;
if (handle->fcode.bf_insns == NULL ||
bpf_filter(handle->fcode.bf_insns, handle->buffer,
pkth.len, pkth.caplen)) {
handlep->packets_read++;
callback(user, &pkth, handle->buffer);
return 1;
}
return 0; /* didn't pass filter */
}
static int
usb_inject_linux(pcap_t *handle, const void *buf _U_, size_t size _U_)
{
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Packet injection is not supported on USB devices"); "Packet injection is not supported on USB devices");
return (-1); return (-1);
} }
static int
usb_stats_linux(pcap_t *handle, struct pcap_stat *stats)
{
struct pcap_usb_linux *handlep = handle->priv;
int dummy, ret, consumed, cnt;
char string[USB_LINE_LEN];
char token[USB_LINE_LEN];
char * ptr = string;
int fd;
pcap_snprintf(string, USB_LINE_LEN, USB_TEXT_DIR"/%ds", handlep->bus_index);
fd = open(string, O_RDONLY, 0);
if (fd < 0)
{
if (errno == ENOENT)
{
/*
* Not found at the new location; try the old
* location.
*/
pcap_snprintf(string, USB_LINE_LEN, USB_TEXT_DIR_OLD"/%ds", handlep->bus_index);
fd = open(string, O_RDONLY, 0);
}
if (fd < 0) {
pcap_fmt_errmsg_for_errno(handle->errbuf,
PCAP_ERRBUF_SIZE, errno,
"Can't open USB stats file %s", string);
return -1;
}
}
/* read stats line */
do {
ret = read(fd, string, USB_LINE_LEN-1);
} while ((ret == -1) && (errno == EINTR));
close(fd);
if (ret < 0)
{
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't read stats from fd %d ", fd);
return -1;
}
string[ret] = 0;
stats->ps_recv = handlep->packets_read;
stats->ps_drop = 0; /* unless we find text_lost */
stats->ps_ifdrop = 0;
/* extract info on dropped urbs */
for (consumed=0; consumed < ret; ) {
/* from the sscanf man page:
* The C standard says: "Execution of a %n directive does
* not increment the assignment count returned at the completion
* of execution" but the Corrigendum seems to contradict this.
* Do not make any assumptions on the effect of %n conversions
* on the return value and explicitly check for cnt assignmet*/
int ntok;
cnt = -1;
ntok = sscanf(ptr, "%s%n", token, &cnt);
if ((ntok < 1) || (cnt < 0))
break;
consumed += cnt;
ptr += cnt;
if (strcmp(token, "text_lost") == 0)
ntok = sscanf(ptr, "%d%n", &stats->ps_drop, &cnt);
else
ntok = sscanf(ptr, "%d%n", &dummy, &cnt);
if ((ntok != 1) || (cnt < 0))
break;
consumed += cnt;
ptr += cnt;
}
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)
{ {
/*
* It's guaranteed, at this point, that d is a valid
* direction value.
*/
p->direction = d; p->direction = d;
return 0; return 0;
} }
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)
{ {
@@ -1208,11 +732,11 @@ usb_read_linux_bin(pcap_t *handle, int max_packets _U_, pcap_handler callback, u
*/ */
pkth.len = sizeof(pcap_usb_header) + info.hdr->urb_len; pkth.len = sizeof(pcap_usb_header) + info.hdr->urb_len;
} }
pkth.ts.tv_sec = info.hdr->ts_sec; pkth.ts.tv_sec = (time_t)info.hdr->ts_sec;
pkth.ts.tv_usec = info.hdr->ts_usec; pkth.ts.tv_usec = info.hdr->ts_usec;
if (handle->fcode.bf_insns == NULL || if (handle->fcode.bf_insns == NULL ||
bpf_filter(handle->fcode.bf_insns, handle->buffer, pcap_filter(handle->fcode.bf_insns, handle->buffer,
pkth.len, pkth.caplen)) { pkth.len, pkth.caplen)) {
handlep->packets_read++; handlep->packets_read++;
callback(user, &pkth, handle->buffer); callback(user, &pkth, handle->buffer);
@@ -1323,11 +847,11 @@ usb_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback, u_ch
pkth.len = sizeof(pcap_usb_header_mmapped) + pkth.len = sizeof(pcap_usb_header_mmapped) +
(hdr->ndesc * sizeof (usb_isodesc)) + hdr->urb_len; (hdr->ndesc * sizeof (usb_isodesc)) + hdr->urb_len;
} }
pkth.ts.tv_sec = hdr->ts_sec; pkth.ts.tv_sec = (time_t)hdr->ts_sec;
pkth.ts.tv_usec = hdr->ts_usec; pkth.ts.tv_usec = hdr->ts_usec;
if (handle->fcode.bf_insns == NULL || if (handle->fcode.bf_insns == NULL ||
bpf_filter(handle->fcode.bf_insns, (u_char*) hdr, pcap_filter(handle->fcode.bf_insns, (u_char*) hdr,
pkth.len, pkth.caplen)) { pkth.len, pkth.caplen)) {
handlep->packets_read++; handlep->packets_read++;
callback(user, &pkth, (u_char*) hdr); callback(user, &pkth, (u_char*) hdr);
@@ -1335,7 +859,7 @@ usb_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback, u_ch
} }
} }
/* with max_packets specifying "unlimited" we stop afer the first chunk*/ /* with max_packets specifying "unlimited" we stop after the first chunk*/
if (PACKET_COUNT_IS_UNLIMITED(max_packets) || (packets == max_packets)) if (PACKET_COUNT_IS_UNLIMITED(max_packets) || (packets == max_packets))
break; break;
} }

View File

@@ -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 "25 July 2018" .TH PCAP 3PCAP "9 September 2020"
.SH NAME .SH NAME
pcap \- Packet Capture library pcap \- Packet Capture library
.SH SYNOPSIS .SH SYNOPSIS
@@ -35,12 +35,69 @@ on the network, even those destined for other hosts, are accessible
through this mechanism. through this mechanism.
It also supports saving captured packets to a ``savefile'', and reading It also supports saving captured packets to a ``savefile'', and reading
packets from a ``savefile''. packets from a ``savefile''.
.SS Initializing
.BR pcap_init ()
initializes the library. It takes an argument giving options;
currently, the options are:
.TP
.B PCAP_CHAR_ENC_LOCAL
Treat all strings supplied as arguments, and return all strings to the
caller, as being in the local character encoding.
.TP
.B PCAP_CHAR_ENC_UTF_8
Treat all strings supplied as arguments, and return all strings to the
caller, as being in UTF-8.
.PP
On UNIX-like systems, the local character encoding is assumed to be
UTF-8, so no character encoding transformations are done.
.PP
On Windows, the local character encoding is the local ANSI code page.
.PP
If
.BR pcap_init ()
is called, the deprecated
.BR pcap_lookupdev ()
routine always fails, so it should not be used, and, on Windows,
.BR pcap_create ()
does not attempt to handle UTF-16LE strings.
.PP
If
.BR pcap_init ()
is not called, strings are treated as being in the local ANSI code page
on Windows,
.BR pcap_lookupdev ()
will succeed if there is a device on which to capture, and
.BR pcap_create ()
makes an attempt to check whether the string passed as an argument is a
UTF-16LE string - note that this attempt is unsafe, as it may run past
the end of the string - to handle
.BR pcap_lookupdev ()
returning a UTF-16LE string. Programs that don't call
.BR pcap_init ()
should, on Windows, call
.BR pcap_wsockinit ()
to initialize Winsock; this is not necessary if
.BR pcap_init ()
is called, as
.BR pcap_init ()
will initialize Winsock itself on Windows.
.TP
.B Routines
.RS
.TP
.BR pcap_init (3PCAP)
initialize the library
.RE
.SS Opening a capture handle for reading .SS Opening a capture handle for reading
To open a handle for a live capture, given the name of the network or To open a handle for a live capture, given the name of the network or
other interface on which the capture should be done, call other interface on which the capture should be done, call
.BR pcap_create (), .BR pcap_create (),
set the appropriate options on the handle, and then activate it with set the appropriate options on the handle, and then activate it with
.BR pcap_activate (). .BR pcap_activate ().
If
.BR pcap_activate ()
fails, the handle should be closed with
.BR pcap_close ().
.PP .PP
To obtain a list of devices that can be opened for a live capture, call To obtain a list of devices that can be opened for a live capture, call
.BR pcap_findalldevs (); .BR pcap_findalldevs ();
@@ -121,7 +178,9 @@ Note that even if an application does not set promiscuous mode, the
adapter could well be in promiscuous mode for some other reason. adapter could well be in promiscuous mode for some other reason.
.IP .IP
For now, this doesn't work on the "any" device; if an argument of "any" For now, this doesn't work on the "any" device; if an argument of "any"
or NULL is supplied, the setting of promiscuous mode is ignored. or
.B NULL
is supplied, the setting of promiscuous mode is ignored.
.IP .IP
Promiscuous mode is set with Promiscuous mode is set with
.BR pcap_set_promisc (). .BR pcap_set_promisc ().
@@ -249,7 +308,7 @@ that device. A user can be given that privilege by, for example, adding
that privilege to the user's that privilege to the user's
.B defaultpriv .B defaultpriv
key with the key with the
.B usermod (@MAN_ADMIN_COMMANDS@) .BR usermod (@MAN_ADMIN_COMMANDS@)
command. command.
.TP .TP
.B Under HP-UX with DLPI: .B Under HP-UX with DLPI:
@@ -262,14 +321,11 @@ setuid to root.
.TP .TP
.B Under Linux: .B Under Linux:
You must be root or the application capturing packets must be installed You must be root or the application capturing packets must be installed
setuid to root (unless your distribution has a kernel setuid to root, unless your distribution has a kernel
that supports capability bits such as CAP_NET_RAW and code to allow that supports capability bits such as CAP_NET_RAW and code to allow
those capability bits to be given to particular accounts and to cause those capability bits to be given to particular accounts and to cause
those bits to be set on a user's initial processes when they log in, in those bits to be set on a user's initial processes when they log in, in
which case you must have CAP_NET_RAW in order to capture and which case you must have CAP_NET_RAW in order to capture.
CAP_NET_ADMIN to enumerate network devices with, for example, the
.B \-D
flag).
.TP .TP
.B Under ULTRIX and Digital UNIX/Tru64 UNIX: .B Under ULTRIX and Digital UNIX/Tru64 UNIX:
Any user may capture network traffic. Any user may capture network traffic.
@@ -320,6 +376,8 @@ any given link-layer header type, such as
for Ethernet. For example, the "any" device on Linux will have a for Ethernet. For example, the "any" device on Linux will have a
link-layer header type of link-layer header type of
.B DLT_LINUX_SLL .B DLT_LINUX_SLL
or
.B DLT_LINUX_SLL2
even if all devices on the system at the time the "any" device is opened even if all devices on the system at the time the "any" device is opened
have some other data link type, such as have some other data link type, such as
.B DLT_EN10MB .B DLT_EN10MB
@@ -515,7 +573,11 @@ set link-layer header type for a device
get name for a link-layer header type get name for a link-layer header type
.TP .TP
.BR pcap_datalink_val_to_description (3PCAP) .BR pcap_datalink_val_to_description (3PCAP)
.PD 0
.TP
.BR pcap_datalink_val_to_description_or_dlt (3PCAP)
get description for a link-layer header type get description for a link-layer header type
.PD
.TP .TP
.BR pcap_datalink_name_to_val (3PCAP) .BR pcap_datalink_name_to_val (3PCAP)
get link-layer header type corresponding to a name get link-layer header type corresponding to a name
@@ -585,7 +647,9 @@ packet. It returns a
.I const u_char .I const u_char
to the first to the first
.B caplen .B caplen
bytes of the packet on success, and NULL on error. bytes of the packet on success, and
.B NULL
on error.
.PP .PP
.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
@@ -648,7 +712,7 @@ from the device.
Not all handles have such a descriptor available; Not all handles have such a descriptor available;
.BR pcap_get_selectable_fd () .BR pcap_get_selectable_fd ()
will return will return
.B PCAP_ERROR .B \-1
if no such descriptor is available. If no such if no such descriptor is available. If no such
descriptor is available, this may be because the device must be polled descriptor is available, this may be because the device must be polled
periodically for packets; in that case, periodically for packets; in that case,
@@ -659,7 +723,9 @@ whose value can be used as a timeout in those routines. When the
routine returns, an attmept should be made to read packets from the routine returns, an attmept should be made to read packets from the
device. If device. If
.BR pcap_get_required_select_timeout () .BR pcap_get_required_select_timeout ()
returns NULL, no such timeout is available, and those routines cannot be returns
.BR NULL ,
no such timeout is available, and those routines cannot be
used with the device. used with the device.
.PP .PP
In addition, for various In addition, for various
@@ -723,13 +789,12 @@ and
.BR poll (2) .BR poll (2)
.TP .TP
.BR pcap_get_required_select_timeout (3PCAP) .BR pcap_get_required_select_timeout (3PCAP)
if no descriptor usable with attempt to get a timeout required for using a
.B pcap_t
in calls such as
.BR select (2) .BR select (2)
and and
.BR poll (2) .BR poll (2)
is available for the
.BR pcap_t ,
attempt to get a timeout usable with those routines
.RE .RE
.SS Filters .SS Filters
In order to cause only certain packets to be returned when reading In order to cause only certain packets to be returned when reading
@@ -893,8 +958,9 @@ for a live capture, using
.BR pcap_inject () .BR pcap_inject ()
or or
.BR pcap_sendpacket (). .BR pcap_sendpacket ().
(The two routines exist for compatibility with both OpenBSD and WinPcap; (The two routines exist for compatibility with both OpenBSD and
they perform the same function, but have different return values.) WinPcap/Npcap; they perform the same function, but have different return
values.)
.TP .TP
.B Routines .B Routines
.RS .RS
@@ -958,8 +1024,12 @@ use an
script or some other configuration script to check whether the libpcap script or some other configuration script to check whether the libpcap
1.0 APIs are available and use them only if they are. 1.0 APIs are available and use them only if they are.
.SH SEE ALSO .SH SEE ALSO
autoconf(1), tcpdump(1), tcpslice(1), pcap-filter(@MAN_MISC_INFO@), pfconfig(8), .BR autoconf (1),
usermod(@MAN_ADMIN_COMMANDS@) .BR tcpdump (1),
.BR tcpslice (1),
.BR pcap-filter (@MAN_MISC_INFO@),
.BR pfconfig (8),
.BR usermod (@MAN_ADMIN_COMMANDS@)
.SH AUTHORS .SH AUTHORS
The original authors of libpcap are: The original authors of libpcap are:
.LP .LP
@@ -978,5 +1048,5 @@ To report a security issue please send an e-mail to security@tcpdump.org.
.LP .LP
To report bugs and other problems, contribute patches, request a To report bugs and other problems, contribute patches, request a
feature, provide generic feedback etc please see the file feature, provide generic feedback etc please see the file
.I CONTRIBUTING .I CONTRIBUTING.md
in the libpcap source tree root. in the libpcap source tree root.

File diff suppressed because it is too large Load Diff

View File

@@ -58,10 +58,21 @@
* I don't have earlier versions available to check), or QNX-style * I don't have earlier versions available to check), or QNX-style
* multiple-include protection (as per GitHub pull request #394). * multiple-include protection (as per GitHub pull request #394).
* *
* We trust that they will define structures and macros and types in
* a fashion that's source-compatible and binary-compatible with our
* definitions.
*
* We do not check for BPF_MAJOR_VERSION, as that's defined by * We do not check for BPF_MAJOR_VERSION, as that's defined by
* <linux/filter.h>, which is directly or indirectly included in some * <linux/filter.h>, which is directly or indirectly included in some
* programs that also include pcap.h, and <linux/filter.h> doesn't * programs that also include pcap.h, and <linux/filter.h> doesn't
* define stuff we need. * define stuff we need. We *do* protect against <linux/filter.h>
* defining various macros for BPF code itself; <linux/filter.h> says
*
* Try and keep these values and structures similar to BSD, especially
* the BPF code definitions which need to match so you can share filters
*
* so we trust that it will define them in a fashion that's source-compatible
* and binary-compatible with our definitions.
* *
* This also provides our own multiple-include protection. * This also provides our own multiple-include protection.
*/ */
@@ -70,6 +81,8 @@
#include <pcap/funcattrs.h> #include <pcap/funcattrs.h>
#include <pcap/dlt.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@@ -106,8 +119,6 @@ struct bpf_program {
struct bpf_insn *bf_insns; struct bpf_insn *bf_insns;
}; };
#include <pcap/dlt.h>
/* /*
* The instruction encodings. * The instruction encodings.
* *
@@ -240,12 +251,34 @@ struct bpf_insn {
/* /*
* Macros for insn array initializers. * Macros for insn array initializers.
*
* In case somebody's included <linux/filter.h>, or something else that
* gives the kernel's definitions of BPF statements, get rid of its
* definitions, so we can supply ours instead. If some kernel's
* definitions aren't *binary-compatible* with what BPF has had
* since it first sprung from the brows of Van Jacobson and Steve
* McCanne, that kernel should be fixed.
*/ */
#ifdef BPF_STMT
#undef BPF_STMT
#endif
#define BPF_STMT(code, k) { (u_short)(code), 0, 0, k } #define BPF_STMT(code, k) { (u_short)(code), 0, 0, k }
#ifdef BPF_JUMP
#undef BPF_JUMP
#endif
#define BPF_JUMP(code, k, jt, jf) { (u_short)(code), jt, jf, k } #define BPF_JUMP(code, k, jt, jf) { (u_short)(code), jt, jf, k }
PCAP_API int bpf_validate(const struct bpf_insn *, int); PCAP_AVAILABLE_0_4
PCAP_API u_int bpf_filter(const struct bpf_insn *, const u_char *, u_int, u_int); PCAP_API u_int bpf_filter(const struct bpf_insn *, const u_char *, u_int, u_int);
PCAP_AVAILABLE_0_6
PCAP_API int bpf_validate(const struct bpf_insn *f, int len);
PCAP_AVAILABLE_0_4
PCAP_API char *bpf_image(const struct bpf_insn *, int);
PCAP_AVAILABLE_0_6
PCAP_API void bpf_dump(const struct bpf_program *, int);
/* /*
* Number of scratch memory words (for BPF_LD|BPF_MEM and BPF_ST). * Number of scratch memory words (for BPF_LD|BPF_MEM and BPF_ST).

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