Import libpcap 1.9.1
This commit is contained in:
parent
d109bf9e4b
commit
30a580a870
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/vendor/libpcap/dist/; revision=353141 svn path=/vendor/libpcap/1.9.1/; revision=353142; tag=vendor/libpcap/1.9.1
126
CHANGES
126
CHANGES
@ -1,5 +1,129 @@
|
||||
Wednesday, Jan. 25, 2017 guy@alum.mit.edu
|
||||
Sunday, July 22, 2018
|
||||
Summary for 1.9.1 libpcap release
|
||||
Mention pcap_get_required_select_timeout() in the main pcap man page
|
||||
Fix pcap-usb-linux.c build on systems with musl
|
||||
Fix assorted man page and other documentation issues
|
||||
Plug assorted memory leaks
|
||||
Documentation changes to use https:
|
||||
Changes to how time stamp calculations are done
|
||||
Lots of tweaks to make newer compilers happier and warning-free and
|
||||
to fix instances of C undefined behavior
|
||||
Warn if AC_PROG_CC_C99 can't enable C99 support
|
||||
Rename pcap_set_protocol() to pcap_set_protocol_linux().
|
||||
Align pcap_t private data on an 8-byte boundary.
|
||||
Fix various error messages
|
||||
Use 64-bit clean API in dag_findalldevs()
|
||||
Fix cleaning up after some errors
|
||||
Work around some ethtool ioctl bugs in newer Linux kernels (GitHub
|
||||
issue #689)
|
||||
Add backwards compatibility sections to some man pages (GitHub issue
|
||||
#745)
|
||||
Fix autotool configuration on AIX and macOS
|
||||
Don't export bpf_filter_with_aux_data() or struct bpf_aux_data;
|
||||
they're internal-only and subject to change
|
||||
Fix pcapng block size checking
|
||||
On macOS, don't build rpcapd or test programs any fatter than they
|
||||
need to be
|
||||
Fix reading of capture statistics for Linux USB
|
||||
Fix packet size values for Linux USB packets (GitHub issue #808)
|
||||
Check only VID in VLAN test in filterss (GitHub issue #461)
|
||||
Fix pcap_list_datalinks on 802.11 devices on macOS
|
||||
Fix overflows with very large snapshot length in pcap file
|
||||
Improve parsing of rpcapd configuration file (GitHub issue #767)
|
||||
Handle systems without strlcpy() or strlcat() better
|
||||
Fix crashes and other errors with invalid filter expressions
|
||||
Fix use of uninitialized file descriptor in remote capture
|
||||
Fix some CMake issues
|
||||
Fix some divide-by-zero issues with the filter compiler
|
||||
Work around a GNU libc bug in pcap_nametonetaddr()
|
||||
Add support for DLT_LINUX_SLL2
|
||||
Fix handling of the packet-count argument for Myricom SNF devices
|
||||
Fix --disable-rdma in configure script (GitHub issue #782)
|
||||
Fix compilation of TurboCap support (GitHub issue #764)
|
||||
Constify first argument to pcap_findalldevs_ex()
|
||||
Fix a number of issues when running rpcapd as an inetd-style daemon
|
||||
Fix CMake issues with D-Bus libraries
|
||||
In rpcapd, clean up termination of a capture session
|
||||
Redo remote capture protocol negotiation
|
||||
In rpcapd, report the same error for "invalid user name" and
|
||||
"invalid password", to make brute-forcing harder
|
||||
For remote captures, add an error code for "the server requires TLS"
|
||||
Fix pcap_dump_fopen() on Windows to avoid clashes between
|
||||
{Win,N}Pcap and application C runtimes
|
||||
Fix exporting of functions from Windows DLLs (GitHub issue #810)
|
||||
Fix building as part of Npcap
|
||||
Allow rpcapd to rebind more rapidly
|
||||
Fix building shared libpcap library on midipix (midipix.org)
|
||||
Fix hack to detect UTF-16LE adapter names on Windows not to go past
|
||||
the end of the string
|
||||
Fix handling of "wireless WAN" (mobile phone network modems) on
|
||||
Windows with WinPcap/Npcap (GitHub issue #824)
|
||||
Have pcap_dump_open_append() create the dump file if it doesn't
|
||||
exists (GitHub issue #247)
|
||||
Fix the maxmum snapshot length for DLT_USBPCAP
|
||||
Use -fPIC when building for 64-bit SPARC on Linux (GitHub issue #837)
|
||||
Fix CMake 64-bit library installation directory on some Linux
|
||||
distributions
|
||||
Boost the TPACKET_V3 timeout to the maximum if a timeout of 0 was
|
||||
specified
|
||||
Five CVE-2019-15161, CVE-2019-15162, CVE-2019-15163, CVE-2019-15164, CVE-2019-15165
|
||||
Fixes for CVE-2018-16301, errors in pcapng reading.
|
||||
PCAPNG reader applies some sanity checks before doing malloc().
|
||||
|
||||
Sunday, June 24, 2018, by mcr@sandelman.ca
|
||||
Summary for 1.9.0 libpcap release
|
||||
Added testing system to libpcap, independent of tcpdump
|
||||
Changes to how pcap_t is activated
|
||||
Adding support for Large stream buffers on Endace DAG cards
|
||||
Changes to BSD 3-clause license to 2-clause licence
|
||||
Additions to TCP header parsing, per RFC3168
|
||||
Add CMake build process (extensive number of changes)
|
||||
Assign a value for OpenBSD DLT_OPENFLOW.
|
||||
Support setting non-blocking mode before activating.
|
||||
Extensive build support for Windows VS2010 and MINGW (many many changes, over many months)
|
||||
Added RPCAPD support when --enable-remote (default no)
|
||||
Add the rpcap daemon source and build instructions.
|
||||
Put back the greasy "save the capture filter string so we can tweak it"
|
||||
hack, that keeps libpcap from capturing rpcap traffic.
|
||||
Fixes for captures on MacOS, utun0
|
||||
fixes so that non-AF_INET addresses, are not ==AF_INET6 addresses.
|
||||
Add a linktype for IBM SDLC frames containing SNA PDUs.
|
||||
pcap_compile() in 1.8.0 and later is newly thread-safe.
|
||||
bound snaplen for linux tpacket_v2 to ~64k
|
||||
Make VLAN filter handle both metadata and inline tags
|
||||
D-Bus captures can now be up to 128MB in size
|
||||
Added LORATAP DLT value
|
||||
Added DLT_VSOCK for http://qemu-project.org/Features/VirtioVsock
|
||||
probe_devices() fixes not to overrun buffer for name of device
|
||||
Add linux-specific pcap_set_protocol_linux() to allow specifying a specific capture protocol.
|
||||
RDMA sniffing support for pcap
|
||||
Add Nordic Semiconductor Bluetooth LE sniffer link-layer header type.
|
||||
fixes for reading /etc/ethers
|
||||
Make it possible to build on Windows without packet.dll.
|
||||
Add tests for large file support on UN*X.
|
||||
Solaris fixes to work with 2.8.6
|
||||
configuration test now looks for header files, not capture devices present
|
||||
Fix to work with Berkeley YACC.
|
||||
fixes for DragonBSD compilation of pcap-netmap.c
|
||||
Clean up the ether_hostton() stuff.
|
||||
Add an option to disable Linux memory-mapped capture support.
|
||||
Add DAG API support checks.
|
||||
Add Septel, Myricom SNF, and Riverbed TurboCap checks.
|
||||
Add checks for Linux USB, Linux Bluetooth, D-Bus, and RDMA sniffing support.
|
||||
Add a check for hardware time stamping on Linux.
|
||||
Don't bother supporting pre-2005 Visual Studio.
|
||||
Increased minimum autoconf version requirement to 2.64
|
||||
Add DLT value 273 for XRA-31 sniffer
|
||||
Clean up handing of signal interrupts in pcap_read_nocb_remote().
|
||||
Use the XPG 4.2 versions of the networking APIs in Solaris.
|
||||
Fix, and better explain, the "IPv6 means IPv6, not IPv4" option setting.
|
||||
Explicitly warn that negative packet buffer timeouts should not be used.
|
||||
rpcapd: Add support inetd-likes, including xinetd.conf, and systemd units
|
||||
Rename DLT_IEEE802_15_4 to DLT_IEEE802_15_4_WITHFCS.
|
||||
Add DISPLAYPORT AUX link type
|
||||
Remove the sunos4 kernel modules and all references to them.
|
||||
Add more interface flags to pcap_findalldevs().
|
||||
Summary for 1.9.0 libpcap release (to 2017-01-25 by guy@alum.mit.edu)
|
||||
Man page improvements
|
||||
Fix Linux cooked mode userspace filtering (GitHub pull request #429)
|
||||
Fix compilation if IPv6 support not enabled
|
||||
|
386
CMakeLists.txt
386
CMakeLists.txt
@ -9,7 +9,7 @@ if(POLICY CMP0042)
|
||||
cmake_policy(SET CMP0042 OLD)
|
||||
endif()
|
||||
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/Modules)
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules)
|
||||
|
||||
project(pcap)
|
||||
|
||||
@ -135,83 +135,6 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
option(BUILD_WITH_LIBNL "Build with libnl" ON)
|
||||
endif()
|
||||
|
||||
#
|
||||
# By default, build universal with the appropriate set of architectures
|
||||
# for the OS on which we're doing the build.
|
||||
#
|
||||
if(APPLE AND "${CMAKE_OSX_ARCHITECTURES}" STREQUAL "")
|
||||
#
|
||||
# Get the major version of Darwin.
|
||||
#
|
||||
string(REGEX MATCH "^([0-9]+)" SYSTEM_VERSION_MAJOR "${CMAKE_SYSTEM_VERSION}")
|
||||
|
||||
if(SYSTEM_VERSION_MAJOR LESS 8)
|
||||
#
|
||||
# Pre-Tiger. Build only for 32-bit PowerPC.
|
||||
#
|
||||
set(CMAKE_OSX_ARCHITECTURES "ppc")
|
||||
elseif(SYSTEM_VERSION_MAJOR EQUAL 8)
|
||||
#
|
||||
# Tiger. Is this prior to, or with, Intel support?
|
||||
#
|
||||
# Get the minor version of Darwin.
|
||||
#
|
||||
string(REPLACE "${SYSTEM_VERSION_MAJOR}." "" SYSTEM_MINOR_AND_PATCH_VERSION ${CMAKE_SYSTEM_VERSION})
|
||||
string(REGEX MATCH "^([0-9]+)" SYSTEM_VERSION_MINOR "${SYSTEM_MINOR_AND_PATCH_VERSION}")
|
||||
if(SYSTEM_VERSION_MINOR LESS 4)
|
||||
#
|
||||
# Prior to Intel support. Build for 32-bit
|
||||
# PowerPC and 64-bit PowerPC, with 32-bit PowerPC
|
||||
# first. (I'm guessing that's what Apple does.)
|
||||
#
|
||||
set(CMAKE_OSX_ARCHITECTURES "ppc;ppc64")
|
||||
elseif(SYSTEM_VERSION_MINOR LESS 7)
|
||||
#
|
||||
# With Intel support but prior to x86-64 support.
|
||||
# Build for 32-bit PowerPC, 64-bit PowerPC, and x86,
|
||||
# with 32-bit PowerPC first.
|
||||
# (I'm guessing that's what Apple does.)
|
||||
#
|
||||
set(CMAKE_OSX_ARCHITECTURES "ppc;ppc64;i386")
|
||||
else()
|
||||
#
|
||||
# With Intel support including x86-64 support.
|
||||
# Build for 32-bit PowerPC, 64-bit PowerPC, x86,
|
||||
# and x86-64, with 32-bit PowerPC first.
|
||||
# (I'm guessing that's what Apple does.)
|
||||
#
|
||||
set(CMAKE_OSX_ARCHITECTURES "ppc;ppc64;i386;x86_64")
|
||||
endif()
|
||||
elseif(SYSTEM_VERSION_MAJOR EQUAL 9)
|
||||
#
|
||||
# Leopard. Build for 32-bit PowerPC, 64-bit
|
||||
# PowerPC, x86, and x86-64, with 32-bit PowerPC
|
||||
# first. (That's what Apple does.)
|
||||
#
|
||||
set(CMAKE_OSX_ARCHITECTURES "ppc;ppc64;i386;x86_64")
|
||||
elseif(SYSTEM_VERSION_MAJOR EQUAL 10)
|
||||
#
|
||||
# Snow Leopard. Build for x86-64, x86, and
|
||||
# 32-bit PowerPC, with x86-64 first. (That's
|
||||
# what Apple does, even though Snow Leopard
|
||||
# doesn't run on PPC, so PPC libpcap runs under
|
||||
# Rosetta, and Rosetta doesn't support BPF
|
||||
# ioctls, so PPC programs can't do live
|
||||
# captures.)
|
||||
#
|
||||
set(CMAKE_OSX_ARCHITECTURES "x86_64;i386;ppc")
|
||||
else()
|
||||
#
|
||||
# Post-Snow Leopard. Build for x86-64 and
|
||||
# x86, with x86-64 first. (That's probably what
|
||||
# Apple does, given that Rosetta is gone.)
|
||||
# XXX - update if and when Apple drops support
|
||||
# for 32-bit x86 code.
|
||||
#
|
||||
set(CMAKE_OSX_ARCHITECTURES "x86_64;i386")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
#
|
||||
# Additional capture modules.
|
||||
#
|
||||
@ -233,7 +156,7 @@ option(DISABLE_RDMA "Disable RDMA sniffing support" OFF)
|
||||
option(DISABLE_DAG "Disable Endace DAG card support" OFF)
|
||||
|
||||
option(DISABLE_SEPTEL "Disable Septel card support" OFF)
|
||||
set(SEPTEL_ROOT "${CMAKE_SOURCE_DIR}/../septel" CACHE PATH "Path to directory with include and lib subdirectories for Septel API")
|
||||
set(SEPTEL_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/../septel" CACHE PATH "Path to directory with include and lib subdirectories for Septel API")
|
||||
|
||||
option(DISABLE_SNF "Disable Myricom SNF support" OFF)
|
||||
|
||||
@ -251,7 +174,7 @@ option(YYDEBUG "Build parser debugging code" OFF)
|
||||
|
||||
# Get, parse, format and set pcap's version string from [pcap_root]/VERSION
|
||||
# for later use.
|
||||
|
||||
|
||||
# Get MAJOR, MINOR, PATCH & SUFFIX
|
||||
file(STRINGS ${pcap_SOURCE_DIR}/VERSION
|
||||
PACKAGE_VERSION
|
||||
@ -264,7 +187,7 @@ string(REGEX MATCH "^([0-9]+)" PACKAGE_VERSION_MAJOR "${PACKAGE_VERSION}")
|
||||
# Get MAJOR, MINOR & PATCH
|
||||
string(REGEX MATCH "^([0-9]+.)?([0-9]+.)?([0-9]+)" PACKAGE_VERSION_NOSUFFIX "${PACKAGE_VERSION}")
|
||||
|
||||
if(WIN32)
|
||||
if(WIN32)
|
||||
# Convert PCAP_VERSION_NOSUFFIX to Windows preferred version format
|
||||
string(REPLACE "." "," PACKAGE_VERSION_PREDLL ${PACKAGE_VERSION_NOSUFFIX})
|
||||
|
||||
@ -289,6 +212,7 @@ include_directories(
|
||||
|
||||
include(CheckFunctionExists)
|
||||
include(CMakePushCheckState)
|
||||
include(CheckSymbolExists)
|
||||
|
||||
if(WIN32)
|
||||
|
||||
@ -310,6 +234,14 @@ if(WIN32)
|
||||
cmake_pop_check_state()
|
||||
endif(PACKET_FOUND)
|
||||
|
||||
message(STATUS "checking for Npcap's version.h")
|
||||
check_symbol_exists(WINPCAP_PRODUCT_NAME "../../version.h" HAVE_VERSION_H)
|
||||
if(HAVE_VERSION_H)
|
||||
message(STATUS "HAVE version.h")
|
||||
else(HAVE_VERSION_H)
|
||||
message(STATUS "MISSING version.h")
|
||||
endif(HAVE_VERSION_H)
|
||||
|
||||
endif(WIN32)
|
||||
|
||||
if(MSVC)
|
||||
@ -343,6 +275,11 @@ include(CheckIncludeFiles)
|
||||
include(CheckStructHasMember)
|
||||
include(CheckTypeSize)
|
||||
|
||||
#
|
||||
# Tests are a bit expensive with Visual Studio on Windows, so, on
|
||||
# Windows, we skip tests for UN*X-only headers and functions.
|
||||
#
|
||||
|
||||
#
|
||||
# Header files.
|
||||
#
|
||||
@ -395,12 +332,44 @@ endif(NOT WIN32)
|
||||
#
|
||||
check_function_exists(strerror HAVE_STRERROR)
|
||||
check_function_exists(strerror_r HAVE_STRERROR_R)
|
||||
check_function_exists(strerror_s HAVE_STRERROR_S)
|
||||
if(HAVE_STRERROR_R)
|
||||
#
|
||||
# We have strerror_r; if we define _GNU_SOURCE, is it a
|
||||
# POSIX-compliant strerror_r() or a GNU strerror_r()?
|
||||
#
|
||||
check_c_source_compiles(
|
||||
"#define _GNU_SOURCE
|
||||
#include <string.h>
|
||||
|
||||
/* Define it GNU-style; that will cause an error if it's not GNU-style */
|
||||
extern char *strerror_r(int, char *, size_t);
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
"
|
||||
HAVE_GNU_STRERROR_R)
|
||||
if(NOT HAVE_GNU_STRERROR_R)
|
||||
set(HAVE_POSIX_STRERROR_R YES)
|
||||
endif(NOT HAVE_GNU_STRERROR_R)
|
||||
else(HAVE_STRERROR_R)
|
||||
#
|
||||
# We don't have strerror_r; do we have strerror_s?
|
||||
#
|
||||
check_function_exists(strerror_s HAVE_STRERROR_S)
|
||||
endif(HAVE_STRERROR_R)
|
||||
check_function_exists(strlcpy HAVE_STRLCPY)
|
||||
check_function_exists(strlcat HAVE_STRLCAT)
|
||||
check_function_exists(snprintf HAVE_SNPRINTF)
|
||||
check_function_exists(vsnprintf HAVE_VSNPRINTF)
|
||||
check_function_exists(asprintf HAVE_ASPRINTF)
|
||||
check_function_exists(vasprintf HAVE_VASPRINTF)
|
||||
check_function_exists(strtok_r HAVE_STRTOK_R)
|
||||
if(NOT WIN32)
|
||||
check_function_exists(vsyslog HAVE_VSYSLOG)
|
||||
endif()
|
||||
|
||||
#
|
||||
# These tests are for network applications that need socket functions
|
||||
@ -429,7 +398,6 @@ check_function_exists(strtok_r HAVE_STRTOK_R)
|
||||
#
|
||||
set(PCAP_LINK_LIBRARIES "")
|
||||
include(CheckLibraryExists)
|
||||
include(CheckSymbolExists)
|
||||
if(WIN32)
|
||||
#
|
||||
# We need winsock2.h and ws2tcpip.h.
|
||||
@ -865,11 +833,61 @@ set(PROJECT_SOURCE_LIST_C
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} missing/win_snprintf.c)
|
||||
#
|
||||
# For now, we assume we don't have snprintf() or that it's not one
|
||||
# that behaves enough like C99's snprintf() for our purposes (i.e.,
|
||||
# it doesn't null-terminate the string if it truncates it to fit in
|
||||
# the buffer), so we have to provide our own (a wrapper around
|
||||
# _snprintf() that null-terminates the buffer).
|
||||
#
|
||||
# We also assume we don't have asprintf(), and provide an implementation
|
||||
# that uses _vscprintf() to determine how big the string needs to be.
|
||||
#
|
||||
set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C}
|
||||
missing/win_snprintf.c missing/win_asprintf.c)
|
||||
else()
|
||||
#
|
||||
# Either:
|
||||
#
|
||||
# we have snprintf() and vsnprintf(), and have asprintf() and
|
||||
# vasprintf();
|
||||
#
|
||||
# we have snprintf() and vsnprintf(), but don't have asprintf()
|
||||
# or vasprintf();
|
||||
#
|
||||
# we have neither snprintf() nor vsnprintf(), and don't have
|
||||
# asprintf() or vasprintf(), either.
|
||||
#
|
||||
# We assume that if we have asprintf() we have vasprintf(), as well
|
||||
# as snprintf() and vsnprintf(), and that if we have snprintf() we
|
||||
# have vsnprintf().
|
||||
#
|
||||
# For the first case, we don't need any replacement routines.
|
||||
# For the second case, we need replacement asprintf()/vasprintf()
|
||||
# routines.
|
||||
# For the third case, we need replacement snprintf()/vsnprintf() and
|
||||
# asprintf()/vasprintf() routines.
|
||||
#
|
||||
if(NOT HAVE_SNPRINTF)
|
||||
#
|
||||
# We assume we have none of them; missing/snprintf.c supplies
|
||||
# all of them.
|
||||
#
|
||||
set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} missing/snprintf.c)
|
||||
endif(NOT HAVE_SNPRINTF)
|
||||
elif(NOT HAVE_ASPRINTF)
|
||||
#
|
||||
# We assume we have snprintf()/vsnprintf() but lack
|
||||
# asprintf()/vasprintf(); missing/asprintf.c supplies
|
||||
# the latter (using vsnprintf()).
|
||||
#
|
||||
set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} missing/asprintf.c)
|
||||
endif()
|
||||
if(NOT HAVE_STRLCAT)
|
||||
set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} missing/strlcat.c)
|
||||
endif(NOT HAVE_STRLCAT)
|
||||
if(NOT HAVE_STRLCPY)
|
||||
set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} missing/strlcpy.c)
|
||||
endif(NOT HAVE_STRLCPY)
|
||||
if(NOT HAVE_STRTOK_R)
|
||||
set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} missing/strtok_r.c)
|
||||
endif(NOT HAVE_STRTOK_R)
|
||||
@ -931,13 +949,16 @@ else()
|
||||
# as it's a Linux, it should use packet sockets,
|
||||
# instead.
|
||||
#
|
||||
#
|
||||
# We need:
|
||||
#
|
||||
# sys/types.h, because FreeBSD 10's net/bpf.h
|
||||
# requires that various BSD-style integer types
|
||||
# be defined;
|
||||
#
|
||||
# sys/time.h, because AIX 5.2 and 5.3's net/bpf.h
|
||||
# doesn't include it but does use struct timeval
|
||||
# in ioctl definitions;
|
||||
#
|
||||
# sys/ioctl.h and, if we have it, sys/ioccom.h,
|
||||
# because net/bpf.h defines ioctls;
|
||||
#
|
||||
@ -952,9 +973,9 @@ else()
|
||||
# of those headers itself.
|
||||
#
|
||||
if(HAVE_SYS_IOCCOM_H)
|
||||
check_symbol_exists(BIOCSETIF "sys/types.h;sys/ioctl.h;sys/socket.h;sys/ioccom.h;net/bpf.h;net/if.h" BPF_H_DEFINES_BIOCSETIF)
|
||||
check_symbol_exists(BIOCSETIF "sys/types.h;sys/time.h;sys/ioctl.h;sys/socket.h;sys/ioccom.h;net/bpf.h;net/if.h" BPF_H_DEFINES_BIOCSETIF)
|
||||
else(HAVE_SYS_IOCCOM_H)
|
||||
check_symbol_exists(BIOCSETIF "sys/types.h;sys/ioctl.h;sys/socket.h;net/bpf.h;net/if.h" BPF_H_DEFINES_BIOCSETIF)
|
||||
check_symbol_exists(BIOCSETIF "sys/types.h;sys/time.h;sys/ioctl.h;sys/socket.h;net/bpf.h;net/if.h" BPF_H_DEFINES_BIOCSETIF)
|
||||
endif(HAVE_SYS_IOCCOM_H)
|
||||
endif(HAVE_NET_BPF_H)
|
||||
check_include_file(net/pfilt.h HAVE_NET_PFILT_H)
|
||||
@ -1436,7 +1457,28 @@ if(NOT DISABLE_DBUS)
|
||||
set(PCAP_SUPPORT_DBUS TRUE)
|
||||
set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} pcap-dbus.c)
|
||||
include_directories(${DBUS_INCLUDE_DIRS})
|
||||
set(PCAP_LINK_LIBRARIES ${PCAP_LINK_LIBRARIES} ${DBUS_LIBRARIES})
|
||||
|
||||
#
|
||||
# This "helpfully" supplies DBUS_LIBRARIES as a bunch of
|
||||
# library names - not paths - and DBUS_LIBRARY_DIRS as
|
||||
# a bunch of directories.
|
||||
#
|
||||
# CMake *really* doesn't like the notion of specifying "here are
|
||||
# the directories in which to look for libraries" except in
|
||||
# find_library() calls; it *really* prefers using full paths to
|
||||
# library files, rather than library names.
|
||||
#
|
||||
# Find the libraries and add their full paths.
|
||||
#
|
||||
set(DBUS_LIBRARY_FULLPATHS)
|
||||
foreach(_lib IN LISTS DBUS_LIBRARIES)
|
||||
#
|
||||
# Try to find this library, so we get its full path.
|
||||
#
|
||||
find_library(_libfullpath ${_lib} HINTS ${DBUS_LIBRARY_DIRS})
|
||||
list(APPEND DBUS_LIBRARY_FULLPATHS ${_libfullpath})
|
||||
endforeach()
|
||||
set(PCAP_LINK_LIBRARIES ${PCAP_LINK_LIBRARIES} ${DBUS_LIBRARY_FULLPATHS})
|
||||
endif(DBUS_FOUND)
|
||||
endif(NOT DISABLE_DBUS)
|
||||
|
||||
@ -1499,7 +1541,7 @@ if(NOT DISABLE_DAG)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Check for Septel card support.
|
||||
set(PROJECT_EXTERNAL_OBJECT_LIST "")
|
||||
@ -1521,7 +1563,7 @@ if(NOT DISABLE_SEPTEL)
|
||||
set(PROJECT_EXTERNAL_OBJECT_LIST ${PROJECT_EXTERNAL_OBJECT_LIST} "${SEPTEL_ROOT}/asciibin.o ${SEPTEL_ROOT}/bit2byte.o ${SEPTEL_ROOT}/confirm.o ${SEPTEL_ROOT}/fmtmsg.o ${SEPTEL_ROOT}/gct_unix.o ${SEPTEL_ROOT}/hqueue.o ${SEPTEL_ROOT}/ident.o ${SEPTEL_ROOT}/mem.o ${SEPTEL_ROOT}/pack.o ${SEPTEL_ROOT}/parse.o ${SEPTEL_ROOT}/pool.o ${SEPTEL_ROOT}/sdlsig.o ${SEPTEL_ROOT}/strtonum.o ${SEPTEL_ROOT}/timer.o ${SEPTEL_ROOT}/trace.o")
|
||||
set(HAVE_SEPTEL_API TRUE)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Check for Myricom SNF support.
|
||||
if(NOT DISABLE_SNF)
|
||||
@ -1542,7 +1584,7 @@ if(NOT DISABLE_SNF)
|
||||
set(HAVE_SNF_API TRUE)
|
||||
set(PCAP_LINK_LIBRARIES ${PCAP_LINK_LIBRARIES} ${SNF_LIBRARIES})
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Check for Riverbed TurboCap support.
|
||||
if(NOT DISABLE_TC)
|
||||
@ -1563,7 +1605,7 @@ if(NOT DISABLE_TC)
|
||||
set(HAVE_TC_API TRUE)
|
||||
set(PCAP_LINK_LIBRARIES "${PCAP_LINK_LIBRARIES} ${TC_LIBRARIES} ${CMAKE_USE_PTHREADS_INIT} stdc++")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
#
|
||||
# Remote capture support.
|
||||
@ -1582,7 +1624,7 @@ if(ENABLE_REMOTE)
|
||||
# the check.
|
||||
#
|
||||
cmake_push_check_state()
|
||||
set(CMAKE_REQUIRED_INCLUDES ${CMAKE_SOURCE_DIR})
|
||||
set(CMAKE_REQUIRED_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
check_struct_has_member("struct msghdr" msg_control "ftmacros.h;sys/socket.h" HAVE_STRUCT_MSGHDR_MSG_CONTROL)
|
||||
check_struct_has_member("struct msghdr" msg_flags "ftmacros.h;sys/socket.h" HAVE_STRUCT_MSGHDR_MSG_FLAGS)
|
||||
cmake_pop_check_state()
|
||||
@ -1597,7 +1639,7 @@ endif(ENABLE_REMOTE)
|
||||
#
|
||||
# Check and add warning options if we have a .devel file.
|
||||
#
|
||||
if(EXISTS ${CMAKE_SOURCE_DIR}/.devel OR EXISTS ${CMAKE_BINARY_DIR}/.devel)
|
||||
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/.devel OR EXISTS ${CMAKE_BINARY_DIR}/.devel)
|
||||
#
|
||||
# Warning options.
|
||||
#
|
||||
@ -1808,10 +1850,12 @@ set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/grammar.c PROPERTIES
|
||||
|
||||
#
|
||||
# Assume, by default, no support for shared libraries and V7/BSD
|
||||
# convention for man pages (file formats in section 5, miscellaneous
|
||||
# info in section 7, administrative commands and daemons in section 8).
|
||||
# convention for man pages (devices in section 4, file formats in
|
||||
# section 5, miscellaneous info in section 7, administrative commands
|
||||
# and daemons in section 8). Individual cases can override this.
|
||||
# Individual cases can override this.
|
||||
#
|
||||
set(MAN_DEVICES 4)
|
||||
set(MAN_FILE_FORMATS 5)
|
||||
set(MAN_MISC_INFO 7)
|
||||
set(MAN_ADMIN_COMMANDS 8)
|
||||
@ -1869,6 +1913,7 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "OSF1")
|
||||
#
|
||||
set(MAN_FILE_FORMATS 4)
|
||||
set(MAN_MISC_INFO 5)
|
||||
set(MAN_DEVICES 7)
|
||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "SunOS" AND CMAKE_SYSTEM_VERSION MATCHES "5[.][0-9.]*")
|
||||
#
|
||||
# SunOS 5.x.
|
||||
@ -1892,6 +1937,7 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "SunOS" AND CMAKE_SYSTEM_VERSION MATCHES "5[.]
|
||||
set(MAN_ADMIN_COMMANDS 1m)
|
||||
set(MAN_FILE_FORMATS 4)
|
||||
set(MAN_MISC_INFO 5)
|
||||
set(MAN_DEVICES 7D)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@ -1944,6 +1990,16 @@ if(BUILD_SHARED_LIBS)
|
||||
add_dependencies(${LIBRARY_NAME} SerializeTarget)
|
||||
set_target_properties(${LIBRARY_NAME} PROPERTIES
|
||||
COMPILE_DEFINITIONS BUILDING_PCAP)
|
||||
#
|
||||
# No matter what the library is called - it might be called "wpcap"
|
||||
# in a Windows build - the symbol to define to indicate that we're
|
||||
# building the library, rather than a program using the library,
|
||||
# and thus that we're exporting functions defined in our public
|
||||
# header files, rather than importing those functions, is
|
||||
# pcap_EXPORTS.
|
||||
#
|
||||
set_target_properties(${LIBRARY_NAME} PROPERTIES
|
||||
DEFINE_SYMBOL pcap_EXPORTS)
|
||||
endif(BUILD_SHARED_LIBS)
|
||||
|
||||
add_library(${LIBRARY_NAME}_static STATIC
|
||||
@ -1982,7 +2038,7 @@ if(WIN32)
|
||||
# For compatibility, build the shared library without the "lib" prefix on
|
||||
# MinGW as well.
|
||||
#
|
||||
set_target_properties(${LIBRARY_NAME} PROPERTIES
|
||||
set_target_properties(${LIBRARY_NAME} PROPERTIES
|
||||
PREFIX ""
|
||||
OUTPUT_NAME "${LIBRARY_NAME}"
|
||||
)
|
||||
@ -2020,6 +2076,118 @@ if(NOT C_ADDITIONAL_FLAGS STREQUAL "")
|
||||
set_target_properties(${LIBRARY_NAME}_static PROPERTIES COMPILE_FLAGS ${C_ADDITIONAL_FLAGS})
|
||||
endif()
|
||||
|
||||
#
|
||||
# On macOS, build libpcap for the appropriate architectures, if
|
||||
# CMAKE_OSX_ARCHITECTURES isn't set (if it is, let that control
|
||||
# the architectures for which to build it).
|
||||
#
|
||||
if(APPLE AND "${CMAKE_OSX_ARCHITECTURES}" STREQUAL "")
|
||||
#
|
||||
# Get the major version of Darwin.
|
||||
#
|
||||
string(REGEX MATCH "^([0-9]+)" SYSTEM_VERSION_MAJOR "${CMAKE_SYSTEM_VERSION}")
|
||||
|
||||
if(SYSTEM_VERSION_MAJOR LESS 8)
|
||||
#
|
||||
# Pre-Tiger. Build only for 32-bit PowerPC.
|
||||
#
|
||||
set(OSX_LIBRARY_ARCHITECTURES "ppc")
|
||||
elseif(SYSTEM_VERSION_MAJOR EQUAL 8)
|
||||
#
|
||||
# Tiger. Is this prior to, or with, Intel support?
|
||||
#
|
||||
# Get the minor version of Darwin.
|
||||
#
|
||||
string(REPLACE "${SYSTEM_VERSION_MAJOR}." "" SYSTEM_MINOR_AND_PATCH_VERSION ${CMAKE_SYSTEM_VERSION})
|
||||
string(REGEX MATCH "^([0-9]+)" SYSTEM_VERSION_MINOR "${SYSTEM_MINOR_AND_PATCH_VERSION}")
|
||||
if(SYSTEM_VERSION_MINOR LESS 4)
|
||||
#
|
||||
# Prior to Intel support. Build for 32-bit
|
||||
# PowerPC and 64-bit PowerPC, with 32-bit PowerPC
|
||||
# first. (I'm guessing that's what Apple does.)
|
||||
#
|
||||
set(OSX_LIBRARY_ARCHITECTURES "ppc;ppc64")
|
||||
elseif(SYSTEM_VERSION_MINOR LESS 7)
|
||||
#
|
||||
# With Intel support but prior to x86-64 support.
|
||||
# Build for 32-bit PowerPC, 64-bit PowerPC, and 32-bit x86,
|
||||
# with 32-bit PowerPC first.
|
||||
# (I'm guessing that's what Apple does.)
|
||||
#
|
||||
set(OSX_LIBRARY_ARCHITECTURES "ppc;ppc64;i386")
|
||||
else()
|
||||
#
|
||||
# With Intel support including x86-64 support.
|
||||
# Build for 32-bit PowerPC, 64-bit PowerPC, 32-bit x86,
|
||||
# and x86-64, with 32-bit PowerPC first.
|
||||
# (I'm guessing that's what Apple does.)
|
||||
#
|
||||
set(OSX_LIBRARY_ARCHITECTURES "ppc;ppc64;i386;x86_64")
|
||||
endif()
|
||||
elseif(SYSTEM_VERSION_MAJOR EQUAL 9)
|
||||
#
|
||||
# Leopard. Build for 32-bit PowerPC, 64-bit
|
||||
# PowerPC, 32-bit x86, and x86-64, with 32-bit PowerPC
|
||||
# first. (That's what Apple does.)
|
||||
#
|
||||
set(OSX_LIBRARY_ARCHITECTURES "ppc;ppc64;i386;x86_64")
|
||||
elseif(SYSTEM_VERSION_MAJOR EQUAL 10)
|
||||
#
|
||||
# Snow Leopard. Build for x86-64, 32-bit x86, and
|
||||
# 32-bit PowerPC, with x86-64 first. (That's
|
||||
# what Apple does, even though Snow Leopard
|
||||
# doesn't run on PPC, so PPC libpcap runs under
|
||||
# Rosetta, and Rosetta doesn't support BPF
|
||||
# ioctls, so PPC programs can't do live
|
||||
# captures.)
|
||||
#
|
||||
set(OSX_LIBRARY_ARCHITECTURES "x86_64;i386;ppc")
|
||||
else()
|
||||
#
|
||||
# Post-Snow Leopard. Build for x86-64 and 32-bit x86,
|
||||
# with x86-64 first. (That's what Apple does)
|
||||
# XXX - update if and when Apple drops support
|
||||
# for 32-bit x86 code and if and when Apple adds
|
||||
# ARM-based Macs. (You're on your own for iOS etc.)
|
||||
#
|
||||
# XXX - check whether we *can* build for i386 and, if not,
|
||||
# suggest that the user install the /usr/include headers if
|
||||
# they want to build fat.
|
||||
#
|
||||
cmake_push_check_state()
|
||||
set(CMAKE_REQUIRED_FLAGS "-arch i386")
|
||||
check_c_source_compiles(
|
||||
"int
|
||||
main(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
"
|
||||
X86_32_BIT_SUPPORTED)
|
||||
cmake_pop_check_state()
|
||||
if(X86_32_BIT_SUPPORTED)
|
||||
set(OSX_LIBRARY_ARCHITECTURES "x86_64;i386")
|
||||
else()
|
||||
set(OSX_LIBRARY_ARCHITECTURES "x86_64")
|
||||
if(SYSTEM_VERSION_MAJOR LESS 18)
|
||||
#
|
||||
# Pre-Mojave; the command-line tools should be sufficient to
|
||||
# enable 32-bit x86 builds.
|
||||
#
|
||||
message(WARNING "Compiling for 32-bit x86 gives an error; try installing the command-line tools")
|
||||
else()
|
||||
message(WARNING "Compiling for 32-bit x86 gives an error; try installing the command-line tools and, after that, installing the /usr/include headers from the /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg package")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
if(BUILD_SHARED_LIBS)
|
||||
set_target_properties(${LIBRARY_NAME} PROPERTIES
|
||||
OSX_ARCHITECTURES "${OSX_LIBRARY_ARCHITECTURES}")
|
||||
endif(BUILD_SHARED_LIBS)
|
||||
set_target_properties(${LIBRARY_NAME}_static PROPERTIES
|
||||
OSX_ARCHITECTURES "${OSX_LIBRARY_ARCHITECTURES}")
|
||||
endif()
|
||||
|
||||
######################################
|
||||
# Write out the config.h file
|
||||
######################################
|
||||
@ -2079,6 +2247,7 @@ set(MAN3PCAP_EXPAND
|
||||
pcap_list_tstamp_types.3pcap.in
|
||||
pcap_open_dead.3pcap.in
|
||||
pcap_open_offline.3pcap.in
|
||||
pcap_set_immediate_mode.3pcap.in
|
||||
pcap_set_tstamp_precision.3pcap.in
|
||||
pcap_set_tstamp_type.3pcap.in
|
||||
)
|
||||
@ -2114,9 +2283,8 @@ set(MAN3PCAP_NOEXPAND
|
||||
pcap_open_live.3pcap
|
||||
pcap_set_buffer_size.3pcap
|
||||
pcap_set_datalink.3pcap
|
||||
pcap_set_immediate_mode.3pcap
|
||||
pcap_set_promisc.3pcap
|
||||
pcap_set_protocol.3pcap
|
||||
pcap_set_protocol_linux.3pcap
|
||||
pcap_set_rfmon.3pcap
|
||||
pcap_set_snaplen.3pcap
|
||||
pcap_set_timeout.3pcap
|
||||
@ -2179,11 +2347,13 @@ if(WIN32)
|
||||
endif(NOT MINGW)
|
||||
endif(MSVC AND CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
else(WIN32)
|
||||
install(TARGETS ${LIBRARY_NAME} ${LIBRARY_NAME_STATIC} DESTINATION lib)
|
||||
install(TARGETS ${LIBRARY_NAME} ${LIBRARY_NAME_STATIC} DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR})
|
||||
endif(WIN32)
|
||||
|
||||
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/pcap/ DESTINATION include/pcap)
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/pcap.h DESTINATION include)
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/pcap-bpf.h DESTINATION include)
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/pcap-namedb.h DESTINATION include)
|
||||
|
||||
# On UN*X, and on Windows when not using MSVC, generate libpcap.pc and
|
||||
# pcap-config and process man pages and arrange that they be installed.
|
||||
@ -2223,8 +2393,8 @@ if(NOT MSVC)
|
||||
foreach(LIB ${PCAP_LINK_LIBRARIES})
|
||||
set(LIBS "${LIBS} -l${LIB}")
|
||||
endforeach(LIB)
|
||||
configure_file(${CMAKE_SOURCE_DIR}/pcap-config.in ${CMAKE_CURRENT_BINARY_DIR}/pcap-config @ONLY)
|
||||
configure_file(${CMAKE_SOURCE_DIR}/libpcap.pc.in ${CMAKE_CURRENT_BINARY_DIR}/libpcap.pc @ONLY)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/pcap-config.in ${CMAKE_CURRENT_BINARY_DIR}/pcap-config @ONLY)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libpcap.pc.in ${CMAKE_CURRENT_BINARY_DIR}/libpcap.pc @ONLY)
|
||||
install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/pcap-config DESTINATION bin)
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libpcap.pc DESTINATION lib/pkgconfig)
|
||||
|
||||
@ -2236,17 +2406,17 @@ if(NOT MSVC)
|
||||
#
|
||||
set(MAN1 "")
|
||||
foreach(MANPAGE ${MAN1_NOEXPAND})
|
||||
set(MAN1 ${MAN1} ${CMAKE_SOURCE_DIR}/${MANPAGE})
|
||||
set(MAN1 ${MAN1} ${CMAKE_CURRENT_SOURCE_DIR}/${MANPAGE})
|
||||
endforeach(MANPAGE)
|
||||
install(FILES ${MAN1} DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
|
||||
|
||||
set(MAN3PCAP "")
|
||||
foreach(MANPAGE ${MAN3PCAP_NOEXPAND})
|
||||
set(MAN3PCAP ${MAN3PCAP} ${CMAKE_SOURCE_DIR}/${MANPAGE})
|
||||
set(MAN3PCAP ${MAN3PCAP} ${CMAKE_CURRENT_SOURCE_DIR}/${MANPAGE})
|
||||
endforeach(MANPAGE)
|
||||
foreach(TEMPLATE_MANPAGE ${MAN3PCAP_EXPAND})
|
||||
string(REPLACE ".in" "" MANPAGE ${TEMPLATE_MANPAGE})
|
||||
configure_file(${CMAKE_SOURCE_DIR}/${TEMPLATE_MANPAGE} ${CMAKE_CURRENT_BINARY_DIR}/${MANPAGE} @ONLY)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/${TEMPLATE_MANPAGE} ${CMAKE_CURRENT_BINARY_DIR}/${MANPAGE} @ONLY)
|
||||
set(MAN3PCAP ${MAN3PCAP} ${CMAKE_CURRENT_BINARY_DIR}/${MANPAGE})
|
||||
endforeach(TEMPLATE_MANPAGE)
|
||||
install(FILES ${MAN3PCAP} DESTINATION ${CMAKE_INSTALL_MANDIR}/man3)
|
||||
@ -2270,7 +2440,7 @@ if(NOT MSVC)
|
||||
set(MANFILE "")
|
||||
foreach(TEMPLATE_MANPAGE ${MANFILE_EXPAND})
|
||||
string(REPLACE ".manfile.in" ".${MAN_FILE_FORMATS}" MANPAGE ${TEMPLATE_MANPAGE})
|
||||
configure_file(${CMAKE_SOURCE_DIR}/${TEMPLATE_MANPAGE} ${CMAKE_CURRENT_BINARY_DIR}/${MANPAGE} @ONLY)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/${TEMPLATE_MANPAGE} ${CMAKE_CURRENT_BINARY_DIR}/${MANPAGE} @ONLY)
|
||||
set(MANFILE ${MANFILE} ${CMAKE_CURRENT_BINARY_DIR}/${MANPAGE})
|
||||
endforeach(TEMPLATE_MANPAGE)
|
||||
install(FILES ${MANFILE} DESTINATION ${CMAKE_INSTALL_MANDIR}/man${MAN_FILE_FORMATS})
|
||||
@ -2278,7 +2448,7 @@ if(NOT MSVC)
|
||||
set(MANMISC "")
|
||||
foreach(TEMPLATE_MANPAGE ${MANMISC_EXPAND})
|
||||
string(REPLACE ".manmisc.in" ".${MAN_MISC_INFO}" MANPAGE ${TEMPLATE_MANPAGE})
|
||||
configure_file(${CMAKE_SOURCE_DIR}/${TEMPLATE_MANPAGE} ${CMAKE_CURRENT_BINARY_DIR}/${MANPAGE} @ONLY)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/${TEMPLATE_MANPAGE} ${CMAKE_CURRENT_BINARY_DIR}/${MANPAGE} @ONLY)
|
||||
set(MANMISC ${MANMISC} ${CMAKE_CURRENT_BINARY_DIR}/${MANPAGE})
|
||||
endforeach(TEMPLATE_MANPAGE)
|
||||
install(FILES ${MANMISC} DESTINATION ${CMAKE_INSTALL_MANDIR}/man${MAN_MISC_INFO})
|
||||
|
@ -25,5 +25,5 @@ Please note that if you know exactly how to solve the problem and the solution
|
||||
would not be too intrusive, it would be best to contribute some development time
|
||||
and open a pull request instead.
|
||||
|
||||
Still not sure how to do? Feel free to [subscribe](http://www.tcpdump.org/#mailing-lists)
|
||||
Still not sure how to do? Feel free to [subscribe](https://www.tcpdump.org/#mailing-lists)
|
||||
to the mailing list tcpdump-workers@lists.tcpdump.org and ask!
|
28
CREDITS
28
CREDITS
@ -1,21 +1,18 @@
|
||||
This file lists people who have contributed to libpcap:
|
||||
This file lists people who have contributed to libpcap.
|
||||
|
||||
The current maintainers:
|
||||
Bill Fenner <fenner at research dot att dot com>
|
||||
The current maintainers (in alphabetical order):
|
||||
Denis Ovsienko <denis at ovsienko dot info>
|
||||
Fulvio Risso <risso at polito dot it>
|
||||
Francois-Xavier Le Bail <devel dot fx dot lebail at orange dot fr>
|
||||
Guy Harris <guy at alum dot mit dot edu>
|
||||
Hannes Gredler <hannes at juniper dot net>
|
||||
Michael Richardson <mcr at sandelman dot ottawa dot on dot ca>
|
||||
Francois-Xavier Le Bail <fx dot lebail at yahoo dot com>
|
||||
|
||||
Additional people who have contributed patches:
|
||||
|
||||
Additional people who have contributed patches (in alphabetical order):
|
||||
Akos Vandra <axos88 at gmail dot com>
|
||||
Alan Bawden <Alan at LCS dot MIT dot EDU>
|
||||
Albert Chin <china at thewrittenword dot com>
|
||||
Alexander 'Leo' Bergolth <Leo dot Bergolth at wu-wien dot ac dot at>
|
||||
Alexey Kuznetsov <kuznet at ms2 dot inr dot ac dot ru>
|
||||
Ali Abdulkadir <autostart dot ini at gmail dot com>
|
||||
Alon Bar-Lev <alonbl at sourceforge dot net>
|
||||
Andres Perera <andres dot p at zoho dot com>
|
||||
Andrew Brown <atatat at atatdot dot net>
|
||||
@ -62,6 +59,7 @@ Additional people who have contributed patches:
|
||||
Gabor Tatarka <gabor dot tatarka at ericsson dot com>
|
||||
Garrett Cooper <yaberauneya at sourceforge dot net>
|
||||
George Neville-Neil <gnn at freebsd dot org>
|
||||
Gerard Garcia <nouboh at gmail 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>
|
||||
@ -99,6 +97,7 @@ Additional people who have contributed patches:
|
||||
Koryn Grant <koryn at endace dot com>
|
||||
Kris Katterjohn <katterjohn at gmail dot com>
|
||||
Krzysztof Halasa <khc at pm dot waw dot pl>
|
||||
Lennert Buytenhek <buytenh at wantstofly dot org>
|
||||
Lorenzo Cavallaro <sullivan at sikurezza dot org>
|
||||
Loris Degioanni <loris at netgroup-serv dot polito dot it>
|
||||
Love Hörnquist-Åstrand <lha at stacken dot kth dot se>
|
||||
@ -114,6 +113,7 @@ Additional people who have contributed patches:
|
||||
Márton Németh <nm127 at freemail dot hu>
|
||||
Matthew Luckie <mjl at luckie dot org dot nz>
|
||||
Max Laier <max at love2party dot net>
|
||||
Michal Kubecek <mkubecek at suse dot cz>
|
||||
Michal Labedzki <michal dot labedzki at tieto dot com>
|
||||
Michal Sekletar <msekleta at redhat dot com>
|
||||
Mike Frysinger <vapier at gmail dot com>
|
||||
@ -129,7 +129,7 @@ Additional people who have contributed patches:
|
||||
Olaf Kirch <okir at caldera dot de>
|
||||
Ollie Wild <aaw at users dot sourceforge dot net>
|
||||
Onno van der Linden <onno at simplex dot nl>
|
||||
Paolo Abeni <paolo dot abeni at email dot it>
|
||||
Paolo Abeni <pabeni at redhat dot com>
|
||||
Patrick Marie <mycroft at virgaria dot org>
|
||||
Patrick McHardy <kaber at trash not net>
|
||||
Paul Mundt <lethal at linux-sh dot org>
|
||||
@ -145,6 +145,8 @@ Additional people who have contributed patches:
|
||||
Rick Jones <raj at cup dot hp dot com>
|
||||
Robert Edmonds <stu-42 at sourceforge dot net>
|
||||
Roberto Mariani <jelot-tcpdump at jelot dot it>
|
||||
Rongxi Li <rongxi dot li at chaitin dot com>
|
||||
Roland Dreier <roland at purestorage dot com>
|
||||
Romain Francoise <rfrancoise at debian dot org>
|
||||
Sagun Shakya <sagun dot shakya at sun dot com>
|
||||
Scott Barron <sb125499 at ohiou dot edu>
|
||||
@ -167,6 +169,7 @@ Additional people who have contributed patches:
|
||||
Wesley Shields <wxs at FreeBSD dot org>
|
||||
Xianjie Zhang <xzhang at cup dot hp dot com>
|
||||
Xin Li <delphij at FreeBSD dot org>
|
||||
Xue Jiang Qing <xuejianqing at star-net dot cn>
|
||||
Yen Yen Lim
|
||||
Yoann Vandoorselaere <yoann at prelude-ids dot org>
|
||||
Yvan Vanhullebus <vanhu at sourceforge dot net>
|
||||
@ -176,5 +179,8 @@ The original LBL crew:
|
||||
Craig Leres
|
||||
Van Jacobson
|
||||
|
||||
Past maintainers:
|
||||
Jun-ichiro itojun Hagino <itojun at iijlab dot net> Also see: http://www.wide.ad.jp/itojun-award/
|
||||
Past maintainers (in alphabetical order):
|
||||
Bill Fenner <fenner at research dot att dot com>
|
||||
Fulvio Risso <risso at polito dot it>
|
||||
Hannes Gredler <hannes at gredler dot at>
|
||||
Jun-ichiro itojun Hagino <itojun at iijlab dot net> Also see: http://www.wide.ad.jp/itojun-award/
|
||||
|
@ -69,10 +69,6 @@ before /usr/ucb or else:
|
||||
before running configure. (You might have to do a "make distclean"
|
||||
if you already ran configure once).
|
||||
|
||||
Also note that "make depend" won't work; while all of the known
|
||||
universe uses -M, the SPARCompiler uses -xM to generate makefile
|
||||
dependencies.
|
||||
|
||||
If you are trying to do packet capture with a FORE ATM card, you may or
|
||||
may not be able to. They usually only release their driver in object
|
||||
code so unless their driver supports packet capture, there's not much
|
||||
@ -258,27 +254,26 @@ ChmodBPF/* - macOS startup item to set ownership and permissions
|
||||
CMakeLists.txt - CMake file
|
||||
CONTRIBUTING - guidelines for contributing
|
||||
CREDITS - people that have helped libpcap along
|
||||
INSTALL.txt - this file
|
||||
INSTALL.md - this file
|
||||
LICENSE - the license under which tcpdump is distributed
|
||||
Makefile.in - compilation rules (input to the configure script)
|
||||
README - description of distribution
|
||||
README.aix - notes on using libpcap on AIX
|
||||
README.dag - notes on using libpcap to capture on Endace DAG devices
|
||||
README.hpux - notes on using libpcap on HP-UX
|
||||
README.linux - notes on using libpcap on Linux
|
||||
README.macos - notes on using libpcap on macOS
|
||||
README.septel - notes on using libpcap to capture on Intel/Septel devices
|
||||
README.sita - notes on using libpcap to capture on SITA devices
|
||||
README.tru64 - notes on using libpcap on Digital/Tru64 UNIX
|
||||
README.Win32 - notes on using libpcap on Win32 systems (with WinPcap)
|
||||
README.md - description of distribution
|
||||
doc/README.aix - notes on using libpcap on AIX
|
||||
doc/README.dag - notes on using libpcap to capture on Endace DAG devices
|
||||
doc/README.hpux - notes on using libpcap on HP-UX
|
||||
doc/README.linux.md - notes on using libpcap on Linux
|
||||
doc/README.macos - notes on using libpcap on macOS
|
||||
doc/README.septel - notes on using libpcap to capture on Intel/Septel devices
|
||||
doc/README.sita - notes on using libpcap to capture on SITA devices
|
||||
doc/README.tru64 - notes on using libpcap on Digital/Tru64 UNIX
|
||||
doc/README.Win32 - notes on using libpcap on Win32 systems (with Npcap)
|
||||
VERSION - version of this release
|
||||
acconfig.h - support for post-2.13 autoconf
|
||||
aclocal.m4 - autoconf macros
|
||||
arcnet.h - ARCNET definitions
|
||||
atmuni31.h - ATM Q.2931 definitions
|
||||
bpf/net - copy of bpf_filter.c
|
||||
bpf_dump.c - BPF program printing routines
|
||||
bpf_filter.c - symlink to bpf/net/bpf_filter.c
|
||||
bpf_filter.c - BPF filtering routines
|
||||
bpf_image.c - BPF disassembly routine
|
||||
config.guess - autoconf support
|
||||
config.h.in - autoconf input
|
47
Makefile.in
47
Makefile.in
@ -69,7 +69,7 @@ INSTALL_RPCAPD=@INSTALL_RPCAPD@
|
||||
EXTRA_NETWORK_LIBS=@EXTRA_NETWORK_LIBS@
|
||||
|
||||
# Standard CFLAGS for building members of a shared library
|
||||
FULL_CFLAGS = $(CCOPT) $(SHLIB_CCOPT) $(INCLS) $(DEFS) $(CFLAGS)
|
||||
FULL_CFLAGS = $(CCOPT) @V_LIB_CCOPT_FAT@ $(SHLIB_CCOPT) $(INCLS) $(DEFS) $(CFLAGS)
|
||||
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
@ -117,6 +117,7 @@ PUBHDR = \
|
||||
pcap/nflog.h \
|
||||
pcap/pcap.h \
|
||||
pcap/sll.h \
|
||||
pcap/socket.h \
|
||||
pcap/vlan.h \
|
||||
pcap/usb.h
|
||||
|
||||
@ -168,6 +169,7 @@ MAN3PCAP_EXPAND = \
|
||||
pcap_list_tstamp_types.3pcap.in \
|
||||
pcap_open_dead.3pcap.in \
|
||||
pcap_open_offline.3pcap.in \
|
||||
pcap_set_immediate_mode.3pcap.in \
|
||||
pcap_set_tstamp_precision.3pcap.in \
|
||||
pcap_set_tstamp_type.3pcap.in
|
||||
|
||||
@ -203,9 +205,8 @@ MAN3PCAP_NOEXPAND = \
|
||||
pcap_open_live.3pcap \
|
||||
pcap_set_buffer_size.3pcap \
|
||||
pcap_set_datalink.3pcap \
|
||||
pcap_set_immediate_mode.3pcap \
|
||||
pcap_set_promisc.3pcap \
|
||||
pcap_set_protocol.3pcap \
|
||||
pcap_set_protocol_linux.3pcap \
|
||||
pcap_set_rfmon.3pcap \
|
||||
pcap_set_snaplen.3pcap \
|
||||
pcap_set_timeout.3pcap \
|
||||
@ -235,21 +236,13 @@ EXTRA_DIST = \
|
||||
ChmodBPF/StartupParameters.plist \
|
||||
CREDITS \
|
||||
CMakeLists.txt \
|
||||
INSTALL.txt \
|
||||
INSTALL.md \
|
||||
LICENSE \
|
||||
Makefile.in \
|
||||
Makefile-devel-adds \
|
||||
README \
|
||||
README.aix \
|
||||
README.dag \
|
||||
README.hpux \
|
||||
README.linux \
|
||||
README.macos \
|
||||
README.septel \
|
||||
README.sita \
|
||||
README.tru64 \
|
||||
README.Win32 \
|
||||
CONTRIBUTING \
|
||||
README.md \
|
||||
doc \
|
||||
CONTRIBUTING.md \
|
||||
TODO \
|
||||
VERSION \
|
||||
aclocal.m4 \
|
||||
@ -284,10 +277,14 @@ EXTRA_DIST = \
|
||||
lbl/os-sunos4.h \
|
||||
lbl/os-ultrix4.h \
|
||||
libpcap.pc.in \
|
||||
missing/asprintf.c \
|
||||
missing/getopt.c \
|
||||
missing/getopt.h \
|
||||
missing/snprintf.c \
|
||||
missing/strlcat.c \
|
||||
missing/strlcpy.c \
|
||||
missing/strtok_r.c \
|
||||
missing/win_asprintf.c \
|
||||
missing/win_snprintf.c \
|
||||
mkdep \
|
||||
msdos/bin2c.c \
|
||||
@ -355,16 +352,18 @@ EXTRA_DIST = \
|
||||
rpcapd/fileconf.c \
|
||||
rpcapd/fileconf.h \
|
||||
rpcapd/log.h \
|
||||
rpcapd/log-stderr.c \
|
||||
rpcapd/log.c \
|
||||
rpcapd/org.tcpdump.rpcapd.plist \
|
||||
rpcapd/rpcapd.c \
|
||||
rpcapd/rpcapd.h \
|
||||
rpcapd/rpcapd.inetd.conf \
|
||||
rpcapd/rpcapd.manadmin.in \
|
||||
rpcapd/rpcapd-config.manfile.in \
|
||||
rpcapd/rpcapd.rc \
|
||||
rpcapd/rpcapd.socket \
|
||||
rpcapd/rpcapd.xinetd.conf \
|
||||
rpcapd/rpcapd@.service \
|
||||
rpcapd/win32-svc.c \
|
||||
rpcapd/win32-svc.h \
|
||||
sockutils.c \
|
||||
sockutils.h \
|
||||
@ -424,7 +423,7 @@ libpcap.dylib: $(OBJ)
|
||||
MAJOR_VER=A; \
|
||||
COMPAT_VER=1; \
|
||||
CURRENT_VER=`sed 's/[^0-9.].*$$//' $(srcdir)/VERSION`; \
|
||||
$(CC) -dynamiclib -undefined error $(LDFLAGS) \
|
||||
$(CC) -dynamiclib -undefined error $(LDFLAGS) @V_LIB_LDFLAGS_FAT@ \
|
||||
-o libpcap.$$VER.dylib $(OBJ) $(ADDLOBJS) $(LIBS) \
|
||||
-install_name $(libdir)/libpcap.$$MAJOR_VER.dylib \
|
||||
-compatibility_version $$COMPAT_VER \
|
||||
@ -496,9 +495,18 @@ grammar.o: grammar.c scanner.h
|
||||
gencode.o: $(srcdir)/gencode.c grammar.h scanner.h
|
||||
$(CC) $(FULL_CFLAGS) -c $(srcdir)/gencode.c
|
||||
|
||||
asprintf.o: $(srcdir)/missing/asprintf.c
|
||||
$(CC) $(FULL_CFLAGS) -o $@ -c $(srcdir)/missing/asprintf.c
|
||||
|
||||
snprintf.o: $(srcdir)/missing/snprintf.c
|
||||
$(CC) $(FULL_CFLAGS) -o $@ -c $(srcdir)/missing/snprintf.c
|
||||
|
||||
strlcat.o: $(srcdir)/missing/strlcat.c
|
||||
$(CC) $(FULL_CFLAGS) -o $@ -c $(srcdir)/missing/strlcat.c
|
||||
|
||||
strlcpy.o: $(srcdir)/missing/strlcpy.c
|
||||
$(CC) $(FULL_CFLAGS) -o $@ -c $(srcdir)/missing/strlcpy.c
|
||||
|
||||
strtok_r.o: $(srcdir)/missing/strtok_r.c
|
||||
$(CC) $(FULL_CFLAGS) -o $@ -c $(srcdir)/missing/strtok_r.c
|
||||
|
||||
@ -582,6 +590,9 @@ install: install-shared install-archive libpcap.pc pcap-config @INSTALL_RPCAPD@
|
||||
rm -f pcap_datalink_val_to_description.3pcap && \
|
||||
$(LN_S) pcap_datalink_val_to_name.3pcap \
|
||||
pcap_datalink_val_to_description.3pcap && \
|
||||
rm -f pcap_datalink_val_to_description_or_dlt.3pcap && \
|
||||
$(LN_S) pcap_datalink_val_to_name.3pcap \
|
||||
pcap_datalink_val_to_description_or_dlt.3pcap && \
|
||||
rm -f pcap_dump_fopen.3pcap && \
|
||||
$(LN_S) pcap_dump_open.3pcap pcap_dump_fopen.3pcap && \
|
||||
rm -f pcap_freealldevs.3pcap && \
|
||||
@ -751,7 +762,7 @@ tags: $(TAGFILES)
|
||||
releasetar:
|
||||
@cwd=`pwd` ; dir=`basename $$cwd` ; name=$(PROG)-`cat VERSION` ; \
|
||||
mkdir $$name; \
|
||||
tar cf - $(CSRC) $(HDR) $(MAN1) $(MAN3PCAP_EXPAND) \
|
||||
tar -c --exclude='*~' -f - $(CSRC) $(HDR) $(MAN1) $(MAN3PCAP_EXPAND) \
|
||||
$(MAN3PCAP_NOEXPAND) $(MANFILE) $(MANMISC) $(EXTRA_DIST) | \
|
||||
(cd $$name; tar xf -); \
|
||||
tar -c -z -f $$name.tar.gz $$name; \
|
||||
|
46
README.Win32
46
README.Win32
@ -1,46 +0,0 @@
|
||||
Under Win32, libpcap is integrated in the WinPcap packet capture system.
|
||||
WinPcap provides a framework that allows libpcap to capture the packets
|
||||
under Windows 95, Windows 98, Windows ME, Windows NT 4, Windows 2000
|
||||
and Windows XP.
|
||||
WinPcap binaries and source code can be found at http://winpcap.polito.it:
|
||||
they include also a developer's pack with all the necessary to compile
|
||||
libpcap-based applications under Windows.
|
||||
|
||||
How to compile libpcap with Visual Studio
|
||||
-----------------------------------------
|
||||
|
||||
In order to compile libpcap you will need:
|
||||
|
||||
- version 6 (or higher) of Microsoft Visual Studio
|
||||
- The November 2001 (or later) edition of Microsoft Platform
|
||||
Software Development Kit (SDK), that contains some necessary includes
|
||||
for IPv6 support. You can download it from http://www.microsoft.com/sdk
|
||||
- the latest WinPcap sources from http://winpcap.polito.it/install
|
||||
|
||||
The WinPcap source code already contains a recent (usually the latest
|
||||
stable) version of libpcap. If you need to compile a different one,
|
||||
simply download it from www.tcpdump.org and copy the sources in the
|
||||
winpcap\wpcap\libpcap folder of the WinPcap distribution. If you want to
|
||||
compile a libpcap source retrieved from the tcpdump.org Git, you will
|
||||
have to create the scanner and the grammar by hand (with lex and yacc)
|
||||
or with the cygnus makefile, since The Visual Studio project is not able
|
||||
to build them.
|
||||
|
||||
Open the project file winpcap\wpcap\prj\wpcap.dsw with Visual Studio and
|
||||
build wpcap.dll. wpcap.lib, the library file to link with the applications,
|
||||
will be generated in winpcap\wpcap\lib\. wpcap.dll will be generated in
|
||||
winpcap\wpcap\prj\release or winpcap\wpcap\prj\debug depending on the type
|
||||
of binary that is being created.
|
||||
|
||||
How to compile libpcap with Cygnus
|
||||
----------------------------------
|
||||
|
||||
To build wpcap.dll, cd to the directory WPCAP/PRJ of the WinPcap source code
|
||||
distribution and type "make". libwpcap.a, the library file to link with the
|
||||
applications, will be generated in winpcap\wpcap\lib\. wpcap.dll will be
|
||||
generated in winpcap\wpcap\prj.
|
||||
|
||||
Remember, you CANNOT use the MSVC-generated .lib files with gcc, use
|
||||
libwpcap.a instead.
|
||||
|
||||
"make install" installs wpcap.dll in the Windows system folder.
|
@ -2,14 +2,17 @@ To report a security issue please send an e-mail to security@tcpdump.org.
|
||||
|
||||
To report bugs and other problems, contribute patches, request a
|
||||
feature, provide generic feedback etc please see the file
|
||||
CONTRIBUTING in the libpcap source tree root.
|
||||
[CONTRIBUTING](CONTRIBUTING.md) in the libpcap source tree root.
|
||||
|
||||
The directory doc/ has README files about specific operating systems and
|
||||
options.
|
||||
|
||||
LIBPCAP 1.x.y
|
||||
Now maintained by "The Tcpdump Group"
|
||||
https://www.tcpdump.org
|
||||
|
||||
Anonymous Git is available via:
|
||||
git clone git://bpf.tcpdump.org/libpcap
|
||||
https://github.com/the-tcpdump-group/libpcap.git
|
||||
|
||||
formerly from Lawrence Berkeley National Laboratory
|
||||
Network Research Group <libpcap@ee.lbl.gov>
|
||||
@ -67,9 +70,10 @@ kernel source and/or object patches available in:
|
||||
|
||||
https://www.tcpdump.org/other/bpfext42.tar.Z
|
||||
|
||||
Linux, in the 2.2 kernel and later kernels, has a "Socket Filter"
|
||||
mechanism that accepts BPF filters; see the README.linux file for
|
||||
information on configuring that option.
|
||||
Linux has a number of BPF based systems, and libpcap does not support
|
||||
any of the eBPF mechanisms as yet, although it supports many of the
|
||||
memory mapped receive mechanisms.
|
||||
See the [README.linux](doc/README.linux.md) file for more information.
|
||||
|
||||
Note to Linux distributions and *BSD systems that include libpcap:
|
||||
|
101
aclocal.m4
vendored
101
aclocal.m4
vendored
@ -266,6 +266,14 @@ dnl Check whether the compiler option specified as the second argument
|
||||
dnl is supported by the compiler and, if so, add it to the macro
|
||||
dnl specified as the first argument
|
||||
dnl
|
||||
dnl If a third argument is supplied, treat it as C code to be compiled
|
||||
dnl with the flag in question, and the "treat warnings as errors" flag
|
||||
dnl set, and don't add the flag to the first argument if the compile
|
||||
dnl fails; this is for warning options cause problems that can't be
|
||||
dnl worked around. If a third argument is supplied, a fourth argument
|
||||
dnl should also be supplied; it's a message desribing what the test
|
||||
dnl program is checking.
|
||||
dnl
|
||||
AC_DEFUN(AC_LBL_CHECK_COMPILER_OPT,
|
||||
[
|
||||
AC_MSG_CHECKING([whether the compiler supports the $2 option])
|
||||
@ -287,8 +295,38 @@ AC_DEFUN(AC_LBL_CHECK_COMPILER_OPT,
|
||||
[return 0],
|
||||
[
|
||||
AC_MSG_RESULT([yes])
|
||||
can_add_to_cflags=yes
|
||||
#
|
||||
# The compile supports this; do we have some C code for
|
||||
# which the warning should *not* appear?
|
||||
# We test the fourth argument because the third argument
|
||||
# could contain quotes, breaking the test.
|
||||
#
|
||||
if test "x$4" != "x"
|
||||
then
|
||||
CFLAGS="$CFLAGS $ac_lbl_cc_force_warning_errors"
|
||||
AC_MSG_CHECKING(whether $2 $4)
|
||||
AC_COMPILE_IFELSE(
|
||||
[AC_LANG_SOURCE($3)],
|
||||
[
|
||||
#
|
||||
# Not a problem.
|
||||
#
|
||||
AC_MSG_RESULT(no)
|
||||
],
|
||||
[
|
||||
#
|
||||
# A problem.
|
||||
#
|
||||
AC_MSG_RESULT(yes)
|
||||
can_add_to_cflags=no
|
||||
])
|
||||
fi
|
||||
CFLAGS="$save_CFLAGS"
|
||||
$1="$$1 $2"
|
||||
if test x"$can_add_to_cflags" = "xyes"
|
||||
then
|
||||
$1="$$1 $2"
|
||||
fi
|
||||
],
|
||||
[
|
||||
AC_MSG_RESULT([no])
|
||||
@ -446,7 +484,7 @@ AC_DEFUN(AC_LBL_SHLIBS_INIT,
|
||||
aix*)
|
||||
;;
|
||||
|
||||
freebsd*|netbsd*|openbsd*|dragonfly*|linux*|osf*)
|
||||
freebsd*|netbsd*|openbsd*|dragonfly*|linux*|osf*|midipix*)
|
||||
#
|
||||
# Platforms where the linker is the GNU linker
|
||||
# or accepts command-line arguments like
|
||||
@ -463,7 +501,7 @@ AC_DEFUN(AC_LBL_SHLIBS_INIT,
|
||||
sparc64*)
|
||||
case "$host_os" in
|
||||
|
||||
freebsd*|openbsd*)
|
||||
freebsd*|openbsd*|linux*)
|
||||
PIC_OPT=-fPIC
|
||||
;;
|
||||
esac
|
||||
@ -840,23 +878,58 @@ AC_DEFUN(AC_LBL_DEVEL,
|
||||
#
|
||||
if test "$ac_lbl_cc_dont_try_gcc_dashW" != yes; then
|
||||
AC_LBL_CHECK_UNKNOWN_WARNING_OPTION_ERROR()
|
||||
AC_LBL_CHECK_COMPILER_OPT($1, -W)
|
||||
AC_LBL_CHECK_COMPILER_OPT($1, -Wall)
|
||||
AC_LBL_CHECK_COMPILER_OPT($1, -Wsign-compare)
|
||||
AC_LBL_CHECK_COMPILER_OPT($1, -Wmissing-prototypes)
|
||||
AC_LBL_CHECK_COMPILER_OPT($1, -Wstrict-prototypes)
|
||||
AC_LBL_CHECK_COMPILER_OPT($1, -Wshadow)
|
||||
AC_LBL_CHECK_COMPILER_OPT($1, -Wdeclaration-after-statement)
|
||||
AC_LBL_CHECK_COMPILER_OPT($1, -Wused-but-marked-unused)
|
||||
AC_LBL_CHECK_COMPILER_OPT($1, -Wdocumentation)
|
||||
AC_LBL_CHECK_COMPILER_OPT($1, -Wcomma)
|
||||
AC_LBL_CHECK_COMPILER_OPT($1, -Wdeclaration-after-statement)
|
||||
AC_LBL_CHECK_COMPILER_OPT($1, -Wdocumentation)
|
||||
AC_LBL_CHECK_COMPILER_OPT($1, -Wformat-nonliteral)
|
||||
AC_LBL_CHECK_COMPILER_OPT($1, -Wmissing-noreturn)
|
||||
AC_LBL_CHECK_COMPILER_OPT($1, -Wmissing-prototypes)
|
||||
AC_LBL_CHECK_COMPILER_OPT($1, -Wmissing-variable-declarations)
|
||||
AC_LBL_CHECK_COMPILER_OPT($1, -Wshadow)
|
||||
AC_LBL_CHECK_COMPILER_OPT($1, -Wsign-compare)
|
||||
AC_LBL_CHECK_COMPILER_OPT($1, -Wstrict-prototypes)
|
||||
AC_LBL_CHECK_COMPILER_OPT($1, -Wunused-parameter)
|
||||
AC_LBL_CHECK_COMPILER_OPT($1, -Wused-but-marked-unused)
|
||||
# Warns about safeguards added in case the enums are
|
||||
# extended
|
||||
# AC_LBL_CHECK_COMPILER_OPT($1, -Wcovered-switch-default)
|
||||
AC_LBL_CHECK_COMPILER_OPT($1, -Wmissing-variable-declarations)
|
||||
AC_LBL_CHECK_COMPILER_OPT($1, -Wunused-parameter)
|
||||
AC_LBL_CHECK_COMPILER_OPT($1, -Wformat-nonliteral)
|
||||
AC_LBL_CHECK_COMPILER_OPT($1, -Wunreachable-code)
|
||||
#
|
||||
# This can cause problems with ntohs(), ntohl(),
|
||||
# htons(), and htonl() on some platforms, such
|
||||
# as OpenBSD 6.3 with Clang 5.0.1. I guess the
|
||||
# problem is that the macro that ultimately does
|
||||
# the byte-swapping involves a conditional
|
||||
# expression that tests whether the value being
|
||||
# swapped is a compile-time constant or not,
|
||||
# using __builtin_constant_p(), and, depending
|
||||
# on whether it is, does a compile-time swap or
|
||||
# a run-time swap; perhaps the compiler always
|
||||
# considers one of the two results of the
|
||||
# conditional expressin is never evaluated,
|
||||
# because the conditional check is done at
|
||||
# compile time, and thus always says "that
|
||||
# expression is never executed".
|
||||
#
|
||||
# (Perhaps there should be a way of flagging
|
||||
# an expression that you *want* evaluated at
|
||||
# compile time, so that the compiler 1) warns
|
||||
# if it *can't* be evaluated at compile time
|
||||
# and 2) *doesn't* warn that the true or false
|
||||
# branch will never be reached.)
|
||||
#
|
||||
AC_LBL_CHECK_COMPILER_OPT($1, -Wunreachable-code,
|
||||
[
|
||||
#include <arpa/inet.h>
|
||||
|
||||
unsigned short
|
||||
testme(unsigned short a)
|
||||
{
|
||||
return ntohs(a);
|
||||
}
|
||||
],
|
||||
[generates warnings from ntohs()])
|
||||
fi
|
||||
AC_LBL_CHECK_DEPENDENCY_GENERATION_OPT()
|
||||
#
|
||||
|
21
bpf_filter.c
21
bpf_filter.c
@ -51,7 +51,7 @@
|
||||
#include <sys/time.h>
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#include <pcap/bpf.h>
|
||||
#include <pcap-int.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
@ -328,11 +328,17 @@ bpf_filter_with_aux_data(const struct bpf_insn *pc, const u_char *p,
|
||||
continue;
|
||||
|
||||
case BPF_ALU|BPF_LSH|BPF_X:
|
||||
A <<= X;
|
||||
if (X < 32)
|
||||
A <<= X;
|
||||
else
|
||||
A = 0;
|
||||
continue;
|
||||
|
||||
case BPF_ALU|BPF_RSH|BPF_X:
|
||||
A >>= X;
|
||||
if (X < 32)
|
||||
A >>= X;
|
||||
else
|
||||
A = 0;
|
||||
continue;
|
||||
|
||||
case BPF_ALU|BPF_ADD|BPF_K:
|
||||
@ -378,10 +384,13 @@ bpf_filter_with_aux_data(const struct bpf_insn *pc, const u_char *p,
|
||||
case BPF_ALU|BPF_NEG:
|
||||
/*
|
||||
* Most BPF arithmetic is unsigned, but negation
|
||||
* can't be unsigned; throw some casts to
|
||||
* specify what we're trying to do.
|
||||
* can't be unsigned; respecify it as subtracting
|
||||
* the accumulator from 0U, so that 1) we don't
|
||||
* get compiler warnings about negating an unsigned
|
||||
* value and 2) don't get UBSan warnings about
|
||||
* the result of negating 0x80000000 being undefined.
|
||||
*/
|
||||
A = (u_int32)(-(int32)A);
|
||||
A = (0U - A);
|
||||
continue;
|
||||
|
||||
case BPF_MISC|BPF_TAX:
|
||||
|
@ -49,9 +49,17 @@
|
||||
#
|
||||
|
||||
# The 64-bit Packet.lib is located under /x64
|
||||
set(64BIT_SUBDIR "")
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set(64BIT_SUBDIR "/x64")
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# 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".
|
||||
#
|
||||
set(CMAKE_LIBRARY_ARCHITECTURE "x64")
|
||||
endif()
|
||||
|
||||
# Find the header
|
||||
@ -64,7 +72,6 @@ find_path(PACKET_INCLUDE_DIR Packet32.h
|
||||
find_library(PACKET_LIBRARY
|
||||
NAMES Packet packet
|
||||
HINTS "${PACKET_DLL_DIR}" ENV PACKET_DLL_DIR
|
||||
PATH_SUFFIXES Lib${64BIT_SUBDIR} lib${64BIT_SUBDIR}
|
||||
)
|
||||
|
||||
# Set PACKET_FOUND to TRUE if PACKET_INCLUDE_DIR and PACKET_LIBRARY are TRUE.
|
||||
|
@ -1,152 +0,0 @@
|
||||
# ==============================================================================
|
||||
# This is a heavily modified version of FindPthreads.cmake for the pcap project.
|
||||
# It's meant to find Pthreads-w32, an implementation of the
|
||||
# Threads component of the POSIX 1003.1c 1995 Standard (or later)
|
||||
# for Microsoft's WIndows.
|
||||
#
|
||||
# Apart from this notice, this module "enjoys" the following modifications:
|
||||
#
|
||||
# - changed its name to FindPthreads-w32.cmake to not conflict with FindThreads.cmake
|
||||
#
|
||||
# - users may be able to use the environment variable PTHREADS_ROOT to point
|
||||
# cmake to the *root* of their Pthreads-w32 installation.
|
||||
# Alternatively, PTHREADS_ROOT may also be set from cmake command line or GUI
|
||||
# (-DPTHREADS_ROOT=/path/to/Pthreads-w32)
|
||||
# Two other variables that can be defined in a similar fashion are
|
||||
# PTHREAD_INCLUDE_PATH and PTHREAD_LIBRARY_PATH.
|
||||
#
|
||||
# - added some additional status/error messages
|
||||
#
|
||||
# - changed formating (uppercase to lowercare + indentation)
|
||||
#
|
||||
# - removed some stuff
|
||||
#
|
||||
# - when searching for Pthreads-win32 libraries, the directory structure of the
|
||||
# pre-build binaries folder found in the pthreads-win32 CVS code repository is
|
||||
# considered (e.i /Pre-built.2/lib/x64 /Pre-built.2/lib/x86)
|
||||
#
|
||||
# Send suggestion, patches, gifts and praises to pcap's developers.
|
||||
# ==============================================================================
|
||||
#
|
||||
# Find the Pthreads library
|
||||
# This module searches for the Pthreads-win32 library (including the
|
||||
# pthreads-win32 port).
|
||||
#
|
||||
# This module defines these variables:
|
||||
#
|
||||
# PTHREADS_FOUND - True if the Pthreads library was found
|
||||
# PTHREADS_LIBRARY - The location of the Pthreads library
|
||||
# PTHREADS_INCLUDE_DIR - The include directory of the Pthreads library
|
||||
# PTHREADS_DEFINITIONS - Preprocessor definitions to define (HAVE_PTHREAD_H is a fairly common one)
|
||||
#
|
||||
# This module responds to the PTHREADS_EXCEPTION_SCHEME
|
||||
# variable on Win32 to allow the user to control the
|
||||
# library linked against. The Pthreads-win32 port
|
||||
# provides the ability to link against a version of the
|
||||
# library with exception handling.
|
||||
# IT IS NOT RECOMMENDED THAT YOU CHANGE PTHREADS_EXCEPTION_SCHEME
|
||||
# TO ANYTHING OTHER THAN "C" because most POSIX thread implementations
|
||||
# do not support stack unwinding.
|
||||
#
|
||||
# PTHREADS_EXCEPTION_SCHEME
|
||||
# C = no exceptions (default)
|
||||
# (NOTE: This is the default scheme on most POSIX thread
|
||||
# implementations and what you should probably be using)
|
||||
# CE = C++ Exception Handling
|
||||
# SE = Structure Exception Handling (MSVC only)
|
||||
#
|
||||
|
||||
#
|
||||
# Define a default exception scheme to link against
|
||||
# and validate user choice.
|
||||
#
|
||||
#
|
||||
if(NOT DEFINED PTHREADS_EXCEPTION_SCHEME)
|
||||
# Assign default if needed
|
||||
set(PTHREADS_EXCEPTION_SCHEME "C")
|
||||
else(NOT DEFINED PTHREADS_EXCEPTION_SCHEME)
|
||||
# Validate
|
||||
if(NOT PTHREADS_EXCEPTION_SCHEME STREQUAL "C" AND
|
||||
NOT PTHREADS_EXCEPTION_SCHEME STREQUAL "CE" AND
|
||||
NOT PTHREADS_EXCEPTION_SCHEME STREQUAL "SE")
|
||||
|
||||
message(FATAL_ERROR "See documentation for FindPthreads.cmake, only C, CE, and SE modes are allowed")
|
||||
|
||||
endif(NOT PTHREADS_EXCEPTION_SCHEME STREQUAL "C" AND
|
||||
NOT PTHREADS_EXCEPTION_SCHEME STREQUAL "CE" AND
|
||||
NOT PTHREADS_EXCEPTION_SCHEME STREQUAL "SE")
|
||||
|
||||
if(NOT MSVC AND PTHREADS_EXCEPTION_SCHEME STREQUAL "SE")
|
||||
message(FATAL_ERROR "Structured Exception Handling is only allowed for MSVC")
|
||||
endif(NOT MSVC AND PTHREADS_EXCEPTION_SCHEME STREQUAL "SE")
|
||||
|
||||
endif(NOT DEFINED PTHREADS_EXCEPTION_SCHEME)
|
||||
|
||||
if(PTHREADS_ROOT)
|
||||
set(PTHREADS_ROOT PATHS ${PTHREADS_ROOT} NO_DEFAULT_PATH)
|
||||
else()
|
||||
set(PTHREADS_ROOT $ENV{PTHREADS_ROOT})
|
||||
endif(PTHREADS_ROOT)
|
||||
|
||||
#
|
||||
# Find the header file
|
||||
#
|
||||
find_path(PTHREADS_INCLUDE_DIR
|
||||
NAMES pthread.h
|
||||
HINTS
|
||||
$ENV{PTHREAD_INCLUDE_PATH}
|
||||
${PTHREADS_ROOT}/include
|
||||
)
|
||||
|
||||
if(PTHREADS_INCLUDE_DIR)
|
||||
message(STATUS "Found pthread.h: ${PTHREADS_INCLUDE_DIR}")
|
||||
# else()
|
||||
# message(FATAL_ERROR "Could not find pthread.h. See README.Win32 for more information.")
|
||||
endif(PTHREADS_INCLUDE_DIR)
|
||||
|
||||
#
|
||||
# Find the library
|
||||
#
|
||||
set(names)
|
||||
if(MSVC)
|
||||
set(names
|
||||
pthreadV${PTHREADS_EXCEPTION_SCHEME}2
|
||||
libpthread
|
||||
)
|
||||
elseif(MINGW)
|
||||
set(names
|
||||
pthreadG${PTHREADS_EXCEPTION_SCHEME}2
|
||||
pthread
|
||||
)
|
||||
endif(MSVC)
|
||||
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||
set(SUBDIR "/x86")
|
||||
elseif(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set(SUBDIR "/x64")
|
||||
endif()
|
||||
|
||||
find_library(PTHREADS_LIBRARY NAMES ${names}
|
||||
DOC "The Portable Threads Library"
|
||||
HINTS
|
||||
${CMAKE_SOURCE_DIR}/lib
|
||||
$ENV{PTHREAD_LIBRARY_PATH}
|
||||
${PTHREADS_ROOT}
|
||||
C:/MinGW/lib/
|
||||
PATH_SUFFIXES lib/${SUBDIR}
|
||||
)
|
||||
|
||||
if(PTHREADS_LIBRARY)
|
||||
message(STATUS "Found PTHREADS library: ${PTHREADS_LIBRARY} (PTHREADS Exception Scheme: ${PTHREADS_EXCEPTION_SCHEME})")
|
||||
# else()
|
||||
# message(FATAL_ERROR "Could not find PTHREADS LIBRARY. See README.Win32 for more information.")
|
||||
endif(PTHREADS_LIBRARY)
|
||||
|
||||
if(PTHREADS_INCLUDE_DIR AND PTHREADS_LIBRARY)
|
||||
set(PTHREADS_DEFINITIONS -DHAVE_PTHREAD_H)
|
||||
set(PTHREADS_INCLUDE_DIRS ${PTHREADS_INCLUDE_DIR})
|
||||
set(PTHREADS_LIBRARIES ${PTHREADS_LIBRARY})
|
||||
set(PTHREADS_FOUND TRUE)
|
||||
endif(PTHREADS_INCLUDE_DIR AND PTHREADS_LIBRARY)
|
||||
|
||||
mark_as_advanced(PTHREADS_INCLUDE_DIR PTHREADS_LIBRARY)
|
@ -15,6 +15,9 @@
|
||||
/* define if we have the AIX getprotobyname_r() */
|
||||
#cmakedefine HAVE_AIX_GETPROTOBYNAME_R 1
|
||||
|
||||
/* Define to 1 if you have the `asprintf' function. */
|
||||
#cmakedefine HAVE_ASPRINTF 1
|
||||
|
||||
/* define if you have the DAG API */
|
||||
#cmakedefine HAVE_DAG_API 1
|
||||
|
||||
@ -48,6 +51,9 @@
|
||||
/* Define to 1 if you have the `getspnam' function. */
|
||||
#cmakedefine HAVE_GETSPNAM 1
|
||||
|
||||
/* Define to 1 if you have a GNU-style `strerror_r' function. */
|
||||
#cmakedefine HAVE_GNU_STRERROR_R 1
|
||||
|
||||
/* on HP-UX 10.20 or later */
|
||||
#cmakedefine HAVE_HPUX10_20_OR_LATER 1
|
||||
|
||||
@ -138,9 +144,15 @@
|
||||
/* if there's an os_proto.h for this platform, to use additional prototypes */
|
||||
#cmakedefine HAVE_OS_PROTO_H 1
|
||||
|
||||
/* Define to 1 if Packet32 API (WinPcap NPF driver) is available */
|
||||
/* Define to 1 if Packet32 API (Npcap driver) is available */
|
||||
#cmakedefine HAVE_PACKET32 1
|
||||
|
||||
/* Define to 1 if NPcap's version.h is available */
|
||||
#cmakedefine HAVE_VERSION_H 1
|
||||
|
||||
/* Define to 1 if you have a POSIX-style `strerror_r' function. */
|
||||
#cmakedefine HAVE_POSIX_STRERROR_R 1
|
||||
|
||||
/* define if net/pfvar.h defines PF_NAT through PF_NORDR */
|
||||
#cmakedefine HAVE_PF_NAT_THROUGH_PF_NORDR 1
|
||||
|
||||
@ -174,9 +186,6 @@
|
||||
/* Define to 1 if you have the `strerror' function. */
|
||||
#cmakedefine HAVE_STRERROR 1
|
||||
|
||||
/* Define to 1 if you have the `strerror_r' function. */
|
||||
#cmakedefine HAVE_STRERROR_R 1
|
||||
|
||||
/* Define to 1 if you have the `strerror_s' function. */
|
||||
#cmakedefine HAVE_STRERROR_S 1
|
||||
|
||||
@ -256,9 +265,15 @@
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#cmakedefine HAVE_UNISTD_H 1
|
||||
|
||||
/* Define to 1 if you have the `vasprintf' function. */
|
||||
#cmakedefine HAVE_VASPRINTF 1
|
||||
|
||||
/* Define to 1 if you have the `vsnprintf' function. */
|
||||
#cmakedefine HAVE_VSNPRINTF 1
|
||||
|
||||
/* Define to 1 if you have the `vsyslog' function. */
|
||||
#undef HAVE_VSYSLOG
|
||||
|
||||
/* Define to 1 if you have the `PacketIsLoopbackAdapter' function. */
|
||||
#cmakedefine HAVE_PACKET_IS_LOOPBACK_ADAPTER 1
|
||||
|
||||
|
685
config.guess
vendored
685
config.guess
vendored
File diff suppressed because it is too large
Load Diff
18
config.h.in
18
config.h.in
@ -15,6 +15,9 @@
|
||||
/* define if we have the AIX getprotobyname_r() */
|
||||
#undef HAVE_AIX_GETPROTOBYNAME_R
|
||||
|
||||
/* Define to 1 if you have the `asprintf' function. */
|
||||
#undef HAVE_ASPRINTF
|
||||
|
||||
/* Define to 1 if you have the <dagapi.h> header file. */
|
||||
#undef HAVE_DAGAPI_H
|
||||
|
||||
@ -54,6 +57,9 @@
|
||||
/* Define to 1 if you have the `getspnam' function. */
|
||||
#undef HAVE_GETSPNAM
|
||||
|
||||
/* Define to 1 if you have a GNU-style `strerror_r' function. */
|
||||
#undef HAVE_GNU_STRERROR_R
|
||||
|
||||
/* on HP-UX 10.20 or later */
|
||||
#undef HAVE_HPUX10_20_OR_LATER
|
||||
|
||||
@ -150,6 +156,9 @@
|
||||
/* define if net/pfvar.h defines PF_NAT through PF_NORDR */
|
||||
#undef HAVE_PF_NAT_THROUGH_PF_NORDR
|
||||
|
||||
/* Define to 1 if you have a POSIX-style `strerror_r' function. */
|
||||
#undef HAVE_POSIX_STRERROR_R
|
||||
|
||||
/* define if you have the Septel API */
|
||||
#undef HAVE_SEPTEL_API
|
||||
|
||||
@ -180,9 +189,6 @@
|
||||
/* Define to 1 if you have the `strerror' function. */
|
||||
#undef HAVE_STRERROR
|
||||
|
||||
/* Define to 1 if you have the `strerror_r' function. */
|
||||
#undef HAVE_STRERROR_R
|
||||
|
||||
/* Define to 1 if you have the `strerror_s' function. */
|
||||
#undef HAVE_STRERROR_S
|
||||
|
||||
@ -262,9 +268,15 @@
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#undef HAVE_UNISTD_H
|
||||
|
||||
/* Define to 1 if you have the `vasprintf' function. */
|
||||
#undef HAVE_VASPRINTF
|
||||
|
||||
/* Define to 1 if you have the `vsnprintf' function. */
|
||||
#undef HAVE_VSNPRINTF
|
||||
|
||||
/* Define to 1 if you have the `vsyslog' function. */
|
||||
#undef HAVE_VSYSLOG
|
||||
|
||||
/* IPv6 */
|
||||
#undef INET6
|
||||
|
||||
|
1695
config.sub
vendored
1695
config.sub
vendored
File diff suppressed because it is too large
Load Diff
292
configure.ac
292
configure.ac
@ -28,6 +28,9 @@ AC_LBL_C_INIT_BEFORE_CC(V_CCOPT, V_INCLS)
|
||||
# At minimum, we want C++/C99-style // comments.
|
||||
#
|
||||
AC_PROG_CC_C99
|
||||
if test "$ac_cv_prog_cc_c99" = "no"; then
|
||||
AC_MSG_WARN([The C compiler does not support C99; there may be compiler errors])
|
||||
fi
|
||||
AC_LBL_C_INIT(V_CCOPT, V_INCLS)
|
||||
AC_LBL_SHLIBS_INIT
|
||||
AC_LBL_C_INLINE
|
||||
@ -83,13 +86,109 @@ esac
|
||||
|
||||
AC_LBL_FIXINCLUDES
|
||||
|
||||
AC_CHECK_FUNCS(strerror strerror_r strerror_s strlcpy strlcat)
|
||||
AC_CHECK_FUNCS(strerror)
|
||||
AC_CHECK_FUNC(strerror_r,
|
||||
[
|
||||
#
|
||||
# We have strerror_r; if we define _GNU_SOURCE, is it a
|
||||
# POSIX-compliant strerror_r() or a GNU strerror_r()?
|
||||
#
|
||||
AC_MSG_CHECKING(whether strerror_r is GNU-style)
|
||||
AC_COMPILE_IFELSE(
|
||||
[
|
||||
AC_LANG_SOURCE(
|
||||
#define _GNU_SOURCE
|
||||
#include <string.h>
|
||||
|
||||
/* Define it GNU-style; that will cause an error if it's not GNU-style */
|
||||
extern char *strerror_r(int, char *, size_t);
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
)
|
||||
],
|
||||
[
|
||||
# GNU-style
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_GNU_STRERROR_R,,
|
||||
[Define to 1 if you have a GNU-style `strerror_r' function.])
|
||||
],
|
||||
[
|
||||
AC_MSG_RESULT(no)
|
||||
AC_DEFINE(HAVE_POSIX_STRERROR_R,,
|
||||
[Define to 1 if you have a POSIX-style `strerror_r' function.])
|
||||
])
|
||||
],
|
||||
[
|
||||
#
|
||||
# We don't have strerror_r; do we have strerror_s?
|
||||
#
|
||||
AC_CHECK_FUNCS(strerror_s)
|
||||
])
|
||||
|
||||
#
|
||||
# Thanks, IBM, for not providing vsyslog() in AIX!
|
||||
#
|
||||
AC_CHECK_FUNCS(vsyslog)
|
||||
|
||||
#
|
||||
# Either:
|
||||
#
|
||||
# we have snprintf() and vsnprintf(), and have asprintf() and
|
||||
# vasprintf();
|
||||
#
|
||||
# we have snprintf() and vsnprintf(), but don't have asprintf()
|
||||
# or vasprintf();
|
||||
#
|
||||
# we have neither snprintf() nor vsnprintf(), and don't have
|
||||
# asprintf() or vasprintf(), either.
|
||||
#
|
||||
# We assume that if we have asprintf() we have vasprintf(), as well
|
||||
# as snprintf() and vsnprintf(), and that if we have snprintf() we
|
||||
# have vsnprintf().
|
||||
#
|
||||
# For the first case, we don't need any replacement routines.
|
||||
# For the second case, we need replacement asprintf()/vasprintf()
|
||||
# routines.
|
||||
# For the third case, we need replacement snprintf()/vsnprintf() and
|
||||
# asprintf()/vasprintf() routines.
|
||||
#
|
||||
needsnprintf=no
|
||||
AC_CHECK_FUNCS(vsnprintf snprintf,,
|
||||
[needsnprintf=yes])
|
||||
needasprintf=no
|
||||
AC_CHECK_FUNCS(vasprintf asprintf,,
|
||||
[needasprintf=yes])
|
||||
if test $needsnprintf = yes; then
|
||||
#
|
||||
# We assume we have none of them; missing/snprintf.c supplies
|
||||
# all of them.
|
||||
#
|
||||
AC_LIBOBJ([snprintf])
|
||||
elif test $needasprintf = yes; then
|
||||
#
|
||||
# We assume we have snprintf()/vsnprintf() but lack
|
||||
# asprintf()/vasprintf(); missing/asprintf.c supplies
|
||||
# the latter (using vsnprintf()).
|
||||
#
|
||||
AC_LIBOBJ([asprintf])
|
||||
fi
|
||||
|
||||
needstrlcat=no
|
||||
AC_CHECK_FUNCS(strlcat,,
|
||||
[needstrlcat=yes])
|
||||
if test $needstrlcat = yes; then
|
||||
AC_LIBOBJ([strlcat])
|
||||
fi
|
||||
|
||||
needstrlcpy=no
|
||||
AC_CHECK_FUNCS(strlcpy,,
|
||||
[needstrlcpy=yes])
|
||||
if test $needstrlcpy = yes; then
|
||||
AC_LIBOBJ([strlcpy])
|
||||
fi
|
||||
|
||||
needstrtok_r=no
|
||||
@ -550,6 +649,10 @@ else
|
||||
# requires that various BSD-style integer types
|
||||
# be defined;
|
||||
#
|
||||
# sys/time.h, because AIX 5.2 and 5.3's net/bpf.h
|
||||
# doesn't include it but does use struct timeval
|
||||
# in ioctl definitions;
|
||||
#
|
||||
# sys/ioctl.h and, if we have it, sys/ioccom.h,
|
||||
# because net/bpf.h defines ioctls;
|
||||
#
|
||||
@ -568,6 +671,7 @@ else
|
||||
AC_TRY_COMPILE(
|
||||
[
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#ifdef HAVE_SYS_IOCCOM_H
|
||||
@ -1529,18 +1633,20 @@ AC_CACHE_CHECK([for capable yacc/bison], tcpdump_cv_capable_yacc,
|
||||
fi)
|
||||
if test $tcpdump_cv_capable_yacc = insufficient ; then
|
||||
AC_MSG_ERROR([$YACC is insufficient to compile libpcap.
|
||||
libpcap requires Bison, Berkeley YACC, or another YACC compatible with them.])
|
||||
libpcap requires Bison, a newer version of Berkeley YACC with support
|
||||
for reentrant parsers, or another YACC compatible with them.])
|
||||
fi
|
||||
|
||||
#
|
||||
# Do various checks for various OSes and versions of those OSes.
|
||||
#
|
||||
# Assume, by default, no support for shared libraries and V7/BSD
|
||||
# convention for man pages (file formats in section 5, miscellaneous
|
||||
# info in section 7, administrative commands and daemons in section 8).
|
||||
# Individual cases can override this.
|
||||
# convention for man pages (devices in section 4, file formats in
|
||||
# section 5, miscellaneous info in section 7, administrative commands
|
||||
# and daemons in section 8). Individual cases can override this.
|
||||
#
|
||||
DYEXT="none"
|
||||
MAN_DEVICES=4
|
||||
MAN_FILE_FORMATS=5
|
||||
MAN_MISC_INFO=7
|
||||
MAN_ADMIN_COMMANDS=8
|
||||
@ -1596,79 +1702,151 @@ darwin*)
|
||||
if test "$enable_universal" != "no"; then
|
||||
case "$host_os" in
|
||||
|
||||
darwin[0-7].*)
|
||||
darwin[[0-7]].*)
|
||||
#
|
||||
# Pre-Tiger. Build only for 32-bit PowerPC; no
|
||||
# need for any special compiler or linker flags.
|
||||
#
|
||||
;;
|
||||
|
||||
darwin8.[0123]*)
|
||||
darwin8.[[0123]]|darwin8.[[0123]].*)
|
||||
#
|
||||
# Tiger, prior to Intel support. Build for 32-bit
|
||||
# PowerPC and 64-bit PowerPC, with 32-bit PowerPC
|
||||
# first. (I'm guessing that's what Apple does.)
|
||||
#
|
||||
V_CCOPT="$V_CCOPT -arch ppc -arch ppc64"
|
||||
LDFLAGS="$LDFLAGS -arch ppc -arch ppc64"
|
||||
;;
|
||||
|
||||
darwin8.[456]*)
|
||||
#
|
||||
# Tiger, subsequent to Intel support but prior to
|
||||
# x86-64 support. Build for 32-bit PowerPC, 64-bit
|
||||
# PowerPC, and x86, with 32-bit PowerPC first.
|
||||
# Tiger, prior to Intel support. Build
|
||||
# libraries and executables for 32-bit PowerPC
|
||||
# and 64-bit PowerPC, with 32-bit PowerPC first.
|
||||
# (I'm guessing that's what Apple does.)
|
||||
#
|
||||
V_CCOPT="$V_CCOPT -arch ppc -arch ppc64 -arch i386"
|
||||
LDFLAGS="$LDFLAGS -arch ppc -arch ppc64 -arch i386"
|
||||
# (The double brackets are needed because
|
||||
# autotools/m4 use brackets as a quoting
|
||||
# character; the double brackets turn into
|
||||
# single brackets in the generated configure
|
||||
# file.)
|
||||
#
|
||||
V_LIB_CCOPT_FAT="-arch ppc -arch ppc64"
|
||||
V_LIB_LDFLAGS_FAT="-arch ppc -arch ppc64"
|
||||
V_PROG_CCOPT_FAT="-arch ppc -arch ppc64"
|
||||
V_PROG_LDFLAGS_FAT="-arch ppc -arch ppc64"
|
||||
;;
|
||||
|
||||
darwin8.[[456]]|darwin.[[456]].*)
|
||||
#
|
||||
# Tiger, subsequent to Intel support but prior
|
||||
# to x86-64 support. Build libraries and
|
||||
# executables for 32-bit PowerPC, 64-bit
|
||||
# PowerPC, and 32-bit x86, with 32-bit PowerPC
|
||||
# first. (I'm guessing that's what Apple does.)
|
||||
#
|
||||
# (The double brackets are needed because
|
||||
# autotools/m4 use brackets as a quoting
|
||||
# character; the double brackets turn into
|
||||
# single brackets in the generated configure
|
||||
# file.)
|
||||
#
|
||||
V_LIB_CCOPT_FAT="-arch ppc -arch ppc64 -arch i386"
|
||||
V_LIB_LDFLAGS_FAT="-arch ppc -arch ppc64 -arch i386"
|
||||
V_PROG_CCOPT_FAT="-arch ppc -arch ppc64 -arch i386"
|
||||
V_PROG_LDFLAGS_FAT="-arch ppc -arch ppc64 -arch i386"
|
||||
;;
|
||||
|
||||
darwin8.*)
|
||||
#
|
||||
# All other Tiger, so subsequent to x86-64
|
||||
# support. Build for 32-bit PowerPC, 64-bit
|
||||
# PowerPC, x86, and x86-64, and with 32-bit PowerPC
|
||||
# first. (I'm guessing that's what Apple does.)
|
||||
# support. Build libraries and executables for
|
||||
# 32-bit PowerPC, 64-bit PowerPC, 32-bit x86,
|
||||
# and x86-64, with 32-bit PowerPC first. (I'm
|
||||
# guessing that's what Apple does.)
|
||||
#
|
||||
V_CCOPT="$V_CCOPT -arch ppc -arch ppc64 -arch i386 -arch x86_64"
|
||||
LDFLAGS="$LDFLAGS -arch ppc -arch ppc64 -arch i386 -arch x86_64"
|
||||
V_LIB_CCOPT_FAT="-arch ppc -arch ppc64 -arch i386 -arch x86_64"
|
||||
V_LIB_LDFLAGS_FAT="-arch ppc -arch ppc64 -arch i386 -arch x86_64"
|
||||
V_PROG_CCOPT_FAT="-arch ppc -arch ppc64 -arch i386 -arch x86_64"
|
||||
V_PROG_LDFLAGS_FAT="-arch ppc -arch ppc64 -arch i386 -arch x86_64"
|
||||
;;
|
||||
|
||||
darwin9.*)
|
||||
#
|
||||
# Leopard. Build for 32-bit PowerPC, 64-bit
|
||||
# PowerPC, x86, and x86-64, with 32-bit PowerPC
|
||||
# first. (That's what Apple does.)
|
||||
# Leopard. Build libraries for 32-bit PowerPC,
|
||||
# 64-bit PowerPC, 32-bit x86, and x86-64, with
|
||||
# 32-bit PowerPC first, and build executables
|
||||
# for 32-bit x86 and 32-bit PowerPC, with 32-bit
|
||||
# x86 first. (That's what Apple does.)
|
||||
#
|
||||
V_CCOPT="$V_CCOPT -arch ppc -arch ppc64 -arch i386 -arch x86_64"
|
||||
LDFLAGS="$LDFLAGS -arch ppc -arch ppc64 -arch i386 -arch x86_64"
|
||||
V_LIB_CCOPT_FAT="-arch ppc -arch ppc64 -arch i386 -arch x86_64"
|
||||
V_LIB_LDFLAGS_FAT="-arch ppc -arch ppc64 -arch i386 -arch x86_64"
|
||||
V_PROG_CCOPT_FAT="-arch i386 -arch ppc"
|
||||
V_PROG_LDFLAGS_FAT="-arch i386 -arch ppc"
|
||||
;;
|
||||
|
||||
darwin10.*)
|
||||
#
|
||||
# Snow Leopard. Build for x86-64, x86, and
|
||||
# 32-bit PowerPC, with x86-64 first. (That's
|
||||
# what Apple does, even though Snow Leopard
|
||||
# doesn't run on PPC, so PPC libpcap runs under
|
||||
# Rosetta, and Rosetta doesn't support BPF
|
||||
# ioctls, so PPC programs can't do live
|
||||
# captures.)
|
||||
# Snow Leopard. Build libraries for x86-64,
|
||||
# 32-bit x86, and 32-bit PowerPC, with x86-64
|
||||
# first, and build executables for x86-64 and
|
||||
# 32-bit x86, with x86-64 first. (That's what
|
||||
# Apple does, even though Snow Leopard doesn't
|
||||
# run on PPC, so PPC libpcap runs under Rosetta,
|
||||
# and Rosetta doesn't support BPF ioctls, so PPC
|
||||
# programs can't do live captures.)
|
||||
#
|
||||
V_CCOPT="$V_CCOPT -arch x86_64 -arch i386 -arch ppc"
|
||||
LDFLAGS="$LDFLAGS -arch x86_64 -arch i386 -arch ppc"
|
||||
V_LIB_CCOPT_FAT="-arch x86_64 -arch i386 -arch ppc"
|
||||
V_LIB_LDFLAGS_FAT="-arch x86_64 -arch i386 -arch ppc"
|
||||
V_PROG_CCOPT_FAT="-arch x86_64 -arch i386"
|
||||
V_PROG_LDFLAGS_FAT="-arch x86_64 -arch i386"
|
||||
;;
|
||||
|
||||
darwin*)
|
||||
#
|
||||
# Post-Snow Leopard. Build for x86-64 and
|
||||
# x86, with x86-64 first. (That's probably what
|
||||
# Apple does, given that Rosetta is gone.)
|
||||
# Post-Snow Leopard. Build libraries for x86-64
|
||||
# and 32-bit x86, with x86-64 first, and build
|
||||
# executables only for x86-64. (That's what
|
||||
# Apple does.) This requires no special flags
|
||||
# for programs.
|
||||
# XXX - update if and when Apple drops support
|
||||
# for 32-bit x86 code.
|
||||
# for 32-bit x86 code and if and when Apple adds
|
||||
# ARM-based Macs. (You're on your own for iOS
|
||||
# etc.)
|
||||
#
|
||||
V_CCOPT="$V_CCOPT -arch x86_64 -arch i386"
|
||||
LDFLAGS="$LDFLAGS -arch x86_64 -arch i386"
|
||||
# XXX - check whether we *can* build for
|
||||
# i386 and, if not, suggest that the user
|
||||
# install the /usr/include headers if they
|
||||
# want to build fat.
|
||||
#
|
||||
AC_MSG_CHECKING(whether building for 32-bit x86 is supported)
|
||||
save_CFLAGS="$CFLAGS"
|
||||
CFLAGS="$CFLAGS -arch i386"
|
||||
AC_TRY_COMPILE(
|
||||
[],
|
||||
[return 0;],
|
||||
[
|
||||
AC_MSG_RESULT(yes)
|
||||
V_LIB_CCOPT_FAT="-arch x86_64 -arch i386"
|
||||
V_LIB_LDFLAGS_FAT="-arch x86_64 -arch i386"
|
||||
],
|
||||
[
|
||||
AC_MSG_RESULT(no)
|
||||
V_LIB_CCOPT_FAT="-arch x86_64"
|
||||
V_LIB_LDFLAGS_FAT="-arch x86_64"
|
||||
case "$host_os" in
|
||||
|
||||
darwin18.*)
|
||||
#
|
||||
# Mojave; you need to install the
|
||||
# /usr/include headers to get
|
||||
# 32-bit x86 builds to work.
|
||||
#
|
||||
AC_MSG_WARN([Compiling for 32-bit x86 gives an error; try installing the command-line tools and, after that, installing the /usr/include headers from the /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg package])
|
||||
;;
|
||||
|
||||
*)
|
||||
#
|
||||
# Pre-Mojave; the command-line
|
||||
# tools should be sufficient to
|
||||
# enable 32-bit x86 builds.
|
||||
#
|
||||
AC_MSG_WARN([Compiling for 32-bit x86 gives an error; try installing the command-line tools])
|
||||
;;
|
||||
esac
|
||||
])
|
||||
CFLAGS="$save_CFLAGS"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
@ -1742,7 +1920,7 @@ irix*)
|
||||
MAN_MISC_INFO=5
|
||||
;;
|
||||
|
||||
linux*|freebsd*|netbsd*|openbsd*|dragonfly*|kfreebsd*|gnu*)
|
||||
linux*|freebsd*|netbsd*|openbsd*|dragonfly*|kfreebsd*|gnu*|midipix*)
|
||||
DYEXT="so"
|
||||
|
||||
#
|
||||
@ -1765,6 +1943,7 @@ osf*)
|
||||
#
|
||||
MAN_FILE_FORMATS=4
|
||||
MAN_MISC_INFO=5
|
||||
MAN_DEVICES=7
|
||||
;;
|
||||
|
||||
sinix*)
|
||||
@ -1808,6 +1987,7 @@ solaris*)
|
||||
MAN_ADMIN_COMMANDS=1m
|
||||
MAN_FILE_FORMATS=4
|
||||
MAN_MISC_INFO=5
|
||||
MAN_DEVICES=7D
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
@ -1863,6 +2043,10 @@ AC_CHECK_MEMBERS([dl_hp_ppa_info_t.dl_module_id_1],,,
|
||||
AC_LBL_UNALIGNED_ACCESS
|
||||
|
||||
AC_SUBST(V_CCOPT)
|
||||
AC_SUBST(V_LIB_CCOPT_FAT)
|
||||
AC_SUBST(V_LIB_LDFLAGS_FAT)
|
||||
AC_SUBST(V_PROG_CCOPT_FAT)
|
||||
AC_SUBST(V_PROG_LDFLAGS_FAT)
|
||||
AC_SUBST(V_DEFS)
|
||||
AC_SUBST(V_FINDALLDEVS)
|
||||
AC_SUBST(V_INCLS)
|
||||
@ -1878,6 +2062,7 @@ AC_SUBST(ADDLOBJS)
|
||||
AC_SUBST(ADDLARCHIVEOBJS)
|
||||
AC_SUBST(SSRC)
|
||||
AC_SUBST(DYEXT)
|
||||
AC_SUBST(MAN_DEVICES)
|
||||
AC_SUBST(MAN_FILE_FORMATS)
|
||||
AC_SUBST(MAN_MISC_INFO)
|
||||
AC_SUBST(MAN_ADMIN_COMMANDS)
|
||||
@ -2212,15 +2397,15 @@ fi
|
||||
AC_ARG_ENABLE([rdma],
|
||||
[AC_HELP_STRING([--enable-rdma],[enable RDMA capture support @<:@default=yes, if support available@:>@])],
|
||||
[],
|
||||
[enable_rdmasniff=ifavailable])
|
||||
[enable_rdma=ifavailable])
|
||||
|
||||
if test "xxx_only" = yes; then
|
||||
# User requested something-else-only pcap, so they don't
|
||||
# want RDMA support.
|
||||
enable_rdmasniff=no
|
||||
enable_rdma=no
|
||||
fi
|
||||
|
||||
if test "x$enable_rdmasniff" != "xno"; then
|
||||
if test "x$enable_rdma" != "xno"; then
|
||||
AC_CHECK_LIB(ibverbs, ibv_get_device_list, [
|
||||
AC_CHECK_HEADER(infiniband/verbs.h, [
|
||||
#
|
||||
@ -2273,7 +2458,8 @@ AC_OUTPUT(Makefile pcap-filter.manmisc pcap-linktype.manmisc
|
||||
pcap_compile.3pcap pcap_datalink.3pcap pcap_dump_open.3pcap
|
||||
pcap_get_tstamp_precision.3pcap pcap_list_datalinks.3pcap
|
||||
pcap_list_tstamp_types.3pcap pcap_open_dead.3pcap
|
||||
pcap_open_offline.3pcap pcap_set_tstamp_precision.3pcap
|
||||
pcap_set_tstamp_type.3pcap rpcapd/Makefile rpcapd/rpcapd.manadmin
|
||||
pcap_open_offline.3pcap pcap_set_immediate_mode.3pcap
|
||||
pcap_set_tstamp_precision.3pcap pcap_set_tstamp_type.3pcap
|
||||
rpcapd/Makefile rpcapd/rpcapd.manadmin rpcapd/rpcapd-config.manfile
|
||||
testprogs/Makefile)
|
||||
exit 0
|
||||
|
@ -120,13 +120,14 @@
|
||||
* shadowing the global declaration.
|
||||
*
|
||||
* So, if the compiler warns about that, we turn off -Wshadow warnings.
|
||||
*
|
||||
* In addition, the generated code may have functions with unreachable
|
||||
* code, so suppress warnings about those.
|
||||
*/
|
||||
#if defined(_MSC_VER)
|
||||
/*
|
||||
* This is Microsoft Visual Studio; we can use
|
||||
* __pragma(warning(disable:XXXX)) and __pragma(warning(push/pop)).
|
||||
*
|
||||
* Suppress unreachable code warnings.
|
||||
*/
|
||||
#define DIAG_OFF_BISON_BYACC \
|
||||
__pragma(warning(push)) \
|
||||
@ -166,6 +167,9 @@
|
||||
#else
|
||||
/*
|
||||
* Bison.
|
||||
*
|
||||
* The generated code may have functions with unreachable code, so
|
||||
* suppress warnings about those.
|
||||
*/
|
||||
#if defined(_MSC_VER)
|
||||
/*
|
||||
|
29
doc/DLT_ALLOCATE_HOWTO.md
Normal file
29
doc/DLT_ALLOCATE_HOWTO.md
Normal file
@ -0,0 +1,29 @@
|
||||
DLT and LINKTYPE allocation
|
||||
===========================
|
||||
|
||||
DLT_ types live in pcap/dlt.h. They can be requested by the community on a
|
||||
First-Come First-Served basis [i.e. https://tools.ietf.org/html/rfc8126#section-4.4 ]
|
||||
(Although libpcap is not at this time an IETF specification, there have been
|
||||
some as yet-incomplete efforts to do this).
|
||||
|
||||
The Tcpdump Group prefers to link to an open specification on the new DLT_
|
||||
type, but they are available for closed, proprietary projects as well.
|
||||
In that case, a stable email address suffices so that someone who finds
|
||||
an unknown DLT_ type can investigate.
|
||||
We prefer to give out unambiguous numbers, and we try to do it as quickly
|
||||
as possible, but DLT_USERx is available while you wait.
|
||||
|
||||
Note that DLT_ types are, in theory, private to the capture mechanism and can
|
||||
in some cases be operating system specific, and so a second set of values,
|
||||
LINKTYPE_ is allocated for actually writing to pcap files. As much as
|
||||
possible going forward, the DLT_ and LINKTYPE_ value are identical, however,
|
||||
this was not always the case. See pcap-common.c.
|
||||
|
||||
The LINKTYPE_ values are not exported, but are in pcap-common.c only.
|
||||
|
||||
DEVELOPER NOTES
|
||||
---------------
|
||||
|
||||
When allocating a new DLT_ value, a corresponding value needs to be
|
||||
added to pcap-common.c.
|
||||
It is not necessary to copy the comments from dlt.h to pcap-common.c.
|
3
doc/README.Win32.md
Normal file
3
doc/README.Win32.md
Normal file
@ -0,0 +1,3 @@
|
||||
Win32 used to build with Visual Studio 6, but we now use cmake.
|
||||
|
||||
This file needs to be adopted by a windows expert developer.
|
@ -5,7 +5,7 @@ Endace (http://www.endace.com, see below for further contact details).
|
||||
|
||||
1) Install and build the DAG software distribution by following the
|
||||
instructions supplied with that package. Current Endace customers can download
|
||||
the DAG software distibution from https://www.endace.com
|
||||
the DAG software distribution from https://www.endace.com
|
||||
|
||||
2) Configure libcap. To allow the 'configure' script to locate the DAG
|
||||
software distribution use the '--with-dag' option:
|
||||
@ -88,7 +88,7 @@ as separate interfaces, e.g. dag0:0, dag0:2, dag0:4 etc. dag0:0 is the same
|
||||
as dag0. These are visible via pcap_findalldevs().
|
||||
|
||||
libpcap now does NOT set the card's hardware snaplen (slen). This must now be
|
||||
set using the appropriate DAG coniguration program, e.g. dagthree, dagfour,
|
||||
set using the appropriate DAG configuration program, e.g. dagthree, dagfour,
|
||||
dagsix, dagconfig. This is because the snaplen is currently shared between
|
||||
all of the streams. In future this may change if per-stream slen is
|
||||
implemented.
|
@ -97,9 +97,9 @@ reported by pcap_stats on Linux are as follows:
|
||||
2.2.x
|
||||
=====
|
||||
ps_recv Number of packets that were accepted by the pcap filter
|
||||
ps_drop Always 0, this statistic is not gatherd on this platform
|
||||
ps_drop Always 0, this statistic is not gathered on this platform
|
||||
|
||||
2.4.x
|
||||
2.4.x and later
|
||||
=====
|
||||
ps_recv Number of packets that were accepted by the pcap filter
|
||||
ps_drop Number of packets that had passed filtering but were not
|
99
fmtutils.c
99
fmtutils.c
@ -65,11 +65,6 @@ pcap_fmt_errmsg_for_errno(char *errbuf, size_t errbuflen, int errnum,
|
||||
size_t msglen;
|
||||
char *p;
|
||||
size_t errbuflen_remaining;
|
||||
#if defined(HAVE_STRERROR_S)
|
||||
errno_t err;
|
||||
#elif defined(HAVE_STRERROR_R)
|
||||
int err;
|
||||
#endif
|
||||
|
||||
va_start(ap, fmt);
|
||||
pcap_vsnprintf(errbuf, errbuflen, fmt, ap);
|
||||
@ -96,7 +91,10 @@ pcap_fmt_errmsg_for_errno(char *errbuf, size_t errbuflen, int errnum,
|
||||
* Now append the string for the error code.
|
||||
*/
|
||||
#if defined(HAVE_STRERROR_S)
|
||||
err = strerror_s(p, errbuflen_remaining, errnum);
|
||||
/*
|
||||
* We have a Windows-style strerror_s().
|
||||
*/
|
||||
errno_t err = strerror_s(p, errbuflen_remaining, errnum);
|
||||
if (err != 0) {
|
||||
/*
|
||||
* It doesn't appear to be documented anywhere obvious
|
||||
@ -104,8 +102,24 @@ pcap_fmt_errmsg_for_errno(char *errbuf, size_t errbuflen, int errnum,
|
||||
*/
|
||||
pcap_snprintf(p, errbuflen_remaining, "Error %d", errnum);
|
||||
}
|
||||
#elif defined(HAVE_STRERROR_R)
|
||||
err = strerror_r(errnum, p, errbuflen_remaining);
|
||||
#elif defined(HAVE_GNU_STRERROR_R)
|
||||
/*
|
||||
* We have a GNU-style strerror_r(), which is *not* guaranteed to
|
||||
* do anything to the buffer handed to it, and which returns a
|
||||
* pointer to the error string, which may or may not be in
|
||||
* the buffer.
|
||||
*
|
||||
* It is, however, guaranteed to succeed.
|
||||
*/
|
||||
char strerror_buf[PCAP_ERRBUF_SIZE];
|
||||
char *errstring = strerror_r(errnum, strerror_buf, PCAP_ERRBUF_SIZE);
|
||||
pcap_snprintf(p, errbuflen_remaining, "%s", errstring);
|
||||
#elif defined(HAVE_POSIX_STRERROR_R)
|
||||
/*
|
||||
* We have a POSIX-style strerror_r(), which is guaranteed to fill
|
||||
* in the buffer, but is not guaranteed to succeed.
|
||||
*/
|
||||
int err = strerror_r(errnum, p, errbuflen_remaining);
|
||||
if (err == EINVAL) {
|
||||
/*
|
||||
* UNIX 03 says this isn't guaranteed to produce a
|
||||
@ -129,3 +143,72 @@ pcap_fmt_errmsg_for_errno(char *errbuf, size_t errbuflen, int errnum,
|
||||
pcap_snprintf(p, errbuflen_remaining, "%s", pcap_strerror(errnum));
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
/*
|
||||
* Generate an error message based on a format, arguments, and a
|
||||
* Win32 error, with a message for the Win32 error after the formatted output.
|
||||
*/
|
||||
void
|
||||
pcap_fmt_errmsg_for_win32_err(char *errbuf, size_t errbuflen, DWORD errnum,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
size_t msglen;
|
||||
char *p;
|
||||
size_t errbuflen_remaining;
|
||||
DWORD retval;
|
||||
char win32_errbuf[PCAP_ERRBUF_SIZE+1];
|
||||
|
||||
va_start(ap, fmt);
|
||||
pcap_vsnprintf(errbuf, errbuflen, fmt, ap);
|
||||
va_end(ap);
|
||||
msglen = strlen(errbuf);
|
||||
|
||||
/*
|
||||
* Do we have enough space to append ": "?
|
||||
* Including the terminating '\0', that's 3 bytes.
|
||||
*/
|
||||
if (msglen + 3 > errbuflen) {
|
||||
/* No - just give them what we've produced. */
|
||||
return;
|
||||
}
|
||||
p = errbuf + msglen;
|
||||
errbuflen_remaining = errbuflen - msglen;
|
||||
*p++ = ':';
|
||||
*p++ = ' ';
|
||||
*p = '\0';
|
||||
msglen += 2;
|
||||
errbuflen_remaining -= 2;
|
||||
|
||||
/*
|
||||
* Now append the string for the error code.
|
||||
*
|
||||
* XXX - what language ID to use?
|
||||
*
|
||||
* For UN*Xes, pcap_strerror() may or may not return localized
|
||||
* strings.
|
||||
*
|
||||
* We currently don't have localized messages for libpcap, but
|
||||
* we might want to do so. On the other hand, if most of these
|
||||
* messages are going to be read by libpcap developers and
|
||||
* perhaps by developers of libpcap-based applications, English
|
||||
* might be a better choice, so the developer doesn't have to
|
||||
* get the message translated if it's in a language they don't
|
||||
* happen to understand.
|
||||
*/
|
||||
retval = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|FORMAT_MESSAGE_MAX_WIDTH_MASK,
|
||||
NULL, errnum, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
win32_errbuf, PCAP_ERRBUF_SIZE, NULL);
|
||||
if (retval == 0) {
|
||||
/*
|
||||
* Failed.
|
||||
*/
|
||||
pcap_snprintf(p, errbuflen_remaining,
|
||||
"Couldn't get error message for error (%lu)", errnum);
|
||||
return;
|
||||
}
|
||||
|
||||
pcap_snprintf(p, errbuflen_remaining, "%s (%lu)", win32_errbuf, errnum);
|
||||
}
|
||||
#endif
|
||||
|
@ -43,6 +43,11 @@ extern "C" {
|
||||
void pcap_fmt_errmsg_for_errno(char *, size_t, int,
|
||||
PCAP_FORMAT_STRING(const char *), ...) PCAP_PRINTFLIKE(4, 5);
|
||||
|
||||
#ifdef _WIN32
|
||||
void pcap_fmt_errmsg_for_win32_err(char *, size_t, DWORD,
|
||||
PCAP_FORMAT_STRING(const char *), ...) PCAP_PRINTFLIKE(4, 5);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
18
ftmacros.h
18
ftmacros.h
@ -85,20 +85,14 @@
|
||||
*/
|
||||
#elif defined(__linux__) || defined(linux) || defined(__linux)
|
||||
/*
|
||||
* We can't turn _GNU_SOURCE on because some versions of GNU Libc
|
||||
* will give the GNU version of strerror_r(), which returns a
|
||||
* string pointer and doesn't necessarily fill in the buffer,
|
||||
* rather than the standard version of strerror_r(), which
|
||||
* returns 0 or an errno and always fills in the buffer. We
|
||||
* require both of the latter behaviors.
|
||||
* Turn on _GNU_SOURCE to get everything GNU libc has to offer,
|
||||
* including asprintf().
|
||||
*
|
||||
* So we try turning everything else on that we can. This includes
|
||||
* defining _XOPEN_SOURCE as 600, because we want to force crypt()
|
||||
* to be declared on systems that use GNU libc, such as most Linux
|
||||
* distributions.
|
||||
* Unfortunately, one thing it has to offer is a strerror_r()
|
||||
* that's not POSIX-compliant, but we deal with that in
|
||||
* pcap_fmt_errmsg_for_errno().
|
||||
*/
|
||||
#define _POSIX_C_SOURCE 200809L
|
||||
#define _XOPEN_SOURCE 600
|
||||
#define _GNU_SOURCE
|
||||
|
||||
/*
|
||||
* We turn on both _DEFAULT_SOURCE and _BSD_SOURCE to try to get
|
||||
|
55
gencode.h
55
gencode.h
@ -113,16 +113,14 @@
|
||||
#define Q_ISIS_L2 32
|
||||
/* PDU types */
|
||||
#define Q_ISIS_IIH 33
|
||||
#define Q_ISIS_LAN_IIH 34
|
||||
#define Q_ISIS_PTP_IIH 35
|
||||
#define Q_ISIS_SNP 36
|
||||
#define Q_ISIS_CSNP 37
|
||||
#define Q_ISIS_PSNP 38
|
||||
#define Q_ISIS_LSP 39
|
||||
#define Q_ISIS_SNP 34
|
||||
#define Q_ISIS_CSNP 35
|
||||
#define Q_ISIS_PSNP 36
|
||||
#define Q_ISIS_LSP 37
|
||||
|
||||
#define Q_RADIO 40
|
||||
#define Q_RADIO 38
|
||||
|
||||
#define Q_CARP 41
|
||||
#define Q_CARP 39
|
||||
|
||||
/* Directional qualifiers. */
|
||||
|
||||
@ -299,8 +297,8 @@ void gen_or(struct block *, struct block *);
|
||||
void gen_not(struct block *);
|
||||
|
||||
struct block *gen_scode(compiler_state_t *, const char *, struct qual);
|
||||
struct block *gen_ecode(compiler_state_t *, const u_char *, struct qual);
|
||||
struct block *gen_acode(compiler_state_t *, const u_char *, struct qual);
|
||||
struct block *gen_ecode(compiler_state_t *, const char *, struct qual);
|
||||
struct block *gen_acode(compiler_state_t *, const char *, struct qual);
|
||||
struct block *gen_mcode(compiler_state_t *, const char *, const char *,
|
||||
unsigned int, struct qual);
|
||||
#ifdef INET6
|
||||
@ -326,13 +324,13 @@ struct block *gen_llc_u(compiler_state_t *);
|
||||
struct block *gen_llc_s_subtype(compiler_state_t *, bpf_u_int32);
|
||||
struct block *gen_llc_u_subtype(compiler_state_t *, bpf_u_int32);
|
||||
|
||||
struct block *gen_vlan(compiler_state_t *, int);
|
||||
struct block *gen_mpls(compiler_state_t *, int);
|
||||
struct block *gen_vlan(compiler_state_t *, bpf_u_int32, int);
|
||||
struct block *gen_mpls(compiler_state_t *, bpf_u_int32, int);
|
||||
|
||||
struct block *gen_pppoed(compiler_state_t *);
|
||||
struct block *gen_pppoes(compiler_state_t *, int);
|
||||
struct block *gen_pppoes(compiler_state_t *, bpf_u_int32, int);
|
||||
|
||||
struct block *gen_geneve(compiler_state_t *, int);
|
||||
struct block *gen_geneve(compiler_state_t *, bpf_u_int32, int);
|
||||
|
||||
struct block *gen_atmfield_code(compiler_state_t *, int, bpf_int32,
|
||||
bpf_u_int32, int);
|
||||
@ -343,29 +341,11 @@ struct block *gen_mtp2type_abbrev(compiler_state_t *, int type);
|
||||
struct block *gen_mtp3field_code(compiler_state_t *, int, bpf_u_int32,
|
||||
bpf_u_int32, int);
|
||||
|
||||
#ifndef HAVE_NET_PFVAR_H
|
||||
PCAP_NORETURN
|
||||
#endif
|
||||
struct block *gen_pf_ifname(compiler_state_t *, const char *);
|
||||
#ifndef HAVE_NET_PFVAR_H
|
||||
PCAP_NORETURN
|
||||
#endif
|
||||
struct block *gen_pf_rnr(compiler_state_t *, int);
|
||||
#ifndef HAVE_NET_PFVAR_H
|
||||
PCAP_NORETURN
|
||||
#endif
|
||||
struct block *gen_pf_srnr(compiler_state_t *, int);
|
||||
#ifndef HAVE_NET_PFVAR_H
|
||||
PCAP_NORETURN
|
||||
#endif
|
||||
struct block *gen_pf_ruleset(compiler_state_t *, char *);
|
||||
#ifndef HAVE_NET_PFVAR_H
|
||||
PCAP_NORETURN
|
||||
#endif
|
||||
struct block *gen_pf_reason(compiler_state_t *, int);
|
||||
#ifndef HAVE_NET_PFVAR_H
|
||||
PCAP_NORETURN
|
||||
#endif
|
||||
struct block *gen_pf_action(compiler_state_t *, int);
|
||||
|
||||
struct block *gen_p80211_type(compiler_state_t *, int, int);
|
||||
@ -386,16 +366,15 @@ struct icode {
|
||||
int cur_mark;
|
||||
};
|
||||
|
||||
void bpf_optimize(compiler_state_t *, struct icode *ic);
|
||||
void PCAP_NORETURN bpf_syntax_error(compiler_state_t *, const char *);
|
||||
void PCAP_NORETURN bpf_error(compiler_state_t *, const char *, ...)
|
||||
int bpf_optimize(struct icode *, char *);
|
||||
void bpf_set_error(compiler_state_t *, const char *, ...)
|
||||
PCAP_PRINTFLIKE(2, 3);
|
||||
|
||||
void finish_parse(compiler_state_t *, struct block *);
|
||||
int finish_parse(compiler_state_t *, struct block *);
|
||||
char *sdup(compiler_state_t *, const char *);
|
||||
|
||||
struct bpf_insn *icode_to_fcode(compiler_state_t *, struct icode *,
|
||||
struct block *, u_int *);
|
||||
struct bpf_insn *icode_to_fcode(struct icode *, struct block *, u_int *,
|
||||
char *);
|
||||
void sappend(struct slist *, struct slist *);
|
||||
|
||||
/*
|
||||
|
312
grammar.y
312
grammar.y
@ -216,13 +216,12 @@ str2tok(const char *str, const struct tok *toks)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static struct qual qerr = { Q_UNDEF, Q_UNDEF, Q_UNDEF, Q_UNDEF };
|
||||
static const struct qual qerr = { Q_UNDEF, Q_UNDEF, Q_UNDEF, Q_UNDEF };
|
||||
|
||||
static PCAP_NORETURN_DEF void
|
||||
static void
|
||||
yyerror(void *yyscanner _U_, compiler_state_t *cstate, const char *msg)
|
||||
{
|
||||
bpf_syntax_error(cstate, msg);
|
||||
/* NOTREACHED */
|
||||
bpf_set_error(cstate, "can't parse filter expression: %s", msg);
|
||||
}
|
||||
|
||||
#ifdef HAVE_NET_PFVAR_H
|
||||
@ -236,8 +235,8 @@ pfreason_to_num(compiler_state_t *cstate, const char *reason)
|
||||
if (pcap_strcasecmp(reason, reasons[i]) == 0)
|
||||
return (i);
|
||||
}
|
||||
bpf_error(cstate, "unknown PF reason");
|
||||
/*NOTREACHED*/
|
||||
bpf_set_error(cstate, "unknown PF reason");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -260,33 +259,38 @@ pfaction_to_num(compiler_state_t *cstate, const char *action)
|
||||
return (PF_NORDR);
|
||||
#endif
|
||||
else {
|
||||
bpf_error(cstate, "unknown PF action");
|
||||
/*NOTREACHED*/
|
||||
bpf_set_error(cstate, "unknown PF action");
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
#else /* !HAVE_NET_PFVAR_H */
|
||||
static PCAP_NORETURN_DEF int
|
||||
static int
|
||||
pfreason_to_num(compiler_state_t *cstate, const char *reason _U_)
|
||||
{
|
||||
bpf_error(cstate, "libpcap was compiled on a machine without pf support");
|
||||
/*NOTREACHED*/
|
||||
bpf_set_error(cstate, "libpcap was compiled on a machine without pf support");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static PCAP_NORETURN_DEF int
|
||||
static int
|
||||
pfaction_to_num(compiler_state_t *cstate, const char *action _U_)
|
||||
{
|
||||
bpf_error(cstate, "libpcap was compiled on a machine without pf support");
|
||||
/*NOTREACHED*/
|
||||
bpf_set_error(cstate, "libpcap was compiled on a machine without pf support");
|
||||
return (-1);
|
||||
}
|
||||
#endif /* HAVE_NET_PFVAR_H */
|
||||
|
||||
/*
|
||||
* For calls that might return an "an error occurred" value.
|
||||
*/
|
||||
#define CHECK_INT_VAL(val) if (val == -1) YYABORT
|
||||
#define CHECK_PTR_VAL(val) if (val == NULL) YYABORT
|
||||
|
||||
DIAG_OFF_BISON_BYACC
|
||||
%}
|
||||
|
||||
%union {
|
||||
int i;
|
||||
bpf_u_int32 h;
|
||||
u_char *e;
|
||||
char *s;
|
||||
struct stmt *stmt;
|
||||
struct arth *a;
|
||||
@ -340,11 +344,9 @@ DIAG_OFF_BISON_BYACC
|
||||
%token RADIO
|
||||
%token FISU LSSU MSU HFISU HLSSU HMSU
|
||||
%token SIO OPC DPC SLS HSIO HOPC HDPC HSLS
|
||||
%token LEX_ERROR
|
||||
|
||||
|
||||
%type <s> ID
|
||||
%type <e> EID
|
||||
%type <e> AID
|
||||
%type <s> ID EID AID
|
||||
%type <s> HID HID6
|
||||
%type <i> NUM action reason type subtype type_subtype dir
|
||||
|
||||
@ -359,7 +361,7 @@ DIAG_OFF_BISON_BYACC
|
||||
%%
|
||||
prog: null expr
|
||||
{
|
||||
finish_parse(cstate, $2.b);
|
||||
CHECK_INT_VAL(finish_parse(cstate, $2.b));
|
||||
}
|
||||
| null
|
||||
;
|
||||
@ -376,64 +378,58 @@ and: AND { $$ = $<blk>0; }
|
||||
or: OR { $$ = $<blk>0; }
|
||||
;
|
||||
id: nid
|
||||
| pnum { $$.b = gen_ncode(cstate, NULL, (bpf_u_int32)$1,
|
||||
$$.q = $<blk>0.q); }
|
||||
| pnum { CHECK_PTR_VAL(($$.b = gen_ncode(cstate, NULL, (bpf_u_int32)$1,
|
||||
$$.q = $<blk>0.q))); }
|
||||
| paren pid ')' { $$ = $2; }
|
||||
;
|
||||
nid: ID { $$.b = gen_scode(cstate, $1, $$.q = $<blk>0.q); }
|
||||
| HID '/' NUM { $$.b = gen_mcode(cstate, $1, NULL, $3,
|
||||
$$.q = $<blk>0.q); }
|
||||
| HID NETMASK HID { $$.b = gen_mcode(cstate, $1, $3, 0,
|
||||
$$.q = $<blk>0.q); }
|
||||
nid: ID { CHECK_PTR_VAL($1); CHECK_PTR_VAL(($$.b = gen_scode(cstate, $1, $$.q = $<blk>0.q))); }
|
||||
| HID '/' NUM { CHECK_PTR_VAL($1); CHECK_PTR_VAL(($$.b = gen_mcode(cstate, $1, NULL, $3,
|
||||
$$.q = $<blk>0.q))); }
|
||||
| HID NETMASK HID { CHECK_PTR_VAL($1); CHECK_PTR_VAL(($$.b = gen_mcode(cstate, $1, $3, 0,
|
||||
$$.q = $<blk>0.q))); }
|
||||
| HID {
|
||||
CHECK_PTR_VAL($1);
|
||||
/* Decide how to parse HID based on proto */
|
||||
$$.q = $<blk>0.q;
|
||||
if ($$.q.addr == Q_PORT)
|
||||
bpf_error(cstate, "'port' modifier applied to ip host");
|
||||
else if ($$.q.addr == Q_PORTRANGE)
|
||||
bpf_error(cstate, "'portrange' modifier applied to ip host");
|
||||
else if ($$.q.addr == Q_PROTO)
|
||||
bpf_error(cstate, "'proto' modifier applied to ip host");
|
||||
else if ($$.q.addr == Q_PROTOCHAIN)
|
||||
bpf_error(cstate, "'protochain' modifier applied to ip host");
|
||||
$$.b = gen_ncode(cstate, $1, 0, $$.q);
|
||||
if ($$.q.addr == Q_PORT) {
|
||||
bpf_set_error(cstate, "'port' modifier applied to ip host");
|
||||
YYABORT;
|
||||
} else if ($$.q.addr == Q_PORTRANGE) {
|
||||
bpf_set_error(cstate, "'portrange' modifier applied to ip host");
|
||||
YYABORT;
|
||||
} else if ($$.q.addr == Q_PROTO) {
|
||||
bpf_set_error(cstate, "'proto' modifier applied to ip host");
|
||||
YYABORT;
|
||||
} else if ($$.q.addr == Q_PROTOCHAIN) {
|
||||
bpf_set_error(cstate, "'protochain' modifier applied to ip host");
|
||||
YYABORT;
|
||||
}
|
||||
CHECK_PTR_VAL(($$.b = gen_ncode(cstate, $1, 0, $$.q)));
|
||||
}
|
||||
| HID6 '/' NUM {
|
||||
CHECK_PTR_VAL($1);
|
||||
#ifdef INET6
|
||||
$$.b = gen_mcode6(cstate, $1, NULL, $3,
|
||||
$$.q = $<blk>0.q);
|
||||
CHECK_PTR_VAL(($$.b = gen_mcode6(cstate, $1, NULL, $3,
|
||||
$$.q = $<blk>0.q)));
|
||||
#else
|
||||
bpf_error(cstate, "'ip6addr/prefixlen' not supported "
|
||||
bpf_set_error(cstate, "'ip6addr/prefixlen' not supported "
|
||||
"in this configuration");
|
||||
YYABORT;
|
||||
#endif /*INET6*/
|
||||
}
|
||||
| HID6 {
|
||||
CHECK_PTR_VAL($1);
|
||||
#ifdef INET6
|
||||
$$.b = gen_mcode6(cstate, $1, 0, 128,
|
||||
$$.q = $<blk>0.q);
|
||||
CHECK_PTR_VAL(($$.b = gen_mcode6(cstate, $1, 0, 128,
|
||||
$$.q = $<blk>0.q)));
|
||||
#else
|
||||
bpf_error(cstate, "'ip6addr' not supported "
|
||||
bpf_set_error(cstate, "'ip6addr' not supported "
|
||||
"in this configuration");
|
||||
YYABORT;
|
||||
#endif /*INET6*/
|
||||
}
|
||||
| EID {
|
||||
$$.b = gen_ecode(cstate, $1, $$.q = $<blk>0.q);
|
||||
/*
|
||||
* $1 was allocated by "pcap_ether_aton()",
|
||||
* so we must free it now that we're done
|
||||
* with it.
|
||||
*/
|
||||
free($1);
|
||||
}
|
||||
| AID {
|
||||
$$.b = gen_acode(cstate, $1, $$.q = $<blk>0.q);
|
||||
/*
|
||||
* $1 was allocated by "pcap_ether_aton()",
|
||||
* so we must free it now that we're done
|
||||
* with it.
|
||||
*/
|
||||
free($1);
|
||||
}
|
||||
| EID { CHECK_PTR_VAL($1); CHECK_PTR_VAL(($$.b = gen_ecode(cstate, $1, $$.q = $<blk>0.q))); }
|
||||
| AID { CHECK_PTR_VAL($1); CHECK_PTR_VAL(($$.b = gen_acode(cstate, $1, $$.q = $<blk>0.q))); }
|
||||
| not id { gen_not($2.b); $$ = $2; }
|
||||
;
|
||||
not: '!' { $$ = $<blk>0; }
|
||||
@ -444,8 +440,8 @@ pid: nid
|
||||
| qid and id { gen_and($1.b, $3.b); $$ = $3; }
|
||||
| qid or id { gen_or($1.b, $3.b); $$ = $3; }
|
||||
;
|
||||
qid: pnum { $$.b = gen_ncode(cstate, NULL, (bpf_u_int32)$1,
|
||||
$$.q = $<blk>0.q); }
|
||||
qid: pnum { CHECK_PTR_VAL(($$.b = gen_ncode(cstate, NULL, (bpf_u_int32)$1,
|
||||
$$.q = $<blk>0.q))); }
|
||||
| pid
|
||||
;
|
||||
term: rterm
|
||||
@ -455,21 +451,28 @@ head: pqual dqual aqual { QSET($$.q, $1, $2, $3); }
|
||||
| pqual dqual { QSET($$.q, $1, $2, Q_DEFAULT); }
|
||||
| pqual aqual { QSET($$.q, $1, Q_DEFAULT, $2); }
|
||||
| pqual PROTO { QSET($$.q, $1, Q_DEFAULT, Q_PROTO); }
|
||||
| pqual PROTOCHAIN { QSET($$.q, $1, Q_DEFAULT, Q_PROTOCHAIN); }
|
||||
| pqual PROTOCHAIN {
|
||||
#ifdef NO_PROTOCHAIN
|
||||
bpf_set_error(cstate, "protochain not supported");
|
||||
YYABORT;
|
||||
#else
|
||||
QSET($$.q, $1, Q_DEFAULT, Q_PROTOCHAIN);
|
||||
#endif
|
||||
}
|
||||
| pqual ndaqual { QSET($$.q, $1, Q_DEFAULT, $2); }
|
||||
;
|
||||
rterm: head id { $$ = $2; }
|
||||
| paren expr ')' { $$.b = $2.b; $$.q = $1.q; }
|
||||
| pname { $$.b = gen_proto_abbrev(cstate, $1); $$.q = qerr; }
|
||||
| arth relop arth { $$.b = gen_relation(cstate, $2, $1, $3, 0);
|
||||
| pname { CHECK_PTR_VAL(($$.b = gen_proto_abbrev(cstate, $1))); $$.q = qerr; }
|
||||
| arth relop arth { CHECK_PTR_VAL(($$.b = gen_relation(cstate, $2, $1, $3, 0)));
|
||||
$$.q = qerr; }
|
||||
| arth irelop arth { $$.b = gen_relation(cstate, $2, $1, $3, 1);
|
||||
| arth irelop arth { CHECK_PTR_VAL(($$.b = gen_relation(cstate, $2, $1, $3, 1)));
|
||||
$$.q = qerr; }
|
||||
| other { $$.b = $1; $$.q = qerr; }
|
||||
| atmtype { $$.b = gen_atmtype_abbrev(cstate, $1); $$.q = qerr; }
|
||||
| atmmultitype { $$.b = gen_atmmulti_abbrev(cstate, $1); $$.q = qerr; }
|
||||
| atmtype { CHECK_PTR_VAL(($$.b = gen_atmtype_abbrev(cstate, $1))); $$.q = qerr; }
|
||||
| atmmultitype { CHECK_PTR_VAL(($$.b = gen_atmmulti_abbrev(cstate, $1))); $$.q = qerr; }
|
||||
| atmfield atmvalue { $$.b = $2.b; $$.q = qerr; }
|
||||
| mtp2type { $$.b = gen_mtp2type_abbrev(cstate, $1); $$.q = qerr; }
|
||||
| mtp2type { CHECK_PTR_VAL(($$.b = gen_mtp2type_abbrev(cstate, $1))); $$.q = qerr; }
|
||||
| mtp3field mtp3value { $$.b = $2.b; $$.q = qerr; }
|
||||
;
|
||||
/* protocol level qualifiers */
|
||||
@ -539,65 +542,69 @@ pname: LINK { $$ = Q_LINK; }
|
||||
| NETBEUI { $$ = Q_NETBEUI; }
|
||||
| RADIO { $$ = Q_RADIO; }
|
||||
;
|
||||
other: pqual TK_BROADCAST { $$ = gen_broadcast(cstate, $1); }
|
||||
| pqual TK_MULTICAST { $$ = gen_multicast(cstate, $1); }
|
||||
| LESS NUM { $$ = gen_less(cstate, $2); }
|
||||
| GREATER NUM { $$ = gen_greater(cstate, $2); }
|
||||
| CBYTE NUM byteop NUM { $$ = gen_byteop(cstate, $3, $2, $4); }
|
||||
| INBOUND { $$ = gen_inbound(cstate, 0); }
|
||||
| OUTBOUND { $$ = gen_inbound(cstate, 1); }
|
||||
| VLAN pnum { $$ = gen_vlan(cstate, $2); }
|
||||
| VLAN { $$ = gen_vlan(cstate, -1); }
|
||||
| MPLS pnum { $$ = gen_mpls(cstate, $2); }
|
||||
| MPLS { $$ = gen_mpls(cstate, -1); }
|
||||
| PPPOED { $$ = gen_pppoed(cstate); }
|
||||
| PPPOES pnum { $$ = gen_pppoes(cstate, $2); }
|
||||
| PPPOES { $$ = gen_pppoes(cstate, -1); }
|
||||
| GENEVE pnum { $$ = gen_geneve(cstate, $2); }
|
||||
| GENEVE { $$ = gen_geneve(cstate, -1); }
|
||||
other: pqual TK_BROADCAST { CHECK_PTR_VAL(($$ = gen_broadcast(cstate, $1))); }
|
||||
| pqual TK_MULTICAST { CHECK_PTR_VAL(($$ = gen_multicast(cstate, $1))); }
|
||||
| LESS NUM { CHECK_PTR_VAL(($$ = gen_less(cstate, $2))); }
|
||||
| GREATER NUM { CHECK_PTR_VAL(($$ = gen_greater(cstate, $2))); }
|
||||
| CBYTE NUM byteop NUM { CHECK_PTR_VAL(($$ = gen_byteop(cstate, $3, $2, $4))); }
|
||||
| INBOUND { CHECK_PTR_VAL(($$ = gen_inbound(cstate, 0))); }
|
||||
| OUTBOUND { CHECK_PTR_VAL(($$ = gen_inbound(cstate, 1))); }
|
||||
| VLAN pnum { CHECK_PTR_VAL(($$ = gen_vlan(cstate, (bpf_u_int32)$2, 1))); }
|
||||
| VLAN { CHECK_PTR_VAL(($$ = gen_vlan(cstate, 0, 0))); }
|
||||
| MPLS pnum { CHECK_PTR_VAL(($$ = gen_mpls(cstate, (bpf_u_int32)$2, 1))); }
|
||||
| MPLS { CHECK_PTR_VAL(($$ = gen_mpls(cstate, 0, 0))); }
|
||||
| PPPOED { CHECK_PTR_VAL(($$ = gen_pppoed(cstate))); }
|
||||
| PPPOES pnum { CHECK_PTR_VAL(($$ = gen_pppoes(cstate, (bpf_u_int32)$2, 1))); }
|
||||
| PPPOES { CHECK_PTR_VAL(($$ = gen_pppoes(cstate, 0, 0))); }
|
||||
| GENEVE pnum { CHECK_PTR_VAL(($$ = gen_geneve(cstate, (bpf_u_int32)$2, 1))); }
|
||||
| GENEVE { CHECK_PTR_VAL(($$ = gen_geneve(cstate, 0, 0))); }
|
||||
| pfvar { $$ = $1; }
|
||||
| pqual p80211 { $$ = $2; }
|
||||
| pllc { $$ = $1; }
|
||||
;
|
||||
|
||||
pfvar: PF_IFNAME ID { $$ = gen_pf_ifname(cstate, $2); }
|
||||
| PF_RSET ID { $$ = gen_pf_ruleset(cstate, $2); }
|
||||
| PF_RNR NUM { $$ = gen_pf_rnr(cstate, $2); }
|
||||
| PF_SRNR NUM { $$ = gen_pf_srnr(cstate, $2); }
|
||||
| PF_REASON reason { $$ = gen_pf_reason(cstate, $2); }
|
||||
| PF_ACTION action { $$ = gen_pf_action(cstate, $2); }
|
||||
pfvar: PF_IFNAME ID { CHECK_PTR_VAL($2); CHECK_PTR_VAL(($$ = gen_pf_ifname(cstate, $2))); }
|
||||
| PF_RSET ID { CHECK_PTR_VAL($2); CHECK_PTR_VAL(($$ = gen_pf_ruleset(cstate, $2))); }
|
||||
| PF_RNR NUM { CHECK_PTR_VAL(($$ = gen_pf_rnr(cstate, $2))); }
|
||||
| PF_SRNR NUM { CHECK_PTR_VAL(($$ = gen_pf_srnr(cstate, $2))); }
|
||||
| PF_REASON reason { CHECK_PTR_VAL(($$ = gen_pf_reason(cstate, $2))); }
|
||||
| PF_ACTION action { CHECK_PTR_VAL(($$ = gen_pf_action(cstate, $2))); }
|
||||
;
|
||||
|
||||
p80211: TYPE type SUBTYPE subtype
|
||||
{ $$ = gen_p80211_type(cstate, $2 | $4,
|
||||
{ CHECK_PTR_VAL(($$ = gen_p80211_type(cstate, $2 | $4,
|
||||
IEEE80211_FC0_TYPE_MASK |
|
||||
IEEE80211_FC0_SUBTYPE_MASK);
|
||||
IEEE80211_FC0_SUBTYPE_MASK)));
|
||||
}
|
||||
| TYPE type { $$ = gen_p80211_type(cstate, $2,
|
||||
IEEE80211_FC0_TYPE_MASK);
|
||||
| TYPE type { CHECK_PTR_VAL(($$ = gen_p80211_type(cstate, $2,
|
||||
IEEE80211_FC0_TYPE_MASK)));
|
||||
}
|
||||
| SUBTYPE type_subtype { $$ = gen_p80211_type(cstate, $2,
|
||||
| SUBTYPE type_subtype { CHECK_PTR_VAL(($$ = gen_p80211_type(cstate, $2,
|
||||
IEEE80211_FC0_TYPE_MASK |
|
||||
IEEE80211_FC0_SUBTYPE_MASK);
|
||||
IEEE80211_FC0_SUBTYPE_MASK)));
|
||||
}
|
||||
| DIR dir { $$ = gen_p80211_fcdir(cstate, $2); }
|
||||
| DIR dir { CHECK_PTR_VAL(($$ = gen_p80211_fcdir(cstate, $2))); }
|
||||
;
|
||||
|
||||
type: NUM
|
||||
| ID { $$ = str2tok($1, ieee80211_types);
|
||||
if ($$ == -1)
|
||||
bpf_error(cstate, "unknown 802.11 type name");
|
||||
| ID { CHECK_PTR_VAL($1);
|
||||
$$ = str2tok($1, ieee80211_types);
|
||||
if ($$ == -1) {
|
||||
bpf_set_error(cstate, "unknown 802.11 type name");
|
||||
YYABORT;
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
subtype: NUM
|
||||
| ID { const struct tok *types = NULL;
|
||||
int i;
|
||||
CHECK_PTR_VAL($1);
|
||||
for (i = 0;; i++) {
|
||||
if (ieee80211_type_subtypes[i].tok == NULL) {
|
||||
/* Ran out of types */
|
||||
bpf_error(cstate, "unknown 802.11 type");
|
||||
break;
|
||||
bpf_set_error(cstate, "unknown 802.11 type");
|
||||
YYABORT;
|
||||
}
|
||||
if ($<i>-1 == ieee80211_type_subtypes[i].type) {
|
||||
types = ieee80211_type_subtypes[i].tok;
|
||||
@ -606,17 +613,20 @@ subtype: NUM
|
||||
}
|
||||
|
||||
$$ = str2tok($1, types);
|
||||
if ($$ == -1)
|
||||
bpf_error(cstate, "unknown 802.11 subtype name");
|
||||
if ($$ == -1) {
|
||||
bpf_set_error(cstate, "unknown 802.11 subtype name");
|
||||
YYABORT;
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
type_subtype: ID { int i;
|
||||
CHECK_PTR_VAL($1);
|
||||
for (i = 0;; i++) {
|
||||
if (ieee80211_type_subtypes[i].tok == NULL) {
|
||||
/* Ran out of types */
|
||||
bpf_error(cstate, "unknown 802.11 type name");
|
||||
break;
|
||||
bpf_set_error(cstate, "unknown 802.11 type name");
|
||||
YYABORT;
|
||||
}
|
||||
$$ = str2tok($1, ieee80211_type_subtypes[i].tok);
|
||||
if ($$ != -1) {
|
||||
@ -627,33 +637,37 @@ type_subtype: ID { int i;
|
||||
}
|
||||
;
|
||||
|
||||
pllc: LLC { $$ = gen_llc(cstate); }
|
||||
| LLC ID { if (pcap_strcasecmp($2, "i") == 0)
|
||||
$$ = gen_llc_i(cstate);
|
||||
else if (pcap_strcasecmp($2, "s") == 0)
|
||||
$$ = gen_llc_s(cstate);
|
||||
else if (pcap_strcasecmp($2, "u") == 0)
|
||||
$$ = gen_llc_u(cstate);
|
||||
else {
|
||||
pllc: LLC { CHECK_PTR_VAL(($$ = gen_llc(cstate))); }
|
||||
| LLC ID { CHECK_PTR_VAL($2);
|
||||
if (pcap_strcasecmp($2, "i") == 0) {
|
||||
CHECK_PTR_VAL(($$ = gen_llc_i(cstate)));
|
||||
} else if (pcap_strcasecmp($2, "s") == 0) {
|
||||
CHECK_PTR_VAL(($$ = gen_llc_s(cstate)));
|
||||
} else if (pcap_strcasecmp($2, "u") == 0) {
|
||||
CHECK_PTR_VAL(($$ = gen_llc_u(cstate)));
|
||||
} else {
|
||||
int subtype;
|
||||
|
||||
subtype = str2tok($2, llc_s_subtypes);
|
||||
if (subtype != -1)
|
||||
$$ = gen_llc_s_subtype(cstate, subtype);
|
||||
else {
|
||||
if (subtype != -1) {
|
||||
CHECK_PTR_VAL(($$ = gen_llc_s_subtype(cstate, subtype)));
|
||||
} else {
|
||||
subtype = str2tok($2, llc_u_subtypes);
|
||||
if (subtype == -1)
|
||||
bpf_error(cstate, "unknown LLC type name \"%s\"", $2);
|
||||
$$ = gen_llc_u_subtype(cstate, subtype);
|
||||
if (subtype == -1) {
|
||||
bpf_set_error(cstate, "unknown LLC type name \"%s\"", $2);
|
||||
YYABORT;
|
||||
}
|
||||
CHECK_PTR_VAL(($$ = gen_llc_u_subtype(cstate, subtype)));
|
||||
}
|
||||
}
|
||||
}
|
||||
/* sigh, "rnr" is already a keyword for PF */
|
||||
| LLC PF_RNR { $$ = gen_llc_s_subtype(cstate, LLC_RNR); }
|
||||
| LLC PF_RNR { CHECK_PTR_VAL(($$ = gen_llc_s_subtype(cstate, LLC_RNR))); }
|
||||
;
|
||||
|
||||
dir: NUM
|
||||
| ID { if (pcap_strcasecmp($1, "nods") == 0)
|
||||
| ID { CHECK_PTR_VAL($1);
|
||||
if (pcap_strcasecmp($1, "nods") == 0)
|
||||
$$ = IEEE80211_FC1_DIR_NODS;
|
||||
else if (pcap_strcasecmp($1, "tods") == 0)
|
||||
$$ = IEEE80211_FC1_DIR_TODS;
|
||||
@ -661,16 +675,18 @@ dir: NUM
|
||||
$$ = IEEE80211_FC1_DIR_FROMDS;
|
||||
else if (pcap_strcasecmp($1, "dstods") == 0)
|
||||
$$ = IEEE80211_FC1_DIR_DSTODS;
|
||||
else
|
||||
bpf_error(cstate, "unknown 802.11 direction");
|
||||
else {
|
||||
bpf_set_error(cstate, "unknown 802.11 direction");
|
||||
YYABORT;
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
reason: NUM { $$ = $1; }
|
||||
| ID { $$ = pfreason_to_num(cstate, $1); }
|
||||
| ID { CHECK_PTR_VAL($1); CHECK_INT_VAL(($$ = pfreason_to_num(cstate, $1))); }
|
||||
;
|
||||
|
||||
action: ID { $$ = pfaction_to_num(cstate, $1); }
|
||||
action: ID { CHECK_PTR_VAL($1); CHECK_INT_VAL(($$ = pfaction_to_num(cstate, $1))); }
|
||||
;
|
||||
|
||||
relop: '>' { $$ = BPF_JGT; }
|
||||
@ -681,24 +697,24 @@ irelop: LEQ { $$ = BPF_JGT; }
|
||||
| '<' { $$ = BPF_JGE; }
|
||||
| NEQ { $$ = BPF_JEQ; }
|
||||
;
|
||||
arth: pnum { $$ = gen_loadi(cstate, $1); }
|
||||
arth: pnum { CHECK_PTR_VAL(($$ = gen_loadi(cstate, $1))); }
|
||||
| narth
|
||||
;
|
||||
narth: pname '[' arth ']' { $$ = gen_load(cstate, $1, $3, 1); }
|
||||
| pname '[' arth ':' NUM ']' { $$ = gen_load(cstate, $1, $3, $5); }
|
||||
| arth '+' arth { $$ = gen_arth(cstate, BPF_ADD, $1, $3); }
|
||||
| arth '-' arth { $$ = gen_arth(cstate, BPF_SUB, $1, $3); }
|
||||
| arth '*' arth { $$ = gen_arth(cstate, BPF_MUL, $1, $3); }
|
||||
| arth '/' arth { $$ = gen_arth(cstate, BPF_DIV, $1, $3); }
|
||||
| arth '%' arth { $$ = gen_arth(cstate, BPF_MOD, $1, $3); }
|
||||
| arth '&' arth { $$ = gen_arth(cstate, BPF_AND, $1, $3); }
|
||||
| arth '|' arth { $$ = gen_arth(cstate, BPF_OR, $1, $3); }
|
||||
| arth '^' arth { $$ = gen_arth(cstate, BPF_XOR, $1, $3); }
|
||||
| arth LSH arth { $$ = gen_arth(cstate, BPF_LSH, $1, $3); }
|
||||
| arth RSH arth { $$ = gen_arth(cstate, BPF_RSH, $1, $3); }
|
||||
| '-' arth %prec UMINUS { $$ = gen_neg(cstate, $2); }
|
||||
narth: pname '[' arth ']' { CHECK_PTR_VAL(($$ = gen_load(cstate, $1, $3, 1))); }
|
||||
| pname '[' arth ':' NUM ']' { CHECK_PTR_VAL(($$ = gen_load(cstate, $1, $3, $5))); }
|
||||
| arth '+' arth { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_ADD, $1, $3))); }
|
||||
| arth '-' arth { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_SUB, $1, $3))); }
|
||||
| arth '*' arth { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_MUL, $1, $3))); }
|
||||
| arth '/' arth { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_DIV, $1, $3))); }
|
||||
| arth '%' arth { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_MOD, $1, $3))); }
|
||||
| arth '&' arth { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_AND, $1, $3))); }
|
||||
| arth '|' arth { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_OR, $1, $3))); }
|
||||
| arth '^' arth { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_XOR, $1, $3))); }
|
||||
| arth LSH arth { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_LSH, $1, $3))); }
|
||||
| arth RSH arth { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_RSH, $1, $3))); }
|
||||
| '-' arth %prec UMINUS { CHECK_PTR_VAL(($$ = gen_neg(cstate, $2))); }
|
||||
| paren narth ')' { $$ = $2; }
|
||||
| LEN { $$ = gen_loadlen(cstate); }
|
||||
| LEN { CHECK_PTR_VAL(($$ = gen_loadlen(cstate))); }
|
||||
;
|
||||
byteop: '&' { $$ = '&'; }
|
||||
| '|' { $$ = '|'; }
|
||||
@ -727,15 +743,15 @@ atmfield: VPI { $$.atmfieldtype = A_VPI; }
|
||||
| VCI { $$.atmfieldtype = A_VCI; }
|
||||
;
|
||||
atmvalue: atmfieldvalue
|
||||
| relop NUM { $$.b = gen_atmfield_code(cstate, $<blk>0.atmfieldtype, (bpf_int32)$2, (bpf_u_int32)$1, 0); }
|
||||
| irelop NUM { $$.b = gen_atmfield_code(cstate, $<blk>0.atmfieldtype, (bpf_int32)$2, (bpf_u_int32)$1, 1); }
|
||||
| relop NUM { CHECK_PTR_VAL(($$.b = gen_atmfield_code(cstate, $<blk>0.atmfieldtype, (bpf_int32)$2, (bpf_u_int32)$1, 0))); }
|
||||
| irelop NUM { CHECK_PTR_VAL(($$.b = gen_atmfield_code(cstate, $<blk>0.atmfieldtype, (bpf_int32)$2, (bpf_u_int32)$1, 1))); }
|
||||
| paren atmlistvalue ')' { $$.b = $2.b; $$.q = qerr; }
|
||||
;
|
||||
atmfieldvalue: NUM {
|
||||
$$.atmfieldtype = $<blk>0.atmfieldtype;
|
||||
if ($$.atmfieldtype == A_VPI ||
|
||||
$$.atmfieldtype == A_VCI)
|
||||
$$.b = gen_atmfield_code(cstate, $$.atmfieldtype, (bpf_int32) $1, BPF_JEQ, 0);
|
||||
CHECK_PTR_VAL(($$.b = gen_atmfield_code(cstate, $$.atmfieldtype, (bpf_int32) $1, BPF_JEQ, 0)));
|
||||
}
|
||||
;
|
||||
atmlistvalue: atmfieldvalue
|
||||
@ -760,8 +776,8 @@ mtp3field: SIO { $$.mtp3fieldtype = M_SIO; }
|
||||
| HSLS { $$.mtp3fieldtype = MH_SLS; }
|
||||
;
|
||||
mtp3value: mtp3fieldvalue
|
||||
| relop NUM { $$.b = gen_mtp3field_code(cstate, $<blk>0.mtp3fieldtype, (u_int)$2, (u_int)$1, 0); }
|
||||
| irelop NUM { $$.b = gen_mtp3field_code(cstate, $<blk>0.mtp3fieldtype, (u_int)$2, (u_int)$1, 1); }
|
||||
| relop NUM { CHECK_PTR_VAL(($$.b = gen_mtp3field_code(cstate, $<blk>0.mtp3fieldtype, (u_int)$2, (u_int)$1, 0))); }
|
||||
| irelop NUM { CHECK_PTR_VAL(($$.b = gen_mtp3field_code(cstate, $<blk>0.mtp3fieldtype, (u_int)$2, (u_int)$1, 1))); }
|
||||
| paren mtp3listvalue ')' { $$.b = $2.b; $$.q = qerr; }
|
||||
;
|
||||
mtp3fieldvalue: NUM {
|
||||
@ -774,7 +790,7 @@ mtp3fieldvalue: NUM {
|
||||
$$.mtp3fieldtype == MH_OPC ||
|
||||
$$.mtp3fieldtype == MH_DPC ||
|
||||
$$.mtp3fieldtype == MH_SLS)
|
||||
$$.b = gen_mtp3field_code(cstate, $$.mtp3fieldtype, (u_int) $1, BPF_JEQ, 0);
|
||||
CHECK_PTR_VAL(($$.b = gen_mtp3field_code(cstate, $$.mtp3fieldtype, (u_int) $1, BPF_JEQ, 0)));
|
||||
}
|
||||
;
|
||||
mtp3listvalue: mtp3fieldvalue
|
||||
|
101
missing/asprintf.c
Normal file
101
missing/asprintf.c
Normal file
@ -0,0 +1,101 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "portability.h"
|
||||
|
||||
/*
|
||||
* vasprintf() and asprintf() for platforms with a C99-compliant
|
||||
* snprintf() - so that, if you format into a 1-byte buffer, it
|
||||
* will return how many characters it would have produced had
|
||||
* it been given an infinite-sized buffer.
|
||||
*/
|
||||
int
|
||||
pcap_vasprintf(char **strp, const char *format, va_list args)
|
||||
{
|
||||
char buf;
|
||||
int len;
|
||||
size_t str_size;
|
||||
char *str;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* XXX - the C99 standard says, in section 7.19.6.5 "Thes
|
||||
* nprintf function":
|
||||
*
|
||||
* The snprintf function is equivalent to fprintf, except that
|
||||
* the output is written into an array (specified by argument s)
|
||||
* rather than to a stream. If n is zero, nothing is written,
|
||||
* and s may be a null pointer. Otherwise, output characters
|
||||
* beyond the n-1st are discarded rather than being written
|
||||
* to the array, and a null character is written at the end
|
||||
* of the characters actually written into the array.
|
||||
*
|
||||
* ...
|
||||
*
|
||||
* The snprintf function returns the number of characters that
|
||||
* would have been written had n been sufficiently large, not
|
||||
* counting the terminating null character, or a negative value
|
||||
* if an encoding error occurred. Thus, the null-terminated
|
||||
* output has been completely written if and only if the returned
|
||||
* value is nonnegative and less than n.
|
||||
*
|
||||
* That doesn't make it entirely clear whether, if a null buffer
|
||||
* pointer and a zero count are passed, it will return the number
|
||||
* of characters that would have been written had a buffer been
|
||||
* passed.
|
||||
*
|
||||
* And, even if C99 *does*, in fact, say it has to work, it
|
||||
* doesn't work in Solaris 8, for example - it returns -1 for
|
||||
* NULL/0, but returns the correct character count for a 1-byte
|
||||
* buffer.
|
||||
*
|
||||
* So we pass a one-character pointer in order to find out how
|
||||
* many characters this format and those arguments will need
|
||||
* without actually generating any more of those characters
|
||||
* than we need.
|
||||
*
|
||||
* (The fact that it might happen to work with GNU libc or with
|
||||
* various BSD libcs is completely uninteresting, as those tend
|
||||
* to have asprintf() already and thus don't even *need* this
|
||||
* code; this is for use in those UN*Xes that *don't* have
|
||||
* asprintf().)
|
||||
*/
|
||||
len = vsnprintf(&buf, sizeof buf, format, args);
|
||||
if (len == -1) {
|
||||
*strp = NULL;
|
||||
return (-1);
|
||||
}
|
||||
str_size = len + 1;
|
||||
str = malloc(str_size);
|
||||
if (str == NULL) {
|
||||
*strp = NULL;
|
||||
return (-1);
|
||||
}
|
||||
ret = vsnprintf(str, str_size, format, args);
|
||||
if (ret == -1) {
|
||||
free(str);
|
||||
*strp = NULL;
|
||||
return (-1);
|
||||
}
|
||||
*strp = str;
|
||||
/*
|
||||
* vsnprintf() shouldn't truncate the string, as we have
|
||||
* allocated a buffer large enough to hold the string, so its
|
||||
* return value should be the number of characters written.
|
||||
*/
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
pcap_asprintf(char **strp, const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
int ret;
|
||||
|
||||
va_start(args, format);
|
||||
ret = pcap_vasprintf(strp, format, args);
|
||||
va_end(args);
|
||||
return (ret);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1995-1999 Kungliga Tekniska Högskolan
|
||||
* Copyright (c) 1995-1999 Kungliga Tekniska Högskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
@ -31,6 +31,10 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* We use this for platforms that don't have snprintf() at all.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
@ -42,7 +46,7 @@
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <pcap-int.h>
|
||||
#include "portability.h"
|
||||
|
||||
enum format_flags {
|
||||
minus_flag = 1,
|
||||
@ -525,6 +529,7 @@ pcap_asnprintf (char **ret, size_t max_sz, const char *format, ...)
|
||||
|
||||
va_start(args, format);
|
||||
val = pcap_vasnprintf (ret, max_sz, format, args);
|
||||
va_end(args);
|
||||
|
||||
#ifdef PARANOIA
|
||||
{
|
||||
@ -534,14 +539,15 @@ pcap_asnprintf (char **ret, size_t max_sz, const char *format, ...)
|
||||
if (tmp == NULL)
|
||||
abort ();
|
||||
|
||||
va_start(args, format);
|
||||
ret2 = pcap_vsprintf (tmp, format, args);
|
||||
va_end(args);
|
||||
if (val != ret2 || strcmp(*ret, tmp))
|
||||
abort ();
|
||||
free (tmp);
|
||||
}
|
||||
#endif
|
||||
|
||||
va_end(args);
|
||||
return val;
|
||||
}
|
||||
#endif
|
||||
|
61
missing/strlcat.c
Normal file
61
missing/strlcat.c
Normal file
@ -0,0 +1,61 @@
|
||||
/* $OpenBSD: pcap_strlcat.c,v 1.15 2015/03/02 21:41:08 millert Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998, 2015 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "portability.h"
|
||||
|
||||
/*
|
||||
* Appends src to string dst of size dsize (unlike strncat, dsize is the
|
||||
* full size of dst, not space left). At most dsize-1 characters
|
||||
* will be copied. Always NUL terminates (unless dsize <= strlen(dst)).
|
||||
* Returns strlen(src) + MIN(dsize, strlen(initial dst)).
|
||||
* If retval >= dsize, truncation occurred.
|
||||
*/
|
||||
size_t
|
||||
pcap_strlcat(char * restrict dst, const char * restrict src, size_t dsize)
|
||||
{
|
||||
const char *odst = dst;
|
||||
const char *osrc = src;
|
||||
size_t n = dsize;
|
||||
size_t dlen;
|
||||
|
||||
/* Find the end of dst and adjust bytes left but don't go past end. */
|
||||
while (n-- != 0 && *dst != '\0')
|
||||
dst++;
|
||||
dlen = dst - odst;
|
||||
n = dsize - dlen;
|
||||
|
||||
if (n-- == 0)
|
||||
return(dlen + strlen(src));
|
||||
while (*src != '\0') {
|
||||
if (n != 0) {
|
||||
*dst++ = *src;
|
||||
n--;
|
||||
}
|
||||
src++;
|
||||
}
|
||||
*dst = '\0';
|
||||
|
||||
return(dlen + (src - osrc)); /* count does not include NUL */
|
||||
}
|
56
missing/strlcpy.c
Normal file
56
missing/strlcpy.c
Normal file
@ -0,0 +1,56 @@
|
||||
/* $OpenBSD: pcap_strlcpy.c,v 1.12 2015/01/15 03:54:12 millert Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998, 2015 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "portability.h"
|
||||
|
||||
/*
|
||||
* Copy string src to buffer dst of size dsize. At most dsize-1
|
||||
* chars will be copied. Always NUL terminates (unless dsize == 0).
|
||||
* Returns strlen(src); if retval >= dsize, truncation occurred.
|
||||
*/
|
||||
size_t
|
||||
pcap_strlcpy(char * restrict dst, const char * restrict src, size_t dsize)
|
||||
{
|
||||
const char *osrc = src;
|
||||
size_t nleft = dsize;
|
||||
|
||||
/* Copy as many bytes as will fit. */
|
||||
if (nleft != 0) {
|
||||
while (--nleft != 0) {
|
||||
if ((*dst++ = *src++) == '\0')
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Not enough room in dst, add NUL and traverse rest of src. */
|
||||
if (nleft == 0) {
|
||||
if (dsize != 0)
|
||||
*dst = '\0'; /* NUL-terminate dst */
|
||||
while (*src++)
|
||||
;
|
||||
}
|
||||
|
||||
return(src - osrc - 1); /* count does not include NUL */
|
||||
}
|
51
missing/win_asprintf.c
Normal file
51
missing/win_asprintf.c
Normal file
@ -0,0 +1,51 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "portability.h"
|
||||
|
||||
int
|
||||
pcap_vasprintf(char **strp, const char *format, va_list args)
|
||||
{
|
||||
int len;
|
||||
size_t str_size;
|
||||
char *str;
|
||||
int ret;
|
||||
|
||||
len = _vscprintf(format, args);
|
||||
if (len == -1) {
|
||||
*strp = NULL;
|
||||
return (-1);
|
||||
}
|
||||
str_size = len + 1;
|
||||
str = malloc(str_size);
|
||||
if (str == NULL) {
|
||||
*strp = NULL;
|
||||
return (-1);
|
||||
}
|
||||
ret = pcap_vsnprintf(str, str_size, format, args);
|
||||
if (ret == -1) {
|
||||
free(str);
|
||||
*strp = NULL;
|
||||
return (-1);
|
||||
}
|
||||
*strp = str;
|
||||
/*
|
||||
* pcap_vsnprintf() shouldn't truncate the string, as we have
|
||||
* allocated a buffer large enough to hold the string, so its
|
||||
* return value should be the number of characters printed.
|
||||
*/
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
pcap_asprintf(char **strp, const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
int ret;
|
||||
|
||||
va_start(args, format);
|
||||
ret = pcap_vasprintf(strp, format, args);
|
||||
va_end(args);
|
||||
return (ret);
|
||||
}
|
@ -1,6 +1,8 @@
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "portability.h"
|
||||
|
||||
int
|
||||
pcap_vsnprintf(char *str, size_t str_size, const char *format, va_list args)
|
||||
{
|
||||
@ -13,6 +15,16 @@ pcap_vsnprintf(char *str, size_t str_size, const char *format, va_list args)
|
||||
* that str is null-terminated, but C99's vsnprintf()
|
||||
* and snprintf() do, and we want to offer C99 behavior,
|
||||
* so forcibly null-terminate the string.
|
||||
*
|
||||
* We don't, however, offer C99 behavior for the return
|
||||
* value; _vsnprintf_s() returns -1, not the number of
|
||||
* characters that would have been put into the buffer
|
||||
* had it been large enough, if the string is truncated.
|
||||
* The only way to get that value is to use _vscprintf();
|
||||
* getting that count isn't worth the re-formatting.
|
||||
*
|
||||
* XXX - does _vsnprintf_s() return -1 on a formatting
|
||||
* error?
|
||||
*/
|
||||
str[str_size - 1] = '\0';
|
||||
return (ret);
|
||||
|
@ -127,7 +127,7 @@ Follow these steps in building libpcap:
|
||||
|
||||
But linking the library with `tcpdump' is the ultimate test. DOS/djgpp
|
||||
should now hopefully be a supported target. Get the sources at:
|
||||
http://www.tcpdump.org/
|
||||
https://www.tcpdump.org/
|
||||
or
|
||||
https://github.com/the-tcpdump-group/tcpdump/
|
||||
|
||||
|
23
nametoaddr.c
23
nametoaddr.c
@ -231,7 +231,22 @@ pcap_nametonetaddr(const char *name)
|
||||
int h_errnoval;
|
||||
int err;
|
||||
|
||||
err = getnetbyname_r(name, &result_buf, buf, sizeof buf, &np,
|
||||
/*
|
||||
* Apparently, the man page at
|
||||
*
|
||||
* http://man7.org/linux/man-pages/man3/getnetbyname_r.3.html
|
||||
*
|
||||
* lies when it says
|
||||
*
|
||||
* If the function call successfully obtains a network record,
|
||||
* then *result is set pointing to result_buf; otherwise, *result
|
||||
* is set to NULL.
|
||||
*
|
||||
* and, in fact, at least in some versions of GNU libc, it does
|
||||
* *not* always get set if getnetbyname_r() succeeds.
|
||||
*/
|
||||
np = NULL;
|
||||
err = getnetbyname_r(name, &result_buf, buf, sizeof buf, &np,
|
||||
&h_errnoval);
|
||||
if (err != 0) {
|
||||
/*
|
||||
@ -306,7 +321,8 @@ pcap_nametoport(const char *name, int *port, int *proto)
|
||||
hints.ai_protocol = IPPROTO_TCP;
|
||||
error = getaddrinfo(NULL, name, &hints, &res);
|
||||
if (error != 0) {
|
||||
if (error != EAI_NONAME) {
|
||||
if (error != EAI_NONAME &&
|
||||
error != EAI_SERVICE) {
|
||||
/*
|
||||
* This is a real error, not just "there's
|
||||
* no such service name".
|
||||
@ -349,7 +365,8 @@ pcap_nametoport(const char *name, int *port, int *proto)
|
||||
hints.ai_protocol = IPPROTO_UDP;
|
||||
error = getaddrinfo(NULL, name, &hints, &res);
|
||||
if (error != 0) {
|
||||
if (error != EAI_NONAME) {
|
||||
if (error != EAI_NONAME &&
|
||||
error != EAI_SERVICE) {
|
||||
/*
|
||||
* This is a real error, not just "there's
|
||||
* no such service name".
|
||||
|
318
optimize.c
318
optimize.c
@ -30,6 +30,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
#include <setjmp.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <errno.h>
|
||||
@ -226,6 +227,16 @@ struct vmapinfo {
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
/*
|
||||
* Place to longjmp to on an error.
|
||||
*/
|
||||
jmp_buf top_ctx;
|
||||
|
||||
/*
|
||||
* The buffer into which to put error message.
|
||||
*/
|
||||
char *errbuf;
|
||||
|
||||
/*
|
||||
* A flag to indicate that further optimization is needed.
|
||||
* Iterative passes are continued until a given pass yields no
|
||||
@ -252,19 +263,19 @@ typedef struct {
|
||||
* True if a is in uset {p}
|
||||
*/
|
||||
#define SET_MEMBER(p, a) \
|
||||
((p)[(unsigned)(a) / BITS_PER_WORD] & (1 << ((unsigned)(a) % BITS_PER_WORD)))
|
||||
((p)[(unsigned)(a) / BITS_PER_WORD] & ((bpf_u_int32)1 << ((unsigned)(a) % BITS_PER_WORD)))
|
||||
|
||||
/*
|
||||
* Add 'a' to uset p.
|
||||
*/
|
||||
#define SET_INSERT(p, a) \
|
||||
(p)[(unsigned)(a) / BITS_PER_WORD] |= (1 << ((unsigned)(a) % BITS_PER_WORD))
|
||||
(p)[(unsigned)(a) / BITS_PER_WORD] |= ((bpf_u_int32)1 << ((unsigned)(a) % BITS_PER_WORD))
|
||||
|
||||
/*
|
||||
* Delete 'a' from uset p.
|
||||
*/
|
||||
#define SET_DELETE(p, a) \
|
||||
(p)[(unsigned)(a) / BITS_PER_WORD] &= ~(1 << ((unsigned)(a) % BITS_PER_WORD))
|
||||
(p)[(unsigned)(a) / BITS_PER_WORD] &= ~((bpf_u_int32)1 << ((unsigned)(a) % BITS_PER_WORD))
|
||||
|
||||
/*
|
||||
* a := a intersect b
|
||||
@ -311,6 +322,16 @@ typedef struct {
|
||||
} opt_state_t;
|
||||
|
||||
typedef struct {
|
||||
/*
|
||||
* Place to longjmp to on an error.
|
||||
*/
|
||||
jmp_buf top_ctx;
|
||||
|
||||
/*
|
||||
* The buffer into which to put error message.
|
||||
*/
|
||||
char *errbuf;
|
||||
|
||||
/*
|
||||
* Some pointers used to convert the basic block form of the code,
|
||||
* into the array form that BPF requires. 'fstart' will point to
|
||||
@ -321,14 +342,16 @@ typedef struct {
|
||||
struct bpf_insn *ftail;
|
||||
} conv_state_t;
|
||||
|
||||
static void opt_init(compiler_state_t *, opt_state_t *, struct icode *);
|
||||
static void opt_init(opt_state_t *, struct icode *);
|
||||
static void opt_cleanup(opt_state_t *);
|
||||
static void PCAP_NORETURN opt_error(opt_state_t *, const char *, ...)
|
||||
PCAP_PRINTFLIKE(2, 3);
|
||||
|
||||
static void intern_blocks(opt_state_t *, struct icode *);
|
||||
|
||||
static void find_inedges(opt_state_t *, struct block *);
|
||||
#ifdef BDEBUG
|
||||
static void opt_dump(compiler_state_t *, struct icode *);
|
||||
static void opt_dump(opt_state_t *, struct icode *);
|
||||
#endif
|
||||
|
||||
#ifndef MAX
|
||||
@ -661,7 +684,7 @@ F(opt_state_t *opt_state, int code, int v0, int v1)
|
||||
int val;
|
||||
struct valnode *p;
|
||||
|
||||
hash = (u_int)code ^ (v0 << 4) ^ (v1 << 8);
|
||||
hash = (u_int)code ^ ((u_int)v0 << 4) ^ ((u_int)v1 << 8);
|
||||
hash %= MODULUS;
|
||||
|
||||
for (p = opt_state->hashtbl[hash]; p; p = p->next)
|
||||
@ -699,8 +722,7 @@ vstore(struct stmt *s, int *valp, int newval, int alter)
|
||||
* (Unary operators are handled elsewhere.)
|
||||
*/
|
||||
static void
|
||||
fold_op(compiler_state_t *cstate, opt_state_t *opt_state,
|
||||
struct stmt *s, int v0, int v1)
|
||||
fold_op(opt_state_t *opt_state, struct stmt *s, int v0, int v1)
|
||||
{
|
||||
bpf_u_int32 a, b;
|
||||
|
||||
@ -722,13 +744,13 @@ fold_op(compiler_state_t *cstate, opt_state_t *opt_state,
|
||||
|
||||
case BPF_DIV:
|
||||
if (b == 0)
|
||||
bpf_error(cstate, "division by zero");
|
||||
opt_error(opt_state, "division by zero");
|
||||
a /= b;
|
||||
break;
|
||||
|
||||
case BPF_MOD:
|
||||
if (b == 0)
|
||||
bpf_error(cstate, "modulus by zero");
|
||||
opt_error(opt_state, "modulus by zero");
|
||||
a %= b;
|
||||
break;
|
||||
|
||||
@ -745,11 +767,39 @@ fold_op(compiler_state_t *cstate, opt_state_t *opt_state,
|
||||
break;
|
||||
|
||||
case BPF_LSH:
|
||||
a <<= b;
|
||||
/*
|
||||
* A left shift of more than the width of the type
|
||||
* is undefined in C; we'll just treat it as shifting
|
||||
* all the bits out.
|
||||
*
|
||||
* XXX - the BPF interpreter doesn't check for this,
|
||||
* so its behavior is dependent on the behavior of
|
||||
* the processor on which it's running. There are
|
||||
* processors on which it shifts all the bits out
|
||||
* and processors on which it does no shift.
|
||||
*/
|
||||
if (b < 32)
|
||||
a <<= b;
|
||||
else
|
||||
a = 0;
|
||||
break;
|
||||
|
||||
case BPF_RSH:
|
||||
a >>= b;
|
||||
/*
|
||||
* A right shift of more than the width of the type
|
||||
* is undefined in C; we'll just treat it as shifting
|
||||
* all the bits out.
|
||||
*
|
||||
* XXX - the BPF interpreter doesn't check for this,
|
||||
* so its behavior is dependent on the behavior of
|
||||
* the processor on which it's running. There are
|
||||
* processors on which it shifts all the bits out
|
||||
* and processors on which it does no shift.
|
||||
*/
|
||||
if (b < 32)
|
||||
a >>= b;
|
||||
else
|
||||
a = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -1041,8 +1091,7 @@ opt_peep(opt_state_t *opt_state, struct block *b)
|
||||
* evaluation and code transformations weren't folded together.
|
||||
*/
|
||||
static void
|
||||
opt_stmt(compiler_state_t *cstate, opt_state_t *opt_state,
|
||||
struct stmt *s, int val[], int alter)
|
||||
opt_stmt(opt_state_t *opt_state, struct stmt *s, int val[], int alter)
|
||||
{
|
||||
int op;
|
||||
int v;
|
||||
@ -1094,7 +1143,23 @@ opt_stmt(compiler_state_t *cstate, opt_state_t *opt_state,
|
||||
case BPF_ALU|BPF_NEG:
|
||||
if (alter && opt_state->vmap[val[A_ATOM]].is_const) {
|
||||
s->code = BPF_LD|BPF_IMM;
|
||||
s->k = -opt_state->vmap[val[A_ATOM]].const_val;
|
||||
/*
|
||||
* Do this negation as unsigned arithmetic; that's
|
||||
* what modern BPF engines do, and it guarantees
|
||||
* that all possible values can be negated. (Yeah,
|
||||
* negating 0x80000000, the minimum signed 32-bit
|
||||
* two's-complement value, results in 0x80000000,
|
||||
* so it's still negative, but we *should* be doing
|
||||
* all unsigned arithmetic here, to match what
|
||||
* modern BPF engines do.)
|
||||
*
|
||||
* Express it as 0U - (unsigned value) so that we
|
||||
* don't get compiler warnings about negating an
|
||||
* unsigned value and don't get UBSan warnings
|
||||
* about the result of negating 0x80000000 being
|
||||
* undefined.
|
||||
*/
|
||||
s->k = 0U - (bpf_u_int32)(opt_state->vmap[val[A_ATOM]].const_val);
|
||||
val[A_ATOM] = K(s->k);
|
||||
}
|
||||
else
|
||||
@ -1114,9 +1179,17 @@ opt_stmt(compiler_state_t *cstate, opt_state_t *opt_state,
|
||||
op = BPF_OP(s->code);
|
||||
if (alter) {
|
||||
if (s->k == 0) {
|
||||
/* don't optimize away "sub #0"
|
||||
/*
|
||||
* Optimize operations where the constant
|
||||
* is zero.
|
||||
*
|
||||
* Don't optimize away "sub #0"
|
||||
* as it may be needed later to
|
||||
* fixup the generated math code */
|
||||
* fixup the generated math code.
|
||||
*
|
||||
* Fail if we're dividing by zero or taking
|
||||
* a modulus by zero.
|
||||
*/
|
||||
if (op == BPF_ADD ||
|
||||
op == BPF_LSH || op == BPF_RSH ||
|
||||
op == BPF_OR || op == BPF_XOR) {
|
||||
@ -1128,9 +1201,15 @@ opt_stmt(compiler_state_t *cstate, opt_state_t *opt_state,
|
||||
val[A_ATOM] = K(s->k);
|
||||
break;
|
||||
}
|
||||
if (op == BPF_DIV)
|
||||
opt_error(opt_state,
|
||||
"division by zero");
|
||||
if (op == BPF_MOD)
|
||||
opt_error(opt_state,
|
||||
"modulus by zero");
|
||||
}
|
||||
if (opt_state->vmap[val[A_ATOM]].is_const) {
|
||||
fold_op(cstate, opt_state, s, val[A_ATOM], K(s->k));
|
||||
fold_op(opt_state, s, val[A_ATOM], K(s->k));
|
||||
val[A_ATOM] = K(s->k);
|
||||
break;
|
||||
}
|
||||
@ -1151,12 +1230,22 @@ opt_stmt(compiler_state_t *cstate, opt_state_t *opt_state,
|
||||
op = BPF_OP(s->code);
|
||||
if (alter && opt_state->vmap[val[X_ATOM]].is_const) {
|
||||
if (opt_state->vmap[val[A_ATOM]].is_const) {
|
||||
fold_op(cstate, opt_state, s, val[A_ATOM], val[X_ATOM]);
|
||||
fold_op(opt_state, s, val[A_ATOM], val[X_ATOM]);
|
||||
val[A_ATOM] = K(s->k);
|
||||
}
|
||||
else {
|
||||
s->code = BPF_ALU|BPF_K|op;
|
||||
s->k = opt_state->vmap[val[X_ATOM]].const_val;
|
||||
/*
|
||||
* XXX - we need to make up our minds
|
||||
* as to what integers are signed and
|
||||
* what integers are unsigned in BPF
|
||||
* programs and in our IR.
|
||||
*/
|
||||
if ((op == BPF_LSH || op == BPF_RSH) &&
|
||||
(s->k < 0 || s->k > 31))
|
||||
opt_error(opt_state,
|
||||
"shift by more than 31 bits");
|
||||
opt_state->done = 0;
|
||||
val[A_ATOM] =
|
||||
F(opt_state, s->code, val[A_ATOM], K(s->k));
|
||||
@ -1275,8 +1364,7 @@ opt_deadstores(opt_state_t *opt_state, register struct block *b)
|
||||
}
|
||||
|
||||
static void
|
||||
opt_blk(compiler_state_t *cstate, opt_state_t *opt_state,
|
||||
struct block *b, int do_stmts)
|
||||
opt_blk(opt_state_t *opt_state, struct block *b, int do_stmts)
|
||||
{
|
||||
struct slist *s;
|
||||
struct edge *p;
|
||||
@ -1326,7 +1414,7 @@ opt_blk(compiler_state_t *cstate, opt_state_t *opt_state,
|
||||
aval = b->val[A_ATOM];
|
||||
xval = b->val[X_ATOM];
|
||||
for (s = b->stmts; s; s = s->next)
|
||||
opt_stmt(cstate, opt_state, &s->s, b->val, do_stmts);
|
||||
opt_stmt(opt_state, &s->s, b->val, do_stmts);
|
||||
|
||||
/*
|
||||
* This is a special case: if we don't use anything from this
|
||||
@ -1480,7 +1568,7 @@ opt_j(opt_state_t *opt_state, struct edge *ep)
|
||||
|
||||
while (x != 0) {
|
||||
k = lowest_set_bit(x);
|
||||
x &=~ (1 << k);
|
||||
x &=~ ((bpf_u_int32)1 << k);
|
||||
k += i * BITS_PER_WORD;
|
||||
|
||||
target = fold_edge(ep->succ, opt_state->edges[k]);
|
||||
@ -1687,8 +1775,7 @@ and_pullup(opt_state_t *opt_state, struct block *b)
|
||||
}
|
||||
|
||||
static void
|
||||
opt_blks(compiler_state_t *cstate, opt_state_t *opt_state, struct icode *ic,
|
||||
int do_stmts)
|
||||
opt_blks(opt_state_t *opt_state, struct icode *ic, int do_stmts)
|
||||
{
|
||||
int i, maxlevel;
|
||||
struct block *p;
|
||||
@ -1699,7 +1786,7 @@ opt_blks(compiler_state_t *cstate, opt_state_t *opt_state, struct icode *ic,
|
||||
find_inedges(opt_state, ic->root);
|
||||
for (i = maxlevel; i >= 0; --i)
|
||||
for (p = opt_state->levels[i]; p; p = p->link)
|
||||
opt_blk(cstate, opt_state, p, do_stmts);
|
||||
opt_blk(opt_state, p, do_stmts);
|
||||
|
||||
if (do_stmts)
|
||||
/*
|
||||
@ -1777,14 +1864,13 @@ opt_root(struct block **b)
|
||||
}
|
||||
|
||||
static void
|
||||
opt_loop(compiler_state_t *cstate, opt_state_t *opt_state, struct icode *ic,
|
||||
int do_stmts)
|
||||
opt_loop(opt_state_t *opt_state, struct icode *ic, int do_stmts)
|
||||
{
|
||||
|
||||
#ifdef BDEBUG
|
||||
if (pcap_optimizer_debug > 1 || pcap_print_dot_graph) {
|
||||
printf("opt_loop(root, %d) begin\n", do_stmts);
|
||||
opt_dump(cstate, ic);
|
||||
opt_dump(opt_state, ic);
|
||||
}
|
||||
#endif
|
||||
do {
|
||||
@ -1794,11 +1880,11 @@ opt_loop(compiler_state_t *cstate, opt_state_t *opt_state, struct icode *ic,
|
||||
find_closure(opt_state, ic->root);
|
||||
find_ud(opt_state, ic->root);
|
||||
find_edom(opt_state, ic->root);
|
||||
opt_blks(cstate, opt_state, ic, do_stmts);
|
||||
opt_blks(opt_state, ic, do_stmts);
|
||||
#ifdef BDEBUG
|
||||
if (pcap_optimizer_debug > 1 || pcap_print_dot_graph) {
|
||||
printf("opt_loop(root, %d) bottom, done=%d\n", do_stmts, opt_state->done);
|
||||
opt_dump(cstate, ic);
|
||||
opt_dump(opt_state, ic);
|
||||
}
|
||||
#endif
|
||||
} while (!opt_state->done);
|
||||
@ -1806,30 +1892,38 @@ opt_loop(compiler_state_t *cstate, opt_state_t *opt_state, struct icode *ic,
|
||||
|
||||
/*
|
||||
* Optimize the filter code in its dag representation.
|
||||
* Return 0 on success, -1 on error.
|
||||
*/
|
||||
void
|
||||
bpf_optimize(compiler_state_t *cstate, struct icode *ic)
|
||||
int
|
||||
bpf_optimize(struct icode *ic, char *errbuf)
|
||||
{
|
||||
opt_state_t opt_state;
|
||||
|
||||
opt_init(cstate, &opt_state, ic);
|
||||
opt_loop(cstate, &opt_state, ic, 0);
|
||||
opt_loop(cstate, &opt_state, ic, 1);
|
||||
memset(&opt_state, 0, sizeof(opt_state));
|
||||
opt_state.errbuf = errbuf;
|
||||
if (setjmp(opt_state.top_ctx)) {
|
||||
opt_cleanup(&opt_state);
|
||||
return -1;
|
||||
}
|
||||
opt_init(&opt_state, ic);
|
||||
opt_loop(&opt_state, ic, 0);
|
||||
opt_loop(&opt_state, ic, 1);
|
||||
intern_blocks(&opt_state, ic);
|
||||
#ifdef BDEBUG
|
||||
if (pcap_optimizer_debug > 1 || pcap_print_dot_graph) {
|
||||
printf("after intern_blocks()\n");
|
||||
opt_dump(cstate, ic);
|
||||
opt_dump(&opt_state, ic);
|
||||
}
|
||||
#endif
|
||||
opt_root(&ic->root);
|
||||
#ifdef BDEBUG
|
||||
if (pcap_optimizer_debug > 1 || pcap_print_dot_graph) {
|
||||
printf("after opt_root()\n");
|
||||
opt_dump(cstate, ic);
|
||||
opt_dump(&opt_state, ic);
|
||||
}
|
||||
#endif
|
||||
opt_cleanup(&opt_state);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1943,6 +2037,24 @@ opt_cleanup(opt_state_t *opt_state)
|
||||
free((void *)opt_state->blocks);
|
||||
}
|
||||
|
||||
/*
|
||||
* For optimizer errors.
|
||||
*/
|
||||
static void PCAP_NORETURN
|
||||
opt_error(opt_state_t *opt_state, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (opt_state->errbuf != NULL) {
|
||||
va_start(ap, fmt);
|
||||
(void)pcap_vsnprintf(opt_state->errbuf,
|
||||
PCAP_ERRBUF_SIZE, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
longjmp(opt_state->top_ctx, 1);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the number of stmts in 's'.
|
||||
*/
|
||||
@ -2027,7 +2139,7 @@ count_stmts(struct icode *ic, struct block *p)
|
||||
* from the total number of blocks and/or statements.
|
||||
*/
|
||||
static void
|
||||
opt_init(compiler_state_t *cstate, opt_state_t *opt_state, struct icode *ic)
|
||||
opt_init(opt_state_t *opt_state, struct icode *ic)
|
||||
{
|
||||
bpf_u_int32 *p;
|
||||
int i, n, max_stmts;
|
||||
@ -2040,22 +2152,24 @@ opt_init(compiler_state_t *cstate, opt_state_t *opt_state, struct icode *ic)
|
||||
n = count_blocks(ic, ic->root);
|
||||
opt_state->blocks = (struct block **)calloc(n, sizeof(*opt_state->blocks));
|
||||
if (opt_state->blocks == NULL)
|
||||
bpf_error(cstate, "malloc");
|
||||
opt_error(opt_state, "malloc");
|
||||
unMarkAll(ic);
|
||||
opt_state->n_blocks = 0;
|
||||
number_blks_r(opt_state, ic, ic->root);
|
||||
|
||||
opt_state->n_edges = 2 * opt_state->n_blocks;
|
||||
opt_state->edges = (struct edge **)calloc(opt_state->n_edges, sizeof(*opt_state->edges));
|
||||
if (opt_state->edges == NULL)
|
||||
bpf_error(cstate, "malloc");
|
||||
if (opt_state->edges == NULL) {
|
||||
opt_error(opt_state, "malloc");
|
||||
}
|
||||
|
||||
/*
|
||||
* The number of levels is bounded by the number of nodes.
|
||||
*/
|
||||
opt_state->levels = (struct block **)calloc(opt_state->n_blocks, sizeof(*opt_state->levels));
|
||||
if (opt_state->levels == NULL)
|
||||
bpf_error(cstate, "malloc");
|
||||
if (opt_state->levels == NULL) {
|
||||
opt_error(opt_state, "malloc");
|
||||
}
|
||||
|
||||
opt_state->edgewords = opt_state->n_edges / (8 * sizeof(bpf_u_int32)) + 1;
|
||||
opt_state->nodewords = opt_state->n_blocks / (8 * sizeof(bpf_u_int32)) + 1;
|
||||
@ -2063,8 +2177,9 @@ opt_init(compiler_state_t *cstate, opt_state_t *opt_state, struct icode *ic)
|
||||
/* XXX */
|
||||
opt_state->space = (bpf_u_int32 *)malloc(2 * opt_state->n_blocks * opt_state->nodewords * sizeof(*opt_state->space)
|
||||
+ opt_state->n_edges * opt_state->edgewords * sizeof(*opt_state->space));
|
||||
if (opt_state->space == NULL)
|
||||
bpf_error(cstate, "malloc");
|
||||
if (opt_state->space == NULL) {
|
||||
opt_error(opt_state, "malloc");
|
||||
}
|
||||
p = opt_state->space;
|
||||
opt_state->all_dom_sets = p;
|
||||
for (i = 0; i < n; ++i) {
|
||||
@ -2101,9 +2216,13 @@ opt_init(compiler_state_t *cstate, opt_state_t *opt_state, struct icode *ic)
|
||||
*/
|
||||
opt_state->maxval = 3 * max_stmts;
|
||||
opt_state->vmap = (struct vmapinfo *)calloc(opt_state->maxval, sizeof(*opt_state->vmap));
|
||||
if (opt_state->vmap == NULL) {
|
||||
opt_error(opt_state, "malloc");
|
||||
}
|
||||
opt_state->vnode_base = (struct valnode *)calloc(opt_state->maxval, sizeof(*opt_state->vnode_base));
|
||||
if (opt_state->vmap == NULL || opt_state->vnode_base == NULL)
|
||||
bpf_error(cstate, "malloc");
|
||||
if (opt_state->vnode_base == NULL) {
|
||||
opt_error(opt_state, "malloc");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2115,6 +2234,9 @@ opt_init(compiler_state_t *cstate, opt_state_t *opt_state, struct icode *ic)
|
||||
int bids[NBIDS];
|
||||
#endif
|
||||
|
||||
static void PCAP_NORETURN conv_error(conv_state_t *, const char *, ...)
|
||||
PCAP_PRINTFLIKE(2, 3);
|
||||
|
||||
/*
|
||||
* Returns true if successful. Returns false if a branch has
|
||||
* an offset that is too large. If so, we have marked that
|
||||
@ -2122,8 +2244,7 @@ int bids[NBIDS];
|
||||
* properly.
|
||||
*/
|
||||
static int
|
||||
convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state,
|
||||
struct icode *ic, struct block *p)
|
||||
convert_code_r(conv_state_t *conv_state, struct icode *ic, struct block *p)
|
||||
{
|
||||
struct bpf_insn *dst;
|
||||
struct slist *src;
|
||||
@ -2136,9 +2257,9 @@ convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state,
|
||||
return (1);
|
||||
Mark(ic, p);
|
||||
|
||||
if (convert_code_r(cstate, conv_state, ic, JF(p)) == 0)
|
||||
if (convert_code_r(conv_state, ic, JF(p)) == 0)
|
||||
return (0);
|
||||
if (convert_code_r(cstate, conv_state, ic, JT(p)) == 0)
|
||||
if (convert_code_r(conv_state, ic, JT(p)) == 0)
|
||||
return (0);
|
||||
|
||||
slen = slength(p->stmts);
|
||||
@ -2151,7 +2272,7 @@ convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state,
|
||||
if (slen) {
|
||||
offset = (struct slist **)calloc(slen, sizeof(struct slist *));
|
||||
if (!offset) {
|
||||
bpf_error(cstate, "not enough core");
|
||||
conv_error(conv_state, "not enough core");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
}
|
||||
@ -2175,7 +2296,8 @@ convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state,
|
||||
if (BPF_CLASS(src->s.code) != BPF_JMP || src->s.code == (BPF_JMP|BPF_JA)) {
|
||||
#if 0
|
||||
if (src->s.jt || src->s.jf) {
|
||||
bpf_error(cstate, "illegal jmp destination");
|
||||
free(offset);
|
||||
conv_error(conv_state, "illegal jmp destination");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
#endif
|
||||
@ -2195,7 +2317,8 @@ convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state,
|
||||
#endif
|
||||
|
||||
if (!src->s.jt || !src->s.jf) {
|
||||
bpf_error(cstate, ljerr, "no jmp destination", off);
|
||||
free(offset);
|
||||
conv_error(conv_state, ljerr, "no jmp destination", off);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
@ -2203,12 +2326,14 @@ convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state,
|
||||
for (i = 0; i < slen; i++) {
|
||||
if (offset[i] == src->s.jt) {
|
||||
if (jt) {
|
||||
bpf_error(cstate, ljerr, "multiple matches", off);
|
||||
free(offset);
|
||||
conv_error(conv_state, ljerr, "multiple matches", off);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
if (i - off - 1 >= 256) {
|
||||
bpf_error(cstate, ljerr, "out-of-range jump", off);
|
||||
free(offset);
|
||||
conv_error(conv_state, ljerr, "out-of-range jump", off);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
dst->jt = (u_char)(i - off - 1);
|
||||
@ -2216,11 +2341,13 @@ convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state,
|
||||
}
|
||||
if (offset[i] == src->s.jf) {
|
||||
if (jf) {
|
||||
bpf_error(cstate, ljerr, "multiple matches", off);
|
||||
free(offset);
|
||||
conv_error(conv_state, ljerr, "multiple matches", off);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
if (i - off - 1 >= 256) {
|
||||
bpf_error(cstate, ljerr, "out-of-range jump", off);
|
||||
free(offset);
|
||||
conv_error(conv_state, ljerr, "out-of-range jump", off);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
dst->jf = (u_char)(i - off - 1);
|
||||
@ -2228,7 +2355,8 @@ convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state,
|
||||
}
|
||||
}
|
||||
if (!jt || !jf) {
|
||||
bpf_error(cstate, ljerr, "no destination found", off);
|
||||
free(offset);
|
||||
conv_error(conv_state, ljerr, "no destination found", off);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
}
|
||||
@ -2257,7 +2385,7 @@ convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state,
|
||||
}
|
||||
/* branch if T to following jump */
|
||||
if (extrajmps >= 256) {
|
||||
bpf_error(cstate, "too many extra jumps");
|
||||
conv_error(conv_state, "too many extra jumps");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
dst->jt = (u_char)extrajmps;
|
||||
@ -2278,7 +2406,7 @@ convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state,
|
||||
/* branch if F to following jump */
|
||||
/* if two jumps are inserted, F goes to second one */
|
||||
if (extrajmps >= 256) {
|
||||
bpf_error(cstate, "too many extra jumps");
|
||||
conv_error(conv_state, "too many extra jumps");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
dst->jf = (u_char)extrajmps;
|
||||
@ -2312,13 +2440,20 @@ convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state,
|
||||
* done with the filter program. See the pcap man page.
|
||||
*/
|
||||
struct bpf_insn *
|
||||
icode_to_fcode(compiler_state_t *cstate, struct icode *ic,
|
||||
struct block *root, u_int *lenp)
|
||||
icode_to_fcode(struct icode *ic, struct block *root, u_int *lenp,
|
||||
char *errbuf)
|
||||
{
|
||||
u_int n;
|
||||
struct bpf_insn *fp;
|
||||
conv_state_t conv_state;
|
||||
|
||||
conv_state.fstart = NULL;
|
||||
conv_state.errbuf = errbuf;
|
||||
if (setjmp(conv_state.top_ctx) != 0) {
|
||||
free(conv_state.fstart);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Loop doing convert_code_r() until no branches remain
|
||||
* with too-large offsets.
|
||||
@ -2328,14 +2463,18 @@ icode_to_fcode(compiler_state_t *cstate, struct icode *ic,
|
||||
n = *lenp = count_stmts(ic, root);
|
||||
|
||||
fp = (struct bpf_insn *)malloc(sizeof(*fp) * n);
|
||||
if (fp == NULL)
|
||||
bpf_error(cstate, "malloc");
|
||||
if (fp == NULL) {
|
||||
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"malloc");
|
||||
free(fp);
|
||||
return NULL;
|
||||
}
|
||||
memset((char *)fp, 0, sizeof(*fp) * n);
|
||||
conv_state.fstart = fp;
|
||||
conv_state.ftail = fp + n;
|
||||
|
||||
unMarkAll(ic);
|
||||
if (convert_code_r(cstate, &conv_state, ic, root))
|
||||
if (convert_code_r(&conv_state, ic, root))
|
||||
break;
|
||||
free(fp);
|
||||
}
|
||||
@ -2343,6 +2482,22 @@ icode_to_fcode(compiler_state_t *cstate, struct icode *ic,
|
||||
return fp;
|
||||
}
|
||||
|
||||
/*
|
||||
* For iconv_to_fconv() errors.
|
||||
*/
|
||||
static void PCAP_NORETURN
|
||||
conv_error(conv_state_t *conv_state, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
(void)pcap_vsnprintf(conv_state->errbuf,
|
||||
PCAP_ERRBUF_SIZE, fmt, ap);
|
||||
va_end(ap);
|
||||
longjmp(conv_state->top_ctx, 1);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/*
|
||||
* Make a copy of a BPF program and put it in the "fcode" member of
|
||||
* a "pcap_t".
|
||||
@ -2452,14 +2607,16 @@ dot_dump_edge(struct icode *ic, struct block *block, FILE *out)
|
||||
* After install graphviz on http://www.graphviz.org/, save it as bpf.dot
|
||||
* and run `dot -Tpng -O bpf.dot' to draw the graph.
|
||||
*/
|
||||
static void
|
||||
dot_dump(compiler_state_t *cstate, struct icode *ic)
|
||||
static int
|
||||
dot_dump(struct icode *ic, char *errbuf)
|
||||
{
|
||||
struct bpf_program f;
|
||||
FILE *out = stdout;
|
||||
|
||||
memset(bids, 0, sizeof bids);
|
||||
f.bf_insns = icode_to_fcode(cstate, ic, ic->root, &f.bf_len);
|
||||
f.bf_insns = icode_to_fcode(ic, ic->root, &f.bf_len, errbuf);
|
||||
if (f.bf_insns == NULL)
|
||||
return -1;
|
||||
|
||||
fprintf(out, "digraph BPF {\n");
|
||||
unMarkAll(ic);
|
||||
@ -2469,30 +2626,39 @@ dot_dump(compiler_state_t *cstate, struct icode *ic)
|
||||
fprintf(out, "}\n");
|
||||
|
||||
free((char *)f.bf_insns);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
plain_dump(compiler_state_t *cstate, struct icode *ic)
|
||||
static int
|
||||
plain_dump(struct icode *ic, char *errbuf)
|
||||
{
|
||||
struct bpf_program f;
|
||||
|
||||
memset(bids, 0, sizeof bids);
|
||||
f.bf_insns = icode_to_fcode(cstate, ic, ic->root, &f.bf_len);
|
||||
f.bf_insns = icode_to_fcode(ic, ic->root, &f.bf_len, errbuf);
|
||||
if (f.bf_insns == NULL)
|
||||
return -1;
|
||||
bpf_dump(&f, 1);
|
||||
putchar('\n');
|
||||
free((char *)f.bf_insns);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
opt_dump(compiler_state_t *cstate, struct icode *ic)
|
||||
opt_dump(opt_state_t *opt_state, struct icode *ic)
|
||||
{
|
||||
int status;
|
||||
char errbuf[PCAP_ERRBUF_SIZE];
|
||||
|
||||
/*
|
||||
* If the CFG, in DOT format, is requested, output it rather than
|
||||
* the code that would be generated from that graph.
|
||||
*/
|
||||
if (pcap_print_dot_graph)
|
||||
dot_dump(cstate, ic);
|
||||
status = dot_dump(ic, errbuf);
|
||||
else
|
||||
plain_dump(cstate, ic);
|
||||
status = plain_dump(ic, errbuf);
|
||||
if (status == -1)
|
||||
opt_error(opt_state, "opt_dump: icode_to_fcode failed: %s", errbuf);
|
||||
}
|
||||
#endif
|
||||
|
108
pcap-bpf.c
108
pcap-bpf.c
@ -206,7 +206,7 @@ static int monitor_mode(pcap_t *, int);
|
||||
# endif
|
||||
|
||||
# if defined(__APPLE__)
|
||||
static void remove_en(pcap_t *);
|
||||
static void remove_non_802_11(pcap_t *);
|
||||
static void remove_802_11(pcap_t *);
|
||||
# endif
|
||||
|
||||
@ -737,10 +737,10 @@ get_dlt_list(int fd, int v, struct bpf_dltlist *bdlp, char *ebuf)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__)
|
||||
static int
|
||||
pcap_can_set_rfmon_bpf(pcap_t *p)
|
||||
{
|
||||
#if defined(__APPLE__)
|
||||
struct utsname osinfo;
|
||||
struct ifreq ifr;
|
||||
int fd;
|
||||
@ -799,8 +799,8 @@ pcap_can_set_rfmon_bpf(pcap_t *p)
|
||||
errno, "socket");
|
||||
return (PCAP_ERROR);
|
||||
}
|
||||
strlcpy(ifr.ifr_name, "wlt", sizeof(ifr.ifr_name));
|
||||
strlcat(ifr.ifr_name, p->opt.device + 2, sizeof(ifr.ifr_name));
|
||||
pcap_strlcpy(ifr.ifr_name, "wlt", sizeof(ifr.ifr_name));
|
||||
pcap_strlcat(ifr.ifr_name, p->opt.device + 2, sizeof(ifr.ifr_name));
|
||||
if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifr) < 0) {
|
||||
/*
|
||||
* No such device?
|
||||
@ -880,7 +880,11 @@ pcap_can_set_rfmon_bpf(pcap_t *p)
|
||||
close(fd);
|
||||
#endif /* BIOCGDLTLIST */
|
||||
return (0);
|
||||
}
|
||||
#elif defined(HAVE_BSD_IEEE80211)
|
||||
static int
|
||||
pcap_can_set_rfmon_bpf(pcap_t *p)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = monitor_mode(p, 0);
|
||||
@ -889,10 +893,14 @@ pcap_can_set_rfmon_bpf(pcap_t *p)
|
||||
if (ret == 0)
|
||||
return (1); /* success */
|
||||
return (ret);
|
||||
#else
|
||||
return (0);
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
static int
|
||||
pcap_can_set_rfmon_bpf(pcap_t *p _U_)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
pcap_stats_bpf(pcap_t *p, struct pcap_stat *ps)
|
||||
@ -1012,18 +1020,21 @@ pcap_read_bpf(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
case EWOULDBLOCK:
|
||||
return (0);
|
||||
|
||||
case ENXIO:
|
||||
case ENXIO: /* FreeBSD, DragonFly BSD, and Darwin */
|
||||
case EIO: /* OpenBSD */
|
||||
/* NetBSD appears not to return an error in this case */
|
||||
/*
|
||||
* The device on which we're capturing
|
||||
* went away.
|
||||
*
|
||||
* XXX - we should really return
|
||||
* PCAP_ERROR_IFACE_NOT_UP, but
|
||||
* pcap_dispatch() etc. aren't
|
||||
* defined to retur that.
|
||||
* an appropriate error for that,
|
||||
* but pcap_dispatch() etc. aren't
|
||||
* documented as having error returns
|
||||
* other than PCAP_ERROR or PCAP_ERROR_BREAK.
|
||||
*/
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"The interface went down");
|
||||
"The interface disappeared");
|
||||
return (PCAP_ERROR);
|
||||
|
||||
#if defined(sun) && !defined(BSD) && !defined(__svr4__) && !defined(__SVR4)
|
||||
@ -1358,8 +1369,8 @@ bpf_load(char *errbuf)
|
||||
|
||||
/* Check if the driver is loaded */
|
||||
memset(&cfg_ld, 0x0, sizeof(cfg_ld));
|
||||
pcap_snprintf(buf, sizeof(buf), "%s/%s", DRIVER_PATH, BPF_NAME);
|
||||
cfg_ld.path = buf;
|
||||
pcap_snprintf(cfg_ld.path, sizeof(cfg_ld.path), "%s/%s", DRIVER_PATH, BPF_NAME);
|
||||
if ((sysconfig(SYS_QUERYLOAD, (void *)&cfg_ld, sizeof(cfg_ld)) == -1) ||
|
||||
(cfg_ld.kmid == 0)) {
|
||||
/* Driver isn't loaded, load it now */
|
||||
@ -1469,7 +1480,7 @@ pcap_cleanup_bpf(pcap_t *p)
|
||||
|
||||
s = socket(AF_LOCAL, SOCK_DGRAM, 0);
|
||||
if (s >= 0) {
|
||||
strlcpy(ifr.ifr_name, pb->device,
|
||||
pcap_strlcpy(ifr.ifr_name, pb->device,
|
||||
sizeof(ifr.ifr_name));
|
||||
ioctl(s, SIOCIFDESTROY, &ifr);
|
||||
close(s);
|
||||
@ -1532,9 +1543,9 @@ check_setif_failure(pcap_t *p, int error)
|
||||
*/
|
||||
fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (fd != -1) {
|
||||
strlcpy(ifr.ifr_name, "en",
|
||||
pcap_strlcpy(ifr.ifr_name, "en",
|
||||
sizeof(ifr.ifr_name));
|
||||
strlcat(ifr.ifr_name, p->opt.device + 3,
|
||||
pcap_strlcat(ifr.ifr_name, p->opt.device + 3,
|
||||
sizeof(ifr.ifr_name));
|
||||
if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifr) < 0) {
|
||||
/*
|
||||
@ -1721,7 +1732,7 @@ pcap_activate_bpf(pcap_t *p)
|
||||
goto bad;
|
||||
}
|
||||
znamelen = zonesep - p->opt.device;
|
||||
(void) strlcpy(path_zname, p->opt.device, znamelen + 1);
|
||||
(void) pcap_strlcpy(path_zname, p->opt.device, znamelen + 1);
|
||||
ifr.lifr_zoneid = getzoneidbyname(path_zname);
|
||||
if (ifr.lifr_zoneid == -1) {
|
||||
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
@ -1786,7 +1797,7 @@ pcap_activate_bpf(pcap_t *p)
|
||||
*/
|
||||
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (sockfd != -1) {
|
||||
strlcpy(ifrname,
|
||||
pcap_strlcpy(ifrname,
|
||||
p->opt.device, ifnamsiz);
|
||||
if (ioctl(sockfd, SIOCGIFFLAGS,
|
||||
(char *)&ifr) < 0) {
|
||||
@ -1888,7 +1899,7 @@ pcap_activate_bpf(pcap_t *p)
|
||||
/*
|
||||
* Create the interface.
|
||||
*/
|
||||
strlcpy(ifr.ifr_name, p->opt.device, sizeof(ifr.ifr_name));
|
||||
pcap_strlcpy(ifr.ifr_name, p->opt.device, sizeof(ifr.ifr_name));
|
||||
if (ioctl(s, SIOCIFCREATE2, &ifr) < 0) {
|
||||
if (errno == EINVAL) {
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
@ -2187,7 +2198,7 @@ pcap_activate_bpf(pcap_t *p)
|
||||
* of link-layer types, as selecting
|
||||
* it will keep monitor mode off.
|
||||
*/
|
||||
remove_en(p);
|
||||
remove_non_802_11(p);
|
||||
|
||||
/*
|
||||
* If the new mode we want isn't
|
||||
@ -2748,12 +2759,21 @@ get_if_flags(const char *name, bpf_u_int32 *flags, char *errbuf)
|
||||
strncpy(req.ifm_name, name, sizeof(req.ifm_name));
|
||||
if (ioctl(sock, SIOCGIFMEDIA, &req) < 0) {
|
||||
if (errno == EOPNOTSUPP || errno == EINVAL || errno == ENOTTY ||
|
||||
errno == ENODEV) {
|
||||
errno == ENODEV || errno == EPERM) {
|
||||
/*
|
||||
* Not supported, so we can't provide any
|
||||
* additional information. Assume that
|
||||
* this means that "connected" vs.
|
||||
* "disconnected" doesn't apply.
|
||||
*
|
||||
* The ioctl routine for Apple's pktap devices,
|
||||
* annoyingly, checks for "are you root?" before
|
||||
* checking whether the ioctl is valid, so it
|
||||
* returns EPERM, rather than ENOTSUP, for the
|
||||
* invalid SIOCGIFMEDIA, unless you're root.
|
||||
* So, just as we do for some ethtool ioctls
|
||||
* on Linux, which makes the same mistake, we
|
||||
* also treat EPERM as meaning "not supported".
|
||||
*/
|
||||
*flags |= PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE;
|
||||
close(sock);
|
||||
@ -2890,7 +2910,7 @@ monitor_mode(pcap_t *p, int set)
|
||||
|
||||
default:
|
||||
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
errno, "SIOCGIFMEDIA 1");
|
||||
errno, "SIOCGIFMEDIA");
|
||||
close(sock);
|
||||
return (PCAP_ERROR);
|
||||
}
|
||||
@ -3032,8 +3052,12 @@ find_802_11(struct bpf_dltlist *bdlp)
|
||||
new_dlt = bdlp->bfl_list[i];
|
||||
break;
|
||||
|
||||
#ifdef DLT_PRISM_HEADER
|
||||
case DLT_PRISM_HEADER:
|
||||
#endif
|
||||
#ifdef DLT_AIRONET_HEADER
|
||||
case DLT_AIRONET_HEADER:
|
||||
#endif
|
||||
case DLT_IEEE802_11_RADIO_AVS:
|
||||
/*
|
||||
* 802.11 with radio, but not radiotap.
|
||||
@ -3068,24 +3092,25 @@ find_802_11(struct bpf_dltlist *bdlp)
|
||||
|
||||
#if defined(__APPLE__) && defined(BIOCGDLTLIST)
|
||||
/*
|
||||
* Remove DLT_EN10MB from the list of DLT_ values, as we're in monitor mode,
|
||||
* and DLT_EN10MB isn't supported in monitor mode.
|
||||
* Remove non-802.11 header types from the list of DLT_ values, as we're in
|
||||
* monitor mode, and those header types aren't supported in monitor mode.
|
||||
*/
|
||||
static void
|
||||
remove_en(pcap_t *p)
|
||||
remove_non_802_11(pcap_t *p)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
/*
|
||||
* Scan the list of DLT_ values and discard DLT_EN10MB.
|
||||
* Scan the list of DLT_ values and discard non-802.11 ones.
|
||||
*/
|
||||
j = 0;
|
||||
for (i = 0; i < p->dlt_count; i++) {
|
||||
switch (p->dlt_list[i]) {
|
||||
|
||||
case DLT_EN10MB:
|
||||
case DLT_RAW:
|
||||
/*
|
||||
* Don't offer this one.
|
||||
* Not 802.11. Don't offer this one.
|
||||
*/
|
||||
continue;
|
||||
|
||||
@ -3127,10 +3152,17 @@ remove_802_11(pcap_t *p)
|
||||
switch (p->dlt_list[i]) {
|
||||
|
||||
case DLT_IEEE802_11:
|
||||
#ifdef DLT_PRISM_HEADER
|
||||
case DLT_PRISM_HEADER:
|
||||
#endif
|
||||
#ifdef DLT_AIRONET_HEADER
|
||||
case DLT_AIRONET_HEADER:
|
||||
#endif
|
||||
case DLT_IEEE802_11_RADIO:
|
||||
case DLT_IEEE802_11_RADIO_AVS:
|
||||
#ifdef DLT_PPI
|
||||
case DLT_PPI:
|
||||
#endif
|
||||
/*
|
||||
* 802.11. Don't offer this one.
|
||||
*/
|
||||
@ -3222,10 +3254,10 @@ pcap_setfilter_bpf(pcap_t *p, struct bpf_program *fp)
|
||||
* Set direction flag: Which packets do we accept on a forwarding
|
||||
* single device? IN, OUT or both?
|
||||
*/
|
||||
#if defined(BIOCSDIRECTION)
|
||||
static int
|
||||
pcap_setdirection_bpf(pcap_t *p, pcap_direction_t d)
|
||||
{
|
||||
#if defined(BIOCSDIRECTION)
|
||||
u_int direction;
|
||||
|
||||
direction = (d == PCAP_D_IN) ? BPF_D_IN :
|
||||
@ -3238,7 +3270,11 @@ pcap_setdirection_bpf(pcap_t *p, pcap_direction_t d)
|
||||
return (-1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
#elif defined(BIOCSSEESENT)
|
||||
static int
|
||||
pcap_setdirection_bpf(pcap_t *p, pcap_direction_t d)
|
||||
{
|
||||
u_int seesent;
|
||||
|
||||
/*
|
||||
@ -3258,25 +3294,35 @@ pcap_setdirection_bpf(pcap_t *p, pcap_direction_t d)
|
||||
return (-1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
#else
|
||||
static int
|
||||
pcap_setdirection_bpf(pcap_t *p, pcap_direction_t d _U_)
|
||||
{
|
||||
(void) pcap_snprintf(p->errbuf, sizeof(p->errbuf),
|
||||
"This system doesn't support BIOCSSEESENT, so the direction can't be set");
|
||||
return (-1);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BIOCSDLT
|
||||
static int
|
||||
pcap_set_datalink_bpf(pcap_t *p, int dlt)
|
||||
{
|
||||
#ifdef BIOCSDLT
|
||||
if (ioctl(p->fd, BIOCSDLT, &dlt) == -1) {
|
||||
pcap_fmt_errmsg_for_errno(p->errbuf, sizeof(p->errbuf),
|
||||
errno, "Cannot set DLT %d", dlt);
|
||||
return (-1);
|
||||
}
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
#else
|
||||
static int
|
||||
pcap_set_datalink_bpf(pcap_t *p _U_, int dlt _U_)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Platform-specific information.
|
||||
|
@ -74,13 +74,14 @@ bt_findalldevs(pcap_if_list_t *devlistp, char *err_str)
|
||||
{
|
||||
struct hci_dev_list_req *dev_list;
|
||||
struct hci_dev_req *dev_req;
|
||||
int i, sock;
|
||||
int sock;
|
||||
unsigned i;
|
||||
int ret = 0;
|
||||
|
||||
sock = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
|
||||
if (sock < 0)
|
||||
{
|
||||
/* if bluetooth is not supported this this is not fatal*/
|
||||
/* if bluetooth is not supported this is not fatal*/
|
||||
if (errno == EAFNOSUPPORT)
|
||||
return 0;
|
||||
pcap_fmt_errmsg_for_errno(err_str, PCAP_ERRBUF_SIZE,
|
||||
@ -109,10 +110,10 @@ bt_findalldevs(pcap_if_list_t *devlistp, char *err_str)
|
||||
|
||||
dev_req = dev_list->dev_req;
|
||||
for (i = 0; i < dev_list->dev_num; i++, dev_req++) {
|
||||
char dev_name[20], dev_descr[30];
|
||||
char dev_name[20], dev_descr[40];
|
||||
|
||||
pcap_snprintf(dev_name, 20, BT_IFACE"%d", dev_req->dev_id);
|
||||
pcap_snprintf(dev_descr, 30, "Bluetooth adapter number %d", i);
|
||||
pcap_snprintf(dev_name, sizeof(dev_name), BT_IFACE"%u", dev_req->dev_id);
|
||||
pcap_snprintf(dev_descr, sizeof(dev_descr), "Bluetooth adapter number %u", i);
|
||||
|
||||
/*
|
||||
* Bluetooth is a wireless technology.
|
||||
@ -379,8 +380,8 @@ bt_read_linux(pcap_t *handle, int max_packets _U_, pcap_handler callback, u_char
|
||||
static int
|
||||
bt_inject_linux(pcap_t *handle, const void *buf _U_, size_t size _U_)
|
||||
{
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "inject not supported on "
|
||||
"bluetooth devices");
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Packet injection is not supported on Bluetooth devices");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
|
@ -149,7 +149,8 @@ bt_monitor_read(pcap_t *handle, int max_packets _U_, pcap_handler callback, u_ch
|
||||
static int
|
||||
bt_monitor_inject(pcap_t *handle, const void *buf _U_, size_t size _U_)
|
||||
{
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "inject not supported yet");
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Packet injection is not supported yet on Bluetooth monitor devices");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -514,11 +514,20 @@
|
||||
#define LINKTYPE_RAIF1 198
|
||||
|
||||
/*
|
||||
* IPMB packet for IPMI, beginning with the I2C slave address, followed
|
||||
* by the netFn and LUN, etc.. Requested by Chanthy Toeung
|
||||
* <chanthy.toeung@ca.kontron.com>.
|
||||
* IPMB packet for IPMI, beginning with a 2-byte header, followed by
|
||||
* the I2C slave address, followed by the netFn and LUN, etc..
|
||||
* Requested by Chanthy Toeung <chanthy.toeung@ca.kontron.com>.
|
||||
*
|
||||
* XXX - its DLT_ value used to be called DLT_IPMB, back when we got the
|
||||
* impression from the email thread requesting it that the packet
|
||||
* had no extra 2-byte header. We've renamed it; if anybody used
|
||||
* DLT_IPMB and assumed no 2-byte header, this will cause the compile
|
||||
* to fail, at which point we'll have to figure out what to do about
|
||||
* the two header types using the same DLT_/LINKTYPE_ value. If that
|
||||
* doesn't happen, we'll assume nobody used it and that the redefinition
|
||||
* is safe.
|
||||
*/
|
||||
#define LINKTYPE_IPMB 199
|
||||
#define LINKTYPE_IPMB_KONTRON 199
|
||||
|
||||
/*
|
||||
* Juniper-private data link type, as per request from
|
||||
@ -549,15 +558,35 @@
|
||||
*/
|
||||
#define LINKTYPE_LAPD 203
|
||||
|
||||
|
||||
/*
|
||||
* Variants of various link-layer headers, with a one-byte direction
|
||||
* pseudo-header prepended - zero means "received by this host",
|
||||
* non-zero (any non-zero value) means "sent by this host" - as per
|
||||
* Will Barker <w.barker@zen.co.uk>.
|
||||
* PPP, with a one-byte direction pseudo-header prepended - zero means
|
||||
* "received by this host", non-zero (any non-zero value) means "sent by
|
||||
* this host" - as per Will Barker <w.barker@zen.co.uk>.
|
||||
*/
|
||||
#define LINKTYPE_PPP_WITH_DIR 204 /* Don't confuse with LINKTYPE_PPP_PPPD */
|
||||
|
||||
/*
|
||||
* Cisco HDLC, with a one-byte direction pseudo-header prepended - zero
|
||||
* means "received by this host", non-zero (any non-zero value) means
|
||||
* "sent by this host" - as per Will Barker <w.barker@zen.co.uk>.
|
||||
*/
|
||||
#define LINKTYPE_PPP_WITH_DIR 204 /* PPP */
|
||||
#define LINKTYPE_C_HDLC_WITH_DIR 205 /* Cisco HDLC */
|
||||
|
||||
/*
|
||||
* Frame Relay, with a one-byte direction pseudo-header prepended - zero
|
||||
* means "received by this host" (DCE -> DTE), non-zero (any non-zero
|
||||
* value) means "sent by this host" (DTE -> DCE) - as per Will Barker
|
||||
* <w.barker@zen.co.uk>.
|
||||
*/
|
||||
#define LINKTYPE_FRELAY_WITH_DIR 206 /* Frame Relay */
|
||||
|
||||
/*
|
||||
* LAPB, with a one-byte direction pseudo-header prepended - zero means
|
||||
* "received by this host" (DCE -> DTE), non-zero (any non-zero value)
|
||||
* means "sent by this host" (DTE -> DCE)- as per Will Barker
|
||||
* <w.barker@zen.co.uk>.
|
||||
*/
|
||||
#define LINKTYPE_LAPB_WITH_DIR 207 /* LAPB */
|
||||
|
||||
/*
|
||||
@ -1081,7 +1110,21 @@
|
||||
*/
|
||||
#define LINKTYPE_DISPLAYPORT_AUX 275
|
||||
|
||||
#define LINKTYPE_MATCHING_MAX 275 /* highest value in the "matching" range */
|
||||
/*
|
||||
* Linux cooked sockets v2.
|
||||
*/
|
||||
#define LINKTYPE_LINUX_SLL2 276
|
||||
|
||||
#define LINKTYPE_MATCHING_MAX 276 /* highest value in the "matching" range */
|
||||
|
||||
/*
|
||||
* The DLT_ and LINKTYPE_ values in the "matching" range should be the
|
||||
* same, so DLT_MATCHING_MAX and LINKTYPE_MATCHING_MAX should be the
|
||||
* same.
|
||||
*/
|
||||
#if LINKTYPE_MATCHING_MAX != DLT_MATCHING_MAX
|
||||
#error The LINKTYPE_ matching range does not match the DLT_ matching range
|
||||
#endif
|
||||
|
||||
static struct linktype_map {
|
||||
int dlt;
|
||||
@ -1231,18 +1274,30 @@ linktype_to_dlt(int linktype)
|
||||
/*
|
||||
* Return the maximum snapshot length for a given DLT_ value.
|
||||
*
|
||||
* For most link-layer types, we use MAXIMUM_SNAPLEN, but for DLT_DBUS,
|
||||
* the maximum is 134217728, as per
|
||||
* For most link-layer types, we use MAXIMUM_SNAPLEN.
|
||||
*
|
||||
* For DLT_DBUS, the maximum is 128MiB, as per
|
||||
*
|
||||
* https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-messages
|
||||
*
|
||||
* For DLT_USBPCAP, the maximum is 1MiB, as per
|
||||
*
|
||||
* https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=15985
|
||||
*/
|
||||
u_int
|
||||
max_snaplen_for_dlt(int dlt)
|
||||
{
|
||||
if (dlt == DLT_DBUS)
|
||||
return 134217728;
|
||||
else
|
||||
switch (dlt) {
|
||||
|
||||
case DLT_DBUS:
|
||||
return 128*1024*1024;
|
||||
|
||||
case DLT_USBPCAP:
|
||||
return 1024*1024;
|
||||
|
||||
default:
|
||||
return MAXIMUM_SNAPLEN;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -35,9 +35,13 @@
|
||||
* machine (if the file was written in little-end order).
|
||||
*/
|
||||
#define SWAPLONG(y) \
|
||||
((((y)&0xff)<<24) | (((y)&0xff00)<<8) | (((y)&0xff0000)>>8) | (((y)>>24)&0xff))
|
||||
(((((u_int)(y))&0xff)<<24) | \
|
||||
((((u_int)(y))&0xff00)<<8) | \
|
||||
((((u_int)(y))&0xff0000)>>8) | \
|
||||
((((u_int)(y))>>24)&0xff))
|
||||
#define SWAPSHORT(y) \
|
||||
( (((y)&0xff)<<8) | ((u_short)((y)&0xff00)>>8) )
|
||||
((u_short)(((((u_int)(y))&0xff)<<8) | \
|
||||
((((u_int)(y))&0xff00)>>8)))
|
||||
|
||||
extern int dlt_to_linktype(int dlt);
|
||||
|
||||
|
71
pcap-dag.c
71
pcap-dag.c
@ -1,18 +1,10 @@
|
||||
/*
|
||||
* pcap-dag.c: Packet capture interface for Emulex EndaceDAG cards.
|
||||
*
|
||||
* The functionality of this code attempts to mimic that of pcap-linux as much
|
||||
* as possible. This code is compiled in several different ways depending on
|
||||
* whether DAG_ONLY and HAVE_DAG_API are defined. If HAVE_DAG_API is not
|
||||
* defined it should not get compiled in, otherwise if DAG_ONLY is defined then
|
||||
* the 'dag_' function calls are renamed to 'pcap_' equivalents. If DAG_ONLY
|
||||
* is not defined then nothing is altered - the dag_ functions will be
|
||||
* called as required from their pcap-linux/bpf equivalents.
|
||||
* pcap-dag.c: Packet capture interface for Endace DAG cards.
|
||||
*
|
||||
* Authors: Richard Littin, Sean Irvine ({richard,sean}@reeltwo.com)
|
||||
* Modifications: Jesper Peterson
|
||||
* Koryn Grant
|
||||
* Stephen Donnelly <stephen.donnelly@emulex.com>
|
||||
* Stephen Donnelly <stephen.donnelly@endace.com>
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
@ -258,12 +250,18 @@ dag_platform_cleanup(pcap_t *p)
|
||||
|
||||
if(pd->dag_ref != NULL) {
|
||||
dag_config_dispose(pd->dag_ref);
|
||||
/*
|
||||
* Note: we don't need to call close(p->fd) or
|
||||
* dag_close(p->fd), as dag_config_dispose(pd->dag_ref)
|
||||
* does this.
|
||||
*
|
||||
* Set p->fd to -1 to make sure that's not done.
|
||||
*/
|
||||
p->fd = -1;
|
||||
pd->dag_ref = NULL;
|
||||
}
|
||||
delete_pcap_dag(p);
|
||||
pcap_cleanup_live_common(p);
|
||||
/* Note: don't need to call close(p->fd) or dag_close(p->fd) as dag_config_dispose(pd->dag_ref) does this. */
|
||||
}
|
||||
|
||||
static void
|
||||
@ -722,7 +720,7 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
static int
|
||||
dag_inject(pcap_t *p, const void *buf _U_, size_t size _U_)
|
||||
{
|
||||
strlcpy(p->errbuf, "Sending packets isn't supported on DAG cards",
|
||||
pcap_strlcpy(p->errbuf, "Sending packets isn't supported on DAG cards",
|
||||
PCAP_ERRBUF_SIZE);
|
||||
return (-1);
|
||||
}
|
||||
@ -746,18 +744,20 @@ static int dag_activate(pcap_t* p)
|
||||
daginf_t* daginf;
|
||||
char * newDev = NULL;
|
||||
char * device = p->opt.device;
|
||||
int ret;
|
||||
dag_size_t mindata;
|
||||
struct timeval maxwait;
|
||||
struct timeval poll;
|
||||
|
||||
if (device == NULL) {
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "device is NULL");
|
||||
return -1;
|
||||
return PCAP_ERROR;
|
||||
}
|
||||
|
||||
/* Initialize some components of the pcap structure. */
|
||||
newDev = (char *)malloc(strlen(device) + 16);
|
||||
if (newDev == NULL) {
|
||||
ret = PCAP_ERROR;
|
||||
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
errno, "Can't allocate string for device name");
|
||||
goto fail;
|
||||
@ -765,6 +765,13 @@ static int dag_activate(pcap_t* p)
|
||||
|
||||
/* Parse input name to get dag device and stream number if provided */
|
||||
if (dag_parse_name(device, newDev, strlen(device) + 16, &pd->dag_stream) < 0) {
|
||||
/*
|
||||
* XXX - it'd be nice if this indicated what was wrong
|
||||
* with the name. Does this reliably set errno?
|
||||
* Should this return PCAP_ERROR_NO_SUCH_DEVICE in some
|
||||
* cases?
|
||||
*/
|
||||
ret = PCAP_ERROR;
|
||||
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
errno, "dag_parse_name");
|
||||
goto fail;
|
||||
@ -772,25 +779,40 @@ static int dag_activate(pcap_t* p)
|
||||
device = newDev;
|
||||
|
||||
if (pd->dag_stream%2) {
|
||||
ret = PCAP_ERROR;
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "dag_parse_name: tx (even numbered) streams not supported for capture");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* setup device parameters */
|
||||
if((pd->dag_ref = dag_config_init((char *)device)) == NULL) {
|
||||
/*
|
||||
* XXX - does this reliably set errno?
|
||||
*/
|
||||
if (errno == ENOENT)
|
||||
ret = PCAP_ERROR_NO_SUCH_DEVICE;
|
||||
else if (errno == EPERM || errno == EACCES)
|
||||
ret = PCAP_ERROR_PERM_DENIED;
|
||||
else
|
||||
ret = PCAP_ERROR;
|
||||
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
errno, "dag_config_init %s", device);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if((p->fd = dag_config_get_card_fd(pd->dag_ref)) < 0) {
|
||||
/*
|
||||
* XXX - does this reliably set errno?
|
||||
*/
|
||||
ret = PCAP_ERROR;
|
||||
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
errno, "dag_config_get_card_fd %s", device);
|
||||
goto fail;
|
||||
goto failclose;
|
||||
}
|
||||
|
||||
/* Open requested stream. Can fail if already locked or on error */
|
||||
if (dag_attach_stream64(p->fd, pd->dag_stream, 0, 0) < 0) {
|
||||
ret = PCAP_ERROR;
|
||||
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
errno, "dag_attach_stream");
|
||||
goto failclose;
|
||||
@ -809,6 +831,7 @@ static int dag_activate(pcap_t* p)
|
||||
*/
|
||||
if (dag_get_stream_poll64(p->fd, pd->dag_stream,
|
||||
&mindata, &maxwait, &poll) < 0) {
|
||||
ret = PCAP_ERROR;
|
||||
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
errno, "dag_get_stream_poll");
|
||||
goto faildetach;
|
||||
@ -853,6 +876,7 @@ static int dag_activate(pcap_t* p)
|
||||
|
||||
if (dag_set_stream_poll64(p->fd, pd->dag_stream,
|
||||
mindata, &maxwait, &poll) < 0) {
|
||||
ret = PCAP_ERROR;
|
||||
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
errno, "dag_set_stream_poll");
|
||||
goto faildetach;
|
||||
@ -875,6 +899,7 @@ static int dag_activate(pcap_t* p)
|
||||
#endif
|
||||
|
||||
if(dag_start_stream(p->fd, pd->dag_stream) < 0) {
|
||||
ret = PCAP_ERROR;
|
||||
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
errno, "dag_start_stream %s", device);
|
||||
goto faildetach;
|
||||
@ -910,6 +935,7 @@ static int dag_activate(pcap_t* p)
|
||||
if ((n = atoi(s)) == 0 || n == 16 || n == 32) {
|
||||
pd->dag_fcs_bits = n;
|
||||
} else {
|
||||
ret = PCAP_ERROR;
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"pcap_activate %s: bad ERF_FCS_BITS value (%d) in environment", device, n);
|
||||
goto failstop;
|
||||
@ -932,12 +958,15 @@ static int dag_activate(pcap_t* p)
|
||||
pd->dag_timeout = p->opt.timeout;
|
||||
|
||||
p->linktype = -1;
|
||||
if (dag_get_datalink(p) < 0)
|
||||
if (dag_get_datalink(p) < 0) {
|
||||
ret = PCAP_ERROR;
|
||||
goto failstop;
|
||||
}
|
||||
|
||||
p->bufsize = 0;
|
||||
|
||||
if (new_pcap_dag(p) < 0) {
|
||||
ret = PCAP_ERROR;
|
||||
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
errno, "new_pcap_dag %s", device);
|
||||
goto failstop;
|
||||
@ -977,6 +1006,14 @@ static int dag_activate(pcap_t* p)
|
||||
|
||||
failclose:
|
||||
dag_config_dispose(pd->dag_ref);
|
||||
/*
|
||||
* Note: we don't need to call close(p->fd) or dag_close(p->fd),
|
||||
* as dag_config_dispose(pd->dag_ref) does this.
|
||||
*
|
||||
* Set p->fd to -1 to make sure that's not done.
|
||||
*/
|
||||
p->fd = -1;
|
||||
pd->dag_ref = NULL;
|
||||
delete_pcap_dag(p);
|
||||
|
||||
fail:
|
||||
@ -985,7 +1022,7 @@ static int dag_activate(pcap_t* p)
|
||||
free((char *)newDev);
|
||||
}
|
||||
|
||||
return PCAP_ERROR;
|
||||
return ret;
|
||||
}
|
||||
|
||||
pcap_t *dag_create(const char *device, char *ebuf, int *is_ours)
|
||||
@ -1137,7 +1174,7 @@ dag_findalldevs(pcap_if_list_t *devlistp, char *errbuf)
|
||||
}
|
||||
rxstreams = dag_rx_get_stream_count(dagfd);
|
||||
for(stream=0;stream<DAG_STREAM_MAX;stream+=2) {
|
||||
if (0 == dag_attach_stream(dagfd, stream, 0, 0)) {
|
||||
if (0 == dag_attach_stream64(dagfd, stream, 0, 0)) {
|
||||
dag_detach_stream(dagfd, stream);
|
||||
|
||||
pcap_snprintf(name, 10, "dag%d:%d", c, stream);
|
||||
|
14
pcap-dlpi.c
14
pcap-dlpi.c
@ -307,7 +307,7 @@ pcap_inject_dlpi(pcap_t *p, const void *buf, size_t size)
|
||||
* it should check "p->linktype" and reject the send request if
|
||||
* it's anything other than DLT_EN10MB.
|
||||
*/
|
||||
strlcpy(p->errbuf, "send: Not supported on this version of this OS",
|
||||
pcap_strlcpy(p->errbuf, "send: Not supported on this version of this OS",
|
||||
PCAP_ERRBUF_SIZE);
|
||||
ret = -1;
|
||||
#endif /* raw mode */
|
||||
@ -363,9 +363,9 @@ open_dlpi_device(const char *name, u_int *ppa, char *errbuf)
|
||||
*/
|
||||
cp = strrchr(name, '/');
|
||||
if (cp == NULL)
|
||||
strlcpy(dname, name, sizeof(dname));
|
||||
pcap_strlcpy(dname, name, sizeof(dname));
|
||||
else
|
||||
strlcpy(dname, cp + 1, sizeof(dname));
|
||||
pcap_strlcpy(dname, cp + 1, sizeof(dname));
|
||||
|
||||
/*
|
||||
* Split the device name into a device type name and a unit number;
|
||||
@ -415,7 +415,7 @@ open_dlpi_device(const char *name, u_int *ppa, char *errbuf)
|
||||
* device name.
|
||||
*/
|
||||
if (*name == '/')
|
||||
strlcpy(dname, name, sizeof(dname));
|
||||
pcap_strlcpy(dname, name, sizeof(dname));
|
||||
else
|
||||
pcap_snprintf(dname, sizeof(dname), "%s/%s", PCAP_DEV_PREFIX,
|
||||
name);
|
||||
@ -432,7 +432,7 @@ open_dlpi_device(const char *name, u_int *ppa, char *errbuf)
|
||||
* Make a copy of the device pathname, and then remove the unit
|
||||
* number from the device pathname.
|
||||
*/
|
||||
strlcpy(dname2, dname, sizeof(dname));
|
||||
pcap_strlcpy(dname2, dname, sizeof(dname));
|
||||
*cp = '\0';
|
||||
|
||||
/* Try device without unit number */
|
||||
@ -968,7 +968,7 @@ dl_dohpuxbind(int fd, char *ebuf)
|
||||
*ebuf = '\0';
|
||||
hpsap++;
|
||||
if (hpsap > 100) {
|
||||
strlcpy(ebuf,
|
||||
pcap_strlcpy(ebuf,
|
||||
"All SAPs from 22 through 100 are in use",
|
||||
PCAP_ERRBUF_SIZE);
|
||||
return (-1);
|
||||
@ -1547,7 +1547,7 @@ get_release(char *buf, size_t bufsize, bpf_u_int32 *majorp,
|
||||
*minorp = 0;
|
||||
*microp = 0;
|
||||
if (sysinfo(SI_RELEASE, buf, bufsize) < 0) {
|
||||
strlcpy(buf, "?", bufsize);
|
||||
pcap_strlcpy(buf, "?", bufsize);
|
||||
return;
|
||||
}
|
||||
cp = buf;
|
||||
|
@ -413,14 +413,14 @@ int pcap_stats_ex (pcap_t *p, struct pcap_stat_ex *se)
|
||||
|
||||
if (!dev || !dev->get_stats)
|
||||
{
|
||||
strlcpy (p->errbuf, "detailed device statistics not available",
|
||||
pcap_strlcpy (p->errbuf, "detailed device statistics not available",
|
||||
PCAP_ERRBUF_SIZE);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (!strnicmp(dev->name,"pkt",3))
|
||||
{
|
||||
strlcpy (p->errbuf, "pktdrvr doesn't have detailed statistics",
|
||||
pcap_strlcpy (p->errbuf, "pktdrvr doesn't have detailed statistics",
|
||||
PCAP_ERRBUF_SIZE);
|
||||
return (-1);
|
||||
}
|
||||
|
@ -18,7 +18,7 @@
|
||||
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
.\"
|
||||
.TH PCAP-FILTER @MAN_MISC_INFO@ "3 August 2015"
|
||||
.TH PCAP-FILTER @MAN_MISC_INFO@ "5 November 2017"
|
||||
.SH NAME
|
||||
pcap-filter \- packet filter syntax
|
||||
.br
|
||||
@ -29,11 +29,11 @@ pcap-filter \- packet filter syntax
|
||||
is used to compile a string into a filter program.
|
||||
The resulting filter program can then be applied to
|
||||
some stream of packets to determine which packets will be supplied to
|
||||
.BR pcap_loop() ,
|
||||
.BR pcap_dispatch() ,
|
||||
.BR pcap_next() ,
|
||||
.BR pcap_loop(3PCAP) ,
|
||||
.BR pcap_dispatch(3PCAP) ,
|
||||
.BR pcap_next(3PCAP) ,
|
||||
or
|
||||
.BR pcap_next_ex() .
|
||||
.BR pcap_next_ex(3PCAP) .
|
||||
.LP
|
||||
The \fIfilter expression\fP consists of one or more
|
||||
.IR primitives .
|
||||
@ -86,12 +86,6 @@ The
|
||||
and
|
||||
.B addr4
|
||||
qualifiers are only valid for IEEE 802.11 Wireless LAN link layers.
|
||||
For some link layers, such as SLIP and the ``cooked'' Linux capture mode
|
||||
used for the ``any'' device and for some other device types, the
|
||||
.B inbound
|
||||
and
|
||||
.B outbound
|
||||
qualifiers can be used to specify a desired direction.
|
||||
.IP \fIproto\fP
|
||||
.I proto
|
||||
qualifiers restrict the match to a particular protocol.
|
||||
@ -466,8 +460,6 @@ Token Ring packets (no check is done for LLC frames);
|
||||
FDDI packets (no check is done for LLC frames);
|
||||
.IP
|
||||
LLC-encapsulated ATM packets, for SunATM on Solaris.
|
||||
.IP
|
||||
|
||||
.IP "\fBllc\fP \Fitype\fR"
|
||||
True if the packet has an 802.2 LLC header and has the specified
|
||||
.IR type .
|
||||
@ -514,6 +506,16 @@ Exchange Identification (XID) U PDUs
|
||||
\fBfrmr\fR
|
||||
Frame Reject (FRMR) U PDUs
|
||||
.RE
|
||||
.IP \fBinbound\fP
|
||||
Packet was received by the host performing the capture rather than being
|
||||
sent by that host. This is only supported for certain link-layer types,
|
||||
such as SLIP and the ``cooked'' Linux capture mode
|
||||
used for the ``any'' device and for some other device types.
|
||||
.IP \fBoutbound\fP
|
||||
Packet was sent by the host performing the capture rather than being
|
||||
received by that host. This is only supported for certain link-layer types,
|
||||
such as SLIP and the ``cooked'' Linux capture mode
|
||||
used for the ``any'' device and for some other device types.
|
||||
.IP "\fBifname \fIinterface\fR"
|
||||
True if the packet was logged as coming from the specified interface (applies
|
||||
only to packets logged by OpenBSD's or FreeBSD's
|
||||
@ -567,7 +569,7 @@ are:
|
||||
and
|
||||
.B block
|
||||
and, with later versions of
|
||||
.BR pf (4)),
|
||||
.BR pf (4),
|
||||
.BR nat ,
|
||||
.BR rdr ,
|
||||
.B binat
|
||||
|
36
pcap-int.h
36
pcap-int.h
@ -86,7 +86,12 @@ extern "C" {
|
||||
* 2) small enough not to cause attempts to allocate huge amounts of
|
||||
* memory; some applications might use the snapshot length in a
|
||||
* savefile header to control the size of the buffer they allocate,
|
||||
* so a size of, say, 2^31-1 might not work well.
|
||||
* so a size of, say, 2^31-1 might not work well. (libpcap uses it
|
||||
* as a hint, but doesn't start out allocating a buffer bigger than
|
||||
* 2 KiB, and grows the buffer as necessary, but not beyond the
|
||||
* per-linktype maximum snapshot length. Other code might naively
|
||||
* use it; we want to avoid writing a too-large snapshot length,
|
||||
* in order not to cause that code problems.)
|
||||
*
|
||||
* We don't enforce this in pcap_set_snaplen(), but we use it internally.
|
||||
*/
|
||||
@ -472,13 +477,38 @@ int add_addr_to_if(pcap_if_list_t *, const char *, bpf_u_int32,
|
||||
* "pcap_open_offline_common()" allocates and fills in a pcap_t, for use
|
||||
* by pcap_open_offline routines.
|
||||
*
|
||||
* "pcap_adjust_snapshot()" adjusts the snapshot to be non-zero and
|
||||
* fit within an int.
|
||||
*
|
||||
* "sf_cleanup()" closes the file handle associated with a pcap_t, if
|
||||
* appropriate, and frees all data common to all modules for handling
|
||||
* savefile types.
|
||||
*/
|
||||
pcap_t *pcap_open_offline_common(char *ebuf, size_t size);
|
||||
bpf_u_int32 pcap_adjust_snapshot(bpf_u_int32 linktype, bpf_u_int32 snaplen);
|
||||
void sf_cleanup(pcap_t *p);
|
||||
|
||||
/*
|
||||
* Internal interfaces for doing user-mode filtering of packets and
|
||||
* validating filter programs.
|
||||
*/
|
||||
/*
|
||||
* Auxiliary data, for use when interpreting a filter intended for the
|
||||
* Linux kernel when the kernel rejects the filter (requiring us to
|
||||
* run it in userland). It contains VLAN tag information.
|
||||
*/
|
||||
struct bpf_aux_data {
|
||||
u_short vlan_tag_present;
|
||||
u_short vlan_tag;
|
||||
};
|
||||
|
||||
/*
|
||||
* Filtering routine that takes the auxiliary data as an additional
|
||||
* argument.
|
||||
*/
|
||||
u_int bpf_filter_with_aux_data(const struct bpf_insn *,
|
||||
const u_char *, u_int, u_int, const struct bpf_aux_data *);
|
||||
|
||||
/*
|
||||
* Internal interfaces for both "pcap_create()" and routines that
|
||||
* open savefiles.
|
||||
@ -488,10 +518,6 @@ void sf_cleanup(pcap_t *p);
|
||||
*/
|
||||
void pcap_oneshot(u_char *, const struct pcap_pkthdr *, const u_char *);
|
||||
|
||||
#ifdef _WIN32
|
||||
void pcap_win32_err_to_str(DWORD, char *);
|
||||
#endif
|
||||
|
||||
int install_bpf_program(pcap_t *, struct bpf_program *);
|
||||
|
||||
int pcap_strcasecmp(const char *, const char *);
|
||||
|
@ -80,7 +80,7 @@ list_interfaces(const char *linkname, void *arg)
|
||||
lwp->lw_err = ENOMEM;
|
||||
return (B_TRUE);
|
||||
}
|
||||
(void) strlcpy(entry->linkname, linkname, DLPI_LINKNAME_MAX);
|
||||
(void) pcap_strlcpy(entry->linkname, linkname, DLPI_LINKNAME_MAX);
|
||||
|
||||
if (lwp->lw_list == NULL) {
|
||||
lwp->lw_list = entry;
|
||||
|
@ -43,6 +43,6 @@ The names for those values begin with
|
||||
.BR LINKTYPE_ .
|
||||
.PP
|
||||
The link-layer header types supported by libpcap are described at
|
||||
http://www.tcpdump.org/linktypes.html.
|
||||
https://www.tcpdump.org/linktypes.html.
|
||||
.SH SEE ALSO
|
||||
pcap_datalink(3PCAP)
|
||||
pcap(3PCAP)
|
||||
|
809
pcap-linux.c
809
pcap-linux.c
File diff suppressed because it is too large
Load Diff
@ -301,7 +301,8 @@ netfilter_stats_linux(pcap_t *handle, struct pcap_stat *stats)
|
||||
static int
|
||||
netfilter_inject_linux(pcap_t *handle, const void *buf _U_, size_t size _U_)
|
||||
{
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "inject not supported on netfilter devices");
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Packet injection is not supported on netfilter devices");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
@ -315,6 +316,7 @@ static int
|
||||
netfilter_send_config_msg(const pcap_t *handle, uint16_t msg_type, int ack, u_int8_t family, u_int16_t res_id, const struct my_nfattr *mynfa)
|
||||
{
|
||||
char buf[1024] __attribute__ ((aligned));
|
||||
memset(buf, 0, sizeof(buf));
|
||||
|
||||
struct nlmsghdr *nlh = (struct nlmsghdr *) buf;
|
||||
struct nfgenmsg *nfg = (struct nfgenmsg *) (buf + sizeof(struct nlmsghdr));
|
||||
|
@ -67,7 +67,7 @@ pcap_netmap_stats(pcap_t *p, struct pcap_stat *ps)
|
||||
{
|
||||
struct pcap_netmap *pn = p->priv;
|
||||
|
||||
ps->ps_recv = pn->rx_pkts;
|
||||
ps->ps_recv = (u_int)pn->rx_pkts;
|
||||
ps->ps_drop = 0;
|
||||
ps->ps_ifdrop = 0;
|
||||
return 0;
|
||||
|
85
pcap-new.c
85
pcap-new.c
@ -35,6 +35,8 @@
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "ftmacros.h"
|
||||
|
||||
/*
|
||||
* sockutils.h may include <crtdbg.h> on Windows, and pcap-int.h will
|
||||
* include portability.h, and portability.h, on Windows, expects that
|
||||
@ -54,11 +56,14 @@
|
||||
|
||||
/* String identifier to be used in the pcap_findalldevs_ex() */
|
||||
#define PCAP_TEXT_SOURCE_FILE "File"
|
||||
#define PCAP_TEXT_SOURCE_FILE_LEN (sizeof PCAP_TEXT_SOURCE_FILE - 1)
|
||||
/* String identifier to be used in the pcap_findalldevs_ex() */
|
||||
#define PCAP_TEXT_SOURCE_ADAPTER "Network adapter"
|
||||
#define PCAP_TEXT_SOURCE_ADAPTER_LEN (sizeof "Network adapter" - 1)
|
||||
|
||||
/* String identifier to be used in the pcap_findalldevs_ex() */
|
||||
#define PCAP_TEXT_SOURCE_ON_LOCAL_HOST "on local host"
|
||||
#define PCAP_TEXT_SOURCE_ON_LOCAL_HOST_LEN (sizeof PCAP_TEXT_SOURCE_ON_LOCAL_HOST + 1)
|
||||
|
||||
/****************************************************
|
||||
* *
|
||||
@ -66,10 +71,12 @@
|
||||
* *
|
||||
****************************************************/
|
||||
|
||||
int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **alldevs, char *errbuf)
|
||||
int pcap_findalldevs_ex(const char *source, struct pcap_rmtauth *auth, pcap_if_t **alldevs, char *errbuf)
|
||||
{
|
||||
int type;
|
||||
char name[PCAP_BUF_SIZE], path[PCAP_BUF_SIZE], filename[PCAP_BUF_SIZE];
|
||||
size_t pathlen;
|
||||
size_t stringlen;
|
||||
pcap_t *fp;
|
||||
char tmpstring[PCAP_BUF_SIZE + 1]; /* Needed to convert names and descriptions from 'old' syntax to the 'new' one */
|
||||
pcap_if_t *lastdev; /* Last device in the pcap_if_t list */
|
||||
@ -113,7 +120,7 @@ int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **all
|
||||
if (*alldevs == NULL)
|
||||
{
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"No interfaces found! Make sure libpcap/WinPcap is properly installed"
|
||||
"No interfaces found! Make sure libpcap/Npcap is properly installed"
|
||||
" on the local machine.");
|
||||
return -1;
|
||||
}
|
||||
@ -123,6 +130,8 @@ int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **all
|
||||
dev = *alldevs;
|
||||
while (dev)
|
||||
{
|
||||
char *localdesc, *desc;
|
||||
|
||||
/* Create the new device identifier */
|
||||
if (pcap_createsrcstr(tmpstring, PCAP_SRC_IFLOCAL, NULL, NULL, dev->name, errbuf) == -1)
|
||||
return -1;
|
||||
@ -141,20 +150,16 @@ int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **all
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Create the new device description */
|
||||
/*
|
||||
* Create the description.
|
||||
*/
|
||||
if ((dev->description == NULL) || (dev->description[0] == 0))
|
||||
pcap_snprintf(tmpstring, sizeof(tmpstring) - 1, "%s '%s' %s", PCAP_TEXT_SOURCE_ADAPTER,
|
||||
dev->name, PCAP_TEXT_SOURCE_ON_LOCAL_HOST);
|
||||
localdesc = dev->name;
|
||||
else
|
||||
pcap_snprintf(tmpstring, sizeof(tmpstring) - 1, "%s '%s' %s", PCAP_TEXT_SOURCE_ADAPTER,
|
||||
dev->description, PCAP_TEXT_SOURCE_ON_LOCAL_HOST);
|
||||
|
||||
/* Delete the old pointer */
|
||||
free(dev->description);
|
||||
|
||||
/* Make a copy of the description */
|
||||
dev->description = strdup(tmpstring);
|
||||
if (dev->description == NULL)
|
||||
localdesc = dev->description;
|
||||
if (pcap_asprintf(&desc, "%s '%s' %s",
|
||||
PCAP_TEXT_SOURCE_ADAPTER, localdesc,
|
||||
PCAP_TEXT_SOURCE_ON_LOCAL_HOST) == -1)
|
||||
{
|
||||
pcap_fmt_errmsg_for_errno(errbuf,
|
||||
PCAP_ERRBUF_SIZE, errno,
|
||||
@ -163,6 +168,10 @@ int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **all
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Now overwrite the description */
|
||||
free(dev->description);
|
||||
dev->description = desc;
|
||||
|
||||
dev = dev->next;
|
||||
}
|
||||
|
||||
@ -170,7 +179,6 @@ int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **all
|
||||
|
||||
case PCAP_SRC_FILE:
|
||||
{
|
||||
size_t stringlen;
|
||||
#ifdef _WIN32
|
||||
WIN32_FIND_DATA filedata;
|
||||
HANDLE filehandle;
|
||||
@ -202,6 +210,7 @@ int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **all
|
||||
|
||||
/* Save the path for future reference */
|
||||
pcap_snprintf(path, sizeof(path), "%s", name);
|
||||
pathlen = strlen(path);
|
||||
|
||||
#ifdef _WIN32
|
||||
/* To perform directory listing, Win32 must have an 'asterisk' as ending char */
|
||||
@ -236,10 +245,14 @@ int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **all
|
||||
/* Add all files we find to the list. */
|
||||
do
|
||||
{
|
||||
|
||||
#ifdef _WIN32
|
||||
/* Skip the file if the pathname won't fit in the buffer */
|
||||
if (pathlen + strlen(filedata.cFileName) >= sizeof(filename))
|
||||
continue;
|
||||
pcap_snprintf(filename, sizeof(filename), "%s%s", path, filedata.cFileName);
|
||||
#else
|
||||
if (pathlen + strlen(filedata->d_name) >= sizeof(filename))
|
||||
continue;
|
||||
pcap_snprintf(filename, sizeof(filename), "%s%s", path, filedata->d_name);
|
||||
#endif
|
||||
|
||||
@ -287,9 +300,7 @@ int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **all
|
||||
return -1;
|
||||
}
|
||||
|
||||
stringlen = strlen(tmpstring);
|
||||
|
||||
dev->name = (char *)malloc(stringlen + 1);
|
||||
dev->name = strdup(tmpstring);
|
||||
if (dev->name == NULL)
|
||||
{
|
||||
pcap_fmt_errmsg_for_errno(errbuf,
|
||||
@ -299,19 +310,12 @@ int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **all
|
||||
return -1;
|
||||
}
|
||||
|
||||
strlcpy(dev->name, tmpstring, stringlen);
|
||||
|
||||
dev->name[stringlen] = 0;
|
||||
|
||||
/* Create the description */
|
||||
pcap_snprintf(tmpstring, sizeof(tmpstring) - 1, "%s '%s' %s", PCAP_TEXT_SOURCE_FILE,
|
||||
filename, PCAP_TEXT_SOURCE_ON_LOCAL_HOST);
|
||||
|
||||
stringlen = strlen(tmpstring);
|
||||
|
||||
dev->description = (char *)malloc(stringlen + 1);
|
||||
|
||||
if (dev->description == NULL)
|
||||
/*
|
||||
* Create the description.
|
||||
*/
|
||||
if (pcap_asprintf(&dev->description,
|
||||
"%s '%s' %s", PCAP_TEXT_SOURCE_FILE,
|
||||
filename, PCAP_TEXT_SOURCE_ON_LOCAL_HOST) == -1)
|
||||
{
|
||||
pcap_fmt_errmsg_for_errno(errbuf,
|
||||
PCAP_ERRBUF_SIZE, errno,
|
||||
@ -320,9 +324,6 @@ int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **all
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Copy the new device description into the correct memory location */
|
||||
strlcpy(dev->description, tmpstring, stringlen + 1);
|
||||
|
||||
pcap_close(fp);
|
||||
}
|
||||
}
|
||||
@ -345,7 +346,7 @@ int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **all
|
||||
return pcap_findalldevs_ex_remote(source, auth, alldevs, errbuf);
|
||||
|
||||
default:
|
||||
strlcpy(errbuf, "Source type not supported", PCAP_ERRBUF_SIZE);
|
||||
pcap_strlcpy(errbuf, "Source type not supported", PCAP_ERRBUF_SIZE);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@ -357,6 +358,16 @@ pcap_t *pcap_open(const char *source, int snaplen, int flags, int read_timeout,
|
||||
pcap_t *fp;
|
||||
int status;
|
||||
|
||||
/*
|
||||
* A null device name is equivalent to the "any" device -
|
||||
* which might not be supported on this platform, but
|
||||
* this means that you'll get a "not supported" error
|
||||
* rather than, say, a crash when we try to dereference
|
||||
* the null pointer.
|
||||
*/
|
||||
if (source == NULL)
|
||||
source = "any";
|
||||
|
||||
if (strlen(source) > PCAP_BUF_SIZE)
|
||||
{
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "The source string is too long. Cannot handle it correctly.");
|
||||
@ -389,7 +400,7 @@ pcap_t *pcap_open(const char *source, int snaplen, int flags, int read_timeout,
|
||||
return pcap_open_rpcap(source, snaplen, flags, read_timeout, auth, errbuf);
|
||||
|
||||
default:
|
||||
strlcpy(errbuf, "Source type not supported", PCAP_ERRBUF_SIZE);
|
||||
pcap_strlcpy(errbuf, "Source type not supported", PCAP_ERRBUF_SIZE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
238
pcap-npf.c
238
pcap-npf.c
@ -70,7 +70,7 @@ static int pcap_setnonblock_npf(pcap_t *, int);
|
||||
#define SWAPS(_X) ((_X & 0xff) << 8) | (_X >> 8)
|
||||
|
||||
/*
|
||||
* Private data for capturing on WinPcap devices.
|
||||
* Private data for capturing on WinPcap/Npcap devices.
|
||||
*/
|
||||
struct pcap_win {
|
||||
ADAPTER *adapter; /* the packet32 ADAPTER for the device */
|
||||
@ -134,7 +134,7 @@ PacketGetMonitorMode(PCHAR AdapterName _U_)
|
||||
* or NDIS_STATUS_NOT_RECOGNIZED if the OID request isn't
|
||||
* supported by the OS or the driver, but that doesn't seem
|
||||
* to make it to the caller of PacketRequest() in a
|
||||
* reiable fashion.
|
||||
* reliable fashion.
|
||||
*/
|
||||
#define NDIS_STATUS_INVALID_OID 0xc0010017
|
||||
#define NDIS_STATUS_NOT_SUPPORTED 0xc00000bb /* STATUS_NOT_SUPPORTED */
|
||||
@ -166,11 +166,8 @@ oid_get_request(ADAPTER *adapter, bpf_u_int32 oid, void *data, size_t *lenp,
|
||||
oid_data_arg->Oid = oid;
|
||||
oid_data_arg->Length = (ULONG)(*lenp); /* XXX - check for ridiculously large value? */
|
||||
if (!PacketRequest(adapter, FALSE, oid_data_arg)) {
|
||||
char errmsgbuf[PCAP_ERRBUF_SIZE+1];
|
||||
|
||||
pcap_win32_err_to_str(GetLastError(), errmsgbuf);
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Error calling PacketRequest: %s", errmsgbuf);
|
||||
pcap_fmt_errmsg_for_win32_err(errbuf, PCAP_ERRBUF_SIZE,
|
||||
GetLastError(), "Error calling PacketRequest");
|
||||
free(oid_data_arg);
|
||||
return (-1);
|
||||
}
|
||||
@ -193,7 +190,6 @@ pcap_stats_npf(pcap_t *p, struct pcap_stat *ps)
|
||||
{
|
||||
struct pcap_win *pw = p->priv;
|
||||
struct bpf_stat bstats;
|
||||
char errbuf[PCAP_ERRBUF_SIZE+1];
|
||||
|
||||
/*
|
||||
* Try to get statistics.
|
||||
@ -209,9 +205,8 @@ pcap_stats_npf(pcap_t *p, struct pcap_stat *ps)
|
||||
* to us.
|
||||
*/
|
||||
if (!PacketGetStats(pw->adapter, &bstats)) {
|
||||
pcap_win32_err_to_str(GetLastError(), errbuf);
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"PacketGetStats error: %s", errbuf);
|
||||
pcap_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
GetLastError(), "PacketGetStats error");
|
||||
return (-1);
|
||||
}
|
||||
ps->ps_recv = bstats.bs_recv;
|
||||
@ -256,7 +251,6 @@ pcap_stats_ex_npf(pcap_t *p, int *pcap_stat_size)
|
||||
{
|
||||
struct pcap_win *pw = p->priv;
|
||||
struct bpf_stat bstats;
|
||||
char errbuf[PCAP_ERRBUF_SIZE+1];
|
||||
|
||||
*pcap_stat_size = sizeof (p->stat);
|
||||
|
||||
@ -268,9 +262,8 @@ pcap_stats_ex_npf(pcap_t *p, int *pcap_stat_size)
|
||||
* same layout, but let's not cheat.)
|
||||
*/
|
||||
if (!PacketGetStatsEx(pw->adapter, &bstats)) {
|
||||
pcap_win32_err_to_str(GetLastError(), errbuf);
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"PacketGetStatsEx error: %s", errbuf);
|
||||
pcap_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
GetLastError(), "PacketGetStatsEx error");
|
||||
return (NULL);
|
||||
}
|
||||
p->stat.ps_recv = bstats.bs_recv;
|
||||
@ -347,7 +340,6 @@ pcap_oid_set_request_npf(pcap_t *p, bpf_u_int32 oid, const void *data,
|
||||
{
|
||||
struct pcap_win *pw = p->priv;
|
||||
PACKET_OID_DATA *oid_data_arg;
|
||||
char errbuf[PCAP_ERRBUF_SIZE+1];
|
||||
|
||||
/*
|
||||
* Allocate a PACKET_OID_DATA structure to hand to PacketRequest().
|
||||
@ -367,9 +359,8 @@ pcap_oid_set_request_npf(pcap_t *p, bpf_u_int32 oid, const void *data,
|
||||
oid_data_arg->Length = (ULONG)(*lenp); /* XXX - check for ridiculously large value? */
|
||||
memcpy(oid_data_arg->Data, data, *lenp);
|
||||
if (!PacketRequest(pw->adapter, TRUE, oid_data_arg)) {
|
||||
pcap_win32_err_to_str(GetLastError(), errbuf);
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Error calling PacketRequest: %s", errbuf);
|
||||
pcap_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
GetLastError(), "Error calling PacketRequest");
|
||||
free(oid_data_arg);
|
||||
return (PCAP_ERROR);
|
||||
}
|
||||
@ -391,7 +382,6 @@ pcap_sendqueue_transmit_npf(pcap_t *p, pcap_send_queue *queue, int sync)
|
||||
{
|
||||
struct pcap_win *pw = p->priv;
|
||||
u_int res;
|
||||
char errbuf[PCAP_ERRBUF_SIZE+1];
|
||||
|
||||
if (pw->adapter==NULL) {
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
@ -405,9 +395,8 @@ pcap_sendqueue_transmit_npf(pcap_t *p, pcap_send_queue *queue, int sync)
|
||||
(BOOLEAN)sync);
|
||||
|
||||
if(res != queue->len){
|
||||
pcap_win32_err_to_str(GetLastError(), errbuf);
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Error opening adapter: %s", errbuf);
|
||||
pcap_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
GetLastError(), "Error opening adapter");
|
||||
}
|
||||
|
||||
return (res);
|
||||
@ -534,7 +523,34 @@ pcap_read_npf(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
*/
|
||||
PacketInitPacket(&Packet, (BYTE *)p->buffer, p->bufsize);
|
||||
if (!PacketReceivePacket(pw->adapter, &Packet, TRUE)) {
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read error: PacketReceivePacket failed");
|
||||
/*
|
||||
* Did the device go away?
|
||||
* If so, the error we get is ERROR_GEN_FAILURE.
|
||||
*/
|
||||
DWORD errcode = GetLastError();
|
||||
|
||||
if (errcode == ERROR_GEN_FAILURE) {
|
||||
/*
|
||||
* The device on which we're capturing
|
||||
* went away, or it became unusable
|
||||
* by NPF due to a suspend/resume.
|
||||
*
|
||||
* XXX - hopefully no other error
|
||||
* conditions are indicated by this.
|
||||
*
|
||||
* XXX - we really should return an
|
||||
* appropriate error for that, but
|
||||
* pcap_dispatch() etc. aren't
|
||||
* documented as having error returns
|
||||
* other than PCAP_ERROR or PCAP_ERROR_BREAK.
|
||||
*/
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"The interface disappeared");
|
||||
} else {
|
||||
pcap_fmt_errmsg_for_win32_err(p->errbuf,
|
||||
PCAP_ERRBUF_SIZE, errcode,
|
||||
"PacketReceivePacket error");
|
||||
}
|
||||
return (PCAP_ERROR);
|
||||
}
|
||||
|
||||
@ -873,7 +889,7 @@ pcap_activate_npf(pcap_t *p)
|
||||
struct pcap_win *pw = p->priv;
|
||||
NetType type;
|
||||
int res;
|
||||
char errbuf[PCAP_ERRBUF_SIZE+1];
|
||||
int status = 0;
|
||||
|
||||
if (p->opt.rfmon) {
|
||||
/*
|
||||
@ -912,23 +928,35 @@ pcap_activate_npf(pcap_t *p)
|
||||
|
||||
if (pw->adapter == NULL)
|
||||
{
|
||||
/* Adapter detected but we are not able to open it. Return failure. */
|
||||
pcap_win32_err_to_str(GetLastError(), errbuf);
|
||||
if (pw->rfmon_selfstart)
|
||||
{
|
||||
PacketSetMonitorMode(p->opt.device, 0);
|
||||
DWORD errcode = GetLastError();
|
||||
|
||||
/*
|
||||
* What error did we get when trying to open the adapter?
|
||||
*/
|
||||
if (errcode == ERROR_BAD_UNIT) {
|
||||
/*
|
||||
* There's no such device.
|
||||
*/
|
||||
return (PCAP_ERROR_NO_SUCH_DEVICE);
|
||||
} else {
|
||||
/*
|
||||
* Unknown - report details.
|
||||
*/
|
||||
pcap_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
errcode, "Error opening adapter");
|
||||
if (pw->rfmon_selfstart)
|
||||
{
|
||||
PacketSetMonitorMode(p->opt.device, 0);
|
||||
}
|
||||
return (PCAP_ERROR);
|
||||
}
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Error opening adapter: %s", errbuf);
|
||||
return (PCAP_ERROR);
|
||||
}
|
||||
|
||||
/*get network type*/
|
||||
if(PacketGetNetType (pw->adapter,&type) == FALSE)
|
||||
{
|
||||
pcap_win32_err_to_str(GetLastError(), errbuf);
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Cannot determine the network type: %s", errbuf);
|
||||
pcap_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
GetLastError(), "Cannot determine the network type");
|
||||
goto bad;
|
||||
}
|
||||
|
||||
@ -1006,8 +1034,29 @@ pcap_activate_npf(pcap_t *p)
|
||||
p->linktype = DLT_PPI;
|
||||
break;
|
||||
|
||||
#ifdef NdisMediumWirelessWan
|
||||
case NdisMediumWirelessWan:
|
||||
p->linktype = DLT_RAW;
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
p->linktype = DLT_EN10MB; /*an unknown adapter is assumed to be ethernet*/
|
||||
/*
|
||||
* An unknown medium type is assumed to supply Ethernet
|
||||
* headers; if not, the user will have to report it,
|
||||
* so that the medium type and link-layer header type
|
||||
* can be determined. If we were to fail here, we
|
||||
* might get the link-layer type in the error, but
|
||||
* the user wouldn't get a capture, so we wouldn't
|
||||
* be able to determine the link-layer type; we report
|
||||
* a warning with the link-layer type, so at least
|
||||
* some programs will report the warning.
|
||||
*/
|
||||
p->linktype = DLT_EN10MB;
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Unknown NdisMedium value %d, defaulting to DLT_EN10MB",
|
||||
type.LinkType);
|
||||
status = PCAP_WARNING;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1085,10 +1134,9 @@ pcap_activate_npf(pcap_t *p)
|
||||
/* tell the driver to copy the buffer as soon as data arrives */
|
||||
if(PacketSetMinToCopy(pw->adapter,0)==FALSE)
|
||||
{
|
||||
pcap_win32_err_to_str(GetLastError(), errbuf);
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Error calling PacketSetMinToCopy: %s",
|
||||
errbuf);
|
||||
pcap_fmt_errmsg_for_win32_err(p->errbuf,
|
||||
PCAP_ERRBUF_SIZE, GetLastError(),
|
||||
"Error calling PacketSetMinToCopy");
|
||||
goto bad;
|
||||
}
|
||||
}
|
||||
@ -1097,10 +1145,9 @@ pcap_activate_npf(pcap_t *p)
|
||||
/* tell the driver to copy the buffer only if it contains at least 16K */
|
||||
if(PacketSetMinToCopy(pw->adapter,16000)==FALSE)
|
||||
{
|
||||
pcap_win32_err_to_str(GetLastError(), errbuf);
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Error calling PacketSetMinToCopy: %s",
|
||||
errbuf);
|
||||
pcap_fmt_errmsg_for_win32_err(p->errbuf,
|
||||
PCAP_ERRBUF_SIZE, GetLastError(),
|
||||
"Error calling PacketSetMinToCopy");
|
||||
goto bad;
|
||||
}
|
||||
}
|
||||
@ -1221,7 +1268,7 @@ pcap_activate_npf(pcap_t *p)
|
||||
*/
|
||||
p->handle = pw->adapter->hFile;
|
||||
|
||||
return (0);
|
||||
return (status);
|
||||
bad:
|
||||
pcap_cleanup_npf(p);
|
||||
return (PCAP_ERROR);
|
||||
@ -1316,7 +1363,7 @@ pcap_setfilter_win32_dag(pcap_t *p, struct bpf_program *fp) {
|
||||
|
||||
if(!fp)
|
||||
{
|
||||
strlcpy(p->errbuf, "setfilter: No filter specified", sizeof(p->errbuf));
|
||||
pcap_strlcpy(p->errbuf, "setfilter: No filter specified", sizeof(p->errbuf));
|
||||
return (-1);
|
||||
}
|
||||
|
||||
@ -1345,7 +1392,6 @@ pcap_setnonblock_npf(pcap_t *p, int nonblock)
|
||||
{
|
||||
struct pcap_win *pw = p->priv;
|
||||
int newtimeout;
|
||||
char win_errbuf[PCAP_ERRBUF_SIZE+1];
|
||||
|
||||
if (nonblock) {
|
||||
/*
|
||||
@ -1365,9 +1411,8 @@ pcap_setnonblock_npf(pcap_t *p, int nonblock)
|
||||
newtimeout = p->opt.timeout;
|
||||
}
|
||||
if (!PacketSetReadTimeout(pw->adapter, newtimeout)) {
|
||||
pcap_win32_err_to_str(GetLastError(), win_errbuf);
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"PacketSetReadTimeout: %s", win_errbuf);
|
||||
pcap_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
GetLastError(), "PacketSetReadTimeout");
|
||||
return (-1);
|
||||
}
|
||||
pw->nonblock = (newtimeout == -1);
|
||||
@ -1684,7 +1729,6 @@ pcap_platform_finddevs(pcap_if_list_t *devlistp, char *errbuf)
|
||||
char *AdaptersName;
|
||||
ULONG NameLength;
|
||||
char *name;
|
||||
char our_errbuf[PCAP_ERRBUF_SIZE+1];
|
||||
|
||||
/*
|
||||
* Find out how big a buffer we need.
|
||||
@ -1710,9 +1754,8 @@ pcap_platform_finddevs(pcap_if_list_t *devlistp, char *errbuf)
|
||||
|
||||
if (last_error != ERROR_INSUFFICIENT_BUFFER)
|
||||
{
|
||||
pcap_win32_err_to_str(last_error, our_errbuf);
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"PacketGetAdapterNames: %s", our_errbuf);
|
||||
pcap_fmt_errmsg_for_win32_err(errbuf, PCAP_ERRBUF_SIZE,
|
||||
last_error, "PacketGetAdapterNames");
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
@ -1727,9 +1770,8 @@ pcap_platform_finddevs(pcap_if_list_t *devlistp, char *errbuf)
|
||||
}
|
||||
|
||||
if (!PacketGetAdapterNames(AdaptersName, &NameLength)) {
|
||||
pcap_win32_err_to_str(GetLastError(), our_errbuf);
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "PacketGetAdapterNames: %s",
|
||||
our_errbuf);
|
||||
pcap_fmt_errmsg_for_win32_err(errbuf, PCAP_ERRBUF_SIZE,
|
||||
GetLastError(), "PacketGetAdapterNames");
|
||||
free(AdaptersName);
|
||||
return (-1);
|
||||
}
|
||||
@ -1818,7 +1860,6 @@ pcap_lookupdev(char *errbuf)
|
||||
{
|
||||
DWORD dwVersion;
|
||||
DWORD dwWindowsMajorVersion;
|
||||
char our_errbuf[PCAP_ERRBUF_SIZE+1];
|
||||
|
||||
#pragma warning (push)
|
||||
#pragma warning (disable: 4996) /* disable MSVC's GetVersion() deprecated warning here */
|
||||
@ -1860,9 +1901,8 @@ pcap_lookupdev(char *errbuf)
|
||||
|
||||
if ( !PacketGetAdapterNames((PTSTR)TAdaptersName,&NameLength) )
|
||||
{
|
||||
pcap_win32_err_to_str(GetLastError(), our_errbuf);
|
||||
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"PacketGetAdapterNames: %s", our_errbuf);
|
||||
pcap_fmt_errmsg_for_win32_err(errbuf, PCAP_ERRBUF_SIZE,
|
||||
GetLastError(), "PacketGetAdapterNames");
|
||||
free(TAdaptersName);
|
||||
return NULL;
|
||||
}
|
||||
@ -2000,59 +2040,48 @@ static const char *pcap_lib_version_string;
|
||||
* tree. Include version.h from that source tree to get the WinPcap/Npcap
|
||||
* version.
|
||||
*
|
||||
* XXX - it'd be nice if we could somehow generate the WinPcap version number
|
||||
* when building WinPcap. (It'd be nice to do so for the packet.dll version
|
||||
* number as well.)
|
||||
* XXX - it'd be nice if we could somehow generate the WinPcap/Npcap version
|
||||
* number when building as part of WinPcap/Npcap. (It'd be nice to do so
|
||||
* for the packet.dll version number as well.)
|
||||
*/
|
||||
#include "../../version.h"
|
||||
|
||||
static const char pcap_version_string[] =
|
||||
WINPCAP_PRODUCT_NAME " version " WINPCAP_VER_STRING ", based on " PCAP_VERSION_STRING;
|
||||
static const char pcap_version_string_packet_dll_fmt[] =
|
||||
WINPCAP_PRODUCT_NAME " version " WINPCAP_VER_STRING " (packet.dll version %s), based on " PCAP_VERSION_STRING;
|
||||
|
||||
const char *
|
||||
pcap_lib_version(void)
|
||||
{
|
||||
char *packet_version_string;
|
||||
size_t full_pcap_version_string_len;
|
||||
char *full_pcap_version_string;
|
||||
|
||||
if (pcap_lib_version_string == NULL) {
|
||||
/*
|
||||
* Generate the version string.
|
||||
*/
|
||||
packet_version_string = PacketGetVersion();
|
||||
char *packet_version_string = PacketGetVersion();
|
||||
|
||||
if (strcmp(WINPCAP_VER_STRING, packet_version_string) == 0) {
|
||||
/*
|
||||
* WinPcap version string and packet.dll version
|
||||
* string are the same; just report the WinPcap
|
||||
* WinPcap/Npcap version string and packet.dll version
|
||||
* string are the same; just report the WinPcap/Npcap
|
||||
* version.
|
||||
*/
|
||||
pcap_lib_version_string = pcap_version_string;
|
||||
} else {
|
||||
/*
|
||||
* WinPcap version string and packet.dll version
|
||||
* WinPcap/Npcap version string and packet.dll version
|
||||
* string are different; that shouldn't be the
|
||||
* case (the two libraries should come from the
|
||||
* same version of WinPcap), so we report both
|
||||
* same version of WinPcap/Npcap), so we report both
|
||||
* versions.
|
||||
*
|
||||
* The -2 is for the %s in the format string,
|
||||
* which will be replaced by packet_version_string.
|
||||
*/
|
||||
full_pcap_version_string_len =
|
||||
(sizeof pcap_version_string_packet_dll_fmt - 2) +
|
||||
strlen(packet_version_string);
|
||||
full_pcap_version_string = malloc(full_pcap_version_string_len);
|
||||
if (full_pcap_version_string == NULL)
|
||||
return (NULL);
|
||||
pcap_snprintf(full_pcap_version_string,
|
||||
full_pcap_version_string_len,
|
||||
pcap_version_string_packet_dll_fmt,
|
||||
packet_version_string);
|
||||
char *full_pcap_version_string;
|
||||
|
||||
if (pcap_asprintf(&full_pcap_version_string,
|
||||
WINPCAP_PRODUCT_NAME " version " WINPCAP_VER_STRING " (packet.dll version %s), based on " PCAP_VERSION_STRING,
|
||||
packet_version_string) != -1) {
|
||||
/* Success */
|
||||
pcap_lib_version_string = full_pcap_version_string;
|
||||
}
|
||||
}
|
||||
pcap_lib_version_string = full_pcap_version_string;
|
||||
}
|
||||
return (pcap_lib_version_string);
|
||||
}
|
||||
@ -2063,35 +2092,22 @@ pcap_lib_version(void)
|
||||
* libpcap being built for Windows, not as part of a WinPcap/Npcap source
|
||||
* tree.
|
||||
*/
|
||||
static const char pcap_version_string_packet_dll_fmt[] =
|
||||
PCAP_VERSION_STRING " (packet.dll version %s)";
|
||||
const char *
|
||||
pcap_lib_version(void)
|
||||
{
|
||||
char *packet_version_string;
|
||||
size_t full_pcap_version_string_len;
|
||||
char *full_pcap_version_string;
|
||||
|
||||
if (pcap_lib_version_string == NULL) {
|
||||
/*
|
||||
* Generate the version string. Report the packet.dll
|
||||
* version.
|
||||
*
|
||||
* The -2 is for the %s in the format string, which will
|
||||
* be replaced by packet_version_string.
|
||||
*/
|
||||
packet_version_string = PacketGetVersion();
|
||||
full_pcap_version_string_len =
|
||||
(sizeof pcap_version_string_packet_dll_fmt - 2) +
|
||||
strlen(packet_version_string);
|
||||
full_pcap_version_string = malloc(full_pcap_version_string_len);
|
||||
if (full_pcap_version_string == NULL)
|
||||
return (NULL);
|
||||
pcap_snprintf(full_pcap_version_string,
|
||||
full_pcap_version_string_len,
|
||||
pcap_version_string_packet_dll_fmt,
|
||||
packet_version_string);
|
||||
pcap_lib_version_string = full_pcap_version_string;
|
||||
char *full_pcap_version_string;
|
||||
|
||||
if (pcap_asprintf(&full_pcap_version_string,
|
||||
PCAP_VERSION_STRING " (packet.dll version %s)",
|
||||
PacketGetVersion()) != -1) {
|
||||
/* Success */
|
||||
pcap_lib_version_string = full_pcap_version_string;
|
||||
}
|
||||
}
|
||||
return (pcap_lib_version_string);
|
||||
}
|
||||
|
@ -32,12 +32,12 @@ static char nosup[] = "live packet capture not supported on this system";
|
||||
pcap_t *
|
||||
pcap_create_interface(const char *device _U_, char *ebuf)
|
||||
{
|
||||
(void)strlcpy(ebuf, nosup, PCAP_ERRBUF_SIZE);
|
||||
(void)pcap_strlcpy(ebuf, nosup, PCAP_ERRBUF_SIZE);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
int
|
||||
pcap_platform_finddevs(pcap_if_list_t *devlistp, char *errbuf)
|
||||
pcap_platform_finddevs(pcap_if_list_t *devlistp _U_, char *errbuf _U_)
|
||||
{
|
||||
/*
|
||||
* There are no interfaces on which we can capture.
|
||||
@ -50,7 +50,7 @@ int
|
||||
pcap_lookupnet(const char *device _U_, bpf_u_int32 *netp _U_,
|
||||
bpf_u_int32 *maskp _U_, char *errbuf)
|
||||
{
|
||||
(void)strlcpy(errbuf, nosup, PCAP_ERRBUF_SIZE);
|
||||
(void)pcap_strlcpy(errbuf, nosup, PCAP_ERRBUF_SIZE);
|
||||
return (-1);
|
||||
}
|
||||
#endif
|
||||
|
631
pcap-rpcap.c
631
pcap-rpcap.c
@ -155,7 +155,6 @@ static void pcap_save_current_filter_rpcap(pcap_t *fp, const char *filter);
|
||||
static int pcap_setfilter_rpcap(pcap_t *fp, struct bpf_program *prog);
|
||||
static int pcap_setsampling_remote(pcap_t *fp);
|
||||
static int pcap_startcapture_remote(pcap_t *fp);
|
||||
static int rpcap_sendauth(SOCKET sock, uint8 *ver, struct pcap_rmtauth *auth, char *errbuf);
|
||||
static int rpcap_recv_msg_header(SOCKET sock, struct rpcap_header *header, char *errbuf);
|
||||
static int rpcap_check_msg_ver(SOCKET sock, uint8 expected_ver, struct rpcap_header *header, char *errbuf);
|
||||
static int rpcap_check_msg_type(SOCKET sock, uint8 request_type, struct rpcap_header *header, uint16 *errcode, char *errbuf);
|
||||
@ -409,7 +408,7 @@ static int pcap_read_nocb_remote(pcap_t *p, struct pcap_pkthdr *pkt_header, u_ch
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
sock_geterror("select(): ", p->errbuf, PCAP_ERRBUF_SIZE);
|
||||
sock_geterror("select()", p->errbuf, PCAP_ERRBUF_SIZE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -763,6 +762,8 @@ static void pcap_cleanup_rpcap(pcap_t *fp)
|
||||
pr->currentfilter = NULL;
|
||||
}
|
||||
|
||||
pcap_cleanup_live_common(fp);
|
||||
|
||||
/* To avoid inconsistencies in the number of sock_init() */
|
||||
sock_cleanup();
|
||||
}
|
||||
@ -908,7 +909,7 @@ static struct pcap_stat *rpcap_stats_rpcap(pcap_t *p, struct pcap_stat *ps, int
|
||||
|
||||
/* Discard the rest of the message. */
|
||||
if (rpcap_discard(pr->rmt_sockctrl, plen, p->errbuf) == -1)
|
||||
goto error;
|
||||
goto error_nodiscard;
|
||||
|
||||
return ps;
|
||||
|
||||
@ -920,6 +921,7 @@ static struct pcap_stat *rpcap_stats_rpcap(pcap_t *p, struct pcap_stat *ps, int
|
||||
*/
|
||||
(void)rpcap_discard(pr->rmt_sockctrl, plen, NULL);
|
||||
|
||||
error_nodiscard:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -1068,7 +1070,7 @@ static int pcap_startcapture_remote(pcap_t *fp)
|
||||
saddrlen = sizeof(struct sockaddr_storage);
|
||||
if (getpeername(pr->rmt_sockctrl, (struct sockaddr *) &saddr, &saddrlen) == -1)
|
||||
{
|
||||
sock_geterror("getsockname(): ", fp->errbuf, PCAP_ERRBUF_SIZE);
|
||||
sock_geterror("getsockname()", fp->errbuf, PCAP_ERRBUF_SIZE);
|
||||
goto error_nodiscard;
|
||||
}
|
||||
ai_family = ((struct sockaddr_storage *) &saddr)->ss_family;
|
||||
@ -1077,7 +1079,7 @@ static int pcap_startcapture_remote(pcap_t *fp)
|
||||
if (getnameinfo((struct sockaddr *) &saddr, saddrlen, host,
|
||||
sizeof(host), NULL, 0, NI_NUMERICHOST))
|
||||
{
|
||||
sock_geterror("getnameinfo(): ", fp->errbuf, PCAP_ERRBUF_SIZE);
|
||||
sock_geterror("getnameinfo()", fp->errbuf, PCAP_ERRBUF_SIZE);
|
||||
goto error_nodiscard;
|
||||
}
|
||||
|
||||
@ -1115,7 +1117,7 @@ static int pcap_startcapture_remote(pcap_t *fp)
|
||||
saddrlen = sizeof(struct sockaddr_storage);
|
||||
if (getsockname(sockdata, (struct sockaddr *) &saddr, &saddrlen) == -1)
|
||||
{
|
||||
sock_geterror("getsockname(): ", fp->errbuf, PCAP_ERRBUF_SIZE);
|
||||
sock_geterror("getsockname()", fp->errbuf, PCAP_ERRBUF_SIZE);
|
||||
goto error_nodiscard;
|
||||
}
|
||||
|
||||
@ -1123,7 +1125,7 @@ static int pcap_startcapture_remote(pcap_t *fp)
|
||||
if (getnameinfo((struct sockaddr *) &saddr, saddrlen, NULL,
|
||||
0, portdata, sizeof(portdata), NI_NUMERICSERV))
|
||||
{
|
||||
sock_geterror("getnameinfo(): ", fp->errbuf, PCAP_ERRBUF_SIZE);
|
||||
sock_geterror("getnameinfo()", fp->errbuf, PCAP_ERRBUF_SIZE);
|
||||
goto error_nodiscard;
|
||||
}
|
||||
}
|
||||
@ -1233,7 +1235,7 @@ static int pcap_startcapture_remote(pcap_t *fp)
|
||||
|
||||
if (socktemp == INVALID_SOCKET)
|
||||
{
|
||||
sock_geterror("accept(): ", fp->errbuf, PCAP_ERRBUF_SIZE);
|
||||
sock_geterror("accept()", fp->errbuf, PCAP_ERRBUF_SIZE);
|
||||
goto error;
|
||||
}
|
||||
|
||||
@ -1259,8 +1261,8 @@ static int pcap_startcapture_remote(pcap_t *fp)
|
||||
res = getsockopt(sockdata, SOL_SOCKET, SO_RCVBUF, (char *)&sockbufsize, &itemp);
|
||||
if (res == -1)
|
||||
{
|
||||
sock_geterror("pcap_startcapture_remote()", fp->errbuf, PCAP_ERRBUF_SIZE);
|
||||
SOCK_DEBUG_MESSAGE(fp->errbuf);
|
||||
sock_geterror("pcap_startcapture_remote(): getsockopt() failed", fp->errbuf, PCAP_ERRBUF_SIZE);
|
||||
goto error;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1334,7 +1336,7 @@ static int pcap_startcapture_remote(pcap_t *fp)
|
||||
|
||||
/* Discard the rest of the message. */
|
||||
if (rpcap_discard(pr->rmt_sockctrl, plen, fp->errbuf) == -1)
|
||||
goto error;
|
||||
goto error_nodiscard;
|
||||
|
||||
/*
|
||||
* In case the user does not want to capture RPCAP packets, let's update the filter
|
||||
@ -1611,21 +1613,19 @@ static int pcap_createfilter_norpcappkt(pcap_t *fp, struct bpf_program *prog)
|
||||
char peeraddress[128];
|
||||
char peerctrlport[128];
|
||||
char *newfilter;
|
||||
const int newstringsize = 1024;
|
||||
size_t currentfiltersize;
|
||||
|
||||
/* Get the name/port of our peer */
|
||||
saddrlen = sizeof(struct sockaddr_storage);
|
||||
if (getpeername(pr->rmt_sockctrl, (struct sockaddr *) &saddr, &saddrlen) == -1)
|
||||
{
|
||||
sock_geterror("getpeername(): ", fp->errbuf, PCAP_ERRBUF_SIZE);
|
||||
sock_geterror("getpeername()", fp->errbuf, PCAP_ERRBUF_SIZE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (getnameinfo((struct sockaddr *) &saddr, saddrlen, peeraddress,
|
||||
sizeof(peeraddress), peerctrlport, sizeof(peerctrlport), NI_NUMERICHOST | NI_NUMERICSERV))
|
||||
{
|
||||
sock_geterror("getnameinfo(): ", fp->errbuf, PCAP_ERRBUF_SIZE);
|
||||
sock_geterror("getnameinfo()", fp->errbuf, PCAP_ERRBUF_SIZE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1633,7 +1633,7 @@ static int pcap_createfilter_norpcappkt(pcap_t *fp, struct bpf_program *prog)
|
||||
/* Get the name/port of the current host */
|
||||
if (getsockname(pr->rmt_sockctrl, (struct sockaddr *) &saddr, &saddrlen) == -1)
|
||||
{
|
||||
sock_geterror("getsockname(): ", fp->errbuf, PCAP_ERRBUF_SIZE);
|
||||
sock_geterror("getsockname()", fp->errbuf, PCAP_ERRBUF_SIZE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1641,43 +1641,60 @@ static int pcap_createfilter_norpcappkt(pcap_t *fp, struct bpf_program *prog)
|
||||
if (getnameinfo((struct sockaddr *) &saddr, saddrlen, myaddress,
|
||||
sizeof(myaddress), myctrlport, sizeof(myctrlport), NI_NUMERICHOST | NI_NUMERICSERV))
|
||||
{
|
||||
sock_geterror("getnameinfo(): ", fp->errbuf, PCAP_ERRBUF_SIZE);
|
||||
sock_geterror("getnameinfo()", fp->errbuf, PCAP_ERRBUF_SIZE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Let's now check the data port */
|
||||
if (getsockname(pr->rmt_sockdata, (struct sockaddr *) &saddr, &saddrlen) == -1)
|
||||
{
|
||||
sock_geterror("getsockname(): ", fp->errbuf, PCAP_ERRBUF_SIZE);
|
||||
sock_geterror("getsockname()", fp->errbuf, PCAP_ERRBUF_SIZE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Get the local port the system picked up */
|
||||
if (getnameinfo((struct sockaddr *) &saddr, saddrlen, NULL, 0, mydataport, sizeof(mydataport), NI_NUMERICSERV))
|
||||
{
|
||||
sock_geterror("getnameinfo(): ", fp->errbuf, PCAP_ERRBUF_SIZE);
|
||||
sock_geterror("getnameinfo()", fp->errbuf, PCAP_ERRBUF_SIZE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
currentfiltersize = pr->currentfilter ? strlen(pr->currentfilter) : 0;
|
||||
|
||||
newfilter = (char *)malloc(currentfiltersize + newstringsize + 1);
|
||||
|
||||
if (currentfiltersize)
|
||||
if (pr->currentfilter && pr->currentfilter[0] != '\0')
|
||||
{
|
||||
pcap_snprintf(newfilter, currentfiltersize + newstringsize,
|
||||
"(%s) and not (host %s and host %s and port %s and port %s) and not (host %s and host %s and port %s)",
|
||||
pr->currentfilter, myaddress, peeraddress, myctrlport, peerctrlport, myaddress, peeraddress, mydataport);
|
||||
/*
|
||||
* We have a current filter; add items to it to
|
||||
* filter out this rpcap session.
|
||||
*/
|
||||
if (pcap_asprintf(&newfilter,
|
||||
"(%s) and not (host %s and host %s and port %s and port %s) and not (host %s and host %s and port %s)",
|
||||
pr->currentfilter, myaddress, peeraddress,
|
||||
myctrlport, peerctrlport, myaddress, peeraddress,
|
||||
mydataport) == -1)
|
||||
{
|
||||
/* Failed. */
|
||||
pcap_snprintf(fp->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Can't allocate memory for new filter");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pcap_snprintf(newfilter, currentfiltersize + newstringsize,
|
||||
"not (host %s and host %s and port %s and port %s) and not (host %s and host %s and port %s)",
|
||||
myaddress, peeraddress, myctrlport, peerctrlport, myaddress, peeraddress, mydataport);
|
||||
/*
|
||||
* We have no current filter; construct a filter to
|
||||
* filter out this rpcap session.
|
||||
*/
|
||||
if (pcap_asprintf(&newfilter,
|
||||
"not (host %s and host %s and port %s and port %s) and not (host %s and host %s and port %s)",
|
||||
myaddress, peeraddress, myctrlport, peerctrlport,
|
||||
myaddress, peeraddress, mydataport) == -1)
|
||||
{
|
||||
/* Failed. */
|
||||
pcap_snprintf(fp->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Can't allocate memory for new filter");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
newfilter[currentfiltersize + newstringsize] = 0;
|
||||
|
||||
/*
|
||||
* This is only an hack to prevent the save_current_filter
|
||||
* routine, which will be called when we call pcap_compile(),
|
||||
@ -1784,16 +1801,25 @@ static int pcap_setsampling_remote(pcap_t *fp)
|
||||
|
||||
/*
|
||||
* This function performs authentication and protocol version
|
||||
* negotiation. It first tries to authenticate with the maximum
|
||||
* version we support and, if that fails with an "I don't support
|
||||
* that version" error from the server, and the version number in
|
||||
* the reply from the server is one we support, tries again with
|
||||
* that version.
|
||||
* negotiation. It is required in order to open the connection
|
||||
* with the other end party.
|
||||
*
|
||||
* It sends authentication parameters on the control socket and
|
||||
* reads the reply. If the reply is a success indication, it
|
||||
* checks whether the reply includes minimum and maximum supported
|
||||
* versions from the server; if not, it assumes both are 0, as
|
||||
* that means it's an older server that doesn't return supported
|
||||
* version numbers in authentication replies, so it only supports
|
||||
* version 0. It then tries to determine the maximum version
|
||||
* supported both by us and by the server. If it can find such a
|
||||
* version, it sets us up to use that version; otherwise, it fails,
|
||||
* indicating that there is no version supported by us and by the
|
||||
* server.
|
||||
*
|
||||
* \param sock: the socket we are currently using.
|
||||
*
|
||||
* \param ver: pointer to variable holding protocol version number to send
|
||||
* and to set to the protocol version number in the reply.
|
||||
* \param ver: pointer to variable to which to set the protocol version
|
||||
* number we selected.
|
||||
*
|
||||
* \param auth: authentication parameters that have to be sent.
|
||||
*
|
||||
@ -1806,96 +1832,17 @@ static int pcap_setsampling_remote(pcap_t *fp)
|
||||
* an error message string is returned in the 'errbuf' variable.
|
||||
*/
|
||||
static int rpcap_doauth(SOCKET sockctrl, uint8 *ver, struct pcap_rmtauth *auth, char *errbuf)
|
||||
{
|
||||
int status;
|
||||
|
||||
/*
|
||||
* Send authentication to the remote machine.
|
||||
*
|
||||
* First try with the maximum version number we support.
|
||||
*/
|
||||
*ver = RPCAP_MAX_VERSION;
|
||||
status = rpcap_sendauth(sockctrl, ver, auth, errbuf);
|
||||
if (status == 0)
|
||||
{
|
||||
//
|
||||
// Success.
|
||||
//
|
||||
return 0;
|
||||
}
|
||||
if (status == -1)
|
||||
{
|
||||
/* Unrecoverable error. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* The server doesn't support the version we used in the initial
|
||||
* message, and it sent us back a reply either with the maximum
|
||||
* version they do support, or with the version we sent, and we
|
||||
* support that version. *ver has been set to that version; try
|
||||
* authenticating again with that version.
|
||||
*/
|
||||
status = rpcap_sendauth(sockctrl, ver, auth, errbuf);
|
||||
if (status == 0)
|
||||
{
|
||||
//
|
||||
// Success.
|
||||
//
|
||||
return 0;
|
||||
}
|
||||
if (status == -1)
|
||||
{
|
||||
/* Unrecoverable error. */
|
||||
return -1;
|
||||
}
|
||||
if (status == -2)
|
||||
{
|
||||
/*
|
||||
* The server doesn't support that version, which
|
||||
* means there is no version we both support, so
|
||||
* this is a fatal error.
|
||||
*/
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "The server doesn't support any protocol version that we support");
|
||||
return -1;
|
||||
}
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "rpcap_sendauth() returned %d", status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function sends the authentication message.
|
||||
*
|
||||
* It sends the authentication parameters on the control socket.
|
||||
* It is required in order to open the connection with the other end party.
|
||||
*
|
||||
* \param sock: the socket we are currently using.
|
||||
*
|
||||
* \param ver: pointer to variable holding protocol version number to send
|
||||
* and to set to the protocol version number in the reply.
|
||||
*
|
||||
* \param auth: authentication parameters that have to be sent.
|
||||
*
|
||||
* \param errbuf: a pointer to a user-allocated buffer (of size
|
||||
* PCAP_ERRBUF_SIZE) that will contain the error message (in case there
|
||||
* is one). It could be a network problem or the fact that the authorization
|
||||
* failed.
|
||||
*
|
||||
* \return '0' if everything is fine, '-2' if the server didn't reply with
|
||||
* the protocol version we requested but replied with a version we do
|
||||
* support, or '-1' for other errors. For errors, an error message string
|
||||
* is returned in the 'errbuf' variable.
|
||||
*/
|
||||
static int rpcap_sendauth(SOCKET sock, uint8 *ver, struct pcap_rmtauth *auth, char *errbuf)
|
||||
{
|
||||
char sendbuf[RPCAP_NETBUF_SIZE]; /* temporary buffer in which data that has to be sent is buffered */
|
||||
int sendbufidx = 0; /* index which keeps the number of bytes currently buffered */
|
||||
uint16 length; /* length of the payload of this message */
|
||||
uint16 errcode;
|
||||
struct rpcap_auth *rpauth;
|
||||
uint16 auth_type;
|
||||
struct rpcap_header header;
|
||||
size_t str_length;
|
||||
uint32 plen;
|
||||
struct rpcap_authreply authreply; /* authentication reply message */
|
||||
uint8 ourvers;
|
||||
|
||||
if (auth)
|
||||
{
|
||||
@ -1942,12 +1889,11 @@ static int rpcap_sendauth(SOCKET sock, uint8 *ver, struct pcap_rmtauth *auth, ch
|
||||
length = sizeof(struct rpcap_auth);
|
||||
}
|
||||
|
||||
|
||||
if (sock_bufferize(NULL, sizeof(struct rpcap_header), NULL,
|
||||
&sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errbuf, PCAP_ERRBUF_SIZE))
|
||||
return -1;
|
||||
|
||||
rpcap_createhdr((struct rpcap_header *) sendbuf, *ver,
|
||||
rpcap_createhdr((struct rpcap_header *) sendbuf, 0,
|
||||
RPCAP_MSG_AUTH_REQ, 0, length);
|
||||
|
||||
rpauth = (struct rpcap_auth *) &sendbuf[sendbufidx];
|
||||
@ -1984,62 +1930,104 @@ static int rpcap_sendauth(SOCKET sock, uint8 *ver, struct pcap_rmtauth *auth, ch
|
||||
rpauth->slen2 = htons(rpauth->slen2);
|
||||
}
|
||||
|
||||
if (sock_send(sock, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) < 0)
|
||||
if (sock_send(sockctrl, sendbuf, sendbufidx, errbuf,
|
||||
PCAP_ERRBUF_SIZE) < 0)
|
||||
return -1;
|
||||
|
||||
/* Receive the reply */
|
||||
if (rpcap_recv_msg_header(sock, &header, errbuf) == -1)
|
||||
/* Receive and process the reply message header */
|
||||
if (rpcap_process_msg_header(sockctrl, 0, RPCAP_MSG_AUTH_REQ,
|
||||
&header, errbuf) == -1)
|
||||
return -1;
|
||||
|
||||
if (rpcap_check_msg_type(sock, RPCAP_MSG_AUTH_REQ, &header,
|
||||
&errcode, errbuf) == -1)
|
||||
/*
|
||||
* OK, it's an authentication reply, so we're logged in.
|
||||
*
|
||||
* Did it send any additional information?
|
||||
*/
|
||||
plen = header.plen;
|
||||
if (plen != 0)
|
||||
{
|
||||
/* Error message - or something else, which is a protocol error. */
|
||||
if (header.type == RPCAP_MSG_ERROR &&
|
||||
errcode == PCAP_ERR_WRONGVER)
|
||||
/* Yes - is it big enough to be version information? */
|
||||
if (plen < sizeof(struct rpcap_authreply))
|
||||
{
|
||||
/*
|
||||
* The server didn't support the version we sent,
|
||||
* and replied with the maximum version it supports
|
||||
* if our version was too big or with the version
|
||||
* we sent if out version was too small.
|
||||
*
|
||||
* Do we also support it?
|
||||
*/
|
||||
if (!RPCAP_VERSION_IS_SUPPORTED(header.ver))
|
||||
{
|
||||
/*
|
||||
* No, so there's no version we both support.
|
||||
* This is an unrecoverable error.
|
||||
*/
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "The server doesn't support any protocol version that we support");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* OK, use that version, and tell our caller to
|
||||
* try again.
|
||||
*/
|
||||
*ver = header.ver;
|
||||
return -2;
|
||||
/* No - discard it and fail. */
|
||||
(void)rpcap_discard(sockctrl, plen, NULL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Read the reply body */
|
||||
if (rpcap_recv(sockctrl, (char *)&authreply,
|
||||
sizeof(struct rpcap_authreply), &plen, errbuf) == -1)
|
||||
{
|
||||
(void)rpcap_discard(sockctrl, plen, NULL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Discard the rest of the message, if there is any. */
|
||||
if (rpcap_discard(sockctrl, plen, errbuf) == -1)
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* Other error - unrecoverable.
|
||||
* Check the minimum and maximum versions for sanity;
|
||||
* the minimum must be <= the maximum.
|
||||
*/
|
||||
return -1;
|
||||
if (authreply.minvers > authreply.maxvers)
|
||||
{
|
||||
/*
|
||||
* Bogus - give up on this server.
|
||||
*/
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"The server's minimum supported protocol version is greater than its maximum supported protocol version");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No - it supports only version 0. */
|
||||
authreply.minvers = 0;
|
||||
authreply.maxvers = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* OK, it's an authentication reply, so they're OK with the
|
||||
* protocol version we sent.
|
||||
*
|
||||
* Discard the rest of it.
|
||||
* OK, let's start with the maximum version the server supports.
|
||||
*/
|
||||
if (rpcap_discard(sock, header.plen, errbuf) == -1)
|
||||
return -1;
|
||||
ourvers = authreply.maxvers;
|
||||
|
||||
#if RPCAP_MIN_VERSION != 0
|
||||
/*
|
||||
* If that's less than the minimum version we support, we
|
||||
* can't communicate.
|
||||
*/
|
||||
if (ourvers < RPCAP_MIN_VERSION)
|
||||
goto novers;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If that's greater than the maximum version we support,
|
||||
* choose the maximum version we support.
|
||||
*/
|
||||
if (ourvers > RPCAP_MAX_VERSION)
|
||||
{
|
||||
ourvers = RPCAP_MAX_VERSION;
|
||||
|
||||
/*
|
||||
* If that's less than the minimum version they
|
||||
* support, we can't communicate.
|
||||
*/
|
||||
if (ourvers < authreply.minvers)
|
||||
goto novers;
|
||||
}
|
||||
|
||||
*ver = ourvers;
|
||||
return 0;
|
||||
|
||||
novers:
|
||||
/*
|
||||
* There is no version we both support; that is a fatal error.
|
||||
*/
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"The server doesn't support any protocol version that we support");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* We don't currently support non-blocking mode. */
|
||||
@ -2059,6 +2047,103 @@ pcap_setnonblock_rpcap(pcap_t *p, int nonblock _U_)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static int
|
||||
rpcap_setup_session(const char *source, struct pcap_rmtauth *auth,
|
||||
int *activep, SOCKET *sockctrlp, uint8 *protocol_versionp,
|
||||
char *host, char *port, char *iface, char *errbuf)
|
||||
{
|
||||
int type;
|
||||
struct activehosts *activeconn; /* active connection, if there is one */
|
||||
int error; /* 1 if rpcap_remoteact_getsock got an error */
|
||||
|
||||
/*
|
||||
* Determine the type of the source (NULL, file, local, remote).
|
||||
* You must have a valid source string even if we're in active mode,
|
||||
* because otherwise the call to the following function will fail.
|
||||
*/
|
||||
if (pcap_parsesrcstr(source, &type, host, port, iface, errbuf) == -1)
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* It must be remote.
|
||||
*/
|
||||
if (type != PCAP_SRC_IFREMOTE)
|
||||
{
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Non-remote interface passed to remote capture routine");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Warning: this call can be the first one called by the user. */
|
||||
/* For this reason, we have to initialize the WinSock support. */
|
||||
if (sock_init(errbuf, PCAP_ERRBUF_SIZE) == -1)
|
||||
return -1;
|
||||
|
||||
/* Check for active mode */
|
||||
activeconn = rpcap_remoteact_getsock(host, &error, errbuf);
|
||||
if (activeconn != NULL)
|
||||
{
|
||||
*activep = 1;
|
||||
*sockctrlp = activeconn->sockctrl;
|
||||
*protocol_versionp = activeconn->protocol_version;
|
||||
}
|
||||
else
|
||||
{
|
||||
*activep = 0;
|
||||
struct addrinfo hints; /* temp variable needed to resolve hostnames into to socket representation */
|
||||
struct addrinfo *addrinfo; /* temp variable needed to resolve hostnames into to socket representation */
|
||||
|
||||
if (error)
|
||||
{
|
||||
/*
|
||||
* Call failed.
|
||||
*/
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* We're not in active mode; let's try to open a new
|
||||
* control connection.
|
||||
*/
|
||||
memset(&hints, 0, sizeof(struct addrinfo));
|
||||
hints.ai_family = PF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
|
||||
if (port[0] == 0)
|
||||
{
|
||||
/* the user chose not to specify the port */
|
||||
if (sock_initaddress(host, RPCAP_DEFAULT_NETPORT,
|
||||
&hints, &addrinfo, errbuf, PCAP_ERRBUF_SIZE) == -1)
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sock_initaddress(host, port, &hints, &addrinfo,
|
||||
errbuf, PCAP_ERRBUF_SIZE) == -1)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((*sockctrlp = sock_open(addrinfo, SOCKOPEN_CLIENT, 0,
|
||||
errbuf, PCAP_ERRBUF_SIZE)) == INVALID_SOCKET)
|
||||
{
|
||||
freeaddrinfo(addrinfo);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* addrinfo is no longer used */
|
||||
freeaddrinfo(addrinfo);
|
||||
addrinfo = NULL;
|
||||
|
||||
if (rpcap_doauth(*sockctrlp, protocol_versionp, auth,
|
||||
errbuf) == -1)
|
||||
{
|
||||
sock_close(*sockctrlp, NULL, 0);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function opens a remote adapter by opening an RPCAP connection and
|
||||
* so on.
|
||||
@ -2104,15 +2189,12 @@ pcap_t *pcap_open_rpcap(const char *source, int snaplen, int flags, int read_tim
|
||||
char *source_str;
|
||||
struct pcap_rpcap *pr; /* structure used when doing a remote live capture */
|
||||
char host[PCAP_BUF_SIZE], ctrlport[PCAP_BUF_SIZE], iface[PCAP_BUF_SIZE];
|
||||
struct activehosts *activeconn; /* active connection, if there is one */
|
||||
int error; /* '1' if rpcap_remoteact_getsock returned an error */
|
||||
SOCKET sockctrl;
|
||||
uint8 protocol_version; /* negotiated protocol version */
|
||||
int active;
|
||||
uint32 plen;
|
||||
char sendbuf[RPCAP_NETBUF_SIZE]; /* temporary buffer in which data to be sent is buffered */
|
||||
int sendbufidx = 0; /* index which keeps the number of bytes currently buffered */
|
||||
int retval; /* store the return value of the functions */
|
||||
|
||||
/* RPCAP-related variables */
|
||||
struct rpcap_header header; /* header of the RPCAP packet */
|
||||
@ -2151,100 +2233,16 @@ pcap_t *pcap_open_rpcap(const char *source, int snaplen, int flags, int read_tim
|
||||
pr->rmt_flags = flags;
|
||||
|
||||
/*
|
||||
* determine the type of the source (NULL, file, local, remote)
|
||||
* You must have a valid source string even if we're in active mode, because otherwise
|
||||
* the call to the following function will fail.
|
||||
* Attempt to set up the session with the server.
|
||||
*/
|
||||
if (pcap_parsesrcstr(fp->opt.device, &retval, host, ctrlport, iface, errbuf) == -1)
|
||||
if (rpcap_setup_session(fp->opt.device, auth, &active, &sockctrl,
|
||||
&protocol_version, host, ctrlport, iface, errbuf) == -1)
|
||||
{
|
||||
/* Session setup failed. */
|
||||
pcap_close(fp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (retval != PCAP_SRC_IFREMOTE)
|
||||
{
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "This function is able to open only remote interfaces");
|
||||
pcap_close(fp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Warning: this call can be the first one called by the user.
|
||||
* For this reason, we have to initialize the WinSock support.
|
||||
*/
|
||||
if (sock_init(errbuf, PCAP_ERRBUF_SIZE) == -1)
|
||||
{
|
||||
pcap_close(fp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Check for active mode */
|
||||
activeconn = rpcap_remoteact_getsock(host, &error, errbuf);
|
||||
if (activeconn != NULL)
|
||||
{
|
||||
sockctrl = activeconn->sockctrl;
|
||||
protocol_version = activeconn->protocol_version;
|
||||
active = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
struct addrinfo hints; /* temp, needed to open a socket connection */
|
||||
struct addrinfo *addrinfo; /* temp, needed to open a socket connection */
|
||||
|
||||
if (error)
|
||||
{
|
||||
/*
|
||||
* Call failed.
|
||||
*/
|
||||
pcap_close(fp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* We're not in active mode; let's try to open a new
|
||||
* control connection.
|
||||
*/
|
||||
memset(&hints, 0, sizeof(struct addrinfo));
|
||||
hints.ai_family = PF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
|
||||
if (ctrlport[0] == 0)
|
||||
{
|
||||
/* the user chose not to specify the port */
|
||||
if (sock_initaddress(host, RPCAP_DEFAULT_NETPORT, &hints, &addrinfo, errbuf, PCAP_ERRBUF_SIZE) == -1)
|
||||
{
|
||||
pcap_close(fp);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sock_initaddress(host, ctrlport, &hints, &addrinfo, errbuf, PCAP_ERRBUF_SIZE) == -1)
|
||||
{
|
||||
pcap_close(fp);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if ((sockctrl = sock_open(addrinfo, SOCKOPEN_CLIENT, 0, errbuf, PCAP_ERRBUF_SIZE)) == INVALID_SOCKET)
|
||||
{
|
||||
freeaddrinfo(addrinfo);
|
||||
pcap_close(fp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* addrinfo is no longer used */
|
||||
freeaddrinfo(addrinfo);
|
||||
|
||||
if (rpcap_doauth(sockctrl, &protocol_version, auth, errbuf) == -1)
|
||||
{
|
||||
sock_close(sockctrl, NULL, 0);
|
||||
pcap_close(fp);
|
||||
return NULL;
|
||||
}
|
||||
active = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now it's time to start playing with the RPCAP protocol
|
||||
* RPCAP open command: create the request message
|
||||
@ -2276,7 +2274,7 @@ pcap_t *pcap_open_rpcap(const char *source, int snaplen, int flags, int read_tim
|
||||
goto error;
|
||||
|
||||
/* Discard the rest of the message, if there is any. */
|
||||
if (rpcap_discard(pr->rmt_sockctrl, plen, errbuf) == -1)
|
||||
if (rpcap_discard(sockctrl, plen, errbuf) == -1)
|
||||
goto error_nodiscard;
|
||||
|
||||
/* Set proper fields into the pcap_t struct */
|
||||
@ -2314,7 +2312,7 @@ pcap_t *pcap_open_rpcap(const char *source, int snaplen, int flags, int read_tim
|
||||
* We already reported an error; if this gets an error, just
|
||||
* drive on.
|
||||
*/
|
||||
(void)rpcap_discard(pr->rmt_sockctrl, plen, NULL);
|
||||
(void)rpcap_discard(sockctrl, plen, NULL);
|
||||
|
||||
error_nodiscard:
|
||||
if (!active)
|
||||
@ -2326,8 +2324,10 @@ pcap_t *pcap_open_rpcap(const char *source, int snaplen, int flags, int read_tim
|
||||
|
||||
/* String identifier to be used in the pcap_findalldevs_ex() */
|
||||
#define PCAP_TEXT_SOURCE_ADAPTER "Network adapter"
|
||||
#define PCAP_TEXT_SOURCE_ADAPTER_LEN (sizeof PCAP_TEXT_SOURCE_ADAPTER - 1)
|
||||
/* String identifier to be used in the pcap_findalldevs_ex() */
|
||||
#define PCAP_TEXT_SOURCE_ON_REMOTE_HOST "on remote node"
|
||||
#define PCAP_TEXT_SOURCE_ON_REMOTE_HOST_LEN (sizeof PCAP_TEXT_SOURCE_ON_REMOTE_HOST - 1)
|
||||
|
||||
static void
|
||||
freeaddr(struct pcap_addr *addr)
|
||||
@ -2340,10 +2340,8 @@ freeaddr(struct pcap_addr *addr)
|
||||
}
|
||||
|
||||
int
|
||||
pcap_findalldevs_ex_remote(char *source, struct pcap_rmtauth *auth, pcap_if_t **alldevs, char *errbuf)
|
||||
pcap_findalldevs_ex_remote(const char *source, struct pcap_rmtauth *auth, pcap_if_t **alldevs, char *errbuf)
|
||||
{
|
||||
struct activehosts *activeconn; /* active connection, if there is one */
|
||||
int error; /* '1' if rpcap_remoteact_getsock returned an error */
|
||||
uint8 protocol_version; /* protocol version */
|
||||
SOCKET sockctrl; /* socket descriptor of the control connection */
|
||||
uint32 plen;
|
||||
@ -2351,7 +2349,6 @@ pcap_findalldevs_ex_remote(char *source, struct pcap_rmtauth *auth, pcap_if_t **
|
||||
int i, j; /* temp variables */
|
||||
int nif; /* Number of interfaces listed */
|
||||
int active; /* 'true' if we the other end-party is in active mode */
|
||||
int type;
|
||||
char host[PCAP_BUF_SIZE], port[PCAP_BUF_SIZE];
|
||||
char tmpstring[PCAP_BUF_SIZE + 1]; /* Needed to convert names and descriptions from 'old' syntax to the 'new' one */
|
||||
pcap_if_t *lastdev; /* Last device in the pcap_if_t list */
|
||||
@ -2361,72 +2358,14 @@ pcap_findalldevs_ex_remote(char *source, struct pcap_rmtauth *auth, pcap_if_t **
|
||||
(*alldevs) = NULL;
|
||||
lastdev = NULL;
|
||||
|
||||
/* Retrieve the needed data for getting adapter list */
|
||||
if (pcap_parsesrcstr(source, &type, host, port, NULL, errbuf) == -1)
|
||||
return -1;
|
||||
|
||||
/* Warning: this call can be the first one called by the user. */
|
||||
/* For this reason, we have to initialize the WinSock support. */
|
||||
if (sock_init(errbuf, PCAP_ERRBUF_SIZE) == -1)
|
||||
return -1;
|
||||
|
||||
/* Check for active mode */
|
||||
activeconn = rpcap_remoteact_getsock(host, &error, errbuf);
|
||||
if (activeconn != NULL)
|
||||
/*
|
||||
* Attempt to set up the session with the server.
|
||||
*/
|
||||
if (rpcap_setup_session(source, auth, &active, &sockctrl,
|
||||
&protocol_version, host, port, NULL, errbuf) == -1)
|
||||
{
|
||||
sockctrl = activeconn->sockctrl;
|
||||
protocol_version = activeconn->protocol_version;
|
||||
active = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
struct addrinfo hints; /* temp variable needed to resolve hostnames into to socket representation */
|
||||
struct addrinfo *addrinfo; /* temp variable needed to resolve hostnames into to socket representation */
|
||||
|
||||
if (error)
|
||||
{
|
||||
/*
|
||||
* Call failed.
|
||||
*/
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* We're not in active mode; let's try to open a new
|
||||
* control connection.
|
||||
*/
|
||||
memset(&hints, 0, sizeof(struct addrinfo));
|
||||
hints.ai_family = PF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
|
||||
if (port[0] == 0)
|
||||
{
|
||||
/* the user chose not to specify the port */
|
||||
if (sock_initaddress(host, RPCAP_DEFAULT_NETPORT, &hints, &addrinfo, errbuf, PCAP_ERRBUF_SIZE) == -1)
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sock_initaddress(host, port, &hints, &addrinfo, errbuf, PCAP_ERRBUF_SIZE) == -1)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((sockctrl = sock_open(addrinfo, SOCKOPEN_CLIENT, 0, errbuf, PCAP_ERRBUF_SIZE)) == INVALID_SOCKET)
|
||||
{
|
||||
freeaddrinfo(addrinfo);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* addrinfo is no longer used */
|
||||
freeaddrinfo(addrinfo);
|
||||
addrinfo = NULL;
|
||||
|
||||
if (rpcap_doauth(sockctrl, &protocol_version, auth, errbuf) == -1)
|
||||
{
|
||||
sock_close(sockctrl, NULL, 0);
|
||||
return -1;
|
||||
}
|
||||
active = 0;
|
||||
/* Session setup failed. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* RPCAP findalldevs command */
|
||||
@ -2452,7 +2391,6 @@ pcap_findalldevs_ex_remote(char *source, struct pcap_rmtauth *auth, pcap_if_t **
|
||||
{
|
||||
struct rpcap_findalldevs_if findalldevs_if;
|
||||
char tmpstring2[PCAP_BUF_SIZE + 1]; /* Needed to convert names and descriptions from 'old' syntax to the 'new' one */
|
||||
size_t stringlen;
|
||||
struct pcap_addr *addr, *prevaddr;
|
||||
|
||||
tmpstring2[PCAP_BUF_SIZE] = 0;
|
||||
@ -2514,21 +2452,17 @@ pcap_findalldevs_ex_remote(char *source, struct pcap_rmtauth *auth, pcap_if_t **
|
||||
tmpstring[findalldevs_if.namelen] = 0;
|
||||
|
||||
/* Create the new device identifier */
|
||||
if (pcap_createsrcstr(tmpstring2, PCAP_SRC_IFREMOTE, host, port, tmpstring, errbuf) == -1)
|
||||
return -1;
|
||||
if (pcap_createsrcstr(tmpstring2, PCAP_SRC_IFREMOTE,
|
||||
host, port, tmpstring, errbuf) == -1)
|
||||
goto error;
|
||||
|
||||
stringlen = strlen(tmpstring2);
|
||||
|
||||
dev->name = (char *)malloc(stringlen + 1);
|
||||
dev->name = strdup(tmpstring2);
|
||||
if (dev->name == NULL)
|
||||
{
|
||||
pcap_fmt_errmsg_for_errno(errbuf,
|
||||
PCAP_ERRBUF_SIZE, errno, "malloc() failed");
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Copy the new device name into the correct memory location */
|
||||
strlcpy(dev->name, tmpstring2, stringlen + 1);
|
||||
}
|
||||
|
||||
if (findalldevs_if.desclen)
|
||||
@ -2546,22 +2480,14 @@ pcap_findalldevs_ex_remote(char *source, struct pcap_rmtauth *auth, pcap_if_t **
|
||||
|
||||
tmpstring[findalldevs_if.desclen] = 0;
|
||||
|
||||
pcap_snprintf(tmpstring2, sizeof(tmpstring2) - 1, "%s '%s' %s %s", PCAP_TEXT_SOURCE_ADAPTER,
|
||||
tmpstring, PCAP_TEXT_SOURCE_ON_REMOTE_HOST, host);
|
||||
|
||||
stringlen = strlen(tmpstring2);
|
||||
|
||||
dev->description = (char *)malloc(stringlen + 1);
|
||||
|
||||
if (dev->description == NULL)
|
||||
if (pcap_asprintf(&dev->description,
|
||||
"%s '%s' %s %s", PCAP_TEXT_SOURCE_ADAPTER,
|
||||
tmpstring, PCAP_TEXT_SOURCE_ON_REMOTE_HOST, host) == -1)
|
||||
{
|
||||
pcap_fmt_errmsg_for_errno(errbuf,
|
||||
PCAP_ERRBUF_SIZE, errno, "malloc() failed");
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Copy the new device description into the correct memory location */
|
||||
strlcpy(dev->description, tmpstring2, stringlen + 1);
|
||||
}
|
||||
|
||||
dev->flags = ntohl(findalldevs_if.flags);
|
||||
@ -2648,7 +2574,7 @@ pcap_findalldevs_ex_remote(char *source, struct pcap_rmtauth *auth, pcap_if_t **
|
||||
|
||||
/* Discard the rest of the message. */
|
||||
if (rpcap_discard(sockctrl, plen, errbuf) == 1)
|
||||
return -1;
|
||||
goto error_nodiscard;
|
||||
|
||||
/* Control connection has to be closed only in case the remote machine is in passive mode */
|
||||
if (!active)
|
||||
@ -2730,7 +2656,6 @@ SOCKET pcap_remoteact_accept(const char *address, const char *port, const char *
|
||||
{
|
||||
if (sock_initaddress(address, RPCAP_DEFAULT_NETPORT_ACTIVE, &hints, &addrinfo, errbuf, PCAP_ERRBUF_SIZE) == -1)
|
||||
{
|
||||
SOCK_DEBUG_MESSAGE(errbuf);
|
||||
return (SOCKET)-2;
|
||||
}
|
||||
}
|
||||
@ -2738,7 +2663,6 @@ SOCKET pcap_remoteact_accept(const char *address, const char *port, const char *
|
||||
{
|
||||
if (sock_initaddress(address, port, &hints, &addrinfo, errbuf, PCAP_ERRBUF_SIZE) == -1)
|
||||
{
|
||||
SOCK_DEBUG_MESSAGE(errbuf);
|
||||
return (SOCKET)-2;
|
||||
}
|
||||
}
|
||||
@ -2746,7 +2670,6 @@ SOCKET pcap_remoteact_accept(const char *address, const char *port, const char *
|
||||
|
||||
if ((sockmain = sock_open(addrinfo, SOCKOPEN_SERVER, 1, errbuf, PCAP_ERRBUF_SIZE)) == INVALID_SOCKET)
|
||||
{
|
||||
SOCK_DEBUG_MESSAGE(errbuf);
|
||||
freeaddrinfo(addrinfo);
|
||||
return (SOCKET)-2;
|
||||
}
|
||||
@ -2764,14 +2687,14 @@ SOCKET pcap_remoteact_accept(const char *address, const char *port, const char *
|
||||
|
||||
if (sockctrl == INVALID_SOCKET)
|
||||
{
|
||||
sock_geterror("accept(): ", errbuf, PCAP_ERRBUF_SIZE);
|
||||
sock_geterror("accept()", errbuf, PCAP_ERRBUF_SIZE);
|
||||
return (SOCKET)-2;
|
||||
}
|
||||
|
||||
/* Get the numeric for of the name of the connecting host */
|
||||
if (getnameinfo((struct sockaddr *) &from, fromlen, connectinghost, RPCAP_HOSTLIST_SIZE, NULL, 0, NI_NUMERICHOST))
|
||||
{
|
||||
sock_geterror("getnameinfo(): ", errbuf, PCAP_ERRBUF_SIZE);
|
||||
sock_geterror("getnameinfo()", errbuf, PCAP_ERRBUF_SIZE);
|
||||
rpcap_senderror(sockctrl, 0, PCAP_ERR_REMOTEACCEPT, errbuf, NULL);
|
||||
sock_close(sockctrl, NULL, 0);
|
||||
return (SOCKET)-1;
|
||||
@ -2970,7 +2893,7 @@ int pcap_remoteact_list(char *hostlist, char sep, int size, char *errbuf)
|
||||
/* if (getnameinfo( (struct sockaddr *) &temp->host, sizeof (struct sockaddr_storage), hoststr, */
|
||||
/* RPCAP_HOSTLIST_SIZE, NULL, 0, NI_NUMERICHOST) ) */
|
||||
{
|
||||
/* sock_geterror("getnameinfo(): ", errbuf, PCAP_ERRBUF_SIZE); */
|
||||
/* sock_geterror("getnameinfo()", errbuf, PCAP_ERRBUF_SIZE); */
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -2983,7 +2906,7 @@ int pcap_remoteact_list(char *hostlist, char sep, int size, char *errbuf)
|
||||
return -1;
|
||||
}
|
||||
|
||||
strlcat(hostlist, hoststr, PCAP_ERRBUF_SIZE);
|
||||
pcap_strlcat(hostlist, hoststr, PCAP_ERRBUF_SIZE);
|
||||
hostlist[len - 1] = sep;
|
||||
hostlist[len] = 0;
|
||||
|
||||
@ -3110,7 +3033,7 @@ static int rpcap_check_msg_type(SOCKET sock, uint8 request_type, struct rpcap_he
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -43,7 +43,7 @@ pcap_t *pcap_open_rpcap(const char *source, int snaplen, int flags,
|
||||
/*
|
||||
* Internal interfaces for "pcap_findalldevs_ex()".
|
||||
*/
|
||||
int pcap_findalldevs_ex_remote(char *source, struct pcap_rmtauth *auth,
|
||||
pcap_if_t **alldevs, char *errbuf);
|
||||
int pcap_findalldevs_ex_remote(const char *source,
|
||||
struct pcap_rmtauth *auth, pcap_if_t **alldevs, char *errbuf);
|
||||
|
||||
#endif
|
||||
|
@ -130,4 +130,4 @@ the packet not been truncated by the snapshot length. The two lengths
|
||||
will be equal if the number of bytes of packet data are less than or
|
||||
equal to the snapshot length.
|
||||
.SH SEE ALSO
|
||||
pcap(3PCAP), pcap-linktype(@MAN_MISC_INFO@)
|
||||
pcap(3PCAP)
|
||||
|
@ -1,15 +1,6 @@
|
||||
/*
|
||||
* pcap-septel.c: Packet capture interface for Intel/Septel card.
|
||||
*
|
||||
* The functionality of this code attempts to mimic that of pcap-linux as much
|
||||
* as possible. This code is compiled in several different ways depending on
|
||||
* whether SEPTEL_ONLY and HAVE_SEPTEL_API are defined. If HAVE_SEPTEL_API is
|
||||
* not defined it should not get compiled in, otherwise if SEPTEL_ONLY is
|
||||
* defined then the 'septel_' function calls are renamed to 'pcap_'
|
||||
* equivalents. If SEPTEL_ONLY is not defined then nothing is altered - the
|
||||
* septel_ functions will be called as required from their
|
||||
* pcap-linux/equivalents.
|
||||
*
|
||||
* Authors: Gilbert HOYEK (gil_hoyek@hotmail.com), Elias M. KHOURY
|
||||
* (+961 3 485243)
|
||||
*/
|
||||
@ -182,7 +173,7 @@ static int septel_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
static int
|
||||
septel_inject(pcap_t *handle, const void *buf _U_, size_t size _U_)
|
||||
{
|
||||
strlcpy(handle->errbuf, "Sending packets isn't supported on Septel cards",
|
||||
pcap_strlcpy(handle->errbuf, "Sending packets isn't supported on Septel cards",
|
||||
PCAP_ERRBUF_SIZE);
|
||||
return (-1);
|
||||
}
|
||||
|
@ -884,7 +884,7 @@ static void acn_start_monitor(int fd, int snaplen, int timeout, int promiscuous,
|
||||
}
|
||||
|
||||
static int pcap_inject_acn(pcap_t *p, const void *buf _U_, size_t size _U_) {
|
||||
strlcpy(p->errbuf, "Sending packets isn't supported on ACN adapters",
|
||||
pcap_strlcpy(p->errbuf, "Sending packets isn't supported on ACN adapters",
|
||||
PCAP_ERRBUF_SIZE);
|
||||
return (-1);
|
||||
}
|
||||
|
@ -411,7 +411,7 @@ A { text-decoration:none }
|
||||
<TR>
|
||||
<TD VALIGN=TOP>Interface ID</TD>
|
||||
<TD VALIGN=TOP ALIGN=CENTER>1</TD>
|
||||
<TD VALIGN=TOP>A NULL to indicate an an empty 'interface ID'.</TD>
|
||||
<TD VALIGN=TOP>A NULL to indicate an empty 'interface ID'.</TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
</TD>
|
||||
|
@ -182,8 +182,8 @@ snf_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
hdr.caplen = caplen;
|
||||
hdr.len = req.length;
|
||||
callback(user, &hdr, req.pkt_addr);
|
||||
n++;
|
||||
}
|
||||
n++;
|
||||
|
||||
/* After one successful packet is received, we won't block
|
||||
* again for that timeout. */
|
||||
@ -237,7 +237,7 @@ snf_inject(pcap_t *p, const void *buf _U_, size_t size _U_)
|
||||
return (-1);
|
||||
}
|
||||
#else
|
||||
strlcpy(p->errbuf, "Sending packets isn't supported with this snf version",
|
||||
pcap_strlcpy(p->errbuf, "Sending packets isn't supported with this snf version",
|
||||
PCAP_ERRBUF_SIZE);
|
||||
return (-1);
|
||||
#endif
|
||||
|
23
pcap-tc.c
23
pcap-tc.c
@ -123,7 +123,7 @@ static int TcSetDatalink(pcap_t *p, int dlt);
|
||||
static int TcGetNonBlock(pcap_t *p);
|
||||
static int TcSetNonBlock(pcap_t *p, int nonblock);
|
||||
static void TcCleanup(pcap_t *p);
|
||||
static int TcInject(pcap_t *p, const void *buf, size_t size);
|
||||
static int TcInject(pcap_t *p, const void *buf, int size);
|
||||
static int TcRead(pcap_t *p, int cnt, pcap_handler callback, u_char *user);
|
||||
static int TcStats(pcap_t *p, struct pcap_stat *ps);
|
||||
static int TcSetFilter(pcap_t *p, struct bpf_program *fp);
|
||||
@ -440,7 +440,7 @@ TcFindAllDevs(pcap_if_list_t *devlist, char *errbuf)
|
||||
PTC_PORT pPorts = NULL;
|
||||
TC_STATUS status;
|
||||
int result = 0;
|
||||
pcap_if_t *dev, *cursor;
|
||||
pcap_if_t *dev;
|
||||
ULONG i;
|
||||
|
||||
do
|
||||
@ -472,22 +472,7 @@ TcFindAllDevs(pcap_if_list_t *devlist, char *errbuf)
|
||||
dev = TcCreatePcapIfFromPort(pPorts[i]);
|
||||
|
||||
if (dev != NULL)
|
||||
{
|
||||
/*
|
||||
* append it at the end
|
||||
*/
|
||||
if (devlistp->beginning == NULL)
|
||||
{
|
||||
devlistp->beginning = dev;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (cursor = devlistp->beginning;
|
||||
cursor->next != NULL;
|
||||
cursor = cursor->next);
|
||||
cursor->next = dev;
|
||||
}
|
||||
}
|
||||
add_dev(devlist, dev->name, dev->flags, dev->description, errbuf);
|
||||
}
|
||||
|
||||
if (numPorts > 0)
|
||||
@ -846,7 +831,7 @@ static void TcCleanup(pcap_t *p)
|
||||
}
|
||||
|
||||
/* Send a packet to the network */
|
||||
static int TcInject(pcap_t *p, const void *buf, size_t size)
|
||||
static int TcInject(pcap_t *p, const void *buf, int size)
|
||||
{
|
||||
struct pcap_tc *pt = p->priv;
|
||||
TC_STATUS status;
|
||||
|
@ -93,9 +93,9 @@ call and before a
|
||||
call to specify the type of time stamp to be used on the device.
|
||||
The time stamp types are listed here; the first value is the #define to
|
||||
use in code, the second value is the value returned by
|
||||
.B pcap_tstamp_type_val_to_name()
|
||||
.B pcap_tstamp_type_val_to_name(3PCAP)
|
||||
and accepted by
|
||||
.BR pcap_tstamp_type_name_to_val() .
|
||||
.BR pcap_tstamp_type_name_to_val(3PCAP) .
|
||||
.RS 5
|
||||
.TP 5
|
||||
.BR PCAP_TSTAMP_HOST " - " host
|
||||
@ -149,9 +149,9 @@ call will fail, and the time stamps supplied after the
|
||||
call will have microsecond resolution.
|
||||
.LP
|
||||
When opening a savefile, the
|
||||
.BR pcap_open_offline_with_tstamp_precision (3PCAP)
|
||||
.BR \%pcap_open_offline_with_tstamp_precision (3PCAP)
|
||||
and
|
||||
.BR pcap_fopen_offline_with_tstamp_precision (3PCAP)
|
||||
.BR \%pcap_fopen_offline_with_tstamp_precision (3PCAP)
|
||||
routines can be used to specify the resolution of time stamps to be read
|
||||
from the file; if the time stamps in the file have a lower resolution,
|
||||
the fraction-of-a-second portion of the time stamps will be scaled to
|
||||
@ -165,13 +165,4 @@ the time stamp supplied by the hardware or operating system and, when
|
||||
reading a savefile, this does not indicate the actual precision of time
|
||||
stamps in the file.
|
||||
.SH SEE ALSO
|
||||
.na
|
||||
pcap_set_tstamp_type(3PCAP),
|
||||
pcap_list_tstamp_types(3PCAP),
|
||||
pcap_tstamp_type_val_to_name(3PCAP),
|
||||
pcap_tstamp_type_name_to_val(3PCAP),
|
||||
pcap_set_tstamp_precision(3PCAP),
|
||||
pcap_open_offline_with_tstamp_precision(3PCAP),
|
||||
\%pcap_fopen_offline_with_tstamp_precision(3PCAP),
|
||||
\%pcap_get_tstamp_precision(3PCAP)
|
||||
.ad
|
||||
pcap(3PCAP)
|
||||
|
273
pcap-usb-linux.c
273
pcap-usb-linux.c
@ -50,6 +50,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <dirent.h>
|
||||
#include <byteswap.h>
|
||||
@ -241,7 +242,7 @@ usb_dev_add(pcap_if_list_t *devlistp, int n, char *err_str)
|
||||
*/
|
||||
if (add_dev(devlistp, dev_name,
|
||||
PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE,
|
||||
"All USB buses", err_str) == NULL)
|
||||
"Raw USB traffic, all USB buses", err_str) == NULL)
|
||||
return -1;
|
||||
} else {
|
||||
/*
|
||||
@ -250,7 +251,7 @@ usb_dev_add(pcap_if_list_t *devlistp, int n, char *err_str)
|
||||
* PCAP_IF_CONNECTION_STATUS_CONNECTED or
|
||||
* PCAP_IF_CONNECTION_STATUS_DISCONNECTED?
|
||||
*/
|
||||
pcap_snprintf(dev_descr, 30, "USB bus number %d", n);
|
||||
pcap_snprintf(dev_descr, 30, "Raw USB traffic, bus number %d", n);
|
||||
if (add_dev(devlistp, dev_name, 0, dev_descr, err_str) == NULL)
|
||||
return -1;
|
||||
}
|
||||
@ -278,7 +279,7 @@ usb_findalldevs(pcap_if_list_t *devlistp, char *err_str)
|
||||
* Split LINUX_USB_MON_DEV into a directory that we'll
|
||||
* scan and a file name prefix that we'll check for.
|
||||
*/
|
||||
strlcpy(usb_mon_dir, LINUX_USB_MON_DEV, sizeof usb_mon_dir);
|
||||
pcap_strlcpy(usb_mon_dir, LINUX_USB_MON_DEV, sizeof usb_mon_dir);
|
||||
usb_mon_prefix = strrchr(usb_mon_dir, '/');
|
||||
if (usb_mon_prefix == NULL) {
|
||||
/*
|
||||
@ -380,18 +381,102 @@ usb_findalldevs(pcap_if_list_t *devlistp, char *err_str)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Matches what's in mon_bin.c in the Linux kernel.
|
||||
*/
|
||||
#define MIN_RING_SIZE (8*1024)
|
||||
#define MAX_RING_SIZE (1200*1024)
|
||||
|
||||
static int
|
||||
usb_set_ring_size(pcap_t* handle, int header_size)
|
||||
{
|
||||
/*
|
||||
* A packet from binary usbmon has:
|
||||
*
|
||||
* 1) a fixed-length header, of size header_size;
|
||||
* 2) descriptors, for isochronous transfers;
|
||||
* 3) the payload.
|
||||
*
|
||||
* The kernel buffer has a size, defaulting to 300KB, with a
|
||||
* minimum of 8KB and a maximum of 1200KB. The size is set with
|
||||
* the MON_IOCT_RING_SIZE ioctl; the size passed in is rounded up
|
||||
* to a page size.
|
||||
*
|
||||
* No more than {buffer size}/5 bytes worth of payload is saved.
|
||||
* Therefore, if we subtract the fixed-length size from the
|
||||
* snapshot length, we have the biggest payload we want (we
|
||||
* don't worry about the descriptors - if we have descriptors,
|
||||
* we'll just discard the last bit of the payload to get it
|
||||
* to fit). We multiply that result by 5 and set the buffer
|
||||
* size to that value.
|
||||
*/
|
||||
int ring_size;
|
||||
|
||||
if (handle->snapshot < header_size)
|
||||
handle->snapshot = header_size;
|
||||
/* The maximum snapshot size is small enough that this won't overflow */
|
||||
ring_size = (handle->snapshot - header_size) * 5;
|
||||
|
||||
/*
|
||||
* Will this get an error?
|
||||
* (There's no wqy to query the minimum or maximum, so we just
|
||||
* copy the value from the kernel source. We don't round it
|
||||
* up to a multiple of the page size.)
|
||||
*/
|
||||
if (ring_size > MAX_RING_SIZE) {
|
||||
/*
|
||||
* Yes. Lower the ring size to the maximum, and set the
|
||||
* snapshot length to the value that would give us a
|
||||
* maximum-size ring.
|
||||
*/
|
||||
ring_size = MAX_RING_SIZE;
|
||||
handle->snapshot = header_size + (MAX_RING_SIZE/5);
|
||||
} else if (ring_size < MIN_RING_SIZE) {
|
||||
/*
|
||||
* Yes. Raise the ring size to the minimum, but leave
|
||||
* the snapshot length unchanged, so we show the
|
||||
* callback no more data than specified by the
|
||||
* snapshot length.
|
||||
*/
|
||||
ring_size = MIN_RING_SIZE;
|
||||
}
|
||||
|
||||
if (ioctl(handle->fd, MON_IOCT_RING_SIZE, ring_size) == -1) {
|
||||
pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
errno, "Can't set ring size from fd %d", handle->fd);
|
||||
return -1;
|
||||
}
|
||||
return ring_size;
|
||||
}
|
||||
|
||||
static
|
||||
int usb_mmap(pcap_t* handle)
|
||||
{
|
||||
struct pcap_usb_linux *handlep = handle->priv;
|
||||
int len = ioctl(handle->fd, MON_IOCQ_RING_SIZE);
|
||||
if (len < 0)
|
||||
int len;
|
||||
|
||||
/*
|
||||
* Attempt to set the ring size as appropriate for the snapshot
|
||||
* length, reducing the snapshot length if that'd make the ring
|
||||
* bigger than the kernel supports.
|
||||
*/
|
||||
len = usb_set_ring_size(handle, (int)sizeof(pcap_usb_header_mmapped));
|
||||
if (len == -1) {
|
||||
/* Failed. Fall back on non-memory-mapped access. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
handlep->mmapbuflen = len;
|
||||
handlep->mmapbuf = mmap(0, handlep->mmapbuflen, PROT_READ,
|
||||
MAP_SHARED, handle->fd, 0);
|
||||
return handlep->mmapbuf != MAP_FAILED;
|
||||
if (handlep->mmapbuf == MAP_FAILED) {
|
||||
/*
|
||||
* Failed. We don't treat that as a fatal error, we
|
||||
* just try to fall back on non-memory-mapped access.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LINUX_USBDEVICE_FS_H
|
||||
@ -514,6 +599,7 @@ usb_activate(pcap_t* handle)
|
||||
{
|
||||
struct pcap_usb_linux *handlep = handle->priv;
|
||||
char full_path[USB_LINE_LEN];
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Turn a negative snapshot value (invalid), a snapshot value of
|
||||
@ -604,6 +690,7 @@ usb_activate(pcap_t* handle)
|
||||
/* try to use fast mmap access */
|
||||
if (usb_mmap(handle))
|
||||
{
|
||||
/* We succeeded. */
|
||||
handle->linktype = DLT_USB_LINUX_MMAPPED;
|
||||
handle->stats_op = usb_stats_linux_bin;
|
||||
handle->read_op = usb_read_linux_mmap;
|
||||
@ -620,7 +707,19 @@ usb_activate(pcap_t* handle)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* can't mmap, use plain binary interface access */
|
||||
/*
|
||||
* We failed; try plain binary interface access.
|
||||
*
|
||||
* Attempt to set the ring size as appropriate for
|
||||
* the snapshot length, reducing the snapshot length
|
||||
* if that'd make the ring bigger than the kernel
|
||||
* supports.
|
||||
*/
|
||||
if (usb_set_ring_size(handle, (int)sizeof(pcap_usb_header)) == -1) {
|
||||
/* Failed. */
|
||||
close(handle->fd);
|
||||
return PCAP_ERROR;
|
||||
}
|
||||
handle->stats_op = usb_stats_linux_bin;
|
||||
handle->read_op = usb_read_linux_bin;
|
||||
#ifdef HAVE_LINUX_USBDEVICE_FS_H
|
||||
@ -646,38 +745,38 @@ usb_activate(pcap_t* handle)
|
||||
handle->fd = open(full_path, O_RDONLY, 0);
|
||||
}
|
||||
if (handle->fd < 0) {
|
||||
/*
|
||||
* Is the problem that we didn't have
|
||||
* sufficient permission to open it?
|
||||
*/
|
||||
if (errno == EACCES) {
|
||||
if (errno == ENOENT)
|
||||
{
|
||||
/*
|
||||
* Yes - return that error.
|
||||
* The problem is that the file
|
||||
* doesn't exist. Report that as
|
||||
* "no such device". (That could
|
||||
* mean "no such USB bus" or
|
||||
* "monitoring not supported".)
|
||||
*/
|
||||
return PCAP_ERROR_PERM_DENIED;
|
||||
ret = PCAP_ERROR_NO_SUCH_DEVICE;
|
||||
}
|
||||
|
||||
/*
|
||||
* No - was the problem something other
|
||||
* than "it doesn't exist"?
|
||||
*/
|
||||
if (errno != ENOENT) {
|
||||
else if (errno == EACCES)
|
||||
{
|
||||
/*
|
||||
* Yes - return *that* error.
|
||||
* The problem is that we don't
|
||||
* have sufficient permission to
|
||||
* open the file. Report that.
|
||||
*/
|
||||
pcap_fmt_errmsg_for_errno(handle->errbuf,
|
||||
PCAP_ERRBUF_SIZE, errno,
|
||||
"Can't open USB bus file %s",
|
||||
full_path);
|
||||
return PCAP_ERROR;
|
||||
ret = PCAP_ERROR_PERM_DENIED;
|
||||
}
|
||||
|
||||
/*
|
||||
* No. Report that as "no such device".
|
||||
* (That could mean "no such USB bus"
|
||||
* or "monitoring not supported".)
|
||||
*/
|
||||
return PCAP_ERROR_NO_SUCH_DEVICE;
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Some other error.
|
||||
*/
|
||||
ret = PCAP_ERROR;
|
||||
}
|
||||
pcap_fmt_errmsg_for_errno(handle->errbuf,
|
||||
PCAP_ERRBUF_SIZE, errno,
|
||||
"Can't open USB bus file %s",
|
||||
full_path);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
@ -923,8 +1022,8 @@ usb_read_linux(pcap_t *handle, int max_packets _U_, pcap_handler callback, u_cha
|
||||
static int
|
||||
usb_inject_linux(pcap_t *handle, const void *buf _U_, size_t size _U_)
|
||||
{
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "inject not supported on "
|
||||
"USB devices");
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Packet injection is not supported on USB devices");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
@ -973,6 +1072,10 @@ usb_stats_linux(pcap_t *handle, struct pcap_stat *stats)
|
||||
}
|
||||
string[ret] = 0;
|
||||
|
||||
stats->ps_recv = handlep->packets_read;
|
||||
stats->ps_drop = 0; /* unless we find text_lost */
|
||||
stats->ps_ifdrop = 0;
|
||||
|
||||
/* extract info on dropped urbs */
|
||||
for (consumed=0; consumed < ret; ) {
|
||||
/* from the sscanf man page:
|
||||
@ -989,18 +1092,16 @@ usb_stats_linux(pcap_t *handle, struct pcap_stat *stats)
|
||||
break;
|
||||
consumed += cnt;
|
||||
ptr += cnt;
|
||||
if (strcmp(token, "nreaders") == 0)
|
||||
ret = sscanf(ptr, "%d", &stats->ps_drop);
|
||||
if (strcmp(token, "text_lost") == 0)
|
||||
ntok = sscanf(ptr, "%d%n", &stats->ps_drop, &cnt);
|
||||
else
|
||||
ret = sscanf(ptr, "%d", &dummy);
|
||||
if (ntok != 1)
|
||||
ntok = sscanf(ptr, "%d%n", &dummy, &cnt);
|
||||
if ((ntok != 1) || (cnt < 0))
|
||||
break;
|
||||
consumed += cnt;
|
||||
ptr += cnt;
|
||||
}
|
||||
|
||||
stats->ps_recv = handlep->packets_read;
|
||||
stats->ps_ifdrop = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1069,13 +1170,44 @@ usb_read_linux_bin(pcap_t *handle, int max_packets _U_, pcap_handler callback, u
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* we can get less that than really captured from kernel, depending on
|
||||
* snaplen, so adjust header accordingly */
|
||||
/*
|
||||
* info.hdr->data_len is the number of bytes of isochronous
|
||||
* descriptors (if any) plus the number of bytes of data
|
||||
* provided. There are no isochronous descriptors here,
|
||||
* because we're using the old 48-byte header.
|
||||
*
|
||||
* If info.hdr->data_flag is non-zero, there's no URB data;
|
||||
* info.hdr->urb_len is the size of the buffer into which
|
||||
* data is to be placed; it does not represent the amount
|
||||
* of data transferred. If info.hdr->data_flag is zero,
|
||||
* there is URB data, and info.hdr->urb_len is the number
|
||||
* of bytes transmitted or received; it doesn't include
|
||||
* isochronous descriptors.
|
||||
*
|
||||
* The kernel may give us more data than the snaplen; if it did,
|
||||
* reduce the data length so that the total number of bytes we
|
||||
* tell our client we have is not greater than the snaplen.
|
||||
*/
|
||||
if (info.hdr->data_len < clen)
|
||||
clen = info.hdr->data_len;
|
||||
info.hdr->data_len = clen;
|
||||
pkth.caplen = clen + sizeof(pcap_usb_header);
|
||||
pkth.len = info.hdr->data_len + sizeof(pcap_usb_header);
|
||||
pkth.caplen = sizeof(pcap_usb_header) + clen;
|
||||
if (info.hdr->data_flag) {
|
||||
/*
|
||||
* No data; just base the on-the-wire length on
|
||||
* info.hdr->data_len (so that it's >= the captured
|
||||
* length).
|
||||
*/
|
||||
pkth.len = sizeof(pcap_usb_header) + info.hdr->data_len;
|
||||
} else {
|
||||
/*
|
||||
* We got data; base the on-the-wire length on
|
||||
* info.hdr->urb_len, so that it includes data
|
||||
* discarded by the USB monitor device due to
|
||||
* its buffer being too small.
|
||||
*/
|
||||
pkth.len = sizeof(pcap_usb_header) + info.hdr->urb_len;
|
||||
}
|
||||
pkth.ts.tv_sec = info.hdr->ts_sec;
|
||||
pkth.ts.tv_usec = info.hdr->ts_usec;
|
||||
|
||||
@ -1102,12 +1234,12 @@ usb_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback, u_ch
|
||||
struct mon_bin_mfetch fetch;
|
||||
int32_t vec[VEC_SIZE];
|
||||
struct pcap_pkthdr pkth;
|
||||
pcap_usb_header* hdr;
|
||||
pcap_usb_header_mmapped* hdr;
|
||||
int nflush = 0;
|
||||
int packets = 0;
|
||||
u_int clen, max_clen;
|
||||
|
||||
max_clen = handle->snapshot - sizeof(pcap_usb_header);
|
||||
max_clen = handle->snapshot - sizeof(pcap_usb_header_mmapped);
|
||||
|
||||
for (;;) {
|
||||
int i, ret;
|
||||
@ -1145,19 +1277,52 @@ usb_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback, u_ch
|
||||
nflush = fetch.nfetch;
|
||||
for (i=0; i<fetch.nfetch; ++i) {
|
||||
/* discard filler */
|
||||
hdr = (pcap_usb_header*) &handlep->mmapbuf[vec[i]];
|
||||
hdr = (pcap_usb_header_mmapped*) &handlep->mmapbuf[vec[i]];
|
||||
if (hdr->event_type == '@')
|
||||
continue;
|
||||
|
||||
/* we can get less that than really captured from kernel, depending on
|
||||
* snaplen, so adjust header accordingly */
|
||||
/*
|
||||
* hdr->data_len is the number of bytes of
|
||||
* isochronous descriptors (if any) plus the
|
||||
* number of bytes of data provided.
|
||||
*
|
||||
* If hdr->data_flag is non-zero, there's no
|
||||
* URB data; hdr->urb_len is the size of the
|
||||
* buffer into which data is to be placed; it does
|
||||
* not represent the amount of data transferred.
|
||||
* If hdr->data_flag is zero, there is URB data,
|
||||
* and hdr->urb_len is the number of bytes
|
||||
* transmitted or received; it doesn't include
|
||||
* isochronous descriptors.
|
||||
*
|
||||
* The kernel may give us more data than the
|
||||
* snaplen; if it did, reduce the data length
|
||||
* so that the total number of bytes we
|
||||
* tell our client we have is not greater than
|
||||
* the snaplen.
|
||||
*/
|
||||
clen = max_clen;
|
||||
if (hdr->data_len < clen)
|
||||
clen = hdr->data_len;
|
||||
|
||||
/* get packet info from header*/
|
||||
pkth.caplen = clen + sizeof(pcap_usb_header_mmapped);
|
||||
pkth.len = hdr->data_len + sizeof(pcap_usb_header_mmapped);
|
||||
pkth.caplen = sizeof(pcap_usb_header_mmapped) + clen;
|
||||
if (hdr->data_flag) {
|
||||
/*
|
||||
* No data; just base the on-the-wire length
|
||||
* on hdr->data_len (so that it's >= the
|
||||
* captured length).
|
||||
*/
|
||||
pkth.len = sizeof(pcap_usb_header_mmapped) +
|
||||
hdr->data_len;
|
||||
} else {
|
||||
/*
|
||||
* We got data; base the on-the-wire length
|
||||
* on hdr->urb_len, so that it includes
|
||||
* data discarded by the USB monitor device
|
||||
* due to its buffer being too small.
|
||||
*/
|
||||
pkth.len = sizeof(pcap_usb_header_mmapped) +
|
||||
(hdr->ndesc * sizeof (usb_isodesc)) + hdr->urb_len;
|
||||
}
|
||||
pkth.ts.tv_sec = hdr->ts_sec;
|
||||
pkth.ts.tv_usec = hdr->ts_usec;
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
.\"
|
||||
.TH PCAP 3PCAP "20 January 2017"
|
||||
.TH PCAP 3PCAP "25 July 2018"
|
||||
.SH NAME
|
||||
pcap \- Packet Capture library
|
||||
.SH SYNOPSIS
|
||||
@ -181,7 +181,7 @@ negative value is unpredictable.
|
||||
the packet buffer timeout cannot be used to cause calls that read
|
||||
packets to return within a limited period of time, because, on some
|
||||
platforms, the packet buffer timeout isn't supported, and, on other
|
||||
platforms, the timer doesn't start until at least one packet arrives.
|
||||
platforms, the timer doesn't start until at least one packet arrives.
|
||||
This means that the packet buffer timeout should
|
||||
.B NOT
|
||||
be used, for example, in an interactive application to allow the packet
|
||||
@ -191,6 +191,10 @@ expires even if no packets have arrived.
|
||||
.IP
|
||||
The packet buffer timeout is set with
|
||||
.BR pcap_set_timeout ().
|
||||
.IP "immediate mode"
|
||||
In immediate mode, packets are always delivered as soon as they arrive,
|
||||
with no buffering. Immediate mode is set with
|
||||
.BR pcap_set_immediate_mode ().
|
||||
.IP "buffer size"
|
||||
Packets that arrive for a capture are stored in a buffer, so that they
|
||||
do not have to be read by the application as soon as they arrive. On
|
||||
@ -304,7 +308,7 @@ link-layer header whose contents can differ for different network
|
||||
interfaces. To determine the format of the packets supplied by the
|
||||
handle, call
|
||||
.BR pcap_datalink ();
|
||||
.I http://www.tcpdump.org/linktypes.html
|
||||
.I https://www.tcpdump.org/linktypes.html
|
||||
lists the values it returns and describes the packet formats that
|
||||
correspond to those values.
|
||||
.PP
|
||||
@ -396,7 +400,7 @@ set promiscuous mode for a not-yet-activated
|
||||
.B pcap_t
|
||||
for live capture
|
||||
.TP
|
||||
.BR pcap_set_protocol (3PCAP)
|
||||
.BR pcap_set_protocol_linux (3PCAP)
|
||||
set capture protocol for a not-yet-activated
|
||||
.B pcap_t
|
||||
for live capture (Linux only)
|
||||
@ -416,6 +420,11 @@ set packet buffer timeout for a not-yet-activated
|
||||
.B pcap_t
|
||||
for live capture
|
||||
.TP
|
||||
.BR pcap_set_immediate_mode (3PCAP)
|
||||
set immediate mode for a not-yet-activated
|
||||
.B pcap_t
|
||||
for live capture
|
||||
.TP
|
||||
.BR pcap_set_buffer_size (3PCAP)
|
||||
set buffer size for a not-yet-activated
|
||||
.B pcap_t
|
||||
@ -632,9 +641,28 @@ or other routines a platform offers to wait for any of a set of
|
||||
descriptors to be ready to read. To obtain, for a handle, a descriptor
|
||||
that can be used in those routines, call
|
||||
.BR pcap_get_selectable_fd ().
|
||||
If the routine indicates that data is
|
||||
available to read on the descriptor, an attempt should be made to read
|
||||
from the device.
|
||||
.PP
|
||||
Not all handles have such a descriptor available;
|
||||
.BR pcap_get_selectable_fd ()
|
||||
will return \-1 if no such descriptor exists. In addition, for various
|
||||
will return
|
||||
.B PCAP_ERROR
|
||||
if no such descriptor is available. If no such
|
||||
descriptor is available, this may be because the device must be polled
|
||||
periodically for packets; in that case,
|
||||
.BR pcap_get_required_select_timeout ()
|
||||
will return a pointer to a
|
||||
.B struct timeval
|
||||
whose value can be used as a timeout in those routines. When the
|
||||
routine returns, an attmept should be made to read packets from the
|
||||
device. If
|
||||
.BR pcap_get_required_select_timeout ()
|
||||
returns NULL, no such timeout is available, and those routines cannot be
|
||||
used with the device.
|
||||
.PP
|
||||
In addition, for various
|
||||
reasons, one or more of those routines will not work properly with the
|
||||
descriptor; the documentation for
|
||||
.BR pcap_get_selectable_fd ()
|
||||
@ -693,6 +721,15 @@ that can be used in calls such as
|
||||
.BR select (2)
|
||||
and
|
||||
.BR poll (2)
|
||||
.TP
|
||||
.BR pcap_get_required_select_timeout (3PCAP)
|
||||
if no descriptor usable with
|
||||
.BR select (2)
|
||||
and
|
||||
.BR poll (2)
|
||||
is available for the
|
||||
.BR pcap_t ,
|
||||
attempt to get a timeout usable with those routines
|
||||
.RE
|
||||
.SS Filters
|
||||
In order to cause only certain packets to be returned when reading
|
||||
@ -890,7 +927,7 @@ To get a string giving version information about libpcap, call
|
||||
.BR pcap_lib_version (3PCAP)
|
||||
get library version string
|
||||
.RE
|
||||
.SH BACKWARDS COMPATIBILITY
|
||||
.SH BACKWARD COMPATIBILITY
|
||||
.PP
|
||||
In versions of libpcap prior to 1.0, the
|
||||
.B pcap.h
|
||||
@ -934,7 +971,7 @@ Lawrence Berkeley National Laboratory, University of California, Berkeley, CA.
|
||||
The current version is available from "The Tcpdump Group"'s Web site at
|
||||
.LP
|
||||
.RS
|
||||
.I http://www.tcpdump.org/
|
||||
.I https://www.tcpdump.org/
|
||||
.RE
|
||||
.SH BUGS
|
||||
To report a security issue please send an e-mail to security@tcpdump.org.
|
||||
|
407
pcap.c
407
pcap.c
@ -139,7 +139,7 @@ BOOL WINAPI DllMain(
|
||||
|
||||
/*
|
||||
* Start WinSock.
|
||||
* Exported in case some applications using WinPcap called it,
|
||||
* Exported in case some applications using WinPcap/Npcap called it,
|
||||
* even though it wasn't exported.
|
||||
*/
|
||||
int
|
||||
@ -186,76 +186,165 @@ pcap_wsockinit(void)
|
||||
PCAP_API char pcap_version[];
|
||||
PCAP_API_DEF char pcap_version[] = PACKAGE_VERSION;
|
||||
|
||||
static int
|
||||
pcap_not_initialized(pcap_t *pcap)
|
||||
static void
|
||||
pcap_set_not_initialized_message(pcap_t *pcap)
|
||||
{
|
||||
if (pcap->activated) {
|
||||
/* A module probably forgot to set the function pointer */
|
||||
(void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf),
|
||||
"This operation isn't properly handled by that device");
|
||||
return (PCAP_ERROR);
|
||||
return;
|
||||
}
|
||||
/* in case the caller doesn't check for PCAP_ERROR_NOT_ACTIVATED */
|
||||
(void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf),
|
||||
"This handle hasn't been activated yet");
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_read_not_initialized(pcap_t *pcap, int cnt _U_, pcap_handler callback _U_,
|
||||
u_char *user _U_)
|
||||
{
|
||||
pcap_set_not_initialized_message(pcap);
|
||||
/* this means 'not initialized' */
|
||||
return (PCAP_ERROR_NOT_ACTIVATED);
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_inject_not_initialized(pcap_t *pcap, const void * buf _U_, size_t size _U_)
|
||||
{
|
||||
pcap_set_not_initialized_message(pcap);
|
||||
/* this means 'not initialized' */
|
||||
return (PCAP_ERROR_NOT_ACTIVATED);
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_setfilter_not_initialized(pcap_t *pcap, struct bpf_program *fp _U_)
|
||||
{
|
||||
pcap_set_not_initialized_message(pcap);
|
||||
/* this means 'not initialized' */
|
||||
return (PCAP_ERROR_NOT_ACTIVATED);
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_setdirection_not_initialized(pcap_t *pcap, pcap_direction_t d _U_)
|
||||
{
|
||||
pcap_set_not_initialized_message(pcap);
|
||||
/* this means 'not initialized' */
|
||||
return (PCAP_ERROR_NOT_ACTIVATED);
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_set_datalink_not_initialized(pcap_t *pcap, int dlt _U_)
|
||||
{
|
||||
pcap_set_not_initialized_message(pcap);
|
||||
/* this means 'not initialized' */
|
||||
return (PCAP_ERROR_NOT_ACTIVATED);
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_getnonblock_not_initialized(pcap_t *pcap)
|
||||
{
|
||||
pcap_set_not_initialized_message(pcap);
|
||||
/* this means 'not initialized' */
|
||||
return (PCAP_ERROR_NOT_ACTIVATED);
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_stats_not_initialized(pcap_t *pcap, struct pcap_stat *ps _U_)
|
||||
{
|
||||
pcap_set_not_initialized_message(pcap);
|
||||
/* this means 'not initialized' */
|
||||
return (PCAP_ERROR_NOT_ACTIVATED);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
static void *
|
||||
pcap_not_initialized_ptr(pcap_t *pcap)
|
||||
struct pcap_stat *
|
||||
pcap_stats_ex_not_initialized(pcap_t *pcap, int *pcap_stat_size _U_)
|
||||
{
|
||||
if (pcap->activated) {
|
||||
/* A module probably forgot to set the function pointer */
|
||||
(void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf),
|
||||
"This operation isn't properly handled by that device");
|
||||
return (NULL);
|
||||
}
|
||||
(void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf),
|
||||
"This handle hasn't been activated yet");
|
||||
pcap_set_not_initialized_message(pcap);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_setbuff_not_initialized(pcap_t *pcap, int dim _U_)
|
||||
{
|
||||
pcap_set_not_initialized_message(pcap);
|
||||
/* this means 'not initialized' */
|
||||
return (PCAP_ERROR_NOT_ACTIVATED);
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_setmode_not_initialized(pcap_t *pcap, int mode _U_)
|
||||
{
|
||||
pcap_set_not_initialized_message(pcap);
|
||||
/* this means 'not initialized' */
|
||||
return (PCAP_ERROR_NOT_ACTIVATED);
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_setmintocopy_not_initialized(pcap_t *pcap, int size _U_)
|
||||
{
|
||||
pcap_set_not_initialized_message(pcap);
|
||||
/* this means 'not initialized' */
|
||||
return (PCAP_ERROR_NOT_ACTIVATED);
|
||||
}
|
||||
|
||||
static HANDLE
|
||||
pcap_getevent_not_initialized(pcap_t *pcap)
|
||||
{
|
||||
if (pcap->activated) {
|
||||
/* A module probably forgot to set the function pointer */
|
||||
(void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf),
|
||||
"This operation isn't properly handled by that device");
|
||||
return (INVALID_HANDLE_VALUE);
|
||||
}
|
||||
(void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf),
|
||||
"This handle hasn't been activated yet");
|
||||
pcap_set_not_initialized_message(pcap);
|
||||
return (INVALID_HANDLE_VALUE);
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_oid_get_request_not_initialized(pcap_t *pcap, bpf_u_int32 oid _U_,
|
||||
void *data _U_, size_t *lenp _U_)
|
||||
{
|
||||
pcap_set_not_initialized_message(pcap);
|
||||
return (PCAP_ERROR_NOT_ACTIVATED);
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_oid_set_request_not_initialized(pcap_t *pcap, bpf_u_int32 oid _U_,
|
||||
const void *data _U_, size_t *lenp _U_)
|
||||
{
|
||||
pcap_set_not_initialized_message(pcap);
|
||||
return (PCAP_ERROR_NOT_ACTIVATED);
|
||||
}
|
||||
|
||||
static u_int
|
||||
pcap_sendqueue_transmit_not_initialized(pcap_t *pcap, pcap_send_queue* queue, int sync)
|
||||
{
|
||||
if (pcap->activated) {
|
||||
/* A module probably forgot to set the function pointer */
|
||||
(void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf),
|
||||
"This operation isn't properly handled by that device");
|
||||
return (0);
|
||||
}
|
||||
(void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf),
|
||||
"This handle hasn't been activated yet");
|
||||
pcap_set_not_initialized_message(pcap);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_setuserbuffer_not_initialized(pcap_t *pcap, int size _U_)
|
||||
{
|
||||
pcap_set_not_initialized_message(pcap);
|
||||
return (PCAP_ERROR_NOT_ACTIVATED);
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_live_dump_not_initialized(pcap_t *pcap, char *filename _U_, int maxsize _U_,
|
||||
int maxpacks _U_)
|
||||
{
|
||||
pcap_set_not_initialized_message(pcap);
|
||||
return (PCAP_ERROR_NOT_ACTIVATED);
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_live_dump_ended_not_initialized(pcap_t *pcap, int sync _U_)
|
||||
{
|
||||
pcap_set_not_initialized_message(pcap);
|
||||
return (PCAP_ERROR_NOT_ACTIVATED);
|
||||
}
|
||||
|
||||
static PAirpcapHandle
|
||||
pcap_get_airpcap_handle_not_initialized(pcap_t *pcap)
|
||||
{
|
||||
if (pcap->activated) {
|
||||
/* A module probably forgot to set the function pointer */
|
||||
(void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf),
|
||||
"This operation isn't properly handled by that device");
|
||||
return (NULL);
|
||||
}
|
||||
(void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf),
|
||||
"This handle hasn't been activated yet");
|
||||
pcap_set_not_initialized_message(pcap);
|
||||
return (NULL);
|
||||
}
|
||||
#endif
|
||||
@ -296,8 +385,17 @@ pcap_list_tstamp_types(pcap_t *p, int **tstamp_typesp)
|
||||
if (p->tstamp_type_count == 0) {
|
||||
/*
|
||||
* We don't support multiple time stamp types.
|
||||
* That means the only type we support is PCAP_TSTAMP_HOST;
|
||||
* set up a list containing only that type.
|
||||
*/
|
||||
*tstamp_typesp = NULL;
|
||||
*tstamp_typesp = (int*)malloc(sizeof(**tstamp_typesp));
|
||||
if (*tstamp_typesp == NULL) {
|
||||
pcap_fmt_errmsg_for_errno(p->errbuf, sizeof(p->errbuf),
|
||||
errno, "malloc");
|
||||
return (PCAP_ERROR);
|
||||
}
|
||||
**tstamp_typesp = PCAP_TSTAMP_HOST;
|
||||
return (1);
|
||||
} else {
|
||||
*tstamp_typesp = (int*)calloc(sizeof(**tstamp_typesp),
|
||||
p->tstamp_type_count);
|
||||
@ -308,8 +406,8 @@ pcap_list_tstamp_types(pcap_t *p, int **tstamp_typesp)
|
||||
}
|
||||
(void)memcpy(*tstamp_typesp, p->tstamp_type_list,
|
||||
sizeof(**tstamp_typesp) * p->tstamp_type_count);
|
||||
return (p->tstamp_type_count);
|
||||
}
|
||||
return (p->tstamp_type_count);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -659,7 +757,7 @@ get_if_description(const char *name)
|
||||
* Get the description for the interface.
|
||||
*/
|
||||
memset(&ifrdesc, 0, sizeof ifrdesc);
|
||||
strlcpy(ifrdesc.ifr_name, name, sizeof ifrdesc.ifr_name);
|
||||
pcap_strlcpy(ifrdesc.ifr_name, name, sizeof ifrdesc.ifr_name);
|
||||
s = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (s >= 0) {
|
||||
#ifdef __FreeBSD__
|
||||
@ -710,7 +808,7 @@ get_if_description(const char *name)
|
||||
}
|
||||
#endif /* __FreeBSD__ */
|
||||
close(s);
|
||||
if (description != NULL && strlen(description) == 0) {
|
||||
if (description != NULL && description[0] == '\0') {
|
||||
/*
|
||||
* Description is empty, so discard it.
|
||||
*/
|
||||
@ -741,20 +839,13 @@ get_if_description(const char *name)
|
||||
* OK, it's a valid number that's not
|
||||
* bigger than INT_MAX. Construct
|
||||
* a description from it.
|
||||
* (If that fails, we don't worry about
|
||||
* it, we just return NULL.)
|
||||
*/
|
||||
static const char descr_prefix[] = "USB bus number ";
|
||||
size_t descr_size;
|
||||
|
||||
/*
|
||||
* Allow enough room for a 32-bit bus number.
|
||||
* sizeof (descr_prefix) includes the
|
||||
* terminating NUL.
|
||||
*/
|
||||
descr_size = sizeof (descr_prefix) + 10;
|
||||
description = malloc(descr_size);
|
||||
if (description != NULL) {
|
||||
pcap_snprintf(description, descr_size,
|
||||
"%s%ld", descr_prefix, busnum);
|
||||
if (pcap_asprintf(&description,
|
||||
"USB bus number %ld", busnum) == -1) {
|
||||
/* Failed. */
|
||||
description = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1292,14 +1383,14 @@ pcap_lookupdev(char *errbuf)
|
||||
* on the list, there aren't any non-loopback devices,
|
||||
* so why not just supply it as the default device?
|
||||
*/
|
||||
(void)strlcpy(errbuf, "no suitable device found",
|
||||
(void)pcap_strlcpy(errbuf, "no suitable device found",
|
||||
PCAP_ERRBUF_SIZE);
|
||||
ret = NULL;
|
||||
} else {
|
||||
/*
|
||||
* Return the name of the first device on the list.
|
||||
*/
|
||||
(void)strlcpy(device, alldevs->name, sizeof(device));
|
||||
(void)pcap_strlcpy(device, alldevs->name, sizeof(device));
|
||||
ret = device;
|
||||
}
|
||||
|
||||
@ -1366,7 +1457,7 @@ pcap_lookupnet(const char *device, bpf_u_int32 *netp, bpf_u_int32 *maskp,
|
||||
/* XXX Work around Linux kernel bug */
|
||||
ifr.ifr_addr.sa_family = AF_INET;
|
||||
#endif
|
||||
(void)strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
|
||||
(void)pcap_strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
|
||||
if (ioctl(fd, SIOCGIFADDR, (char *)&ifr) < 0) {
|
||||
if (errno == EADDRNOTAVAIL) {
|
||||
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
@ -1385,7 +1476,7 @@ pcap_lookupnet(const char *device, bpf_u_int32 *netp, bpf_u_int32 *maskp,
|
||||
/* XXX Work around Linux kernel bug */
|
||||
ifr.ifr_addr.sa_family = AF_INET;
|
||||
#endif
|
||||
(void)strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
|
||||
(void)pcap_strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
|
||||
if (ioctl(fd, SIOCGIFNETMASK, (char *)&ifr) < 0) {
|
||||
pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
|
||||
errno, "SIOCGIFNETMASK: %s", device);
|
||||
@ -1575,13 +1666,14 @@ pcap_parse_source(const char *source, char **schemep, char **userinfop,
|
||||
* the pathname.
|
||||
*/
|
||||
if (pcap_strcasecmp(scheme, "file") == 0) {
|
||||
*schemep = scheme;
|
||||
*pathp = strdup(colonp + 3);
|
||||
if (*pathp == NULL) {
|
||||
pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
|
||||
errno, "malloc");
|
||||
free(scheme);
|
||||
return (-1);
|
||||
}
|
||||
*schemep = scheme;
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -1684,7 +1776,12 @@ pcap_parse_source(const char *source, char **schemep, char **userinfop,
|
||||
* Treat verything up to the closing square
|
||||
* bracket as the IP-Literal; we don't worry
|
||||
* about whether it's a valid IPv6address or
|
||||
* IPvFuture.
|
||||
* IPvFuture (or an IPv4address, for that
|
||||
* matter, just in case we get handed a
|
||||
* URL with an IPv4 IP-Literal, of the sort
|
||||
* that pcap_createsrcstr() used to generate,
|
||||
* and that pcap_parsesrcstr(), in the original
|
||||
* WinPcap code, accepted).
|
||||
*/
|
||||
bracketp = strchr(parsep, ']');
|
||||
if (bracketp == NULL) {
|
||||
@ -1805,9 +1902,9 @@ pcap_createsrcstr(char *source, int type, const char *host, const char *port,
|
||||
switch (type) {
|
||||
|
||||
case PCAP_SRC_FILE:
|
||||
strlcpy(source, PCAP_SRC_FILE_STRING, PCAP_BUF_SIZE);
|
||||
pcap_strlcpy(source, PCAP_SRC_FILE_STRING, PCAP_BUF_SIZE);
|
||||
if (name != NULL && *name != '\0') {
|
||||
strlcat(source, name, PCAP_BUF_SIZE);
|
||||
pcap_strlcat(source, name, PCAP_BUF_SIZE);
|
||||
return (0);
|
||||
} else {
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
@ -1816,7 +1913,7 @@ pcap_createsrcstr(char *source, int type, const char *host, const char *port,
|
||||
}
|
||||
|
||||
case PCAP_SRC_IFREMOTE:
|
||||
strlcpy(source, PCAP_SRC_IF_STRING, PCAP_BUF_SIZE);
|
||||
pcap_strlcpy(source, PCAP_SRC_IF_STRING, PCAP_BUF_SIZE);
|
||||
if (host != NULL && *host != '\0') {
|
||||
if (strchr(host, ':') != NULL) {
|
||||
/*
|
||||
@ -1824,18 +1921,18 @@ pcap_createsrcstr(char *source, int type, const char *host, const char *port,
|
||||
* probably an IPv6 address, and needs to
|
||||
* be included in square brackets.
|
||||
*/
|
||||
strlcat(source, "[", PCAP_BUF_SIZE);
|
||||
strlcat(source, host, PCAP_BUF_SIZE);
|
||||
strlcat(source, "]", PCAP_BUF_SIZE);
|
||||
pcap_strlcat(source, "[", PCAP_BUF_SIZE);
|
||||
pcap_strlcat(source, host, PCAP_BUF_SIZE);
|
||||
pcap_strlcat(source, "]", PCAP_BUF_SIZE);
|
||||
} else
|
||||
strlcat(source, host, PCAP_BUF_SIZE);
|
||||
pcap_strlcat(source, host, PCAP_BUF_SIZE);
|
||||
|
||||
if (port != NULL && *port != '\0') {
|
||||
strlcat(source, ":", PCAP_BUF_SIZE);
|
||||
strlcat(source, port, PCAP_BUF_SIZE);
|
||||
pcap_strlcat(source, ":", PCAP_BUF_SIZE);
|
||||
pcap_strlcat(source, port, PCAP_BUF_SIZE);
|
||||
}
|
||||
|
||||
strlcat(source, "/", PCAP_BUF_SIZE);
|
||||
pcap_strlcat(source, "/", PCAP_BUF_SIZE);
|
||||
} else {
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"The host name cannot be NULL.");
|
||||
@ -1843,15 +1940,15 @@ pcap_createsrcstr(char *source, int type, const char *host, const char *port,
|
||||
}
|
||||
|
||||
if (name != NULL && *name != '\0')
|
||||
strlcat(source, name, PCAP_BUF_SIZE);
|
||||
pcap_strlcat(source, name, PCAP_BUF_SIZE);
|
||||
|
||||
return (0);
|
||||
|
||||
case PCAP_SRC_IFLOCAL:
|
||||
strlcpy(source, PCAP_SRC_IF_STRING, PCAP_BUF_SIZE);
|
||||
pcap_strlcpy(source, PCAP_SRC_IF_STRING, PCAP_BUF_SIZE);
|
||||
|
||||
if (name != NULL && *name != '\0')
|
||||
strlcat(source, name, PCAP_BUF_SIZE);
|
||||
pcap_strlcat(source, name, PCAP_BUF_SIZE);
|
||||
|
||||
return (0);
|
||||
|
||||
@ -1890,7 +1987,7 @@ pcap_parsesrcstr(const char *source, int *type, char *host, char *port,
|
||||
* Local device.
|
||||
*/
|
||||
if (name && tmppath)
|
||||
strlcpy(name, tmppath, PCAP_BUF_SIZE);
|
||||
pcap_strlcpy(name, tmppath, PCAP_BUF_SIZE);
|
||||
if (type)
|
||||
*type = PCAP_SRC_IFLOCAL;
|
||||
free(tmppath);
|
||||
@ -1912,12 +2009,12 @@ pcap_parsesrcstr(const char *source, int *type, char *host, char *port,
|
||||
pcap_snprintf(host, PCAP_BUF_SIZE, "%s@%s",
|
||||
tmpuserinfo, tmphost);
|
||||
else
|
||||
strlcpy(host, tmphost, PCAP_BUF_SIZE);
|
||||
pcap_strlcpy(host, tmphost, PCAP_BUF_SIZE);
|
||||
}
|
||||
if (port && tmpport)
|
||||
strlcpy(port, tmpport, PCAP_BUF_SIZE);
|
||||
pcap_strlcpy(port, tmpport, PCAP_BUF_SIZE);
|
||||
if (name && tmppath)
|
||||
strlcpy(name, tmppath, PCAP_BUF_SIZE);
|
||||
pcap_strlcpy(name, tmppath, PCAP_BUF_SIZE);
|
||||
if (type)
|
||||
*type = PCAP_SRC_IFREMOTE;
|
||||
free(tmppath);
|
||||
@ -1933,7 +2030,7 @@ pcap_parsesrcstr(const char *source, int *type, char *host, char *port,
|
||||
* file://
|
||||
*/
|
||||
if (name && tmppath)
|
||||
strlcpy(name, tmppath, PCAP_BUF_SIZE);
|
||||
pcap_strlcpy(name, tmppath, PCAP_BUF_SIZE);
|
||||
if (type)
|
||||
*type = PCAP_SRC_FILE;
|
||||
free(tmppath);
|
||||
@ -1949,7 +2046,7 @@ pcap_parsesrcstr(const char *source, int *type, char *host, char *port,
|
||||
* as a local device.
|
||||
*/
|
||||
if (name)
|
||||
strlcpy(name, source, PCAP_BUF_SIZE);
|
||||
pcap_strlcpy(name, source, PCAP_BUF_SIZE);
|
||||
if (type)
|
||||
*type = PCAP_SRC_IFLOCAL;
|
||||
free(tmppath);
|
||||
@ -1981,11 +2078,28 @@ pcap_create(const char *device, char *errbuf)
|
||||
else {
|
||||
#ifdef _WIN32
|
||||
/*
|
||||
* If the string appears to be little-endian UCS-2/UTF-16,
|
||||
* convert it to ASCII.
|
||||
* On Windows, for backwards compatibility reasons,
|
||||
* pcap_lookupdev() returns a pointer to a sequence of
|
||||
* pairs of UTF-16LE device names and local code page
|
||||
* description strings.
|
||||
*
|
||||
* XXX - to UTF-8 instead? Or report an error if any
|
||||
* character isn't ASCII?
|
||||
* This means that if a program uses pcap_lookupdev()
|
||||
* to get a default device, and hands that to an API
|
||||
* that opens devices, we'll get handed a UTF-16LE
|
||||
* string, not a string in the local code page.
|
||||
*
|
||||
* To work around that, we check whether the string
|
||||
* looks as if it might be a UTF-16LE strinh and, if
|
||||
* so, convert it back to the local code page's
|
||||
* extended ASCII.
|
||||
*
|
||||
* XXX - you *cannot* reliably detect whether a
|
||||
* string is UTF-16LE or not; "a" could either
|
||||
* be a one-character ASCII string or the first
|
||||
* character of a UTF-16LE string. This particular
|
||||
* version of this heuristic dates back to WinPcap
|
||||
* 4.1.1; PacketOpenAdapter() does uses the same
|
||||
* heuristic, with the exact same vulnerability.
|
||||
*/
|
||||
if (device[0] != '\0' && device[1] == '\0') {
|
||||
size_t length;
|
||||
@ -2077,25 +2191,25 @@ initialize_ops(pcap_t *p)
|
||||
* an activated pcap_t to point to a routine that returns
|
||||
* a "this isn't activated" error.
|
||||
*/
|
||||
p->read_op = (read_op_t)pcap_not_initialized;
|
||||
p->inject_op = (inject_op_t)pcap_not_initialized;
|
||||
p->setfilter_op = (setfilter_op_t)pcap_not_initialized;
|
||||
p->setdirection_op = (setdirection_op_t)pcap_not_initialized;
|
||||
p->set_datalink_op = (set_datalink_op_t)pcap_not_initialized;
|
||||
p->getnonblock_op = (getnonblock_op_t)pcap_not_initialized;
|
||||
p->stats_op = (stats_op_t)pcap_not_initialized;
|
||||
p->read_op = pcap_read_not_initialized;
|
||||
p->inject_op = pcap_inject_not_initialized;
|
||||
p->setfilter_op = pcap_setfilter_not_initialized;
|
||||
p->setdirection_op = pcap_setdirection_not_initialized;
|
||||
p->set_datalink_op = pcap_set_datalink_not_initialized;
|
||||
p->getnonblock_op = pcap_getnonblock_not_initialized;
|
||||
p->stats_op = pcap_stats_not_initialized;
|
||||
#ifdef _WIN32
|
||||
p->stats_ex_op = (stats_ex_op_t)pcap_not_initialized_ptr;
|
||||
p->setbuff_op = (setbuff_op_t)pcap_not_initialized;
|
||||
p->setmode_op = (setmode_op_t)pcap_not_initialized;
|
||||
p->setmintocopy_op = (setmintocopy_op_t)pcap_not_initialized;
|
||||
p->stats_ex_op = pcap_stats_ex_not_initialized;
|
||||
p->setbuff_op = pcap_setbuff_not_initialized;
|
||||
p->setmode_op = pcap_setmode_not_initialized;
|
||||
p->setmintocopy_op = pcap_setmintocopy_not_initialized;
|
||||
p->getevent_op = pcap_getevent_not_initialized;
|
||||
p->oid_get_request_op = (oid_get_request_op_t)pcap_not_initialized;
|
||||
p->oid_set_request_op = (oid_set_request_op_t)pcap_not_initialized;
|
||||
p->oid_get_request_op = pcap_oid_get_request_not_initialized;
|
||||
p->oid_set_request_op = pcap_oid_set_request_not_initialized;
|
||||
p->sendqueue_transmit_op = pcap_sendqueue_transmit_not_initialized;
|
||||
p->setuserbuffer_op = (setuserbuffer_op_t)pcap_not_initialized;
|
||||
p->live_dump_op = (live_dump_op_t)pcap_not_initialized;
|
||||
p->live_dump_ended_op = (live_dump_ended_op_t)pcap_not_initialized;
|
||||
p->setuserbuffer_op = pcap_setuserbuffer_not_initialized;
|
||||
p->live_dump_op = pcap_live_dump_not_initialized;
|
||||
p->live_dump_ended_op = pcap_live_dump_ended_not_initialized;
|
||||
p->get_airpcap_handle_op = pcap_get_airpcap_handle_not_initialized;
|
||||
#endif
|
||||
|
||||
@ -2124,14 +2238,23 @@ pcap_alloc_pcap_t(char *ebuf, size_t size)
|
||||
* plus a structure following it of size "size". The
|
||||
* structure following it is a private data structure
|
||||
* for the routines that handle this pcap_t.
|
||||
*
|
||||
* The structure following it must be aligned on
|
||||
* the appropriate alignment boundary for this platform.
|
||||
* We align on an 8-byte boundary as that's probably what
|
||||
* at least some platforms do, even with 32-bit integers,
|
||||
* and because we can't be sure that some values won't
|
||||
* require 8-byte alignment even on platforms with 32-bit
|
||||
* integers.
|
||||
*/
|
||||
chunk = malloc(sizeof (pcap_t) + size);
|
||||
#define PCAP_T_ALIGNED_SIZE ((sizeof(pcap_t) + 7U) & ~0x7U)
|
||||
chunk = malloc(PCAP_T_ALIGNED_SIZE + size);
|
||||
if (chunk == NULL) {
|
||||
pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
|
||||
errno, "malloc");
|
||||
return (NULL);
|
||||
}
|
||||
memset(chunk, 0, sizeof (pcap_t) + size);
|
||||
memset(chunk, 0, PCAP_T_ALIGNED_SIZE + size);
|
||||
|
||||
/*
|
||||
* Get a pointer to the pcap_t at the beginning.
|
||||
@ -2156,7 +2279,7 @@ pcap_alloc_pcap_t(char *ebuf, size_t size)
|
||||
* Set the pointer to the private data; that's the structure
|
||||
* of size "size" following the pcap_t.
|
||||
*/
|
||||
p->priv = (void *)(chunk + sizeof (pcap_t));
|
||||
p->priv = (void *)(chunk + PCAP_T_ALIGNED_SIZE);
|
||||
}
|
||||
|
||||
return (p);
|
||||
@ -2451,6 +2574,16 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, char *er
|
||||
char name[PCAP_BUF_SIZE + 1];
|
||||
int srctype;
|
||||
|
||||
/*
|
||||
* A null device name is equivalent to the "any" device -
|
||||
* which might not be supported on this platform, but
|
||||
* this means that you'll get a "not supported" error
|
||||
* rather than, say, a crash when we try to dereference
|
||||
* the null pointer.
|
||||
*/
|
||||
if (device == NULL)
|
||||
device = "any";
|
||||
|
||||
/*
|
||||
* Retrofit - we have to make older applications compatible with
|
||||
* remote capture.
|
||||
@ -2522,13 +2655,13 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, char *er
|
||||
return (p);
|
||||
fail:
|
||||
if (status == PCAP_ERROR)
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", device,
|
||||
p->errbuf);
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %.*s", device,
|
||||
PCAP_ERRBUF_SIZE - 3, p->errbuf);
|
||||
else if (status == PCAP_ERROR_NO_SUCH_DEVICE ||
|
||||
status == PCAP_ERROR_PERM_DENIED ||
|
||||
status == PCAP_ERROR_PROMISC_PERM_DENIED)
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s (%s)", device,
|
||||
pcap_statustostr(status), p->errbuf);
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s (%.*s)", device,
|
||||
pcap_statustostr(status), PCAP_ERRBUF_SIZE - 6, p->errbuf);
|
||||
else
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", device,
|
||||
pcap_statustostr(status));
|
||||
@ -2841,7 +2974,7 @@ static struct dlt_choice dlt_choices[] = {
|
||||
DLT_CHOICE(FRELAY, "Frame Relay"),
|
||||
DLT_CHOICE(LOOP, "OpenBSD loopback"),
|
||||
DLT_CHOICE(ENC, "OpenBSD encapsulated IP"),
|
||||
DLT_CHOICE(LINUX_SLL, "Linux cooked"),
|
||||
DLT_CHOICE(LINUX_SLL, "Linux cooked v1"),
|
||||
DLT_CHOICE(LTALK, "Localtalk"),
|
||||
DLT_CHOICE(PFLOG, "OpenBSD pflog file"),
|
||||
DLT_CHOICE(PFSYNC, "Packet filter state syncing"),
|
||||
@ -2875,7 +3008,7 @@ static struct dlt_choice dlt_choices[] = {
|
||||
DLT_CHOICE(GPF_T, "GPF-T"),
|
||||
DLT_CHOICE(GPF_F, "GPF-F"),
|
||||
DLT_CHOICE(JUNIPER_PIC_PEER, "Juniper PIC Peer"),
|
||||
DLT_CHOICE(ERF_ETH, "Ethernet with Endace ERF header"),
|
||||
DLT_CHOICE(ERF_ETH, "Ethernet with Endace ERF header"),
|
||||
DLT_CHOICE(ERF_POS, "Packet-over-SONET with Endace ERF header"),
|
||||
DLT_CHOICE(LINUX_LAPD, "Linux vISDN LAPD"),
|
||||
DLT_CHOICE(JUNIPER_ETHER, "Juniper Ethernet"),
|
||||
@ -2899,10 +3032,11 @@ static struct dlt_choice dlt_choices[] = {
|
||||
DLT_CHOICE(SITA, "SITA pseudo-header"),
|
||||
DLT_CHOICE(ERF, "Endace ERF header"),
|
||||
DLT_CHOICE(RAIF1, "Ethernet with u10 Networks pseudo-header"),
|
||||
DLT_CHOICE(IPMB, "IPMB"),
|
||||
DLT_CHOICE(IPMB_KONTRON, "IPMB with Kontron pseudo-header"),
|
||||
DLT_CHOICE(JUNIPER_ST, "Juniper Secure Tunnel"),
|
||||
DLT_CHOICE(BLUETOOTH_HCI_H4_WITH_PHDR, "Bluetooth HCI UART transport layer plus pseudo-header"),
|
||||
DLT_CHOICE(AX25_KISS, "AX.25 with KISS header"),
|
||||
DLT_CHOICE(IPMB_LINUX, "IPMB with Linux/Pigeon Point pseudo-header"),
|
||||
DLT_CHOICE(IEEE802_15_4_NONASK_PHY, "IEEE 802.15.4 with non-ASK PHY data"),
|
||||
DLT_CHOICE(MPLS, "MPLS with label as link-layer header"),
|
||||
DLT_CHOICE(LINUX_EVDEV, "Linux evdev events"),
|
||||
@ -2959,6 +3093,7 @@ static struct dlt_choice dlt_choices[] = {
|
||||
DLT_CHOICE(DOCSIS31_XRA31, "Excentis XRA-31 DOCSIS 3.1 RF sniffer frames"),
|
||||
DLT_CHOICE(ETHERNET_MPACKET, "802.3br mPackets"),
|
||||
DLT_CHOICE(DISPLAYPORT_AUX, "DisplayPort AUX channel monitoring data"),
|
||||
DLT_CHOICE(LINUX_SLL2, "Linux cooked v2"),
|
||||
DLT_CHOICE_SENTINEL
|
||||
};
|
||||
|
||||
@ -2998,6 +3133,21 @@ pcap_datalink_val_to_description(int dlt)
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
const char *
|
||||
pcap_datalink_val_to_description_or_dlt(int dlt)
|
||||
{
|
||||
static char unkbuf[40];
|
||||
const char *description;
|
||||
|
||||
description = pcap_datalink_val_to_description(dlt);
|
||||
if (description != NULL) {
|
||||
return description;
|
||||
} else {
|
||||
(void)pcap_snprintf(unkbuf, sizeof(unkbuf), "DLT %u", dlt);
|
||||
return unkbuf;
|
||||
}
|
||||
}
|
||||
|
||||
struct tstamp_type_choice {
|
||||
const char *name;
|
||||
const char *description;
|
||||
@ -3150,7 +3300,7 @@ pcap_getnonblock(pcap_t *p, char *errbuf)
|
||||
* We copy the error message to errbuf, so callers
|
||||
* can find it in either place.
|
||||
*/
|
||||
strlcpy(errbuf, p->errbuf, PCAP_ERRBUF_SIZE);
|
||||
pcap_strlcpy(errbuf, p->errbuf, PCAP_ERRBUF_SIZE);
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
@ -3194,7 +3344,7 @@ pcap_setnonblock(pcap_t *p, int nonblock, char *errbuf)
|
||||
* We copy the error message to errbuf, so callers
|
||||
* can find it in either place.
|
||||
*/
|
||||
strlcpy(errbuf, p->errbuf, PCAP_ERRBUF_SIZE);
|
||||
pcap_strlcpy(errbuf, p->errbuf, PCAP_ERRBUF_SIZE);
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
@ -3230,35 +3380,6 @@ pcap_setnonblock_fd(pcap_t *p, int nonblock)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
/*
|
||||
* Generate a string for a Win32-specific error (i.e. an error generated when
|
||||
* calling a Win32 API).
|
||||
* For errors occurred during standard C calls, we still use pcap_strerror()
|
||||
*/
|
||||
void
|
||||
pcap_win32_err_to_str(DWORD error, char *errbuf)
|
||||
{
|
||||
size_t errlen;
|
||||
char *p;
|
||||
|
||||
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, errbuf,
|
||||
PCAP_ERRBUF_SIZE, NULL);
|
||||
|
||||
/*
|
||||
* "FormatMessage()" "helpfully" sticks CR/LF at the end of the
|
||||
* message. Get rid of it.
|
||||
*/
|
||||
errlen = strlen(errbuf);
|
||||
if (errlen >= 2) {
|
||||
errbuf[errlen - 1] = '\0';
|
||||
errbuf[errlen - 2] = '\0';
|
||||
}
|
||||
p = strchr(errbuf, '\0');
|
||||
pcap_snprintf (p, PCAP_ERRBUF_SIZE+1-(p-errbuf), " (%lu)", error);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Generate error strings for PCAP_ERROR_ and PCAP_WARNING_ values.
|
||||
*/
|
||||
@ -3330,7 +3451,7 @@ pcap_strerror(int errnum)
|
||||
errno_t err = strerror_s(errbuf, PCAP_ERRBUF_SIZE, errnum);
|
||||
|
||||
if (err != 0) /* err = 0 if successful */
|
||||
strlcpy(errbuf, "strerror_s() error", PCAP_ERRBUF_SIZE);
|
||||
pcap_strlcpy(errbuf, "strerror_s() error", PCAP_ERRBUF_SIZE);
|
||||
return (errbuf);
|
||||
#else
|
||||
return (strerror(errnum));
|
||||
@ -3552,7 +3673,7 @@ pcap_do_addexit(pcap_t *p)
|
||||
/*
|
||||
* "atexit()" failed; let our caller know.
|
||||
*/
|
||||
strlcpy(p->errbuf, "atexit failed", PCAP_ERRBUF_SIZE);
|
||||
pcap_strlcpy(p->errbuf, "atexit failed", PCAP_ERRBUF_SIZE);
|
||||
return (0);
|
||||
}
|
||||
did_atexit = 1;
|
||||
|
11
pcap/bpf.h
11
pcap/bpf.h
@ -238,16 +238,6 @@ struct bpf_insn {
|
||||
bpf_u_int32 k;
|
||||
};
|
||||
|
||||
/*
|
||||
* Auxiliary data, for use when interpreting a filter intended for the
|
||||
* Linux kernel when the kernel rejects the filter (requiring us to
|
||||
* run it in userland). It contains VLAN tag information.
|
||||
*/
|
||||
struct bpf_aux_data {
|
||||
u_short vlan_tag_present;
|
||||
u_short vlan_tag;
|
||||
};
|
||||
|
||||
/*
|
||||
* Macros for insn array initializers.
|
||||
*/
|
||||
@ -256,7 +246,6 @@ struct bpf_aux_data {
|
||||
|
||||
PCAP_API int bpf_validate(const struct bpf_insn *, int);
|
||||
PCAP_API u_int bpf_filter(const struct bpf_insn *, const u_char *, u_int, u_int);
|
||||
extern u_int bpf_filter_with_aux_data(const struct bpf_insn *, const u_char *, u_int, u_int, const struct bpf_aux_data *);
|
||||
|
||||
/*
|
||||
* Number of scratch memory words (for BPF_LD|BPF_MEM and BPF_ST).
|
||||
|
@ -160,4 +160,4 @@
|
||||
(__HP_aCC >= ((major)*10000 + (minor)*100))
|
||||
#endif
|
||||
|
||||
#endif /* lib_pcap_funcattrs_h */
|
||||
#endif /* lib_pcap_compiler_tests_h */
|
||||
|
63
pcap/dlt.h
63
pcap/dlt.h
@ -50,7 +50,7 @@
|
||||
*
|
||||
* See
|
||||
*
|
||||
* http://www.tcpdump.org/linktypes.html
|
||||
* https://www.tcpdump.org/linktypes.html
|
||||
*
|
||||
* for detailed descriptions of some of these link-layer header types.
|
||||
*/
|
||||
@ -246,7 +246,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is for Linux cooked sockets.
|
||||
* Linux cooked sockets.
|
||||
*/
|
||||
#define DLT_LINUX_SLL 113
|
||||
|
||||
@ -769,11 +769,20 @@
|
||||
#define DLT_RAIF1 198
|
||||
|
||||
/*
|
||||
* IPMB packet for IPMI, beginning with the I2C slave address, followed
|
||||
* by the netFn and LUN, etc.. Requested by Chanthy Toeung
|
||||
* <chanthy.toeung@ca.kontron.com>.
|
||||
* IPMB packet for IPMI, beginning with a 2-byte header, followed by
|
||||
* the I2C slave address, followed by the netFn and LUN, etc..
|
||||
* Requested by Chanthy Toeung <chanthy.toeung@ca.kontron.com>.
|
||||
*
|
||||
* XXX - this used to be called DLT_IPMB, back when we got the
|
||||
* impression from the email thread requesting it that the packet
|
||||
* had no extra 2-byte header. We've renamed it; if anybody used
|
||||
* DLT_IPMB and assumed no 2-byte header, this will cause the compile
|
||||
* to fail, at which point we'll have to figure out what to do about
|
||||
* the two header types using the same DLT_/LINKTYPE_ value. If that
|
||||
* doesn't happen, we'll assume nobody used it and that the redefinition
|
||||
* is safe.
|
||||
*/
|
||||
#define DLT_IPMB 199
|
||||
#define DLT_IPMB_KONTRON 199
|
||||
|
||||
/*
|
||||
* Juniper-private data link type, as per request from
|
||||
@ -805,15 +814,34 @@
|
||||
#define DLT_LAPD 203
|
||||
|
||||
/*
|
||||
* Variants of various link-layer headers, with a one-byte direction
|
||||
* pseudo-header prepended - zero means "received by this host",
|
||||
* non-zero (any non-zero value) means "sent by this host" - as per
|
||||
* Will Barker <w.barker@zen.co.uk>.
|
||||
* PPP, with a one-byte direction pseudo-header prepended - zero means
|
||||
* "received by this host", non-zero (any non-zero value) means "sent by
|
||||
* this host" - as per Will Barker <w.barker@zen.co.uk>.
|
||||
*/
|
||||
#define DLT_PPP_WITH_DIR 204 /* PPP - don't confuse with DLT_PPP_WITH_DIRECTION */
|
||||
#define DLT_C_HDLC_WITH_DIR 205 /* Cisco HDLC */
|
||||
#define DLT_FRELAY_WITH_DIR 206 /* Frame Relay */
|
||||
#define DLT_LAPB_WITH_DIR 207 /* LAPB */
|
||||
#define DLT_PPP_WITH_DIR 204 /* Don't confuse with DLT_PPP_WITH_DIRECTION */
|
||||
|
||||
/*
|
||||
* Cisco HDLC, with a one-byte direction pseudo-header prepended - zero
|
||||
* means "received by this host", non-zero (any non-zero value) means
|
||||
* "sent by this host" - as per Will Barker <w.barker@zen.co.uk>.
|
||||
*/
|
||||
#define DLT_C_HDLC_WITH_DIR 205
|
||||
|
||||
/*
|
||||
* Frame Relay, with a one-byte direction pseudo-header prepended - zero
|
||||
* means "received by this host" (DCE -> DTE), non-zero (any non-zero
|
||||
* value) means "sent by this host" (DTE -> DCE) - as per Will Barker
|
||||
* <w.barker@zen.co.uk>.
|
||||
*/
|
||||
#define DLT_FRELAY_WITH_DIR 206
|
||||
|
||||
/*
|
||||
* LAPB, with a one-byte direction pseudo-header prepended - zero means
|
||||
* "received by this host" (DCE -> DTE), non-zero (any non-zero value)
|
||||
* means "sent by this host" (DTE -> DCE)- as per Will Barker
|
||||
* <w.barker@zen.co.uk>.
|
||||
*/
|
||||
#define DLT_LAPB_WITH_DIR 207
|
||||
|
||||
/*
|
||||
* 208 is reserved for an as-yet-unspecified proprietary link-layer
|
||||
@ -1367,6 +1395,11 @@
|
||||
*/
|
||||
#define DLT_DISPLAYPORT_AUX 275
|
||||
|
||||
/*
|
||||
* Linux cooked sockets v2.
|
||||
*/
|
||||
#define DLT_LINUX_SLL2 276
|
||||
|
||||
/*
|
||||
* In case the code that includes this file (directly or indirectly)
|
||||
* has also included OS files that happen to define DLT_MATCHING_MAX,
|
||||
@ -1377,7 +1410,7 @@
|
||||
#ifdef DLT_MATCHING_MAX
|
||||
#undef DLT_MATCHING_MAX
|
||||
#endif
|
||||
#define DLT_MATCHING_MAX 275 /* highest value in the "matching" range */
|
||||
#define DLT_MATCHING_MAX 276 /* highest value in the "matching" range */
|
||||
|
||||
/*
|
||||
* DLT and savefile link type values are split into a class and
|
||||
|
@ -164,10 +164,11 @@
|
||||
|| PCAP_IS_AT_LEAST_XL_C_VERSION(10,1) \
|
||||
|| PCAP_IS_AT_LEAST_HP_C_VERSION(6,10)
|
||||
/*
|
||||
* Compiler with support for __attribute((noreturn)), or GCC 2.5 and
|
||||
* later, or Solaris Studio 12 (Sun C 5.9) and later, or IBM XL C 10.1
|
||||
* and later (do any earlier versions of XL C support this?), or
|
||||
* HP aCC A.06.10 and later.
|
||||
* Compiler with support for __attribute((noreturn)), or GCC 2.5 or
|
||||
* later, or some compiler asserting compatibility with GCC 2.5 or
|
||||
* later, or Solaris Studio 12 (Sun C 5.9) or later, or IBM XL C 10.1
|
||||
* or later (do any earlier versions of XL C support this?), or HP aCC
|
||||
* A.06.10 or later.
|
||||
*/
|
||||
#define PCAP_NORETURN __attribute((noreturn))
|
||||
#define PCAP_NORETURN_DEF __attribute((noreturn))
|
||||
@ -193,7 +194,8 @@
|
||||
|| PCAP_IS_AT_LEAST_XL_C_VERSION(10,1) \
|
||||
|| PCAP_IS_AT_LEAST_HP_C_VERSION(6,10)
|
||||
/*
|
||||
* Compiler with support for it, or GCC 2.3 and later, or IBM XL C 10.1
|
||||
* Compiler with support for it, or GCC 2.3 or later, or some compiler
|
||||
* asserting compatibility with GCC 2.3 or later, or IBM XL C 10.1
|
||||
* and later (do any earlier versions of XL C support this?),
|
||||
* or HP aCC A.06.10 and later.
|
||||
*/
|
||||
@ -216,7 +218,7 @@
|
||||
|| PCAP_IS_AT_LEAST_SUNC_VERSION(5,13)
|
||||
/*
|
||||
* Compiler that supports __has_attribute and __attribute__((deprecated)),
|
||||
* or GCC 4.5 and later, or Sun/Oracle C 12.4 (Sun C 5.13) or later.
|
||||
* or GCC 4.5 or later, or Sun/Oracle C 12.4 (Sun C 5.13) or later.
|
||||
*
|
||||
* Those support __attribute__((deprecated(msg))) (we assume, perhaps
|
||||
* incorrectly, that anything that supports __has_attribute() is
|
||||
|
18
pcap/nflog.h
18
pcap/nflog.h
@ -32,7 +32,7 @@
|
||||
|
||||
/*
|
||||
* Structure of an NFLOG header and TLV parts, as described at
|
||||
* http://www.tcpdump.org/linktypes/LINKTYPE_NFLOG.html
|
||||
* https://www.tcpdump.org/linktypes/LINKTYPE_NFLOG.html
|
||||
*
|
||||
* The NFLOG header is big-endian.
|
||||
*
|
||||
@ -42,27 +42,27 @@
|
||||
* data, etc.).
|
||||
*/
|
||||
typedef struct nflog_hdr {
|
||||
uint8_t nflog_family; /* address family */
|
||||
uint8_t nflog_version; /* version */
|
||||
uint16_t nflog_rid; /* resource ID */
|
||||
uint8_t nflog_family; /* address family */
|
||||
uint8_t nflog_version; /* version */
|
||||
uint16_t nflog_rid; /* resource ID */
|
||||
} nflog_hdr_t;
|
||||
|
||||
typedef struct nflog_tlv {
|
||||
uint16_t tlv_length; /* tlv length */
|
||||
uint16_t tlv_type; /* tlv type */
|
||||
uint16_t tlv_length; /* tlv length */
|
||||
uint16_t tlv_type; /* tlv type */
|
||||
/* value follows this */
|
||||
} nflog_tlv_t;
|
||||
|
||||
typedef struct nflog_packet_hdr {
|
||||
uint16_t hw_protocol; /* hw protocol */
|
||||
uint8_t hook; /* netfilter hook */
|
||||
uint8_t pad; /* padding to 32 bits */
|
||||
uint8_t hook; /* netfilter hook */
|
||||
uint8_t pad; /* padding to 32 bits */
|
||||
} nflog_packet_hdr_t;
|
||||
|
||||
typedef struct nflog_hwaddr {
|
||||
uint16_t hw_addrlen; /* address length */
|
||||
uint16_t pad; /* padding to 32-bit boundary */
|
||||
uint8_t hw_addr[8]; /* address, up to 8 bytes */
|
||||
uint8_t hw_addr[8]; /* address, up to 8 bytes */
|
||||
} nflog_hwaddr_t;
|
||||
|
||||
typedef struct nflog_timestamp {
|
||||
|
@ -106,12 +106,23 @@
|
||||
#define PRIu64 "llu"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* MSVC's support library doesn't support %zu to print a size_t until
|
||||
* Visual Studio 2017, but supports %Iu earlier, so use that.
|
||||
*/
|
||||
#define PRIsize "Iu"
|
||||
#elif defined(__MINGW32__) || !defined(_WIN32)
|
||||
/*
|
||||
* Compiler is MinGW or target is UN*X or MS-DOS. Just use
|
||||
* <inttypes.h>.
|
||||
*/
|
||||
#include <inttypes.h>
|
||||
|
||||
/*
|
||||
* Assume the support library supports %zu; it's required by C99.
|
||||
*/
|
||||
#define PRIsize "zu"
|
||||
#endif
|
||||
|
||||
#endif /* pcap/pcap-inttypes.h */
|
||||
|
53
pcap/pcap.h
53
pcap/pcap.h
@ -84,6 +84,8 @@
|
||||
#include <sys/time.h>
|
||||
#endif /* _WIN32/MSDOS/UN*X */
|
||||
|
||||
#include <pcap/socket.h> /* for SOCKET, as the active-mode rpcap APIs use it */
|
||||
|
||||
#ifndef PCAP_DONT_INCLUDE_PCAP_BPF_H
|
||||
#include <pcap/bpf.h>
|
||||
#endif
|
||||
@ -348,7 +350,7 @@ PCAP_API const char *pcap_tstamp_type_val_to_name(int);
|
||||
PCAP_API const char *pcap_tstamp_type_val_to_description(int);
|
||||
|
||||
#ifdef __linux__
|
||||
PCAP_API int pcap_set_protocol(pcap_t *, int);
|
||||
PCAP_API int pcap_set_protocol_linux(pcap_t *, int);
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -468,6 +470,7 @@ PCAP_API void pcap_free_datalinks(int *);
|
||||
PCAP_API int pcap_datalink_name_to_val(const char *);
|
||||
PCAP_API const char *pcap_datalink_val_to_name(int);
|
||||
PCAP_API const char *pcap_datalink_val_to_description(int);
|
||||
PCAP_API const char *pcap_datalink_val_to_description_or_dlt(int);
|
||||
PCAP_API int pcap_snapshot(pcap_t *);
|
||||
PCAP_API int pcap_is_swapped(pcap_t *);
|
||||
PCAP_API int pcap_major_version(pcap_t *);
|
||||
@ -483,7 +486,28 @@ PCAP_API int pcap_fileno(pcap_t *);
|
||||
#endif
|
||||
|
||||
PCAP_API pcap_dumper_t *pcap_dump_open(pcap_t *, const char *);
|
||||
PCAP_API pcap_dumper_t *pcap_dump_fopen(pcap_t *, FILE *fp);
|
||||
#ifdef _WIN32
|
||||
PCAP_API pcap_dumper_t *pcap_dump_hopen(pcap_t *, intptr_t);
|
||||
/*
|
||||
* If we're building libpcap, this is an internal routine in sf-pcap.c, so
|
||||
* we must not define it as a macro.
|
||||
*
|
||||
* If we're not building libpcap, given that the version of the C runtime
|
||||
* with which libpcap was built might be different from the version
|
||||
* of the C runtime with which an application using libpcap was built,
|
||||
* and that a FILE structure may differ between the two versions of the
|
||||
* C runtime, calls to _fileno() must use the version of _fileno() in
|
||||
* the C runtime used to open the FILE *, not the version in the C
|
||||
* runtime with which libpcap was built. (Maybe once the Universal CRT
|
||||
* rules the world, this will cease to be a problem.)
|
||||
*/
|
||||
#ifndef BUILDING_PCAP
|
||||
#define pcap_dump_fopen(p,f) \
|
||||
pcap_dump_hopen(p, _get_osfhandle(_fileno(f)))
|
||||
#endif
|
||||
#else /*_WIN32*/
|
||||
PCAP_API pcap_dumper_t *pcap_dump_fopen(pcap_t *, FILE *fp);
|
||||
#endif /*_WIN32*/
|
||||
PCAP_API pcap_dumper_t *pcap_dump_open_append(pcap_t *, const char *);
|
||||
PCAP_API FILE *pcap_dump_file(pcap_dumper_t *);
|
||||
PCAP_API long pcap_dump_ftell(pcap_dumper_t *);
|
||||
@ -858,8 +882,8 @@ PCAP_API int pcap_parsesrcstr(const char *source, int *type, char *host,
|
||||
* For listing remote capture devices, pcap_findalldevs_ex() is currently
|
||||
* the only API available.
|
||||
*/
|
||||
PCAP_API int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth,
|
||||
pcap_if_t **alldevs, char *errbuf);
|
||||
PCAP_API int pcap_findalldevs_ex(const char *source,
|
||||
struct pcap_rmtauth *auth, pcap_if_t **alldevs, char *errbuf);
|
||||
|
||||
/*
|
||||
* Sampling methods.
|
||||
@ -937,27 +961,6 @@ PCAP_API struct pcap_samp *pcap_setsampling(pcap_t *p);
|
||||
/* Maximum length of an host name (needed for the RPCAP active mode) */
|
||||
#define RPCAP_HOSTLIST_SIZE 1024
|
||||
|
||||
/*
|
||||
* Some minor differences between UN*X sockets and and Winsock sockets.
|
||||
*/
|
||||
#ifndef _WIN32
|
||||
/*!
|
||||
* \brief In Winsock, a socket handle is of type SOCKET; in UN*X, it's
|
||||
* a file descriptor, and therefore a signed integer.
|
||||
* We define SOCKET to be a signed integer on UN*X, so that it can
|
||||
* be used on both platforms.
|
||||
*/
|
||||
#define SOCKET int
|
||||
|
||||
/*!
|
||||
* \brief In Winsock, the error return if socket() fails is INVALID_SOCKET;
|
||||
* in UN*X, it's -1.
|
||||
* We define INVALID_SOCKET to be -1 on UN*X, so that it can be used on
|
||||
* both platforms.
|
||||
*/
|
||||
#define INVALID_SOCKET -1
|
||||
#endif
|
||||
|
||||
PCAP_API SOCKET pcap_remoteact_accept(const char *address, const char *port,
|
||||
const char *hostlist, char *connectinghost,
|
||||
struct pcap_rmtauth *auth, char *errbuf);
|
||||
|
40
pcap/sll.h
40
pcap/sll.h
@ -74,27 +74,44 @@
|
||||
#ifndef lib_pcap_sll_h
|
||||
#define lib_pcap_sll_h
|
||||
|
||||
#include <pcap/pcap-inttypes.h>
|
||||
|
||||
/*
|
||||
* A DLT_LINUX_SLL fake link-layer header.
|
||||
*/
|
||||
#define SLL_HDR_LEN 16 /* total header length */
|
||||
#define SLL_ADDRLEN 8 /* length of address field */
|
||||
|
||||
#include <pcap/pcap-inttypes.h>
|
||||
|
||||
struct sll_header {
|
||||
uint16_t sll_pkttype; /* packet type */
|
||||
uint16_t sll_hatype; /* link-layer address type */
|
||||
uint16_t sll_halen; /* link-layer address length */
|
||||
uint8_t sll_addr[SLL_ADDRLEN]; /* link-layer address */
|
||||
uint8_t sll_addr[SLL_ADDRLEN]; /* link-layer address */
|
||||
uint16_t sll_protocol; /* protocol */
|
||||
};
|
||||
|
||||
/*
|
||||
* The LINUX_SLL_ values for "sll_pkttype"; these correspond to the
|
||||
* PACKET_ values on Linux, but are defined here so that they're
|
||||
* available even on systems other than Linux, and so that they
|
||||
* don't change even if the PACKET_ values change.
|
||||
* A DLT_LINUX_SLL2 fake link-layer header.
|
||||
*/
|
||||
#define SLL2_HDR_LEN 20 /* total header length */
|
||||
|
||||
struct sll2_header {
|
||||
uint16_t sll2_protocol; /* protocol */
|
||||
uint16_t sll2_reserved_mbz; /* reserved - must be zero */
|
||||
uint32_t sll2_if_index; /* 1-based interface index */
|
||||
uint16_t sll2_hatype; /* link-layer address type */
|
||||
uint8_t sll2_pkttype; /* packet type */
|
||||
uint8_t sll2_halen; /* link-layer address length */
|
||||
uint8_t sll2_addr[SLL_ADDRLEN]; /* link-layer address */
|
||||
};
|
||||
|
||||
/*
|
||||
* The LINUX_SLL_ values for "sll_pkttype" and LINUX_SLL2_ values for
|
||||
* "sll2_pkttype"; these correspond to the PACKET_ values on Linux,
|
||||
* which are defined by a header under include/uapi in the current
|
||||
* kernel source, and are thus not going to change on Linux. We
|
||||
* define them here so that they're available even on systems other
|
||||
* than Linux.
|
||||
*/
|
||||
#define LINUX_SLL_HOST 0
|
||||
#define LINUX_SLL_BROADCAST 1
|
||||
@ -103,10 +120,11 @@ struct sll_header {
|
||||
#define LINUX_SLL_OUTGOING 4
|
||||
|
||||
/*
|
||||
* The LINUX_SLL_ values for "sll_protocol"; these correspond to the
|
||||
* ETH_P_ values on Linux, but are defined here so that they're
|
||||
* available even on systems other than Linux. We assume, for now,
|
||||
* that the ETH_P_ values won't change in Linux; if they do, then:
|
||||
* The LINUX_SLL_ values for "sll_protocol" and LINUX_SLL2_ values for
|
||||
* "sll2_protocol"; these correspond to the ETH_P_ values on Linux, but
|
||||
* are defined here so that they're available even on systems other than
|
||||
* Linux. We assume, for now, that the ETH_P_ values won't change in
|
||||
* Linux; if they do, then:
|
||||
*
|
||||
* if we don't translate them in "pcap-linux.c", capture files
|
||||
* won't necessarily be readable if captured on a system that
|
||||
|
93
pcap/socket.h
Normal file
93
pcap/socket.h
Normal file
@ -0,0 +1,93 @@
|
||||
/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */
|
||||
/*
|
||||
* Copyright (c) 1993, 1994, 1995, 1996, 1997
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the Computer Systems
|
||||
* Engineering Group at Lawrence Berkeley Laboratory.
|
||||
* 4. Neither the name of the University nor of the Laboratory may be used
|
||||
* to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef lib_pcap_socket_h
|
||||
#define lib_pcap_socket_h
|
||||
|
||||
/*
|
||||
* Some minor differences between sockets on various platforms.
|
||||
* We include whatever sockets are needed for Internet-protocol
|
||||
* socket access on UN*X and Windows.
|
||||
*/
|
||||
#ifdef _WIN32
|
||||
/* Need windef.h for defines used in winsock2.h under MingW32 */
|
||||
#ifdef __MINGW32__
|
||||
#include <windef.h>
|
||||
#endif
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
|
||||
/*
|
||||
* Winsock doesn't have this UN*X type; it's used in the UN*X
|
||||
* sockets API.
|
||||
*
|
||||
* XXX - do we need to worry about UN*Xes so old that *they*
|
||||
* don't have it, either?
|
||||
*/
|
||||
typedef int socklen_t;
|
||||
|
||||
/*
|
||||
* Winsock doesn't have this POSIX type; it's used for the
|
||||
* tv_usec value of struct timeval.
|
||||
*/
|
||||
typedef long suseconds_t;
|
||||
#else /* _WIN32 */
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h> /* for struct addrinfo/getaddrinfo() */
|
||||
#include <netinet/in.h> /* for sockaddr_in, in BSD at least */
|
||||
#include <arpa/inet.h>
|
||||
|
||||
/*!
|
||||
* \brief In Winsock, a socket handle is of type SOCKET; in UN*X, it's
|
||||
* a file descriptor, and therefore a signed integer.
|
||||
* We define SOCKET to be a signed integer on UN*X, so that it can
|
||||
* be used on both platforms.
|
||||
*/
|
||||
#ifndef SOCKET
|
||||
#define SOCKET int
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* \brief In Winsock, the error return if socket() fails is INVALID_SOCKET;
|
||||
* in UN*X, it's -1.
|
||||
* We define INVALID_SOCKET to be -1 on UN*X, so that it can be used on
|
||||
* both platforms.
|
||||
*/
|
||||
#ifndef INVALID_SOCKET
|
||||
#define INVALID_SOCKET -1
|
||||
#endif
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#endif /* lib_pcap_socket_h */
|
@ -17,7 +17,7 @@
|
||||
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
.\"
|
||||
.TH PCAP_ACTIVATE 3PCAP "7 April 2014"
|
||||
.TH PCAP_ACTIVATE 3PCAP "31 July 2016"
|
||||
.SH NAME
|
||||
pcap_activate \- activate a capture handle
|
||||
.SH SYNOPSIS
|
||||
@ -50,15 +50,15 @@ promiscuous mode.
|
||||
.TP
|
||||
.B PCAP_WARNING_TSTAMP_TYPE_NOTSUP
|
||||
The time stamp type specified in a previous
|
||||
.B pcap_set_tstamp_type()
|
||||
.B pcap_set_tstamp_type(3PCAP)
|
||||
call isn't supported by the capture source (the time stamp type is
|
||||
left as the default),
|
||||
.TP
|
||||
.B PCAP_WARNING
|
||||
Another warning condition occurred;
|
||||
.B pcap_geterr()
|
||||
.B pcap_geterr(3PCAP)
|
||||
or
|
||||
.B pcap_perror()
|
||||
.B pcap_perror(3PCAP)
|
||||
may be called with
|
||||
.I p
|
||||
as an argument to fetch or display a message describing the warning
|
||||
@ -115,7 +115,7 @@ Additional warning and error codes may be added in the future; a program
|
||||
should check for positive, negative, and zero return codes, and treat
|
||||
all positive return codes as warnings and all negative return
|
||||
codes as errors.
|
||||
.B pcap_statustostr()
|
||||
.B pcap_statustostr(3PCAP)
|
||||
can be called, with a warning or error code as an argument, to fetch a
|
||||
message describing the warning or error code.
|
||||
.SH SEE ALSO
|
||||
|
@ -17,7 +17,7 @@
|
||||
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
.\"
|
||||
.TH PCAP_BREAKLOOP 3PCAP "8 March 2015"
|
||||
.TH PCAP_BREAKLOOP 3PCAP "25 July 2018"
|
||||
.SH NAME
|
||||
pcap_breakloop \- force a pcap_dispatch() or pcap_loop() call to return
|
||||
.SH SYNOPSIS
|
||||
@ -33,12 +33,13 @@ void pcap_breakloop(pcap_t *);
|
||||
.SH DESCRIPTION
|
||||
.B pcap_breakloop()
|
||||
sets a flag that will force
|
||||
.B pcap_dispatch()
|
||||
.B pcap_dispatch(3PCAP)
|
||||
or
|
||||
.B pcap_loop()
|
||||
.B pcap_loop(3PCAP)
|
||||
to return rather than looping; they will return the number of packets
|
||||
that have been processed so far, or \-2 if no packets have been
|
||||
processed so far.
|
||||
that have been processed so far, or
|
||||
.B PCAP_ERROR_BREAK
|
||||
if no packets have been processed so far.
|
||||
.PP
|
||||
This routine is safe to use inside a signal handler on UNIX or a console
|
||||
control handler on Windows, as it merely sets a flag that is checked
|
||||
@ -60,7 +61,7 @@ packets arrive and the call completes.
|
||||
.PP
|
||||
.ft B
|
||||
Note also that, in a multi-threaded application, if one thread is
|
||||
blocked in pcap_dispatch(), pcap_loop(), pcap_next(), or pcap_next_ex(),
|
||||
blocked in pcap_dispatch(), pcap_loop(), pcap_next(3PCAP), or pcap_next_ex(3PCAP),
|
||||
a call to pcap_breakloop() in a different thread will not unblock that
|
||||
thread.
|
||||
.ft R
|
||||
@ -99,12 +100,16 @@ or
|
||||
.B pcap_loop()
|
||||
after it is called; at most one more packet might be processed.
|
||||
.PP
|
||||
If \-2 is returned from
|
||||
If
|
||||
.B PCAP_ERROR_BREAK
|
||||
is returned from
|
||||
.B pcap_dispatch()
|
||||
or
|
||||
.BR pcap_loop() ,
|
||||
the flag is cleared, so a subsequent call will resume reading packets.
|
||||
If a positive number is returned, the flag is not cleared, so a
|
||||
subsequent call will return \-2 and clear the flag.
|
||||
subsequent call will return
|
||||
.B PCAP_ERROR_BREAK
|
||||
and clear the flag.
|
||||
.SH SEE ALSO
|
||||
pcap(3PCAP), pcap_loop(3PCAP), pcap_next_ex(3PCAP)
|
||||
pcap(3PCAP)
|
||||
|
@ -17,7 +17,7 @@
|
||||
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
.\"
|
||||
.TH PCAP_CAN_SET_RFMON 3PCAP "3 January 2014"
|
||||
.TH PCAP_CAN_SET_RFMON 3PCAP "31 July 2016"
|
||||
.SH NAME
|
||||
pcap_can_set_rfmon \- check whether monitor mode can be set for a
|
||||
not-yet-activated capture handle
|
||||
@ -54,9 +54,9 @@ The capture handle has already been activated.
|
||||
.TP
|
||||
.B PCAP_ERROR
|
||||
Another error occurred.
|
||||
.B pcap_geterr()
|
||||
.B pcap_geterr(3PCAP)
|
||||
or
|
||||
.B pcap_perror()
|
||||
.B \%pcap_perror(3PCAP)
|
||||
may be called with
|
||||
.I p
|
||||
as an argument to fetch or display a message describing the error.
|
||||
@ -64,7 +64,7 @@ as an argument to fetch or display a message describing the error.
|
||||
Additional error codes may be added in the future; a program should
|
||||
check for 0, 1, and negative, return codes, and treat all negative
|
||||
return codes as errors.
|
||||
.B pcap_statustostr()
|
||||
.B pcap_statustostr(3PCAP)
|
||||
can be called, with a warning or error code as an argument, to fetch a
|
||||
message describing the warning or error code.
|
||||
.SH SEE ALSO
|
||||
|
@ -17,7 +17,7 @@
|
||||
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
.\"
|
||||
.TH PCAP_COMPILE 3PCAP "7 April 2014"
|
||||
.TH PCAP_COMPILE 3PCAP "22 August 2018"
|
||||
.SH NAME
|
||||
pcap_compile \- compile a filter expression
|
||||
.SH SYNOPSIS
|
||||
@ -52,7 +52,9 @@ captured; it is used only when checking for IPv4 broadcast addresses in
|
||||
the filter program. If the netmask of the network on which packets are
|
||||
being captured isn't known to the program, or if packets are being
|
||||
captured on the Linux "any" pseudo-interface that can capture on more
|
||||
than one network, a value of PCAP_NETMASK_UNKNOWN can be supplied; tests
|
||||
than one network, a value of
|
||||
.B PCAP_NETMASK_UNKNOWN
|
||||
can be supplied; tests
|
||||
for IPv4 broadcast addresses will fail to compile, but all other tests in
|
||||
the filter program will be OK.
|
||||
.LP
|
||||
@ -67,14 +69,21 @@ in multiple threads in a single process without some form of mutual
|
||||
exclusion allowing only one thread to call it at any given time.
|
||||
.SH RETURN VALUE
|
||||
.B pcap_compile()
|
||||
returns 0 on success and \-1 on failure.
|
||||
If \-1 is returned,
|
||||
.B pcap_geterr()
|
||||
returns 0 on success and
|
||||
.B PCAP_ERROR
|
||||
on failure. If
|
||||
.B PCAP_ERROR
|
||||
is returned,
|
||||
.B pcap_geterr(3PCAP)
|
||||
or
|
||||
.B pcap_perror()
|
||||
.B pcap_perror(3PCAP)
|
||||
may be called with
|
||||
.I p
|
||||
as an argument to fetch or display the error text.
|
||||
.SH BACKWARD COMPATIBILITY
|
||||
.PP
|
||||
The
|
||||
.B PCAP_NETMASK_UNKNOWN
|
||||
constant became available in libpcap release 1.1.0.
|
||||
.SH SEE ALSO
|
||||
pcap(3PCAP), pcap_setfilter(3PCAP), pcap_freecode(3PCAP),
|
||||
pcap_geterr(3PCAP), pcap-filter(@MAN_MISC_INFO@)
|
||||
|
@ -48,7 +48,7 @@ argument of "any" or
|
||||
can be used to capture packets from all interfaces.
|
||||
.PP
|
||||
The returned handle must be activated with
|
||||
.B pcap_activate()
|
||||
.B pcap_activate(3PCAP)
|
||||
before packets can be captured
|
||||
with it; options for the capture, such as promiscuous mode, can be set
|
||||
on the handle before activating it.
|
||||
@ -69,4 +69,4 @@ is assumed to be able to hold at least
|
||||
.B PCAP_ERRBUF_SIZE
|
||||
chars.
|
||||
.SH SEE ALSO
|
||||
pcap(3PCAP), pcap_activate(3PCAP)
|
||||
pcap(3PCAP)
|
||||
|
@ -37,11 +37,11 @@ specified by
|
||||
.IR p .
|
||||
.PP
|
||||
It must not be called on a pcap descriptor created by
|
||||
.B pcap_create()
|
||||
.B \%pcap_create(3PCAP)
|
||||
that has not yet been activated by
|
||||
.BR pcap_activate() .
|
||||
.BR \%pcap_activate(3PCAP) .
|
||||
.PP
|
||||
.I http://www.tcpdump.org/linktypes.html
|
||||
.I https://www.tcpdump.org/linktypes.html
|
||||
lists the values
|
||||
.B pcap_datalink()
|
||||
can return and describes the packet formats that
|
||||
|
@ -17,7 +17,7 @@
|
||||
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
.\"
|
||||
.TH PCAP_DATALINK_NAME_TO_VAL 3PCAP "5 December 2014"
|
||||
.TH PCAP_DATALINK_NAME_TO_VAL 3PCAP "25 July 2018"
|
||||
.SH NAME
|
||||
pcap_datalink_name_to_val \- get the link-layer header type value
|
||||
corresponding to a header type name
|
||||
@ -41,7 +41,9 @@ removed, to the corresponding link-layer header type value. The
|
||||
translation is case-insensitive.
|
||||
.SH RETURN VALUE
|
||||
.B pcap_datalink_name_to_val()
|
||||
returns the type value on success and \-1 if the name is not a known
|
||||
returns the type value on success and
|
||||
.B PCAP_ERROR
|
||||
if the name is not a known
|
||||
type name..
|
||||
.SH SEE ALSO
|
||||
pcap(3PCAP)
|
||||
|
@ -17,9 +17,10 @@
|
||||
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
.\"
|
||||
.TH PCAP_DATALINK_VAL_TO_NAME 3PCAP "3 January 2014"
|
||||
.TH PCAP_DATALINK_VAL_TO_NAME 3PCAP "12 October 2016"
|
||||
.SH NAME
|
||||
pcap_datalink_val_to_name, pcap_datalink_val_to_description \- get a
|
||||
pcap_datalink_val_to_name, pcap_datalink_val_to_description,
|
||||
pcap_datalink_val_to_description_or_dlt \- get a
|
||||
name or description for a link-layer header type value
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
@ -30,6 +31,7 @@ name or description for a link-layer header type value
|
||||
.ft B
|
||||
const char *pcap_datalink_val_to_name(int dlt);
|
||||
const char *pcap_datalink_val_to_description(int dlt);
|
||||
const char *pcap_datalink_val_to_description_or_dlt(int dlt);
|
||||
.ft
|
||||
.fi
|
||||
.SH DESCRIPTION
|
||||
@ -52,3 +54,13 @@ link-layer header type.
|
||||
is returned if the type value does not correspond to a known
|
||||
.B DLT_
|
||||
value.
|
||||
.PP
|
||||
.B pcap_datalink_val_to_description_or_dlt()
|
||||
translates a link-layer header type value to a short description of that
|
||||
link-layer header type just like pcap_datalink_val_to_description.
|
||||
If the type value does not correspond to a known
|
||||
.B DLT_
|
||||
value, the string "DLT n" is returned, where n is the value of
|
||||
the dlt argument.
|
||||
.SH SEE ALSO
|
||||
pcap(3PCAP)
|
||||
|
@ -35,11 +35,11 @@ u_char *sp);
|
||||
.SH DESCRIPTION
|
||||
.B pcap_dump()
|
||||
outputs a packet to the ``savefile'' opened with
|
||||
.BR pcap_dump_open() .
|
||||
.BR pcap_dump_open(3PCAP) .
|
||||
Note that its calling arguments are suitable for use with
|
||||
.B pcap_dispatch()
|
||||
.B pcap_dispatch(3PCAP)
|
||||
or
|
||||
.BR pcap_loop() .
|
||||
.BR pcap_loop(3PCAP) .
|
||||
If called directly, the
|
||||
.I user
|
||||
parameter is of type
|
||||
@ -47,5 +47,4 @@ parameter is of type
|
||||
as returned by
|
||||
.BR pcap_dump_open() .
|
||||
.SH SEE ALSO
|
||||
pcap(3PCAP), pcap_dump_open(3PCAP), pcap_dispatch(3PCAP),
|
||||
pcap_loop(3PCAP)
|
||||
pcap(3PCAP)
|
||||
|
@ -33,6 +33,6 @@ FILE *pcap_dump_file(pcap_dumper_t *p);
|
||||
.SH DESCRIPTION
|
||||
.B pcap_dump_file()
|
||||
returns the standard I/O stream of the ``savefile'' opened by
|
||||
.BR pcap_dump_open() .
|
||||
.BR pcap_dump_open(3PCAP) .
|
||||
.SH SEE ALSO
|
||||
pcap(3PCAP)
|
||||
|
@ -17,7 +17,7 @@
|
||||
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
.\"
|
||||
.TH PCAP_DUMP_FLUSH 3PCAP "3 January 2014"
|
||||
.TH PCAP_DUMP_FLUSH 3PCAP "25 July 2018"
|
||||
.SH NAME
|
||||
pcap_dump_flush \- flush to a savefile packets dumped
|
||||
.SH SYNOPSIS
|
||||
@ -34,10 +34,12 @@ int pcap_dump_flush(pcap_dumper_t *p);
|
||||
.B pcap_dump_flush()
|
||||
flushes the output buffer to the ``savefile,'' so that any packets
|
||||
written with
|
||||
.B pcap_dump()
|
||||
.B pcap_dump(3PCAP)
|
||||
but not yet written to the ``savefile'' will be written.
|
||||
.SH RETURN VALUE
|
||||
.B pcap_dump_flush()
|
||||
returns 0 on success and \-1 on failure.
|
||||
returns 0 on success and
|
||||
.B PCAP_ERROR
|
||||
on failure.
|
||||
.SH SEE ALSO
|
||||
pcap(3PCAP), pcap_dump_open(3PCAP), pcap_dump(3PCAP)
|
||||
pcap(3PCAP), pcap_dump_open(3PCAP)
|
||||
|
@ -17,7 +17,7 @@
|
||||
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
.\"
|
||||
.TH PCAP_DUMP_FTELL 3PCAP "3 January 2014"
|
||||
.TH PCAP_DUMP_FTELL 3PCAP "25 July 2018"
|
||||
.SH NAME
|
||||
pcap_dump_ftell, pcap_dump_ftell64 \- get the current file offset for a savefile being written
|
||||
.SH SYNOPSIS
|
||||
@ -36,11 +36,11 @@ int64_t pcap_dump_ftell64(pcap_dumper_t *p);
|
||||
.B pcap_dump_ftell()
|
||||
returns the current file position for the ``savefile'', representing the
|
||||
number of bytes written by
|
||||
.B pcap_dump_open()
|
||||
.B pcap_dump_open(3PCAP)
|
||||
and
|
||||
.BR pcap_dump() .
|
||||
\-1 is returned on error.
|
||||
If the current file position does not fit in a
|
||||
.BR pcap_dump(3PCAP) .
|
||||
.B PCAP_ERROR
|
||||
is returned on error. If the current file position does not fit in a
|
||||
.BR long ,
|
||||
it will be truncated; this can happen on 32-bit UNIX-like systems with
|
||||
large file support and on Windows.
|
||||
@ -52,6 +52,7 @@ so if file offsets that don't fit in a
|
||||
but that fit in a
|
||||
.B int64_t
|
||||
are supported, this will return the file offset without truncation.
|
||||
\-1 is returned on error.
|
||||
.B PCAP_ERROR
|
||||
is returned on error.
|
||||
.SH SEE ALSO
|
||||
pcap(3PCAP), pcap_dump_open(3PCAP), pcap_dump(3PCAP)
|
||||
pcap(3PCAP)
|
||||
|
@ -17,7 +17,7 @@
|
||||
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
.\"
|
||||
.TH PCAP_DUMP_OPEN 3PCAP "16 February 2015"
|
||||
.TH PCAP_DUMP_OPEN 3PCAP "22 August 2018"
|
||||
.SH NAME
|
||||
pcap_dump_open, pcap_dump_fopen \- open a file to which to write packets
|
||||
.SH SYNOPSIS
|
||||
@ -48,26 +48,28 @@ for
|
||||
.PP
|
||||
.B pcap_dump_fopen()
|
||||
is called to write data to an existing open stream
|
||||
.IR fp .
|
||||
.IR fp ;
|
||||
this stream will be closed by a subsequent call to
|
||||
.BR pcap_dump_close(3PCAP) .
|
||||
Note that on Windows, that stream should be opened in binary mode.
|
||||
.PP
|
||||
.I p
|
||||
is a capture or ``savefile'' handle returned by an earlier call to
|
||||
.B pcap_create()
|
||||
.B pcap_create(3PCAP)
|
||||
and activated by an earlier call to
|
||||
.BR pcap_activate() ,
|
||||
.BR \%pcap_activate(3PCAP) ,
|
||||
or returned by an earlier call to
|
||||
.BR pcap_open_offline() ,
|
||||
.BR pcap_open_live() ,
|
||||
.BR \%pcap_open_offline(3PCAP) ,
|
||||
.BR pcap_open_live(3PCAP) ,
|
||||
or
|
||||
.BR pcap_open_dead() .
|
||||
.BR pcap_open_dead(3PCAP) .
|
||||
The time stamp precision, link-layer type, and snapshot length from
|
||||
.I p
|
||||
are used as the link-layer type and snapshot length of the output file.
|
||||
.PP
|
||||
.B pcap_dump_open_append()
|
||||
is like
|
||||
.B pcap_dump_open
|
||||
.B pcap_dump_open()
|
||||
but does not create the file if it does not exist and, if it does
|
||||
already exist, and is a pcap file with the same byte order as the host
|
||||
opening the file, and has the same time stamp precision, link-layer
|
||||
@ -78,19 +80,24 @@ it will write new packets at the end of the file.
|
||||
A pointer to a
|
||||
.B pcap_dumper_t
|
||||
structure to use in subsequent
|
||||
.B pcap_dump()
|
||||
.B pcap_dump(3PCAP)
|
||||
and
|
||||
.B pcap_dump_close()
|
||||
.B pcap_dump_close(3PCAP)
|
||||
calls is returned on success.
|
||||
.B NULL
|
||||
is returned on failure.
|
||||
If
|
||||
.B NULL
|
||||
is returned,
|
||||
.B pcap_geterr(\fIp\fB)
|
||||
.B pcap_geterr(3PCAP)
|
||||
can be used to get the error text.
|
||||
.SH BACKWARD COMPATIBILITY
|
||||
.PP
|
||||
The
|
||||
.B pcap_dump_open_append()
|
||||
function became available in libpcap release 1.7.2. In previous
|
||||
releases, there is no support for appending packets to an existing
|
||||
savefile.
|
||||
.SH SEE ALSO
|
||||
pcap(3PCAP), pcap_create(3PCAP), pcap_activate(3PCAP),
|
||||
\%pcap_open_offline(3PCAP), pcap_open_live(3PCAP), pcap_open_dead(3PCAP),
|
||||
pcap_dump(3PCAP), pcap_dump_close(3PCAP), pcap_geterr(3PCAP),
|
||||
pcap(3PCAP),
|
||||
\%pcap-savefile(@MAN_FILE_FORMATS@)
|
||||
|
@ -34,13 +34,15 @@ FILE *pcap_file(pcap_t *p);
|
||||
.B pcap_file()
|
||||
returns the standard I/O stream of the ``savefile,'' if a ``savefile''
|
||||
was opened with
|
||||
.BR pcap_open_offline() ,
|
||||
or NULL, if a network device was opened with
|
||||
.B pcap_create()
|
||||
.BR pcap_open_offline(3PCAP) ,
|
||||
or
|
||||
.BR NULL ,
|
||||
if a network device was opened with
|
||||
.B pcap_create(3PCAP)
|
||||
and
|
||||
.BR pcap_activate() ,
|
||||
.BR \%pcap_activate(3PCAP) ,
|
||||
or with
|
||||
.BR pcap_open_live() .
|
||||
.BR pcap_open_live(3PCAP) .
|
||||
.PP
|
||||
Note that the Packet Capture library is usually built with large file
|
||||
support, so the standard I/O stream of the ``savefile'' might refer to
|
||||
@ -50,8 +52,8 @@ should, if possible, use calls that support large files on the return
|
||||
value of
|
||||
.B pcap_file()
|
||||
or the value returned by
|
||||
.B fileno()
|
||||
.B fileno(3)
|
||||
when passed the return value of
|
||||
.BR pcap_file() .
|
||||
.SH SEE ALSO
|
||||
pcap(3PCAP), pcap_open_offline(3PCAP)
|
||||
pcap(3PCAP)
|
||||
|
@ -17,7 +17,7 @@
|
||||
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
.\"
|
||||
.TH PCAP_FILENO 3PCAP "7 April 2014"
|
||||
.TH PCAP_FILENO 3PCAP "25 July 2018"
|
||||
.SH NAME
|
||||
pcap_fileno \- get the file descriptor for a live capture
|
||||
.SH SYNOPSIS
|
||||
@ -35,32 +35,31 @@ If
|
||||
.I p
|
||||
refers to a network device that was opened for a live capture using
|
||||
a combination of
|
||||
.B pcap_create()
|
||||
.B pcap_create(3PCAP)
|
||||
and
|
||||
.BR pcap_activate() ,
|
||||
.BR pcap_activate(3PCAP) ,
|
||||
or using
|
||||
.BR pcap_open_live() ,
|
||||
.BR pcap_open_live(3PCAP) ,
|
||||
.B pcap_fileno()
|
||||
returns the file descriptor from which captured packets are read.
|
||||
.LP
|
||||
If
|
||||
.I p
|
||||
refers to a ``savefile'' that was opened using functions such as
|
||||
.BR pcap_open_offline()
|
||||
.BR pcap_open_offline(3PCAP)
|
||||
or
|
||||
.BR pcap_fopen_offline() ,
|
||||
.BR pcap_fopen_offline(3PCAP) ,
|
||||
a ``dead''
|
||||
.B pcap_t
|
||||
opened using
|
||||
.BR pcap_open_dead() ,
|
||||
.BR pcap_open_dead(3PCAP) ,
|
||||
or a
|
||||
.B pcap_t
|
||||
that was created with
|
||||
.B pcap_create()
|
||||
but that has not yet been activated with
|
||||
.BR pcap_activate() ,
|
||||
it returns \-1.
|
||||
it returns
|
||||
.BR PCAP_ERROR .
|
||||
.SH SEE ALSO
|
||||
pcap(3PCAP), pcap_create(3PCAP), pcap_activate(3PCAP),
|
||||
pcap_open_live(3PCAP), pcap_open_offline(3PCAP),
|
||||
\%pcap_fopen_offline(3PCAP), pcap_open_dead(3PCAP)
|
||||
pcap(3PCAP)
|
||||
|
@ -17,7 +17,7 @@
|
||||
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
.\"
|
||||
.TH PCAP_FINDALLDEVS 3PCAP "7 April 2014"
|
||||
.TH PCAP_FINDALLDEVS 3PCAP "22 August 2018"
|
||||
.SH NAME
|
||||
pcap_findalldevs, pcap_freealldevs \- get a list of capture devices, and
|
||||
free that list
|
||||
@ -40,11 +40,11 @@ void pcap_freealldevs(pcap_if_t *alldevs);
|
||||
.SH DESCRIPTION
|
||||
.B pcap_findalldevs()
|
||||
constructs a list of network devices that can be opened with
|
||||
.B pcap_create()
|
||||
.B pcap_create(3PCAP)
|
||||
and
|
||||
.B pcap_activate()
|
||||
.B pcap_activate(3PCAP)
|
||||
or with
|
||||
.BR pcap_open_live() .
|
||||
.BR pcap_open_live(3PCAP) .
|
||||
(Note that there may be network devices that cannot be opened by the
|
||||
process calling
|
||||
.BR pcap_findalldevs() ,
|
||||
@ -194,21 +194,38 @@ for IPv6 addresses, it can be interpreted as if it pointed to a
|
||||
.BR "struct sockaddr_in6".
|
||||
.PP
|
||||
The list of devices must be freed with
|
||||
.BR pcap_freealldevs() ,
|
||||
.BR pcap_freealldevs(3PCAP) ,
|
||||
which frees the list pointed to by
|
||||
.IR alldevs .
|
||||
.SH RETURN VALUE
|
||||
.B pcap_findalldevs()
|
||||
returns 0 on success and \-1 on failure; as indicated, finding no
|
||||
returns 0 on success and
|
||||
.B PCAP_ERROR
|
||||
on failure; as indicated, finding no
|
||||
devices is considered success, rather than failure, so 0 will be
|
||||
returned in that case.
|
||||
If \-1 is returned,
|
||||
returned in that case. If
|
||||
.B PCAP_ERROR
|
||||
is returned,
|
||||
.I errbuf
|
||||
is filled in with an appropriate error message.
|
||||
.I errbuf
|
||||
is assumed to be able to hold at least
|
||||
.B PCAP_ERRBUF_SIZE
|
||||
chars.
|
||||
.SH BACKWARD COMPATIBILITY
|
||||
.PP
|
||||
The
|
||||
.B PCAP_IF_UP
|
||||
and
|
||||
.B PCAP_IF_RUNNING
|
||||
constants became available in libpcap release 1.6.1. The
|
||||
.BR PCAP_IF_WIRELESS ,
|
||||
.BR PCAP_IF_CONNECTION_STATUS ,
|
||||
.BR PCAP_IF_CONNECTION_STATUS_UNKNOWN ,
|
||||
.BR PCAP_IF_CONNECTION_STATUS_CONNECTED ,
|
||||
.BR PCAP_IF_CONNECTION_STATUS_DISCONNECTED ,
|
||||
and
|
||||
.B PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE
|
||||
constants became available in libpcap release 1.9.0.
|
||||
.SH SEE ALSO
|
||||
pcap(3PCAP), pcap_create(3PCAP), pcap_activate(3PCAP),
|
||||
pcap_open_live(3PCAP)
|
||||
pcap(3PCAP)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user