mirror of
https://git.freebsd.org/src.git
synced 2026-01-11 19:57:22 +00:00
Import libpcap 1.10.6
This commit is contained in:
parent
025be3f592
commit
0a1fbf4c24
69 changed files with 3222 additions and 1406 deletions
107
CHANGES
107
CHANGES
|
|
@ -1,3 +1,110 @@
|
|||
Tuesday, December 30, 2025 / The Tcpdump Group
|
||||
Summary for 1.10.6 libpcap release
|
||||
General:
|
||||
Fix "tcpdump -i <n>" for something-only libpcap builds.
|
||||
gencode: Fix an undefined behavior in gen_mcode().
|
||||
gencode: Add a missing free() in gen_scode().
|
||||
Remove "DLT_" from the descriptions of two dlt_choices[] entries.
|
||||
Report the size of time_t in the version string.
|
||||
Validate remote capture source strings better.
|
||||
CVE-2025-11961: Fix OOBR and OOBW in pcap_ether_aton().
|
||||
Source code:
|
||||
Remove some unneeded includes.
|
||||
pcapint_find_function() changed to return "void *" to avoid
|
||||
warnings.
|
||||
Clean up code that computes the length of a netmask.
|
||||
Mind netmap support in pcap_lib_version().
|
||||
Link-layer types:
|
||||
Add LINKTYPE_ETW/DLT_ETW.
|
||||
Add LINKTYPE_NETANALYZER_NG/DLT_NETANALYZER_NG (pull request
|
||||
#1008).
|
||||
Add LINKTYPE_ZBOSS_NCP/DLT_ZBOSS_NCP.
|
||||
Add LINKTYPE_USB_2_0_LOW_SPEED/DLT_USB_2_0_LOW_SPEED,
|
||||
LINKTYPE_USB_2_0_FULL_SPEED/DLT_USB_2_0_FULL_SPEED,
|
||||
LINKTYPE_USB_2_0_HIGH_SPEED/DLT_USB_2_0_HIGH_SPEED
|
||||
Add LINKTYPE_AUERSWALD_LOG/DLT_AUERSWALD_LOG.
|
||||
Add LINKTYPE_ZWAVE_TAP/DLT_ZWAVE_TAP.
|
||||
Add LINKTYPE_SILABS_DEBUG_CHANNEL/DLT_SILABS_DEBUG_CHANNEL.
|
||||
Add LINKTYPE_FIRA_UCI/DLT_FIRA_UCI.
|
||||
Rename LINKTYPE_IPMB_LINUX/DLT_IPMB_LINUX to
|
||||
LINKTYPE_I2C_LINUX/DLT_I2C_LINUX, as it's really just an
|
||||
encapsulation of I2C, and is also being used for HDMI DDC.
|
||||
Keep DLT_IPMB_LINUX around as a #define for backwards
|
||||
compatibility.
|
||||
Add LINKTYPE_MDB/DLT_MDB.
|
||||
Add LINKTYPE_DECT_NR/DLT_DECT_NR.
|
||||
Add LINKTYPE_EDK2_MM/DLT_EDK2_MM.
|
||||
Add LINKTYPE_DEBUG_ONLY/DLT_DEBUG_ONLY.
|
||||
Packet filtering:
|
||||
Make the chunk allocator's alignment more general and
|
||||
platform-independent.
|
||||
IEEE 802.11: Fix three undefined behaviors in grammar.y.
|
||||
Fix IPv4 multicast filtering to only include 224.0.0.0/4.
|
||||
Fix "(arp|rarp) host NAME" to ignore IPv6 quietly.
|
||||
Fix ARCnet address parsing.
|
||||
Linux:
|
||||
Fix check for mac80211 phydev.
|
||||
Don't create monitor-mode interface if we're capturing on one.
|
||||
Expand the table of DSA tag types to include all current types.
|
||||
Fix an error message when deleting a monN interface.
|
||||
Fix returning PCAP_ERROR_RFMON_NOTSUP with libnl.
|
||||
Fix the error message when capure permission is denied.
|
||||
Fix the error message if PF_PACKET sockets aren't supported.
|
||||
Fix a file descriptor leak in an error case (pull request #1537).
|
||||
Handle errors better when checking for a DSA-tagged interface.
|
||||
Use DLT_DEBUG_ONLY for DSA tags that do not [yet] have a better support.
|
||||
FreeBSD:
|
||||
Fix detection and enabling of zero-copy support.
|
||||
Fix errors in the zero-copy code.
|
||||
Solaris:
|
||||
Fix not to ignore logical interfaces in fad-gifc.c and
|
||||
fad-glifc.c.
|
||||
Fix attempts to open all-numeric device names with DLPI to
|
||||
return "no such device".
|
||||
Fix error returns and messages when an interface has no DLPI
|
||||
device.
|
||||
Return all interfaces in pcap_findalldevs() even if they can't be
|
||||
opened.
|
||||
HP-UX:
|
||||
Fix attempts to open all-numeric device names to return
|
||||
"no such device".
|
||||
Fix error message if there's no /dev/dlpi device.
|
||||
Return all interfaces in pcap_findalldevs() even if they can't be
|
||||
opened.
|
||||
Windows:
|
||||
Fix filtering for VLAN-tagged frames.
|
||||
Add support for Npcap's nanosecond-resolution time stamps in
|
||||
captures.
|
||||
CVE-2025-11964: Fix a bug in error message character encoding mapping
|
||||
from UTF-16 to UTF-8.
|
||||
Check at create time whether the NPF driver supports nanosecond
|
||||
precision.
|
||||
D-Bus:
|
||||
Fix message leak.
|
||||
Capture file writing:
|
||||
Don't close the output stream if it's stdout, just flush it.
|
||||
Documentation:
|
||||
Explicitly document that closing a pcap_t for a savefile opened
|
||||
with pcap_fopen_offline() will close the standard I/O stream.
|
||||
Building and testing:
|
||||
Makefile.in: Include instrument-functions.c in the release tarball.
|
||||
CMake: Fix libnl usage with pkg-config.
|
||||
CMake: Fix build with CMake 3.31.
|
||||
CI: Report CMake version in builds.
|
||||
CI: Visual Studio 2022 builds added, including ARM64 builds;
|
||||
Visual Studio 2015 builds dropped.
|
||||
Don't build with sslutils.c if we don't have a TLS library.
|
||||
Build on Windows with a newer version of OpenSSL.
|
||||
CMake: generalize handling of non-x86 Windows architectures.
|
||||
CI: use the -A flag for all Visual Studio generators.
|
||||
Remove the fuzzing props from the release tarball.
|
||||
Autoconf: Use AC_SYS_YEAR2038_RECOMMENDED when possible if the
|
||||
environment variable BUILD_YEAR2038 = yes (via autogen.sh)
|
||||
DPDK: don't enable it by default.
|
||||
Update Npcap SDK to 1.15.
|
||||
autogen.sh: Allow to configure Autoconf warnings.
|
||||
autogen.sh: Delete all trailing blank lines at end of configure.
|
||||
|
||||
Friday, August 30, 2024 / The Tcpdump Group
|
||||
Summary for 1.10.5 libpcap release
|
||||
Source code:
|
||||
|
|
|
|||
|
|
@ -13,14 +13,21 @@ else(WIN32)
|
|||
# on a "long-term support" version # of some OS and that
|
||||
# version supplies an older version of CMake;
|
||||
#
|
||||
# otherwise, require 3.5, so we don't get messages warning
|
||||
# that support for versions of CMake lower than 3.5 is
|
||||
# otherwise, if it's a version less than 3.10, require only
|
||||
# 3.5, just in case somebody is configuring with CMake
|
||||
# on a "long-term support" version # of some OS and that
|
||||
# version supplies an older version of CMake;
|
||||
#
|
||||
# otherwise, require 3.10, so we don't get messages warning
|
||||
# that support for versions of CMake lower than 3.10 is
|
||||
# deprecated.
|
||||
#
|
||||
if(CMAKE_VERSION VERSION_LESS "3.5")
|
||||
cmake_minimum_required(VERSION 2.8.12)
|
||||
else()
|
||||
elseif(CMAKE_VERSION VERSION_LESS "3.10")
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
else()
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
endif()
|
||||
endif(WIN32)
|
||||
|
||||
|
|
@ -506,7 +513,13 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
|||
endif()
|
||||
option(DISABLE_BLUETOOTH "Disable Bluetooth sniffing support" OFF)
|
||||
option(DISABLE_NETMAP "Disable netmap support" OFF)
|
||||
option(DISABLE_DPDK "Disable DPDK support" OFF)
|
||||
|
||||
#
|
||||
# Require that DPDK support be explicitly enabled, as the code is
|
||||
# immensely hard to keep compiling for every random API change
|
||||
# the DPDK folks make.
|
||||
#
|
||||
set(DISABLE_DPDK ON)
|
||||
|
||||
#
|
||||
# We don't support D-Bus sniffing on macOS; see
|
||||
|
|
@ -578,6 +591,7 @@ include_directories(
|
|||
include(CheckFunctionExists)
|
||||
include(CMakePushCheckState)
|
||||
include(CheckSymbolExists)
|
||||
include(CheckIncludeFile)
|
||||
|
||||
if(WIN32)
|
||||
|
||||
|
|
@ -595,8 +609,11 @@ if(WIN32)
|
|||
#
|
||||
cmake_push_check_state()
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${Packet_LIBRARIES})
|
||||
set(CMAKE_REQUIRED_INCLUDES ${Packet_INCLUDE_DIRS})
|
||||
check_function_exists(PacketIsLoopbackAdapter HAVE_PACKET_IS_LOOPBACK_ADAPTER)
|
||||
check_function_exists(PacketGetTimestampModes HAVE_PACKET_GET_TIMESTAMP_MODES)
|
||||
check_function_exists(PacketGetInfo HAVE_PACKET_GET_INFO)
|
||||
check_include_file(npcap-bpf.h HAVE_NPCAP_BPF_H)
|
||||
cmake_pop_check_state()
|
||||
endif(Packet_FOUND)
|
||||
|
||||
|
|
@ -634,7 +651,6 @@ endif(USE_STATIC_RT)
|
|||
# Detect available platform features
|
||||
###################################################################
|
||||
|
||||
include(CheckIncludeFile)
|
||||
include(CheckIncludeFiles)
|
||||
include(CheckStructHasMember)
|
||||
include(CheckTypeSize)
|
||||
|
|
@ -1244,6 +1260,19 @@ if(NOT WIN32)
|
|||
endif()
|
||||
endif()
|
||||
|
||||
#
|
||||
# Find and print the size of time_t.
|
||||
#
|
||||
cmake_push_check_state()
|
||||
set(CMAKE_EXTRA_INCLUDE_FILES time.h)
|
||||
check_type_size("time_t" SIZEOF_TIME_T)
|
||||
if(SIZEOF_TIME_T EQUAL 4)
|
||||
message(STATUS "32-bit time_t")
|
||||
elseif(SIZEOF_TIME_T EQUAL 8)
|
||||
message(STATUS "64-bit time_t")
|
||||
endif()
|
||||
cmake_pop_check_state()
|
||||
|
||||
if(INET6)
|
||||
message(STATUS "Support IPv6")
|
||||
endif(INET6)
|
||||
|
|
@ -1984,6 +2013,7 @@ else(WIN32)
|
|||
#
|
||||
check_include_file(sys/bufmod.h HAVE_SYS_BUFMOD_H)
|
||||
check_include_file(sys/dlpi_ext.h HAVE_SYS_DLPI_EXT_H)
|
||||
check_include_file(zone.h HAVE_ZONE_H)
|
||||
|
||||
#
|
||||
# Checks to see if Solaris has the public libdlpi(3LIB) library.
|
||||
|
|
@ -2025,12 +2055,6 @@ else(WIN32)
|
|||
check_type_size(dl_passive_req_t DL_PASSIVE_REQ_T)
|
||||
cmake_pop_check_state()
|
||||
elseif(PCAP_TYPE STREQUAL "linux")
|
||||
#
|
||||
# Do we have the wireless extensions?
|
||||
# linux/wireless.h requires sys/socket.h.
|
||||
#
|
||||
check_include_files("sys/socket.h;linux/wireless.h" HAVE_LINUX_WIRELESS_H)
|
||||
|
||||
#
|
||||
# Do we have libnl?
|
||||
# We only want version 3. Version 2 was, apparently,
|
||||
|
|
@ -2043,6 +2067,8 @@ else(WIN32)
|
|||
if(BUILD_WITH_LIBNL)
|
||||
pkg_check_modules(LIBNL libnl-genl-3.0)
|
||||
if(LIBNL_FOUND)
|
||||
set(HAVE_LIBNL TRUE)
|
||||
include_directories(${LIBNL_INCLUDE_DIRS})
|
||||
set(PCAP_LINK_LIBRARIES ${LIBNL_LIBRARIES} ${PCAP_LINK_LIBRARIES})
|
||||
|
||||
#
|
||||
|
|
@ -2698,7 +2724,10 @@ if(ENABLE_REMOTE)
|
|||
check_struct_has_member("struct msghdr" msg_flags "ftmacros.h;sys/socket.h" HAVE_STRUCT_MSGHDR_MSG_FLAGS)
|
||||
cmake_pop_check_state()
|
||||
set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C}
|
||||
pcap-new.c pcap-rpcap.c rpcap-protocol.c sockutils.c sslutils.c)
|
||||
pcap-new.c pcap-rpcap.c rpcap-protocol.c sockutils.c)
|
||||
if(OPENSSL_FOUND)
|
||||
set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} sslutils.c)
|
||||
endif()
|
||||
endif(ENABLE_REMOTE)
|
||||
|
||||
###################################################################
|
||||
|
|
@ -2917,7 +2946,6 @@ endif()
|
|||
|
||||
add_custom_command(
|
||||
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/scanner.c ${CMAKE_CURRENT_BINARY_DIR}/scanner.h
|
||||
SOURCE ${pcap_SOURCE_DIR}/scanner.l
|
||||
COMMAND ${LEX_EXECUTABLE} -P pcap_ --header-file=scanner.h --nounput -o${CMAKE_CURRENT_BINARY_DIR}/scanner.c ${pcap_SOURCE_DIR}/scanner.l
|
||||
DEPENDS ${pcap_SOURCE_DIR}/scanner.l
|
||||
)
|
||||
|
|
@ -2992,7 +3020,6 @@ message(STATUS "Parser generator: ${YACC_EXECUTABLE}")
|
|||
#
|
||||
add_custom_command(
|
||||
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/grammar.c ${CMAKE_CURRENT_BINARY_DIR}/grammar.h
|
||||
SOURCE ${pcap_BINARY_DIR}/grammar.y
|
||||
COMMAND ${YACC_EXECUTABLE} -p pcap_ -o ${CMAKE_CURRENT_BINARY_DIR}/grammar.c -d ${pcap_BINARY_DIR}/grammar.y
|
||||
DEPENDS ${pcap_BINARY_DIR}/grammar.y
|
||||
)
|
||||
|
|
|
|||
13
CREDITS
13
CREDITS
|
|
@ -14,6 +14,7 @@ Additional people who have contributed patches (in alphabetical order):
|
|||
Alexander Galanin <al at galanin dot nnov dot ru>
|
||||
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 Vishnyakov <vishnya at ispras 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>
|
||||
|
|
@ -34,6 +35,7 @@ Additional people who have contributed patches (in alphabetical order):
|
|||
Assar Westerlund <assar at sics dot se>
|
||||
Atzm Watanabe <atzm at atzm dot org>
|
||||
Baptiste Peugnez <baptiste dot peugnez at cea dot fr>
|
||||
Barnabás Pőcze <pobrn at protonmail dot com>
|
||||
Baruch Siach <baruch at tkos dot co dot il>
|
||||
Bill Parker <wp02855 at gmail dot com>
|
||||
Biswapriyo Nath <nathbappai at gmail dot com>
|
||||
|
|
@ -78,6 +80,7 @@ Additional people who have contributed patches (in alphabetical order):
|
|||
Eli Schwartz <eschwartz93 at gmail 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>
|
||||
Eugene Exarevsky <eugene dot exarevsky at dsr-corporation 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>
|
||||
|
|
@ -85,6 +88,7 @@ Additional people who have contributed patches (in alphabetical order):
|
|||
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>
|
||||
Frank Gorgas-Waller <frank dot gorgas-waller at auerswald dot de>
|
||||
Franz Schaefer <schaefer at mond dot at>
|
||||
frederich <frederich at sourceforge dot net>
|
||||
Fulko Hew <fulko dot hew at gmail dot com>
|
||||
|
|
@ -95,6 +99,7 @@ Additional people who have contributed patches (in alphabetical order):
|
|||
George Neville-Neil <gnn at freebsd dot org>
|
||||
Gerald Combs <gerald at zing dot org>
|
||||
Gerard Garcia <nouboh at gmail dot com>
|
||||
Gerd Hoffmann <kraxel at redhat dot com>
|
||||
Gianluca Varenni <gianluca dot varenni at gmail dot com>
|
||||
Gilbert Hoyek <gil_hoyek at hotmail dot com>
|
||||
Gisle Vanem <gvanem at yahoo dot no>
|
||||
|
|
@ -106,14 +111,17 @@ Additional people who have contributed patches (in alphabetical order):
|
|||
Gustavo Zacarias <gustavo at zacarias dot com dot ar>
|
||||
Hagen Paul Pfeifer <hagen at jauu dot net>
|
||||
headshog <craaaaaachind at gmail dot com>
|
||||
Henri Chataing <henrichataing at google dot com>
|
||||
Henri Doreau <hdoreau at sourceforge dot net>
|
||||
Hiroaki KAWAI <kawai at stratosphere dot co dot jp>
|
||||
hopper-vul <hopper dot vul at gmail dot com>
|
||||
Hyung Sik Yoon <hsyn at kr dot ibm dot com>
|
||||
Ido Yariv <yarivido at gmail dot com>
|
||||
Igor Khristophorov <igor at atdot dot org>
|
||||
Jakub Sitnicki <jsitnicki at gmail dot com>
|
||||
Jakub Zawadzki <darkjames at darkjames dot pl>
|
||||
James Ko <jck at exegin dot com>
|
||||
Jan Adam <jadam at hilscher dot com>
|
||||
Jan-Philip Velders <jpv at veldersjes dot net>
|
||||
Jason R. Thorpe <thorpej at netbsd dot org>
|
||||
Javier Achirica <achirica at ttd dot net>
|
||||
|
|
@ -124,6 +132,7 @@ Additional people who have contributed patches (in alphabetical order):
|
|||
Jesper Dangaard Brouer <hawk at comx dot dk>
|
||||
Jesper Peterson <jesper at endace dot com>
|
||||
Jesse Gross <jesse at nicira dot com>
|
||||
Jessica Clarke <jrtc27 at jrtc27 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>
|
||||
|
|
@ -131,6 +140,7 @@ Additional people who have contributed patches (in alphabetical order):
|
|||
Joel <82591719+joelg989 at users dot noreply dot github dot com>
|
||||
Joerg Mayer <jmayer at loplof dot de>
|
||||
John Bankier <jbankier at rainfinity dot com>
|
||||
John Thacker <johnthacker at gmail dot com>
|
||||
Jon Lindgren <jonl at yubyub dot net>
|
||||
Jon Smirl <jonsmirl at gmail dot com>
|
||||
Jorge Boncompte [DTI2] <jorge at dti2 dot net>
|
||||
|
|
@ -165,6 +175,7 @@ Additional people who have contributed patches (in alphabetical order):
|
|||
Mark Pizzolato <List-tcpdump-workers at subscriptions dot pizzolato dot net>
|
||||
Markus Mayer <markus_mayer at sourceforge dot net>
|
||||
Martin Husemann <martin at netbsd dot org>
|
||||
Martin Kaiser <martin at kaiser dot cx>
|
||||
Márton Németh <nm127 at freemail dot hu>
|
||||
Matias Karhumaa <matias dot karhumaa at gmail dot com>
|
||||
Matt Eaton <agnosticdev at gmail dot com>
|
||||
|
|
@ -183,6 +194,7 @@ Additional people who have contributed patches (in alphabetical order):
|
|||
Milosz Kaniewski <milosz dot kaniewski at gmail dot com>
|
||||
Miroslav Lichvar <mlichvar at redhat dot com>
|
||||
Monroe Williams <monroe at pobox dot com>
|
||||
mooon04 <mirae dot kim040506 at gmail dot com>
|
||||
Myricom Help <myri at users dot noreply dot github dot com>
|
||||
Nan Xiao <nan at chinadtrace dot org>
|
||||
nic-kaczinsky <68271784+nic-kaczinsky at users dot noreply dot github dot com>
|
||||
|
|
@ -240,6 +252,7 @@ Additional people who have contributed patches (in alphabetical order):
|
|||
Stefan Hudson <hudson at mbay dot net>
|
||||
Stephen Donnelly <stephen at endace dot com>
|
||||
Steve Karg <skarg at users dot sourceforge dot net>
|
||||
Stig Bjørlykke <stig at bjorlykke dot org>
|
||||
stubbfel <stubbfel at gmail dot com>
|
||||
Takashi Yamamoto <yamt at mwd dot biglobe dot ne dot jp>
|
||||
Tanaka Shin-ya <zstanaka at archer dot livedoor dot com>
|
||||
|
|
|
|||
|
|
@ -8,6 +8,10 @@ To build libpcap with the configure script and `make`:
|
|||
run `./autogen.sh` (a shell script). The autogen.sh script will
|
||||
build the `configure` and `config.h.in` files.
|
||||
|
||||
* If you build on a Linux 32-bit system, with Autoconf version >= 2.72
|
||||
and GNU C Library version >= 2.34, run `export BUILD_YEAR2038=yes`
|
||||
before running `./autogen.sh` to build with 64-bit time_t (Y2038-safe).
|
||||
|
||||
On some system, you may need to set the `AUTORECONF` variable, like:
|
||||
`AUTORECONF=autoreconf-2.69 ./autogen.sh`
|
||||
to select the `autoreconf` version you want to use.
|
||||
|
|
|
|||
12
Makefile.in
12
Makefile.in
|
|
@ -291,6 +291,7 @@ EXTRA_DIST = \
|
|||
fad-glifc.c \
|
||||
grammar.y.in \
|
||||
install-sh \
|
||||
instrument-functions.c \
|
||||
lbl/os-aix4.h \
|
||||
lbl/os-aix7.h \
|
||||
lbl/os-hpux11.h \
|
||||
|
|
@ -402,14 +403,6 @@ EXTRA_DIST = \
|
|||
testprogs/filtertest.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/nonblocktest.c \
|
||||
testprogs/opentest.c \
|
||||
testprogs/reactivatetest.c \
|
||||
|
|
@ -417,6 +410,7 @@ EXTRA_DIST = \
|
|||
testprogs/threadsignaltest.c \
|
||||
testprogs/unix.h \
|
||||
testprogs/valgrindtest.c \
|
||||
testprogs/versiontest.c \
|
||||
testprogs/visopts.py \
|
||||
testprogs/writecaptest.c
|
||||
|
||||
|
|
@ -858,7 +852,7 @@ releasetar:
|
|||
tar xf -) && \
|
||||
echo "No $$TAG tag. Archive build from HEAD."; \
|
||||
fi && \
|
||||
(cd "$$TAG" && "$${AUTORECONF:-autoreconf}" && rm -rf autom4te.cache) && \
|
||||
(cd "$$TAG" && ./autogen.sh && rm -rf autom4te.cache) && \
|
||||
tar cf "$$DIR/$$TAG".tar "$$TAG" && \
|
||||
rm -f "$$DIR/$$TAG".tar.gz && \
|
||||
gzip --best "$$DIR/$$TAG".tar && \
|
||||
|
|
|
|||
2
VERSION
2
VERSION
|
|
@ -1 +1 @@
|
|||
1.10.5
|
||||
1.10.6
|
||||
|
|
|
|||
11
aclocal.m4
vendored
11
aclocal.m4
vendored
|
|
@ -825,6 +825,11 @@ dnl os-proto.h (symlinked)
|
|||
dnl
|
||||
AC_DEFUN(AC_LBL_DEVEL,
|
||||
[rm -f os-proto.h
|
||||
#
|
||||
# MKDEP defaults to no-op (":") if we don't test whether the compiler
|
||||
# supports generating dependencies
|
||||
#
|
||||
MKDEP=:
|
||||
if test "${LBL_CFLAGS+set}" = set; then
|
||||
$1="$$1 ${LBL_CFLAGS}"
|
||||
fi
|
||||
|
|
@ -901,14 +906,16 @@ testme(unsigned short a)
|
|||
# .devel file; why should the ABI for which we produce code
|
||||
# depend on .devel?
|
||||
#
|
||||
AC_MSG_CHECKING([whether to use an os-proto.h header])
|
||||
os=`echo $host_os | sed -e 's/\([[0-9]][[0-9]]*\)[[^0-9]].*$/\1/'`
|
||||
name="lbl/os-$os.h"
|
||||
if test -f $name ; then
|
||||
AC_MSG_RESULT([yes, at "$name"])
|
||||
ln -s $name os-proto.h
|
||||
AC_DEFINE(HAVE_OS_PROTO_H, 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])
|
||||
else
|
||||
AC_MSG_WARN(can't find $name)
|
||||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
fi])
|
||||
|
||||
|
|
|
|||
41
autogen.sh
41
autogen.sh
|
|
@ -1,6 +1,7 @@
|
|||
#!/bin/sh -e
|
||||
|
||||
: "${AUTORECONF:=autoreconf}"
|
||||
: "${BUILD_YEAR2038:=no}"
|
||||
|
||||
AUTORECONFVERSION=`$AUTORECONF --version 2>&1 | grep "^autoreconf" | sed 's/.*) *//'`
|
||||
|
||||
|
|
@ -21,5 +22,43 @@ if [ "$maj" = "" ] || [ "$min" = "" ] || \
|
|||
exit 1
|
||||
fi
|
||||
|
||||
# On Linux, if Autoconf version >= 2.72 and GNU C Library version >= 2.34,
|
||||
# s/AC_SYS_LARGEFILE/AC_SYS_YEAR2038_RECOMMENDED/ to ensure time_t
|
||||
# is Y2038-safe.
|
||||
if [ "$BUILD_YEAR2038" = yes ] && [ "`uname -s`" = Linux ]; then
|
||||
if [ "$maj" -gt 2 ] || { [ "$maj" -eq 2 ] && [ "$min" -ge 72 ]; }; then
|
||||
GLIBC_VERSION=`ldd --version|head -1|grep GLIBC|sed 's/.* //'`
|
||||
maj_glibc=`echo "$GLIBC_VERSION" | cut -d. -f1`
|
||||
min_glibc=`echo "$GLIBC_VERSION" | cut -d. -f2`
|
||||
echo "GNU C Library identification: $GLIBC_VERSION"
|
||||
if [ "$maj_glibc" -gt 2 ] || { [ "$maj_glibc" -eq 2 ] && \
|
||||
[ "$min_glibc" -ge 34 ]; }; then
|
||||
CONFIGURE_AC_NEW="configure.ac.new$$"
|
||||
sed 's/^AC_SYS_LARGEFILE/AC_SYS_YEAR2038_RECOMMENDED/' \
|
||||
<configure.ac >"$CONFIGURE_AC_NEW"
|
||||
cmp -s configure.ac "$CONFIGURE_AC_NEW" || \
|
||||
cat "$CONFIGURE_AC_NEW" >configure.ac
|
||||
rm -f "$CONFIGURE_AC_NEW"
|
||||
echo 'Setup to ensure time_t is Y2038-safe.'
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "$AUTORECONF identification: $AUTORECONFVERSION"
|
||||
"$AUTORECONF" -f
|
||||
|
||||
# configure.ac is an Autoconf 2.69 file, but it works as expected even with
|
||||
# Autoconf 2.72. However, in Autoconf versions 2.70 and later obsolete
|
||||
# construct warnings are enabled by default, which adds varying (depending on
|
||||
# the branch) amount of noise to the build matrix output, so provide a means
|
||||
# to silence that.
|
||||
env ${AUTOCONF_WARNINGS:+WARNINGS="$AUTOCONF_WARNINGS"} "$AUTORECONF" -f
|
||||
|
||||
# Autoconf 2.71 adds a blank line after the final "exit 0" on Linux, but not
|
||||
# on OpenBSD. Remove this difference to make it easier to compare the result
|
||||
# of "make releasetar" across different platforms. From sed one-liners:
|
||||
# "delete all trailing blank lines at end of file (works on all seds)". Don't
|
||||
# use mktemp(1) because AIX does not have it.
|
||||
CONFIGURE_NEW="configure.new$$"
|
||||
sed -e :a -e '/^\n*$/{$d;N;ba' -e '}' <configure >"$CONFIGURE_NEW"
|
||||
cmp -s configure "$CONFIGURE_NEW" || cat "$CONFIGURE_NEW" >configure
|
||||
rm -f "$CONFIGURE_NEW"
|
||||
|
|
|
|||
|
|
@ -47,42 +47,27 @@
|
|||
# (e.g cmake -DPacket_ROOT=C:\path\to\packet [...])
|
||||
#
|
||||
|
||||
# The 64-bit Packet.lib is located under /x64
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
if(CMAKE_GENERATOR_PLATFORM STREQUAL "Win32")
|
||||
#
|
||||
# 32-bit x86; no need to look in subdirectories of the SDK's
|
||||
# Lib directory for the libraries, as the libraries are in
|
||||
# the Lib directory
|
||||
#
|
||||
else()
|
||||
#
|
||||
# Platform other than 32-bit x86.
|
||||
#
|
||||
# For the WinPcap and Npcap SDKs, the Lib subdirectory of the top-level
|
||||
# directory contains 32-bit libraries; the 64-bit libraries are in the
|
||||
# Lib/x64 directory.
|
||||
# directory contains 32-bit x86 libraries; the libraries for other
|
||||
# platforms are in subdirectories of the Lib directory whose names
|
||||
# are the names of the supported platforms.
|
||||
#
|
||||
# The only way to *FORCE* CMake to look in the Lib/x64 directory
|
||||
# without searching in the Lib directory first appears to be to set
|
||||
# CMAKE_LIBRARY_ARCHITECTURE to "x64".
|
||||
# The only way to *FORCE* CMake to look in the appropriate
|
||||
# subdirectory of Lib for libraries without searching in the
|
||||
# Lib directory first appears to be to set
|
||||
# CMAKE_LIBRARY_ARCHITECTURE to the name of the subdirectory.
|
||||
#
|
||||
# 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()
|
||||
set(CMAKE_LIBRARY_ARCHITECTURE "${CMAKE_GENERATOR_PLATFORM}")
|
||||
endif()
|
||||
|
||||
# Find the header
|
||||
|
|
|
|||
|
|
@ -93,9 +93,6 @@
|
|||
/* Define to 1 if you have the <linux/usbdevice_fs.h> header file. */
|
||||
#cmakedefine HAVE_LINUX_USBDEVICE_FS_H 1
|
||||
|
||||
/* Define to 1 if you have the <linux/wireless.h> header file. */
|
||||
#cmakedefine HAVE_LINUX_WIRELESS_H 1
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#cmakedefine HAVE_MEMORY_H 1
|
||||
|
||||
|
|
@ -129,6 +126,9 @@
|
|||
/* Define to 1 if Packet32 API (Npcap driver) is available */
|
||||
#cmakedefine HAVE_PACKET32 1
|
||||
|
||||
/* Define to 1 if Npcap BPF extension definitions are available */
|
||||
#cmakedefine HAVE_NPCAP_BPF_H 1
|
||||
|
||||
/* Define to 1 if NPcap's version.h is available */
|
||||
#cmakedefine HAVE_VERSION_H 1
|
||||
|
||||
|
|
@ -265,6 +265,9 @@
|
|||
/* Define to 1 if you have the `PacketIsLoopbackAdapter' function. */
|
||||
#cmakedefine HAVE_PACKET_IS_LOOPBACK_ADAPTER 1
|
||||
|
||||
/* Define to 1 if you have the `PacketGetInfo' function. */
|
||||
#cmakedefine HAVE_PACKET_GET_INFO 1
|
||||
|
||||
/* IPv6 */
|
||||
#cmakedefine INET6 1
|
||||
|
||||
|
|
@ -325,6 +328,9 @@
|
|||
/* target host supports RDMA sniffing */
|
||||
#cmakedefine PCAP_SUPPORT_RDMASNIFF 1
|
||||
|
||||
/* The size of `time_t', as computed by sizeof. */
|
||||
#cmakedefine SIZEOF_TIME_T @SIZEOF_TIME_T@
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#cmakedefine STDC_HEADERS 1
|
||||
|
||||
|
|
|
|||
|
|
@ -102,9 +102,6 @@
|
|||
/* Define to 1 if you have the <linux/usbdevice_fs.h> header file. */
|
||||
#undef HAVE_LINUX_USBDEVICE_FS_H
|
||||
|
||||
/* Define to 1 if you have the <linux/wireless.h> header file. */
|
||||
#undef HAVE_LINUX_WIRELESS_H
|
||||
|
||||
/* Define to 1 if you have the <netpacket/packet.h> header file. */
|
||||
#undef HAVE_NETPACKET_PACKET_H
|
||||
|
||||
|
|
@ -138,7 +135,7 @@
|
|||
/* 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
|
||||
|
||||
/* Define to 1 if you have a POSIX-style `strerror_r' function. */
|
||||
|
|
@ -256,6 +253,9 @@
|
|||
/* Define to 1 if you have the `vsyslog' function. */
|
||||
#undef HAVE_VSYSLOG
|
||||
|
||||
/* Define to 1 if you have the <zone.h> header file. */
|
||||
#undef HAVE_ZONE_H
|
||||
|
||||
/* Define to 1 if you have the `_wcserror_s' function. */
|
||||
#undef HAVE__WCSERROR_S
|
||||
|
||||
|
|
|
|||
721
configure
vendored
721
configure
vendored
|
|
@ -1,6 +1,6 @@
|
|||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.71 for pcap 1.10.5.
|
||||
# Generated by GNU Autoconf 2.71 for pcap 1.10.6.
|
||||
#
|
||||
#
|
||||
# Copyright (C) 1992-1996, 1998-2017, 2020-2021 Free Software Foundation,
|
||||
|
|
@ -608,8 +608,8 @@ MAKEFLAGS=
|
|||
# Identity of this package.
|
||||
PACKAGE_NAME='pcap'
|
||||
PACKAGE_TARNAME='pcap'
|
||||
PACKAGE_VERSION='1.10.5'
|
||||
PACKAGE_STRING='pcap 1.10.5'
|
||||
PACKAGE_VERSION='1.10.6'
|
||||
PACKAGE_STRING='pcap 1.10.6'
|
||||
PACKAGE_BUGREPORT=''
|
||||
PACKAGE_URL=''
|
||||
|
||||
|
|
@ -1380,7 +1380,7 @@ if test "$ac_init_help" = "long"; then
|
|||
# Omit some internal or obsolete options to make the list less imposing.
|
||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||
cat <<_ACEOF
|
||||
\`configure' configures pcap 1.10.5 to adapt to many kinds of systems.
|
||||
\`configure' configures pcap 1.10.6 to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
|
|
@ -1447,7 +1447,7 @@ fi
|
|||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of pcap 1.10.5:";;
|
||||
short | recursive ) echo "Configuration of pcap 1.10.6:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
|
|
@ -1502,7 +1502,7 @@ Optional Packages:
|
|||
directory DIR, if supplied). [default=yes, if
|
||||
present]
|
||||
--with-dpdk[=DIR] include DPDK support (located in directory DIR, if
|
||||
supplied). [default=yes, if present]
|
||||
supplied). [default=no]
|
||||
|
||||
Some influential environment variables:
|
||||
CC C compiler command
|
||||
|
|
@ -1611,7 +1611,7 @@ fi
|
|||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
pcap configure 1.10.5
|
||||
pcap configure 1.10.6
|
||||
generated by GNU Autoconf 2.71
|
||||
|
||||
Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
|
|
@ -1664,6 +1664,53 @@ fi
|
|||
|
||||
} # ac_fn_c_try_compile
|
||||
|
||||
# ac_fn_c_try_link LINENO
|
||||
# -----------------------
|
||||
# Try to link conftest.$ac_ext, and return whether this succeeded.
|
||||
ac_fn_c_try_link ()
|
||||
{
|
||||
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
|
||||
rm -f conftest.$ac_objext conftest.beam conftest$ac_exeext
|
||||
if { { ac_try="$ac_link"
|
||||
case "(($ac_try" in
|
||||
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
|
||||
*) ac_try_echo=$ac_try;;
|
||||
esac
|
||||
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
|
||||
printf "%s\n" "$ac_try_echo"; } >&5
|
||||
(eval "$ac_link") 2>conftest.err
|
||||
ac_status=$?
|
||||
if test -s conftest.err; then
|
||||
grep -v '^ *+' conftest.err >conftest.er1
|
||||
cat conftest.er1 >&5
|
||||
mv -f conftest.er1 conftest.err
|
||||
fi
|
||||
printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
|
||||
test $ac_status = 0; } && {
|
||||
test -z "$ac_c_werror_flag" ||
|
||||
test ! -s conftest.err
|
||||
} && test -s conftest$ac_exeext && {
|
||||
test "$cross_compiling" = yes ||
|
||||
test -x conftest$ac_exeext
|
||||
}
|
||||
then :
|
||||
ac_retval=0
|
||||
else $as_nop
|
||||
printf "%s\n" "$as_me: failed program was:" >&5
|
||||
sed 's/^/| /' conftest.$ac_ext >&5
|
||||
|
||||
ac_retval=1
|
||||
fi
|
||||
# Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
|
||||
# created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
|
||||
# interfere with the next link command; also delete a directory that is
|
||||
# left behind by Apple's compiler. We do this before executing the actions.
|
||||
rm -rf conftest.dSYM conftest_ipa8_conftest.oo
|
||||
eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
|
||||
as_fn_set_status $ac_retval
|
||||
|
||||
} # ac_fn_c_try_link
|
||||
|
||||
# ac_fn_c_try_run LINENO
|
||||
# ----------------------
|
||||
# Try to run conftest.$ac_ext, and return whether this succeeded. Assumes that
|
||||
|
|
@ -2183,7 +2230,7 @@ cat >config.log <<_ACEOF
|
|||
This file contains any messages produced by compilers while
|
||||
running configure, to aid debugging if configure makes a mistake.
|
||||
|
||||
It was created by pcap $as_me 1.10.5, which was
|
||||
It was created by pcap $as_me 1.10.6, which was
|
||||
generated by GNU Autoconf 2.71. Invocation command line was
|
||||
|
||||
$ $0$ac_configure_args_raw
|
||||
|
|
@ -4220,11 +4267,288 @@ if test "$ac_cv_prog_cc_c99" = "no"; then
|
|||
as_fn_error $? "The C compiler does not support C99" "$LINENO" 5
|
||||
fi
|
||||
|
||||
#
|
||||
# Try to arrange for large file support.
|
||||
#
|
||||
|
||||
# Check whether --enable-largefile was given.
|
||||
if test ${enable_largefile+y}
|
||||
then :
|
||||
enableval=$enable_largefile;
|
||||
fi
|
||||
|
||||
if test "$enable_largefile" != no; then
|
||||
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for special C compiler options needed for large files" >&5
|
||||
printf %s "checking for special C compiler options needed for large files... " >&6; }
|
||||
if test ${ac_cv_sys_largefile_CC+y}
|
||||
then :
|
||||
printf %s "(cached) " >&6
|
||||
else $as_nop
|
||||
ac_cv_sys_largefile_CC=no
|
||||
if test "$GCC" != yes; then
|
||||
ac_save_CC=$CC
|
||||
while :; do
|
||||
# IRIX 6.2 and later do not support large files by default,
|
||||
# so use the C compiler's -n32 option if that helps.
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
#include <sys/types.h>
|
||||
/* Check that off_t can represent 2**63 - 1 correctly.
|
||||
We can't simply define LARGE_OFF_T to be 9223372036854775807,
|
||||
since some C++ compilers masquerading as C compilers
|
||||
incorrectly reject 9223372036854775807. */
|
||||
#define LARGE_OFF_T (((off_t) 1 << 31 << 31) - 1 + ((off_t) 1 << 31 << 31))
|
||||
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
|
||||
&& LARGE_OFF_T % 2147483647 == 1)
|
||||
? 1 : -1];
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_compile "$LINENO"
|
||||
then :
|
||||
break
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.beam
|
||||
CC="$CC -n32"
|
||||
if ac_fn_c_try_compile "$LINENO"
|
||||
then :
|
||||
ac_cv_sys_largefile_CC=' -n32'; break
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.beam
|
||||
break
|
||||
done
|
||||
CC=$ac_save_CC
|
||||
rm -f conftest.$ac_ext
|
||||
fi
|
||||
fi
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_CC" >&5
|
||||
printf "%s\n" "$ac_cv_sys_largefile_CC" >&6; }
|
||||
if test "$ac_cv_sys_largefile_CC" != no; then
|
||||
CC=$CC$ac_cv_sys_largefile_CC
|
||||
fi
|
||||
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS value needed for large files" >&5
|
||||
printf %s "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; }
|
||||
if test ${ac_cv_sys_file_offset_bits+y}
|
||||
then :
|
||||
printf %s "(cached) " >&6
|
||||
else $as_nop
|
||||
while :; do
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
#include <sys/types.h>
|
||||
/* Check that off_t can represent 2**63 - 1 correctly.
|
||||
We can't simply define LARGE_OFF_T to be 9223372036854775807,
|
||||
since some C++ compilers masquerading as C compilers
|
||||
incorrectly reject 9223372036854775807. */
|
||||
#define LARGE_OFF_T (((off_t) 1 << 31 << 31) - 1 + ((off_t) 1 << 31 << 31))
|
||||
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
|
||||
&& LARGE_OFF_T % 2147483647 == 1)
|
||||
? 1 : -1];
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_compile "$LINENO"
|
||||
then :
|
||||
ac_cv_sys_file_offset_bits=no; break
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
#define _FILE_OFFSET_BITS 64
|
||||
#include <sys/types.h>
|
||||
/* Check that off_t can represent 2**63 - 1 correctly.
|
||||
We can't simply define LARGE_OFF_T to be 9223372036854775807,
|
||||
since some C++ compilers masquerading as C compilers
|
||||
incorrectly reject 9223372036854775807. */
|
||||
#define LARGE_OFF_T (((off_t) 1 << 31 << 31) - 1 + ((off_t) 1 << 31 << 31))
|
||||
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
|
||||
&& LARGE_OFF_T % 2147483647 == 1)
|
||||
? 1 : -1];
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_compile "$LINENO"
|
||||
then :
|
||||
ac_cv_sys_file_offset_bits=64; break
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
|
||||
ac_cv_sys_file_offset_bits=unknown
|
||||
break
|
||||
done
|
||||
fi
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_file_offset_bits" >&5
|
||||
printf "%s\n" "$ac_cv_sys_file_offset_bits" >&6; }
|
||||
case $ac_cv_sys_file_offset_bits in #(
|
||||
no | unknown) ;;
|
||||
*)
|
||||
printf "%s\n" "#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits" >>confdefs.h
|
||||
;;
|
||||
esac
|
||||
rm -rf conftest*
|
||||
if test $ac_cv_sys_file_offset_bits = unknown; then
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for _LARGE_FILES value needed for large files" >&5
|
||||
printf %s "checking for _LARGE_FILES value needed for large files... " >&6; }
|
||||
if test ${ac_cv_sys_large_files+y}
|
||||
then :
|
||||
printf %s "(cached) " >&6
|
||||
else $as_nop
|
||||
while :; do
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
#include <sys/types.h>
|
||||
/* Check that off_t can represent 2**63 - 1 correctly.
|
||||
We can't simply define LARGE_OFF_T to be 9223372036854775807,
|
||||
since some C++ compilers masquerading as C compilers
|
||||
incorrectly reject 9223372036854775807. */
|
||||
#define LARGE_OFF_T (((off_t) 1 << 31 << 31) - 1 + ((off_t) 1 << 31 << 31))
|
||||
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
|
||||
&& LARGE_OFF_T % 2147483647 == 1)
|
||||
? 1 : -1];
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_compile "$LINENO"
|
||||
then :
|
||||
ac_cv_sys_large_files=no; break
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
#define _LARGE_FILES 1
|
||||
#include <sys/types.h>
|
||||
/* Check that off_t can represent 2**63 - 1 correctly.
|
||||
We can't simply define LARGE_OFF_T to be 9223372036854775807,
|
||||
since some C++ compilers masquerading as C compilers
|
||||
incorrectly reject 9223372036854775807. */
|
||||
#define LARGE_OFF_T (((off_t) 1 << 31 << 31) - 1 + ((off_t) 1 << 31 << 31))
|
||||
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
|
||||
&& LARGE_OFF_T % 2147483647 == 1)
|
||||
? 1 : -1];
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_compile "$LINENO"
|
||||
then :
|
||||
ac_cv_sys_large_files=1; break
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
|
||||
ac_cv_sys_large_files=unknown
|
||||
break
|
||||
done
|
||||
fi
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_large_files" >&5
|
||||
printf "%s\n" "$ac_cv_sys_large_files" >&6; }
|
||||
case $ac_cv_sys_large_files in #(
|
||||
no | unknown) ;;
|
||||
*)
|
||||
printf "%s\n" "#define _LARGE_FILES $ac_cv_sys_large_files" >>confdefs.h
|
||||
;;
|
||||
esac
|
||||
rm -rf conftest*
|
||||
fi
|
||||
fi
|
||||
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for _LARGEFILE_SOURCE value needed for large files" >&5
|
||||
printf %s "checking for _LARGEFILE_SOURCE value needed for large files... " >&6; }
|
||||
if test ${ac_cv_sys_largefile_source+y}
|
||||
then :
|
||||
printf %s "(cached) " >&6
|
||||
else $as_nop
|
||||
while :; do
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
#include <sys/types.h> /* for off_t */
|
||||
#include <stdio.h>
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
int (*fp) (FILE *, off_t, int) = fseeko;
|
||||
return fseeko (stdin, 0, 0) && fp (stdin, 0, 0);
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
then :
|
||||
ac_cv_sys_largefile_source=no; break
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.beam \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
#define _LARGEFILE_SOURCE 1
|
||||
#include <sys/types.h> /* for off_t */
|
||||
#include <stdio.h>
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
int (*fp) (FILE *, off_t, int) = fseeko;
|
||||
return fseeko (stdin, 0, 0) && fp (stdin, 0, 0);
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
then :
|
||||
ac_cv_sys_largefile_source=1; break
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.beam \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
ac_cv_sys_largefile_source=unknown
|
||||
break
|
||||
done
|
||||
fi
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_source" >&5
|
||||
printf "%s\n" "$ac_cv_sys_largefile_source" >&6; }
|
||||
case $ac_cv_sys_largefile_source in #(
|
||||
no | unknown) ;;
|
||||
*)
|
||||
printf "%s\n" "#define _LARGEFILE_SOURCE $ac_cv_sys_largefile_source" >>confdefs.h
|
||||
;;
|
||||
esac
|
||||
rm -rf conftest*
|
||||
|
||||
# We used to try defining _XOPEN_SOURCE=500 too, to work around a bug
|
||||
# in glibc 2.1.3, but that breaks too many other things.
|
||||
# If you want fseeko and ftello with glibc, upgrade to a fixed glibc.
|
||||
if test $ac_cv_sys_largefile_source != unknown; then
|
||||
|
||||
printf "%s\n" "#define HAVE_FSEEKO 1" >>confdefs.h
|
||||
|
||||
fi
|
||||
|
||||
|
||||
#
|
||||
# Get the size of a void *, to determine whether this is a 32-bit
|
||||
# or 64-bit build.
|
||||
#
|
||||
|
||||
ac_header= ac_cache=
|
||||
for ac_item in $ac_header_c_list
|
||||
do
|
||||
|
|
@ -4986,54 +5310,7 @@ printf %s "checking for __atomic_load_n... " >&6; }
|
|||
then :
|
||||
printf %s "(cached) " >&6
|
||||
else $as_nop
|
||||
|
||||
# ac_fn_c_try_link LINENO
|
||||
# -----------------------
|
||||
# Try to link conftest.$ac_ext, and return whether this succeeded.
|
||||
ac_fn_c_try_link ()
|
||||
{
|
||||
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
|
||||
rm -f conftest.$ac_objext conftest.beam conftest$ac_exeext
|
||||
if { { ac_try="$ac_link"
|
||||
case "(($ac_try" in
|
||||
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
|
||||
*) ac_try_echo=$ac_try;;
|
||||
esac
|
||||
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
|
||||
printf "%s\n" "$ac_try_echo"; } >&5
|
||||
(eval "$ac_link") 2>conftest.err
|
||||
ac_status=$?
|
||||
if test -s conftest.err; then
|
||||
grep -v '^ *+' conftest.err >conftest.er1
|
||||
cat conftest.er1 >&5
|
||||
mv -f conftest.er1 conftest.err
|
||||
fi
|
||||
printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
|
||||
test $ac_status = 0; } && {
|
||||
test -z "$ac_c_werror_flag" ||
|
||||
test ! -s conftest.err
|
||||
} && test -s conftest$ac_exeext && {
|
||||
test "$cross_compiling" = yes ||
|
||||
test -x conftest$ac_exeext
|
||||
}
|
||||
then :
|
||||
ac_retval=0
|
||||
else $as_nop
|
||||
printf "%s\n" "$as_me: failed program was:" >&5
|
||||
sed 's/^/| /' conftest.$ac_ext >&5
|
||||
|
||||
ac_retval=1
|
||||
fi
|
||||
# Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
|
||||
# created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
|
||||
# interfere with the next link command; also delete a directory that is
|
||||
# left behind by Apple's compiler. We do this before executing the actions.
|
||||
rm -rf conftest.dSYM conftest_ipa8_conftest.oo
|
||||
eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
|
||||
as_fn_set_status $ac_retval
|
||||
|
||||
} # ac_fn_c_try_link
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
int
|
||||
|
|
@ -5104,283 +5381,6 @@ printf "%s\n" "#define HAVE___ATOMIC_STORE_N 1" >>confdefs.h
|
|||
|
||||
fi
|
||||
|
||||
#
|
||||
# Try to arrange for large file support.
|
||||
#
|
||||
# Check whether --enable-largefile was given.
|
||||
if test ${enable_largefile+y}
|
||||
then :
|
||||
enableval=$enable_largefile;
|
||||
fi
|
||||
|
||||
if test "$enable_largefile" != no; then
|
||||
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for special C compiler options needed for large files" >&5
|
||||
printf %s "checking for special C compiler options needed for large files... " >&6; }
|
||||
if test ${ac_cv_sys_largefile_CC+y}
|
||||
then :
|
||||
printf %s "(cached) " >&6
|
||||
else $as_nop
|
||||
ac_cv_sys_largefile_CC=no
|
||||
if test "$GCC" != yes; then
|
||||
ac_save_CC=$CC
|
||||
while :; do
|
||||
# IRIX 6.2 and later do not support large files by default,
|
||||
# so use the C compiler's -n32 option if that helps.
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
#include <sys/types.h>
|
||||
/* Check that off_t can represent 2**63 - 1 correctly.
|
||||
We can't simply define LARGE_OFF_T to be 9223372036854775807,
|
||||
since some C++ compilers masquerading as C compilers
|
||||
incorrectly reject 9223372036854775807. */
|
||||
#define LARGE_OFF_T (((off_t) 1 << 31 << 31) - 1 + ((off_t) 1 << 31 << 31))
|
||||
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
|
||||
&& LARGE_OFF_T % 2147483647 == 1)
|
||||
? 1 : -1];
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_compile "$LINENO"
|
||||
then :
|
||||
break
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.beam
|
||||
CC="$CC -n32"
|
||||
if ac_fn_c_try_compile "$LINENO"
|
||||
then :
|
||||
ac_cv_sys_largefile_CC=' -n32'; break
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.beam
|
||||
break
|
||||
done
|
||||
CC=$ac_save_CC
|
||||
rm -f conftest.$ac_ext
|
||||
fi
|
||||
fi
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_CC" >&5
|
||||
printf "%s\n" "$ac_cv_sys_largefile_CC" >&6; }
|
||||
if test "$ac_cv_sys_largefile_CC" != no; then
|
||||
CC=$CC$ac_cv_sys_largefile_CC
|
||||
fi
|
||||
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS value needed for large files" >&5
|
||||
printf %s "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; }
|
||||
if test ${ac_cv_sys_file_offset_bits+y}
|
||||
then :
|
||||
printf %s "(cached) " >&6
|
||||
else $as_nop
|
||||
while :; do
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
#include <sys/types.h>
|
||||
/* Check that off_t can represent 2**63 - 1 correctly.
|
||||
We can't simply define LARGE_OFF_T to be 9223372036854775807,
|
||||
since some C++ compilers masquerading as C compilers
|
||||
incorrectly reject 9223372036854775807. */
|
||||
#define LARGE_OFF_T (((off_t) 1 << 31 << 31) - 1 + ((off_t) 1 << 31 << 31))
|
||||
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
|
||||
&& LARGE_OFF_T % 2147483647 == 1)
|
||||
? 1 : -1];
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_compile "$LINENO"
|
||||
then :
|
||||
ac_cv_sys_file_offset_bits=no; break
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
#define _FILE_OFFSET_BITS 64
|
||||
#include <sys/types.h>
|
||||
/* Check that off_t can represent 2**63 - 1 correctly.
|
||||
We can't simply define LARGE_OFF_T to be 9223372036854775807,
|
||||
since some C++ compilers masquerading as C compilers
|
||||
incorrectly reject 9223372036854775807. */
|
||||
#define LARGE_OFF_T (((off_t) 1 << 31 << 31) - 1 + ((off_t) 1 << 31 << 31))
|
||||
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
|
||||
&& LARGE_OFF_T % 2147483647 == 1)
|
||||
? 1 : -1];
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_compile "$LINENO"
|
||||
then :
|
||||
ac_cv_sys_file_offset_bits=64; break
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
|
||||
ac_cv_sys_file_offset_bits=unknown
|
||||
break
|
||||
done
|
||||
fi
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_file_offset_bits" >&5
|
||||
printf "%s\n" "$ac_cv_sys_file_offset_bits" >&6; }
|
||||
case $ac_cv_sys_file_offset_bits in #(
|
||||
no | unknown) ;;
|
||||
*)
|
||||
printf "%s\n" "#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits" >>confdefs.h
|
||||
;;
|
||||
esac
|
||||
rm -rf conftest*
|
||||
if test $ac_cv_sys_file_offset_bits = unknown; then
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for _LARGE_FILES value needed for large files" >&5
|
||||
printf %s "checking for _LARGE_FILES value needed for large files... " >&6; }
|
||||
if test ${ac_cv_sys_large_files+y}
|
||||
then :
|
||||
printf %s "(cached) " >&6
|
||||
else $as_nop
|
||||
while :; do
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
#include <sys/types.h>
|
||||
/* Check that off_t can represent 2**63 - 1 correctly.
|
||||
We can't simply define LARGE_OFF_T to be 9223372036854775807,
|
||||
since some C++ compilers masquerading as C compilers
|
||||
incorrectly reject 9223372036854775807. */
|
||||
#define LARGE_OFF_T (((off_t) 1 << 31 << 31) - 1 + ((off_t) 1 << 31 << 31))
|
||||
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
|
||||
&& LARGE_OFF_T % 2147483647 == 1)
|
||||
? 1 : -1];
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_compile "$LINENO"
|
||||
then :
|
||||
ac_cv_sys_large_files=no; break
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
#define _LARGE_FILES 1
|
||||
#include <sys/types.h>
|
||||
/* Check that off_t can represent 2**63 - 1 correctly.
|
||||
We can't simply define LARGE_OFF_T to be 9223372036854775807,
|
||||
since some C++ compilers masquerading as C compilers
|
||||
incorrectly reject 9223372036854775807. */
|
||||
#define LARGE_OFF_T (((off_t) 1 << 31 << 31) - 1 + ((off_t) 1 << 31 << 31))
|
||||
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
|
||||
&& LARGE_OFF_T % 2147483647 == 1)
|
||||
? 1 : -1];
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_compile "$LINENO"
|
||||
then :
|
||||
ac_cv_sys_large_files=1; break
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
|
||||
ac_cv_sys_large_files=unknown
|
||||
break
|
||||
done
|
||||
fi
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_large_files" >&5
|
||||
printf "%s\n" "$ac_cv_sys_large_files" >&6; }
|
||||
case $ac_cv_sys_large_files in #(
|
||||
no | unknown) ;;
|
||||
*)
|
||||
printf "%s\n" "#define _LARGE_FILES $ac_cv_sys_large_files" >>confdefs.h
|
||||
;;
|
||||
esac
|
||||
rm -rf conftest*
|
||||
fi
|
||||
fi
|
||||
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for _LARGEFILE_SOURCE value needed for large files" >&5
|
||||
printf %s "checking for _LARGEFILE_SOURCE value needed for large files... " >&6; }
|
||||
if test ${ac_cv_sys_largefile_source+y}
|
||||
then :
|
||||
printf %s "(cached) " >&6
|
||||
else $as_nop
|
||||
while :; do
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
#include <sys/types.h> /* for off_t */
|
||||
#include <stdio.h>
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
int (*fp) (FILE *, off_t, int) = fseeko;
|
||||
return fseeko (stdin, 0, 0) && fp (stdin, 0, 0);
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
then :
|
||||
ac_cv_sys_largefile_source=no; break
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.beam \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
#define _LARGEFILE_SOURCE 1
|
||||
#include <sys/types.h> /* for off_t */
|
||||
#include <stdio.h>
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
int (*fp) (FILE *, off_t, int) = fseeko;
|
||||
return fseeko (stdin, 0, 0) && fp (stdin, 0, 0);
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
then :
|
||||
ac_cv_sys_largefile_source=1; break
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.beam \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
ac_cv_sys_largefile_source=unknown
|
||||
break
|
||||
done
|
||||
fi
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_source" >&5
|
||||
printf "%s\n" "$ac_cv_sys_largefile_source" >&6; }
|
||||
case $ac_cv_sys_largefile_source in #(
|
||||
no | unknown) ;;
|
||||
*)
|
||||
printf "%s\n" "#define _LARGEFILE_SOURCE $ac_cv_sys_largefile_source" >>confdefs.h
|
||||
;;
|
||||
esac
|
||||
rm -rf conftest*
|
||||
|
||||
# We used to try defining _XOPEN_SOURCE=500 too, to work around a bug
|
||||
# in glibc 2.1.3, but that breaks too many other things.
|
||||
# If you want fseeko and ftello with glibc, upgrade to a fixed glibc.
|
||||
if test $ac_cv_sys_largefile_source != unknown; then
|
||||
|
||||
printf "%s\n" "#define HAVE_FSEEKO 1" >>confdefs.h
|
||||
|
||||
fi
|
||||
|
||||
|
||||
ac_fn_c_check_header_compile "$LINENO" "sys/ioccom.h" "ac_cv_header_sys_ioccom_h" "$ac_includes_default"
|
||||
if test "x$ac_cv_header_sys_ioccom_h" = xyes
|
||||
then :
|
||||
|
|
@ -7232,6 +7232,12 @@ if test "x$ac_cv_header_sys_dlpi_ext_h" = xyes
|
|||
then :
|
||||
printf "%s\n" "#define HAVE_SYS_DLPI_EXT_H 1" >>confdefs.h
|
||||
|
||||
fi
|
||||
ac_fn_c_check_header_compile "$LINENO" "zone.h" "ac_cv_header_zone_h" "$ac_includes_default"
|
||||
if test "x$ac_cv_header_zone_h" = xyes
|
||||
then :
|
||||
printf "%s\n" "#define HAVE_ZONE_H 1" >>confdefs.h
|
||||
|
||||
fi
|
||||
|
||||
|
||||
|
|
@ -7418,22 +7424,6 @@ linux)
|
|||
#
|
||||
PLATFORM_C_SRC="pcap-linux.c"
|
||||
|
||||
#
|
||||
# Do we have the wireless extensions?
|
||||
#
|
||||
ac_fn_c_check_header_compile "$LINENO" "linux/wireless.h" "ac_cv_header_linux_wireless_h" "
|
||||
#include <sys/socket.h>
|
||||
#include <linux/if.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
"
|
||||
if test "x$ac_cv_header_linux_wireless_h" = xyes
|
||||
then :
|
||||
printf "%s\n" "#define HAVE_LINUX_WIRELESS_H 1" >>confdefs.h
|
||||
|
||||
fi
|
||||
|
||||
|
||||
#
|
||||
# Do we have libnl?
|
||||
# We only want version 3. Version 2 was, apparently,
|
||||
|
|
@ -10444,6 +10434,11 @@ fi
|
|||
|
||||
|
||||
rm -f os-proto.h
|
||||
#
|
||||
# MKDEP defaults to no-op (":") if we don't test whether the compiler
|
||||
# supports generating dependencies
|
||||
#
|
||||
MKDEP=:
|
||||
if test "${LBL_CFLAGS+set}" = set; then
|
||||
V_CCOPT="$V_CCOPT ${LBL_CFLAGS}"
|
||||
fi
|
||||
|
|
@ -12550,16 +12545,20 @@ printf "%s\n" "no" >&6; }
|
|||
# .devel file; why should the ABI for which we produce code
|
||||
# depend on .devel?
|
||||
#
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to use an os-proto.h header" >&5
|
||||
printf %s "checking whether to use an os-proto.h header... " >&6; }
|
||||
os=`echo $host_os | sed -e 's/\([0-9][0-9]*\)[^0-9].*$/\1/'`
|
||||
name="lbl/os-$os.h"
|
||||
if test -f $name ; then
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes, at \"$name\"" >&5
|
||||
printf "%s\n" "yes, at \"$name\"" >&6; }
|
||||
ln -s $name os-proto.h
|
||||
|
||||
printf "%s\n" "#define HAVE_OS_PROTO_H 1" >>confdefs.h
|
||||
|
||||
else
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: can't find $name" >&5
|
||||
printf "%s\n" "$as_me: WARNING: can't find $name" >&2;}
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
printf "%s\n" "no" >&6; }
|
||||
fi
|
||||
fi
|
||||
|
||||
|
|
@ -12870,9 +12869,12 @@ else $as_nop
|
|||
want_dpdk=no
|
||||
else
|
||||
#
|
||||
# Use DPDK API if present, otherwise don't
|
||||
# User didn't explicitly request DPDK; don't give it
|
||||
# to them without their consent, as the code is
|
||||
# immensely hard to keep compiling for every random
|
||||
# API change the DPDK folks make.
|
||||
#
|
||||
want_dpdk=ifpresent
|
||||
want_dpdk=no
|
||||
fi
|
||||
|
||||
fi
|
||||
|
|
@ -13282,10 +13284,10 @@ else $as_nop
|
|||
# Bluetooth sniffing.
|
||||
#
|
||||
if test "x$enable_bluetooth" = "xyes" ; then
|
||||
as_fn_error $? "Bluetooth sniffing is not supported; install bluez-lib devel to enable it" "$LINENO" 5
|
||||
as_fn_error $? "Bluetooth sniffing is not supported; install a Bluetooth devel library (libbluetooth-dev|bluez-libs-devel|bluez-dev|libbluetooth-devel|...) to enable it" "$LINENO" 5
|
||||
else
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: Bluetooth sniffing is not supported; install bluez-lib devel to enable it" >&5
|
||||
printf "%s\n" "$as_me: Bluetooth sniffing is not supported; install bluez-lib devel to enable it" >&6;}
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: Bluetooth sniffing is not supported; install a Bluetooth devel library (libbluetooth-dev|bluez-libs-devel|bluez-dev|libbluetooth-devel|...) to enable it" >&5
|
||||
printf "%s\n" "$as_me: Bluetooth sniffing is not supported; install a Bluetooth devel library (libbluetooth-dev|bluez-libs-devel|bluez-dev|libbluetooth-devel|...) to enable it" >&6;}
|
||||
fi
|
||||
|
||||
fi
|
||||
|
|
@ -14460,7 +14462,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
|
|||
# report actual input values of CONFIG_FILES etc. instead of their
|
||||
# values after options handling.
|
||||
ac_log="
|
||||
This file was extended by pcap $as_me 1.10.5, which was
|
||||
This file was extended by pcap $as_me 1.10.6, which was
|
||||
generated by GNU Autoconf 2.71. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
|
|
@ -14528,7 +14530,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\
|
|||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||
ac_cs_config='$ac_cs_config_escaped'
|
||||
ac_cs_version="\\
|
||||
pcap config.status 1.10.5
|
||||
pcap config.status 1.10.6
|
||||
configured by $0, generated by GNU Autoconf 2.71,
|
||||
with options \\"\$ac_cs_config\\"
|
||||
|
||||
|
|
@ -15278,4 +15280,3 @@ printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2
|
|||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
|
|
|
|||
37
configure.ac
37
configure.ac
|
|
@ -111,6 +111,12 @@ if test "$ac_cv_prog_cc_c99" = "no"; then
|
|||
AC_MSG_ERROR([The C compiler does not support C99])
|
||||
fi
|
||||
|
||||
#
|
||||
# Try to arrange for large file support.
|
||||
#
|
||||
AC_SYS_LARGEFILE
|
||||
AC_FUNC_FSEEKO
|
||||
|
||||
#
|
||||
# Get the size of a void *, to determine whether this is a 32-bit
|
||||
# or 64-bit build.
|
||||
|
|
@ -128,12 +134,6 @@ AC_LBL_SHLIBS_INIT
|
|||
AC_LBL_C_INLINE
|
||||
AC_PCAP_C___ATOMICS
|
||||
|
||||
#
|
||||
# Try to arrange for large file support.
|
||||
#
|
||||
AC_SYS_LARGEFILE
|
||||
AC_FUNC_FSEEKO
|
||||
|
||||
dnl
|
||||
dnl Even if <net/bpf.h> were, on all OSes that support BPF, fixed to
|
||||
dnl include <sys/ioccom.h>, and we were to drop support for older
|
||||
|
|
@ -905,7 +905,7 @@ dlpi)
|
|||
#
|
||||
# Checks for some header files.
|
||||
#
|
||||
AC_CHECK_HEADERS(sys/bufmod.h sys/dlpi_ext.h)
|
||||
AC_CHECK_HEADERS(sys/bufmod.h sys/dlpi_ext.h zone.h)
|
||||
|
||||
#
|
||||
# Checks to see if Solaris has the public libdlpi(3LIB) library.
|
||||
|
|
@ -1003,16 +1003,6 @@ linux)
|
|||
#
|
||||
PLATFORM_C_SRC="pcap-linux.c"
|
||||
|
||||
#
|
||||
# Do we have the wireless extensions?
|
||||
#
|
||||
AC_CHECK_HEADERS(linux/wireless.h, [], [],
|
||||
[
|
||||
#include <sys/socket.h>
|
||||
#include <linux/if.h>
|
||||
#include <linux/types.h>
|
||||
])
|
||||
|
||||
#
|
||||
# Do we have libnl?
|
||||
# We only want version 3. Version 2 was, apparently,
|
||||
|
|
@ -2682,7 +2672,7 @@ fi
|
|||
|
||||
# Check for DPDK support.
|
||||
AC_ARG_WITH([dpdk],
|
||||
AS_HELP_STRING([--with-dpdk@<:@=DIR@:>@],[include DPDK support (located in directory DIR, if supplied). @<:@default=yes, if present@:>@]),
|
||||
AS_HELP_STRING([--with-dpdk@<:@=DIR@:>@],[include DPDK support (located in directory DIR, if supplied). @<:@default=no@:>@]),
|
||||
[
|
||||
if test "$withval" = no
|
||||
then
|
||||
|
|
@ -2709,9 +2699,12 @@ AS_HELP_STRING([--with-dpdk@<:@=DIR@:>@],[include DPDK support (located in direc
|
|||
want_dpdk=no
|
||||
else
|
||||
#
|
||||
# Use DPDK API if present, otherwise don't
|
||||
# User didn't explicitly request DPDK; don't give it
|
||||
# to them without their consent, as the code is
|
||||
# immensely hard to keep compiling for every random
|
||||
# API change the DPDK folks make.
|
||||
#
|
||||
want_dpdk=ifpresent
|
||||
want_dpdk=no
|
||||
fi
|
||||
])
|
||||
|
||||
|
|
@ -2951,9 +2944,9 @@ if test "x$enable_bluetooth" != "xno" ; then
|
|||
# Bluetooth sniffing.
|
||||
#
|
||||
if test "x$enable_bluetooth" = "xyes" ; then
|
||||
AC_MSG_ERROR(Bluetooth sniffing is not supported; install bluez-lib devel to enable it)
|
||||
AC_MSG_ERROR(Bluetooth sniffing is not supported; install a Bluetooth devel library (libbluetooth-dev|bluez-libs-devel|bluez-dev|libbluetooth-devel|...) to enable it)
|
||||
else
|
||||
AC_MSG_NOTICE(Bluetooth sniffing is not supported; install bluez-lib devel to enable it)
|
||||
AC_MSG_NOTICE(Bluetooth sniffing is not supported; install a Bluetooth devel library (libbluetooth-dev|bluez-libs-devel|bluez-dev|libbluetooth-devel|...) to enable it)
|
||||
fi
|
||||
])
|
||||
;;
|
||||
|
|
|
|||
124
dlpisubs.c
124
dlpisubs.c
|
|
@ -60,10 +60,20 @@
|
|||
#include <stropts.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sockio.h>
|
||||
|
||||
#include <net/if.h>
|
||||
|
||||
#ifdef HAVE_LIBDLPI
|
||||
#include <libdlpi.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ZONE_H
|
||||
#include <zone.h>
|
||||
#endif
|
||||
|
||||
#include "pcap-int.h"
|
||||
#include "dlpisubs.h"
|
||||
|
||||
|
|
@ -413,3 +423,117 @@ pcap_stream_err(const char *func, int err, char *errbuf)
|
|||
pcapint_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, err, "%s", func);
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
handle_nonexistent_dlpi_device(const char *ifname, char *errbuf)
|
||||
{
|
||||
int fd;
|
||||
int status;
|
||||
#ifdef LIFNAMSIZ
|
||||
struct lifreq lifr;
|
||||
#else
|
||||
struct ifreq ifr;
|
||||
#endif
|
||||
|
||||
#ifdef LIFNAMSIZ
|
||||
if (strlen(ifname) >= sizeof(lifr.lifr_name)) {
|
||||
#else
|
||||
if (strlen(ifname) >= sizeof(ifr.ifr_name)) {
|
||||
#endif
|
||||
/*
|
||||
* The name is too long, so it can't possibly exist.
|
||||
*/
|
||||
strlcpy(errbuf, "", PCAP_ERRBUF_SIZE);
|
||||
return (PCAP_ERROR_NO_SUCH_DEVICE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Try to get a socket on which to do an ioctl to get the
|
||||
* interface's flags.
|
||||
*/
|
||||
fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (fd < 0) {
|
||||
/* That failed; report that as the error. */
|
||||
pcapint_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
|
||||
errno, "Can't open socket to get interface flags");
|
||||
return (PCAP_ERROR);
|
||||
}
|
||||
|
||||
#ifdef LIFNAMSIZ
|
||||
pcapint_strlcpy(lifr.lifr_name, ifname, sizeof(lifr.lifr_name));
|
||||
status = ioctl(fd, SIOCGLIFFLAGS, (char *)&lifr);
|
||||
#else
|
||||
pcapint_strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
|
||||
status = ioctl(fd, SIOCGIFFLAGS, (char *)&ifr);
|
||||
#endif
|
||||
|
||||
if (status < 0) {
|
||||
if (errno == ENXIO || errno == EINVAL) {
|
||||
/*
|
||||
* macOS, *BSD, and Solaris return one of
|
||||
* those two errors if the device doesn't exist.
|
||||
*/
|
||||
strlcpy(errbuf, "", PCAP_ERRBUF_SIZE);
|
||||
close(fd);
|
||||
return (PCAP_ERROR_NO_SUCH_DEVICE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Some other error.
|
||||
*/
|
||||
pcapint_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, errno,
|
||||
"Can't get interface flags");
|
||||
close(fd);
|
||||
return (PCAP_ERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
* The interface exists.
|
||||
*/
|
||||
close(fd);
|
||||
|
||||
#ifdef HAVE_ZONE_H
|
||||
/*
|
||||
* If we're not in a global zone, the problem is probably
|
||||
* that the zone we're in doesn't happen to have any
|
||||
* DLPI devices. Exclusive-IP non-global zones have
|
||||
* their own interfaces and have DLPI devices for them:
|
||||
*
|
||||
* https://docs.oracle.com/cd/E37838_01/html/E61040/z.config.ov-6.html#VLZCRgekkb
|
||||
*
|
||||
* https://docs.oracle.com/cd/E19044-01/sol.containers/817-1592/geprv/index.html
|
||||
*
|
||||
* but shared-IP non-global zones don't:
|
||||
*
|
||||
* https://docs.oracle.com/cd/E37838_01/html/E61040/z.config.ov-6.html#VLZCRgekku
|
||||
*/
|
||||
if (getzoneid() != GLOBAL_ZONEID) {
|
||||
/*
|
||||
* Not a global zone; note that capturing on network
|
||||
* interfaces is only supported for interfaces
|
||||
* in an exclusive-IP zone.
|
||||
*/
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Capturing on interfaces in a non-global zone is supported only for interfaces in exclusive-IP zones");
|
||||
return (PCAP_ERROR_CAPTURE_NOTSUP);
|
||||
}
|
||||
#endif /* HAVE_ZONE_H */
|
||||
|
||||
/*
|
||||
* Some other problem; just report it as not having
|
||||
* a DLPI device. We don't report the DLPI device
|
||||
* name, so people don't get confused and think, for
|
||||
* example, that if they can't capture on that interface
|
||||
* on Solaris prior to Solaris 11 the fix is to change
|
||||
* libpcap (or the application that uses it) to look
|
||||
* for something other than "/dev/{ifname}", as the fix
|
||||
* is to use Solaris 11 or some operating system other
|
||||
* than Solaris - you just *can't* capture on that
|
||||
* interface on Solaris prior to Solaris 11, the lack
|
||||
* of a DLPI device for the loopback interface is just
|
||||
* a symptom of that inability.
|
||||
*/
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Capturing on that interface is not supported - no DLPI device found");
|
||||
return (PCAP_ERROR_CAPTURE_NOTSUP);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ int pcap_conf_bufmod(pcap_t *, int);
|
|||
#endif
|
||||
int pcap_alloc_databuf(pcap_t *);
|
||||
int strioctl(int, int, int, char *);
|
||||
int handle_nonexistent_dlpi_device(const char *ifname, char *errbuf);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,10 +2,9 @@
|
|||
|
||||
Haiku R1/beta4 and earlier versions do not support packet capture on the
|
||||
loopback interface. Using this version of libpcap, loopback capture works
|
||||
since Haiku revision hrev57585 and is expected to work in Haiku R1/beta5 when
|
||||
the latter becomes available. Packet timestamping and filtering always occur
|
||||
in userland. Wireless monitor mode is not supported. The "any"
|
||||
pseudo-interface is not supported.
|
||||
since Haiku revision hrev57585, including Haiku R1/beta5 and later versions.
|
||||
Packet timestamping and filtering always occur in userland. Wireless monitor
|
||||
mode is not supported. The "any" pseudo-interface is not supported.
|
||||
[**pcap_set_buffer_size**](https://www.tcpdump.org/manpages/pcap_set_buffer_size.3pcap.html)(3PCAP)
|
||||
has no effect.
|
||||
[**pcap_setdirection**](https://www.tcpdump.org/manpages/pcap_setdirection.3pcap.html)(3PCAP)
|
||||
|
|
@ -22,36 +21,19 @@ on Haiku are as follows:
|
|||
* `ps_ifdrop` is the number of packets dropped by the network interface (as
|
||||
seen via `SIOCGIFSTATS`) since the capture handle became active.
|
||||
|
||||
## 64-bit x86 R1/beta4
|
||||
## 64-bit x86 R1/beta5
|
||||
|
||||
* Autoconf 2.71 works.
|
||||
* CMake 3.28.3 works.
|
||||
* GCC 13.2.0 works.
|
||||
* Clang 12.0.1 works with the latest llvm12_clang-12.0.1-5 version.
|
||||
* Autoconf 2.72 works.
|
||||
* CMake 4.1.4 works.
|
||||
* GCC 13.3.0 works.
|
||||
* Clang 21.1.8
|
||||
* flex 2.6.4 works.
|
||||
* bison 3.8.2 works.
|
||||
* GNU Bison 3.8.2 works.
|
||||
|
||||
The following command will install respective non-default packages:
|
||||
```
|
||||
pkgman install cmake llvm12_clang
|
||||
pkgman install cmake llvm21_clang
|
||||
```
|
||||
|
||||
For reference, the tests were done using a system installed from
|
||||
`haiku-r1beta4-x86_64-anyboot.iso`.
|
||||
|
||||
## 32-bit x86 R1/beta4
|
||||
|
||||
* Autoconf 2.71 works.
|
||||
* CMake 3.24.2 works.
|
||||
* GCC 11.2.0 works.
|
||||
* Clang does not work.
|
||||
* flex 2.6.4 works.
|
||||
* bison 3.0.5 works.
|
||||
|
||||
The following command will install respective non-default packages:
|
||||
```
|
||||
pkgman install cmake_x86
|
||||
```
|
||||
|
||||
For reference, the tests were done using a system installed from
|
||||
`haiku-r1beta4-x86_gcc2h-anyboot.iso`.
|
||||
`haiku-r1beta5-x86_64-anyboot.iso`.
|
||||
|
|
|
|||
|
|
@ -5,6 +5,12 @@
|
|||
* Neither illumos lex nor illumos yacc are suitable.
|
||||
* Solaris m4 and illumos m4 are suitable.
|
||||
|
||||
## OmniOS r151054/AMD64
|
||||
|
||||
* flex 2.6.4 and GNU Bison 3.8.2 work.
|
||||
* CMake 4.0.3 works.
|
||||
* GCC 14.2.0 and Clang 19.1.7 work.
|
||||
|
||||
## OmniOS r151042/AMD64
|
||||
|
||||
* flex 2.6.4 and GNU Bison 3.8.2 work.
|
||||
|
|
@ -30,15 +36,18 @@ developer/clang-90
|
|||
ENDOFTEXT
|
||||
```
|
||||
|
||||
## Solaris 11/AMD64
|
||||
## Solaris CBE 11.4.81.193.1/AMD64
|
||||
* flex 2.6.4 and GNU Bison 3.8.2 work.
|
||||
* CMake 3.24.0 works.
|
||||
* Clang 19.1.7 works, GCC 14.2.0 works.
|
||||
|
||||
## Solaris CBE 11.4.42.111.0/AMD64
|
||||
|
||||
* flex 2.6.4 and GNU Bison 3.7.3 work.
|
||||
* CMake 3.21.0 works.
|
||||
* Clang 11.0 works, GCC 11.2 works.
|
||||
|
||||
For reference, the tests were done using Oracle Solaris 11.4.42.111.0.
|
||||
|
||||
## Solaris 11/SPARC
|
||||
## Solaris 11.3/SPARC
|
||||
|
||||
* flex 2.6.4 and GNU Bison 3.7.1 work.
|
||||
* CMake 3.14.3 works.
|
||||
|
|
@ -51,8 +60,7 @@ For reference, the tests were done using Oracle Solaris 11.4.42.111.0.
|
|||
* CMake 3.14.3 works.
|
||||
* Sun C 5.13 works, GCC 5.5.0 works.
|
||||
|
||||
## Solaris 9/SPARC
|
||||
## Solaris 9
|
||||
|
||||
* flex 2.5.35 and GNU Bison 3.0.2 work.
|
||||
* CMake 2.8.9 does not work.
|
||||
* Neither Sun C 5.8 nor Sun C 5.9 work, GCC 4.6.4 works.
|
||||
This version of this OS is not supported because the snprintf(3) implementation
|
||||
in its libc is not suitable.
|
||||
|
|
|
|||
|
|
@ -26,48 +26,43 @@ only if there is some other requirement to use it rather than Npcap,
|
|||
such as a requirement to support versions of Windows earlier than
|
||||
Windows Vista, which is the earliest version supported by Npcap.
|
||||
|
||||
Npcap and its SDK can be downloaded from its home page:
|
||||
|
||||
https://npcap.com
|
||||
|
||||
The SDK is a ZIP archive; create a folder on your C: drive, e.g.
|
||||
C:\npcap-sdk, and put the contents of the ZIP archive into that folder.
|
||||
Npcap and its SDK can be downloaded from its [home page](https://npcap.com).
|
||||
The SDK is a ZIP archive; create a folder on your `C:` drive, e.g.
|
||||
`C:\npcap-sdk`, and put the contents of the ZIP archive into that folder.
|
||||
|
||||
The WinPcap installer can be downloaded from
|
||||
|
||||
https://www.winpcap.org/install/default.htm
|
||||
|
||||
[here](https://www.winpcap.org/install/default.htm)
|
||||
and the WinPcap Developer's Kit can be downloaded from
|
||||
|
||||
https://www.winpcap.org/devel.htm
|
||||
[here](https://www.winpcap.org/devel.htm).
|
||||
|
||||
Required build tools
|
||||
--------------------
|
||||
|
||||
The Developer's Kit is a ZIP archive; it contains a folder named
|
||||
WpdPack, which you should place on your C: drive, e.g. C:\WpdPack.
|
||||
`WpdPack`, which you should place on your `C:` drive, e.g. `C:\WpdPack`.
|
||||
|
||||
Building libpcap on Windows requires Visual Studio 2015 or later. The
|
||||
Community Edition of Visual Studio can be downloaded at no cost from
|
||||
|
||||
https://visualstudio.microsoft.com
|
||||
[here](https://visualstudio.microsoft.com).
|
||||
|
||||
Additional tools are also required. Chocolatey is a package manager for
|
||||
Windows with which those tools, and other tools, can be installed; it
|
||||
can be downloaded from
|
||||
|
||||
https://chocolatey.org
|
||||
can be downloaded from [here](https://chocolatey.org).
|
||||
|
||||
It is a command-line tool; a GUI tool, Chocolatey GUI, is provided as a
|
||||
Chocolatey package, which can be installed from the command line:
|
||||
|
||||
choco install chocolateygui
|
||||
```
|
||||
choco install chocolateygui
|
||||
```
|
||||
|
||||
For convenience, the "choco install" command can be run with the "-y"
|
||||
For convenience, the `choco install` command can be run with the `-y`
|
||||
flag, forcing it to automatically answer all questions asked of the user
|
||||
with "yes":
|
||||
|
||||
choco install -y chocolateygui
|
||||
```
|
||||
choco install -y chocolateygui
|
||||
```
|
||||
|
||||
The required tools are:
|
||||
|
||||
|
|
@ -77,31 +72,31 @@ libpcap does not provide supported project files for Visual Studio
|
|||
(there are currently unsupported project files provided, but we do not
|
||||
guarantee that they will work or that we will continue to provide them).
|
||||
It does provide files for CMake, which is a cross-platform tool that
|
||||
runs on UN*Xes and on Windows and that can generate project files for
|
||||
UN*X Make, the Ninja build system, and Visual Studio, among other build
|
||||
runs on UN\*Xes and on Windows and that can generate project files for
|
||||
UN\*X Make, the Ninja build system, and Visual Studio, among other build
|
||||
systems.
|
||||
|
||||
Visual Studio 2015 does not provide CMake; an installer can be
|
||||
downloaded from
|
||||
|
||||
https://cmake.org/download/
|
||||
downloaded from [here](https://cmake.org/download/).
|
||||
|
||||
When you run the installer, you should choose to add CMake to the system
|
||||
PATH for all users and to create the desktop icon.
|
||||
`PATH` for all users and to create the desktop icon.
|
||||
|
||||
CMake can also be installed as the Chocolatey package "cmake":
|
||||
|
||||
choco install -y cmake
|
||||
|
||||
Visual Studio 2017 and later provide CMake, so you will not need to
|
||||
install CMake if you have installed Visual Studio 2017 or later. They
|
||||
include built-in support for CMake-based projects:
|
||||
|
||||
https://devblogs.microsoft.com/cppblog/cmake-support-in-visual-studio/
|
||||
Visual Studio 2017, 2019, and 2022 provide CMake, so you will not need
|
||||
to install CMake if you have installed one of those versions of Visual
|
||||
Studio or later. They include built-in support for CMake-based projects
|
||||
as described
|
||||
[here](https://devblogs.microsoft.com/cppblog/cmake-support-in-visual-studio/).
|
||||
|
||||
For Visual Studio 2017, make sure "Visual C++ tools for CMake" is
|
||||
installed; for Visual Studio 2019, make sure "C++ CMake tools for
|
||||
Windows" is installed.
|
||||
installed; for Visual Studio 2019 and 2022, make sure "C++ CMake tools
|
||||
for Windows" is installed.
|
||||
|
||||
CMake can also be installed as the Chocolatey package `cmake`:
|
||||
|
||||
```
|
||||
choco install -y cmake
|
||||
```
|
||||
|
||||
### winflexbison ###
|
||||
|
||||
|
|
@ -140,19 +135,21 @@ Debug build.
|
|||
|
||||
In the CMakeSettings.json tab, change cmakeCommandArgs to include
|
||||
|
||||
-DPacket_ROOT={path-to-sdk}
|
||||
```
|
||||
-DPacket_ROOT={path-to-sdk}
|
||||
```
|
||||
|
||||
where {path-to-sdk} is the path of the directory containing the Npcap or
|
||||
where `{path-to-sdk}` is the path of the directory containing the Npcap or
|
||||
WinPcap SDK. Note that backslashes in the path must be specified as two
|
||||
backslashes.
|
||||
|
||||
Save the configuration changes with File > "Save CMakeSettings.json" or
|
||||
with control-S.
|
||||
with Control-S.
|
||||
|
||||
Visual Studio will then re-run CMake. If that completes without errors,
|
||||
you can build with CMake > "Build All".
|
||||
|
||||
### Visual Studio 2019 ###
|
||||
### Visual Studio 2019 and 2022 ###
|
||||
|
||||
Open the folder containing the libpcap source with Open > Folder.
|
||||
Visual Studio will run CMake; however, you will need to indicate where
|
||||
|
|
@ -169,7 +166,7 @@ the directory containing the Npcap or WinPcap SDK or use the "Browse..."
|
|||
button to browse for that directory.
|
||||
|
||||
Save the configuration changes with File > "Save CMakeSettings.json" or
|
||||
with control-S.
|
||||
with Control-S.
|
||||
|
||||
Visual Studio will then re-run CMake. If that completes without errors,
|
||||
you can build with Build > "Build All".
|
||||
|
|
@ -177,6 +174,8 @@ you can build with Build > "Build All".
|
|||
Building from the command line
|
||||
------------------------------
|
||||
|
||||
### Visual Studio 2017 ###
|
||||
|
||||
Start the appropriate Native Tools command line prompt.
|
||||
|
||||
Change to the directory into which you want to build libpcap, possibly
|
||||
|
|
@ -185,14 +184,96 @@ of the libpcap source directory.
|
|||
|
||||
Run the command
|
||||
|
||||
cmake "-DPacket_ROOT={path-to-sdk}" {path-to-libpcap-source}
|
||||
```
|
||||
cmake "-DPacket_ROOT={path-to-sdk}" -G {generator} {path-to-libpcap-source}
|
||||
```
|
||||
|
||||
where {path-to-sdk} is the path of the directory containing the Npcap or
|
||||
WinPcap SDK and {path-to-libpcap-source} is the pathname of the
|
||||
top-level source directory for libpcap.
|
||||
`{path-to-sdk}` is the path of the directory containing the Npcap or
|
||||
WinPcap SDK.
|
||||
|
||||
`{generator}` is the string "Visual Studio 15 2017" to build a 32-bit
|
||||
version of libpcap or the string "Visual Studio 15 2017 Win64" to build
|
||||
a 64-bit version of libpcap.
|
||||
|
||||
`{path-to-libpcap-source}` is the pathname of the top-level source
|
||||
directory for libpcap.
|
||||
|
||||
Run the command
|
||||
|
||||
msbuild/m pcap.sln
|
||||
```
|
||||
msbuild /m /nologo /p:Configuration={configuration} pcap.sln
|
||||
```
|
||||
|
||||
to compile libpcap.
|
||||
where `{configuration}` can be "Release", "Debug", or "RelWithDebInfo".
|
||||
|
||||
### Visual Studio 2019 ###
|
||||
|
||||
Start the appropriate Native Tools command line prompt.
|
||||
|
||||
Change to the directory into which you want to build libpcap, possibly
|
||||
after creating it first. One choice is to create it as a subdirectory
|
||||
of the libpcap source directory.
|
||||
|
||||
Run the command
|
||||
|
||||
```
|
||||
cmake "-DPacket_ROOT={path-to-sdk}" -G "Visual Studio 16 2019" {platform} {path-to-libpcap-source}
|
||||
```
|
||||
|
||||
`{path-to-sdk}` is the path of the directory containing the Npcap or
|
||||
WinPcap SDK.
|
||||
|
||||
`{platform}` is `-A Win32` to build a 32-bit version of libpcap or `-A
|
||||
x64` to build a 64-bit version of libpcap.
|
||||
|
||||
`{path-to-libpcap-source}` is the pathname of the top-level source
|
||||
directory for libpcap.
|
||||
|
||||
Run the command
|
||||
|
||||
```
|
||||
msbuild /m /nologo /p:Configuration={configuration} pcap.sln
|
||||
```
|
||||
|
||||
where `{configuration}` can be "Release", "Debug", or "RelWithDebInfo".
|
||||
|
||||
### Visual Studio 2022 ###
|
||||
|
||||
Start the appropriate Native Tools command line prompt.
|
||||
|
||||
Change to the directory into which you want to build libpcap, possibly
|
||||
after creating it first. One choice is to create it as a subdirectory
|
||||
of the libpcap source directory.
|
||||
|
||||
Run the command
|
||||
|
||||
```
|
||||
cmake "-DPacket_ROOT={path-to-sdk}" -G "Visual Studio 17 2022" {platform} {path-to-libpcap-source}
|
||||
```
|
||||
|
||||
`{path-to-sdk}` is the path of the directory containing the Npcap or
|
||||
WinPcap SDK.
|
||||
|
||||
`{platform}` is `-A Win32` to build a 32-bit version of libpcap or `-A
|
||||
x64` to build a 64-bit version of libpcap.
|
||||
|
||||
`{path-to-libpcap-source}` is the pathname of the top-level source
|
||||
directory for libpcap.
|
||||
|
||||
Run the command
|
||||
|
||||
```
|
||||
msbuild /m /nologo /p:Configuration={configuration} pcap.sln
|
||||
```
|
||||
|
||||
where `{configuration}` can be "Release", "Debug", or "RelWithDebInfo".
|
||||
|
||||
Building with MinGW
|
||||
-------------------
|
||||
|
||||
MinGW is not supported because its snprintf(3) implementation is not suitable.
|
||||
|
||||
Building with SSL/TLS support
|
||||
-----------------------------
|
||||
|
||||
This is currently not implemented on Windows.
|
||||
|
|
|
|||
13
fad-getad.c
13
fad-getad.c
|
|
@ -162,7 +162,7 @@ pcapint_findalldevs_interfaces(pcap_if_list_t *devlistp, char *errbuf,
|
|||
{
|
||||
struct ifaddrs *ifap, *ifa;
|
||||
struct sockaddr *addr, *netmask, *broadaddr, *dstaddr;
|
||||
size_t addr_size, broadaddr_size, dstaddr_size;
|
||||
size_t addr_size, netmask_size, broadaddr_size, dstaddr_size;
|
||||
int ret = 0;
|
||||
char *p, *q;
|
||||
|
||||
|
|
@ -235,11 +235,18 @@ pcapint_findalldevs_interfaces(pcap_if_list_t *devlistp, char *errbuf,
|
|||
if (ifa->ifa_addr != NULL) {
|
||||
addr = ifa->ifa_addr;
|
||||
addr_size = SA_LEN(addr);
|
||||
netmask = ifa->ifa_netmask;
|
||||
if (ifa->ifa_netmask != NULL) {
|
||||
netmask = ifa->ifa_netmask;
|
||||
netmask_size = SA_LEN(ifa->ifa_netmask);
|
||||
} else {
|
||||
netmask = NULL;
|
||||
netmask_size = 0;
|
||||
}
|
||||
} else {
|
||||
addr = NULL;
|
||||
addr_size = 0;
|
||||
netmask = NULL;
|
||||
netmask_size = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -279,7 +286,7 @@ pcapint_findalldevs_interfaces(pcap_if_list_t *devlistp, char *errbuf,
|
|||
*/
|
||||
if (pcapint_add_addr_to_if(devlistp, ifa->ifa_name, ifa->ifa_flags,
|
||||
get_flags_func,
|
||||
addr, addr_size, netmask, addr_size,
|
||||
addr, addr_size, netmask, netmask_size,
|
||||
broadaddr, broadaddr_size, dstaddr, dstaddr_size,
|
||||
errbuf) < 0) {
|
||||
ret = -1;
|
||||
|
|
|
|||
|
|
@ -233,7 +233,7 @@ utf_16le_to_utf_8_truncated(const wchar_t *utf_16, char *utf_8,
|
|||
*utf_8++ = ((uc >> 12) & 0x3F) | 0x80;
|
||||
*utf_8++ = ((uc >> 6) & 0x3F) | 0x80;
|
||||
*utf_8++ = ((uc >> 0) & 0x3F) | 0x80;
|
||||
utf_8_len -= 3;
|
||||
utf_8_len -= 4;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
346
gencode.c
346
gencode.c
|
|
@ -24,14 +24,7 @@
|
|||
#ifdef _WIN32
|
||||
#include <ws2tcpip.h>
|
||||
#else
|
||||
#include <sys/socket.h>
|
||||
|
||||
#ifdef __NetBSD__
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#include <stdlib.h>
|
||||
|
|
@ -76,6 +69,10 @@
|
|||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef HAVE_NPCAP_BPF_H
|
||||
/* Defines BPF extensions for Npcap */
|
||||
#include <npcap-bpf.h>
|
||||
#endif
|
||||
#ifdef INET6
|
||||
#if defined(__MINGW32__) && defined(DEFINE_ADDITIONAL_IPV6_STUFF)
|
||||
/* IPv6 address */
|
||||
|
|
@ -230,6 +227,26 @@ struct chunk {
|
|||
void *m;
|
||||
};
|
||||
|
||||
/*
|
||||
* A chunk can store any of:
|
||||
* - a string (guaranteed alignment 1 but present for completeness)
|
||||
* - a block
|
||||
* - an slist
|
||||
* - an arth
|
||||
* For this simple allocator every allocated chunk gets rounded up to the
|
||||
* alignment needed for any chunk.
|
||||
*/
|
||||
struct chunk_align {
|
||||
char dummy;
|
||||
union {
|
||||
char c;
|
||||
struct block b;
|
||||
struct slist s;
|
||||
struct arth a;
|
||||
} u;
|
||||
};
|
||||
#define CHUNK_ALIGN (offsetof(struct chunk_align, u))
|
||||
|
||||
/* Code generator state */
|
||||
|
||||
struct _compiler_state {
|
||||
|
|
@ -526,7 +543,7 @@ static struct block *gen_hostop(compiler_state_t *, bpf_u_int32, bpf_u_int32,
|
|||
static struct block *gen_hostop6(compiler_state_t *, struct in6_addr *,
|
||||
struct in6_addr *, int, bpf_u_int32, u_int, u_int);
|
||||
#endif
|
||||
static struct block *gen_ahostop(compiler_state_t *, const u_char *, int);
|
||||
static struct block *gen_ahostop(compiler_state_t *, const uint8_t, int);
|
||||
static struct block *gen_ehostop(compiler_state_t *, const u_char *, int);
|
||||
static struct block *gen_fhostop(compiler_state_t *, const u_char *, int);
|
||||
static struct block *gen_thostop(compiler_state_t *, const u_char *, int);
|
||||
|
|
@ -598,13 +615,8 @@ newchunk_nolongjmp(compiler_state_t *cstate, size_t n)
|
|||
int k;
|
||||
size_t size;
|
||||
|
||||
#ifndef __NetBSD__
|
||||
/* XXX Round up to nearest long. */
|
||||
n = (n + sizeof(long) - 1) & ~(sizeof(long) - 1);
|
||||
#else
|
||||
/* XXX Round up to structure boundary. */
|
||||
n = ALIGN(n);
|
||||
#endif
|
||||
/* Round up to chunk alignment. */
|
||||
n = (n + CHUNK_ALIGN - 1) & ~(CHUNK_ALIGN - 1);
|
||||
|
||||
cp = &cstate->chunks[cstate->cur_chunk];
|
||||
if (n > cp->n_left) {
|
||||
|
|
@ -696,7 +708,7 @@ new_stmt(compiler_state_t *cstate, int code)
|
|||
}
|
||||
|
||||
static struct block *
|
||||
gen_retblk(compiler_state_t *cstate, int v)
|
||||
gen_retblk_internal(compiler_state_t *cstate, int v)
|
||||
{
|
||||
struct block *b = new_block(cstate, BPF_RET|BPF_K);
|
||||
|
||||
|
|
@ -704,6 +716,22 @@ gen_retblk(compiler_state_t *cstate, int v)
|
|||
return b;
|
||||
}
|
||||
|
||||
static struct block *
|
||||
gen_retblk(compiler_state_t *cstate, int v)
|
||||
{
|
||||
if (setjmp(cstate->top_ctx)) {
|
||||
/*
|
||||
* gen_retblk() only fails because a memory
|
||||
* allocation failed in newchunk(), meaning
|
||||
* that it can't return a pointer.
|
||||
*
|
||||
* Return NULL.
|
||||
*/
|
||||
return NULL;
|
||||
}
|
||||
return gen_retblk_internal(cstate, v);
|
||||
}
|
||||
|
||||
static inline PCAP_NORETURN_DEF void
|
||||
syntax(compiler_state_t *cstate)
|
||||
{
|
||||
|
|
@ -718,9 +746,8 @@ pcap_compile(pcap_t *p, struct bpf_program *program,
|
|||
static int done = 0;
|
||||
#endif
|
||||
compiler_state_t cstate;
|
||||
const char * volatile xbuf = buf;
|
||||
yyscan_t scanner = NULL;
|
||||
volatile YY_BUFFER_STATE in_buffer = NULL;
|
||||
YY_BUFFER_STATE in_buffer = NULL;
|
||||
u_int len;
|
||||
int rc;
|
||||
|
||||
|
|
@ -790,7 +817,7 @@ pcap_compile(pcap_t *p, struct bpf_program *program,
|
|||
rc = PCAP_ERROR;
|
||||
goto quit;
|
||||
}
|
||||
in_buffer = pcap__scan_string(xbuf ? xbuf : "", scanner);
|
||||
in_buffer = pcap__scan_string(buf ? buf : "", scanner);
|
||||
|
||||
/*
|
||||
* Associate the compiler state with the lexical analyzer
|
||||
|
|
@ -814,14 +841,15 @@ pcap_compile(pcap_t *p, struct bpf_program *program,
|
|||
}
|
||||
|
||||
if (cstate.ic.root == NULL) {
|
||||
cstate.ic.root = gen_retblk(&cstate, cstate.snaplen);
|
||||
|
||||
/*
|
||||
* Catch errors reported by gen_retblk().
|
||||
*/
|
||||
if (setjmp(cstate.top_ctx)) {
|
||||
if (cstate.ic.root== NULL) {
|
||||
rc = PCAP_ERROR;
|
||||
goto quit;
|
||||
}
|
||||
cstate.ic.root = gen_retblk(&cstate, cstate.snaplen);
|
||||
}
|
||||
|
||||
if (optimize && !cstate.no_optimize) {
|
||||
|
|
@ -990,9 +1018,9 @@ finish_parse(compiler_state_t *cstate, struct block *p)
|
|||
if (ppi_dlt_check != NULL)
|
||||
gen_and(ppi_dlt_check, p);
|
||||
|
||||
backpatch(p, gen_retblk(cstate, cstate->snaplen));
|
||||
backpatch(p, gen_retblk_internal(cstate, cstate->snaplen));
|
||||
p->sense = !p->sense;
|
||||
backpatch(p, gen_retblk(cstate, 0));
|
||||
backpatch(p, gen_retblk_internal(cstate, 0));
|
||||
cstate->ic.root = p->head;
|
||||
return (0);
|
||||
}
|
||||
|
|
@ -1704,6 +1732,83 @@ init_linktype(compiler_state_t *cstate, pcap_t *p)
|
|||
cstate->off_nl_nosnap = 3; /* 802.3+802.2 */
|
||||
break;
|
||||
|
||||
case DLT_EN3MB:
|
||||
/*
|
||||
* Currently, only raw "link[N:M]" filtering is supported.
|
||||
*/
|
||||
cstate->off_linktype.constant_part = OFFSET_NOT_SET; /* variable, min 15, max 71 steps of 7 */
|
||||
cstate->off_linkpl.constant_part = OFFSET_NOT_SET;
|
||||
cstate->off_nl = OFFSET_NOT_SET; /* variable, min 16, max 71 steps of 7 */
|
||||
cstate->off_nl_nosnap = OFFSET_NOT_SET; /* no 802.2 LLC */
|
||||
break;
|
||||
|
||||
case DLT_AX25:
|
||||
/*
|
||||
* Currently, only raw "link[N:M]" filtering is supported.
|
||||
*/
|
||||
cstate->off_linktype.constant_part = OFFSET_NOT_SET; /* variable, min 15, max 71 steps of 7 */
|
||||
cstate->off_linkpl.constant_part = OFFSET_NOT_SET;
|
||||
cstate->off_nl = OFFSET_NOT_SET; /* variable, min 16, max 71 steps of 7 */
|
||||
cstate->off_nl_nosnap = OFFSET_NOT_SET; /* no 802.2 LLC */
|
||||
break;
|
||||
|
||||
case DLT_PRONET:
|
||||
/*
|
||||
* Currently, only raw "link[N:M]" filtering is supported.
|
||||
*/
|
||||
cstate->off_linktype.constant_part = OFFSET_NOT_SET; /* variable, min 15, max 71 steps of 7 */
|
||||
cstate->off_linkpl.constant_part = OFFSET_NOT_SET;
|
||||
cstate->off_nl = OFFSET_NOT_SET; /* variable, min 16, max 71 steps of 7 */
|
||||
cstate->off_nl_nosnap = OFFSET_NOT_SET; /* no 802.2 LLC */
|
||||
break;
|
||||
|
||||
case DLT_CHAOS:
|
||||
/*
|
||||
* Currently, only raw "link[N:M]" filtering is supported.
|
||||
*/
|
||||
cstate->off_linktype.constant_part = OFFSET_NOT_SET; /* variable, min 15, max 71 steps of 7 */
|
||||
cstate->off_linkpl.constant_part = OFFSET_NOT_SET;
|
||||
cstate->off_nl = OFFSET_NOT_SET; /* variable, min 16, max 71 steps of 7 */
|
||||
cstate->off_nl_nosnap = OFFSET_NOT_SET; /* no 802.2 LLC */
|
||||
break;
|
||||
|
||||
#ifdef DLT_HIPPI
|
||||
case DLT_HIPPI:
|
||||
/*
|
||||
* Currently, only raw "link[N:M]" filtering is supported.
|
||||
*/
|
||||
cstate->off_linktype.constant_part = OFFSET_NOT_SET; /* variable, min 15, max 71 steps of 7 */
|
||||
cstate->off_linkpl.constant_part = OFFSET_NOT_SET;
|
||||
cstate->off_nl = OFFSET_NOT_SET; /* variable, min 16, max 71 steps of 7 */
|
||||
cstate->off_nl_nosnap = OFFSET_NOT_SET; /* no 802.2 LLC */
|
||||
break;
|
||||
|
||||
#endif
|
||||
|
||||
case DLT_REDBACK_SMARTEDGE:
|
||||
/*
|
||||
* Currently, only raw "link[N:M]" filtering is supported.
|
||||
*/
|
||||
cstate->off_linktype.constant_part = OFFSET_NOT_SET; /* variable, min 15, max 71 steps of 7 */
|
||||
cstate->off_linkpl.constant_part = OFFSET_NOT_SET;
|
||||
cstate->off_nl = OFFSET_NOT_SET; /* variable, min 16, max 71 steps of 7 */
|
||||
cstate->off_nl_nosnap = OFFSET_NOT_SET; /* no 802.2 LLC */
|
||||
break;
|
||||
|
||||
|
||||
#ifdef DLT_HHDLC
|
||||
case DLT_HHDLC:
|
||||
/*
|
||||
* Currently, only raw "link[N:M]" filtering is supported.
|
||||
*/
|
||||
cstate->off_linktype.constant_part = OFFSET_NOT_SET; /* variable, min 15, max 71 steps of 7 */
|
||||
cstate->off_linkpl.constant_part = OFFSET_NOT_SET;
|
||||
cstate->off_nl = OFFSET_NOT_SET; /* variable, min 16, max 71 steps of 7 */
|
||||
cstate->off_nl_nosnap = OFFSET_NOT_SET; /* no 802.2 LLC */
|
||||
break;
|
||||
|
||||
#endif
|
||||
|
||||
default:
|
||||
/*
|
||||
* For values in the range in which we've assigned new
|
||||
|
|
@ -1716,8 +1821,8 @@ init_linktype(compiler_state_t *cstate, pcap_t *p)
|
|||
cstate->off_nl = OFFSET_NOT_SET;
|
||||
cstate->off_nl_nosnap = OFFSET_NOT_SET;
|
||||
} else {
|
||||
bpf_set_error(cstate, "unknown data link type %d (min %d, max %d)",
|
||||
cstate->linktype, DLT_HIGH_MATCHING_MIN, DLT_HIGH_MATCHING_MAX);
|
||||
bpf_set_error(cstate, "unknown data link type %d",
|
||||
cstate->linktype);
|
||||
return (-1);
|
||||
}
|
||||
break;
|
||||
|
|
@ -6945,7 +7050,8 @@ gen_scode(compiler_state_t *cstate, const char *name, struct qual q)
|
|||
int proto = q.proto;
|
||||
int dir = q.dir;
|
||||
int tproto;
|
||||
u_char *eaddr;
|
||||
u_char *eaddrp;
|
||||
u_char eaddr[6];
|
||||
bpf_u_int32 mask, addr;
|
||||
struct addrinfo *res, *res0;
|
||||
struct sockaddr_in *sin4;
|
||||
|
|
@ -6987,33 +7093,36 @@ gen_scode(compiler_state_t *cstate, const char *name, struct qual q)
|
|||
case DLT_EN10MB:
|
||||
case DLT_NETANALYZER:
|
||||
case DLT_NETANALYZER_TRANSPARENT:
|
||||
eaddr = pcap_ether_hostton(name);
|
||||
if (eaddr == NULL)
|
||||
eaddrp = pcap_ether_hostton(name);
|
||||
if (eaddrp == NULL)
|
||||
bpf_error(cstate,
|
||||
"unknown ether host '%s'", name);
|
||||
memcpy(eaddr, eaddrp, sizeof(eaddr));
|
||||
free(eaddrp);
|
||||
tmp = gen_prevlinkhdr_check(cstate);
|
||||
b = gen_ehostop(cstate, eaddr, dir);
|
||||
if (tmp != NULL)
|
||||
gen_and(tmp, b);
|
||||
free(eaddr);
|
||||
return b;
|
||||
|
||||
case DLT_FDDI:
|
||||
eaddr = pcap_ether_hostton(name);
|
||||
if (eaddr == NULL)
|
||||
eaddrp = pcap_ether_hostton(name);
|
||||
if (eaddrp == NULL)
|
||||
bpf_error(cstate,
|
||||
"unknown FDDI host '%s'", name);
|
||||
memcpy(eaddr, eaddrp, sizeof(eaddr));
|
||||
free(eaddrp);
|
||||
b = gen_fhostop(cstate, eaddr, dir);
|
||||
free(eaddr);
|
||||
return b;
|
||||
|
||||
case DLT_IEEE802:
|
||||
eaddr = pcap_ether_hostton(name);
|
||||
if (eaddr == NULL)
|
||||
eaddrp = pcap_ether_hostton(name);
|
||||
if (eaddrp == NULL)
|
||||
bpf_error(cstate,
|
||||
"unknown token ring host '%s'", name);
|
||||
memcpy(eaddr, eaddrp, sizeof(eaddr));
|
||||
free(eaddrp);
|
||||
b = gen_thostop(cstate, eaddr, dir);
|
||||
free(eaddr);
|
||||
return b;
|
||||
|
||||
case DLT_IEEE802_11:
|
||||
|
|
@ -7021,21 +7130,23 @@ gen_scode(compiler_state_t *cstate, const char *name, struct qual q)
|
|||
case DLT_IEEE802_11_RADIO_AVS:
|
||||
case DLT_IEEE802_11_RADIO:
|
||||
case DLT_PPI:
|
||||
eaddr = pcap_ether_hostton(name);
|
||||
if (eaddr == NULL)
|
||||
eaddrp = pcap_ether_hostton(name);
|
||||
if (eaddrp == NULL)
|
||||
bpf_error(cstate,
|
||||
"unknown 802.11 host '%s'", name);
|
||||
memcpy(eaddr, eaddrp, sizeof(eaddr));
|
||||
free(eaddrp);
|
||||
b = gen_wlanhostop(cstate, eaddr, dir);
|
||||
free(eaddr);
|
||||
return b;
|
||||
|
||||
case DLT_IP_OVER_FC:
|
||||
eaddr = pcap_ether_hostton(name);
|
||||
if (eaddr == NULL)
|
||||
eaddrp = pcap_ether_hostton(name);
|
||||
if (eaddrp == NULL)
|
||||
bpf_error(cstate,
|
||||
"unknown Fibre Channel host '%s'", name);
|
||||
memcpy(eaddr, eaddrp, sizeof(eaddr));
|
||||
free(eaddrp);
|
||||
b = gen_ipfchostop(cstate, eaddr, dir);
|
||||
free(eaddr);
|
||||
return b;
|
||||
}
|
||||
|
||||
|
|
@ -7080,6 +7191,11 @@ gen_scode(compiler_state_t *cstate, const char *name, struct qual q)
|
|||
switch (res->ai_family) {
|
||||
case AF_INET:
|
||||
#ifdef INET6
|
||||
/*
|
||||
* Ignore any IPv4 addresses when resolving
|
||||
* "ip6 host NAME", validate all other proto
|
||||
* qualifiers in gen_host().
|
||||
*/
|
||||
if (tproto == Q_IPV6)
|
||||
continue;
|
||||
#endif
|
||||
|
|
@ -7091,7 +7207,13 @@ gen_scode(compiler_state_t *cstate, const char *name, struct qual q)
|
|||
break;
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
if (tproto6 == Q_IP)
|
||||
/*
|
||||
* Ignore any IPv6 addresses when resolving
|
||||
* "(arp|ip|rarp) host NAME", validate all
|
||||
* other proto qualifiers in gen_host6().
|
||||
*/
|
||||
if (tproto6 == Q_ARP || tproto6 == Q_IP ||
|
||||
tproto6 == Q_RARP)
|
||||
continue;
|
||||
|
||||
sin6 = (struct sockaddr_in6 *)
|
||||
|
|
@ -7204,9 +7326,11 @@ gen_scode(compiler_state_t *cstate, const char *name, struct qual q)
|
|||
|
||||
case Q_GATEWAY:
|
||||
#ifndef INET6
|
||||
eaddr = pcap_ether_hostton(name);
|
||||
if (eaddr == NULL)
|
||||
eaddrp = pcap_ether_hostton(name);
|
||||
if (eaddrp == NULL)
|
||||
bpf_error(cstate, "unknown ether host: %s", name);
|
||||
memcpy(eaddr, eaddrp, sizeof(eaddr));
|
||||
free(eaddrp);
|
||||
|
||||
res = pcap_nametoaddrinfo(name);
|
||||
cstate->ai = res;
|
||||
|
|
@ -7252,6 +7376,7 @@ gen_mcode(compiler_state_t *cstate, const char *s1, const char *s2,
|
|||
{
|
||||
register int nlen, mlen;
|
||||
bpf_u_int32 n, m;
|
||||
uint64_t m64;
|
||||
|
||||
/*
|
||||
* Catch errors reported by us and routines below us, and return NULL
|
||||
|
|
@ -7279,14 +7404,8 @@ gen_mcode(compiler_state_t *cstate, const char *s1, const char *s2,
|
|||
/* Convert mask len to mask */
|
||||
if (masklen > 32)
|
||||
bpf_error(cstate, "mask length must be <= 32");
|
||||
if (masklen == 0) {
|
||||
/*
|
||||
* X << 32 is not guaranteed by C to be 0; it's
|
||||
* undefined.
|
||||
*/
|
||||
m = 0;
|
||||
} else
|
||||
m = 0xffffffff << (32 - masklen);
|
||||
m64 = UINT64_C(0xffffffff) << (32 - masklen);
|
||||
m = (bpf_u_int32)m64;
|
||||
if ((n & ~m) != 0)
|
||||
bpf_error(cstate, "non-network bits set in \"%s/%d\"",
|
||||
s1, masklen);
|
||||
|
|
@ -7501,6 +7620,11 @@ gen_ecode(compiler_state_t *cstate, const char *s, struct qual q)
|
|||
return (NULL);
|
||||
|
||||
if ((q.addr == Q_HOST || q.addr == Q_DEFAULT) && q.proto == Q_LINK) {
|
||||
/*
|
||||
* Because the lexer guards the input string format, in this
|
||||
* context the function returns NULL iff the implicit malloc()
|
||||
* has failed.
|
||||
*/
|
||||
cstate->e = pcap_ether_aton(s);
|
||||
if (cstate->e == NULL)
|
||||
bpf_error(cstate, "malloc");
|
||||
|
|
@ -8212,8 +8336,6 @@ gen_byteop(compiler_state_t *cstate, int op, int idx, bpf_u_int32 val)
|
|||
return b;
|
||||
}
|
||||
|
||||
static const u_char abroadcast[] = { 0x0 };
|
||||
|
||||
struct block *
|
||||
gen_broadcast(compiler_state_t *cstate, int proto)
|
||||
{
|
||||
|
|
@ -8235,7 +8357,8 @@ gen_broadcast(compiler_state_t *cstate, int proto)
|
|||
switch (cstate->linktype) {
|
||||
case DLT_ARCNET:
|
||||
case DLT_ARCNET_LINUX:
|
||||
return gen_ahostop(cstate, abroadcast, Q_DST);
|
||||
// ARCnet broadcast is [8-bit] destination address 0.
|
||||
return gen_ahostop(cstate, 0, Q_DST);
|
||||
case DLT_EN10MB:
|
||||
case DLT_NETANALYZER:
|
||||
case DLT_NETANALYZER_TRANSPARENT:
|
||||
|
|
@ -8320,8 +8443,8 @@ gen_multicast(compiler_state_t *cstate, int proto)
|
|||
switch (cstate->linktype) {
|
||||
case DLT_ARCNET:
|
||||
case DLT_ARCNET_LINUX:
|
||||
/* all ARCnet multicasts use the same address */
|
||||
return gen_ahostop(cstate, abroadcast, Q_DST);
|
||||
// ARCnet multicast is the same as broadcast.
|
||||
return gen_ahostop(cstate, 0, Q_DST);
|
||||
case DLT_EN10MB:
|
||||
case DLT_NETANALYZER:
|
||||
case DLT_NETANALYZER_TRANSPARENT:
|
||||
|
|
@ -8470,7 +8593,12 @@ gen_multicast(compiler_state_t *cstate, int proto)
|
|||
|
||||
case Q_IP:
|
||||
b0 = gen_linktype(cstate, ETHERTYPE_IP);
|
||||
b1 = gen_cmp_ge(cstate, OR_LINKPL, 16, BPF_B, 224);
|
||||
|
||||
/*
|
||||
* Compare address with 224.0.0.0/4
|
||||
*/
|
||||
b1 = gen_mcmp(cstate, OR_LINKPL, 16, BPF_B, 0xe0, 0xf0);
|
||||
|
||||
gen_and(b0, b1);
|
||||
return b1;
|
||||
|
||||
|
|
@ -8896,11 +9024,10 @@ gen_p80211_fcdir(compiler_state_t *cstate, bpf_u_int32 fcdir)
|
|||
return (b0);
|
||||
}
|
||||
|
||||
// Process an ARCnet host address string.
|
||||
struct block *
|
||||
gen_acode(compiler_state_t *cstate, const char *s, struct qual q)
|
||||
{
|
||||
struct block *b;
|
||||
|
||||
/*
|
||||
* Catch errors reported by us and routines below us, and return NULL
|
||||
* on an error.
|
||||
|
|
@ -8914,13 +9041,16 @@ gen_acode(compiler_state_t *cstate, const char *s, struct qual q)
|
|||
case DLT_ARCNET_LINUX:
|
||||
if ((q.addr == Q_HOST || q.addr == Q_DEFAULT) &&
|
||||
q.proto == Q_LINK) {
|
||||
cstate->e = pcap_ether_aton(s);
|
||||
if (cstate->e == NULL)
|
||||
bpf_error(cstate, "malloc");
|
||||
b = gen_ahostop(cstate, cstate->e, (int)q.dir);
|
||||
free(cstate->e);
|
||||
cstate->e = NULL;
|
||||
return (b);
|
||||
uint8_t addr;
|
||||
/*
|
||||
* The lexer currently defines the address format in a
|
||||
* way that makes this error condition never true.
|
||||
* Let's check it anyway in case this part of the lexer
|
||||
* changes in future.
|
||||
*/
|
||||
if (! pcapint_atoan(s, &addr))
|
||||
bpf_error(cstate, "invalid ARCnet address '%s'", s);
|
||||
return gen_ahostop(cstate, addr, (int)q.dir);
|
||||
} else
|
||||
bpf_error(cstate, "ARCnet address used in non-arc expression");
|
||||
/*NOTREACHED*/
|
||||
|
|
@ -8931,18 +9061,25 @@ gen_acode(compiler_state_t *cstate, const char *s, struct qual q)
|
|||
}
|
||||
}
|
||||
|
||||
// Compare an ARCnet host address with the given value.
|
||||
static struct block *
|
||||
gen_ahostop(compiler_state_t *cstate, const u_char *eaddr, int dir)
|
||||
gen_ahostop(compiler_state_t *cstate, const uint8_t eaddr, int dir)
|
||||
{
|
||||
register struct block *b0, *b1;
|
||||
|
||||
switch (dir) {
|
||||
/* src comes first, different from Ethernet */
|
||||
/*
|
||||
* ARCnet is different from Ethernet: the source address comes before
|
||||
* the destination address, each is one byte long. This holds for all
|
||||
* three "buffer formats" in RFC 1201 Section 2.1, see also page 4-10
|
||||
* in the 1983 edition of the "ARCNET Designer's Handbook" published
|
||||
* by Datapoint (document number 61610-01).
|
||||
*/
|
||||
case Q_SRC:
|
||||
return gen_bcmp(cstate, OR_LINKHDR, 0, 1, eaddr);
|
||||
return gen_cmp(cstate, OR_LINKHDR, 0, BPF_B, eaddr);
|
||||
|
||||
case Q_DST:
|
||||
return gen_bcmp(cstate, OR_LINKHDR, 1, 1, eaddr);
|
||||
return gen_cmp(cstate, OR_LINKHDR, 1, BPF_B, eaddr);
|
||||
|
||||
case Q_AND:
|
||||
b0 = gen_ahostop(cstate, eaddr, Q_SRC);
|
||||
|
|
@ -9090,7 +9227,7 @@ gen_vlan_patch_vid_test(compiler_state_t *cstate, struct block *b_vid)
|
|||
unsigned cnt;
|
||||
|
||||
s = new_stmt(cstate, BPF_LD|BPF_B|BPF_ABS);
|
||||
s->s.k = SKF_AD_OFF + SKF_AD_VLAN_TAG_PRESENT;
|
||||
s->s.k = (bpf_u_int32)(SKF_AD_OFF + SKF_AD_VLAN_TAG_PRESENT);
|
||||
|
||||
/* true -> next instructions, false -> beginning of b_vid */
|
||||
sjeq = new_stmt(cstate, JMP(BPF_JEQ));
|
||||
|
|
@ -9098,8 +9235,8 @@ gen_vlan_patch_vid_test(compiler_state_t *cstate, struct block *b_vid)
|
|||
sjeq->s.jf = b_vid->stmts;
|
||||
sappend(s, sjeq);
|
||||
|
||||
s2 = new_stmt(cstate, BPF_LD|BPF_B|BPF_ABS);
|
||||
s2->s.k = SKF_AD_OFF + SKF_AD_VLAN_TAG;
|
||||
s2 = new_stmt(cstate, BPF_LD|BPF_H|BPF_ABS);
|
||||
s2->s.k = (bpf_u_int32)(SKF_AD_OFF + SKF_AD_VLAN_TAG);
|
||||
sappend(s, s2);
|
||||
sjeq->s.jt = s2;
|
||||
|
||||
|
|
@ -9137,7 +9274,7 @@ gen_vlan_bpf_extensions(compiler_state_t *cstate, bpf_u_int32 vlan_num,
|
|||
/* generate new filter code based on extracting packet
|
||||
* metadata */
|
||||
s = new_stmt(cstate, BPF_LD|BPF_B|BPF_ABS);
|
||||
s->s.k = SKF_AD_OFF + SKF_AD_VLAN_TAG_PRESENT;
|
||||
s->s.k = (bpf_u_int32)(SKF_AD_OFF + SKF_AD_VLAN_TAG_PRESENT);
|
||||
|
||||
b0 = new_block(cstate, JMP(BPF_JEQ));
|
||||
b0->stmts = s;
|
||||
|
|
@ -9272,20 +9409,12 @@ gen_vlan(compiler_state_t *cstate, bpf_u_int32 vlan_num, int has_vlan_tag)
|
|||
* label_num might be clobbered by longjmp - yeah, it might, but *WHO CARES*?
|
||||
* It's not *used* after setjmp returns.
|
||||
*/
|
||||
struct block *
|
||||
gen_mpls(compiler_state_t *cstate, bpf_u_int32 label_num_arg,
|
||||
static struct block *
|
||||
gen_mpls_internal(compiler_state_t *cstate, bpf_u_int32 label_num,
|
||||
int has_label_num)
|
||||
{
|
||||
volatile bpf_u_int32 label_num = label_num_arg;
|
||||
struct block *b0, *b1;
|
||||
|
||||
/*
|
||||
* Catch errors reported by us and routines below us, and return NULL
|
||||
* on an error.
|
||||
*/
|
||||
if (setjmp(cstate->top_ctx))
|
||||
return (NULL);
|
||||
|
||||
if (cstate->label_stack_depth > 0) {
|
||||
/* just match the bottom-of-stack bit clear */
|
||||
b0 = gen_mcmp(cstate, OR_PREVMPLSHDR, 2, BPF_B, 0, 0x01);
|
||||
|
|
@ -9352,6 +9481,19 @@ gen_mpls(compiler_state_t *cstate, bpf_u_int32 label_num_arg,
|
|||
return (b0);
|
||||
}
|
||||
|
||||
struct block *
|
||||
gen_mpls(compiler_state_t *cstate, bpf_u_int32 label_num, int has_label_num)
|
||||
{
|
||||
/*
|
||||
* Catch errors reported by us and routines below us, and return NULL
|
||||
* on an error.
|
||||
*/
|
||||
if (setjmp(cstate->top_ctx))
|
||||
return (NULL);
|
||||
|
||||
return gen_mpls_internal(cstate, label_num, has_label_num);
|
||||
}
|
||||
|
||||
/*
|
||||
* Support PPPOE discovery and session.
|
||||
*/
|
||||
|
|
@ -10024,16 +10166,10 @@ gen_mtp2type_abbrev(compiler_state_t *cstate, int type)
|
|||
return b0;
|
||||
}
|
||||
|
||||
/*
|
||||
* The jvalue_arg dance is to avoid annoying whining by compilers that
|
||||
* jvalue might be clobbered by longjmp - yeah, it might, but *WHO CARES*?
|
||||
* It's not *used* after setjmp returns.
|
||||
*/
|
||||
struct block *
|
||||
gen_mtp3field_code(compiler_state_t *cstate, int mtp3field,
|
||||
bpf_u_int32 jvalue_arg, int jtype, int reverse)
|
||||
static struct block *
|
||||
gen_mtp3field_code_internal(compiler_state_t *cstate, int mtp3field,
|
||||
bpf_u_int32 jvalue, int jtype, int reverse)
|
||||
{
|
||||
volatile bpf_u_int32 jvalue = jvalue_arg;
|
||||
struct block *b0;
|
||||
bpf_u_int32 val1 , val2 , val3;
|
||||
u_int newoff_sio;
|
||||
|
|
@ -10041,13 +10177,6 @@ gen_mtp3field_code(compiler_state_t *cstate, int mtp3field,
|
|||
u_int newoff_dpc;
|
||||
u_int newoff_sls;
|
||||
|
||||
/*
|
||||
* Catch errors reported by us and routines below us, and return NULL
|
||||
* on an error.
|
||||
*/
|
||||
if (setjmp(cstate->top_ctx))
|
||||
return (NULL);
|
||||
|
||||
newoff_sio = cstate->off_sio;
|
||||
newoff_opc = cstate->off_opc;
|
||||
newoff_dpc = cstate->off_dpc;
|
||||
|
|
@ -10139,6 +10268,21 @@ gen_mtp3field_code(compiler_state_t *cstate, int mtp3field,
|
|||
return b0;
|
||||
}
|
||||
|
||||
struct block *
|
||||
gen_mtp3field_code(compiler_state_t *cstate, int mtp3field,
|
||||
bpf_u_int32 jvalue, int jtype, int reverse)
|
||||
{
|
||||
/*
|
||||
* Catch errors reported by us and routines below us, and return NULL
|
||||
* on an error.
|
||||
*/
|
||||
if (setjmp(cstate->top_ctx))
|
||||
return (NULL);
|
||||
|
||||
return gen_mtp3field_code_internal(cstate, mtp3field, jvalue, jtype,
|
||||
reverse);
|
||||
}
|
||||
|
||||
static struct block *
|
||||
gen_msg_abbrev(compiler_state_t *cstate, int type)
|
||||
{
|
||||
|
|
|
|||
13
grammar.y.in
13
grammar.y.in
|
|
@ -78,19 +78,6 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#if __STDC__
|
||||
struct mbuf;
|
||||
struct rtentry;
|
||||
#endif
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "diag-control.h"
|
||||
|
|
|
|||
|
|
@ -41,13 +41,13 @@
|
|||
#define IEEE80211_FC0_VERSION_MASK 0x03
|
||||
#define IEEE80211_FC0_VERSION_SHIFT 0
|
||||
#define IEEE80211_FC0_VERSION_0 0x00
|
||||
#define IEEE80211_FC0_TYPE_MASK 0x0c
|
||||
#define IEEE80211_FC0_TYPE_MASK 0x0cU
|
||||
#define IEEE80211_FC0_TYPE_SHIFT 2
|
||||
#define IEEE80211_FC0_TYPE_MGT 0x00
|
||||
#define IEEE80211_FC0_TYPE_CTL 0x04
|
||||
#define IEEE80211_FC0_TYPE_DATA 0x08
|
||||
|
||||
#define IEEE80211_FC0_SUBTYPE_MASK 0xf0
|
||||
#define IEEE80211_FC0_SUBTYPE_MASK 0xf0U
|
||||
#define IEEE80211_FC0_SUBTYPE_SHIFT 4
|
||||
/* for TYPE_MGT */
|
||||
#define IEEE80211_FC0_SUBTYPE_ASSOC_REQ 0x00
|
||||
|
|
@ -80,7 +80,7 @@
|
|||
#define IEEE80211_FC0_SUBTYPE_QOS 0x80
|
||||
#define IEEE80211_FC0_SUBTYPE_QOS_NULL 0xc0
|
||||
|
||||
#define IEEE80211_FC1_DIR_MASK 0x03
|
||||
#define IEEE80211_FC1_DIR_MASK 0x03U
|
||||
#define IEEE80211_FC1_DIR_NODS 0x00 /* STA->STA */
|
||||
#define IEEE80211_FC1_DIR_TODS 0x01 /* STA->AP */
|
||||
#define IEEE80211_FC1_DIR_FROMDS 0x02 /* AP ->STA */
|
||||
|
|
|
|||
250
instrument-functions.c
Normal file
250
instrument-functions.c
Normal file
|
|
@ -0,0 +1,250 @@
|
|||
/*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that: (1) source code
|
||||
* distributions retain the above copyright notice and this paragraph
|
||||
* in its entirety, and (2) distributions including binary code include
|
||||
* the above copyright notice and this paragraph in its entirety in
|
||||
* the documentation or other materials provided with the distribution.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND
|
||||
* WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
|
||||
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <bfd.h>
|
||||
|
||||
/*
|
||||
* Generate instrumentation calls for entry and exit to functions.
|
||||
* Just after function entry and just before function exit, the
|
||||
* following profiling functions are called with the address of the
|
||||
* current function and its call site (currently not use).
|
||||
*
|
||||
* The attribute 'no_instrument_function' causes this instrumentation is
|
||||
* not done.
|
||||
*
|
||||
* These profiling functions call print_debug(). This function prints the
|
||||
* current function name with indentation and call level.
|
||||
* If entering in a function it prints also the calling function name with
|
||||
* file name and line number.
|
||||
*
|
||||
* If the environment variable INSTRUMENT is
|
||||
* unset or set to an empty string, print nothing, like with no instrumentation
|
||||
* set to "all" or "a", print all the functions names
|
||||
* set to "global" or "g", print only the global functions names
|
||||
*/
|
||||
|
||||
#define ND_NO_INSTRUMENT __attribute__((no_instrument_function))
|
||||
|
||||
/* Store the function call level, used also in pretty_print_packet() */
|
||||
extern int profile_func_level;
|
||||
int profile_func_level = -1;
|
||||
|
||||
typedef enum {
|
||||
ENTER,
|
||||
EXIT
|
||||
} action_type;
|
||||
|
||||
void __cyg_profile_func_enter(void *this_fn, void *call_site) ND_NO_INSTRUMENT;
|
||||
|
||||
void __cyg_profile_func_exit(void *this_fn, void *call_site) ND_NO_INSTRUMENT;
|
||||
|
||||
static void print_debug(void *this_fn, void *call_site, action_type action)
|
||||
ND_NO_INSTRUMENT;
|
||||
|
||||
void
|
||||
__cyg_profile_func_enter(void *this_fn, void *call_site)
|
||||
{
|
||||
print_debug(this_fn, call_site, ENTER);
|
||||
}
|
||||
|
||||
void
|
||||
__cyg_profile_func_exit(void *this_fn, void *call_site)
|
||||
{
|
||||
print_debug(this_fn, call_site, EXIT);
|
||||
}
|
||||
|
||||
static void print_debug(void *this_fn, void *call_site, action_type action)
|
||||
{
|
||||
static bfd* abfd;
|
||||
static asymbol **symtab;
|
||||
static long symcount;
|
||||
static asection *text;
|
||||
static bfd_vma vma;
|
||||
static int instrument_set;
|
||||
static int instrument_off;
|
||||
static int instrument_global;
|
||||
|
||||
if (!instrument_set) {
|
||||
static char *instrument_type;
|
||||
|
||||
/* Get the configuration environment variable INSTRUMENT value if any */
|
||||
instrument_type = getenv("INSTRUMENT");
|
||||
/* unset or set to an empty string ? */
|
||||
if (instrument_type == NULL ||
|
||||
!strncmp(instrument_type, "", sizeof(""))) {
|
||||
instrument_off = 1;
|
||||
} else {
|
||||
/* set to "global" or "g" ? */
|
||||
if (!strncmp(instrument_type, "global", sizeof("global")) ||
|
||||
!strncmp(instrument_type, "g", sizeof("g")))
|
||||
instrument_global = 1;
|
||||
else if (strncmp(instrument_type, "all", sizeof("all")) &&
|
||||
strncmp(instrument_type, "a", sizeof("a"))) {
|
||||
fprintf(stderr, "INSTRUMENT can be only \"\", \"all\", \"a\", "
|
||||
"\"global\" or \"g\".\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
instrument_set = 1;
|
||||
}
|
||||
|
||||
if (instrument_off)
|
||||
return;
|
||||
|
||||
/* If no errors, this block should be executed one time */
|
||||
if (!abfd) {
|
||||
char pgm_name[1024];
|
||||
long symsize;
|
||||
|
||||
ssize_t ret = readlink("/proc/self/exe", pgm_name, sizeof(pgm_name));
|
||||
if (ret == -1) {
|
||||
perror("failed to find executable");
|
||||
return;
|
||||
}
|
||||
if (ret == sizeof(pgm_name)) {
|
||||
/* no space for the '\0' */
|
||||
printf("truncation may have occurred\n");
|
||||
return;
|
||||
}
|
||||
pgm_name[ret] = '\0';
|
||||
|
||||
bfd_init();
|
||||
|
||||
abfd = bfd_openr(pgm_name, NULL);
|
||||
if (!abfd) {
|
||||
bfd_perror("bfd_openr");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!bfd_check_format(abfd, bfd_object)) {
|
||||
bfd_perror("bfd_check_format");
|
||||
return;
|
||||
}
|
||||
|
||||
if((symsize = bfd_get_symtab_upper_bound(abfd)) == -1) {
|
||||
bfd_perror("bfd_get_symtab_upper_bound");
|
||||
return;
|
||||
}
|
||||
|
||||
symtab = (asymbol **)malloc((size_t)symsize);
|
||||
symcount = bfd_canonicalize_symtab(abfd, symtab);
|
||||
if (symcount < 0) {
|
||||
free(symtab);
|
||||
bfd_perror("bfd_canonicalize_symtab");
|
||||
return;
|
||||
}
|
||||
|
||||
if ((text = bfd_get_section_by_name(abfd, ".text")) == NULL) {
|
||||
bfd_perror("bfd_get_section_by_name");
|
||||
return;
|
||||
}
|
||||
vma = text->vma;
|
||||
}
|
||||
|
||||
if (instrument_global) {
|
||||
symbol_info syminfo;
|
||||
int found;
|
||||
long i;
|
||||
|
||||
i = 0;
|
||||
found = 0;
|
||||
while (i < symcount && !found) {
|
||||
bfd_get_symbol_info(abfd, symtab[i], &syminfo);
|
||||
if ((void *)syminfo.value == this_fn) {
|
||||
found = 1;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
/* type == 'T' for a global function */
|
||||
if (found == 1 && syminfo.type != 'T')
|
||||
return;
|
||||
}
|
||||
|
||||
/* Current function */
|
||||
if ((bfd_vma)this_fn < vma) {
|
||||
printf("[ERROR address this_fn]");
|
||||
} else {
|
||||
const char *file;
|
||||
const char *func;
|
||||
unsigned int line;
|
||||
|
||||
if (!bfd_find_nearest_line(abfd, text, symtab, (bfd_vma)this_fn - vma,
|
||||
&file, &func, &line)) {
|
||||
printf("[ERROR bfd_find_nearest_line this_fn]");
|
||||
} else {
|
||||
int i;
|
||||
|
||||
if (action == ENTER)
|
||||
profile_func_level += 1;
|
||||
/* Indentation */
|
||||
for (i = 0 ; i < profile_func_level ; i++)
|
||||
putchar(' ');
|
||||
if (action == ENTER)
|
||||
printf("[>> ");
|
||||
else
|
||||
printf("[<< ");
|
||||
/* Function name */
|
||||
if (func == NULL || *func == '\0')
|
||||
printf("???");
|
||||
else
|
||||
printf("%s", func);
|
||||
printf(" (%d)", profile_func_level);
|
||||
/* Print the "from" part except for the main function) */
|
||||
if (action == ENTER && func != NULL &&
|
||||
strncmp(func, "main", sizeof("main"))) {
|
||||
/* Calling function */
|
||||
if ((bfd_vma)call_site < vma) {
|
||||
printf("[ERROR address call_site]");
|
||||
} else {
|
||||
if (!bfd_find_nearest_line(abfd, text, symtab,
|
||||
(bfd_vma)call_site - vma, &file,
|
||||
&func, &line)) {
|
||||
printf("[ERROR bfd_find_nearest_line call_site]");
|
||||
} else {
|
||||
printf(" from ");
|
||||
/* Function name */
|
||||
if (func == NULL || *func == '\0')
|
||||
printf("???");
|
||||
else
|
||||
printf("%s", func);
|
||||
/* File name */
|
||||
if (file == NULL || *file == '\0')
|
||||
printf(" ??:");
|
||||
else {
|
||||
char *slashp = strrchr(file, '/');
|
||||
if (slashp != NULL)
|
||||
file = slashp + 1;
|
||||
printf(" %s:", file);
|
||||
}
|
||||
/* Line number */
|
||||
if (line == 0)
|
||||
printf("?");
|
||||
else
|
||||
printf("%u", line);
|
||||
printf("]");
|
||||
}
|
||||
}
|
||||
}
|
||||
putchar('\n');
|
||||
if (action == EXIT)
|
||||
profile_func_level -= 1;
|
||||
}
|
||||
}
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
/* vi: set tabstop=4 softtabstop=0 shiftwidth=4 smarttab autoindent : */
|
||||
454
nametoaddr.c
454
nametoaddr.c
|
|
@ -32,31 +32,6 @@
|
|||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
|
||||
#ifdef INET6
|
||||
/*
|
||||
* To quote the MSDN page for getaddrinfo() at
|
||||
*
|
||||
* https://msdn.microsoft.com/en-us/library/windows/desktop/ms738520(v=vs.85).aspx
|
||||
*
|
||||
* "Support for getaddrinfo on Windows 2000 and older versions
|
||||
* The getaddrinfo function was added to the Ws2_32.dll on Windows XP and
|
||||
* later. To execute an application that uses this function on earlier
|
||||
* versions of Windows, then you need to include the Ws2tcpip.h and
|
||||
* Wspiapi.h files. When the Wspiapi.h include file is added, the
|
||||
* getaddrinfo function is defined to the WspiapiGetAddrInfo inline
|
||||
* function in the Wspiapi.h file. At runtime, the WspiapiGetAddrInfo
|
||||
* function is implemented in such a way that if the Ws2_32.dll or the
|
||||
* Wship6.dll (the file containing getaddrinfo in the IPv6 Technology
|
||||
* Preview for Windows 2000) does not include getaddrinfo, then a
|
||||
* version of getaddrinfo is implemented inline based on code in the
|
||||
* Wspiapi.h header file. This inline code will be used on older Windows
|
||||
* platforms that do not natively support the getaddrinfo function."
|
||||
*
|
||||
* We use getaddrinfo(), so we include Wspiapi.h here.
|
||||
*/
|
||||
#include <wspiapi.h>
|
||||
#endif /* INET6 */
|
||||
#else /* _WIN32 */
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
|
|
@ -639,7 +614,7 @@ pcap_nametollc(const char *s)
|
|||
|
||||
/* Hex digit to 8-bit unsigned integer. */
|
||||
static inline u_char
|
||||
xdtoi(u_char c)
|
||||
pcapint_xdtoi(u_char c)
|
||||
{
|
||||
if (c >= '0' && c <= '9')
|
||||
return (u_char)(c - '0');
|
||||
|
|
@ -697,38 +672,417 @@ __pcap_atodn(const char *s, bpf_u_int32 *addr)
|
|||
}
|
||||
|
||||
/*
|
||||
* Convert 's', which can have the one of the forms:
|
||||
* libpcap ARCnet address format is "^\$[0-9a-fA-F]{1,2}$" in regexp syntax.
|
||||
* Iff the given string is a well-formed ARCnet address, parse the string,
|
||||
* store the 8-bit unsigned value into the provided integer and return 1.
|
||||
* Otherwise return 0.
|
||||
*
|
||||
* "xx:xx:xx:xx:xx:xx"
|
||||
* "xx.xx.xx.xx.xx.xx"
|
||||
* "xx-xx-xx-xx-xx-xx"
|
||||
* "xxxx.xxxx.xxxx"
|
||||
* "xxxxxxxxxxxx"
|
||||
* --> START -- $ --> DOLLAR -- [0-9a-fA-F] --> HEX1 -- \0 -->-+
|
||||
* | | | |
|
||||
* [.] [.] [0-9a-fA-F] |
|
||||
* | | | |
|
||||
* v v v v
|
||||
* (invalid) <--------+-<---------------[.]-- HEX2 -- \0 -->-+--> (valid)
|
||||
*/
|
||||
int
|
||||
pcapint_atoan(const char *s, uint8_t *addr)
|
||||
{
|
||||
enum {
|
||||
START,
|
||||
DOLLAR,
|
||||
HEX1,
|
||||
HEX2,
|
||||
} fsm_state = START;
|
||||
uint8_t tmp = 0;
|
||||
|
||||
while (*s) {
|
||||
switch (fsm_state) {
|
||||
case START:
|
||||
if (*s != '$')
|
||||
goto invalid;
|
||||
fsm_state = DOLLAR;
|
||||
break;
|
||||
case DOLLAR:
|
||||
if (! PCAP_ISXDIGIT(*s))
|
||||
goto invalid;
|
||||
tmp = pcapint_xdtoi(*s);
|
||||
fsm_state = HEX1;
|
||||
break;
|
||||
case HEX1:
|
||||
if (! PCAP_ISXDIGIT(*s))
|
||||
goto invalid;
|
||||
tmp <<= 4;
|
||||
tmp |= pcapint_xdtoi(*s);
|
||||
fsm_state = HEX2;
|
||||
break;
|
||||
case HEX2:
|
||||
goto invalid;
|
||||
} // switch
|
||||
s++;
|
||||
} // while
|
||||
if (fsm_state == HEX1 || fsm_state == HEX2) {
|
||||
*addr = tmp;
|
||||
return 1;
|
||||
}
|
||||
|
||||
invalid:
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Man page: "xxxxxxxxxxxx", regexp: "^[0-9a-fA-F]{12}$".
|
||||
static u_char
|
||||
pcapint_atomac48_xxxxxxxxxxxx(const char *s, uint8_t *addr)
|
||||
{
|
||||
if (strlen(s) == 12 &&
|
||||
PCAP_ISXDIGIT(s[0]) &&
|
||||
PCAP_ISXDIGIT(s[1]) &&
|
||||
PCAP_ISXDIGIT(s[2]) &&
|
||||
PCAP_ISXDIGIT(s[3]) &&
|
||||
PCAP_ISXDIGIT(s[4]) &&
|
||||
PCAP_ISXDIGIT(s[5]) &&
|
||||
PCAP_ISXDIGIT(s[6]) &&
|
||||
PCAP_ISXDIGIT(s[7]) &&
|
||||
PCAP_ISXDIGIT(s[8]) &&
|
||||
PCAP_ISXDIGIT(s[9]) &&
|
||||
PCAP_ISXDIGIT(s[10]) &&
|
||||
PCAP_ISXDIGIT(s[11])) {
|
||||
addr[0] = pcapint_xdtoi(s[0]) << 4 | pcapint_xdtoi(s[1]);
|
||||
addr[1] = pcapint_xdtoi(s[2]) << 4 | pcapint_xdtoi(s[3]);
|
||||
addr[2] = pcapint_xdtoi(s[4]) << 4 | pcapint_xdtoi(s[5]);
|
||||
addr[3] = pcapint_xdtoi(s[6]) << 4 | pcapint_xdtoi(s[7]);
|
||||
addr[4] = pcapint_xdtoi(s[8]) << 4 | pcapint_xdtoi(s[9]);
|
||||
addr[5] = pcapint_xdtoi(s[10]) << 4 | pcapint_xdtoi(s[11]);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Man page: "xxxx.xxxx.xxxx", regexp: "^[0-9a-fA-F]{4}(\.[0-9a-fA-F]{4}){2}$".
|
||||
static u_char
|
||||
pcapint_atomac48_xxxx_3_times(const char *s, uint8_t *addr)
|
||||
{
|
||||
const char sep = '.';
|
||||
if (strlen(s) == 14 &&
|
||||
PCAP_ISXDIGIT(s[0]) &&
|
||||
PCAP_ISXDIGIT(s[1]) &&
|
||||
PCAP_ISXDIGIT(s[2]) &&
|
||||
PCAP_ISXDIGIT(s[3]) &&
|
||||
s[4] == sep &&
|
||||
PCAP_ISXDIGIT(s[5]) &&
|
||||
PCAP_ISXDIGIT(s[6]) &&
|
||||
PCAP_ISXDIGIT(s[7]) &&
|
||||
PCAP_ISXDIGIT(s[8]) &&
|
||||
s[9] == sep &&
|
||||
PCAP_ISXDIGIT(s[10]) &&
|
||||
PCAP_ISXDIGIT(s[11]) &&
|
||||
PCAP_ISXDIGIT(s[12]) &&
|
||||
PCAP_ISXDIGIT(s[13])) {
|
||||
addr[0] = pcapint_xdtoi(s[0]) << 4 | pcapint_xdtoi(s[1]);
|
||||
addr[1] = pcapint_xdtoi(s[2]) << 4 | pcapint_xdtoi(s[3]);
|
||||
addr[2] = pcapint_xdtoi(s[5]) << 4 | pcapint_xdtoi(s[6]);
|
||||
addr[3] = pcapint_xdtoi(s[7]) << 4 | pcapint_xdtoi(s[8]);
|
||||
addr[4] = pcapint_xdtoi(s[10]) << 4 | pcapint_xdtoi(s[11]);
|
||||
addr[5] = pcapint_xdtoi(s[12]) << 4 | pcapint_xdtoi(s[13]);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Man page: "xx:xx:xx:xx:xx:xx", regexp: "^[0-9a-fA-F]{1,2}(:[0-9a-fA-F]{1,2}){5}$".
|
||||
* Man page: "xx-xx-xx-xx-xx-xx", regexp: "^[0-9a-fA-F]{1,2}(-[0-9a-fA-F]{1,2}){5}$".
|
||||
* Man page: "xx.xx.xx.xx.xx.xx", regexp: "^[0-9a-fA-F]{1,2}(\.[0-9a-fA-F]{1,2}){5}$".
|
||||
* (Any "xx" above can be "x", which is equivalent to "0x".)
|
||||
*
|
||||
* (or various mixes of ':', '.', and '-') into a new
|
||||
* ethernet address. Assumes 's' is well formed.
|
||||
* An equivalent (and parametrisable for EUI-64) FSM could be implemented using
|
||||
* a smaller graph, but that graph would be neither acyclic nor planar nor
|
||||
* trivial to verify.
|
||||
*
|
||||
* |
|
||||
* [.] v
|
||||
* +<---------- START
|
||||
* | |
|
||||
* | | [0-9a-fA-F]
|
||||
* | [.] v
|
||||
* +<--------- BYTE0_X ----------+
|
||||
* | | |
|
||||
* | | [0-9a-fA-F] |
|
||||
* | [.] v |
|
||||
* +<--------- BYTE0_XX | [:\.-]
|
||||
* | | |
|
||||
* | | [:\.-] |
|
||||
* | [.] v |
|
||||
* +<----- BYTE0_SEP_BYTE1 <-----+
|
||||
* | |
|
||||
* | | [0-9a-fA-F]
|
||||
* | [.] v
|
||||
* +<--------- BYTE1_X ----------+
|
||||
* | | |
|
||||
* | | [0-9a-fA-F] |
|
||||
* | [.] v |
|
||||
* +<--------- BYTE1_XX | <sep>
|
||||
* | | |
|
||||
* | | <sep> |
|
||||
* | [.] v |
|
||||
* +<----- BYTE1_SEP_BYTE2 <-----+
|
||||
* | |
|
||||
* | | [0-9a-fA-F]
|
||||
* | [.] v
|
||||
* +<--------- BYTE2_X ----------+
|
||||
* | | |
|
||||
* | | [0-9a-fA-F] |
|
||||
* | [.] v |
|
||||
* +<--------- BYTE2_XX | <sep>
|
||||
* | | |
|
||||
* | | <sep> |
|
||||
* | [.] v |
|
||||
* +<----- BYTE2_SEP_BYTE3 <-----+
|
||||
* | |
|
||||
* | | [0-9a-fA-F]
|
||||
* | [.] v
|
||||
* +<--------- BYTE3_X ----------+
|
||||
* | | |
|
||||
* | | [0-9a-fA-F] |
|
||||
* | [.] v |
|
||||
* +<--------- BYTE3_XX | <sep>
|
||||
* | | |
|
||||
* | | <sep> |
|
||||
* | [.] v |
|
||||
* +<----- BYTE3_SEP_BYTE4 <-----+
|
||||
* | |
|
||||
* | | [0-9a-fA-F]
|
||||
* | [.] v
|
||||
* +<--------- BYTE4_X ----------+
|
||||
* | | |
|
||||
* | | [0-9a-fA-F] |
|
||||
* | [.] v |
|
||||
* +<--------- BYTE4_XX | <sep>
|
||||
* | | |
|
||||
* | | <sep> |
|
||||
* | [.] v |
|
||||
* +<----- BYTE4_SEP_BYTE5 <-----+
|
||||
* | |
|
||||
* | | [0-9a-fA-F]
|
||||
* | [.] v
|
||||
* +<--------- BYTE5_X ----------+
|
||||
* | | |
|
||||
* | | [0-9a-fA-F] |
|
||||
* | [.] v |
|
||||
* +<--------- BYTE5_XX | \0
|
||||
* | | |
|
||||
* | | \0 |
|
||||
* | | v
|
||||
* +--> (reject) +---------> (accept)
|
||||
*
|
||||
*/
|
||||
static u_char
|
||||
pcapint_atomac48_x_xx_6_times(const char *s, uint8_t *addr)
|
||||
{
|
||||
enum {
|
||||
START,
|
||||
BYTE0_X,
|
||||
BYTE0_XX,
|
||||
BYTE0_SEP_BYTE1,
|
||||
BYTE1_X,
|
||||
BYTE1_XX,
|
||||
BYTE1_SEP_BYTE2,
|
||||
BYTE2_X,
|
||||
BYTE2_XX,
|
||||
BYTE2_SEP_BYTE3,
|
||||
BYTE3_X,
|
||||
BYTE3_XX,
|
||||
BYTE3_SEP_BYTE4,
|
||||
BYTE4_X,
|
||||
BYTE4_XX,
|
||||
BYTE4_SEP_BYTE5,
|
||||
BYTE5_X,
|
||||
BYTE5_XX,
|
||||
} fsm_state = START;
|
||||
uint8_t buf[6];
|
||||
const char *seplist = ":.-";
|
||||
char sep;
|
||||
|
||||
while (*s) {
|
||||
switch (fsm_state) {
|
||||
case START:
|
||||
if (PCAP_ISXDIGIT(*s)) {
|
||||
buf[0] = pcapint_xdtoi(*s);
|
||||
fsm_state = BYTE0_X;
|
||||
break;
|
||||
}
|
||||
goto reject;
|
||||
case BYTE0_X:
|
||||
if (strchr(seplist, *s)) {
|
||||
sep = *s;
|
||||
fsm_state = BYTE0_SEP_BYTE1;
|
||||
break;
|
||||
}
|
||||
if (PCAP_ISXDIGIT(*s)) {
|
||||
buf[0] = buf[0] << 4 | pcapint_xdtoi(*s);
|
||||
fsm_state = BYTE0_XX;
|
||||
break;
|
||||
}
|
||||
goto reject;
|
||||
case BYTE0_XX:
|
||||
if (strchr(seplist, *s)) {
|
||||
sep = *s;
|
||||
fsm_state = BYTE0_SEP_BYTE1;
|
||||
break;
|
||||
}
|
||||
goto reject;
|
||||
case BYTE0_SEP_BYTE1:
|
||||
if (PCAP_ISXDIGIT(*s)) {
|
||||
buf[1] = pcapint_xdtoi(*s);
|
||||
fsm_state = BYTE1_X;
|
||||
break;
|
||||
}
|
||||
goto reject;
|
||||
case BYTE1_X:
|
||||
if (*s == sep) {
|
||||
fsm_state = BYTE1_SEP_BYTE2;
|
||||
break;
|
||||
}
|
||||
if (PCAP_ISXDIGIT(*s)) {
|
||||
buf[1] = buf[1] << 4 | pcapint_xdtoi(*s);
|
||||
fsm_state = BYTE1_XX;
|
||||
break;
|
||||
}
|
||||
goto reject;
|
||||
case BYTE1_XX:
|
||||
if (*s == sep) {
|
||||
fsm_state = BYTE1_SEP_BYTE2;
|
||||
break;
|
||||
}
|
||||
goto reject;
|
||||
case BYTE1_SEP_BYTE2:
|
||||
if (PCAP_ISXDIGIT(*s)) {
|
||||
buf[2] = pcapint_xdtoi(*s);
|
||||
fsm_state = BYTE2_X;
|
||||
break;
|
||||
}
|
||||
goto reject;
|
||||
case BYTE2_X:
|
||||
if (*s == sep) {
|
||||
fsm_state = BYTE2_SEP_BYTE3;
|
||||
break;
|
||||
}
|
||||
if (PCAP_ISXDIGIT(*s)) {
|
||||
buf[2] = buf[2] << 4 | pcapint_xdtoi(*s);
|
||||
fsm_state = BYTE2_XX;
|
||||
break;
|
||||
}
|
||||
goto reject;
|
||||
case BYTE2_XX:
|
||||
if (*s == sep) {
|
||||
fsm_state = BYTE2_SEP_BYTE3;
|
||||
break;
|
||||
}
|
||||
goto reject;
|
||||
case BYTE2_SEP_BYTE3:
|
||||
if (PCAP_ISXDIGIT(*s)) {
|
||||
buf[3] = pcapint_xdtoi(*s);
|
||||
fsm_state = BYTE3_X;
|
||||
break;
|
||||
}
|
||||
goto reject;
|
||||
case BYTE3_X:
|
||||
if (*s == sep) {
|
||||
fsm_state = BYTE3_SEP_BYTE4;
|
||||
break;
|
||||
}
|
||||
if (PCAP_ISXDIGIT(*s)) {
|
||||
buf[3] = buf[3] << 4 | pcapint_xdtoi(*s);
|
||||
fsm_state = BYTE3_XX;
|
||||
break;
|
||||
}
|
||||
goto reject;
|
||||
case BYTE3_XX:
|
||||
if (*s == sep) {
|
||||
fsm_state = BYTE3_SEP_BYTE4;
|
||||
break;
|
||||
}
|
||||
goto reject;
|
||||
case BYTE3_SEP_BYTE4:
|
||||
if (PCAP_ISXDIGIT(*s)) {
|
||||
buf[4] = pcapint_xdtoi(*s);
|
||||
fsm_state = BYTE4_X;
|
||||
break;
|
||||
}
|
||||
goto reject;
|
||||
case BYTE4_X:
|
||||
if (*s == sep) {
|
||||
fsm_state = BYTE4_SEP_BYTE5;
|
||||
break;
|
||||
}
|
||||
if (PCAP_ISXDIGIT(*s)) {
|
||||
buf[4] = buf[4] << 4 | pcapint_xdtoi(*s);
|
||||
fsm_state = BYTE4_XX;
|
||||
break;
|
||||
}
|
||||
goto reject;
|
||||
case BYTE4_XX:
|
||||
if (*s == sep) {
|
||||
fsm_state = BYTE4_SEP_BYTE5;
|
||||
break;
|
||||
}
|
||||
goto reject;
|
||||
case BYTE4_SEP_BYTE5:
|
||||
if (PCAP_ISXDIGIT(*s)) {
|
||||
buf[5] = pcapint_xdtoi(*s);
|
||||
fsm_state = BYTE5_X;
|
||||
break;
|
||||
}
|
||||
goto reject;
|
||||
case BYTE5_X:
|
||||
if (PCAP_ISXDIGIT(*s)) {
|
||||
buf[5] = buf[5] << 4 | pcapint_xdtoi(*s);
|
||||
fsm_state = BYTE5_XX;
|
||||
break;
|
||||
}
|
||||
goto reject;
|
||||
case BYTE5_XX:
|
||||
goto reject;
|
||||
} // switch
|
||||
s++;
|
||||
} // while
|
||||
|
||||
if (fsm_state == BYTE5_X || fsm_state == BYTE5_XX) {
|
||||
// accept
|
||||
memcpy(addr, buf, sizeof(buf));
|
||||
return 1;
|
||||
}
|
||||
|
||||
reject:
|
||||
return 0;
|
||||
}
|
||||
|
||||
// The 'addr' argument must point to an array of at least 6 elements.
|
||||
static int
|
||||
pcapint_atomac48(const char *s, uint8_t *addr)
|
||||
{
|
||||
return s && (
|
||||
pcapint_atomac48_xxxxxxxxxxxx(s, addr) ||
|
||||
pcapint_atomac48_xxxx_3_times(s, addr) ||
|
||||
pcapint_atomac48_x_xx_6_times(s, addr)
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* If 's' is a MAC-48 address in one of the forms documented in pcap-filter(7)
|
||||
* for "ether host", return a pointer to an allocated buffer with the binary
|
||||
* value of the address. Return NULL on any error.
|
||||
*/
|
||||
u_char *
|
||||
pcap_ether_aton(const char *s)
|
||||
{
|
||||
register u_char *ep, *e;
|
||||
register u_char d;
|
||||
|
||||
e = ep = (u_char *)malloc(6);
|
||||
if (e == NULL)
|
||||
uint8_t tmp[6];
|
||||
if (! pcapint_atomac48(s, tmp))
|
||||
return (NULL);
|
||||
|
||||
while (*s) {
|
||||
if (*s == ':' || *s == '.' || *s == '-')
|
||||
s += 1;
|
||||
d = xdtoi(*s++);
|
||||
if (PCAP_ISXDIGIT(*s)) {
|
||||
d <<= 4;
|
||||
d |= xdtoi(*s++);
|
||||
}
|
||||
*ep++ = d;
|
||||
}
|
||||
|
||||
u_char *e = malloc(6);
|
||||
if (e == NULL)
|
||||
return (NULL);
|
||||
memcpy(e, tmp, sizeof(tmp));
|
||||
return (e);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ extern "C" {
|
|||
int __pcap_atodn(const char *, bpf_u_int32 *);
|
||||
int __pcap_atoin(const char *, bpf_u_int32 *);
|
||||
int __pcap_nametodnaddr(const char *, u_short *);
|
||||
extern int pcapint_atoan(const char *, uint8_t *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ pcap_set_print_dot_graph(int value)
|
|||
#define lowest_set_bit(mask) ((u_int)__builtin_ctz(mask))
|
||||
#elif defined(_MSC_VER)
|
||||
/*
|
||||
* Visual Studio; we support only 2005 and later, so use
|
||||
* Visual Studio; we support only 2015 and later, so use
|
||||
* _BitScanForward().
|
||||
*/
|
||||
#include <intrin.h>
|
||||
|
|
|
|||
40
pcap-bpf.c
40
pcap-bpf.c
|
|
@ -73,16 +73,6 @@ static const char usbus_prefix[] = "usbus";
|
|||
#include <net/bpf.h>
|
||||
#define _AIX
|
||||
|
||||
/*
|
||||
* If both BIOCROTZBUF and BPF_BUFMODE_ZBUF are defined, we have
|
||||
* zero-copy BPF.
|
||||
*/
|
||||
#if defined(BIOCROTZBUF) && defined(BPF_BUFMODE_ZBUF)
|
||||
#define HAVE_ZEROCOPY_BPF
|
||||
#include <sys/mman.h>
|
||||
#include <machine/atomic.h>
|
||||
#endif
|
||||
|
||||
#include <net/if_types.h> /* for IFT_ values */
|
||||
#include <sys/sysconfig.h>
|
||||
#include <sys/device.h>
|
||||
|
|
@ -126,6 +116,16 @@ static int bpf_load(char *errbuf);
|
|||
# include <net/if_media.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If both BIOCROTZBUF and BPF_BUFMODE_ZBUF are defined, we have
|
||||
* zero-copy BPF.
|
||||
*/
|
||||
#if defined(BIOCROTZBUF) && defined(BPF_BUFMODE_ZBUF)
|
||||
#define HAVE_ZEROCOPY_BPF
|
||||
#include <sys/mman.h>
|
||||
#include <machine/atomic.h>
|
||||
#endif
|
||||
|
||||
#include "pcap-int.h"
|
||||
|
||||
#ifdef HAVE_OS_PROTO_H
|
||||
|
|
@ -290,7 +290,7 @@ pcap_setnonblock_bpf(pcap_t *p, int nonblock)
|
|||
* buffer filled for a fresh BPF session.
|
||||
*/
|
||||
static int
|
||||
pcap_next_zbuf_shm(pcap_t *p, int *cc)
|
||||
pcap_next_zbuf_shm(pcap_t *p, ssize_t *cc)
|
||||
{
|
||||
struct pcap_bpf *pb = p->priv;
|
||||
struct bpf_zbuf_header *bzh;
|
||||
|
|
@ -328,7 +328,7 @@ pcap_next_zbuf_shm(pcap_t *p, int *cc)
|
|||
* work.
|
||||
*/
|
||||
static int
|
||||
pcap_next_zbuf(pcap_t *p, int *cc)
|
||||
pcap_next_zbuf(pcap_t *p, ssize_t *cc)
|
||||
{
|
||||
struct pcap_bpf *pb = p->priv;
|
||||
struct bpf_zbuf bz;
|
||||
|
|
@ -336,7 +336,7 @@ pcap_next_zbuf(pcap_t *p, int *cc)
|
|||
struct timespec cur;
|
||||
fd_set r_set;
|
||||
int data, r;
|
||||
int expire, tmout;
|
||||
long expire, tmout;
|
||||
|
||||
#define TSTOMILLI(ts) (((ts)->tv_sec * 1000) + ((ts)->tv_nsec / 1000000))
|
||||
/*
|
||||
|
|
@ -2182,7 +2182,7 @@ pcap_activate_bpf(pcap_t *p)
|
|||
status = PCAP_ERROR;
|
||||
goto bad;
|
||||
}
|
||||
status = bpf_bind(fd, p->opt.device, ifnamsiz, p->errbuf);
|
||||
status = bpf_bind(fd, p->opt.device, p->errbuf);
|
||||
if (status != BPF_BIND_SUCCEEDED) {
|
||||
if (status == BPF_BIND_BUFFER_TOO_BIG) {
|
||||
/*
|
||||
|
|
@ -3682,11 +3682,19 @@ pcap_set_datalink_bpf(pcap_t *p _U_, int dlt _U_)
|
|||
/*
|
||||
* Platform-specific information.
|
||||
*/
|
||||
#if defined(HAVE_ZEROCOPY_BPF) && defined(PCAP_SUPPORT_NETMAP)
|
||||
#define ADDITIONAL_INFO_STRING "with zerocopy and netmap support"
|
||||
#elif defined(HAVE_ZEROCOPY_BPF)
|
||||
#define ADDITIONAL_INFO_STRING "with zerocopy support"
|
||||
#elif defined(PCAP_SUPPORT_NETMAP)
|
||||
#define ADDITIONAL_INFO_STRING "with netmap support"
|
||||
#endif
|
||||
|
||||
const char *
|
||||
pcap_lib_version(void)
|
||||
{
|
||||
#ifdef HAVE_ZEROCOPY_BPF
|
||||
return (PCAP_VERSION_STRING " (with zerocopy support)");
|
||||
#ifdef ADDITIONAL_INFO_STRING
|
||||
return (PCAP_VERSION_STRING_WITH_ADDITIONAL_INFO(ADDITIONAL_INFO_STRING));
|
||||
#else
|
||||
return (PCAP_VERSION_STRING);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1199,6 +1199,8 @@
|
|||
|
||||
/*
|
||||
* USB 2.0, 1.1, and 1.0 packets as transmitted over the cable.
|
||||
* Deprecated in favor of speed specific LINKTYPEs: LINKTYPE_USB_2_0_LOW_SPEED,
|
||||
* LINKTYPE_USB_2_0_FULL_SPEED and LINKTYPE_USB_2_0_HIGH_SPEED.
|
||||
*/
|
||||
#define LINKTYPE_USB_2_0 288
|
||||
|
||||
|
|
@ -1207,7 +1209,91 @@
|
|||
*/
|
||||
#define LINKTYPE_ATSC_ALP 289
|
||||
|
||||
#define LINKTYPE_HIGH_MATCHING_MAX 289 /* highest value in the "matching" range */
|
||||
/*
|
||||
* Event Tracing for Windows messages.
|
||||
*/
|
||||
#define LINKTYPE_ETW 290
|
||||
|
||||
/*
|
||||
* Hilscher Gesellschaft fuer Systemautomation mbH
|
||||
* netANALYZER NG hardware and software.
|
||||
*
|
||||
* The specification for this footer can be found at:
|
||||
* https://kb.hilscher.com/x/brDJBw
|
||||
*
|
||||
* Requested by Jan Adam <jadam@hilscher.com>
|
||||
*/
|
||||
#define LINKTYPE_NETANALYZER_NG 291
|
||||
|
||||
/*
|
||||
* Serial NCP (Network Co-Processor) protocol for Zigbee stack ZBOSS
|
||||
* by DSR, https://dsr-iot.com/downloads
|
||||
*/
|
||||
#define LINKTYPE_ZBOSS_NCP 292
|
||||
|
||||
/*
|
||||
* USB 2.0, 1.1, and 1.0 packets as transmitted over the cable.
|
||||
*/
|
||||
#define LINKTYPE_USB_2_0_LOW_SPEED 293
|
||||
#define LINKTYPE_USB_2_0_FULL_SPEED 294
|
||||
#define LINKTYPE_USB_2_0_HIGH_SPEED 295
|
||||
|
||||
/*
|
||||
* Auerswald Logger Protocol
|
||||
* description is provided on
|
||||
* https://github.com/Auerswald-GmbH/auerlog/blob/master/auerlog.txt
|
||||
* requested by Auerswald Developer Team <developer(at)auerswald.de>
|
||||
*/
|
||||
#define LINKTYPE_AUERSWALD_LOG 296
|
||||
|
||||
/*
|
||||
* Z-Wave packets with a TAP meta-data header
|
||||
* https://gitlab.com/exegin/zwave-g9959-tap
|
||||
* requested on tcpdump-workers@
|
||||
*/
|
||||
#define LINKTYPE_ZWAVE_TAP 297
|
||||
|
||||
/*
|
||||
* Silicon Labs debug channel protocol:
|
||||
*/
|
||||
#define LINKTYPE_SILABS_DEBUG_CHANNEL 298
|
||||
|
||||
/*
|
||||
* Ultra-wideband (UWB) controller interface protocol (UCI).
|
||||
*/
|
||||
#define LINKTYPE_FIRA_UCI 299
|
||||
|
||||
/*
|
||||
* MDB (Multi-Drop Bus) protocol between a vending machine controller and
|
||||
* peripherals inside the vending machine. See
|
||||
*
|
||||
* https://www.kaiser.cx/pcap-mdb.html
|
||||
*
|
||||
* for the specification.
|
||||
*
|
||||
* Requested by Martin Kaiser <martin@kaiser.cx>.
|
||||
*/
|
||||
#define LINKTYPE_MDB 300
|
||||
|
||||
/*
|
||||
* DECT-2020 New Radio (NR) - ETSI TS 103 636.
|
||||
* Requested by Stig Bjorlykke <stig@bjorlykke.org>.
|
||||
*/
|
||||
#define LINKTYPE_DECT_NR 301
|
||||
|
||||
/*
|
||||
* Request serialization protocol used by edk2 firmware to communicate between
|
||||
* normal mode and management mode ('MM' for short).
|
||||
*
|
||||
* The qemu uefi variable store implementation reuses the request serialization
|
||||
* protocol for firmware <-> qemu communication.
|
||||
*/
|
||||
#define LINKTYPE_EDK2_MM 302
|
||||
|
||||
// See DLT_DEBUG_ONLY
|
||||
#define LINKTYPE_DEBUG_ONLY 303
|
||||
|
||||
#define LINKTYPE_HIGH_MATCHING_MAX 303 /* highest value in the "matching" range */
|
||||
|
||||
/*
|
||||
* The DLT_ and LINKTYPE_ values in the "matching" range should be the
|
||||
|
|
@ -1274,7 +1360,7 @@ dlt_to_linktype(int dlt)
|
|||
/*
|
||||
* These DLT_* codes have different values on different
|
||||
* platforms, so we assigned them LINKTYPE_* codes just
|
||||
* below the lower bound of the high matchig range;
|
||||
* below the lower bound of the high matching range;
|
||||
* those values should never be equal to any DLT_*
|
||||
* code, so that should avoid collisions.
|
||||
*
|
||||
|
|
@ -1426,7 +1512,7 @@ linktype_to_dlt(int linktype)
|
|||
/*
|
||||
* These DLT_* codes have different values on different
|
||||
* platforms, so we assigned them LINKTYPE_* codes just
|
||||
* below the lower bound of the high matchig range;
|
||||
* below the lower bound of the high matching range;
|
||||
* those values should never be equal to any DLT_*
|
||||
* code, so that should avoid collisions.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1425,8 +1425,7 @@ pcapint_platform_finddevs(pcap_if_list_t *devlistp _U_, char *errbuf)
|
|||
pcap_t *
|
||||
pcapint_create_interface(const char *device, char *errbuf)
|
||||
{
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"This version of libpcap only supports DAG cards");
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE, PCAP_ENODEV_MESSAGE, "DAG");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -1436,6 +1435,6 @@ pcapint_create_interface(const char *device, char *errbuf)
|
|||
const char *
|
||||
pcap_lib_version(void)
|
||||
{
|
||||
return (PCAP_VERSION_STRING " (DAG-only)");
|
||||
return (PCAP_VERSION_STRING_WITH_ADDITIONAL_INFO("DAG-only"));
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -80,6 +80,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")) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Disconnected");
|
||||
dbus_message_unref(message);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -97,6 +98,9 @@ dbus_read(pcap_t *handle, int max_packets _U_, pcap_handler callback, u_char *us
|
|||
|
||||
dbus_free(raw_msg);
|
||||
}
|
||||
|
||||
dbus_message_unref(message);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
|
|
|||
348
pcap-dlpi.c
348
pcap-dlpi.c
|
|
@ -20,7 +20,7 @@
|
|||
*
|
||||
* This code contributed by Atanu Ghosh (atanu@cs.ucl.ac.uk),
|
||||
* University College London, and subsequently modified by
|
||||
* Guy Harris (guy@alum.mit.edu), Mark Pizzolato
|
||||
* Guy Harris, Mark Pizzolato
|
||||
* <List-tcpdump-workers@subscriptions.pizzolato.net>,
|
||||
* Mark C. Brown (mbrown@hp.com), and Sagun Shakya <Sagun.Shakya@Sun.COM>.
|
||||
*/
|
||||
|
|
@ -336,14 +336,156 @@ pcap_cleanup_dlpi(pcap_t *p)
|
|||
pcapint_cleanup_live_common(p);
|
||||
}
|
||||
|
||||
#ifdef HAVE_DEV_DLPI
|
||||
static int
|
||||
handle_dev_dlpi_open_error(const char *ifname, int error, char *errbuf)
|
||||
{
|
||||
/*
|
||||
* An attempt to open /dev/dlpi failed.
|
||||
* Report the appropriate error.
|
||||
*/
|
||||
if (error == ENOENT) {
|
||||
/*
|
||||
* Missing; I guess that means we don't support
|
||||
* opening DLPI devices, and thus can't capture
|
||||
* traffic at all.
|
||||
*/
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Capturing network traffic not supported - /dev/dlpi doesn't exist");
|
||||
return (PCAP_ERROR_CAPTURE_NOTSUP);
|
||||
} else if (error == EPERM || error == EACCES) {
|
||||
/*
|
||||
* We lack permission to open it.
|
||||
*
|
||||
* If the interface exists, report the permission error,
|
||||
* otherwise report "no such interface".
|
||||
*/
|
||||
int fd;
|
||||
struct ifreq ifr;
|
||||
|
||||
if (strlen(ifname) >= sizeof(ifr.ifr_name)) {
|
||||
/*
|
||||
* The name is too long, so it can't possibly exist.
|
||||
* Report that.
|
||||
*
|
||||
* There's nothing more to say, so clear
|
||||
* the error message.
|
||||
*/
|
||||
errbuf[0] = '\0';
|
||||
return (PCAP_ERROR_NO_SUCH_DEVICE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Try to get a socket on which to do an ioctl to get the
|
||||
* interface's flags.
|
||||
*/
|
||||
fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (fd < 0) {
|
||||
/* That failed; report that as the error. */
|
||||
pcapint_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
|
||||
errno, "Can't open socket to get interface flags");
|
||||
return (PCAP_ERROR);
|
||||
}
|
||||
|
||||
pcapint_strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
|
||||
if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifr) < 0) {
|
||||
if (errno == ENXIO || errno == EINVAL) {
|
||||
/*
|
||||
* macOS, *BSD, and Solaris return one of
|
||||
* those two errors if the device doesn't
|
||||
* exist. Report that.
|
||||
* XXX - what about HP-UX?
|
||||
*
|
||||
* There's nothing more to say, so clear
|
||||
* the error message.
|
||||
*/
|
||||
errbuf[0] = '\0';
|
||||
close(fd);
|
||||
return (PCAP_ERROR_NO_SUCH_DEVICE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Some other error.
|
||||
*/
|
||||
pcapint_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
|
||||
errno, "Can't get interface flags");
|
||||
close(fd);
|
||||
return (PCAP_ERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
* The device exists; report this as a permissions problem.
|
||||
*/
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Attempt to open /dev/dlpi failed with %s - root privilege may be required",
|
||||
(error == EPERM) ? "EPERM" : "EACCES");
|
||||
close(fd);
|
||||
return (PCAP_ERROR_PERM_DENIED);
|
||||
} else {
|
||||
/*
|
||||
* Soe other error.
|
||||
*/
|
||||
pcapint_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
|
||||
error, "Attempt to open /dev/dlpi failed");
|
||||
return (PCAP_ERROR);
|
||||
}
|
||||
}
|
||||
#else /* HAVE_DEV_DLPI */
|
||||
static int
|
||||
handle_dlpi_device_open_error(const char *ifname, const char *device,
|
||||
int error, char *errbuf)
|
||||
{
|
||||
/*
|
||||
* We couldn't open a DLPI device.
|
||||
* Was that due to a permission error?
|
||||
*/
|
||||
if (error == EPERM || error == EACCES) {
|
||||
/*
|
||||
* We lack permission to open it.
|
||||
*
|
||||
* If the interface doesn't exist, there wouldn't be
|
||||
* a DLPI device corresponding to it, so we wouldn't
|
||||
* have gotten a permissions error.
|
||||
*/
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Attempt to open %s failed with %s - root privilege may be required",
|
||||
device, (error == EPERM) ? "EPERM" : "EACCES");
|
||||
return (PCAP_ERROR_PERM_DENIED);
|
||||
}
|
||||
|
||||
/*
|
||||
* Was that due to the DLPI device not existing?
|
||||
*/
|
||||
if (error != ENOENT) {
|
||||
/*
|
||||
* No; report it as a generic error, giving the error
|
||||
* message for the error code and the name of the
|
||||
* device we tried to open.
|
||||
*/
|
||||
pcapint_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
|
||||
error, "Attempt to open %s failed", device);
|
||||
return (PCAP_ERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
* Yes. That means we can't do DLPI capturing, at least not
|
||||
* on that interface.
|
||||
*
|
||||
* Test whether it exists and, if it does, whether it's
|
||||
* a loopback interface.
|
||||
*/
|
||||
return (handle_nonexistent_dlpi_device(ifname, errbuf));
|
||||
}
|
||||
#endif /* not HAVE_DEV_DLPI */
|
||||
|
||||
static int
|
||||
open_dlpi_device(const char *name, u_int *ppa, char *errbuf)
|
||||
{
|
||||
int status;
|
||||
char dname[100];
|
||||
char *cp;
|
||||
char *cp, *cq;
|
||||
int fd;
|
||||
#ifdef HAVE_DEV_DLPI
|
||||
int status;
|
||||
u_int unit;
|
||||
#else
|
||||
char dname2[100];
|
||||
|
|
@ -359,6 +501,32 @@ open_dlpi_device(const char *name, u_int *ppa, char *errbuf)
|
|||
else
|
||||
pcapint_strlcpy(dname, cp + 1, sizeof(dname));
|
||||
|
||||
/*
|
||||
* If this name has a colon followed by a number at
|
||||
* the end, it's a logical interface. Those are just
|
||||
* the way you assign multiple IP addresses to a real
|
||||
* interface, so an entry for a logical interface should
|
||||
* be treated like the entry for the real interface;
|
||||
* we do that by stripping off the ":" and the number.
|
||||
*/
|
||||
cp = strchr(dname, ':');
|
||||
if (cp != NULL) {
|
||||
/*
|
||||
* We have a ":"; is it followed by a number?
|
||||
*/
|
||||
cq = cp + 1;
|
||||
while (PCAP_ISDIGIT(*cq))
|
||||
cq++;
|
||||
if (*cq == '\0') {
|
||||
/*
|
||||
* All digits after the ":" until the end.
|
||||
* Strip off the ":" and everything after
|
||||
* it.
|
||||
*/
|
||||
*cp = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Split the device name into a device type name and a unit number;
|
||||
* chop off the unit number, so "dname" is just a device type name.
|
||||
|
|
@ -383,20 +551,8 @@ open_dlpi_device(const char *name, u_int *ppa, char *errbuf)
|
|||
* search "/dev" for the appropriate device with that major
|
||||
* device number, rather than hardwiring "/dev/dlpi".
|
||||
*/
|
||||
cp = "/dev/dlpi";
|
||||
if ((fd = open(cp, O_RDWR)) < 0) {
|
||||
if (errno == EPERM || errno == EACCES) {
|
||||
status = PCAP_ERROR_PERM_DENIED;
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Attempt to open %s failed with %s - root privilege may be required",
|
||||
cp, (errno == EPERM) ? "EPERM" : "EACCES");
|
||||
} else {
|
||||
status = PCAP_ERROR;
|
||||
pcapint_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
|
||||
errno, "Attempt to open %s failed", cp);
|
||||
}
|
||||
return (status);
|
||||
}
|
||||
if ((fd = open("/dev/dlpi", O_RDWR)) < 0)
|
||||
return (handle_dev_dlpi_open_error(name, errno, errbuf));
|
||||
|
||||
/*
|
||||
* Get a table of all PPAs for that device, and search that
|
||||
|
|
@ -420,6 +576,32 @@ open_dlpi_device(const char *name, u_int *ppa, char *errbuf)
|
|||
snprintf(dname, sizeof(dname), "%s/%s", PCAP_DEV_PREFIX,
|
||||
name);
|
||||
|
||||
/*
|
||||
* If this name has a colon followed by a number at
|
||||
* the end, it's a logical interface. Those are just
|
||||
* the way you assign multiple IP addresses to a real
|
||||
* interface, so an entry for a logical interface should
|
||||
* be treated like the entry for the real interface;
|
||||
* we do that by stripping off the ":" and the number.
|
||||
*/
|
||||
cp = strchr(dname, ':');
|
||||
if (cp != NULL) {
|
||||
/*
|
||||
* We have a ":"; is it followed by a number?
|
||||
*/
|
||||
cq = cp + 1;
|
||||
while (PCAP_ISDIGIT(*cq))
|
||||
cq++;
|
||||
if (*cq == '\0') {
|
||||
/*
|
||||
* All digits after the ":" until the end.
|
||||
* Strip off the ":" and everything after
|
||||
* it.
|
||||
*/
|
||||
*cp = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the unit number, and a pointer to the end of the device
|
||||
* type name.
|
||||
|
|
@ -441,69 +623,20 @@ open_dlpi_device(const char *name, u_int *ppa, char *errbuf)
|
|||
|
||||
/* Try device without unit number */
|
||||
if ((fd = open(dname, O_RDWR)) < 0) {
|
||||
if (errno != ENOENT) {
|
||||
if (errno == EPERM || errno == EACCES) {
|
||||
status = PCAP_ERROR_PERM_DENIED;
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Attempt to open %s failed with %s - root privilege may be required",
|
||||
dname,
|
||||
(errno == EPERM) ? "EPERM" : "EACCES");
|
||||
} else {
|
||||
status = PCAP_ERROR;
|
||||
pcapint_fmt_errmsg_for_errno(errbuf,
|
||||
PCAP_ERRBUF_SIZE, errno,
|
||||
"Attempt to open %s failed", dname);
|
||||
}
|
||||
return (status);
|
||||
}
|
||||
if (errno != ENOENT)
|
||||
return (handle_dlpi_device_open_error(name, dname,
|
||||
errno, errbuf));
|
||||
|
||||
/* Try again with unit number */
|
||||
if ((fd = open(dname2, O_RDWR)) < 0) {
|
||||
if (errno == ENOENT) {
|
||||
status = PCAP_ERROR_NO_SUCH_DEVICE;
|
||||
|
||||
/*
|
||||
* We provide an error message even
|
||||
* for this error, for diagnostic
|
||||
* purposes (so that, for example,
|
||||
* the app can show the message if the
|
||||
* user requests it).
|
||||
*
|
||||
* In it, we just report "No DLPI device
|
||||
* found" with the device name, so people
|
||||
* don't get confused and think, for example,
|
||||
* that if they can't capture on "lo0"
|
||||
* on Solaris prior to Solaris 11 the fix
|
||||
* is to change libpcap (or the application
|
||||
* that uses it) to look for something other
|
||||
* than "/dev/lo0", as the fix is to use
|
||||
* Solaris 11 or some operating system
|
||||
* other than Solaris - you just *can't*
|
||||
* capture on a loopback interface
|
||||
* on Solaris prior to Solaris 11, the lack
|
||||
* of a DLPI device for the loopback
|
||||
* interface is just a symptom of that
|
||||
* inability.
|
||||
*/
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"%s: No DLPI device found", name);
|
||||
} else {
|
||||
if (errno == EPERM || errno == EACCES) {
|
||||
status = PCAP_ERROR_PERM_DENIED;
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Attempt to open %s failed with %s - root privilege may be required",
|
||||
dname2,
|
||||
(errno == EPERM) ? "EPERM" : "EACCES");
|
||||
} else {
|
||||
status = PCAP_ERROR;
|
||||
pcapint_fmt_errmsg_for_errno(errbuf,
|
||||
PCAP_ERRBUF_SIZE, errno,
|
||||
"Attempt to open %s failed",
|
||||
dname2);
|
||||
}
|
||||
}
|
||||
return (status);
|
||||
}
|
||||
/*
|
||||
* There's no DLPI device whose name is the interface
|
||||
* name with the unit number removed.
|
||||
*
|
||||
* Try again with a device name that includes the
|
||||
* unit number.
|
||||
*/
|
||||
if ((fd = open(dname2, O_RDWR)) < 0)
|
||||
return (handle_dlpi_device_open_error(name, dname2,
|
||||
errno, errbuf));
|
||||
/* XXX Assume unit zero */
|
||||
*ppa = 0;
|
||||
}
|
||||
|
|
@ -905,6 +1038,11 @@ split_dname(char *device, u_int *unitp, char *ebuf)
|
|||
/* Digits at end of string are unit number */
|
||||
while (cp-1 >= device && *(cp-1) >= '0' && *(cp-1) <= '9')
|
||||
cp--;
|
||||
if (cp == device || *(cp-1) == '/') {
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s has only a unit number",
|
||||
device);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
unit = strtol(cp, &eos, 10);
|
||||
|
|
@ -1025,52 +1163,16 @@ dlpromiscon(pcap_t *p, bpf_u_int32 level)
|
|||
}
|
||||
|
||||
/*
|
||||
* Not all interfaces are DLPI interfaces, and thus not all interfaces
|
||||
* can be opened with DLPI (for example, the loopback interface is not
|
||||
* a DLPI interface on Solaris prior to Solaris 11), so try to open
|
||||
* the specified interface; return 0 if we fail with PCAP_ERROR_NO_SUCH_DEVICE
|
||||
* and 1 otherwise.
|
||||
* Show all interfaces, so users don't ask "why is this interface not
|
||||
* showing up?" or "why are no interfaces showing up?" We report
|
||||
* PCAP_ERROR_CAPTURE_NOTSUP if there's no DLPI device, with an
|
||||
* error message that tries to explain the source of the problem,
|
||||
* which is some flavor of "sorry, that's simply not supported by
|
||||
* your OS".
|
||||
*/
|
||||
static int
|
||||
is_dlpi_interface(const char *name)
|
||||
show_them_all(const char *name _U_)
|
||||
{
|
||||
int fd;
|
||||
u_int ppa;
|
||||
char errbuf[PCAP_ERRBUF_SIZE];
|
||||
|
||||
fd = open_dlpi_device(name, &ppa, errbuf);
|
||||
if (fd < 0) {
|
||||
/*
|
||||
* Error - was it PCAP_ERROR_NO_SUCH_DEVICE?
|
||||
*/
|
||||
if (fd == PCAP_ERROR_NO_SUCH_DEVICE) {
|
||||
/*
|
||||
* Yes, so we can't open this because it's
|
||||
* not a DLPI interface.
|
||||
*/
|
||||
return (0);
|
||||
}
|
||||
/*
|
||||
* No, so, in the case where there's a single DLPI
|
||||
* device for all interfaces of this type ("style
|
||||
* 2" providers?), we don't know whether it's a DLPI
|
||||
* interface or not, as we didn't try an attach.
|
||||
* Say it is a DLPI device, so that the user can at
|
||||
* least try to open it and report the error (which
|
||||
* is probably "you don't have permission to open that
|
||||
* DLPI device"; reporting those interfaces means
|
||||
* users will ask "why am I getting a permissions error
|
||||
* when I try to capture" rather than "why am I not
|
||||
* seeing any interfaces", making the underlying problem
|
||||
* clearer).
|
||||
*/
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Success.
|
||||
*/
|
||||
close(fd);
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
|
@ -1114,7 +1216,7 @@ pcapint_platform_finddevs(pcap_if_list_t *devlistp, char *errbuf)
|
|||
/*
|
||||
* Get the list of regular interfaces first.
|
||||
*/
|
||||
if (pcapint_findalldevs_interfaces(devlistp, errbuf, is_dlpi_interface,
|
||||
if (pcapint_findalldevs_interfaces(devlistp, errbuf, show_them_all,
|
||||
get_if_flags) == -1)
|
||||
return (-1); /* failure */
|
||||
|
||||
|
|
|
|||
|
|
@ -1068,8 +1068,7 @@ pcapint_platform_finddevs(pcap_if_list_t *devlistp _U_, char *errbuf)
|
|||
pcap_t *
|
||||
pcapint_create_interface(const char *device, char *errbuf)
|
||||
{
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"This version of libpcap only supports DPDK");
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE, PCAP_ENODEV_MESSAGE, "DPDK");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -1079,6 +1078,6 @@ pcapint_create_interface(const char *device, char *errbuf)
|
|||
const char *
|
||||
pcap_lib_version(void)
|
||||
{
|
||||
return (PCAP_VERSION_STRING " (DPDK-only)");
|
||||
return (PCAP_VERSION_STRING_WITH_ADDITIONAL_INFO("DPDK-only"));
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -212,7 +212,7 @@ pcap_inject_haiku(pcap_t *handle, const void *buffer _U_, int size _U_)
|
|||
{
|
||||
// Haiku currently (hrev57588) does not support sending raw packets.
|
||||
// https://dev.haiku-os.org/ticket/18810
|
||||
strlcpy(handle->errbuf, "Sending packets isn't supported yet",
|
||||
pcapint_strlcpy(handle->errbuf, "Sending packets isn't supported yet",
|
||||
PCAP_ERRBUF_SIZE);
|
||||
return PCAP_ERROR;
|
||||
}
|
||||
|
|
@ -435,7 +435,8 @@ pcapint_create_interface(const char *device, char *errorBuffer)
|
|||
|
||||
struct pcap_haiku *handlep = (struct pcap_haiku *)handle->priv;
|
||||
handlep->aux_socket = -1;
|
||||
strcpy(handlep->ifreq.ifr_name, device);
|
||||
// validate_ifname() has already checked "device" length.
|
||||
(void)pcapint_strlcpy(handlep->ifreq.ifr_name, device, IF_NAMESIZE);
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
|
@ -468,7 +469,8 @@ get_if_flags(const char *name, bpf_u_int32 *flags, char *errbuf)
|
|||
if (fd < 0)
|
||||
return PCAP_ERROR;
|
||||
struct ifreq ifreq;
|
||||
strcpy(ifreq.ifr_name, name);
|
||||
// validate_ifname() has already checked "name" length.
|
||||
(void)pcapint_strlcpy(ifreq.ifr_name, name, IF_NAMESIZE);
|
||||
if (ioctl_ifreq(fd, SIOCGIFFLAGS, "SIOCGIFFLAGS", &ifreq, errbuf) < 0) {
|
||||
close(fd);
|
||||
return PCAP_ERROR;
|
||||
|
|
|
|||
35
pcap-int.h
35
pcap-int.h
|
|
@ -73,10 +73,28 @@
|
|||
#endif
|
||||
|
||||
/*
|
||||
* Version string.
|
||||
* Uses PACKAGE_VERSION from config.h.
|
||||
* Version string trailer.
|
||||
* Uses SIZEOF_TIME_T from config.h.
|
||||
* (There's no need to announce the pointer size; if it doesn't
|
||||
* match the pointer size in code linked with libpcap, either
|
||||
* build-time linking or run-time linking will fail.)
|
||||
*/
|
||||
#define PCAP_VERSION_STRING "libpcap version " PACKAGE_VERSION
|
||||
#if SIZEOF_TIME_T == 8
|
||||
#define PCAP_SIZEOF_TIME_T_BITS_STRING "64"
|
||||
#elif SIZEOF_TIME_T == 4
|
||||
#define PCAP_SIZEOF_TIME_T_BITS_STRING "32"
|
||||
#else
|
||||
#error Unknown time_t size
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Version string.
|
||||
* Uses PACKAGE_VERSION from config.h and PCAP_SIZEOF_TIME_T_BITS_STRING.
|
||||
*/
|
||||
#define PCAP_VERSION_STRING \
|
||||
"libpcap version " PACKAGE_VERSION " (" PCAP_SIZEOF_TIME_T_BITS_STRING "-bit time_t)"
|
||||
#define PCAP_VERSION_STRING_WITH_ADDITIONAL_INFO(additional_info) \
|
||||
"libpcap version " PACKAGE_VERSION " (" PCAP_SIZEOF_TIME_T_BITS_STRING "-bit time_t, " additional_info ")"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
|
@ -413,6 +431,14 @@ int pcapint_setnonblock_fd(pcap_t *p, int);
|
|||
* by pcap_create routines.
|
||||
*/
|
||||
pcap_t *pcapint_create_interface(const char *, char *);
|
||||
/*
|
||||
* A format string for something-only libpcap builds, which use a stub
|
||||
* implementation of pcapint_create_interface(). It contains the substring
|
||||
* "No such device" (one of the standard descriptions of ENODEV) -- this way
|
||||
* tcpdump can detect a particular error condition even though pcap_create()
|
||||
* returns NULL for all errors.
|
||||
*/
|
||||
#define PCAP_ENODEV_MESSAGE "No such device (this build of libpcap supports %s devices only)."
|
||||
|
||||
/*
|
||||
* This wrapper takes an error buffer pointer and a type to use for the
|
||||
|
|
@ -530,10 +556,9 @@ FILE *pcapint_charset_fopen(const char *path, const char *mode);
|
|||
*/
|
||||
#ifdef _WIN32
|
||||
#define pcap_code_handle_t HMODULE
|
||||
#define pcap_funcptr_t FARPROC
|
||||
|
||||
pcap_code_handle_t pcapint_load_code(const char *);
|
||||
pcap_funcptr_t pcapint_find_function(pcap_code_handle_t, const char *);
|
||||
void *pcapint_find_function(pcap_code_handle_t, const char *);
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -106,20 +106,47 @@ pcap_activate_libdlpi(pcap_t *p)
|
|||
*/
|
||||
retv = dlpi_open(p->opt.device, &dh, DLPI_RAW|DLPI_PASSIVE);
|
||||
if (retv != DLPI_SUCCESS) {
|
||||
if (retv == DLPI_ELINKNAMEINVAL || retv == DLPI_ENOLINK) {
|
||||
if (retv == DLPI_ELINKNAMEINVAL) {
|
||||
/*
|
||||
* The interface name is not syntactiacally
|
||||
* valid, and thus doesn't correspond to
|
||||
* an interface.
|
||||
*
|
||||
* There's nothing more to say, so clear the
|
||||
* error message.
|
||||
*/
|
||||
status = PCAP_ERROR_NO_SUCH_DEVICE;
|
||||
p->errbuf[0] = '\0';
|
||||
} else if (retv == DLPI_ENOLINK) {
|
||||
/*
|
||||
* The interface name is syntactically valid,
|
||||
* but we don't have a DLPI device that
|
||||
* would be used for that interface.
|
||||
*/
|
||||
status = handle_nonexistent_dlpi_device(p->opt.device,
|
||||
p->errbuf);
|
||||
} else if (retv == DL_SYSERR &&
|
||||
(errno == EPERM || errno == EACCES)) {
|
||||
/*
|
||||
* We got EPERM or EACCES trying to open the
|
||||
* DLPI device, so we know it exists.
|
||||
*/
|
||||
status = PCAP_ERROR_PERM_DENIED;
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Attempt to open DLPI device failed with %s - root privilege may be required",
|
||||
(errno == EPERM) ? "EPERM" : "EACCES");
|
||||
} else {
|
||||
/*
|
||||
* pcap_libdlpi_err() calls dlpi_strerror(),
|
||||
* which handles DL_SYSERR.
|
||||
*
|
||||
* XXX - does DLPI_ERAWNOTSUP mean that the
|
||||
* interface exists and supports DLPI but,
|
||||
* as it doesn't support raw mode, it
|
||||
* doesn't support packet capture?
|
||||
*
|
||||
* XXX - what does DLPI_EBADLINK mean?
|
||||
*/
|
||||
status = PCAP_ERROR;
|
||||
pcap_libdlpi_err(p->opt.device, "dlpi_open", retv,
|
||||
p->errbuf);
|
||||
|
|
@ -131,7 +158,7 @@ pcap_activate_libdlpi(pcap_t *p)
|
|||
if (p->opt.rfmon) {
|
||||
/*
|
||||
* This device exists, but we don't support monitor mode
|
||||
* any platforms that support DLPI.
|
||||
* on any platforms that support DLPI.
|
||||
*/
|
||||
status = PCAP_ERROR_RFMON_NOTSUP;
|
||||
goto bad;
|
||||
|
|
@ -488,7 +515,7 @@ pcap_cleanup_libdlpi(pcap_t *p)
|
|||
static void
|
||||
pcap_libdlpi_err(const char *linkname, const char *func, int err, char *errbuf)
|
||||
{
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE, "libpcap: %s failed on %s: %s",
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s failed on %s: %s",
|
||||
func, linkname, dlpi_strerror(err));
|
||||
}
|
||||
|
||||
|
|
|
|||
668
pcap-linux.c
668
pcap-linux.c
|
|
@ -91,6 +91,7 @@
|
|||
#include <linux/ethtool.h>
|
||||
#include <netinet/in.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/netlink.h>
|
||||
#include <linux/if_arp.h>
|
||||
#include <poll.h>
|
||||
#include <dirent.h>
|
||||
|
|
@ -213,8 +214,7 @@ struct pcap_linux {
|
|||
/*
|
||||
* Stuff to do when we close.
|
||||
*/
|
||||
#define MUST_CLEAR_RFMON 0x00000001 /* clear rfmon (monitor) mode */
|
||||
#define MUST_DELETE_MONIF 0x00000002 /* delete monitor-mode interface */
|
||||
#define MUST_DELETE_MONIF 0x00000001 /* delete monitor-mode interface */
|
||||
|
||||
/*
|
||||
* Prototypes for internal functions and methods.
|
||||
|
|
@ -457,9 +457,57 @@ get_mac80211_phydev(pcap_t *handle, const char *device, char *phydev_path,
|
|||
}
|
||||
bytes_read = readlink(pathstr, phydev_path, phydev_max_pathlen);
|
||||
if (bytes_read == -1) {
|
||||
if (errno == ENOENT || errno == EINVAL) {
|
||||
if (errno == ENOENT) {
|
||||
/*
|
||||
* Doesn't exist, or not a symlink; assume that
|
||||
* This either means that the directory
|
||||
* /sys/class/net/{device} exists but doesn't
|
||||
* have anything named "phy80211" in it,
|
||||
* in which case it's not a mac80211 device,
|
||||
* or that the directory doesn't exist,
|
||||
* in which case the device doesn't exist.
|
||||
*
|
||||
* Directly check whether the directory
|
||||
* exists.
|
||||
*/
|
||||
struct stat statb;
|
||||
|
||||
free(pathstr);
|
||||
if (asprintf(&pathstr, "/sys/class/net/%s", device) == -1) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"%s: Can't generate path name string for /sys/class/net device",
|
||||
device);
|
||||
return PCAP_ERROR;
|
||||
}
|
||||
if (stat(pathstr, &statb) == -1) {
|
||||
if (errno == ENOENT) {
|
||||
/*
|
||||
* No such device.
|
||||
*/
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"%s: %s doesn't exist",
|
||||
device, pathstr);
|
||||
free(pathstr);
|
||||
return PCAP_ERROR_NO_SUCH_DEVICE;
|
||||
}
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"%s: Can't stat %s: %s",
|
||||
device, pathstr, strerror(errno));
|
||||
free(pathstr);
|
||||
return PCAP_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Path to the directory that would contain
|
||||
* "phy80211" exists, but "phy80211" doesn't
|
||||
* exist; that means it's not a mac80211
|
||||
* device.
|
||||
*/
|
||||
free(pathstr);
|
||||
return 0;
|
||||
}
|
||||
if (errno == EINVAL) {
|
||||
/*
|
||||
* Exists, but it's not a symlink; assume that
|
||||
* means it's not a mac80211 device.
|
||||
*/
|
||||
free(pathstr);
|
||||
|
|
@ -535,6 +583,119 @@ static int
|
|||
del_mon_if(pcap_t *handle, int sock_fd, struct nl80211_state *state,
|
||||
const char *device, const char *mondevice);
|
||||
|
||||
static int
|
||||
if_type_cb(struct nl_msg *msg, void* arg)
|
||||
{
|
||||
struct nlmsghdr* ret_hdr = nlmsg_hdr(msg);
|
||||
struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];
|
||||
int *type = (int*)arg;
|
||||
|
||||
struct genlmsghdr *gnlh = (struct genlmsghdr*) nlmsg_data(ret_hdr);
|
||||
|
||||
nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
|
||||
genlmsg_attrlen(gnlh, 0), NULL);
|
||||
|
||||
/*
|
||||
* We sent a message asking for info about a single index.
|
||||
* To be really paranoid, we could check if the index matched
|
||||
* by examining nla_get_u32(tb_msg[NL80211_ATTR_IFINDEX]).
|
||||
*/
|
||||
|
||||
if (tb_msg[NL80211_ATTR_IFTYPE]) {
|
||||
*type = nla_get_u32(tb_msg[NL80211_ATTR_IFTYPE]);
|
||||
}
|
||||
|
||||
return NL_SKIP;
|
||||
}
|
||||
|
||||
static int
|
||||
get_if_type(pcap_t *handle, int sock_fd, struct nl80211_state *state,
|
||||
const char *device, int *type)
|
||||
{
|
||||
int ifindex;
|
||||
struct nl_msg *msg;
|
||||
int err;
|
||||
|
||||
ifindex = iface_get_id(sock_fd, device, handle->errbuf);
|
||||
if (ifindex == -1)
|
||||
return PCAP_ERROR;
|
||||
|
||||
msg = nlmsg_alloc();
|
||||
if (!msg) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"%s: failed to allocate netlink msg", device);
|
||||
return PCAP_ERROR;
|
||||
}
|
||||
|
||||
genlmsg_put(msg, NL_AUTO_PORT, NL_AUTO_SEQ,
|
||||
genl_family_get_id(state->nl80211), 0,
|
||||
0, NL80211_CMD_GET_INTERFACE, 0);
|
||||
NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex);
|
||||
|
||||
err = nl_send_auto(state->nl_sock, msg);
|
||||
nlmsg_free(msg);
|
||||
if (err < 0) {
|
||||
if (err == -NLE_FAILURE) {
|
||||
/*
|
||||
* Device not available; our caller should just
|
||||
* keep trying. (libnl 2.x maps ENFILE to
|
||||
* NLE_FAILURE; it can also map other errors
|
||||
* to that, but there's not much we can do
|
||||
* about that.)
|
||||
*/
|
||||
return 0;
|
||||
} else {
|
||||
/*
|
||||
* Real failure, not just "that device is not
|
||||
* available.
|
||||
*/
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"%s: nl_send_auto failed getting interface type: %s",
|
||||
device, nl_geterror(-err));
|
||||
return PCAP_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT);
|
||||
nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, if_type_cb, (void*)type);
|
||||
err = nl_recvmsgs(state->nl_sock, cb);
|
||||
nl_cb_put(cb);
|
||||
|
||||
if (err < 0) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"%s: nl_recvmsgs failed getting interface type: %s",
|
||||
device, nl_geterror(-err));
|
||||
return PCAP_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* If this is a mac80211 device not in monitor mode, nl_sock will be
|
||||
* reused for add_mon_if. So we must wait for the ACK here so that
|
||||
* add_mon_if does not receive it instead and incorrectly interpret
|
||||
* the ACK as its NEW_INTERFACE command succeeding, even when it fails.
|
||||
*/
|
||||
err = nl_wait_for_ack(state->nl_sock);
|
||||
if (err < 0) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"%s: nl_wait_for_ack failed getting interface type: %s",
|
||||
device, nl_geterror(-err));
|
||||
return PCAP_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Success.
|
||||
*/
|
||||
return 1;
|
||||
|
||||
nla_put_failure:
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"%s: nl_put failed getting interface type",
|
||||
device);
|
||||
nlmsg_free(msg);
|
||||
// Do not call nl_cb_put(): nl_cb_alloc() has not been called.
|
||||
return PCAP_ERROR;
|
||||
}
|
||||
|
||||
static int
|
||||
add_mon_if(pcap_t *handle, int sock_fd, struct nl80211_state *state,
|
||||
const char *device, const char *mondevice)
|
||||
|
|
@ -555,7 +716,8 @@ add_mon_if(pcap_t *handle, int sock_fd, struct nl80211_state *state,
|
|||
return PCAP_ERROR;
|
||||
}
|
||||
|
||||
genlmsg_put(msg, 0, 0, genl_family_get_id(state->nl80211), 0,
|
||||
genlmsg_put(msg, NL_AUTO_PORT, NL_AUTO_SEQ,
|
||||
genl_family_get_id(state->nl80211), 0,
|
||||
0, NL80211_CMD_NEW_INTERFACE, 0);
|
||||
NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex);
|
||||
DIAG_OFF_NARROWING
|
||||
|
|
@ -563,9 +725,12 @@ DIAG_OFF_NARROWING
|
|||
DIAG_ON_NARROWING
|
||||
NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, NL80211_IFTYPE_MONITOR);
|
||||
|
||||
err = nl_send_auto_complete(state->nl_sock, msg);
|
||||
err = nl_send_sync(state->nl_sock, msg); // calls nlmsg_free()
|
||||
if (err < 0) {
|
||||
if (err == -NLE_FAILURE) {
|
||||
switch (err) {
|
||||
|
||||
case -NLE_FAILURE:
|
||||
case -NLE_AGAIN:
|
||||
/*
|
||||
* Device not available; our caller should just
|
||||
* keep trying. (libnl 2.x maps ENFILE to
|
||||
|
|
@ -573,41 +738,25 @@ DIAG_ON_NARROWING
|
|||
* to that, but there's not much we can do
|
||||
* about that.)
|
||||
*/
|
||||
nlmsg_free(msg);
|
||||
return 0;
|
||||
} else {
|
||||
|
||||
case -NLE_OPNOTSUPP:
|
||||
/*
|
||||
* Device is a mac80211 device but adding it as a
|
||||
* monitor mode device isn't supported. Report our
|
||||
* error.
|
||||
*/
|
||||
return PCAP_ERROR_RFMON_NOTSUP;
|
||||
|
||||
default:
|
||||
/*
|
||||
* Real failure, not just "that device is not
|
||||
* available.
|
||||
* available." Report a generic error, using the
|
||||
* error message from libnl.
|
||||
*/
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"%s: nl_send_auto_complete failed adding %s interface: %s",
|
||||
"%s: nl_send_sync failed adding %s interface: %s",
|
||||
device, mondevice, nl_geterror(-err));
|
||||
nlmsg_free(msg);
|
||||
return PCAP_ERROR;
|
||||
}
|
||||
}
|
||||
err = nl_wait_for_ack(state->nl_sock);
|
||||
if (err < 0) {
|
||||
if (err == -NLE_FAILURE) {
|
||||
/*
|
||||
* Device not available; our caller should just
|
||||
* keep trying. (libnl 2.x maps ENFILE to
|
||||
* NLE_FAILURE; it can also map other errors
|
||||
* to that, but there's not much we can do
|
||||
* about that.)
|
||||
*/
|
||||
nlmsg_free(msg);
|
||||
return 0;
|
||||
} else {
|
||||
/*
|
||||
* Real failure, not just "that device is not
|
||||
* available.
|
||||
*/
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"%s: nl_wait_for_ack failed adding %s interface: %s",
|
||||
device, mondevice, nl_geterror(-err));
|
||||
nlmsg_free(msg);
|
||||
return PCAP_ERROR;
|
||||
}
|
||||
}
|
||||
|
|
@ -615,7 +764,6 @@ DIAG_ON_NARROWING
|
|||
/*
|
||||
* Success.
|
||||
*/
|
||||
nlmsg_free(msg);
|
||||
|
||||
/*
|
||||
* Try to remember the monitor device.
|
||||
|
|
@ -659,31 +807,22 @@ del_mon_if(pcap_t *handle, int sock_fd, struct nl80211_state *state,
|
|||
return PCAP_ERROR;
|
||||
}
|
||||
|
||||
genlmsg_put(msg, 0, 0, genl_family_get_id(state->nl80211), 0,
|
||||
genlmsg_put(msg, NL_AUTO_PORT, NL_AUTO_SEQ,
|
||||
genl_family_get_id(state->nl80211), 0,
|
||||
0, NL80211_CMD_DEL_INTERFACE, 0);
|
||||
NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex);
|
||||
|
||||
err = nl_send_auto_complete(state->nl_sock, msg);
|
||||
err = nl_send_sync(state->nl_sock, msg); // calls nlmsg_free()
|
||||
if (err < 0) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"%s: nl_send_auto_complete failed deleting %s interface: %s",
|
||||
"%s: nl_send_sync failed deleting %s interface: %s",
|
||||
device, mondevice, nl_geterror(-err));
|
||||
nlmsg_free(msg);
|
||||
return PCAP_ERROR;
|
||||
}
|
||||
err = nl_wait_for_ack(state->nl_sock);
|
||||
if (err < 0) {
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"%s: nl_wait_for_ack failed adding %s interface: %s",
|
||||
device, mondevice, nl_geterror(-err));
|
||||
nlmsg_free(msg);
|
||||
return PCAP_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Success.
|
||||
*/
|
||||
nlmsg_free(msg);
|
||||
return 1;
|
||||
|
||||
nla_put_failure:
|
||||
|
|
@ -1231,19 +1370,17 @@ linux_check_direction(const pcap_t *handle, const struct sockaddr_ll *sll)
|
|||
return 0;
|
||||
|
||||
/*
|
||||
* If this is an outgoing CAN or CAN FD frame, and
|
||||
* the user doesn't only want outgoing packets,
|
||||
* reject it; CAN devices and drivers, and the CAN
|
||||
* stack, always arrange to loop back transmitted
|
||||
* packets, so they also appear as incoming packets.
|
||||
* We don't want duplicate packets, and we can't
|
||||
* easily distinguish packets looped back by the CAN
|
||||
* layer than those received by the CAN layer, so we
|
||||
* eliminate this packet instead.
|
||||
* If this is an outgoing CAN frame, and the user doesn't
|
||||
* want only outgoing packets, reject it; CAN devices
|
||||
* and drivers, and the CAN stack, always arrange to
|
||||
* loop back transmitted packets, so they also appear
|
||||
* as incoming packets. We don't want duplicate packets,
|
||||
* and we can't easily distinguish packets looped back
|
||||
* by the CAN layer than those received by the CAN layer,
|
||||
* so we eliminate this packet instead.
|
||||
*
|
||||
* We check whether this is a CAN or CAN FD frame
|
||||
* by checking whether the device's hardware type
|
||||
* is ARPHRD_CAN.
|
||||
* We check whether this is a CAN frame by checking whether
|
||||
* the device's hardware type is ARPHRD_CAN.
|
||||
*/
|
||||
if (sll->sll_hatype == ARPHRD_CAN &&
|
||||
handle->direction != PCAP_D_OUT)
|
||||
|
|
@ -1925,8 +2062,8 @@ static int map_arphrd_to_dlt(pcap_t *handle, int arptype,
|
|||
if (ret == 1) {
|
||||
/*
|
||||
* This is a DSA master/management network
|
||||
* device linktype is already set by
|
||||
* iface_dsa_get_proto_info() set an
|
||||
* device, linktype is already set by
|
||||
* iface_dsa_get_proto_info(), set an
|
||||
* appropriate offset here.
|
||||
*/
|
||||
handle->offset = 2;
|
||||
|
|
@ -2218,7 +2355,7 @@ static int map_arphrd_to_dlt(pcap_t *handle, int arptype,
|
|||
*
|
||||
* https://github.com/mcr/libpcap/pull/29
|
||||
*
|
||||
* There doesn't seem to be any network drivers that uses
|
||||
* There don't seem to be any network drivers that uses
|
||||
* any of the ARPHRD_FC* values for IP-over-FC, and
|
||||
* it's not exactly clear what the "Dummy types for non
|
||||
* ARP hardware" are supposed to mean (link-layer
|
||||
|
|
@ -2374,9 +2511,9 @@ setup_socket(pcap_t *handle, int is_any_device)
|
|||
* Other error.
|
||||
*/
|
||||
status = PCAP_ERROR;
|
||||
pcapint_fmt_errmsg_for_errno(handle->errbuf,
|
||||
PCAP_ERRBUF_SIZE, errno, "socket");
|
||||
}
|
||||
pcapint_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
errno, "socket");
|
||||
return status;
|
||||
}
|
||||
|
||||
|
|
@ -2564,6 +2701,7 @@ setup_socket(pcap_t *handle, int is_any_device)
|
|||
if (handle->dlt_list == NULL) {
|
||||
pcapint_fmt_errmsg_for_errno(handle->errbuf,
|
||||
PCAP_ERRBUF_SIZE, errno, "malloc");
|
||||
close(sock_fd);
|
||||
return (PCAP_ERROR);
|
||||
}
|
||||
handle->dlt_list[0] = DLT_LINUX_SLL;
|
||||
|
|
@ -4810,18 +4948,40 @@ enter_rfmon_mode(pcap_t *handle, int sock_fd, const char *device)
|
|||
if (ret == 0)
|
||||
return 0; /* no error, but not mac80211 device */
|
||||
|
||||
/*
|
||||
* XXX - is this already a monN device?
|
||||
* If so, we're done.
|
||||
*/
|
||||
|
||||
/*
|
||||
* OK, it's apparently a mac80211 device.
|
||||
* Try to find an unused monN device for it.
|
||||
*/
|
||||
ret = nl80211_init(handle, &nlstate, device);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* Is this already a monN device?
|
||||
* If so, we're done.
|
||||
*/
|
||||
int type;
|
||||
ret = get_if_type(handle, sock_fd, &nlstate, device, &type);
|
||||
if (ret <= 0) {
|
||||
/*
|
||||
* < 0 is a Hard failure. Just return ret; handle->errbuf
|
||||
* has already been set.
|
||||
*
|
||||
* 0 is "device not available"; the caller should retry later.
|
||||
*/
|
||||
nl80211_cleanup(&nlstate);
|
||||
return ret;
|
||||
}
|
||||
if (type == NL80211_IFTYPE_MONITOR) {
|
||||
/*
|
||||
* OK, it's already a monitor mode device; just use it.
|
||||
* There's no point in creating another monitor device
|
||||
* that will have to be cleaned up.
|
||||
*/
|
||||
nl80211_cleanup(&nlstate);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* OK, it's apparently a mac80211 device but not a monitor device.
|
||||
* Try to find an unused monN device for it.
|
||||
*/
|
||||
for (n = 0; n < UINT_MAX; n++) {
|
||||
/*
|
||||
* Try mon{n}.
|
||||
|
|
@ -5267,22 +5427,294 @@ iface_get_offload(pcap_t *handle _U_)
|
|||
}
|
||||
#endif /* SIOCETHTOOL */
|
||||
|
||||
/*
|
||||
* As per
|
||||
*
|
||||
* https://www.kernel.org/doc/html/latest/networking/dsa/dsa.html#switch-tagging-protocols
|
||||
*
|
||||
* Type 1 means that the tag is prepended to the Ethernet packet.
|
||||
*
|
||||
* Type 2 means that the tag is inserted into the Ethernet header
|
||||
* after the source address and before the type/length field.
|
||||
*
|
||||
* Type 3 means that tag is a packet trailer.
|
||||
*
|
||||
* Every element in the array below uses a DLT. Because a DSA-tagged frame is
|
||||
* not a standard IEEE 802.3 Ethernet frame, the array elements must not use
|
||||
* DLT_EN10MB. It is safe, albeit only barely useful, to use DLT_DEBUG_ONLY,
|
||||
* which is also the implicit default for any DSA tag that is not present in
|
||||
* the array. To implement proper support for a particular DSA tag of
|
||||
* interest, please do as much of the following as is reasonably practicable:
|
||||
*
|
||||
* 1. Using recent versions of tcpdump and libpcap on a Linux host with a
|
||||
* network interface that implements the required DSA tag, capture packets
|
||||
* on the interface and study the hex dumps.
|
||||
* 2. Using the hex dumps and any other available supporting materials, produce
|
||||
* a sufficiently detailed description of the DSA tag structure, complete
|
||||
* with a full comment indicating whether it's type 1, 2, or 3, and, for
|
||||
* type 2, indicating whether it has an Ethertype and, if so, what that type
|
||||
* is, and whether it's registered with the IEEE or not. Refer to the
|
||||
* specification(s), existing implementation(s), or any other relevant
|
||||
* resources.
|
||||
* 3. Using the description, request and obtain a new DLT for the DSA tag.
|
||||
* 4. Associate the new DLT with the DSA tag in the array below.
|
||||
* 5. Using the updated libpcap, capture packets again, produce a .pcap file
|
||||
* and confirm it uses the new DLT.
|
||||
* 6. Using the .pcap file as a test, prepare additional changes to tcpdump to
|
||||
* enable decoding of packets for the new DLT.
|
||||
* 7. Using the .pcap file as a test, prepare additional changes to libpcap to
|
||||
* enable filtering of packets for the new DLT.
|
||||
*
|
||||
* For working examples of such support, see the existing DLTs other than
|
||||
* DLT_DEBUG_ONLY in the array below.
|
||||
*/
|
||||
static struct dsa_proto {
|
||||
const char *name;
|
||||
bpf_u_int32 linktype;
|
||||
} dsa_protos[] = {
|
||||
/*
|
||||
* None is special and indicates that the interface does not have
|
||||
* any tagging protocol configured, and is therefore a standard
|
||||
* Ethernet interface.
|
||||
* Type 1. See
|
||||
*
|
||||
* https://elixir.bootlin.com/linux/v6.13.2/source/net/dsa/tag_ar9331.c
|
||||
*/
|
||||
{ "ar9331", DLT_DEBUG_ONLY },
|
||||
|
||||
/*
|
||||
* Type 2, without an EtherType at the beginning.
|
||||
*/
|
||||
{ "none", DLT_EN10MB },
|
||||
{ "brcm", DLT_DSA_TAG_BRCM },
|
||||
|
||||
/*
|
||||
* Type 2, with EtherType 0x8874, assigned to Broadcom.
|
||||
*/
|
||||
{ "brcm-legacy", DLT_DEBUG_ONLY },
|
||||
|
||||
/*
|
||||
* Type 1.
|
||||
*/
|
||||
{ "brcm-prepend", DLT_DSA_TAG_BRCM_PREPEND },
|
||||
|
||||
/*
|
||||
* Type 2, without an EtherType at the beginning.
|
||||
*/
|
||||
{ "dsa", DLT_DSA_TAG_DSA },
|
||||
|
||||
/*
|
||||
* Type 2, with an Ethertype field, but without
|
||||
* an assigned EtherType value that can be relied
|
||||
* on.
|
||||
*/
|
||||
{ "edsa", DLT_DSA_TAG_EDSA },
|
||||
|
||||
/*
|
||||
* Type 1, with different transmit and receive headers,
|
||||
* so can't really be handled well with the current
|
||||
* libpcap API and with pcap files.
|
||||
*
|
||||
* See
|
||||
*
|
||||
* https://elixir.bootlin.com/linux/v6.13.2/source/net/dsa/tag_gswip.c
|
||||
*/
|
||||
{ "gswip", DLT_DEBUG_ONLY },
|
||||
|
||||
/*
|
||||
* Type 3. See
|
||||
*
|
||||
* https://elixir.bootlin.com/linux/v6.13.2/source/net/dsa/tag_hellcreek.c
|
||||
*/
|
||||
{ "hellcreek", DLT_DEBUG_ONLY },
|
||||
|
||||
/*
|
||||
* Type 3, with different transmit and receive headers,
|
||||
* so can't really be handled well with the current
|
||||
* libpcap API and with pcap files.
|
||||
*
|
||||
* See
|
||||
*
|
||||
* https://elixir.bootlin.com/linux/v6.13.2/source/net/dsa/tag_ksz.c#L102
|
||||
*/
|
||||
{ "ksz8795", DLT_DEBUG_ONLY },
|
||||
|
||||
/*
|
||||
* Type 3, with different transmit and receive headers,
|
||||
* so can't really be handled well with the current
|
||||
* libpcap API and with pcap files.
|
||||
*
|
||||
* See
|
||||
*
|
||||
* https://elixir.bootlin.com/linux/v6.13.2/source/net/dsa/tag_ksz.c#L160
|
||||
*/
|
||||
{ "ksz9477", DLT_DEBUG_ONLY },
|
||||
|
||||
/*
|
||||
* Type 3, with different transmit and receive headers,
|
||||
* so can't really be handled well with the current
|
||||
* libpcap API and with pcap files.
|
||||
*
|
||||
* See
|
||||
*
|
||||
* https://elixir.bootlin.com/linux/v6.13.2/source/net/dsa/tag_ksz.c#L341
|
||||
*/
|
||||
{ "ksz9893", DLT_DEBUG_ONLY },
|
||||
|
||||
/*
|
||||
* Type 3, with different transmit and receive headers,
|
||||
* so can't really be handled well with the current
|
||||
* libpcap API and with pcap files.
|
||||
*
|
||||
* See
|
||||
*
|
||||
* https://elixir.bootlin.com/linux/v6.13.2/source/net/dsa/tag_ksz.c#L386
|
||||
*/
|
||||
{ "lan937x", DLT_DEBUG_ONLY },
|
||||
|
||||
/*
|
||||
* Type 2, with EtherType 0x8100; the VID can be interpreted
|
||||
* as per
|
||||
*
|
||||
* https://elixir.bootlin.com/linux/v6.13.2/source/net/dsa/tag_lan9303.c#L24
|
||||
*/
|
||||
{ "lan9303", DLT_DEBUG_ONLY },
|
||||
|
||||
/*
|
||||
* Type 2, without an EtherType at the beginning.
|
||||
*
|
||||
* See
|
||||
*
|
||||
* https://elixir.bootlin.com/linux/v6.13.2/source/net/dsa/tag_mtk.c#L15
|
||||
*
|
||||
* Linux kernel implements this tag so that it does not indicate the frame
|
||||
* encoding reliably. The matter is, some drivers use METADATA_HW_PORT_MUX,
|
||||
* which (for the switch->CPU direction only, at the time of this writing)
|
||||
* means that the frame does not have a DSA tag, the frame metadata is stored
|
||||
* elsewhere and libpcap receives the frame only. Specifically, this is the
|
||||
* case for drivers/net/ethernet/mediatek/mtk_eth_soc.c, but the tag visible
|
||||
* in sysfs is still "mtk" even though the wire encoding is different.
|
||||
*/
|
||||
{ "mtk", DLT_DEBUG_ONLY },
|
||||
|
||||
/*
|
||||
* Type 1.
|
||||
*
|
||||
* See
|
||||
*
|
||||
* https://elixir.bootlin.com/linux/v6.13.2/source/net/dsa/tag_ocelot.c
|
||||
*/
|
||||
{ "ocelot", DLT_DEBUG_ONLY },
|
||||
|
||||
/*
|
||||
* Type 1.
|
||||
*
|
||||
* See
|
||||
*
|
||||
* https://elixir.bootlin.com/linux/v6.13.2/source/net/dsa/tag_ocelot.c
|
||||
*/
|
||||
{ "seville", DLT_DEBUG_ONLY },
|
||||
|
||||
/*
|
||||
* Type 2, with EtherType 0x8100; the VID can be interpreted
|
||||
* as per
|
||||
*
|
||||
* https://elixir.bootlin.com/linux/v6.13.2/source/net/dsa/tag_8021q.c#L15
|
||||
*/
|
||||
{ "ocelot-8021q", DLT_DEBUG_ONLY },
|
||||
|
||||
/*
|
||||
* Type 2, without an EtherType at the beginning.
|
||||
*
|
||||
* See
|
||||
*
|
||||
* https://elixir.bootlin.com/linux/v6.13.2/source/net/dsa/tag_qca.c
|
||||
*/
|
||||
{ "qca", DLT_DEBUG_ONLY },
|
||||
|
||||
/*
|
||||
* Type 2, with EtherType 0x8899, assigned to Realtek;
|
||||
* they use it for several on-the-Ethernet protocols
|
||||
* as well, but there are fields that allow the two
|
||||
* tag formats, and all the protocols in question,
|
||||
* to be distinguiished from one another.
|
||||
*
|
||||
* See
|
||||
*
|
||||
* https://elixir.bootlin.com/linux/v6.13.2/source/net/dsa/tag_rtl4_a.c
|
||||
*
|
||||
* http://realtek.info/pdf/rtl8306sd%28m%29_datasheet_1.1.pdf
|
||||
*
|
||||
* and various pages in tcpdump's print-realtek.c and Wireshark's
|
||||
* epan/dissectors/packet-realtek.c for the other protocols.
|
||||
*/
|
||||
{ "rtl4a", DLT_DEBUG_ONLY },
|
||||
|
||||
/*
|
||||
* Type 2, with EtherType 0x8899, assigned to Realtek;
|
||||
* see above.
|
||||
*/
|
||||
{ "rtl8_4", DLT_DEBUG_ONLY },
|
||||
|
||||
/*
|
||||
* Type 3, with the same tag format as rtl8_4.
|
||||
*/
|
||||
{ "rtl8_4t", DLT_DEBUG_ONLY },
|
||||
|
||||
/*
|
||||
* Type 2, with EtherType 0xe001; that's probably
|
||||
* self-assigned.
|
||||
*
|
||||
* See
|
||||
*
|
||||
* https://elixir.bootlin.com/linux/v6.13.2/source/net/dsa/tag_rzn1_a5psw.c
|
||||
*/
|
||||
{ "a5psw", DLT_DEBUG_ONLY },
|
||||
|
||||
/*
|
||||
* Type 2, with EtherType 0x8100 or the self-assigned
|
||||
* 0xdadb, so this really should have its own
|
||||
* LINKTYPE_/DLT_ value; that would also allow the
|
||||
* VID of the tag to be dissected as per
|
||||
*
|
||||
* https://elixir.bootlin.com/linux/v6.13.2/source/net/dsa/tag_8021q.c#L15
|
||||
*/
|
||||
{ "sja1105", DLT_DEBUG_ONLY },
|
||||
|
||||
/*
|
||||
* Type "none of the above", with both a header and trailer,
|
||||
* with different transmit and receive tags. Has
|
||||
* EtherType 0xdadc, which is probably self-assigned.
|
||||
*/
|
||||
{ "sja1110", DLT_DEBUG_ONLY },
|
||||
|
||||
/*
|
||||
* Type 3, as the name suggests.
|
||||
*
|
||||
* See
|
||||
*
|
||||
* https://elixir.bootlin.com/linux/v6.13.2/source/net/dsa/tag_trailer.c
|
||||
*/
|
||||
{ "trailer", DLT_DEBUG_ONLY },
|
||||
|
||||
/*
|
||||
* Type 2, with EtherType 0x8100; the VID can be interpreted
|
||||
* as per
|
||||
*
|
||||
* https://elixir.bootlin.com/linux/v6.13.2/source/net/dsa/tag_8021q.c#L15
|
||||
*/
|
||||
{ "vsc73xx-8021q", DLT_DEBUG_ONLY },
|
||||
|
||||
/*
|
||||
* Type 3.
|
||||
*
|
||||
* See
|
||||
*
|
||||
* https://elixir.bootlin.com/linux/v6.13.2/source/net/dsa/tag_xrs700x.c
|
||||
*/
|
||||
{ "xrs700x", DLT_DEBUG_ONLY },
|
||||
};
|
||||
|
||||
/*
|
||||
* Return 1 if the interface uses DSA tagging, 0 if the interface does not use
|
||||
* DSA tagging, or PCAP_ERROR on error.
|
||||
*/
|
||||
static int
|
||||
iface_dsa_get_proto_info(const char *device, pcap_t *handle)
|
||||
{
|
||||
|
|
@ -5309,10 +5741,18 @@ iface_dsa_get_proto_info(const char *device, pcap_t *handle)
|
|||
fd = open(pathstr, O_RDONLY);
|
||||
free(pathstr);
|
||||
/*
|
||||
* This is not fatal, kernel >= 4.20 *might* expose this attribute
|
||||
* This could be not fatal: kernel >= 4.20 *might* expose this
|
||||
* attribute. However, if it exposes the attribute, but the read has
|
||||
* failed due to another reason (ENFILE, EMFILE, ENOMEM...), propagate
|
||||
* the failure.
|
||||
*/
|
||||
if (fd < 0)
|
||||
return 0;
|
||||
if (fd < 0) {
|
||||
if (errno == ENOENT)
|
||||
return 0;
|
||||
pcapint_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
errno, "open");
|
||||
return PCAP_ERROR;
|
||||
}
|
||||
|
||||
r = read(fd, buf, sizeof(buf) - 1);
|
||||
if (r <= 0) {
|
||||
|
|
@ -5330,23 +5770,41 @@ iface_dsa_get_proto_info(const char *device, pcap_t *handle)
|
|||
r--;
|
||||
buf[r] = '\0';
|
||||
|
||||
/*
|
||||
* The string "none" indicates that the interface does not have
|
||||
* any tagging protocol configured, and is therefore a standard
|
||||
* Ethernet interface.
|
||||
*/
|
||||
if (strcmp(buf, "none") == 0)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Every element in the array stands for a DSA-tagged interface. Using
|
||||
* DLT_EN10MB (the standard IEEE 802.3 Ethernet) for such an interface
|
||||
* may seem a good idea at first, but doing so would certainly cause
|
||||
* major problems in areas that are already complicated and depend on
|
||||
* DLT_EN10MB meaning the standard IEEE 802.3 Ethernet only, namely:
|
||||
*
|
||||
* - live capturing of packets on Linux, and
|
||||
* - live kernel filtering of packets on Linux, and
|
||||
* - live userspace filtering of packets on Linux, and
|
||||
* - offline filtering of packets on all supported OSes, and
|
||||
* - identification of savefiles on all OSes.
|
||||
*
|
||||
* Therefore use a default DLT value that does not block capturing and
|
||||
* hexdumping of unsupported DSA encodings (in case the tag is not in
|
||||
* the array) and enforce the non-use of DLT_EN10MB (in case the tag is
|
||||
* in the array, but is incorrectly declared).
|
||||
*/
|
||||
handle->linktype = DLT_DEBUG_ONLY;
|
||||
for (i = 0; i < sizeof(dsa_protos) / sizeof(dsa_protos[0]); i++) {
|
||||
if (strlen(dsa_protos[i].name) == (size_t)r &&
|
||||
strcmp(buf, dsa_protos[i].name) == 0) {
|
||||
handle->linktype = dsa_protos[i].linktype;
|
||||
switch (dsa_protos[i].linktype) {
|
||||
case DLT_EN10MB:
|
||||
return 0;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
if (strcmp(buf, dsa_protos[i].name) == 0) {
|
||||
if (dsa_protos[i].linktype != DLT_EN10MB)
|
||||
handle->linktype = dsa_protos[i].linktype;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"unsupported DSA tag: %s", buf);
|
||||
|
||||
return PCAP_ERROR;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -5724,12 +6182,18 @@ pcap_set_protocol_linux(pcap_t *p, int protocol)
|
|||
/*
|
||||
* Libpcap version string.
|
||||
*/
|
||||
#if defined(HAVE_TPACKET3) && defined(PCAP_SUPPORT_NETMAP)
|
||||
#define ADDITIONAL_INFO_STRING "with TPACKET_V3 and netmap"
|
||||
#elif defined(HAVE_TPACKET3)
|
||||
#define ADDITIONAL_INFO_STRING "with TPACKET_V3"
|
||||
#elif defined(PCAP_SUPPORT_NETMAP)
|
||||
#define ADDITIONAL_INFO_STRING "with TPACKET_V2 and netmap"
|
||||
#else
|
||||
#define ADDITIONAL_INFO_STRING "with TPACKET_V2"
|
||||
#endif
|
||||
|
||||
const char *
|
||||
pcap_lib_version(void)
|
||||
{
|
||||
#if defined(HAVE_TPACKET3)
|
||||
return (PCAP_VERSION_STRING " (with TPACKET_V3)");
|
||||
#else
|
||||
return (PCAP_VERSION_STRING " (with TPACKET_V2)");
|
||||
#endif
|
||||
return (PCAP_VERSION_STRING_WITH_ADDITIONAL_INFO(ADDITIONAL_INFO_STRING));
|
||||
}
|
||||
|
|
|
|||
54
pcap-new.c
54
pcap-new.c
|
|
@ -85,6 +85,12 @@ int pcap_findalldevs_ex(const char *source, struct pcap_rmtauth *auth, pcap_if_t
|
|||
(*alldevs) = NULL;
|
||||
lastdev = NULL;
|
||||
|
||||
if (source == NULL)
|
||||
{
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"The source string must not be NULL.");
|
||||
return -1;
|
||||
}
|
||||
if (strlen(source) > PCAP_BUF_SIZE)
|
||||
{
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE, "The source string is too long. Cannot handle it correctly.");
|
||||
|
|
@ -93,21 +99,23 @@ int pcap_findalldevs_ex(const char *source, struct pcap_rmtauth *auth, pcap_if_t
|
|||
|
||||
/*
|
||||
* Determine the type of the source (file, local, remote)
|
||||
* There are some differences if pcap_findalldevs_ex() is called to list files and remote adapters.
|
||||
* In the first case, the name of the directory we have to look into must be present (therefore
|
||||
* the 'name' parameter of the pcap_parsesrcstr() is present).
|
||||
* In the second case, the name of the adapter is not required (we need just the host). So, we have
|
||||
* to use a first time this function to get the source type, and a second time to get the appropriate
|
||||
* info, which depends on the source type.
|
||||
*
|
||||
* To list files in a local directory, the source string must specify
|
||||
* the directory name. To list local or remote capture devices, the
|
||||
* source string must not specify a device name. Retrieve the name
|
||||
* component now and validate it for each source type next.
|
||||
*/
|
||||
if (pcap_parsesrcstr(source, &type, NULL, NULL, NULL, errbuf) == -1)
|
||||
if (pcap_parsesrcstr(source, &type, NULL, NULL, name, errbuf) == -1)
|
||||
return -1;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case PCAP_SRC_IFLOCAL:
|
||||
if (pcap_parsesrcstr(source, &type, NULL, NULL, NULL, errbuf) == -1)
|
||||
if (strlen(name)) {
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"To list local capture devices, the source string must not include a device name.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Initialize temporary string */
|
||||
tmpstring[PCAP_BUF_SIZE] = 0;
|
||||
|
|
@ -186,12 +194,15 @@ int pcap_findalldevs_ex(const char *source, struct pcap_rmtauth *auth, pcap_if_t
|
|||
DIR *unixdir;
|
||||
#endif
|
||||
|
||||
if (pcap_parsesrcstr(source, &type, NULL, NULL, name, errbuf) == -1)
|
||||
return -1;
|
||||
|
||||
/* Check that the filename is correct */
|
||||
stringlen = strlen(name);
|
||||
|
||||
if (! stringlen) {
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"To list local files, the source string must include a directory.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* The directory must end with '\' in Win32 and '/' in UNIX */
|
||||
#ifdef _WIN32
|
||||
#define ENDING_CHAR '\\'
|
||||
|
|
@ -378,6 +389,12 @@ int pcap_findalldevs_ex(const char *source, struct pcap_rmtauth *auth, pcap_if_t
|
|||
}
|
||||
|
||||
case PCAP_SRC_IFREMOTE:
|
||||
if (strlen(name)) {
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"To list remote capture devices, the source string must not include a device name.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return pcap_findalldevs_ex_remote(source, auth, alldevs, errbuf);
|
||||
|
||||
default:
|
||||
|
|
@ -419,13 +436,28 @@ pcap_t *pcap_open(const char *source, int snaplen, int flags, int read_timeout,
|
|||
switch (type)
|
||||
{
|
||||
case PCAP_SRC_FILE:
|
||||
if (! strlen(name)) {
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"To open a local file, the source string must include the file path.");
|
||||
return NULL;
|
||||
}
|
||||
return pcap_open_offline(name, errbuf);
|
||||
|
||||
case PCAP_SRC_IFLOCAL:
|
||||
if (! strlen(name)) {
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"To open a local capture device, the source string must include the device name.");
|
||||
return NULL;
|
||||
}
|
||||
fp = pcap_create(name, errbuf);
|
||||
break;
|
||||
|
||||
case PCAP_SRC_IFREMOTE:
|
||||
if (! strlen(name)) {
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"To open a remote capture device, the source string must include the device name.");
|
||||
return NULL;
|
||||
}
|
||||
/*
|
||||
* Although we already have host, port and iface, we prefer
|
||||
* to pass only 'source' to pcap_open_rpcap(), so that it
|
||||
|
|
|
|||
100
pcap-npf.c
100
pcap-npf.c
|
|
@ -196,6 +196,10 @@ PacketGetMonitorMode(PCHAR AdapterName _U_)
|
|||
#define NDIS_STATUS_NOT_SUPPORTED 0xc00000bb /* STATUS_NOT_SUPPORTED */
|
||||
#define NDIS_STATUS_NOT_RECOGNIZED 0x00010001
|
||||
|
||||
#ifndef PACKET_OID_DATA_LENGTH
|
||||
#define PACKET_OID_DATA_LENGTH(_DataLength) \
|
||||
(offsetof(PACKET_OID_DATA, Data) + _DataLength)
|
||||
#endif
|
||||
static int
|
||||
oid_get_request(ADAPTER *adapter, bpf_u_int32 oid, void *data, size_t *lenp,
|
||||
char *errbuf)
|
||||
|
|
@ -204,12 +208,9 @@ oid_get_request(ADAPTER *adapter, bpf_u_int32 oid, void *data, size_t *lenp,
|
|||
|
||||
/*
|
||||
* Allocate a PACKET_OID_DATA structure to hand to PacketRequest().
|
||||
* It should be big enough to hold "*lenp" bytes of data; it
|
||||
* will actually be slightly larger, as PACKET_OID_DATA has a
|
||||
* 1-byte data array at the end, standing in for the variable-length
|
||||
* data that's actually there.
|
||||
* It should be big enough to hold "*lenp" bytes of data;
|
||||
*/
|
||||
oid_data_arg = malloc(sizeof (PACKET_OID_DATA) + *lenp);
|
||||
oid_data_arg = malloc(PACKET_OID_DATA_LENGTH(*lenp));
|
||||
if (oid_data_arg == NULL) {
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Couldn't allocate argument buffer for PacketRequest");
|
||||
|
|
@ -404,12 +405,9 @@ pcap_oid_set_request_npf(pcap_t *p, bpf_u_int32 oid, const void *data,
|
|||
|
||||
/*
|
||||
* Allocate a PACKET_OID_DATA structure to hand to PacketRequest().
|
||||
* It should be big enough to hold "*lenp" bytes of data; it
|
||||
* will actually be slightly larger, as PACKET_OID_DATA has a
|
||||
* 1-byte data array at the end, standing in for the variable-length
|
||||
* data that's actually there.
|
||||
* It should be big enough to hold "*lenp" bytes of data;
|
||||
*/
|
||||
oid_data_arg = malloc(sizeof (PACKET_OID_DATA) + *lenp);
|
||||
oid_data_arg = malloc(PACKET_OID_DATA_LENGTH(*lenp));
|
||||
if (oid_data_arg == NULL) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Couldn't allocate argument buffer for PacketRequest");
|
||||
|
|
@ -1033,6 +1031,10 @@ pcap_activate_npf(pcap_t *p)
|
|||
int status = 0;
|
||||
struct bpf_insn total_insn;
|
||||
struct bpf_program total_prog;
|
||||
#ifdef HAVE_PACKET_GET_INFO
|
||||
char oid_data_buf[PACKET_OID_DATA_LENGTH(sizeof(ULONG))] = {0};
|
||||
PACKET_OID_DATA *oid_data_arg = (PACKET_OID_DATA *)oid_data_buf;
|
||||
#endif
|
||||
|
||||
if (p->opt.rfmon) {
|
||||
/*
|
||||
|
|
@ -1292,6 +1294,42 @@ pcap_activate_npf(pcap_t *p)
|
|||
}
|
||||
#endif /* HAVE_PACKET_GET_TIMESTAMP_MODES */
|
||||
|
||||
#ifdef PACKET_MODE_NANO
|
||||
/*
|
||||
* If nanosecond timestamp resolution is requested, set
|
||||
* the packet mode to enable it.
|
||||
*
|
||||
* XXX - it's not nanosecond resolution, as the internal
|
||||
* NT clock has 100 ns resolution, but we can't indicate
|
||||
* that. An updated-for-pcapng API should support that.
|
||||
*/
|
||||
if (p->opt.tstamp_precision == PCAP_TSTAMP_PRECISION_NANO) {
|
||||
res = PacketSetMode(pw->adapter, PACKET_MODE_NANO);
|
||||
if(res == FALSE){
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Error setting nanosecond capture mode");
|
||||
goto bad;
|
||||
}
|
||||
}
|
||||
#endif /* PACKET_MODE_NANO */
|
||||
|
||||
#if defined(HAVE_PACKET_GET_INFO) && defined(NPF_GETINFO_BPFEXT) && defined(SKF_AD_VLAN_TAG_PRESENT)
|
||||
|
||||
/* Can we generate special code for VLAN checks? */
|
||||
oid_data_arg->Oid = NPF_GETINFO_BPFEXT;
|
||||
oid_data_arg->Length = sizeof(ULONG);
|
||||
if (PacketGetInfo(pw->adapter, oid_data_arg)) {
|
||||
if (*((ULONG *)oid_data_arg->Data) >= SKF_AD_VLAN_TAG_PRESENT) {
|
||||
/* Yes, we can. Request that we do so. */
|
||||
p->bpf_codegen_flags |= BPF_SPECIAL_VLAN_HANDLING;
|
||||
}
|
||||
}
|
||||
else {
|
||||
pcapint_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
GetLastError(), "Error calling PacketGetInfo");
|
||||
}
|
||||
#endif /* HAVE_PACKET_GET_INFO */
|
||||
|
||||
/*
|
||||
* Turn a negative snapshot value (invalid), a snapshot value of
|
||||
* 0 (unspecified), or a value bigger than the normal maximum
|
||||
|
|
@ -1613,11 +1651,11 @@ pcap_can_set_rfmon_npf(pcap_t *p)
|
|||
}
|
||||
|
||||
/*
|
||||
* Get a list of time stamp types.
|
||||
* Get lists of time stamp types and precisions.
|
||||
*/
|
||||
#ifdef HAVE_PACKET_GET_TIMESTAMP_MODES
|
||||
static int
|
||||
get_ts_types(const char *device, pcap_t *p, char *ebuf)
|
||||
get_ts_support(const char *device, pcap_t *p, char *ebuf)
|
||||
{
|
||||
char *device_copy = NULL;
|
||||
ADAPTER *adapter = NULL;
|
||||
|
|
@ -1632,6 +1670,12 @@ get_ts_types(const char *device, pcap_t *p, char *ebuf)
|
|||
ULONG *modes = NULL;
|
||||
int status = 0;
|
||||
|
||||
/*
|
||||
* This is called in pcapint_create_interface(), after the
|
||||
* pcap_t is allocated and initialized, so the time stamp
|
||||
* type list and the time stamp precision lists are both
|
||||
* empty.
|
||||
*/
|
||||
do {
|
||||
/*
|
||||
* First, find out how many time stamp modes we have.
|
||||
|
|
@ -1683,8 +1727,6 @@ get_ts_types(const char *device, pcap_t *p, char *ebuf)
|
|||
*/
|
||||
if (error == ERROR_BAD_UNIT ||
|
||||
error == ERROR_ACCESS_DENIED) {
|
||||
p->tstamp_type_count = 0;
|
||||
p->tstamp_type_list = NULL;
|
||||
status = 0;
|
||||
} else {
|
||||
pcapint_fmt_errmsg_for_win32_err(ebuf,
|
||||
|
|
@ -1692,6 +1734,10 @@ get_ts_types(const char *device, pcap_t *p, char *ebuf)
|
|||
"Error opening adapter");
|
||||
status = -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* We're done; clean up and return the status.
|
||||
*/
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -1865,6 +1911,25 @@ get_ts_types(const char *device, pcap_t *p, char *ebuf)
|
|||
}
|
||||
}
|
||||
p->tstamp_type_count = num_ts_types;
|
||||
|
||||
#ifdef PACKET_MODE_NANO
|
||||
/*
|
||||
* Check if we support nanosecond time stamps.
|
||||
*/
|
||||
if (PacketSetMode(adapter, PACKET_MODE_NANO)) {
|
||||
p->tstamp_precision_list = malloc(2 * sizeof(u_int));
|
||||
if (p->tstamp_precision_list == NULL) {
|
||||
pcapint_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
|
||||
errno, "malloc");
|
||||
pcap_close(p);
|
||||
return (NULL);
|
||||
}
|
||||
p->tstamp_precision_list[0] = PCAP_TSTAMP_PRECISION_MICRO;
|
||||
p->tstamp_precision_list[1] = PCAP_TSTAMP_PRECISION_NANO;
|
||||
p->tstamp_precision_count = 2;
|
||||
}
|
||||
#endif /* PACKET_MODE_NANO */
|
||||
|
||||
} while (0);
|
||||
|
||||
/* Clean up temporary allocations */
|
||||
|
|
@ -1882,7 +1947,7 @@ get_ts_types(const char *device, pcap_t *p, char *ebuf)
|
|||
}
|
||||
#else /* HAVE_PACKET_GET_TIMESTAMP_MODES */
|
||||
static int
|
||||
get_ts_types(const char *device _U_, pcap_t *p _U_, char *ebuf _U_)
|
||||
get_ts_support(const char *device _U_, pcap_t *p _U_, char *ebuf _U_)
|
||||
{
|
||||
/*
|
||||
* Nothing to fetch, so it always "succeeds".
|
||||
|
|
@ -1903,10 +1968,11 @@ pcapint_create_interface(const char *device _U_, char *ebuf)
|
|||
p->activate_op = pcap_activate_npf;
|
||||
p->can_set_rfmon_op = pcap_can_set_rfmon_npf;
|
||||
|
||||
if (get_ts_types(device, p, ebuf) == -1) {
|
||||
if (get_ts_support(device, p, ebuf) == -1) {
|
||||
pcap_close(p);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
return (p);
|
||||
}
|
||||
|
||||
|
|
@ -2766,7 +2832,7 @@ pcap_lib_version(void)
|
|||
char *full_pcap_version_string;
|
||||
|
||||
if (pcapint_asprintf(&full_pcap_version_string,
|
||||
PCAP_VERSION_STRING " (packet.dll version %s)",
|
||||
PCAP_VERSION_STRING_WITH_ADDITIONAL_INFO("packet.dll version %s"),
|
||||
PacketGetVersion()) != -1) {
|
||||
/* Success */
|
||||
pcap_lib_version_string = full_pcap_version_string;
|
||||
|
|
|
|||
|
|
@ -267,7 +267,7 @@ static int rpcap_read_packet_msg(struct pcap_rpcap const *, pcap_t *p, size_t si
|
|||
|
||||
/*
|
||||
* Possible IPv4 family values other than the designated over-the-wire value,
|
||||
* which is 2 (because everybody, except for Haiku uses 2 for AF_INET,
|
||||
* which is 2 (because everybody, except for Haiku, uses 2 for AF_INET,
|
||||
* and Haiku has probably never run the old rpcapd code that put address
|
||||
* structures directly on the wire, rather than the new rpcapd code
|
||||
* that serializes addresses, using 2 for AF_INET).
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
.\"
|
||||
.TH PCAP-SAVEFILE @MAN_FILE_FORMATS@ "16 Aug 2023"
|
||||
.TH PCAP-SAVEFILE @MAN_FILE_FORMATS@ "6 Jan 2025"
|
||||
.SH NAME
|
||||
pcap-savefile \- libpcap savefile format
|
||||
.SH DESCRIPTION
|
||||
|
|
@ -55,19 +55,30 @@ The per-file header length is 24 octets.
|
|||
.PP
|
||||
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
|
||||
4-byte magic number, with the value 0xa1b2c3d4. The magic number, when
|
||||
4-byte magic number, with the value
|
||||
.BR 0xa1b2c3d4 .
|
||||
The magic number, when
|
||||
read by a host with the same byte order as the host that wrote the file,
|
||||
will have the value 0xa1b2c3d4, and, when read by a host with the
|
||||
will have the value
|
||||
.BR 0xa1b2c3d4 ,
|
||||
and, when read by a host with the
|
||||
opposite byte order as the host that wrote the file, will have the value
|
||||
0xd4c3b2a1. That allows software reading the file to determine whether
|
||||
.BR 0xd4c3b2a1 .
|
||||
That allows software reading the file to determine whether
|
||||
the byte order of the host that wrote the file is the same as the byte
|
||||
order of the host on which the file is being read, and thus whether the
|
||||
values in the per-file and per-packet headers need to be byte-swapped.
|
||||
.PP
|
||||
If the magic number has the value 0xa1b23c4d (with the two nibbles of
|
||||
If the magic number has the value
|
||||
.B 0xa1b23c4d
|
||||
(with the two nibbles of
|
||||
the two lower-order bytes of the magic number swapped), which would be
|
||||
read as 0xa1b23c4d by a host with the same byte order as the host that
|
||||
wrote the file and as 0x4d3cb2a1 by a host with the opposite byte order
|
||||
read as
|
||||
.B 0xa1b23c4d
|
||||
by a host with the same byte order as the host that
|
||||
wrote the file and as
|
||||
.B 0x4d3cb2a1
|
||||
by a host with the opposite byte order
|
||||
as the host that wrote the file, the file format is the same as for
|
||||
regular files, except that the time stamps for packets are given in
|
||||
seconds and nanoseconds rather than seconds and microseconds.
|
||||
|
|
@ -75,10 +86,10 @@ seconds and nanoseconds rather than seconds and microseconds.
|
|||
Following this are:
|
||||
.IP
|
||||
A 2-byte file format major version number; the current version number is
|
||||
2.
|
||||
2 (big-endian 0x00 0x02 or little-endian 0x02 0x00).
|
||||
.IP
|
||||
A 2-byte file format minor version number; the current version number is
|
||||
4.
|
||||
4 (big-endian 0x00 0x04 or little-endian 0x04 0x00).
|
||||
.IP
|
||||
A 4-byte not used - SHOULD be filled with 0 by pcap file writers, and MUST
|
||||
be ignored by pcap file readers. This value was documented by some older
|
||||
|
|
|
|||
|
|
@ -312,8 +312,7 @@ pcapint_platform_finddevs(pcap_if_list_t *devlistp, char *errbuf)
|
|||
pcap_t *
|
||||
pcapint_create_interface(const char *device, char *errbuf)
|
||||
{
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"This version of libpcap only supports Septel cards");
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE, PCAP_ENODEV_MESSAGE, "Septel");
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -599,8 +599,7 @@ pcapint_platform_finddevs(pcap_if_list_t *devlistp, char *errbuf)
|
|||
pcap_t *
|
||||
pcapint_create_interface(const char *device, char *errbuf)
|
||||
{
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"This version of libpcap only supports SNF cards");
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE, PCAP_ENODEV_MESSAGE, "SNF");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -610,6 +609,6 @@ pcapint_create_interface(const char *device, char *errbuf)
|
|||
const char *
|
||||
pcap_lib_version(void)
|
||||
{
|
||||
return (PCAP_VERSION_STRING " (SNF-only)");
|
||||
return (PCAP_VERSION_STRING_WITH_ADDITIONAL_INFO("SNF-only"));
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
73
pcap.c
73
pcap.c
|
|
@ -1781,6 +1781,17 @@ pcap_parse_source(const char *source, char **schemep, char **userinfop,
|
|||
char *parsep, *atsignp, *bracketp;
|
||||
char *userinfo, *host, *port, *path;
|
||||
|
||||
if (source == NULL) {
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
||||
"The source string must not be NULL.");
|
||||
return (-1);
|
||||
}
|
||||
if (! strcmp(source, "")) {
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
||||
"The source string must not be empty.");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Start out returning nothing.
|
||||
*/
|
||||
|
|
@ -2271,19 +2282,16 @@ pcapint_parsesrcstr_ex(const char *source, int *type, char *host, char *port,
|
|||
}
|
||||
|
||||
/*
|
||||
* Neither rpcap: nor file:; just treat the entire string
|
||||
* as a local device.
|
||||
* The code above has already completely handled the case of no scheme,
|
||||
* as well as each case of a valid scheme.
|
||||
*/
|
||||
if (name)
|
||||
pcapint_strlcpy(name, source, PCAP_BUF_SIZE);
|
||||
if (type)
|
||||
*type = PCAP_SRC_IFLOCAL;
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE, "The source string URL scheme is not supported.");
|
||||
free(tmppath);
|
||||
free(tmpport);
|
||||
free(tmphost);
|
||||
free(tmpuserinfo);
|
||||
free(scheme);
|
||||
return (0);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
@ -3341,7 +3349,7 @@ static struct dlt_choice dlt_choices[] = {
|
|||
DLT_CHOICE(BLUETOOTH_BREDR_BB, "Bluetooth Basic Rate/Enhanced Data Rate baseband packets"),
|
||||
DLT_CHOICE(BLUETOOTH_LE_LL_WITH_PHDR, "Bluetooth Low Energy air interface with pseudo-header"),
|
||||
DLT_CHOICE(PROFIBUS_DL, "PROFIBUS data link layer"),
|
||||
DLT_CHOICE(PKTAP, "Apple DLT_PKTAP"),
|
||||
DLT_CHOICE(PKTAP, "Apple PKTAP"),
|
||||
DLT_CHOICE(EPON, "Ethernet with 802.3 Clause 65 EPON preamble"),
|
||||
DLT_CHOICE(IPMI_HPM_2, "IPMI trace packets"),
|
||||
DLT_CHOICE(ZWAVE_R1_R2, "Z-Wave RF profile R1 and R2 packets"),
|
||||
|
|
@ -3350,7 +3358,7 @@ static struct dlt_choice dlt_choices[] = {
|
|||
DLT_CHOICE(ISO_14443, "ISO 14443 messages"),
|
||||
DLT_CHOICE(RDS, "IEC 62106 Radio Data System groups"),
|
||||
DLT_CHOICE(USB_DARWIN, "USB with Darwin header"),
|
||||
DLT_CHOICE(OPENFLOW, "OpenBSD DLT_OPENFLOW"),
|
||||
DLT_CHOICE(OPENFLOW, "OpenBSD OpenFlow"),
|
||||
DLT_CHOICE(SDLC, "IBM SDLC frames"),
|
||||
DLT_CHOICE(TI_LLN_SNIFFER, "TI LLN sniffer frames"),
|
||||
DLT_CHOICE(VSOCK, "Linux vsock"),
|
||||
|
|
@ -3371,6 +3379,36 @@ static struct dlt_choice dlt_choices[] = {
|
|||
DLT_CHOICE(Z_WAVE_SERIAL, "Z-Wave serial frames between host and chip"),
|
||||
DLT_CHOICE(USB_2_0, "USB 2.0/1.1/1.0 as transmitted over the cable"),
|
||||
DLT_CHOICE(ATSC_ALP, "ATSC Link-Layer Protocol packets"),
|
||||
DLT_CHOICE(ETW, "Event Tracing for Windows messages"),
|
||||
DLT_CHOICE(NETANALYZER_NG, "Hilscher netANALYZER NG pseudo-footer"),
|
||||
DLT_CHOICE(ZBOSS_NCP, "ZBOSS NCP protocol with pseudo-header"),
|
||||
DLT_CHOICE(USB_2_0_LOW_SPEED, "Low-Speed USB 2.0/1.1/1.0 as transmitted over the cable"),
|
||||
DLT_CHOICE(USB_2_0_FULL_SPEED, "Full-Speed USB 2.0/1.1/1.0 as transmitted over the cable"),
|
||||
DLT_CHOICE(USB_2_0_HIGH_SPEED, "High-Speed USB 2.0 as transmitted over the cable"),
|
||||
DLT_CHOICE(AUERSWALD_LOG, "Auerswald Logger Protocol"),
|
||||
DLT_CHOICE(ZWAVE_TAP, "Z-Wave packets with a TAP meta-data header"),
|
||||
DLT_CHOICE(SILABS_DEBUG_CHANNEL, "Silicon Labs debug channel protocol"),
|
||||
DLT_CHOICE(FIRA_UCI, "Ultra-wideband controller interface protocol"),
|
||||
DLT_CHOICE(MDB, "Multi-Drop Bus"),
|
||||
DLT_CHOICE(DECT_NR, "DECT New Radio"),
|
||||
DLT_CHOICE(USER0, "Private use 0"),
|
||||
DLT_CHOICE(USER1, "Private use 1"),
|
||||
DLT_CHOICE(USER2, "Private use 2"),
|
||||
DLT_CHOICE(USER3, "Private use 3"),
|
||||
DLT_CHOICE(USER4, "Private use 4"),
|
||||
DLT_CHOICE(USER5, "Private use 5"),
|
||||
DLT_CHOICE(USER6, "Private use 6"),
|
||||
DLT_CHOICE(USER7, "Private use 7"),
|
||||
DLT_CHOICE(USER8, "Private use 8"),
|
||||
DLT_CHOICE(USER9, "Private use 9"),
|
||||
DLT_CHOICE(USER10, "Private use 10"),
|
||||
DLT_CHOICE(USER11, "Private use 11"),
|
||||
DLT_CHOICE(USER12, "Private use 12"),
|
||||
DLT_CHOICE(USER13, "Private use 13"),
|
||||
DLT_CHOICE(USER14, "Private use 14"),
|
||||
DLT_CHOICE(USER15, "Private use 15"),
|
||||
DLT_CHOICE(EDK2_MM, "edk2 mm request serialization protocol"),
|
||||
DLT_CHOICE(DEBUG_ONLY, "unstructured data for manual debugging only"),
|
||||
DLT_CHOICE_SENTINEL
|
||||
};
|
||||
|
||||
|
|
@ -4278,10 +4316,23 @@ pcapint_load_code(const char *name)
|
|||
return hModule;
|
||||
}
|
||||
|
||||
pcap_funcptr_t
|
||||
/*
|
||||
* Casting from FARPROC, which is the type of the return value of
|
||||
* GetProcAddress(), to a function pointer gets a C4191 warning
|
||||
* from Visual Studio 2022.
|
||||
*
|
||||
* Casting FARPROC to void * and returning the result, and then
|
||||
* casting the void * to a function pointer, doesn't get the
|
||||
* same warning.
|
||||
*
|
||||
* Given that, and given that the equivalent UN*X API, dlsym(),
|
||||
* returns a void *, we have pcapint_find_function() return
|
||||
* a void *.
|
||||
*/
|
||||
void *
|
||||
pcapint_find_function(pcap_code_handle_t code, const char *func)
|
||||
{
|
||||
return (GetProcAddress(code, func));
|
||||
return ((void *)GetProcAddress(code, func));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
|||
102
pcap/dlt.h
102
pcap/dlt.h
|
|
@ -390,7 +390,7 @@
|
|||
* 121 was reserved for Siemens HiPath HDLC on 2002-01-25, as
|
||||
* requested by Tomas Kukosa.
|
||||
*
|
||||
* On 2004-02-25, a FreeBSD checkin to sys/net/bpf.h was made that
|
||||
* On 2004-02-25, a FreeBSD check in to sys/net/bpf.h was made that
|
||||
* assigned 121 as DLT_PFSYNC. In current versions, its libpcap
|
||||
* does DLT_ <-> LINKTYPE_ mapping, mapping DLT_PFSYNC to a
|
||||
* LINKTYPE_PFSYNC value of 246, so it should write out DLT_PFSYNC
|
||||
|
|
@ -1570,6 +1570,8 @@
|
|||
|
||||
/*
|
||||
* USB 2.0, 1.1, and 1.0 packets as transmitted over the cable.
|
||||
* Deprecated in favor of speed specific DLTs: DLT_USB_2_0_LOW_SPEED,
|
||||
* DLT_USB_2_0_FULL_SPEED and DLT_USB_2_0_HIGH_SPEED.
|
||||
*/
|
||||
#define DLT_USB_2_0 288
|
||||
|
||||
|
|
@ -1578,6 +1580,102 @@
|
|||
*/
|
||||
#define DLT_ATSC_ALP 289
|
||||
|
||||
/*
|
||||
* Event Tracing for Windows messages.
|
||||
*/
|
||||
#define DLT_ETW 290
|
||||
|
||||
/*
|
||||
* Hilscher Gesellschaft fuer Systemautomation mbH
|
||||
* netANALYZER NG hardware and software.
|
||||
*
|
||||
* The specification for this footer can be found at:
|
||||
* https://kb.hilscher.com/x/brDJBw
|
||||
*
|
||||
* Requested by Jan Adam <jadam@hilscher.com>
|
||||
*/
|
||||
#define DLT_NETANALYZER_NG 291
|
||||
|
||||
/*
|
||||
* Serial NCP (Network Co-Processor) protocol for Zigbee stack ZBOSS
|
||||
* by DSR, https://dsr-iot.com/downloads
|
||||
*/
|
||||
#define DLT_ZBOSS_NCP 292
|
||||
|
||||
/*
|
||||
* USB 2.0, 1.1, and 1.0 packets as transmitted over the cable.
|
||||
*/
|
||||
#define DLT_USB_2_0_LOW_SPEED 293
|
||||
#define DLT_USB_2_0_FULL_SPEED 294
|
||||
#define DLT_USB_2_0_HIGH_SPEED 295
|
||||
|
||||
/*
|
||||
* Auerswald Logger Protocol
|
||||
* description is provided on
|
||||
* https://github.com/Auerswald-GmbH/auerlog/blob/master/auerlog.txt
|
||||
*/
|
||||
#define DLT_AUERSWALD_LOG 296
|
||||
|
||||
/*
|
||||
* Z-Wave packets with a TAP meta-data header
|
||||
* https://gitlab.com/exegin/zwave-g9959-tap
|
||||
* requested on tcpdump-workers@
|
||||
*/
|
||||
#define DLT_ZWAVE_TAP 297
|
||||
|
||||
/*
|
||||
* Silicon Labs debug channel protocol:
|
||||
*/
|
||||
#define DLT_SILABS_DEBUG_CHANNEL 298
|
||||
|
||||
/*
|
||||
* Ultra-wideband (UWB) controller interface protocol (UCI).
|
||||
* requested by Henri Chataing <henrichataing@google.com>
|
||||
*/
|
||||
#define DLT_FIRA_UCI 299
|
||||
|
||||
/*
|
||||
* MDB (Multi-Drop Bus) protocol between a vending machine controller and
|
||||
* peripherals inside the vending machine. See
|
||||
*
|
||||
* https://www.kaiser.cx/pcap-mdb.html
|
||||
*
|
||||
* for the specification.
|
||||
*
|
||||
* Requested by Martin Kaiser <martin@kaiser.cx>.
|
||||
*/
|
||||
#define DLT_MDB 300
|
||||
|
||||
/*
|
||||
* DECT-2020 New Radio (NR) - ETSI TS 103 636.
|
||||
* Requested by Stig Bjorlykke <stig@bjorlykke.org>.
|
||||
*/
|
||||
#define DLT_DECT_NR 301
|
||||
|
||||
/*
|
||||
* Request serialization protocol used by edk2 firmware to communicate between
|
||||
* normal mode and management mode ('MM' for short).
|
||||
*
|
||||
* The qemu uefi variable store implementation reuses the request serialization
|
||||
* protocol for firmware <-> qemu communication.
|
||||
*/
|
||||
#define DLT_EDK2_MM 302
|
||||
|
||||
/*
|
||||
* Unstructured data for manual debugging only. In other words, this DLT is
|
||||
* suitable for expert interpretation of hex dumps, and that's it. Do not use
|
||||
* this DLT for any other purpose. For any automated (identification, saving,
|
||||
* loading, filtering, decoding) processing please either use another existing
|
||||
* DLT that fits the use case or document, assign and implement a new, properly
|
||||
* structured DLT.
|
||||
*
|
||||
* In this DLT do not assume any specification, any structure, any format, any
|
||||
* version, any header, any payload, any byte order, any implementation, any
|
||||
* software/firmware/hardware particulars, any source, any destination, any
|
||||
* direction, any protocol or any data integrity/consistency whatsoever.
|
||||
*/
|
||||
#define DLT_DEBUG_ONLY 303
|
||||
|
||||
/*
|
||||
* In case the code that includes this file (directly or indirectly)
|
||||
* has also included OS files that happen to define DLT_HIGH_MATCHING_MAX,
|
||||
|
|
@ -1588,6 +1686,6 @@
|
|||
#ifdef DLT_HIGH_MATCHING_MAX
|
||||
#undef DLT_HIGH_MATCHING_MAX
|
||||
#endif
|
||||
#define DLT_HIGH_MATCHING_MAX 289 /* highest value in the "matching" range */
|
||||
#define DLT_HIGH_MATCHING_MAX 303 /* highest value in the "matching" range */
|
||||
|
||||
#endif /* !defined(lib_pcap_dlt_h) */
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
.\"
|
||||
.TH PCAP_CLOSE 3PCAP "3 January 2014"
|
||||
.TH PCAP_CLOSE 3PCAP "12 October 2024"
|
||||
.SH NAME
|
||||
pcap_close \- close a capture device or savefile
|
||||
.SH SYNOPSIS
|
||||
|
|
@ -34,6 +34,14 @@ void pcap_close(pcap_t *p);
|
|||
.BR pcap_close ()
|
||||
closes the files associated with
|
||||
.I p
|
||||
and deallocates resources.
|
||||
and deallocates resources. This means that, for example, if
|
||||
.I p
|
||||
refers to a savefile that was opened with
|
||||
.BR pcap_fopen_offline ()
|
||||
or
|
||||
.BR pcap_fopen_offline_with_tstamp_precision (),
|
||||
the stream provided to the routine will be closed unless it is
|
||||
.BR stdin .
|
||||
.SH SEE ALSO
|
||||
.BR pcap (3PCAP)
|
||||
.BR pcap (3PCAP),
|
||||
.BR pcap_open_offline (3PCAP)
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
.\"
|
||||
.TH PCAP_DUMP_CLOSE 3PCAP "3 January 2014"
|
||||
.TH PCAP_DUMP_CLOSE 3PCAP "12 October 2024"
|
||||
.SH NAME
|
||||
pcap_dump_close \- close a savefile being written to
|
||||
.SH SYNOPSIS
|
||||
|
|
@ -32,7 +32,14 @@ void pcap_dump_close(pcap_dumper_t *p);
|
|||
.fi
|
||||
.SH DESCRIPTION
|
||||
.BR pcap_dump_close ()
|
||||
closes the ``savefile.''
|
||||
closes the ``savefile'' associated with
|
||||
.I p
|
||||
and deallocates resources. This means that, for example, if
|
||||
.I p
|
||||
refers to a savefile that was opened with
|
||||
.BR pcap_dump_fopen (),
|
||||
the stream provided to that routine will be closed unless it is
|
||||
.BR stdout .
|
||||
.SH SEE ALSO
|
||||
.BR pcap (3PCAP),
|
||||
.BR pcap_dump_open (3PCAP),
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ int pcap_dump_flush(pcap_dumper_t *p);
|
|||
.fi
|
||||
.SH DESCRIPTION
|
||||
.BR pcap_dump_flush ()
|
||||
flushes the output buffer to the ``savefile,'' so that any packets
|
||||
flushes the output buffer to the ``savefile'', so that any packets
|
||||
written with
|
||||
.BR pcap_dump (3PCAP)
|
||||
but not yet written to the ``savefile'' will be written.
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ FILE *pcap_file(pcap_t *p);
|
|||
.fi
|
||||
.SH DESCRIPTION
|
||||
.BR pcap_file ()
|
||||
returns the standard I/O stream of the ``savefile,'' if a ``savefile''
|
||||
returns the standard I/O stream of the ``savefile'', if a ``savefile''
|
||||
was opened with
|
||||
.BR pcap_open_offline (3PCAP),
|
||||
or
|
||||
|
|
|
|||
|
|
@ -180,7 +180,7 @@ platforms that support a packet buffer timeout that starts before any
|
|||
packets arrive, the timeout expires before any packets arrive, or if the
|
||||
file descriptor for the capture device is in non-blocking mode and no
|
||||
packets were available to be read) or if no more packets are available
|
||||
in a ``savefile.'' It returns
|
||||
in a ``savefile''. It returns
|
||||
.B PCAP_ERROR_BREAK
|
||||
if the loop terminated due to a call to
|
||||
.BR pcap_breakloop ()
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@ packet filter, or if, on platforms that support a packet buffer timeout
|
|||
that starts before any packets arrive, the timeout expires before any
|
||||
packets arrive, or if the file descriptor for the capture device is in
|
||||
non-blocking mode and no packets were available to be read), or if no
|
||||
more packets are available in a ``savefile.'' Unfortunately, there is no
|
||||
more packets are available in a ``savefile''. Unfortunately, there is no
|
||||
way to determine whether an error occurred or not.
|
||||
.SH SEE ALSO
|
||||
.BR pcap (3PCAP)
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
.\"
|
||||
.TH PCAP_OPEN_OFFLINE 3PCAP "30 November 2023"
|
||||
.TH PCAP_OPEN_OFFLINE 3PCAP "12 October 2024"
|
||||
.SH NAME
|
||||
pcap_open_offline, pcap_open_offline_with_tstamp_precision,
|
||||
pcap_fopen_offline, pcap_fopen_offline_with_tstamp_precision \- open a saved capture file for reading
|
||||
|
|
@ -80,7 +80,11 @@ Alternatively, you may call
|
|||
or
|
||||
.BR pcap_fopen_offline_with_tstamp_precision ()
|
||||
to read dumped data from an existing open stream
|
||||
.IR fp .
|
||||
.IR fp ;
|
||||
this stream will be closed by a subsequent call to
|
||||
.BR pcap_close (3PCAP)
|
||||
unless it is
|
||||
.BR stdin .
|
||||
.BR pcap_fopen_offline_with_tstamp_precision ()
|
||||
takes an additional
|
||||
.I precision
|
||||
|
|
|
|||
4
pflog.h
4
pflog.h
|
|
@ -31,6 +31,10 @@
|
|||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* pflog headers, at least as they exist now.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -48,26 +48,30 @@ if(WIN32 OR ((CMAKE_USE_PTHREADS_INIT OR PTHREADS_FOUND) AND HAVE_CRYPT))
|
|||
endif(NOT STDLIBS_HAVE_GETADDRINFO)
|
||||
endif(UNIX)
|
||||
|
||||
if(WIN32)
|
||||
set(RPCAPD_EXTRA_SOURCES
|
||||
win32-svc.c
|
||||
${pcap_SOURCE_DIR}/charconv.c
|
||||
${pcap_SOURCE_DIR}/missing/getopt.c
|
||||
rpcapd.rc)
|
||||
include_directories(${pcap_SOURCE_DIR}/rpcapd ${pcap_SOURCE_DIR}/missing)
|
||||
endif(WIN32)
|
||||
|
||||
add_executable(rpcapd
|
||||
set(RPCAPD_SOURCES
|
||||
daemon.c
|
||||
fileconf.c
|
||||
log.c
|
||||
rpcapd.c
|
||||
${pcap_SOURCE_DIR}/rpcap-protocol.c
|
||||
${pcap_SOURCE_DIR}/sockutils.c
|
||||
${pcap_SOURCE_DIR}/sslutils.c
|
||||
${pcap_SOURCE_DIR}/fmtutils.c
|
||||
${RPCAPD_EXTRA_SOURCES}
|
||||
)
|
||||
if(OPENSSL_FOUND)
|
||||
set(RPCAPD_SOURCES ${RPCAPD_SOURCES}
|
||||
${pcap_SOURCE_DIR}/sslutils.c)
|
||||
endif(OPENSSL_FOUND)
|
||||
if(WIN32)
|
||||
set(RPCAPD_SOURCES ${RPCAPD_SOURCES}
|
||||
win32-svc.c
|
||||
${pcap_SOURCE_DIR}/charconv.c
|
||||
${pcap_SOURCE_DIR}/missing/getopt.c
|
||||
rpcapd.rc
|
||||
)
|
||||
include_directories(${pcap_SOURCE_DIR}/rpcapd ${pcap_SOURCE_DIR}/missing)
|
||||
endif(WIN32)
|
||||
|
||||
add_executable(rpcapd ${RPCAPD_SOURCES})
|
||||
|
||||
if(NOT C_ADDITIONAL_FLAGS STREQUAL "")
|
||||
set_target_properties(rpcapd PROPERTIES COMPILE_FLAGS ${C_ADDITIONAL_FLAGS})
|
||||
|
|
|
|||
|
|
@ -87,9 +87,12 @@ static char address[MAX_LINE + 1]; //!< keeps the network address (either numer
|
|||
static char port[MAX_LINE + 1]; //!< keeps the network port to bind to
|
||||
#ifdef _WIN32
|
||||
static HANDLE state_change_event; //!< event to signal that a state change should take place
|
||||
#endif
|
||||
static volatile long shutdown_server; //!< '1' if the server is to shut down
|
||||
static volatile long reread_config; //!< '1' if the server is to re-read its configuration
|
||||
#else
|
||||
static volatile sig_atomic_t shutdown_server; //!< '1' if the server is to shut down
|
||||
static volatile sig_atomic_t reread_config; //!< '1' if the server is to re-read its configuration
|
||||
#endif
|
||||
static int uses_ssl; //!< '1' to use TLS over TCP
|
||||
|
||||
extern char *optarg; // for getopt()
|
||||
|
|
@ -754,7 +757,7 @@ send_shutdown_notification(void)
|
|||
//
|
||||
// Indicate that the server should shut down.
|
||||
//
|
||||
shutdown_server = 1;
|
||||
_InterlockedExchange(&shutdown_server, 1);
|
||||
|
||||
//
|
||||
// Send a state change event, to wake up WSAWaitForMultipleEvents().
|
||||
|
|
@ -768,7 +771,7 @@ send_reread_configuration_notification(void)
|
|||
//
|
||||
// Indicate that the server should re-read its configuration file.
|
||||
//
|
||||
reread_config = 1;
|
||||
_InterlockedExchange(&reread_config, 1);
|
||||
|
||||
//
|
||||
// Send a state change event, to wake up WSAWaitForMultipleEvents().
|
||||
|
|
@ -947,20 +950,19 @@ accept_connections(void)
|
|||
//
|
||||
// The state change event was set.
|
||||
//
|
||||
if (shutdown_server)
|
||||
if (_InterlockedExchange(&shutdown_server, 0))
|
||||
{
|
||||
//
|
||||
// Time to quit. Exit the loop.
|
||||
//
|
||||
break;
|
||||
}
|
||||
if (reread_config)
|
||||
if (_InterlockedExchange(&reread_config, 0))
|
||||
{
|
||||
//
|
||||
// We should re-read the configuration
|
||||
// file.
|
||||
//
|
||||
reread_config = 0; // clear the indicator
|
||||
fileconf_read();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
22
scanner.l
22
scanner.l
|
|
@ -126,28 +126,6 @@ void pcap_set_column(int, yyscan_t);
|
|||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
/*
|
||||
* To quote the MSDN page for getaddrinfo() at
|
||||
*
|
||||
* https://msdn.microsoft.com/en-us/library/windows/desktop/ms738520(v=vs.85).aspx
|
||||
*
|
||||
* "Support for getaddrinfo on Windows 2000 and older versions
|
||||
* The getaddrinfo function was added to the Ws2_32.dll on Windows XP and
|
||||
* later. To execute an application that uses this function on earlier
|
||||
* versions of Windows, then you need to include the Ws2tcpip.h and
|
||||
* Wspiapi.h files. When the Wspiapi.h include file is added, the
|
||||
* getaddrinfo function is defined to the WspiapiGetAddrInfo inline
|
||||
* function in the Wspiapi.h file. At runtime, the WspiapiGetAddrInfo
|
||||
* function is implemented in such a way that if the Ws2_32.dll or the
|
||||
* Wship6.dll (the file containing getaddrinfo in the IPv6 Technology
|
||||
* Preview for Windows 2000) does not include getaddrinfo, then a
|
||||
* version of getaddrinfo is implemented inline based on code in the
|
||||
* Wspiapi.h header file. This inline code will be used on older Windows
|
||||
* platforms that do not natively support the getaddrinfo function."
|
||||
*
|
||||
* We use getaddrinfo(), so we include Wspiapi.h here.
|
||||
*/
|
||||
#include <wspiapi.h>
|
||||
#else /* _WIN32 */
|
||||
#include <sys/socket.h> /* for "struct sockaddr" in "struct addrinfo" */
|
||||
#include <netdb.h> /* for "struct addrinfo" */
|
||||
|
|
|
|||
15
sf-pcap.c
15
sf-pcap.c
|
|
@ -108,7 +108,7 @@
|
|||
* read on systems with the same tv_sec size as the system on which
|
||||
* the file was written.
|
||||
*
|
||||
* THe fields are unsigned, as that's what the pcap draft specification
|
||||
* The fields are unsigned, as that's what the pcap draft specification
|
||||
* says they are. (That gives pcap a 68-year Y2.038K reprieve, although
|
||||
* in 2106 it runs out for good. pcapng doesn't have that problem,
|
||||
* unless you pick a *really* high time stamp precision.)
|
||||
|
|
@ -1224,7 +1224,7 @@ pcap_dump_ftell64(pcap_dumper_t *p)
|
|||
}
|
||||
#elif defined(_MSC_VER)
|
||||
/*
|
||||
* We have Visual Studio; we support only 2005 and later, so we have
|
||||
* We have Visual Studio; we support only 2015 and later, so we have
|
||||
* _ftelli64().
|
||||
*/
|
||||
int64_t
|
||||
|
|
@ -1262,11 +1262,16 @@ pcap_dump_flush(pcap_dumper_t *p)
|
|||
void
|
||||
pcap_dump_close(pcap_dumper_t *p)
|
||||
{
|
||||
FILE *fp = (FILE *)p;
|
||||
|
||||
#ifdef notyet
|
||||
if (ferror((FILE *)p))
|
||||
if (ferror(fp))
|
||||
return-an-error;
|
||||
/* XXX should check return from fclose() too */
|
||||
/* XXX should check return from fflush()/fclose() too */
|
||||
#endif
|
||||
(void)fclose((FILE *)p);
|
||||
/* Don't close the standard output, but *do* flush it */
|
||||
if (fp == stdout)
|
||||
(void)fflush(fp);
|
||||
else
|
||||
(void)fclose(fp);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ add_test_executable(findalldevstest)
|
|||
add_test_executable(findalldevstest-perf)
|
||||
add_test_executable(opentest)
|
||||
add_test_executable(reactivatetest)
|
||||
add_test_executable(versiontest)
|
||||
add_test_executable(writecaptest)
|
||||
|
||||
if(NOT WIN32)
|
||||
|
|
@ -48,4 +49,10 @@ if(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD" OR
|
|||
add_test_executable(valgrindtest)
|
||||
endif()
|
||||
|
||||
add_subdirectory(fuzz)
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD" OR
|
||||
CMAKE_SYSTEM_NAME STREQUAL "Darwin" OR
|
||||
CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
if(IS_DIRECTORY ${CMAKE_HOME_DIRECTORY}/.git)
|
||||
add_subdirectory(fuzz)
|
||||
endif(IS_DIRECTORY ${CMAKE_HOME_DIRECTORY}/.git)
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -89,6 +89,7 @@ SRC = @VALGRINDTEST_SRC@ \
|
|||
reactivatetest.c \
|
||||
selpolltest.c \
|
||||
threadsignaltest.c \
|
||||
versiontest.c \
|
||||
writecaptest.c
|
||||
|
||||
TESTS = $(SRC:.c=)
|
||||
|
|
@ -148,6 +149,10 @@ valgrindtest: $(srcdir)/valgrindtest.c ../libpcap.a
|
|||
$(CC) $(FULL_CFLAGS) -I. -L. -o valgrindtest $(srcdir)/valgrindtest.c \
|
||||
../libpcap.a $(LIBS)
|
||||
|
||||
versiontest: $(srcdir)/versiontest.c ../libpcap.a
|
||||
$(CC) $(FULL_CFLAGS) -I. -L. -o $@ $(srcdir)/versiontest.c \
|
||||
../libpcap.a $(LIBS)
|
||||
|
||||
writecaptest: $(srcdir)/writecaptest.c ../libpcap.a
|
||||
$(CC) $(FULL_CFLAGS) -I. -L. -o writecaptest $(srcdir)/writecaptest.c \
|
||||
../libpcap.a $(LIBS)
|
||||
|
|
|
|||
|
|
@ -356,6 +356,9 @@ main(int argc, char **argv)
|
|||
free(cmdbuf);
|
||||
pcap_freecode (&fcode);
|
||||
pcap_close(pd);
|
||||
#ifdef _WIN32
|
||||
WSACleanup();
|
||||
#endif
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,43 +0,0 @@
|
|||
add_executable(fuzz_pcap onefile.c fuzz_pcap.c)
|
||||
target_link_libraries(fuzz_pcap ${ARGN} ${LIBRARY_NAME}_static ${PCAP_LINK_LIBRARIES})
|
||||
if(NOT "${SANITIZER_FLAGS}" STREQUAL "")
|
||||
set_target_properties(fuzz_pcap PROPERTIES
|
||||
LINK_FLAGS "${SANITIZER_FLAGS}")
|
||||
endif()
|
||||
|
||||
add_executable(fuzz_filter onefile.c fuzz_filter.c)
|
||||
target_link_libraries(fuzz_filter ${ARGN} ${LIBRARY_NAME}_static ${PCAP_LINK_LIBRARIES})
|
||||
if(NOT "${SANITIZER_FLAGS}" STREQUAL "")
|
||||
set_target_properties(fuzz_filter PROPERTIES
|
||||
LINK_FLAGS "${SANITIZER_FLAGS}")
|
||||
endif()
|
||||
|
||||
add_executable(fuzz_both onefile.c fuzz_both.c)
|
||||
target_link_libraries(fuzz_both ${ARGN} ${LIBRARY_NAME}_static ${PCAP_LINK_LIBRARIES})
|
||||
if(NOT "${SANITIZER_FLAGS}" STREQUAL "")
|
||||
set_target_properties(fuzz_both PROPERTIES
|
||||
LINK_FLAGS "${SANITIZER_FLAGS}")
|
||||
endif()
|
||||
|
||||
if(ENABLE_REMOTE AND "$ENV{CFLAGS}" MATCHES "-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION")
|
||||
add_executable(fuzz_rclient onefile.c fuzz_rclient.c)
|
||||
target_link_libraries(fuzz_rclient ${ARGN} ${LIBRARY_NAME}_static ${PCAP_LINK_LIBRARIES})
|
||||
if(NOT "${SANITIZER_FLAGS}" STREQUAL "")
|
||||
set_target_properties(fuzz_rclient PROPERTIES
|
||||
LINK_FLAGS "${SANITIZER_FLAGS}")
|
||||
endif()
|
||||
|
||||
add_executable(fuzz_rserver onefile.c fuzz_rserver.c ../../rpcapd/daemon.c)
|
||||
check_function_exists(crypt HAVE_CRYPT_IN_SYSTEM_LIBRARIES)
|
||||
if(HAVE_CRYPT_IN_SYSTEM_LIBRARIES)
|
||||
set(HAVE_CRYPT TRUE)
|
||||
else(HAVE_CRYPT_IN_SYSTEM_LIBRARIES)
|
||||
set(PCAP_LINK_LIBRARIES ${PCAP_LINK_LIBRARIES} crypt)
|
||||
endif(HAVE_CRYPT_IN_SYSTEM_LIBRARIES)
|
||||
target_link_libraries(fuzz_rserver ${ARGN} ${LIBRARY_NAME}_static ${PCAP_LINK_LIBRARIES})
|
||||
|
||||
if(NOT "${SANITIZER_FLAGS}" STREQUAL "")
|
||||
set_target_properties(fuzz_rserver PROPERTIES
|
||||
LINK_FLAGS "${SANITIZER_FLAGS}")
|
||||
endif()
|
||||
endif(ENABLE_REMOTE AND "$ENV{CFLAGS}" MATCHES "-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION")
|
||||
|
|
@ -1,101 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <pcap/pcap.h>
|
||||
|
||||
FILE * outfile = NULL;
|
||||
|
||||
static int bufferToFile(const char * name, const uint8_t *Data, size_t Size) {
|
||||
FILE * fd;
|
||||
if (remove(name) != 0) {
|
||||
if (errno != ENOENT) {
|
||||
printf("failed remove, errno=%d\n", errno);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
fd = fopen(name, "wb");
|
||||
if (fd == NULL) {
|
||||
printf("failed open, errno=%d\n", errno);
|
||||
return -2;
|
||||
}
|
||||
if (fwrite (Data, 1, Size, fd) != Size) {
|
||||
fclose(fd);
|
||||
return -3;
|
||||
}
|
||||
fclose(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void fuzz_openFile(const char * name) {
|
||||
if (outfile != NULL) {
|
||||
fclose(outfile);
|
||||
}
|
||||
outfile = fopen(name, "w");
|
||||
}
|
||||
|
||||
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
|
||||
pcap_t * pkts;
|
||||
char errbuf[PCAP_ERRBUF_SIZE];
|
||||
const u_char *pkt;
|
||||
struct pcap_pkthdr *header;
|
||||
int r;
|
||||
size_t filterSize;
|
||||
char * filter;
|
||||
struct bpf_program bpf;
|
||||
|
||||
|
||||
//initialize output file
|
||||
if (outfile == NULL) {
|
||||
outfile = fopen("/dev/null", "w");
|
||||
if (outfile == NULL) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (Size < 1) {
|
||||
return 0;
|
||||
}
|
||||
filterSize = Data[0];
|
||||
if (Size < 1+filterSize || filterSize == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
//rewrite buffer to a file as libpcap does not have buffer inputs
|
||||
if (bufferToFile("/tmp/fuzz.pcap", Data+1+filterSize, Size-(1+filterSize)) < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
//initialize structure
|
||||
pkts = pcap_open_offline("/tmp/fuzz.pcap", errbuf);
|
||||
if (pkts == NULL) {
|
||||
fprintf(outfile, "Couldn't open pcap file %s\n", errbuf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
filter = malloc(filterSize);
|
||||
memcpy(filter, Data+1, filterSize);
|
||||
//null terminate string
|
||||
filter[filterSize-1] = 0;
|
||||
|
||||
if (pcap_compile(pkts, &bpf, filter, 1, PCAP_NETMASK_UNKNOWN) == 0) {
|
||||
//loop over packets
|
||||
r = pcap_next_ex(pkts, &header, &pkt);
|
||||
while (r > 0) {
|
||||
//checks filter
|
||||
fprintf(outfile, "packet length=%d/%d filter=%d\n",header->caplen, header->len, pcap_offline_filter(&bpf, header, pkt));
|
||||
r = pcap_next_ex(pkts, &header, &pkt);
|
||||
}
|
||||
//close structure
|
||||
pcap_close(pkts);
|
||||
pcap_freecode(&bpf);
|
||||
}
|
||||
else {
|
||||
pcap_close(pkts);
|
||||
}
|
||||
free(filter);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
[libfuzzer]
|
||||
max_len = 65535
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <pcap/pcap.h>
|
||||
|
||||
void fuzz_openFile(const char * name){
|
||||
//do nothing
|
||||
}
|
||||
|
||||
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
|
||||
pcap_t * pkts;
|
||||
struct bpf_program bpf;
|
||||
char * filter;
|
||||
|
||||
//we need at least 1 byte for linktype
|
||||
if (Size < 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
//initialize structure snaplen = 65535
|
||||
pkts = pcap_open_dead(Data[Size-1], 0xFFFF);
|
||||
if (pkts == NULL) {
|
||||
printf("pcap_open_dead failed\n");
|
||||
return 0;
|
||||
}
|
||||
filter = malloc(Size);
|
||||
memcpy(filter, Data, Size);
|
||||
//null terminate string
|
||||
filter[Size-1] = 0;
|
||||
|
||||
if (pcap_compile(pkts, &bpf, filter, 1, PCAP_NETMASK_UNKNOWN) == 0) {
|
||||
pcap_setfilter(pkts, &bpf);
|
||||
pcap_close(pkts);
|
||||
pcap_freecode(&bpf);
|
||||
}
|
||||
else {
|
||||
pcap_close(pkts);
|
||||
}
|
||||
free(filter);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
[libfuzzer]
|
||||
max_len = 4096
|
||||
|
|
@ -1,80 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <pcap/pcap.h>
|
||||
|
||||
FILE * outfile = NULL;
|
||||
|
||||
static int bufferToFile(const char * name, const uint8_t *Data, size_t Size) {
|
||||
FILE * fd;
|
||||
if (remove(name) != 0) {
|
||||
if (errno != ENOENT) {
|
||||
printf("failed remove, errno=%d\n", errno);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
fd = fopen(name, "wb");
|
||||
if (fd == NULL) {
|
||||
printf("failed open, errno=%d\n", errno);
|
||||
return -2;
|
||||
}
|
||||
if (fwrite (Data, 1, Size, fd) != Size) {
|
||||
fclose(fd);
|
||||
return -3;
|
||||
}
|
||||
fclose(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void fuzz_openFile(const char * name) {
|
||||
if (outfile != NULL) {
|
||||
fclose(outfile);
|
||||
}
|
||||
outfile = fopen(name, "w");
|
||||
}
|
||||
|
||||
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
|
||||
pcap_t * pkts;
|
||||
char errbuf[PCAP_ERRBUF_SIZE];
|
||||
const u_char *pkt;
|
||||
struct pcap_pkthdr *header;
|
||||
struct pcap_stat stats;
|
||||
int r;
|
||||
|
||||
//initialize output file
|
||||
if (outfile == NULL) {
|
||||
outfile = fopen("/dev/null", "w");
|
||||
if (outfile == NULL) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
//rewrite buffer to a file as libpcap does not have buffer inputs
|
||||
if (bufferToFile("/tmp/fuzz.pcap", Data, Size) < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
//initialize structure
|
||||
pkts = pcap_open_offline("/tmp/fuzz.pcap", errbuf);
|
||||
if (pkts == NULL) {
|
||||
fprintf(outfile, "Couldn't open pcap file %s\n", errbuf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//loop over packets
|
||||
r = pcap_next_ex(pkts, &header, &pkt);
|
||||
while (r > 0) {
|
||||
//TODO pcap_offline_filter
|
||||
fprintf(outfile, "packet length=%d/%d\n",header->caplen, header->len);
|
||||
r = pcap_next_ex(pkts, &header, &pkt);
|
||||
}
|
||||
if (pcap_stats(pkts, &stats) == 0) {
|
||||
fprintf(outfile, "number of packets=%d\n", stats.ps_recv);
|
||||
}
|
||||
//close structure
|
||||
pcap_close(pkts);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
[libfuzzer]
|
||||
max_len = 65535
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
|
||||
void fuzz_openFile(const char * name);
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
FILE * fp;
|
||||
uint8_t *Data;
|
||||
size_t Size;
|
||||
|
||||
if (argc == 3) {
|
||||
fuzz_openFile(argv[2]);
|
||||
} else if (argc != 2) {
|
||||
return 1;
|
||||
}
|
||||
//opens the file, get its size, and reads it into a buffer
|
||||
fp = fopen(argv[1], "rb");
|
||||
if (fp == NULL) {
|
||||
return 2;
|
||||
}
|
||||
if (fseek(fp, 0L, SEEK_END) != 0) {
|
||||
fclose(fp);
|
||||
return 2;
|
||||
}
|
||||
Size = ftell(fp);
|
||||
if (Size == (size_t) -1) {
|
||||
fclose(fp);
|
||||
return 2;
|
||||
}
|
||||
if (fseek(fp, 0L, SEEK_SET) != 0) {
|
||||
fclose(fp);
|
||||
return 2;
|
||||
}
|
||||
Data = malloc(Size);
|
||||
if (Data == NULL) {
|
||||
fclose(fp);
|
||||
return 2;
|
||||
}
|
||||
if (fread(Data, Size, 1, fp) != 1) {
|
||||
fclose(fp);
|
||||
free(Data);
|
||||
return 2;
|
||||
}
|
||||
|
||||
//launch fuzzer
|
||||
LLVMFuzzerTestOneInput(Data, Size);
|
||||
free(Data);
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
29
testprogs/versiontest.c
Normal file
29
testprogs/versiontest.c
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that: (1) source code distributions
|
||||
* retain the above copyright notice and this paragraph in its entirety, (2)
|
||||
* distributions including binary code include the above copyright notice and
|
||||
* this paragraph in its entirety in the documentation or other materials
|
||||
* provided with the distribution, and (3) all advertising materials mentioning
|
||||
* features or use of this software display the following acknowledgement:
|
||||
* ``This product includes software developed by the University of California,
|
||||
* Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
|
||||
* the University nor the names of its contributors may be used to endorse
|
||||
* or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#include <pcap.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
printf("%s\n", pcap_lib_version());
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue