MFV r353141 (by phillip):

Update libpcap from 1.9.0 to 1.9.1.

MFC after:	2 weeks
This commit is contained in:
Cy Schubert 2019-12-21 21:01:03 +00:00
commit 57e22627f9
178 changed files with 17941 additions and 4816 deletions

View File

@ -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 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 Man page improvements
Fix Linux cooked mode userspace filtering (GitHub pull request #429) Fix Linux cooked mode userspace filtering (GitHub pull request #429)
Fix compilation if IPv6 support not enabled Fix compilation if IPv6 support not enabled

View File

@ -9,7 +9,7 @@ if(POLICY CMP0042)
cmake_policy(SET CMP0042 OLD) cmake_policy(SET CMP0042 OLD)
endif() endif()
set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/Modules) set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules)
project(pcap) project(pcap)
@ -135,83 +135,6 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
option(BUILD_WITH_LIBNL "Build with libnl" ON) option(BUILD_WITH_LIBNL "Build with libnl" ON)
endif() 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. # 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_DAG "Disable Endace DAG card support" OFF)
option(DISABLE_SEPTEL "Disable Septel 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) option(DISABLE_SNF "Disable Myricom SNF support" OFF)
@ -289,6 +212,7 @@ include_directories(
include(CheckFunctionExists) include(CheckFunctionExists)
include(CMakePushCheckState) include(CMakePushCheckState)
include(CheckSymbolExists)
if(WIN32) if(WIN32)
@ -310,6 +234,14 @@ if(WIN32)
cmake_pop_check_state() cmake_pop_check_state()
endif(PACKET_FOUND) 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) endif(WIN32)
if(MSVC) if(MSVC)
@ -343,6 +275,11 @@ include(CheckIncludeFiles)
include(CheckStructHasMember) include(CheckStructHasMember)
include(CheckTypeSize) 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. # Header files.
# #
@ -395,12 +332,44 @@ endif(NOT WIN32)
# #
check_function_exists(strerror HAVE_STRERROR) check_function_exists(strerror HAVE_STRERROR)
check_function_exists(strerror_r HAVE_STRERROR_R) 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(strlcpy HAVE_STRLCPY)
check_function_exists(strlcat HAVE_STRLCAT) check_function_exists(strlcat HAVE_STRLCAT)
check_function_exists(snprintf HAVE_SNPRINTF) check_function_exists(snprintf HAVE_SNPRINTF)
check_function_exists(vsnprintf HAVE_VSNPRINTF) 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) 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 # 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 "") set(PCAP_LINK_LIBRARIES "")
include(CheckLibraryExists) include(CheckLibraryExists)
include(CheckSymbolExists)
if(WIN32) if(WIN32)
# #
# We need winsock2.h and ws2tcpip.h. # We need winsock2.h and ws2tcpip.h.
@ -865,11 +833,61 @@ set(PROJECT_SOURCE_LIST_C
) )
if(WIN32) 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() 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) 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) 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) if(NOT HAVE_STRTOK_R)
set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} missing/strtok_r.c) set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} missing/strtok_r.c)
endif(NOT HAVE_STRTOK_R) endif(NOT HAVE_STRTOK_R)
@ -931,13 +949,16 @@ else()
# as it's a Linux, it should use packet sockets, # as it's a Linux, it should use packet sockets,
# instead. # instead.
# #
#
# We need: # We need:
# #
# sys/types.h, because FreeBSD 10's net/bpf.h # sys/types.h, because FreeBSD 10's net/bpf.h
# requires that various BSD-style integer types # requires that various BSD-style integer types
# be defined; # 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, # sys/ioctl.h and, if we have it, sys/ioccom.h,
# because net/bpf.h defines ioctls; # because net/bpf.h defines ioctls;
# #
@ -952,9 +973,9 @@ else()
# of those headers itself. # of those headers itself.
# #
if(HAVE_SYS_IOCCOM_H) 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) 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_SYS_IOCCOM_H)
endif(HAVE_NET_BPF_H) endif(HAVE_NET_BPF_H)
check_include_file(net/pfilt.h HAVE_NET_PFILT_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(PCAP_SUPPORT_DBUS TRUE)
set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} pcap-dbus.c) set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} pcap-dbus.c)
include_directories(${DBUS_INCLUDE_DIRS}) 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(DBUS_FOUND)
endif(NOT DISABLE_DBUS) endif(NOT DISABLE_DBUS)
@ -1582,7 +1624,7 @@ if(ENABLE_REMOTE)
# the check. # the check.
# #
cmake_push_check_state() 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_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) check_struct_has_member("struct msghdr" msg_flags "ftmacros.h;sys/socket.h" HAVE_STRUCT_MSGHDR_MSG_FLAGS)
cmake_pop_check_state() cmake_pop_check_state()
@ -1597,7 +1639,7 @@ endif(ENABLE_REMOTE)
# #
# Check and add warning options if we have a .devel file. # 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. # 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 # Assume, by default, no support for shared libraries and V7/BSD
# convention for man pages (file formats in section 5, miscellaneous # convention for man pages (devices in section 4, file formats in
# info in section 7, administrative commands and daemons in section 8). # section 5, miscellaneous info in section 7, administrative commands
# and daemons in section 8). Individual cases can override this.
# Individual cases can override this. # Individual cases can override this.
# #
set(MAN_DEVICES 4)
set(MAN_FILE_FORMATS 5) set(MAN_FILE_FORMATS 5)
set(MAN_MISC_INFO 7) set(MAN_MISC_INFO 7)
set(MAN_ADMIN_COMMANDS 8) set(MAN_ADMIN_COMMANDS 8)
@ -1869,6 +1913,7 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "OSF1")
# #
set(MAN_FILE_FORMATS 4) set(MAN_FILE_FORMATS 4)
set(MAN_MISC_INFO 5) set(MAN_MISC_INFO 5)
set(MAN_DEVICES 7)
elseif(CMAKE_SYSTEM_NAME STREQUAL "SunOS" AND CMAKE_SYSTEM_VERSION MATCHES "5[.][0-9.]*") elseif(CMAKE_SYSTEM_NAME STREQUAL "SunOS" AND CMAKE_SYSTEM_VERSION MATCHES "5[.][0-9.]*")
# #
# SunOS 5.x. # 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_ADMIN_COMMANDS 1m)
set(MAN_FILE_FORMATS 4) set(MAN_FILE_FORMATS 4)
set(MAN_MISC_INFO 5) set(MAN_MISC_INFO 5)
set(MAN_DEVICES 7D)
endif() endif()
endif() endif()
@ -1944,6 +1990,16 @@ if(BUILD_SHARED_LIBS)
add_dependencies(${LIBRARY_NAME} SerializeTarget) add_dependencies(${LIBRARY_NAME} SerializeTarget)
set_target_properties(${LIBRARY_NAME} PROPERTIES set_target_properties(${LIBRARY_NAME} PROPERTIES
COMPILE_DEFINITIONS BUILDING_PCAP) 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) endif(BUILD_SHARED_LIBS)
add_library(${LIBRARY_NAME}_static STATIC add_library(${LIBRARY_NAME}_static STATIC
@ -2020,6 +2076,118 @@ if(NOT C_ADDITIONAL_FLAGS STREQUAL "")
set_target_properties(${LIBRARY_NAME}_static PROPERTIES COMPILE_FLAGS ${C_ADDITIONAL_FLAGS}) set_target_properties(${LIBRARY_NAME}_static PROPERTIES COMPILE_FLAGS ${C_ADDITIONAL_FLAGS})
endif() 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 # Write out the config.h file
###################################### ######################################
@ -2079,6 +2247,7 @@ set(MAN3PCAP_EXPAND
pcap_list_tstamp_types.3pcap.in pcap_list_tstamp_types.3pcap.in
pcap_open_dead.3pcap.in pcap_open_dead.3pcap.in
pcap_open_offline.3pcap.in pcap_open_offline.3pcap.in
pcap_set_immediate_mode.3pcap.in
pcap_set_tstamp_precision.3pcap.in pcap_set_tstamp_precision.3pcap.in
pcap_set_tstamp_type.3pcap.in pcap_set_tstamp_type.3pcap.in
) )
@ -2114,9 +2283,8 @@ set(MAN3PCAP_NOEXPAND
pcap_open_live.3pcap pcap_open_live.3pcap
pcap_set_buffer_size.3pcap pcap_set_buffer_size.3pcap
pcap_set_datalink.3pcap pcap_set_datalink.3pcap
pcap_set_immediate_mode.3pcap
pcap_set_promisc.3pcap pcap_set_promisc.3pcap
pcap_set_protocol.3pcap pcap_set_protocol_linux.3pcap
pcap_set_rfmon.3pcap pcap_set_rfmon.3pcap
pcap_set_snaplen.3pcap pcap_set_snaplen.3pcap
pcap_set_timeout.3pcap pcap_set_timeout.3pcap
@ -2179,11 +2347,13 @@ if(WIN32)
endif(NOT MINGW) endif(NOT MINGW)
endif(MSVC AND CMAKE_SIZEOF_VOID_P EQUAL 8) endif(MSVC AND CMAKE_SIZEOF_VOID_P EQUAL 8)
else(WIN32) 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) endif(WIN32)
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/pcap/ DESTINATION include/pcap) 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.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 # 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. # pcap-config and process man pages and arrange that they be installed.
@ -2223,8 +2393,8 @@ if(NOT MSVC)
foreach(LIB ${PCAP_LINK_LIBRARIES}) foreach(LIB ${PCAP_LINK_LIBRARIES})
set(LIBS "${LIBS} -l${LIB}") set(LIBS "${LIBS} -l${LIB}")
endforeach(LIB) endforeach(LIB)
configure_file(${CMAKE_SOURCE_DIR}/pcap-config.in ${CMAKE_CURRENT_BINARY_DIR}/pcap-config @ONLY) configure_file(${CMAKE_CURRENT_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}/libpcap.pc.in ${CMAKE_CURRENT_BINARY_DIR}/libpcap.pc @ONLY)
install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/pcap-config DESTINATION bin) install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/pcap-config DESTINATION bin)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libpcap.pc DESTINATION lib/pkgconfig) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libpcap.pc DESTINATION lib/pkgconfig)
@ -2236,17 +2406,17 @@ if(NOT MSVC)
# #
set(MAN1 "") set(MAN1 "")
foreach(MANPAGE ${MAN1_NOEXPAND}) foreach(MANPAGE ${MAN1_NOEXPAND})
set(MAN1 ${MAN1} ${CMAKE_SOURCE_DIR}/${MANPAGE}) set(MAN1 ${MAN1} ${CMAKE_CURRENT_SOURCE_DIR}/${MANPAGE})
endforeach(MANPAGE) endforeach(MANPAGE)
install(FILES ${MAN1} DESTINATION ${CMAKE_INSTALL_MANDIR}/man1) install(FILES ${MAN1} DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
set(MAN3PCAP "") set(MAN3PCAP "")
foreach(MANPAGE ${MAN3PCAP_NOEXPAND}) foreach(MANPAGE ${MAN3PCAP_NOEXPAND})
set(MAN3PCAP ${MAN3PCAP} ${CMAKE_SOURCE_DIR}/${MANPAGE}) set(MAN3PCAP ${MAN3PCAP} ${CMAKE_CURRENT_SOURCE_DIR}/${MANPAGE})
endforeach(MANPAGE) endforeach(MANPAGE)
foreach(TEMPLATE_MANPAGE ${MAN3PCAP_EXPAND}) foreach(TEMPLATE_MANPAGE ${MAN3PCAP_EXPAND})
string(REPLACE ".in" "" MANPAGE ${TEMPLATE_MANPAGE}) 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}) set(MAN3PCAP ${MAN3PCAP} ${CMAKE_CURRENT_BINARY_DIR}/${MANPAGE})
endforeach(TEMPLATE_MANPAGE) endforeach(TEMPLATE_MANPAGE)
install(FILES ${MAN3PCAP} DESTINATION ${CMAKE_INSTALL_MANDIR}/man3) install(FILES ${MAN3PCAP} DESTINATION ${CMAKE_INSTALL_MANDIR}/man3)
@ -2270,7 +2440,7 @@ if(NOT MSVC)
set(MANFILE "") set(MANFILE "")
foreach(TEMPLATE_MANPAGE ${MANFILE_EXPAND}) foreach(TEMPLATE_MANPAGE ${MANFILE_EXPAND})
string(REPLACE ".manfile.in" ".${MAN_FILE_FORMATS}" MANPAGE ${TEMPLATE_MANPAGE}) 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}) set(MANFILE ${MANFILE} ${CMAKE_CURRENT_BINARY_DIR}/${MANPAGE})
endforeach(TEMPLATE_MANPAGE) endforeach(TEMPLATE_MANPAGE)
install(FILES ${MANFILE} DESTINATION ${CMAKE_INSTALL_MANDIR}/man${MAN_FILE_FORMATS}) install(FILES ${MANFILE} DESTINATION ${CMAKE_INSTALL_MANDIR}/man${MAN_FILE_FORMATS})
@ -2278,7 +2448,7 @@ if(NOT MSVC)
set(MANMISC "") set(MANMISC "")
foreach(TEMPLATE_MANPAGE ${MANMISC_EXPAND}) foreach(TEMPLATE_MANPAGE ${MANMISC_EXPAND})
string(REPLACE ".manmisc.in" ".${MAN_MISC_INFO}" MANPAGE ${TEMPLATE_MANPAGE}) 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}) set(MANMISC ${MANMISC} ${CMAKE_CURRENT_BINARY_DIR}/${MANPAGE})
endforeach(TEMPLATE_MANPAGE) endforeach(TEMPLATE_MANPAGE)
install(FILES ${MANMISC} DESTINATION ${CMAKE_INSTALL_MANDIR}/man${MAN_MISC_INFO}) install(FILES ${MANMISC} DESTINATION ${CMAKE_INSTALL_MANDIR}/man${MAN_MISC_INFO})

View File

@ -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 would not be too intrusive, it would be best to contribute some development time
and open a pull request instead. 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! to the mailing list tcpdump-workers@lists.tcpdump.org and ask!

View File

@ -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: The current maintainers (in alphabetical order):
Bill Fenner <fenner at research dot att dot com>
Denis Ovsienko <denis at ovsienko dot info> 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> 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> 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> Akos Vandra <axos88 at gmail dot com>
Alan Bawden <Alan at LCS dot MIT dot EDU> Alan Bawden <Alan at LCS dot MIT dot EDU>
Albert Chin <china at thewrittenword dot com> Albert Chin <china at thewrittenword dot com>
Alexander 'Leo' Bergolth <Leo dot Bergolth at wu-wien dot ac dot at> Alexander 'Leo' Bergolth <Leo dot Bergolth at wu-wien dot ac dot at>
Alexey Kuznetsov <kuznet at ms2 dot inr dot ac dot ru> Alexey Kuznetsov <kuznet at ms2 dot inr dot ac dot ru>
Ali Abdulkadir <autostart dot ini at gmail dot com>
Alon Bar-Lev <alonbl at sourceforge dot net> Alon Bar-Lev <alonbl at sourceforge dot net>
Andres Perera <andres dot p at zoho dot com> Andres Perera <andres dot p at zoho dot com>
Andrew Brown <atatat at atatdot dot net> Andrew Brown <atatat at atatdot dot net>
@ -62,6 +59,7 @@ Additional people who have contributed patches:
Gabor Tatarka <gabor dot tatarka at ericsson dot com> Gabor Tatarka <gabor dot tatarka at ericsson dot com>
Garrett Cooper <yaberauneya at sourceforge dot net> Garrett Cooper <yaberauneya at sourceforge dot net>
George Neville-Neil <gnn at freebsd dot org> George Neville-Neil <gnn at freebsd dot org>
Gerard Garcia <nouboh at gmail dot com>
Gianluca Varenni <gianluca dot varenni at gmail dot com> Gianluca Varenni <gianluca dot varenni at gmail dot com>
Gilbert Hoyek <gil_hoyek at hotmail dot com> Gilbert Hoyek <gil_hoyek at hotmail dot com>
Gisle Vanem <gvanem at yahoo dot no> Gisle Vanem <gvanem at yahoo dot no>
@ -99,6 +97,7 @@ Additional people who have contributed patches:
Koryn Grant <koryn at endace dot com> Koryn Grant <koryn at endace dot com>
Kris Katterjohn <katterjohn at gmail dot com> Kris Katterjohn <katterjohn at gmail dot com>
Krzysztof Halasa <khc at pm dot waw dot pl> Krzysztof Halasa <khc at pm dot waw dot pl>
Lennert Buytenhek <buytenh at wantstofly dot org>
Lorenzo Cavallaro <sullivan at sikurezza dot org> Lorenzo Cavallaro <sullivan at sikurezza dot org>
Loris Degioanni <loris at netgroup-serv dot polito dot it> Loris Degioanni <loris at netgroup-serv dot polito dot it>
Love Hörnquist-Åstrand <lha at stacken dot kth dot se> Love Hörnquist-Åstrand <lha at stacken dot kth dot se>
@ -114,6 +113,7 @@ Additional people who have contributed patches:
Márton Németh <nm127 at freemail dot hu> Márton Németh <nm127 at freemail dot hu>
Matthew Luckie <mjl at luckie dot org dot nz> Matthew Luckie <mjl at luckie dot org dot nz>
Max Laier <max at love2party dot net> Max Laier <max at love2party dot net>
Michal Kubecek <mkubecek at suse dot cz>
Michal Labedzki <michal dot labedzki at tieto dot com> Michal Labedzki <michal dot labedzki at tieto dot com>
Michal Sekletar <msekleta at redhat dot com> Michal Sekletar <msekleta at redhat dot com>
Mike Frysinger <vapier at gmail 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> Olaf Kirch <okir at caldera dot de>
Ollie Wild <aaw at users dot sourceforge dot net> Ollie Wild <aaw at users dot sourceforge dot net>
Onno van der Linden <onno at simplex dot nl> 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 Marie <mycroft at virgaria dot org>
Patrick McHardy <kaber at trash not net> Patrick McHardy <kaber at trash not net>
Paul Mundt <lethal at linux-sh dot org> Paul Mundt <lethal at linux-sh dot org>
@ -145,6 +145,8 @@ Additional people who have contributed patches:
Rick Jones <raj at cup dot hp dot com> Rick Jones <raj at cup dot hp dot com>
Robert Edmonds <stu-42 at sourceforge dot net> Robert Edmonds <stu-42 at sourceforge dot net>
Roberto Mariani <jelot-tcpdump at jelot dot it> Roberto Mariani <jelot-tcpdump at jelot dot it>
Rongxi Li <rongxi dot li at chaitin dot com>
Roland Dreier <roland at purestorage dot com>
Romain Francoise <rfrancoise at debian dot org> Romain Francoise <rfrancoise at debian dot org>
Sagun Shakya <sagun dot shakya at sun dot com> Sagun Shakya <sagun dot shakya at sun dot com>
Scott Barron <sb125499 at ohiou dot edu> Scott Barron <sb125499 at ohiou dot edu>
@ -167,6 +169,7 @@ Additional people who have contributed patches:
Wesley Shields <wxs at FreeBSD dot org> Wesley Shields <wxs at FreeBSD dot org>
Xianjie Zhang <xzhang at cup dot hp dot com> Xianjie Zhang <xzhang at cup dot hp dot com>
Xin Li <delphij at FreeBSD dot org> Xin Li <delphij at FreeBSD dot org>
Xue Jiang Qing <xuejianqing at star-net dot cn>
Yen Yen Lim Yen Yen Lim
Yoann Vandoorselaere <yoann at prelude-ids dot org> Yoann Vandoorselaere <yoann at prelude-ids dot org>
Yvan Vanhullebus <vanhu at sourceforge dot net> Yvan Vanhullebus <vanhu at sourceforge dot net>
@ -176,5 +179,8 @@ The original LBL crew:
Craig Leres Craig Leres
Van Jacobson Van Jacobson
Past maintainers: 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/ Jun-ichiro itojun Hagino <itojun at iijlab dot net> Also see: http://www.wide.ad.jp/itojun-award/

View File

@ -69,10 +69,6 @@ before /usr/ucb or else:
before running configure. (You might have to do a "make distclean" before running configure. (You might have to do a "make distclean"
if you already ran configure once). 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 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 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 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 CMakeLists.txt - CMake file
CONTRIBUTING - guidelines for contributing CONTRIBUTING - guidelines for contributing
CREDITS - people that have helped libpcap along CREDITS - people that have helped libpcap along
INSTALL.txt - this file INSTALL.md - this file
LICENSE - the license under which tcpdump is distributed LICENSE - the license under which tcpdump is distributed
Makefile.in - compilation rules (input to the configure script) Makefile.in - compilation rules (input to the configure script)
README - description of distribution README.md - description of distribution
README.aix - notes on using libpcap on AIX doc/README.aix - notes on using libpcap on AIX
README.dag - notes on using libpcap to capture on Endace DAG devices doc/README.dag - notes on using libpcap to capture on Endace DAG devices
README.hpux - notes on using libpcap on HP-UX doc/README.hpux - notes on using libpcap on HP-UX
README.linux - notes on using libpcap on Linux doc/README.linux.md - notes on using libpcap on Linux
README.macos - notes on using libpcap on macOS doc/README.macos - notes on using libpcap on macOS
README.septel - notes on using libpcap to capture on Intel/Septel devices doc/README.septel - notes on using libpcap to capture on Intel/Septel devices
README.sita - notes on using libpcap to capture on SITA devices doc/README.sita - notes on using libpcap to capture on SITA devices
README.tru64 - notes on using libpcap on Digital/Tru64 UNIX doc/README.tru64 - notes on using libpcap on Digital/Tru64 UNIX
README.Win32 - notes on using libpcap on Win32 systems (with WinPcap) doc/README.Win32 - notes on using libpcap on Win32 systems (with Npcap)
VERSION - version of this release VERSION - version of this release
acconfig.h - support for post-2.13 autoconf acconfig.h - support for post-2.13 autoconf
aclocal.m4 - autoconf macros aclocal.m4 - autoconf macros
arcnet.h - ARCNET definitions arcnet.h - ARCNET definitions
atmuni31.h - ATM Q.2931 definitions atmuni31.h - ATM Q.2931 definitions
bpf/net - copy of bpf_filter.c
bpf_dump.c - BPF program printing routines 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 bpf_image.c - BPF disassembly routine
config.guess - autoconf support config.guess - autoconf support
config.h.in - autoconf input config.h.in - autoconf input

View File

@ -69,7 +69,7 @@ INSTALL_RPCAPD=@INSTALL_RPCAPD@
EXTRA_NETWORK_LIBS=@EXTRA_NETWORK_LIBS@ EXTRA_NETWORK_LIBS=@EXTRA_NETWORK_LIBS@
# Standard CFLAGS for building members of a shared library # Standard CFLAGS for building members of a shared library
FULL_CFLAGS = $(CCOPT) $(SHLIB_CCOPT) $(INCLS) $(DEFS) $(CFLAGS) FULL_CFLAGS = $(CCOPT) @V_LIB_CCOPT_FAT@ $(SHLIB_CCOPT) $(INCLS) $(DEFS) $(CFLAGS)
INSTALL = @INSTALL@ INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
@ -117,6 +117,7 @@ PUBHDR = \
pcap/nflog.h \ pcap/nflog.h \
pcap/pcap.h \ pcap/pcap.h \
pcap/sll.h \ pcap/sll.h \
pcap/socket.h \
pcap/vlan.h \ pcap/vlan.h \
pcap/usb.h pcap/usb.h
@ -168,6 +169,7 @@ MAN3PCAP_EXPAND = \
pcap_list_tstamp_types.3pcap.in \ pcap_list_tstamp_types.3pcap.in \
pcap_open_dead.3pcap.in \ pcap_open_dead.3pcap.in \
pcap_open_offline.3pcap.in \ pcap_open_offline.3pcap.in \
pcap_set_immediate_mode.3pcap.in \
pcap_set_tstamp_precision.3pcap.in \ pcap_set_tstamp_precision.3pcap.in \
pcap_set_tstamp_type.3pcap.in pcap_set_tstamp_type.3pcap.in
@ -203,9 +205,8 @@ MAN3PCAP_NOEXPAND = \
pcap_open_live.3pcap \ pcap_open_live.3pcap \
pcap_set_buffer_size.3pcap \ pcap_set_buffer_size.3pcap \
pcap_set_datalink.3pcap \ pcap_set_datalink.3pcap \
pcap_set_immediate_mode.3pcap \
pcap_set_promisc.3pcap \ pcap_set_promisc.3pcap \
pcap_set_protocol.3pcap \ pcap_set_protocol_linux.3pcap \
pcap_set_rfmon.3pcap \ pcap_set_rfmon.3pcap \
pcap_set_snaplen.3pcap \ pcap_set_snaplen.3pcap \
pcap_set_timeout.3pcap \ pcap_set_timeout.3pcap \
@ -235,21 +236,13 @@ EXTRA_DIST = \
ChmodBPF/StartupParameters.plist \ ChmodBPF/StartupParameters.plist \
CREDITS \ CREDITS \
CMakeLists.txt \ CMakeLists.txt \
INSTALL.txt \ INSTALL.md \
LICENSE \ LICENSE \
Makefile.in \ Makefile.in \
Makefile-devel-adds \ Makefile-devel-adds \
README \ README.md \
README.aix \ doc \
README.dag \ CONTRIBUTING.md \
README.hpux \
README.linux \
README.macos \
README.septel \
README.sita \
README.tru64 \
README.Win32 \
CONTRIBUTING \
TODO \ TODO \
VERSION \ VERSION \
aclocal.m4 \ aclocal.m4 \
@ -284,10 +277,14 @@ EXTRA_DIST = \
lbl/os-sunos4.h \ lbl/os-sunos4.h \
lbl/os-ultrix4.h \ lbl/os-ultrix4.h \
libpcap.pc.in \ libpcap.pc.in \
missing/asprintf.c \
missing/getopt.c \ missing/getopt.c \
missing/getopt.h \ missing/getopt.h \
missing/snprintf.c \ missing/snprintf.c \
missing/strlcat.c \
missing/strlcpy.c \
missing/strtok_r.c \ missing/strtok_r.c \
missing/win_asprintf.c \
missing/win_snprintf.c \ missing/win_snprintf.c \
mkdep \ mkdep \
msdos/bin2c.c \ msdos/bin2c.c \
@ -355,16 +352,18 @@ EXTRA_DIST = \
rpcapd/fileconf.c \ rpcapd/fileconf.c \
rpcapd/fileconf.h \ rpcapd/fileconf.h \
rpcapd/log.h \ rpcapd/log.h \
rpcapd/log-stderr.c \ rpcapd/log.c \
rpcapd/org.tcpdump.rpcapd.plist \ rpcapd/org.tcpdump.rpcapd.plist \
rpcapd/rpcapd.c \ rpcapd/rpcapd.c \
rpcapd/rpcapd.h \ rpcapd/rpcapd.h \
rpcapd/rpcapd.inetd.conf \ rpcapd/rpcapd.inetd.conf \
rpcapd/rpcapd.manadmin.in \ rpcapd/rpcapd.manadmin.in \
rpcapd/rpcapd-config.manfile.in \
rpcapd/rpcapd.rc \ rpcapd/rpcapd.rc \
rpcapd/rpcapd.socket \ rpcapd/rpcapd.socket \
rpcapd/rpcapd.xinetd.conf \ rpcapd/rpcapd.xinetd.conf \
rpcapd/rpcapd@.service \ rpcapd/rpcapd@.service \
rpcapd/win32-svc.c \
rpcapd/win32-svc.h \ rpcapd/win32-svc.h \
sockutils.c \ sockutils.c \
sockutils.h \ sockutils.h \
@ -424,7 +423,7 @@ libpcap.dylib: $(OBJ)
MAJOR_VER=A; \ MAJOR_VER=A; \
COMPAT_VER=1; \ COMPAT_VER=1; \
CURRENT_VER=`sed 's/[^0-9.].*$$//' $(srcdir)/VERSION`; \ 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) \ -o libpcap.$$VER.dylib $(OBJ) $(ADDLOBJS) $(LIBS) \
-install_name $(libdir)/libpcap.$$MAJOR_VER.dylib \ -install_name $(libdir)/libpcap.$$MAJOR_VER.dylib \
-compatibility_version $$COMPAT_VER \ -compatibility_version $$COMPAT_VER \
@ -496,9 +495,18 @@ grammar.o: grammar.c scanner.h
gencode.o: $(srcdir)/gencode.c grammar.h scanner.h gencode.o: $(srcdir)/gencode.c grammar.h scanner.h
$(CC) $(FULL_CFLAGS) -c $(srcdir)/gencode.c $(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 snprintf.o: $(srcdir)/missing/snprintf.c
$(CC) $(FULL_CFLAGS) -o $@ -c $(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 strtok_r.o: $(srcdir)/missing/strtok_r.c
$(CC) $(FULL_CFLAGS) -o $@ -c $(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 && \ rm -f pcap_datalink_val_to_description.3pcap && \
$(LN_S) pcap_datalink_val_to_name.3pcap \ $(LN_S) pcap_datalink_val_to_name.3pcap \
pcap_datalink_val_to_description.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 && \ rm -f pcap_dump_fopen.3pcap && \
$(LN_S) pcap_dump_open.3pcap pcap_dump_fopen.3pcap && \ $(LN_S) pcap_dump_open.3pcap pcap_dump_fopen.3pcap && \
rm -f pcap_freealldevs.3pcap && \ rm -f pcap_freealldevs.3pcap && \
@ -751,7 +762,7 @@ tags: $(TAGFILES)
releasetar: releasetar:
@cwd=`pwd` ; dir=`basename $$cwd` ; name=$(PROG)-`cat VERSION` ; \ @cwd=`pwd` ; dir=`basename $$cwd` ; name=$(PROG)-`cat VERSION` ; \
mkdir $$name; \ mkdir $$name; \
tar cf - $(CSRC) $(HDR) $(MAN1) $(MAN3PCAP_EXPAND) \ tar -c --exclude='*~' -f - $(CSRC) $(HDR) $(MAN1) $(MAN3PCAP_EXPAND) \
$(MAN3PCAP_NOEXPAND) $(MANFILE) $(MANMISC) $(EXTRA_DIST) | \ $(MAN3PCAP_NOEXPAND) $(MANFILE) $(MANMISC) $(EXTRA_DIST) | \
(cd $$name; tar xf -); \ (cd $$name; tar xf -); \
tar -c -z -f $$name.tar.gz $$name; \ tar -c -z -f $$name.tar.gz $$name; \

View File

@ -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.

View File

@ -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 To report bugs and other problems, contribute patches, request a
feature, provide generic feedback etc please see the file feature, provide generic feedback etc please see the file
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 LIBPCAP 1.x.y
Now maintained by "The Tcpdump Group" Now maintained by "The Tcpdump Group"
https://www.tcpdump.org https://www.tcpdump.org
Anonymous Git is available via: 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 formerly from Lawrence Berkeley National Laboratory
Network Research Group <libpcap@ee.lbl.gov> 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 https://www.tcpdump.org/other/bpfext42.tar.Z
Linux, in the 2.2 kernel and later kernels, has a "Socket Filter" Linux has a number of BPF based systems, and libpcap does not support
mechanism that accepts BPF filters; see the README.linux file for any of the eBPF mechanisms as yet, although it supports many of the
information on configuring that option. 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: Note to Linux distributions and *BSD systems that include libpcap:

View File

@ -1 +1 @@
1.9.0-PRE-GIT 1.9.1

View File

@ -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 is supported by the compiler and, if so, add it to the macro
dnl specified as the first argument dnl specified as the first argument
dnl 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_DEFUN(AC_LBL_CHECK_COMPILER_OPT,
[ [
AC_MSG_CHECKING([whether the compiler supports the $2 option]) AC_MSG_CHECKING([whether the compiler supports the $2 option])
@ -287,8 +295,38 @@ AC_DEFUN(AC_LBL_CHECK_COMPILER_OPT,
[return 0], [return 0],
[ [
AC_MSG_RESULT([yes]) 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" CFLAGS="$save_CFLAGS"
if test x"$can_add_to_cflags" = "xyes"
then
$1="$$1 $2" $1="$$1 $2"
fi
], ],
[ [
AC_MSG_RESULT([no]) AC_MSG_RESULT([no])
@ -446,7 +484,7 @@ AC_DEFUN(AC_LBL_SHLIBS_INIT,
aix*) aix*)
;; ;;
freebsd*|netbsd*|openbsd*|dragonfly*|linux*|osf*) freebsd*|netbsd*|openbsd*|dragonfly*|linux*|osf*|midipix*)
# #
# Platforms where the linker is the GNU linker # Platforms where the linker is the GNU linker
# or accepts command-line arguments like # or accepts command-line arguments like
@ -463,7 +501,7 @@ AC_DEFUN(AC_LBL_SHLIBS_INIT,
sparc64*) sparc64*)
case "$host_os" in case "$host_os" in
freebsd*|openbsd*) freebsd*|openbsd*|linux*)
PIC_OPT=-fPIC PIC_OPT=-fPIC
;; ;;
esac esac
@ -840,23 +878,58 @@ AC_DEFUN(AC_LBL_DEVEL,
# #
if test "$ac_lbl_cc_dont_try_gcc_dashW" != yes; then if test "$ac_lbl_cc_dont_try_gcc_dashW" != yes; then
AC_LBL_CHECK_UNKNOWN_WARNING_OPTION_ERROR() 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, -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, -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-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 # Warns about safeguards added in case the enums are
# extended # extended
# AC_LBL_CHECK_COMPILER_OPT($1, -Wcovered-switch-default) # 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) # This can cause problems with ntohs(), ntohl(),
AC_LBL_CHECK_COMPILER_OPT($1, -Wformat-nonliteral) # htons(), and htonl() on some platforms, such
AC_LBL_CHECK_COMPILER_OPT($1, -Wunreachable-code) # 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 fi
AC_LBL_CHECK_DEPENDENCY_GENERATION_OPT() AC_LBL_CHECK_DEPENDENCY_GENERATION_OPT()
# #

View File

@ -51,7 +51,7 @@
#include <sys/time.h> #include <sys/time.h>
#endif /* _WIN32 */ #endif /* _WIN32 */
#include <pcap/bpf.h> #include <pcap-int.h>
#include <stdlib.h> #include <stdlib.h>
@ -328,11 +328,17 @@ bpf_filter_with_aux_data(const struct bpf_insn *pc, const u_char *p,
continue; continue;
case BPF_ALU|BPF_LSH|BPF_X: case BPF_ALU|BPF_LSH|BPF_X:
if (X < 32)
A <<= X; A <<= X;
else
A = 0;
continue; continue;
case BPF_ALU|BPF_RSH|BPF_X: case BPF_ALU|BPF_RSH|BPF_X:
if (X < 32)
A >>= X; A >>= X;
else
A = 0;
continue; continue;
case BPF_ALU|BPF_ADD|BPF_K: 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: case BPF_ALU|BPF_NEG:
/* /*
* Most BPF arithmetic is unsigned, but negation * Most BPF arithmetic is unsigned, but negation
* can't be unsigned; throw some casts to * can't be unsigned; respecify it as subtracting
* specify what we're trying to do. * 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; continue;
case BPF_MISC|BPF_TAX: case BPF_MISC|BPF_TAX:

View File

@ -49,9 +49,17 @@
# #
# The 64-bit Packet.lib is located under /x64 # The 64-bit Packet.lib is located under /x64
set(64BIT_SUBDIR "")
if(CMAKE_SIZEOF_VOID_P EQUAL 8) 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() endif()
# Find the header # Find the header
@ -64,7 +72,6 @@ find_path(PACKET_INCLUDE_DIR Packet32.h
find_library(PACKET_LIBRARY find_library(PACKET_LIBRARY
NAMES Packet packet NAMES Packet packet
HINTS "${PACKET_DLL_DIR}" ENV PACKET_DLL_DIR 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. # Set PACKET_FOUND to TRUE if PACKET_INCLUDE_DIR and PACKET_LIBRARY are TRUE.

View File

@ -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)

View File

@ -15,6 +15,9 @@
/* define if we have the AIX getprotobyname_r() */ /* define if we have the AIX getprotobyname_r() */
#cmakedefine HAVE_AIX_GETPROTOBYNAME_R 1 #cmakedefine HAVE_AIX_GETPROTOBYNAME_R 1
/* Define to 1 if you have the `asprintf' function. */
#cmakedefine HAVE_ASPRINTF 1
/* define if you have the DAG API */ /* define if you have the DAG API */
#cmakedefine HAVE_DAG_API 1 #cmakedefine HAVE_DAG_API 1
@ -48,6 +51,9 @@
/* Define to 1 if you have the `getspnam' function. */ /* Define to 1 if you have the `getspnam' function. */
#cmakedefine HAVE_GETSPNAM 1 #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 */ /* on HP-UX 10.20 or later */
#cmakedefine HAVE_HPUX10_20_OR_LATER 1 #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 */ /* if there's an os_proto.h for this platform, to use additional prototypes */
#cmakedefine HAVE_OS_PROTO_H 1 #cmakedefine HAVE_OS_PROTO_H 1
/* 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 #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 */ /* define if net/pfvar.h defines PF_NAT through PF_NORDR */
#cmakedefine HAVE_PF_NAT_THROUGH_PF_NORDR 1 #cmakedefine HAVE_PF_NAT_THROUGH_PF_NORDR 1
@ -174,9 +186,6 @@
/* Define to 1 if you have the `strerror' function. */ /* Define to 1 if you have the `strerror' function. */
#cmakedefine HAVE_STRERROR 1 #cmakedefine HAVE_STRERROR 1
/* Define to 1 if you have the `strerror_r' function. */
#cmakedefine HAVE_STRERROR_R 1
/* Define to 1 if you have the `strerror_s' function. */ /* Define to 1 if you have the `strerror_s' function. */
#cmakedefine HAVE_STRERROR_S 1 #cmakedefine HAVE_STRERROR_S 1
@ -256,9 +265,15 @@
/* Define to 1 if you have the <unistd.h> header file. */ /* Define to 1 if you have the <unistd.h> header file. */
#cmakedefine HAVE_UNISTD_H 1 #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. */ /* Define to 1 if you have the `vsnprintf' function. */
#cmakedefine HAVE_VSNPRINTF 1 #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. */ /* Define to 1 if you have the `PacketIsLoopbackAdapter' function. */
#cmakedefine HAVE_PACKET_IS_LOOPBACK_ADAPTER 1 #cmakedefine HAVE_PACKET_IS_LOOPBACK_ADAPTER 1

File diff suppressed because it is too large Load Diff

View File

@ -15,6 +15,9 @@
/* define if we have the AIX getprotobyname_r() */ /* define if we have the AIX getprotobyname_r() */
#undef HAVE_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. */ /* Define to 1 if you have the <dagapi.h> header file. */
#undef HAVE_DAGAPI_H #undef HAVE_DAGAPI_H
@ -54,6 +57,9 @@
/* Define to 1 if you have the `getspnam' function. */ /* Define to 1 if you have the `getspnam' function. */
#undef HAVE_GETSPNAM #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 */ /* on HP-UX 10.20 or later */
#undef HAVE_HPUX10_20_OR_LATER #undef HAVE_HPUX10_20_OR_LATER
@ -150,6 +156,9 @@
/* define if net/pfvar.h defines PF_NAT through PF_NORDR */ /* define if net/pfvar.h defines PF_NAT through PF_NORDR */
#undef HAVE_PF_NAT_THROUGH_PF_NORDR #undef HAVE_PF_NAT_THROUGH_PF_NORDR
/* Define to 1 if you have a POSIX-style `strerror_r' function. */
#undef HAVE_POSIX_STRERROR_R
/* define if you have the Septel API */ /* define if you have the Septel API */
#undef HAVE_SEPTEL_API #undef HAVE_SEPTEL_API
@ -180,9 +189,6 @@
/* Define to 1 if you have the `strerror' function. */ /* Define to 1 if you have the `strerror' function. */
#undef HAVE_STRERROR #undef HAVE_STRERROR
/* Define to 1 if you have the `strerror_r' function. */
#undef HAVE_STRERROR_R
/* Define to 1 if you have the `strerror_s' function. */ /* Define to 1 if you have the `strerror_s' function. */
#undef HAVE_STRERROR_S #undef HAVE_STRERROR_S
@ -262,9 +268,15 @@
/* Define to 1 if you have the <unistd.h> header file. */ /* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H #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. */ /* Define to 1 if you have the `vsnprintf' function. */
#undef HAVE_VSNPRINTF #undef HAVE_VSNPRINTF
/* Define to 1 if you have the `vsyslog' function. */
#undef HAVE_VSYSLOG
/* IPv6 */ /* IPv6 */
#undef INET6 #undef INET6

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -28,6 +28,9 @@ AC_LBL_C_INIT_BEFORE_CC(V_CCOPT, V_INCLS)
# At minimum, we want C++/C99-style // comments. # At minimum, we want C++/C99-style // comments.
# #
AC_PROG_CC_C99 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_C_INIT(V_CCOPT, V_INCLS)
AC_LBL_SHLIBS_INIT AC_LBL_SHLIBS_INIT
AC_LBL_C_INLINE AC_LBL_C_INLINE
@ -83,13 +86,109 @@ esac
AC_LBL_FIXINCLUDES 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 needsnprintf=no
AC_CHECK_FUNCS(vsnprintf snprintf,, AC_CHECK_FUNCS(vsnprintf snprintf,,
[needsnprintf=yes]) [needsnprintf=yes])
needasprintf=no
AC_CHECK_FUNCS(vasprintf asprintf,,
[needasprintf=yes])
if test $needsnprintf = yes; then if test $needsnprintf = yes; then
#
# We assume we have none of them; missing/snprintf.c supplies
# all of them.
#
AC_LIBOBJ([snprintf]) 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 fi
needstrtok_r=no needstrtok_r=no
@ -550,6 +649,10 @@ else
# requires that various BSD-style integer types # requires that various BSD-style integer types
# be defined; # 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, # sys/ioctl.h and, if we have it, sys/ioccom.h,
# because net/bpf.h defines ioctls; # because net/bpf.h defines ioctls;
# #
@ -568,6 +671,7 @@ else
AC_TRY_COMPILE( AC_TRY_COMPILE(
[ [
#include <sys/types.h> #include <sys/types.h>
#include <sys/time.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/socket.h> #include <sys/socket.h>
#ifdef HAVE_SYS_IOCCOM_H #ifdef HAVE_SYS_IOCCOM_H
@ -1529,18 +1633,20 @@ AC_CACHE_CHECK([for capable yacc/bison], tcpdump_cv_capable_yacc,
fi) fi)
if test $tcpdump_cv_capable_yacc = insufficient ; then if test $tcpdump_cv_capable_yacc = insufficient ; then
AC_MSG_ERROR([$YACC is insufficient to compile libpcap. 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 fi
# #
# Do various checks for various OSes and versions of those OSes. # Do various checks for various OSes and versions of those OSes.
# #
# Assume, by default, no support for shared libraries and V7/BSD # Assume, by default, no support for shared libraries and V7/BSD
# convention for man pages (file formats in section 5, miscellaneous # convention for man pages (devices in section 4, file formats in
# info in section 7, administrative commands and daemons in section 8). # section 5, miscellaneous info in section 7, administrative commands
# Individual cases can override this. # and daemons in section 8). Individual cases can override this.
# #
DYEXT="none" DYEXT="none"
MAN_DEVICES=4
MAN_FILE_FORMATS=5 MAN_FILE_FORMATS=5
MAN_MISC_INFO=7 MAN_MISC_INFO=7
MAN_ADMIN_COMMANDS=8 MAN_ADMIN_COMMANDS=8
@ -1596,79 +1702,151 @@ darwin*)
if test "$enable_universal" != "no"; then if test "$enable_universal" != "no"; then
case "$host_os" in case "$host_os" in
darwin[0-7].*) darwin[[0-7]].*)
# #
# Pre-Tiger. Build only for 32-bit PowerPC; no # Pre-Tiger. Build only for 32-bit PowerPC; no
# need for any special compiler or linker flags. # need for any special compiler or linker flags.
# #
;; ;;
darwin8.[0123]*) darwin8.[[0123]]|darwin8.[[0123]].*)
# #
# Tiger, prior to Intel support. Build for 32-bit # Tiger, prior to Intel support. Build
# PowerPC and 64-bit PowerPC, with 32-bit PowerPC # libraries and executables for 32-bit PowerPC
# first. (I'm guessing that's what Apple does.) # and 64-bit PowerPC, with 32-bit PowerPC first.
#
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.
# (I'm guessing that's what Apple does.) # (I'm guessing that's what Apple does.)
# #
V_CCOPT="$V_CCOPT -arch ppc -arch ppc64 -arch i386" # (The double brackets are needed because
LDFLAGS="$LDFLAGS -arch ppc -arch ppc64 -arch i386" # 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.*) darwin8.*)
# #
# All other Tiger, so subsequent to x86-64 # All other Tiger, so subsequent to x86-64
# support. Build for 32-bit PowerPC, 64-bit # support. Build libraries and executables for
# PowerPC, x86, and x86-64, and with 32-bit PowerPC # 32-bit PowerPC, 64-bit PowerPC, 32-bit x86,
# first. (I'm guessing that's what Apple does.) # 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" V_LIB_CCOPT_FAT="-arch ppc -arch ppc64 -arch i386 -arch x86_64"
LDFLAGS="$LDFLAGS -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.*) darwin9.*)
# #
# Leopard. Build for 32-bit PowerPC, 64-bit # Leopard. Build libraries for 32-bit PowerPC,
# PowerPC, x86, and x86-64, with 32-bit PowerPC # 64-bit PowerPC, 32-bit x86, and x86-64, with
# first. (That's what Apple does.) # 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" V_LIB_CCOPT_FAT="-arch ppc -arch ppc64 -arch i386 -arch x86_64"
LDFLAGS="$LDFLAGS -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.*) darwin10.*)
# #
# Snow Leopard. Build for x86-64, x86, and # Snow Leopard. Build libraries for x86-64,
# 32-bit PowerPC, with x86-64 first. (That's # 32-bit x86, and 32-bit PowerPC, with x86-64
# what Apple does, even though Snow Leopard # first, and build executables for x86-64 and
# doesn't run on PPC, so PPC libpcap runs under # 32-bit x86, with x86-64 first. (That's what
# Rosetta, and Rosetta doesn't support BPF # Apple does, even though Snow Leopard doesn't
# ioctls, so PPC programs can't do live # run on PPC, so PPC libpcap runs under Rosetta,
# captures.) # 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" V_LIB_CCOPT_FAT="-arch x86_64 -arch i386 -arch ppc"
LDFLAGS="$LDFLAGS -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*) darwin*)
# #
# Post-Snow Leopard. Build for x86-64 and # Post-Snow Leopard. Build libraries for x86-64
# x86, with x86-64 first. (That's probably what # and 32-bit x86, with x86-64 first, and build
# Apple does, given that Rosetta is gone.) # 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 # 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" # XXX - check whether we *can* build for
LDFLAGS="$LDFLAGS -arch x86_64 -arch i386" # 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 esac
fi fi
@ -1742,7 +1920,7 @@ irix*)
MAN_MISC_INFO=5 MAN_MISC_INFO=5
;; ;;
linux*|freebsd*|netbsd*|openbsd*|dragonfly*|kfreebsd*|gnu*) linux*|freebsd*|netbsd*|openbsd*|dragonfly*|kfreebsd*|gnu*|midipix*)
DYEXT="so" DYEXT="so"
# #
@ -1765,6 +1943,7 @@ osf*)
# #
MAN_FILE_FORMATS=4 MAN_FILE_FORMATS=4
MAN_MISC_INFO=5 MAN_MISC_INFO=5
MAN_DEVICES=7
;; ;;
sinix*) sinix*)
@ -1808,6 +1987,7 @@ solaris*)
MAN_ADMIN_COMMANDS=1m MAN_ADMIN_COMMANDS=1m
MAN_FILE_FORMATS=4 MAN_FILE_FORMATS=4
MAN_MISC_INFO=5 MAN_MISC_INFO=5
MAN_DEVICES=7D
esac esac
;; ;;
esac esac
@ -1863,6 +2043,10 @@ AC_CHECK_MEMBERS([dl_hp_ppa_info_t.dl_module_id_1],,,
AC_LBL_UNALIGNED_ACCESS AC_LBL_UNALIGNED_ACCESS
AC_SUBST(V_CCOPT) 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_DEFS)
AC_SUBST(V_FINDALLDEVS) AC_SUBST(V_FINDALLDEVS)
AC_SUBST(V_INCLS) AC_SUBST(V_INCLS)
@ -1878,6 +2062,7 @@ AC_SUBST(ADDLOBJS)
AC_SUBST(ADDLARCHIVEOBJS) AC_SUBST(ADDLARCHIVEOBJS)
AC_SUBST(SSRC) AC_SUBST(SSRC)
AC_SUBST(DYEXT) AC_SUBST(DYEXT)
AC_SUBST(MAN_DEVICES)
AC_SUBST(MAN_FILE_FORMATS) AC_SUBST(MAN_FILE_FORMATS)
AC_SUBST(MAN_MISC_INFO) AC_SUBST(MAN_MISC_INFO)
AC_SUBST(MAN_ADMIN_COMMANDS) AC_SUBST(MAN_ADMIN_COMMANDS)
@ -2212,15 +2397,15 @@ fi
AC_ARG_ENABLE([rdma], AC_ARG_ENABLE([rdma],
[AC_HELP_STRING([--enable-rdma],[enable RDMA capture support @<:@default=yes, if support available@:>@])], [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 if test "xxx_only" = yes; then
# User requested something-else-only pcap, so they don't # User requested something-else-only pcap, so they don't
# want RDMA support. # want RDMA support.
enable_rdmasniff=no enable_rdma=no
fi 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_LIB(ibverbs, ibv_get_device_list, [
AC_CHECK_HEADER(infiniband/verbs.h, [ 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_compile.3pcap pcap_datalink.3pcap pcap_dump_open.3pcap
pcap_get_tstamp_precision.3pcap pcap_list_datalinks.3pcap pcap_get_tstamp_precision.3pcap pcap_list_datalinks.3pcap
pcap_list_tstamp_types.3pcap pcap_open_dead.3pcap pcap_list_tstamp_types.3pcap pcap_open_dead.3pcap
pcap_open_offline.3pcap pcap_set_tstamp_precision.3pcap pcap_open_offline.3pcap pcap_set_immediate_mode.3pcap
pcap_set_tstamp_type.3pcap rpcapd/Makefile rpcapd/rpcapd.manadmin pcap_set_tstamp_precision.3pcap pcap_set_tstamp_type.3pcap
rpcapd/Makefile rpcapd/rpcapd.manadmin rpcapd/rpcapd-config.manfile
testprogs/Makefile) testprogs/Makefile)
exit 0 exit 0

View File

@ -120,13 +120,14 @@
* shadowing the global declaration. * shadowing the global declaration.
* *
* So, if the compiler warns about that, we turn off -Wshadow warnings. * 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) #if defined(_MSC_VER)
/* /*
* This is Microsoft Visual Studio; we can use * This is Microsoft Visual Studio; we can use
* __pragma(warning(disable:XXXX)) and __pragma(warning(push/pop)). * __pragma(warning(disable:XXXX)) and __pragma(warning(push/pop)).
*
* Suppress unreachable code warnings.
*/ */
#define DIAG_OFF_BISON_BYACC \ #define DIAG_OFF_BISON_BYACC \
__pragma(warning(push)) \ __pragma(warning(push)) \
@ -166,6 +167,9 @@
#else #else
/* /*
* Bison. * Bison.
*
* The generated code may have functions with unreachable code, so
* suppress warnings about those.
*/ */
#if defined(_MSC_VER) #if defined(_MSC_VER)
/* /*

View 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.

View 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.

View File

@ -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 1) Install and build the DAG software distribution by following the
instructions supplied with that package. Current Endace customers can download 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 2) Configure libcap. To allow the 'configure' script to locate the DAG
software distribution use the '--with-dag' option: 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(). as dag0. These are visible via pcap_findalldevs().
libpcap now does NOT set the card's hardware snaplen (slen). This must now be 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 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 all of the streams. In future this may change if per-stream slen is
implemented. implemented.

View File

@ -97,9 +97,9 @@ reported by pcap_stats on Linux are as follows:
2.2.x 2.2.x
===== =====
ps_recv Number of packets that were accepted by the pcap filter 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_recv Number of packets that were accepted by the pcap filter
ps_drop Number of packets that had passed filtering but were not ps_drop Number of packets that had passed filtering but were not

View File

@ -65,11 +65,6 @@ pcap_fmt_errmsg_for_errno(char *errbuf, size_t errbuflen, int errnum,
size_t msglen; size_t msglen;
char *p; char *p;
size_t errbuflen_remaining; size_t errbuflen_remaining;
#if defined(HAVE_STRERROR_S)
errno_t err;
#elif defined(HAVE_STRERROR_R)
int err;
#endif
va_start(ap, fmt); va_start(ap, fmt);
pcap_vsnprintf(errbuf, errbuflen, fmt, ap); 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. * Now append the string for the error code.
*/ */
#if defined(HAVE_STRERROR_S) #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) { if (err != 0) {
/* /*
* It doesn't appear to be documented anywhere obvious * 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); pcap_snprintf(p, errbuflen_remaining, "Error %d", errnum);
} }
#elif defined(HAVE_STRERROR_R) #elif defined(HAVE_GNU_STRERROR_R)
err = strerror_r(errnum, p, errbuflen_remaining); /*
* 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) { if (err == EINVAL) {
/* /*
* UNIX 03 says this isn't guaranteed to produce a * 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)); pcap_snprintf(p, errbuflen_remaining, "%s", pcap_strerror(errnum));
#endif #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

View File

@ -43,6 +43,11 @@ extern "C" {
void pcap_fmt_errmsg_for_errno(char *, size_t, int, void pcap_fmt_errmsg_for_errno(char *, size_t, int,
PCAP_FORMAT_STRING(const char *), ...) PCAP_PRINTFLIKE(4, 5); PCAP_FORMAT_STRING(const char *), ...) PCAP_PRINTFLIKE(4, 5);
#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 #ifdef __cplusplus
} }
#endif #endif

View File

@ -85,20 +85,14 @@
*/ */
#elif defined(__linux__) || defined(linux) || defined(__linux) #elif defined(__linux__) || defined(linux) || defined(__linux)
/* /*
* We can't turn _GNU_SOURCE on because some versions of GNU Libc * Turn on _GNU_SOURCE to get everything GNU libc has to offer,
* will give the GNU version of strerror_r(), which returns a * including asprintf().
* 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.
* *
* So we try turning everything else on that we can. This includes * Unfortunately, one thing it has to offer is a strerror_r()
* defining _XOPEN_SOURCE as 600, because we want to force crypt() * that's not POSIX-compliant, but we deal with that in
* to be declared on systems that use GNU libc, such as most Linux * pcap_fmt_errmsg_for_errno().
* distributions.
*/ */
#define _POSIX_C_SOURCE 200809L #define _GNU_SOURCE
#define _XOPEN_SOURCE 600
/* /*
* We turn on both _DEFAULT_SOURCE and _BSD_SOURCE to try to get * We turn on both _DEFAULT_SOURCE and _BSD_SOURCE to try to get

File diff suppressed because it is too large Load Diff

View File

@ -113,16 +113,14 @@
#define Q_ISIS_L2 32 #define Q_ISIS_L2 32
/* PDU types */ /* PDU types */
#define Q_ISIS_IIH 33 #define Q_ISIS_IIH 33
#define Q_ISIS_LAN_IIH 34 #define Q_ISIS_SNP 34
#define Q_ISIS_PTP_IIH 35 #define Q_ISIS_CSNP 35
#define Q_ISIS_SNP 36 #define Q_ISIS_PSNP 36
#define Q_ISIS_CSNP 37 #define Q_ISIS_LSP 37
#define Q_ISIS_PSNP 38
#define Q_ISIS_LSP 39
#define Q_RADIO 40 #define Q_RADIO 38
#define Q_CARP 41 #define Q_CARP 39
/* Directional qualifiers. */ /* Directional qualifiers. */
@ -299,8 +297,8 @@ void gen_or(struct block *, struct block *);
void gen_not(struct block *); void gen_not(struct block *);
struct block *gen_scode(compiler_state_t *, const char *, struct qual); struct block *gen_scode(compiler_state_t *, const char *, struct qual);
struct block *gen_ecode(compiler_state_t *, const u_char *, struct qual); struct block *gen_ecode(compiler_state_t *, const char *, struct qual);
struct block *gen_acode(compiler_state_t *, const u_char *, struct qual); struct block *gen_acode(compiler_state_t *, const char *, struct qual);
struct block *gen_mcode(compiler_state_t *, const char *, const char *, struct block *gen_mcode(compiler_state_t *, const char *, const char *,
unsigned int, struct qual); unsigned int, struct qual);
#ifdef INET6 #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_s_subtype(compiler_state_t *, bpf_u_int32);
struct block *gen_llc_u_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_vlan(compiler_state_t *, bpf_u_int32, int);
struct block *gen_mpls(compiler_state_t *, int); struct block *gen_mpls(compiler_state_t *, bpf_u_int32, int);
struct block *gen_pppoed(compiler_state_t *); 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, struct block *gen_atmfield_code(compiler_state_t *, int, bpf_int32,
bpf_u_int32, int); 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, struct block *gen_mtp3field_code(compiler_state_t *, int, bpf_u_int32,
bpf_u_int32, int); bpf_u_int32, int);
#ifndef HAVE_NET_PFVAR_H
PCAP_NORETURN
#endif
struct block *gen_pf_ifname(compiler_state_t *, const char *); 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); 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); 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 *); 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); 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_pf_action(compiler_state_t *, int);
struct block *gen_p80211_type(compiler_state_t *, int, int); struct block *gen_p80211_type(compiler_state_t *, int, int);
@ -386,16 +366,15 @@ struct icode {
int cur_mark; int cur_mark;
}; };
void bpf_optimize(compiler_state_t *, struct icode *ic); int bpf_optimize(struct icode *, char *);
void PCAP_NORETURN bpf_syntax_error(compiler_state_t *, const char *); void bpf_set_error(compiler_state_t *, const char *, ...)
void PCAP_NORETURN bpf_error(compiler_state_t *, const char *, ...)
PCAP_PRINTFLIKE(2, 3); 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 *); char *sdup(compiler_state_t *, const char *);
struct bpf_insn *icode_to_fcode(compiler_state_t *, struct icode *, struct bpf_insn *icode_to_fcode(struct icode *, struct block *, u_int *,
struct block *, u_int *); char *);
void sappend(struct slist *, struct slist *); void sappend(struct slist *, struct slist *);
/* /*

View File

@ -216,13 +216,12 @@ str2tok(const char *str, const struct tok *toks)
return (-1); 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) yyerror(void *yyscanner _U_, compiler_state_t *cstate, const char *msg)
{ {
bpf_syntax_error(cstate, msg); bpf_set_error(cstate, "can't parse filter expression: %s", msg);
/* NOTREACHED */
} }
#ifdef HAVE_NET_PFVAR_H #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) if (pcap_strcasecmp(reason, reasons[i]) == 0)
return (i); return (i);
} }
bpf_error(cstate, "unknown PF reason"); bpf_set_error(cstate, "unknown PF reason");
/*NOTREACHED*/ return (-1);
} }
static int static int
@ -260,33 +259,38 @@ pfaction_to_num(compiler_state_t *cstate, const char *action)
return (PF_NORDR); return (PF_NORDR);
#endif #endif
else { else {
bpf_error(cstate, "unknown PF action"); bpf_set_error(cstate, "unknown PF action");
/*NOTREACHED*/ return (-1);
} }
} }
#else /* !HAVE_NET_PFVAR_H */ #else /* !HAVE_NET_PFVAR_H */
static PCAP_NORETURN_DEF int static int
pfreason_to_num(compiler_state_t *cstate, const char *reason _U_) pfreason_to_num(compiler_state_t *cstate, const char *reason _U_)
{ {
bpf_error(cstate, "libpcap was compiled on a machine without pf support"); bpf_set_error(cstate, "libpcap was compiled on a machine without pf support");
/*NOTREACHED*/ return (-1);
} }
static PCAP_NORETURN_DEF int static int
pfaction_to_num(compiler_state_t *cstate, const char *action _U_) pfaction_to_num(compiler_state_t *cstate, const char *action _U_)
{ {
bpf_error(cstate, "libpcap was compiled on a machine without pf support"); bpf_set_error(cstate, "libpcap was compiled on a machine without pf support");
/*NOTREACHED*/ return (-1);
} }
#endif /* HAVE_NET_PFVAR_H */ #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 DIAG_OFF_BISON_BYACC
%} %}
%union { %union {
int i; int i;
bpf_u_int32 h; bpf_u_int32 h;
u_char *e;
char *s; char *s;
struct stmt *stmt; struct stmt *stmt;
struct arth *a; struct arth *a;
@ -340,11 +344,9 @@ DIAG_OFF_BISON_BYACC
%token RADIO %token RADIO
%token FISU LSSU MSU HFISU HLSSU HMSU %token FISU LSSU MSU HFISU HLSSU HMSU
%token SIO OPC DPC SLS HSIO HOPC HDPC HSLS %token SIO OPC DPC SLS HSIO HOPC HDPC HSLS
%token LEX_ERROR
%type <s> ID EID AID
%type <s> ID
%type <e> EID
%type <e> AID
%type <s> HID HID6 %type <s> HID HID6
%type <i> NUM action reason type subtype type_subtype dir %type <i> NUM action reason type subtype type_subtype dir
@ -359,7 +361,7 @@ DIAG_OFF_BISON_BYACC
%% %%
prog: null expr prog: null expr
{ {
finish_parse(cstate, $2.b); CHECK_INT_VAL(finish_parse(cstate, $2.b));
} }
| null | null
; ;
@ -376,64 +378,58 @@ and: AND { $$ = $<blk>0; }
or: OR { $$ = $<blk>0; } or: OR { $$ = $<blk>0; }
; ;
id: nid id: nid
| pnum { $$.b = gen_ncode(cstate, NULL, (bpf_u_int32)$1, | pnum { CHECK_PTR_VAL(($$.b = gen_ncode(cstate, NULL, (bpf_u_int32)$1,
$$.q = $<blk>0.q); } $$.q = $<blk>0.q))); }
| paren pid ')' { $$ = $2; } | paren pid ')' { $$ = $2; }
; ;
nid: ID { $$.b = gen_scode(cstate, $1, $$.q = $<blk>0.q); } nid: ID { CHECK_PTR_VAL($1); CHECK_PTR_VAL(($$.b = gen_scode(cstate, $1, $$.q = $<blk>0.q))); }
| HID '/' NUM { $$.b = gen_mcode(cstate, $1, NULL, $3, | HID '/' NUM { CHECK_PTR_VAL($1); CHECK_PTR_VAL(($$.b = gen_mcode(cstate, $1, NULL, $3,
$$.q = $<blk>0.q); } $$.q = $<blk>0.q))); }
| HID NETMASK HID { $$.b = gen_mcode(cstate, $1, $3, 0, | HID NETMASK HID { CHECK_PTR_VAL($1); CHECK_PTR_VAL(($$.b = gen_mcode(cstate, $1, $3, 0,
$$.q = $<blk>0.q); } $$.q = $<blk>0.q))); }
| HID { | HID {
CHECK_PTR_VAL($1);
/* Decide how to parse HID based on proto */ /* Decide how to parse HID based on proto */
$$.q = $<blk>0.q; $$.q = $<blk>0.q;
if ($$.q.addr == Q_PORT) if ($$.q.addr == Q_PORT) {
bpf_error(cstate, "'port' modifier applied to ip host"); bpf_set_error(cstate, "'port' modifier applied to ip host");
else if ($$.q.addr == Q_PORTRANGE) YYABORT;
bpf_error(cstate, "'portrange' modifier applied to ip host"); } else if ($$.q.addr == Q_PORTRANGE) {
else if ($$.q.addr == Q_PROTO) bpf_set_error(cstate, "'portrange' modifier applied to ip host");
bpf_error(cstate, "'proto' modifier applied to ip host"); YYABORT;
else if ($$.q.addr == Q_PROTOCHAIN) } else if ($$.q.addr == Q_PROTO) {
bpf_error(cstate, "'protochain' modifier applied to ip host"); bpf_set_error(cstate, "'proto' modifier applied to ip host");
$$.b = gen_ncode(cstate, $1, 0, $$.q); 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 { | HID6 '/' NUM {
CHECK_PTR_VAL($1);
#ifdef INET6 #ifdef INET6
$$.b = gen_mcode6(cstate, $1, NULL, $3, CHECK_PTR_VAL(($$.b = gen_mcode6(cstate, $1, NULL, $3,
$$.q = $<blk>0.q); $$.q = $<blk>0.q)));
#else #else
bpf_error(cstate, "'ip6addr/prefixlen' not supported " bpf_set_error(cstate, "'ip6addr/prefixlen' not supported "
"in this configuration"); "in this configuration");
YYABORT;
#endif /*INET6*/ #endif /*INET6*/
} }
| HID6 { | HID6 {
CHECK_PTR_VAL($1);
#ifdef INET6 #ifdef INET6
$$.b = gen_mcode6(cstate, $1, 0, 128, CHECK_PTR_VAL(($$.b = gen_mcode6(cstate, $1, 0, 128,
$$.q = $<blk>0.q); $$.q = $<blk>0.q)));
#else #else
bpf_error(cstate, "'ip6addr' not supported " bpf_set_error(cstate, "'ip6addr' not supported "
"in this configuration"); "in this configuration");
YYABORT;
#endif /*INET6*/ #endif /*INET6*/
} }
| EID { | EID { CHECK_PTR_VAL($1); CHECK_PTR_VAL(($$.b = gen_ecode(cstate, $1, $$.q = $<blk>0.q))); }
$$.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))); }
/*
* $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);
}
| not id { gen_not($2.b); $$ = $2; } | not id { gen_not($2.b); $$ = $2; }
; ;
not: '!' { $$ = $<blk>0; } not: '!' { $$ = $<blk>0; }
@ -444,8 +440,8 @@ pid: nid
| qid and id { gen_and($1.b, $3.b); $$ = $3; } | qid and id { gen_and($1.b, $3.b); $$ = $3; }
| qid or id { gen_or($1.b, $3.b); $$ = $3; } | qid or id { gen_or($1.b, $3.b); $$ = $3; }
; ;
qid: pnum { $$.b = gen_ncode(cstate, NULL, (bpf_u_int32)$1, qid: pnum { CHECK_PTR_VAL(($$.b = gen_ncode(cstate, NULL, (bpf_u_int32)$1,
$$.q = $<blk>0.q); } $$.q = $<blk>0.q))); }
| pid | pid
; ;
term: rterm term: rterm
@ -455,21 +451,28 @@ head: pqual dqual aqual { QSET($$.q, $1, $2, $3); }
| pqual dqual { QSET($$.q, $1, $2, Q_DEFAULT); } | pqual dqual { QSET($$.q, $1, $2, Q_DEFAULT); }
| pqual aqual { QSET($$.q, $1, Q_DEFAULT, $2); } | pqual aqual { QSET($$.q, $1, Q_DEFAULT, $2); }
| pqual PROTO { QSET($$.q, $1, Q_DEFAULT, Q_PROTO); } | 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); } | pqual ndaqual { QSET($$.q, $1, Q_DEFAULT, $2); }
; ;
rterm: head id { $$ = $2; } rterm: head id { $$ = $2; }
| paren expr ')' { $$.b = $2.b; $$.q = $1.q; } | paren expr ')' { $$.b = $2.b; $$.q = $1.q; }
| pname { $$.b = gen_proto_abbrev(cstate, $1); $$.q = qerr; } | pname { CHECK_PTR_VAL(($$.b = gen_proto_abbrev(cstate, $1))); $$.q = qerr; }
| arth relop arth { $$.b = gen_relation(cstate, $2, $1, $3, 0); | arth relop arth { CHECK_PTR_VAL(($$.b = gen_relation(cstate, $2, $1, $3, 0)));
$$.q = qerr; } $$.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; } $$.q = qerr; }
| other { $$.b = $1; $$.q = qerr; } | other { $$.b = $1; $$.q = qerr; }
| atmtype { $$.b = gen_atmtype_abbrev(cstate, $1); $$.q = qerr; } | atmtype { CHECK_PTR_VAL(($$.b = gen_atmtype_abbrev(cstate, $1))); $$.q = qerr; }
| atmmultitype { $$.b = gen_atmmulti_abbrev(cstate, $1); $$.q = qerr; } | atmmultitype { CHECK_PTR_VAL(($$.b = gen_atmmulti_abbrev(cstate, $1))); $$.q = qerr; }
| atmfield atmvalue { $$.b = $2.b; $$.q = qerr; } | atmfield atmvalue { $$.b = $2.b; $$.q = qerr; }
| mtp2type { $$.b = gen_mtp2type_abbrev(cstate, $1); $$.q = qerr; } | mtp2type { CHECK_PTR_VAL(($$.b = gen_mtp2type_abbrev(cstate, $1))); $$.q = qerr; }
| mtp3field mtp3value { $$.b = $2.b; $$.q = qerr; } | mtp3field mtp3value { $$.b = $2.b; $$.q = qerr; }
; ;
/* protocol level qualifiers */ /* protocol level qualifiers */
@ -539,65 +542,69 @@ pname: LINK { $$ = Q_LINK; }
| NETBEUI { $$ = Q_NETBEUI; } | NETBEUI { $$ = Q_NETBEUI; }
| RADIO { $$ = Q_RADIO; } | RADIO { $$ = Q_RADIO; }
; ;
other: pqual TK_BROADCAST { $$ = gen_broadcast(cstate, $1); } other: pqual TK_BROADCAST { CHECK_PTR_VAL(($$ = gen_broadcast(cstate, $1))); }
| pqual TK_MULTICAST { $$ = gen_multicast(cstate, $1); } | pqual TK_MULTICAST { CHECK_PTR_VAL(($$ = gen_multicast(cstate, $1))); }
| LESS NUM { $$ = gen_less(cstate, $2); } | LESS NUM { CHECK_PTR_VAL(($$ = gen_less(cstate, $2))); }
| GREATER NUM { $$ = gen_greater(cstate, $2); } | GREATER NUM { CHECK_PTR_VAL(($$ = gen_greater(cstate, $2))); }
| CBYTE NUM byteop NUM { $$ = gen_byteop(cstate, $3, $2, $4); } | CBYTE NUM byteop NUM { CHECK_PTR_VAL(($$ = gen_byteop(cstate, $3, $2, $4))); }
| INBOUND { $$ = gen_inbound(cstate, 0); } | INBOUND { CHECK_PTR_VAL(($$ = gen_inbound(cstate, 0))); }
| OUTBOUND { $$ = gen_inbound(cstate, 1); } | OUTBOUND { CHECK_PTR_VAL(($$ = gen_inbound(cstate, 1))); }
| VLAN pnum { $$ = gen_vlan(cstate, $2); } | VLAN pnum { CHECK_PTR_VAL(($$ = gen_vlan(cstate, (bpf_u_int32)$2, 1))); }
| VLAN { $$ = gen_vlan(cstate, -1); } | VLAN { CHECK_PTR_VAL(($$ = gen_vlan(cstate, 0, 0))); }
| MPLS pnum { $$ = gen_mpls(cstate, $2); } | MPLS pnum { CHECK_PTR_VAL(($$ = gen_mpls(cstate, (bpf_u_int32)$2, 1))); }
| MPLS { $$ = gen_mpls(cstate, -1); } | MPLS { CHECK_PTR_VAL(($$ = gen_mpls(cstate, 0, 0))); }
| PPPOED { $$ = gen_pppoed(cstate); } | PPPOED { CHECK_PTR_VAL(($$ = gen_pppoed(cstate))); }
| PPPOES pnum { $$ = gen_pppoes(cstate, $2); } | PPPOES pnum { CHECK_PTR_VAL(($$ = gen_pppoes(cstate, (bpf_u_int32)$2, 1))); }
| PPPOES { $$ = gen_pppoes(cstate, -1); } | PPPOES { CHECK_PTR_VAL(($$ = gen_pppoes(cstate, 0, 0))); }
| GENEVE pnum { $$ = gen_geneve(cstate, $2); } | GENEVE pnum { CHECK_PTR_VAL(($$ = gen_geneve(cstate, (bpf_u_int32)$2, 1))); }
| GENEVE { $$ = gen_geneve(cstate, -1); } | GENEVE { CHECK_PTR_VAL(($$ = gen_geneve(cstate, 0, 0))); }
| pfvar { $$ = $1; } | pfvar { $$ = $1; }
| pqual p80211 { $$ = $2; } | pqual p80211 { $$ = $2; }
| pllc { $$ = $1; } | pllc { $$ = $1; }
; ;
pfvar: PF_IFNAME ID { $$ = gen_pf_ifname(cstate, $2); } pfvar: PF_IFNAME ID { CHECK_PTR_VAL($2); CHECK_PTR_VAL(($$ = gen_pf_ifname(cstate, $2))); }
| PF_RSET ID { $$ = gen_pf_ruleset(cstate, $2); } | PF_RSET ID { CHECK_PTR_VAL($2); CHECK_PTR_VAL(($$ = gen_pf_ruleset(cstate, $2))); }
| PF_RNR NUM { $$ = gen_pf_rnr(cstate, $2); } | PF_RNR NUM { CHECK_PTR_VAL(($$ = gen_pf_rnr(cstate, $2))); }
| PF_SRNR NUM { $$ = gen_pf_srnr(cstate, $2); } | PF_SRNR NUM { CHECK_PTR_VAL(($$ = gen_pf_srnr(cstate, $2))); }
| PF_REASON reason { $$ = gen_pf_reason(cstate, $2); } | PF_REASON reason { CHECK_PTR_VAL(($$ = gen_pf_reason(cstate, $2))); }
| PF_ACTION action { $$ = gen_pf_action(cstate, $2); } | PF_ACTION action { CHECK_PTR_VAL(($$ = gen_pf_action(cstate, $2))); }
; ;
p80211: TYPE type SUBTYPE subtype 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_TYPE_MASK |
IEEE80211_FC0_SUBTYPE_MASK); IEEE80211_FC0_SUBTYPE_MASK)));
} }
| TYPE type { $$ = gen_p80211_type(cstate, $2, | TYPE type { CHECK_PTR_VAL(($$ = gen_p80211_type(cstate, $2,
IEEE80211_FC0_TYPE_MASK); 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_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 type: NUM
| ID { $$ = str2tok($1, ieee80211_types); | ID { CHECK_PTR_VAL($1);
if ($$ == -1) $$ = str2tok($1, ieee80211_types);
bpf_error(cstate, "unknown 802.11 type name"); if ($$ == -1) {
bpf_set_error(cstate, "unknown 802.11 type name");
YYABORT;
}
} }
; ;
subtype: NUM subtype: NUM
| ID { const struct tok *types = NULL; | ID { const struct tok *types = NULL;
int i; int i;
CHECK_PTR_VAL($1);
for (i = 0;; i++) { for (i = 0;; i++) {
if (ieee80211_type_subtypes[i].tok == NULL) { if (ieee80211_type_subtypes[i].tok == NULL) {
/* Ran out of types */ /* Ran out of types */
bpf_error(cstate, "unknown 802.11 type"); bpf_set_error(cstate, "unknown 802.11 type");
break; YYABORT;
} }
if ($<i>-1 == ieee80211_type_subtypes[i].type) { if ($<i>-1 == ieee80211_type_subtypes[i].type) {
types = ieee80211_type_subtypes[i].tok; types = ieee80211_type_subtypes[i].tok;
@ -606,17 +613,20 @@ subtype: NUM
} }
$$ = str2tok($1, types); $$ = str2tok($1, types);
if ($$ == -1) if ($$ == -1) {
bpf_error(cstate, "unknown 802.11 subtype name"); bpf_set_error(cstate, "unknown 802.11 subtype name");
YYABORT;
}
} }
; ;
type_subtype: ID { int i; type_subtype: ID { int i;
CHECK_PTR_VAL($1);
for (i = 0;; i++) { for (i = 0;; i++) {
if (ieee80211_type_subtypes[i].tok == NULL) { if (ieee80211_type_subtypes[i].tok == NULL) {
/* Ran out of types */ /* Ran out of types */
bpf_error(cstate, "unknown 802.11 type name"); bpf_set_error(cstate, "unknown 802.11 type name");
break; YYABORT;
} }
$$ = str2tok($1, ieee80211_type_subtypes[i].tok); $$ = str2tok($1, ieee80211_type_subtypes[i].tok);
if ($$ != -1) { if ($$ != -1) {
@ -627,33 +637,37 @@ type_subtype: ID { int i;
} }
; ;
pllc: LLC { $$ = gen_llc(cstate); } pllc: LLC { CHECK_PTR_VAL(($$ = gen_llc(cstate))); }
| LLC ID { if (pcap_strcasecmp($2, "i") == 0) | LLC ID { CHECK_PTR_VAL($2);
$$ = gen_llc_i(cstate); if (pcap_strcasecmp($2, "i") == 0) {
else if (pcap_strcasecmp($2, "s") == 0) CHECK_PTR_VAL(($$ = gen_llc_i(cstate)));
$$ = gen_llc_s(cstate); } else if (pcap_strcasecmp($2, "s") == 0) {
else if (pcap_strcasecmp($2, "u") == 0) CHECK_PTR_VAL(($$ = gen_llc_s(cstate)));
$$ = gen_llc_u(cstate); } else if (pcap_strcasecmp($2, "u") == 0) {
else { CHECK_PTR_VAL(($$ = gen_llc_u(cstate)));
} else {
int subtype; int subtype;
subtype = str2tok($2, llc_s_subtypes); subtype = str2tok($2, llc_s_subtypes);
if (subtype != -1) if (subtype != -1) {
$$ = gen_llc_s_subtype(cstate, subtype); CHECK_PTR_VAL(($$ = gen_llc_s_subtype(cstate, subtype)));
else { } else {
subtype = str2tok($2, llc_u_subtypes); subtype = str2tok($2, llc_u_subtypes);
if (subtype == -1) if (subtype == -1) {
bpf_error(cstate, "unknown LLC type name \"%s\"", $2); bpf_set_error(cstate, "unknown LLC type name \"%s\"", $2);
$$ = gen_llc_u_subtype(cstate, subtype); YYABORT;
}
CHECK_PTR_VAL(($$ = gen_llc_u_subtype(cstate, subtype)));
} }
} }
} }
/* sigh, "rnr" is already a keyword for PF */ /* sigh, "rnr" is already a keyword for PF */
| LLC PF_RNR { $$ = gen_llc_s_subtype(cstate, LLC_RNR); } | LLC PF_RNR { CHECK_PTR_VAL(($$ = gen_llc_s_subtype(cstate, LLC_RNR))); }
; ;
dir: NUM dir: NUM
| ID { if (pcap_strcasecmp($1, "nods") == 0) | ID { CHECK_PTR_VAL($1);
if (pcap_strcasecmp($1, "nods") == 0)
$$ = IEEE80211_FC1_DIR_NODS; $$ = IEEE80211_FC1_DIR_NODS;
else if (pcap_strcasecmp($1, "tods") == 0) else if (pcap_strcasecmp($1, "tods") == 0)
$$ = IEEE80211_FC1_DIR_TODS; $$ = IEEE80211_FC1_DIR_TODS;
@ -661,16 +675,18 @@ dir: NUM
$$ = IEEE80211_FC1_DIR_FROMDS; $$ = IEEE80211_FC1_DIR_FROMDS;
else if (pcap_strcasecmp($1, "dstods") == 0) else if (pcap_strcasecmp($1, "dstods") == 0)
$$ = IEEE80211_FC1_DIR_DSTODS; $$ = IEEE80211_FC1_DIR_DSTODS;
else else {
bpf_error(cstate, "unknown 802.11 direction"); bpf_set_error(cstate, "unknown 802.11 direction");
YYABORT;
}
} }
; ;
reason: NUM { $$ = $1; } 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; } relop: '>' { $$ = BPF_JGT; }
@ -681,24 +697,24 @@ irelop: LEQ { $$ = BPF_JGT; }
| '<' { $$ = BPF_JGE; } | '<' { $$ = BPF_JGE; }
| NEQ { $$ = BPF_JEQ; } | NEQ { $$ = BPF_JEQ; }
; ;
arth: pnum { $$ = gen_loadi(cstate, $1); } arth: pnum { CHECK_PTR_VAL(($$ = gen_loadi(cstate, $1))); }
| narth | narth
; ;
narth: pname '[' arth ']' { $$ = gen_load(cstate, $1, $3, 1); } narth: pname '[' arth ']' { CHECK_PTR_VAL(($$ = gen_load(cstate, $1, $3, 1))); }
| pname '[' arth ':' NUM ']' { $$ = gen_load(cstate, $1, $3, $5); } | pname '[' arth ':' NUM ']' { CHECK_PTR_VAL(($$ = gen_load(cstate, $1, $3, $5))); }
| arth '+' arth { $$ = gen_arth(cstate, BPF_ADD, $1, $3); } | arth '+' arth { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_ADD, $1, $3))); }
| arth '-' arth { $$ = gen_arth(cstate, BPF_SUB, $1, $3); } | arth '-' arth { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_SUB, $1, $3))); }
| arth '*' arth { $$ = gen_arth(cstate, BPF_MUL, $1, $3); } | arth '*' arth { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_MUL, $1, $3))); }
| arth '/' arth { $$ = gen_arth(cstate, BPF_DIV, $1, $3); } | arth '/' arth { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_DIV, $1, $3))); }
| arth '%' arth { $$ = gen_arth(cstate, BPF_MOD, $1, $3); } | arth '%' arth { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_MOD, $1, $3))); }
| arth '&' arth { $$ = gen_arth(cstate, BPF_AND, $1, $3); } | arth '&' arth { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_AND, $1, $3))); }
| arth '|' arth { $$ = gen_arth(cstate, BPF_OR, $1, $3); } | arth '|' arth { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_OR, $1, $3))); }
| arth '^' arth { $$ = gen_arth(cstate, BPF_XOR, $1, $3); } | arth '^' arth { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_XOR, $1, $3))); }
| arth LSH arth { $$ = gen_arth(cstate, BPF_LSH, $1, $3); } | arth LSH arth { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_LSH, $1, $3))); }
| arth RSH arth { $$ = gen_arth(cstate, BPF_RSH, $1, $3); } | arth RSH arth { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_RSH, $1, $3))); }
| '-' arth %prec UMINUS { $$ = gen_neg(cstate, $2); } | '-' arth %prec UMINUS { CHECK_PTR_VAL(($$ = gen_neg(cstate, $2))); }
| paren narth ')' { $$ = $2; } | paren narth ')' { $$ = $2; }
| LEN { $$ = gen_loadlen(cstate); } | LEN { CHECK_PTR_VAL(($$ = gen_loadlen(cstate))); }
; ;
byteop: '&' { $$ = '&'; } byteop: '&' { $$ = '&'; }
| '|' { $$ = '|'; } | '|' { $$ = '|'; }
@ -727,15 +743,15 @@ atmfield: VPI { $$.atmfieldtype = A_VPI; }
| VCI { $$.atmfieldtype = A_VCI; } | VCI { $$.atmfieldtype = A_VCI; }
; ;
atmvalue: atmfieldvalue atmvalue: atmfieldvalue
| relop NUM { $$.b = gen_atmfield_code(cstate, $<blk>0.atmfieldtype, (bpf_int32)$2, (bpf_u_int32)$1, 0); } | relop NUM { CHECK_PTR_VAL(($$.b = gen_atmfield_code(cstate, $<blk>0.atmfieldtype, (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); } | 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; } | paren atmlistvalue ')' { $$.b = $2.b; $$.q = qerr; }
; ;
atmfieldvalue: NUM { atmfieldvalue: NUM {
$$.atmfieldtype = $<blk>0.atmfieldtype; $$.atmfieldtype = $<blk>0.atmfieldtype;
if ($$.atmfieldtype == A_VPI || if ($$.atmfieldtype == A_VPI ||
$$.atmfieldtype == A_VCI) $$.atmfieldtype == A_VCI)
$$.b = gen_atmfield_code(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 atmlistvalue: atmfieldvalue
@ -760,8 +776,8 @@ mtp3field: SIO { $$.mtp3fieldtype = M_SIO; }
| HSLS { $$.mtp3fieldtype = MH_SLS; } | HSLS { $$.mtp3fieldtype = MH_SLS; }
; ;
mtp3value: mtp3fieldvalue mtp3value: mtp3fieldvalue
| relop NUM { $$.b = gen_mtp3field_code(cstate, $<blk>0.mtp3fieldtype, (u_int)$2, (u_int)$1, 0); } | relop NUM { CHECK_PTR_VAL(($$.b = gen_mtp3field_code(cstate, $<blk>0.mtp3fieldtype, (u_int)$2, (u_int)$1, 0))); }
| irelop NUM { $$.b = gen_mtp3field_code(cstate, $<blk>0.mtp3fieldtype, (u_int)$2, (u_int)$1, 1); } | irelop NUM { CHECK_PTR_VAL(($$.b = gen_mtp3field_code(cstate, $<blk>0.mtp3fieldtype, (u_int)$2, (u_int)$1, 1))); }
| paren mtp3listvalue ')' { $$.b = $2.b; $$.q = qerr; } | paren mtp3listvalue ')' { $$.b = $2.b; $$.q = qerr; }
; ;
mtp3fieldvalue: NUM { mtp3fieldvalue: NUM {
@ -774,7 +790,7 @@ mtp3fieldvalue: NUM {
$$.mtp3fieldtype == MH_OPC || $$.mtp3fieldtype == MH_OPC ||
$$.mtp3fieldtype == MH_DPC || $$.mtp3fieldtype == MH_DPC ||
$$.mtp3fieldtype == MH_SLS) $$.mtp3fieldtype == MH_SLS)
$$.b = gen_mtp3field_code(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 mtp3listvalue: mtp3fieldvalue

View 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);
}

View File

@ -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). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
@ -31,6 +31,10 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
/*
* We use this for platforms that don't have snprintf() at all.
*/
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include <config.h> #include <config.h>
#endif #endif
@ -42,7 +46,7 @@
#include <ctype.h> #include <ctype.h>
#include <sys/types.h> #include <sys/types.h>
#include <pcap-int.h> #include "portability.h"
enum format_flags { enum format_flags {
minus_flag = 1, minus_flag = 1,
@ -525,6 +529,7 @@ pcap_asnprintf (char **ret, size_t max_sz, const char *format, ...)
va_start(args, format); va_start(args, format);
val = pcap_vasnprintf (ret, max_sz, format, args); val = pcap_vasnprintf (ret, max_sz, format, args);
va_end(args);
#ifdef PARANOIA #ifdef PARANOIA
{ {
@ -534,14 +539,15 @@ pcap_asnprintf (char **ret, size_t max_sz, const char *format, ...)
if (tmp == NULL) if (tmp == NULL)
abort (); abort ();
va_start(args, format);
ret2 = pcap_vsprintf (tmp, format, args); ret2 = pcap_vsprintf (tmp, format, args);
va_end(args);
if (val != ret2 || strcmp(*ret, tmp)) if (val != ret2 || strcmp(*ret, tmp))
abort (); abort ();
free (tmp); free (tmp);
} }
#endif #endif
va_end(args);
return val; return val;
} }
#endif #endif

View 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 */
}

View 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 */
}

View 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);
}

View File

@ -1,6 +1,8 @@
#include <stdio.h> #include <stdio.h>
#include <stdarg.h> #include <stdarg.h>
#include "portability.h"
int int
pcap_vsnprintf(char *str, size_t str_size, const char *format, va_list args) 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() * that str is null-terminated, but C99's vsnprintf()
* and snprintf() do, and we want to offer C99 behavior, * and snprintf() do, and we want to offer C99 behavior,
* so forcibly null-terminate the string. * 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'; str[str_size - 1] = '\0';
return (ret); return (ret);

View File

@ -127,7 +127,7 @@ Follow these steps in building libpcap:
But linking the library with `tcpdump' is the ultimate test. DOS/djgpp But linking the library with `tcpdump' is the ultimate test. DOS/djgpp
should now hopefully be a supported target. Get the sources at: should now hopefully be a supported target. Get the sources at:
http://www.tcpdump.org/ https://www.tcpdump.org/
or or
https://github.com/the-tcpdump-group/tcpdump/ https://github.com/the-tcpdump-group/tcpdump/

View File

@ -231,6 +231,21 @@ pcap_nametonetaddr(const char *name)
int h_errnoval; int h_errnoval;
int err; int err;
/*
* 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, err = getnetbyname_r(name, &result_buf, buf, sizeof buf, &np,
&h_errnoval); &h_errnoval);
if (err != 0) { if (err != 0) {
@ -306,7 +321,8 @@ pcap_nametoport(const char *name, int *port, int *proto)
hints.ai_protocol = IPPROTO_TCP; hints.ai_protocol = IPPROTO_TCP;
error = getaddrinfo(NULL, name, &hints, &res); error = getaddrinfo(NULL, name, &hints, &res);
if (error != 0) { if (error != 0) {
if (error != EAI_NONAME) { if (error != EAI_NONAME &&
error != EAI_SERVICE) {
/* /*
* This is a real error, not just "there's * This is a real error, not just "there's
* no such service name". * no such service name".
@ -349,7 +365,8 @@ pcap_nametoport(const char *name, int *port, int *proto)
hints.ai_protocol = IPPROTO_UDP; hints.ai_protocol = IPPROTO_UDP;
error = getaddrinfo(NULL, name, &hints, &res); error = getaddrinfo(NULL, name, &hints, &res);
if (error != 0) { if (error != 0) {
if (error != EAI_NONAME) { if (error != EAI_NONAME &&
error != EAI_SERVICE) {
/* /*
* This is a real error, not just "there's * This is a real error, not just "there's
* no such service name". * no such service name".

View File

@ -30,6 +30,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <memory.h> #include <memory.h>
#include <setjmp.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
@ -226,6 +227,16 @@ struct vmapinfo {
}; };
typedef struct { 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. * A flag to indicate that further optimization is needed.
* Iterative passes are continued until a given pass yields no * Iterative passes are continued until a given pass yields no
@ -252,19 +263,19 @@ typedef struct {
* True if a is in uset {p} * True if a is in uset {p}
*/ */
#define SET_MEMBER(p, a) \ #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. * Add 'a' to uset p.
*/ */
#define SET_INSERT(p, a) \ #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. * Delete 'a' from uset p.
*/ */
#define SET_DELETE(p, a) \ #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 * a := a intersect b
@ -311,6 +322,16 @@ typedef struct {
} opt_state_t; } opt_state_t;
typedef struct { 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, * Some pointers used to convert the basic block form of the code,
* into the array form that BPF requires. 'fstart' will point to * into the array form that BPF requires. 'fstart' will point to
@ -321,14 +342,16 @@ typedef struct {
struct bpf_insn *ftail; struct bpf_insn *ftail;
} conv_state_t; } 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 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 intern_blocks(opt_state_t *, struct icode *);
static void find_inedges(opt_state_t *, struct block *); static void find_inedges(opt_state_t *, struct block *);
#ifdef BDEBUG #ifdef BDEBUG
static void opt_dump(compiler_state_t *, struct icode *); static void opt_dump(opt_state_t *, struct icode *);
#endif #endif
#ifndef MAX #ifndef MAX
@ -661,7 +684,7 @@ F(opt_state_t *opt_state, int code, int v0, int v1)
int val; int val;
struct valnode *p; 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; hash %= MODULUS;
for (p = opt_state->hashtbl[hash]; p; p = p->next) 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.) * (Unary operators are handled elsewhere.)
*/ */
static void static void
fold_op(compiler_state_t *cstate, opt_state_t *opt_state, fold_op(opt_state_t *opt_state, struct stmt *s, int v0, int v1)
struct stmt *s, int v0, int v1)
{ {
bpf_u_int32 a, b; bpf_u_int32 a, b;
@ -722,13 +744,13 @@ fold_op(compiler_state_t *cstate, opt_state_t *opt_state,
case BPF_DIV: case BPF_DIV:
if (b == 0) if (b == 0)
bpf_error(cstate, "division by zero"); opt_error(opt_state, "division by zero");
a /= b; a /= b;
break; break;
case BPF_MOD: case BPF_MOD:
if (b == 0) if (b == 0)
bpf_error(cstate, "modulus by zero"); opt_error(opt_state, "modulus by zero");
a %= b; a %= b;
break; break;
@ -745,11 +767,39 @@ fold_op(compiler_state_t *cstate, opt_state_t *opt_state,
break; break;
case BPF_LSH: case BPF_LSH:
/*
* 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; a <<= b;
else
a = 0;
break; break;
case BPF_RSH: case BPF_RSH:
/*
* 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; a >>= b;
else
a = 0;
break; break;
default: default:
@ -1041,8 +1091,7 @@ opt_peep(opt_state_t *opt_state, struct block *b)
* evaluation and code transformations weren't folded together. * evaluation and code transformations weren't folded together.
*/ */
static void static void
opt_stmt(compiler_state_t *cstate, opt_state_t *opt_state, opt_stmt(opt_state_t *opt_state, struct stmt *s, int val[], int alter)
struct stmt *s, int val[], int alter)
{ {
int op; int op;
int v; int v;
@ -1094,7 +1143,23 @@ opt_stmt(compiler_state_t *cstate, opt_state_t *opt_state,
case BPF_ALU|BPF_NEG: case BPF_ALU|BPF_NEG:
if (alter && opt_state->vmap[val[A_ATOM]].is_const) { if (alter && opt_state->vmap[val[A_ATOM]].is_const) {
s->code = BPF_LD|BPF_IMM; 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); val[A_ATOM] = K(s->k);
} }
else else
@ -1114,9 +1179,17 @@ opt_stmt(compiler_state_t *cstate, opt_state_t *opt_state,
op = BPF_OP(s->code); op = BPF_OP(s->code);
if (alter) { if (alter) {
if (s->k == 0) { 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 * 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 || if (op == BPF_ADD ||
op == BPF_LSH || op == BPF_RSH || op == BPF_LSH || op == BPF_RSH ||
op == BPF_OR || op == BPF_XOR) { 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); val[A_ATOM] = K(s->k);
break; 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) { 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); val[A_ATOM] = K(s->k);
break; break;
} }
@ -1151,12 +1230,22 @@ opt_stmt(compiler_state_t *cstate, opt_state_t *opt_state,
op = BPF_OP(s->code); op = BPF_OP(s->code);
if (alter && opt_state->vmap[val[X_ATOM]].is_const) { if (alter && opt_state->vmap[val[X_ATOM]].is_const) {
if (opt_state->vmap[val[A_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); val[A_ATOM] = K(s->k);
} }
else { else {
s->code = BPF_ALU|BPF_K|op; s->code = BPF_ALU|BPF_K|op;
s->k = opt_state->vmap[val[X_ATOM]].const_val; 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; opt_state->done = 0;
val[A_ATOM] = val[A_ATOM] =
F(opt_state, s->code, val[A_ATOM], K(s->k)); 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 static void
opt_blk(compiler_state_t *cstate, opt_state_t *opt_state, opt_blk(opt_state_t *opt_state, struct block *b, int do_stmts)
struct block *b, int do_stmts)
{ {
struct slist *s; struct slist *s;
struct edge *p; struct edge *p;
@ -1326,7 +1414,7 @@ opt_blk(compiler_state_t *cstate, opt_state_t *opt_state,
aval = b->val[A_ATOM]; aval = b->val[A_ATOM];
xval = b->val[X_ATOM]; xval = b->val[X_ATOM];
for (s = b->stmts; s; s = s->next) 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 * 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) { while (x != 0) {
k = lowest_set_bit(x); k = lowest_set_bit(x);
x &=~ (1 << k); x &=~ ((bpf_u_int32)1 << k);
k += i * BITS_PER_WORD; k += i * BITS_PER_WORD;
target = fold_edge(ep->succ, opt_state->edges[k]); 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 static void
opt_blks(compiler_state_t *cstate, opt_state_t *opt_state, struct icode *ic, opt_blks(opt_state_t *opt_state, struct icode *ic, int do_stmts)
int do_stmts)
{ {
int i, maxlevel; int i, maxlevel;
struct block *p; 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); find_inedges(opt_state, ic->root);
for (i = maxlevel; i >= 0; --i) for (i = maxlevel; i >= 0; --i)
for (p = opt_state->levels[i]; p; p = p->link) 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) if (do_stmts)
/* /*
@ -1777,14 +1864,13 @@ opt_root(struct block **b)
} }
static void static void
opt_loop(compiler_state_t *cstate, opt_state_t *opt_state, struct icode *ic, opt_loop(opt_state_t *opt_state, struct icode *ic, int do_stmts)
int do_stmts)
{ {
#ifdef BDEBUG #ifdef BDEBUG
if (pcap_optimizer_debug > 1 || pcap_print_dot_graph) { if (pcap_optimizer_debug > 1 || pcap_print_dot_graph) {
printf("opt_loop(root, %d) begin\n", do_stmts); printf("opt_loop(root, %d) begin\n", do_stmts);
opt_dump(cstate, ic); opt_dump(opt_state, ic);
} }
#endif #endif
do { 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_closure(opt_state, ic->root);
find_ud(opt_state, ic->root); find_ud(opt_state, ic->root);
find_edom(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 #ifdef BDEBUG
if (pcap_optimizer_debug > 1 || pcap_print_dot_graph) { if (pcap_optimizer_debug > 1 || pcap_print_dot_graph) {
printf("opt_loop(root, %d) bottom, done=%d\n", do_stmts, opt_state->done); printf("opt_loop(root, %d) bottom, done=%d\n", do_stmts, opt_state->done);
opt_dump(cstate, ic); opt_dump(opt_state, ic);
} }
#endif #endif
} while (!opt_state->done); } 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. * Optimize the filter code in its dag representation.
* Return 0 on success, -1 on error.
*/ */
void int
bpf_optimize(compiler_state_t *cstate, struct icode *ic) bpf_optimize(struct icode *ic, char *errbuf)
{ {
opt_state_t opt_state; opt_state_t opt_state;
opt_init(cstate, &opt_state, ic); memset(&opt_state, 0, sizeof(opt_state));
opt_loop(cstate, &opt_state, ic, 0); opt_state.errbuf = errbuf;
opt_loop(cstate, &opt_state, ic, 1); 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); intern_blocks(&opt_state, ic);
#ifdef BDEBUG #ifdef BDEBUG
if (pcap_optimizer_debug > 1 || pcap_print_dot_graph) { if (pcap_optimizer_debug > 1 || pcap_print_dot_graph) {
printf("after intern_blocks()\n"); printf("after intern_blocks()\n");
opt_dump(cstate, ic); opt_dump(&opt_state, ic);
} }
#endif #endif
opt_root(&ic->root); opt_root(&ic->root);
#ifdef BDEBUG #ifdef BDEBUG
if (pcap_optimizer_debug > 1 || pcap_print_dot_graph) { if (pcap_optimizer_debug > 1 || pcap_print_dot_graph) {
printf("after opt_root()\n"); printf("after opt_root()\n");
opt_dump(cstate, ic); opt_dump(&opt_state, ic);
} }
#endif #endif
opt_cleanup(&opt_state); opt_cleanup(&opt_state);
return 0;
} }
static void static void
@ -1943,6 +2037,24 @@ opt_cleanup(opt_state_t *opt_state)
free((void *)opt_state->blocks); 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'. * 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. * from the total number of blocks and/or statements.
*/ */
static void 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; bpf_u_int32 *p;
int i, n, max_stmts; 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); n = count_blocks(ic, ic->root);
opt_state->blocks = (struct block **)calloc(n, sizeof(*opt_state->blocks)); opt_state->blocks = (struct block **)calloc(n, sizeof(*opt_state->blocks));
if (opt_state->blocks == NULL) if (opt_state->blocks == NULL)
bpf_error(cstate, "malloc"); opt_error(opt_state, "malloc");
unMarkAll(ic); unMarkAll(ic);
opt_state->n_blocks = 0; opt_state->n_blocks = 0;
number_blks_r(opt_state, ic, ic->root); number_blks_r(opt_state, ic, ic->root);
opt_state->n_edges = 2 * opt_state->n_blocks; opt_state->n_edges = 2 * opt_state->n_blocks;
opt_state->edges = (struct edge **)calloc(opt_state->n_edges, sizeof(*opt_state->edges)); opt_state->edges = (struct edge **)calloc(opt_state->n_edges, sizeof(*opt_state->edges));
if (opt_state->edges == NULL) if (opt_state->edges == NULL) {
bpf_error(cstate, "malloc"); opt_error(opt_state, "malloc");
}
/* /*
* The number of levels is bounded by the number of nodes. * 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)); opt_state->levels = (struct block **)calloc(opt_state->n_blocks, sizeof(*opt_state->levels));
if (opt_state->levels == NULL) if (opt_state->levels == NULL) {
bpf_error(cstate, "malloc"); opt_error(opt_state, "malloc");
}
opt_state->edgewords = opt_state->n_edges / (8 * sizeof(bpf_u_int32)) + 1; 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; 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 */ /* XXX */
opt_state->space = (bpf_u_int32 *)malloc(2 * opt_state->n_blocks * opt_state->nodewords * sizeof(*opt_state->space) 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)); + opt_state->n_edges * opt_state->edgewords * sizeof(*opt_state->space));
if (opt_state->space == NULL) if (opt_state->space == NULL) {
bpf_error(cstate, "malloc"); opt_error(opt_state, "malloc");
}
p = opt_state->space; p = opt_state->space;
opt_state->all_dom_sets = p; opt_state->all_dom_sets = p;
for (i = 0; i < n; ++i) { 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->maxval = 3 * max_stmts;
opt_state->vmap = (struct vmapinfo *)calloc(opt_state->maxval, sizeof(*opt_state->vmap)); 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)); 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) if (opt_state->vnode_base == NULL) {
bpf_error(cstate, "malloc"); 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]; int bids[NBIDS];
#endif #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 * Returns true if successful. Returns false if a branch has
* an offset that is too large. If so, we have marked that * an offset that is too large. If so, we have marked that
@ -2122,8 +2244,7 @@ int bids[NBIDS];
* properly. * properly.
*/ */
static int static int
convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state, convert_code_r(conv_state_t *conv_state, struct icode *ic, struct block *p)
struct icode *ic, struct block *p)
{ {
struct bpf_insn *dst; struct bpf_insn *dst;
struct slist *src; struct slist *src;
@ -2136,9 +2257,9 @@ convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state,
return (1); return (1);
Mark(ic, p); 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); 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); return (0);
slen = slength(p->stmts); slen = slength(p->stmts);
@ -2151,7 +2272,7 @@ convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state,
if (slen) { if (slen) {
offset = (struct slist **)calloc(slen, sizeof(struct slist *)); offset = (struct slist **)calloc(slen, sizeof(struct slist *));
if (!offset) { if (!offset) {
bpf_error(cstate, "not enough core"); conv_error(conv_state, "not enough core");
/*NOTREACHED*/ /*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 (BPF_CLASS(src->s.code) != BPF_JMP || src->s.code == (BPF_JMP|BPF_JA)) {
#if 0 #if 0
if (src->s.jt || src->s.jf) { if (src->s.jt || src->s.jf) {
bpf_error(cstate, "illegal jmp destination"); free(offset);
conv_error(conv_state, "illegal jmp destination");
/*NOTREACHED*/ /*NOTREACHED*/
} }
#endif #endif
@ -2195,7 +2317,8 @@ convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state,
#endif #endif
if (!src->s.jt || !src->s.jf) { 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*/ /*NOTREACHED*/
} }
@ -2203,12 +2326,14 @@ convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state,
for (i = 0; i < slen; i++) { for (i = 0; i < slen; i++) {
if (offset[i] == src->s.jt) { if (offset[i] == src->s.jt) {
if (jt) { if (jt) {
bpf_error(cstate, ljerr, "multiple matches", off); free(offset);
conv_error(conv_state, ljerr, "multiple matches", off);
/*NOTREACHED*/ /*NOTREACHED*/
} }
if (i - off - 1 >= 256) { 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*/ /*NOTREACHED*/
} }
dst->jt = (u_char)(i - off - 1); 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 (offset[i] == src->s.jf) {
if (jf) { if (jf) {
bpf_error(cstate, ljerr, "multiple matches", off); free(offset);
conv_error(conv_state, ljerr, "multiple matches", off);
/*NOTREACHED*/ /*NOTREACHED*/
} }
if (i - off - 1 >= 256) { 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*/ /*NOTREACHED*/
} }
dst->jf = (u_char)(i - off - 1); 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) { if (!jt || !jf) {
bpf_error(cstate, ljerr, "no destination found", off); free(offset);
conv_error(conv_state, ljerr, "no destination found", off);
/*NOTREACHED*/ /*NOTREACHED*/
} }
} }
@ -2257,7 +2385,7 @@ convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state,
} }
/* branch if T to following jump */ /* branch if T to following jump */
if (extrajmps >= 256) { if (extrajmps >= 256) {
bpf_error(cstate, "too many extra jumps"); conv_error(conv_state, "too many extra jumps");
/*NOTREACHED*/ /*NOTREACHED*/
} }
dst->jt = (u_char)extrajmps; 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 */ /* branch if F to following jump */
/* if two jumps are inserted, F goes to second one */ /* if two jumps are inserted, F goes to second one */
if (extrajmps >= 256) { if (extrajmps >= 256) {
bpf_error(cstate, "too many extra jumps"); conv_error(conv_state, "too many extra jumps");
/*NOTREACHED*/ /*NOTREACHED*/
} }
dst->jf = (u_char)extrajmps; 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. * done with the filter program. See the pcap man page.
*/ */
struct bpf_insn * struct bpf_insn *
icode_to_fcode(compiler_state_t *cstate, struct icode *ic, icode_to_fcode(struct icode *ic, struct block *root, u_int *lenp,
struct block *root, u_int *lenp) char *errbuf)
{ {
u_int n; u_int n;
struct bpf_insn *fp; struct bpf_insn *fp;
conv_state_t conv_state; 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 * Loop doing convert_code_r() until no branches remain
* with too-large offsets. * with too-large offsets.
@ -2328,14 +2463,18 @@ icode_to_fcode(compiler_state_t *cstate, struct icode *ic,
n = *lenp = count_stmts(ic, root); n = *lenp = count_stmts(ic, root);
fp = (struct bpf_insn *)malloc(sizeof(*fp) * n); fp = (struct bpf_insn *)malloc(sizeof(*fp) * n);
if (fp == NULL) if (fp == NULL) {
bpf_error(cstate, "malloc"); (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"malloc");
free(fp);
return NULL;
}
memset((char *)fp, 0, sizeof(*fp) * n); memset((char *)fp, 0, sizeof(*fp) * n);
conv_state.fstart = fp; conv_state.fstart = fp;
conv_state.ftail = fp + n; conv_state.ftail = fp + n;
unMarkAll(ic); unMarkAll(ic);
if (convert_code_r(cstate, &conv_state, ic, root)) if (convert_code_r(&conv_state, ic, root))
break; break;
free(fp); free(fp);
} }
@ -2343,6 +2482,22 @@ icode_to_fcode(compiler_state_t *cstate, struct icode *ic,
return fp; 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 * Make a copy of a BPF program and put it in the "fcode" member of
* a "pcap_t". * 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 * After install graphviz on http://www.graphviz.org/, save it as bpf.dot
* and run `dot -Tpng -O bpf.dot' to draw the graph. * and run `dot -Tpng -O bpf.dot' to draw the graph.
*/ */
static void static int
dot_dump(compiler_state_t *cstate, struct icode *ic) dot_dump(struct icode *ic, char *errbuf)
{ {
struct bpf_program f; struct bpf_program f;
FILE *out = stdout; FILE *out = stdout;
memset(bids, 0, sizeof bids); 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"); fprintf(out, "digraph BPF {\n");
unMarkAll(ic); unMarkAll(ic);
@ -2469,30 +2626,39 @@ dot_dump(compiler_state_t *cstate, struct icode *ic)
fprintf(out, "}\n"); fprintf(out, "}\n");
free((char *)f.bf_insns); free((char *)f.bf_insns);
return 0;
} }
static void static int
plain_dump(compiler_state_t *cstate, struct icode *ic) plain_dump(struct icode *ic, char *errbuf)
{ {
struct bpf_program f; struct bpf_program f;
memset(bids, 0, sizeof bids); 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); bpf_dump(&f, 1);
putchar('\n'); putchar('\n');
free((char *)f.bf_insns); free((char *)f.bf_insns);
return 0;
} }
static void 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 * If the CFG, in DOT format, is requested, output it rather than
* the code that would be generated from that graph. * the code that would be generated from that graph.
*/ */
if (pcap_print_dot_graph) if (pcap_print_dot_graph)
dot_dump(cstate, ic); status = dot_dump(ic, errbuf);
else 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 #endif

View File

@ -206,7 +206,7 @@ static int monitor_mode(pcap_t *, int);
# endif # endif
# if defined(__APPLE__) # if defined(__APPLE__)
static void remove_en(pcap_t *); static void remove_non_802_11(pcap_t *);
static void remove_802_11(pcap_t *); static void remove_802_11(pcap_t *);
# endif # endif
@ -737,10 +737,10 @@ get_dlt_list(int fd, int v, struct bpf_dltlist *bdlp, char *ebuf)
} }
#endif #endif
#if defined(__APPLE__)
static int static int
pcap_can_set_rfmon_bpf(pcap_t *p) pcap_can_set_rfmon_bpf(pcap_t *p)
{ {
#if defined(__APPLE__)
struct utsname osinfo; struct utsname osinfo;
struct ifreq ifr; struct ifreq ifr;
int fd; int fd;
@ -799,8 +799,8 @@ pcap_can_set_rfmon_bpf(pcap_t *p)
errno, "socket"); errno, "socket");
return (PCAP_ERROR); return (PCAP_ERROR);
} }
strlcpy(ifr.ifr_name, "wlt", sizeof(ifr.ifr_name)); pcap_strlcpy(ifr.ifr_name, "wlt", sizeof(ifr.ifr_name));
strlcat(ifr.ifr_name, p->opt.device + 2, sizeof(ifr.ifr_name)); pcap_strlcat(ifr.ifr_name, p->opt.device + 2, sizeof(ifr.ifr_name));
if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifr) < 0) { if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifr) < 0) {
/* /*
* No such device? * No such device?
@ -880,7 +880,11 @@ pcap_can_set_rfmon_bpf(pcap_t *p)
close(fd); close(fd);
#endif /* BIOCGDLTLIST */ #endif /* BIOCGDLTLIST */
return (0); return (0);
}
#elif defined(HAVE_BSD_IEEE80211) #elif defined(HAVE_BSD_IEEE80211)
static int
pcap_can_set_rfmon_bpf(pcap_t *p)
{
int ret; int ret;
ret = monitor_mode(p, 0); ret = monitor_mode(p, 0);
@ -889,10 +893,14 @@ pcap_can_set_rfmon_bpf(pcap_t *p)
if (ret == 0) if (ret == 0)
return (1); /* success */ return (1); /* success */
return (ret); return (ret);
#else
return (0);
#endif
} }
#else
static int
pcap_can_set_rfmon_bpf(pcap_t *p _U_)
{
return (0);
}
#endif
static int static int
pcap_stats_bpf(pcap_t *p, struct pcap_stat *ps) 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: case EWOULDBLOCK:
return (0); 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 * The device on which we're capturing
* went away. * went away.
* *
* XXX - we should really return * XXX - we should really return
* PCAP_ERROR_IFACE_NOT_UP, but * an appropriate error for that,
* pcap_dispatch() etc. aren't * but pcap_dispatch() etc. aren't
* defined to retur that. * documented as having error returns
* other than PCAP_ERROR or PCAP_ERROR_BREAK.
*/ */
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"The interface went down"); "The interface disappeared");
return (PCAP_ERROR); return (PCAP_ERROR);
#if defined(sun) && !defined(BSD) && !defined(__svr4__) && !defined(__SVR4) #if defined(sun) && !defined(BSD) && !defined(__svr4__) && !defined(__SVR4)
@ -1358,8 +1369,8 @@ bpf_load(char *errbuf)
/* Check if the driver is loaded */ /* Check if the driver is loaded */
memset(&cfg_ld, 0x0, sizeof(cfg_ld)); memset(&cfg_ld, 0x0, sizeof(cfg_ld));
pcap_snprintf(buf, sizeof(buf), "%s/%s", DRIVER_PATH, BPF_NAME);
cfg_ld.path = buf; 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) || if ((sysconfig(SYS_QUERYLOAD, (void *)&cfg_ld, sizeof(cfg_ld)) == -1) ||
(cfg_ld.kmid == 0)) { (cfg_ld.kmid == 0)) {
/* Driver isn't loaded, load it now */ /* Driver isn't loaded, load it now */
@ -1469,7 +1480,7 @@ pcap_cleanup_bpf(pcap_t *p)
s = socket(AF_LOCAL, SOCK_DGRAM, 0); s = socket(AF_LOCAL, SOCK_DGRAM, 0);
if (s >= 0) { if (s >= 0) {
strlcpy(ifr.ifr_name, pb->device, pcap_strlcpy(ifr.ifr_name, pb->device,
sizeof(ifr.ifr_name)); sizeof(ifr.ifr_name));
ioctl(s, SIOCIFDESTROY, &ifr); ioctl(s, SIOCIFDESTROY, &ifr);
close(s); close(s);
@ -1532,9 +1543,9 @@ check_setif_failure(pcap_t *p, int error)
*/ */
fd = socket(AF_INET, SOCK_DGRAM, 0); fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd != -1) { if (fd != -1) {
strlcpy(ifr.ifr_name, "en", pcap_strlcpy(ifr.ifr_name, "en",
sizeof(ifr.ifr_name)); 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)); sizeof(ifr.ifr_name));
if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifr) < 0) { if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifr) < 0) {
/* /*
@ -1721,7 +1732,7 @@ pcap_activate_bpf(pcap_t *p)
goto bad; goto bad;
} }
znamelen = zonesep - p->opt.device; 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); ifr.lifr_zoneid = getzoneidbyname(path_zname);
if (ifr.lifr_zoneid == -1) { if (ifr.lifr_zoneid == -1) {
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 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); sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd != -1) { if (sockfd != -1) {
strlcpy(ifrname, pcap_strlcpy(ifrname,
p->opt.device, ifnamsiz); p->opt.device, ifnamsiz);
if (ioctl(sockfd, SIOCGIFFLAGS, if (ioctl(sockfd, SIOCGIFFLAGS,
(char *)&ifr) < 0) { (char *)&ifr) < 0) {
@ -1888,7 +1899,7 @@ pcap_activate_bpf(pcap_t *p)
/* /*
* Create the interface. * 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 (ioctl(s, SIOCIFCREATE2, &ifr) < 0) {
if (errno == EINVAL) { if (errno == EINVAL) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
@ -2187,7 +2198,7 @@ pcap_activate_bpf(pcap_t *p)
* of link-layer types, as selecting * of link-layer types, as selecting
* it will keep monitor mode off. * it will keep monitor mode off.
*/ */
remove_en(p); remove_non_802_11(p);
/* /*
* If the new mode we want isn't * 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)); strncpy(req.ifm_name, name, sizeof(req.ifm_name));
if (ioctl(sock, SIOCGIFMEDIA, &req) < 0) { if (ioctl(sock, SIOCGIFMEDIA, &req) < 0) {
if (errno == EOPNOTSUPP || errno == EINVAL || errno == ENOTTY || if (errno == EOPNOTSUPP || errno == EINVAL || errno == ENOTTY ||
errno == ENODEV) { errno == ENODEV || errno == EPERM) {
/* /*
* Not supported, so we can't provide any * Not supported, so we can't provide any
* additional information. Assume that * additional information. Assume that
* this means that "connected" vs. * this means that "connected" vs.
* "disconnected" doesn't apply. * "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; *flags |= PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE;
close(sock); close(sock);
@ -2890,7 +2910,7 @@ monitor_mode(pcap_t *p, int set)
default: default:
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
errno, "SIOCGIFMEDIA 1"); errno, "SIOCGIFMEDIA");
close(sock); close(sock);
return (PCAP_ERROR); return (PCAP_ERROR);
} }
@ -3032,8 +3052,12 @@ find_802_11(struct bpf_dltlist *bdlp)
new_dlt = bdlp->bfl_list[i]; new_dlt = bdlp->bfl_list[i];
break; break;
#ifdef DLT_PRISM_HEADER
case DLT_PRISM_HEADER: case DLT_PRISM_HEADER:
#endif
#ifdef DLT_AIRONET_HEADER
case DLT_AIRONET_HEADER: case DLT_AIRONET_HEADER:
#endif
case DLT_IEEE802_11_RADIO_AVS: case DLT_IEEE802_11_RADIO_AVS:
/* /*
* 802.11 with radio, but not radiotap. * 802.11 with radio, but not radiotap.
@ -3068,24 +3092,25 @@ find_802_11(struct bpf_dltlist *bdlp)
#if defined(__APPLE__) && defined(BIOCGDLTLIST) #if defined(__APPLE__) && defined(BIOCGDLTLIST)
/* /*
* Remove DLT_EN10MB from the list of DLT_ values, as we're in monitor mode, * Remove non-802.11 header types from the list of DLT_ values, as we're in
* and DLT_EN10MB isn't supported in monitor mode. * monitor mode, and those header types aren't supported in monitor mode.
*/ */
static void static void
remove_en(pcap_t *p) remove_non_802_11(pcap_t *p)
{ {
int i, j; 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; j = 0;
for (i = 0; i < p->dlt_count; i++) { for (i = 0; i < p->dlt_count; i++) {
switch (p->dlt_list[i]) { switch (p->dlt_list[i]) {
case DLT_EN10MB: case DLT_EN10MB:
case DLT_RAW:
/* /*
* Don't offer this one. * Not 802.11. Don't offer this one.
*/ */
continue; continue;
@ -3127,10 +3152,17 @@ remove_802_11(pcap_t *p)
switch (p->dlt_list[i]) { switch (p->dlt_list[i]) {
case DLT_IEEE802_11: case DLT_IEEE802_11:
#ifdef DLT_PRISM_HEADER
case DLT_PRISM_HEADER: case DLT_PRISM_HEADER:
#endif
#ifdef DLT_AIRONET_HEADER
case DLT_AIRONET_HEADER: case DLT_AIRONET_HEADER:
#endif
case DLT_IEEE802_11_RADIO: case DLT_IEEE802_11_RADIO:
case DLT_IEEE802_11_RADIO_AVS: case DLT_IEEE802_11_RADIO_AVS:
#ifdef DLT_PPI
case DLT_PPI:
#endif
/* /*
* 802.11. Don't offer this one. * 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 * Set direction flag: Which packets do we accept on a forwarding
* single device? IN, OUT or both? * single device? IN, OUT or both?
*/ */
#if defined(BIOCSDIRECTION)
static int static int
pcap_setdirection_bpf(pcap_t *p, pcap_direction_t d) pcap_setdirection_bpf(pcap_t *p, pcap_direction_t d)
{ {
#if defined(BIOCSDIRECTION)
u_int direction; u_int direction;
direction = (d == PCAP_D_IN) ? BPF_D_IN : 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 (-1);
} }
return (0); return (0);
}
#elif defined(BIOCSSEESENT) #elif defined(BIOCSSEESENT)
static int
pcap_setdirection_bpf(pcap_t *p, pcap_direction_t d)
{
u_int seesent; u_int seesent;
/* /*
@ -3258,25 +3294,35 @@ pcap_setdirection_bpf(pcap_t *p, pcap_direction_t d)
return (-1); return (-1);
} }
return (0); return (0);
}
#else #else
static int
pcap_setdirection_bpf(pcap_t *p, pcap_direction_t d _U_)
{
(void) pcap_snprintf(p->errbuf, sizeof(p->errbuf), (void) pcap_snprintf(p->errbuf, sizeof(p->errbuf),
"This system doesn't support BIOCSSEESENT, so the direction can't be set"); "This system doesn't support BIOCSSEESENT, so the direction can't be set");
return (-1); return (-1);
#endif
} }
#endif
#ifdef BIOCSDLT
static int static int
pcap_set_datalink_bpf(pcap_t *p, int dlt) pcap_set_datalink_bpf(pcap_t *p, int dlt)
{ {
#ifdef BIOCSDLT
if (ioctl(p->fd, BIOCSDLT, &dlt) == -1) { if (ioctl(p->fd, BIOCSDLT, &dlt) == -1) {
pcap_fmt_errmsg_for_errno(p->errbuf, sizeof(p->errbuf), pcap_fmt_errmsg_for_errno(p->errbuf, sizeof(p->errbuf),
errno, "Cannot set DLT %d", dlt); errno, "Cannot set DLT %d", dlt);
return (-1); return (-1);
} }
#endif
return (0); return (0);
} }
#else
static int
pcap_set_datalink_bpf(pcap_t *p _U_, int dlt _U_)
{
return (0);
}
#endif
/* /*
* Platform-specific information. * Platform-specific information.

View File

@ -74,13 +74,14 @@ bt_findalldevs(pcap_if_list_t *devlistp, char *err_str)
{ {
struct hci_dev_list_req *dev_list; struct hci_dev_list_req *dev_list;
struct hci_dev_req *dev_req; struct hci_dev_req *dev_req;
int i, sock; int sock;
unsigned i;
int ret = 0; int ret = 0;
sock = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); sock = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
if (sock < 0) if (sock < 0)
{ {
/* if bluetooth is not supported this this is not fatal*/ /* if bluetooth is not supported this is not fatal*/
if (errno == EAFNOSUPPORT) if (errno == EAFNOSUPPORT)
return 0; return 0;
pcap_fmt_errmsg_for_errno(err_str, PCAP_ERRBUF_SIZE, 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; dev_req = dev_list->dev_req;
for (i = 0; i < dev_list->dev_num; i++, dev_req++) { for (i = 0; i < dev_list->dev_num; i++, dev_req++) {
char dev_name[20], dev_descr[30]; char dev_name[20], dev_descr[40];
pcap_snprintf(dev_name, 20, BT_IFACE"%d", dev_req->dev_id); pcap_snprintf(dev_name, sizeof(dev_name), BT_IFACE"%u", dev_req->dev_id);
pcap_snprintf(dev_descr, 30, "Bluetooth adapter number %d", i); pcap_snprintf(dev_descr, sizeof(dev_descr), "Bluetooth adapter number %u", i);
/* /*
* Bluetooth is a wireless technology. * 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 static int
bt_inject_linux(pcap_t *handle, const void *buf _U_, size_t size _U_) bt_inject_linux(pcap_t *handle, const void *buf _U_, size_t size _U_)
{ {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "inject not supported on " pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"bluetooth devices"); "Packet injection is not supported on Bluetooth devices");
return (-1); return (-1);
} }

View File

@ -149,7 +149,8 @@ bt_monitor_read(pcap_t *handle, int max_packets _U_, pcap_handler callback, u_ch
static int static int
bt_monitor_inject(pcap_t *handle, const void *buf _U_, size_t size _U_) bt_monitor_inject(pcap_t *handle, const void *buf _U_, size_t size _U_)
{ {
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; return -1;
} }

View File

@ -514,11 +514,20 @@
#define LINKTYPE_RAIF1 198 #define LINKTYPE_RAIF1 198
/* /*
* IPMB packet for IPMI, beginning with the I2C slave address, followed * IPMB packet for IPMI, beginning with a 2-byte header, followed by
* by the netFn and LUN, etc.. Requested by Chanthy Toeung * the I2C slave address, followed by the netFn and LUN, etc..
* <chanthy.toeung@ca.kontron.com>. * 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 * Juniper-private data link type, as per request from
@ -549,15 +558,35 @@
*/ */
#define LINKTYPE_LAPD 203 #define LINKTYPE_LAPD 203
/* /*
* Variants of various link-layer headers, with a one-byte direction * PPP, with a one-byte direction pseudo-header prepended - zero means
* pseudo-header prepended - zero means "received by this host", * "received by this host", non-zero (any non-zero value) means "sent by
* non-zero (any non-zero value) means "sent by this host" - as per * this host" - as per Will Barker <w.barker@zen.co.uk>.
* 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 */ #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 */ #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 */ #define LINKTYPE_LAPB_WITH_DIR 207 /* LAPB */
/* /*
@ -1081,7 +1110,21 @@
*/ */
#define LINKTYPE_DISPLAYPORT_AUX 275 #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 { static struct linktype_map {
int dlt; int dlt;
@ -1231,18 +1274,30 @@ linktype_to_dlt(int linktype)
/* /*
* Return the maximum snapshot length for a given DLT_ value. * Return the maximum snapshot length for a given DLT_ value.
* *
* For most link-layer types, we use MAXIMUM_SNAPLEN, but for DLT_DBUS, * For most link-layer types, we use MAXIMUM_SNAPLEN.
* the maximum is 134217728, as per *
* For DLT_DBUS, the maximum is 128MiB, as per
* *
* https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-messages * 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 u_int
max_snaplen_for_dlt(int dlt) max_snaplen_for_dlt(int dlt)
{ {
if (dlt == DLT_DBUS) switch (dlt) {
return 134217728;
else case DLT_DBUS:
return 128*1024*1024;
case DLT_USBPCAP:
return 1024*1024;
default:
return MAXIMUM_SNAPLEN; return MAXIMUM_SNAPLEN;
}
} }
/* /*

View File

@ -35,9 +35,13 @@
* machine (if the file was written in little-end order). * machine (if the file was written in little-end order).
*/ */
#define SWAPLONG(y) \ #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) \ #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); extern int dlt_to_linktype(int dlt);

View File

@ -1,18 +1,10 @@
/* /*
* pcap-dag.c: Packet capture interface for Emulex EndaceDAG cards. * pcap-dag.c: Packet capture interface for Endace DAG 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.
* *
* Authors: Richard Littin, Sean Irvine ({richard,sean}@reeltwo.com) * Authors: Richard Littin, Sean Irvine ({richard,sean}@reeltwo.com)
* Modifications: Jesper Peterson * Modifications: Jesper Peterson
* Koryn Grant * Koryn Grant
* Stephen Donnelly <stephen.donnelly@emulex.com> * Stephen Donnelly <stephen.donnelly@endace.com>
*/ */
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
@ -258,12 +250,18 @@ dag_platform_cleanup(pcap_t *p)
if(pd->dag_ref != NULL) { if(pd->dag_ref != NULL) {
dag_config_dispose(pd->dag_ref); 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; p->fd = -1;
pd->dag_ref = NULL; pd->dag_ref = NULL;
} }
delete_pcap_dag(p); delete_pcap_dag(p);
pcap_cleanup_live_common(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 static void
@ -722,7 +720,7 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
static int static int
dag_inject(pcap_t *p, const void *buf _U_, size_t size _U_) dag_inject(pcap_t *p, const void *buf _U_, 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); PCAP_ERRBUF_SIZE);
return (-1); return (-1);
} }
@ -746,18 +744,20 @@ static int dag_activate(pcap_t* p)
daginf_t* daginf; daginf_t* daginf;
char * newDev = NULL; char * newDev = NULL;
char * device = p->opt.device; char * device = p->opt.device;
int ret;
dag_size_t mindata; dag_size_t mindata;
struct timeval maxwait; struct timeval maxwait;
struct timeval poll; struct timeval poll;
if (device == NULL) { if (device == NULL) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "device is NULL"); pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "device is NULL");
return -1; return PCAP_ERROR;
} }
/* Initialize some components of the pcap structure. */ /* Initialize some components of the pcap structure. */
newDev = (char *)malloc(strlen(device) + 16); newDev = (char *)malloc(strlen(device) + 16);
if (newDev == NULL) { if (newDev == NULL) {
ret = PCAP_ERROR;
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
errno, "Can't allocate string for device name"); errno, "Can't allocate string for device name");
goto fail; 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 */ /* 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) { 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, pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
errno, "dag_parse_name"); errno, "dag_parse_name");
goto fail; goto fail;
@ -772,25 +779,40 @@ static int dag_activate(pcap_t* p)
device = newDev; device = newDev;
if (pd->dag_stream%2) { 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"); pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "dag_parse_name: tx (even numbered) streams not supported for capture");
goto fail; goto fail;
} }
/* setup device parameters */ /* setup device parameters */
if((pd->dag_ref = dag_config_init((char *)device)) == NULL) { 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, pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
errno, "dag_config_init %s", device); errno, "dag_config_init %s", device);
goto fail; goto fail;
} }
if((p->fd = dag_config_get_card_fd(pd->dag_ref)) < 0) { 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, pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
errno, "dag_config_get_card_fd %s", device); errno, "dag_config_get_card_fd %s", device);
goto fail; goto failclose;
} }
/* Open requested stream. Can fail if already locked or on error */ /* Open requested stream. Can fail if already locked or on error */
if (dag_attach_stream64(p->fd, pd->dag_stream, 0, 0) < 0) { 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, pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
errno, "dag_attach_stream"); errno, "dag_attach_stream");
goto failclose; goto failclose;
@ -809,6 +831,7 @@ static int dag_activate(pcap_t* p)
*/ */
if (dag_get_stream_poll64(p->fd, pd->dag_stream, if (dag_get_stream_poll64(p->fd, pd->dag_stream,
&mindata, &maxwait, &poll) < 0) { &mindata, &maxwait, &poll) < 0) {
ret = PCAP_ERROR;
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
errno, "dag_get_stream_poll"); errno, "dag_get_stream_poll");
goto faildetach; goto faildetach;
@ -853,6 +876,7 @@ static int dag_activate(pcap_t* p)
if (dag_set_stream_poll64(p->fd, pd->dag_stream, if (dag_set_stream_poll64(p->fd, pd->dag_stream,
mindata, &maxwait, &poll) < 0) { mindata, &maxwait, &poll) < 0) {
ret = PCAP_ERROR;
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
errno, "dag_set_stream_poll"); errno, "dag_set_stream_poll");
goto faildetach; goto faildetach;
@ -875,6 +899,7 @@ static int dag_activate(pcap_t* p)
#endif #endif
if(dag_start_stream(p->fd, pd->dag_stream) < 0) { if(dag_start_stream(p->fd, pd->dag_stream) < 0) {
ret = PCAP_ERROR;
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
errno, "dag_start_stream %s", device); errno, "dag_start_stream %s", device);
goto faildetach; goto faildetach;
@ -910,6 +935,7 @@ static int dag_activate(pcap_t* p)
if ((n = atoi(s)) == 0 || n == 16 || n == 32) { if ((n = atoi(s)) == 0 || n == 16 || n == 32) {
pd->dag_fcs_bits = n; pd->dag_fcs_bits = n;
} else { } else {
ret = PCAP_ERROR;
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"pcap_activate %s: bad ERF_FCS_BITS value (%d) in environment", device, n); "pcap_activate %s: bad ERF_FCS_BITS value (%d) in environment", device, n);
goto failstop; goto failstop;
@ -932,12 +958,15 @@ static int dag_activate(pcap_t* p)
pd->dag_timeout = p->opt.timeout; pd->dag_timeout = p->opt.timeout;
p->linktype = -1; p->linktype = -1;
if (dag_get_datalink(p) < 0) if (dag_get_datalink(p) < 0) {
ret = PCAP_ERROR;
goto failstop; goto failstop;
}
p->bufsize = 0; p->bufsize = 0;
if (new_pcap_dag(p) < 0) { if (new_pcap_dag(p) < 0) {
ret = PCAP_ERROR;
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
errno, "new_pcap_dag %s", device); errno, "new_pcap_dag %s", device);
goto failstop; goto failstop;
@ -977,6 +1006,14 @@ static int dag_activate(pcap_t* p)
failclose: failclose:
dag_config_dispose(pd->dag_ref); 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); delete_pcap_dag(p);
fail: fail:
@ -985,7 +1022,7 @@ static int dag_activate(pcap_t* p)
free((char *)newDev); free((char *)newDev);
} }
return PCAP_ERROR; return ret;
} }
pcap_t *dag_create(const char *device, char *ebuf, int *is_ours) 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); rxstreams = dag_rx_get_stream_count(dagfd);
for(stream=0;stream<DAG_STREAM_MAX;stream+=2) { 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); dag_detach_stream(dagfd, stream);
pcap_snprintf(name, 10, "dag%d:%d", c, stream); pcap_snprintf(name, 10, "dag%d:%d", c, stream);

View File

@ -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 should check "p->linktype" and reject the send request if
* it's anything other than DLT_EN10MB. * 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); PCAP_ERRBUF_SIZE);
ret = -1; ret = -1;
#endif /* raw mode */ #endif /* raw mode */
@ -363,9 +363,9 @@ open_dlpi_device(const char *name, u_int *ppa, char *errbuf)
*/ */
cp = strrchr(name, '/'); cp = strrchr(name, '/');
if (cp == NULL) if (cp == NULL)
strlcpy(dname, name, sizeof(dname)); pcap_strlcpy(dname, name, sizeof(dname));
else 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; * 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. * device name.
*/ */
if (*name == '/') if (*name == '/')
strlcpy(dname, name, sizeof(dname)); pcap_strlcpy(dname, name, sizeof(dname));
else else
pcap_snprintf(dname, sizeof(dname), "%s/%s", PCAP_DEV_PREFIX, pcap_snprintf(dname, sizeof(dname), "%s/%s", PCAP_DEV_PREFIX,
name); 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 * Make a copy of the device pathname, and then remove the unit
* number from the device pathname. * number from the device pathname.
*/ */
strlcpy(dname2, dname, sizeof(dname)); pcap_strlcpy(dname2, dname, sizeof(dname));
*cp = '\0'; *cp = '\0';
/* Try device without unit number */ /* Try device without unit number */
@ -968,7 +968,7 @@ dl_dohpuxbind(int fd, char *ebuf)
*ebuf = '\0'; *ebuf = '\0';
hpsap++; hpsap++;
if (hpsap > 100) { if (hpsap > 100) {
strlcpy(ebuf, pcap_strlcpy(ebuf,
"All SAPs from 22 through 100 are in use", "All SAPs from 22 through 100 are in use",
PCAP_ERRBUF_SIZE); PCAP_ERRBUF_SIZE);
return (-1); return (-1);
@ -1547,7 +1547,7 @@ get_release(char *buf, size_t bufsize, bpf_u_int32 *majorp,
*minorp = 0; *minorp = 0;
*microp = 0; *microp = 0;
if (sysinfo(SI_RELEASE, buf, bufsize) < 0) { if (sysinfo(SI_RELEASE, buf, bufsize) < 0) {
strlcpy(buf, "?", bufsize); pcap_strlcpy(buf, "?", bufsize);
return; return;
} }
cp = buf; cp = buf;

View File

@ -413,14 +413,14 @@ int pcap_stats_ex (pcap_t *p, struct pcap_stat_ex *se)
if (!dev || !dev->get_stats) 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); PCAP_ERRBUF_SIZE);
return (-1); return (-1);
} }
if (!strnicmp(dev->name,"pkt",3)) 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); PCAP_ERRBUF_SIZE);
return (-1); return (-1);
} }

View File

@ -18,7 +18,7 @@
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF .\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\" .\"
.TH PCAP-FILTER @MAN_MISC_INFO@ "3 August 2015" .TH PCAP-FILTER @MAN_MISC_INFO@ "5 November 2017"
.SH NAME .SH NAME
pcap-filter \- packet filter syntax pcap-filter \- packet filter syntax
.br .br
@ -29,11 +29,11 @@ pcap-filter \- packet filter syntax
is used to compile a string into a filter program. is used to compile a string into a filter program.
The resulting filter program can then be applied to The resulting filter program can then be applied to
some stream of packets to determine which packets will be supplied to some stream of packets to determine which packets will be supplied to
.BR pcap_loop() , .BR pcap_loop(3PCAP) ,
.BR pcap_dispatch() , .BR pcap_dispatch(3PCAP) ,
.BR pcap_next() , .BR pcap_next(3PCAP) ,
or or
.BR pcap_next_ex() . .BR pcap_next_ex(3PCAP) .
.LP .LP
The \fIfilter expression\fP consists of one or more The \fIfilter expression\fP consists of one or more
.IR primitives . .IR primitives .
@ -86,12 +86,6 @@ The
and and
.B addr4 .B addr4
qualifiers are only valid for IEEE 802.11 Wireless LAN link layers. 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 .IP \fIproto\fP
.I proto .I proto
qualifiers restrict the match to a particular protocol. 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); FDDI packets (no check is done for LLC frames);
.IP .IP
LLC-encapsulated ATM packets, for SunATM on Solaris. LLC-encapsulated ATM packets, for SunATM on Solaris.
.IP
.IP "\fBllc\fP \Fitype\fR" .IP "\fBllc\fP \Fitype\fR"
True if the packet has an 802.2 LLC header and has the specified True if the packet has an 802.2 LLC header and has the specified
.IR type . .IR type .
@ -514,6 +506,16 @@ Exchange Identification (XID) U PDUs
\fBfrmr\fR \fBfrmr\fR
Frame Reject (FRMR) U PDUs Frame Reject (FRMR) U PDUs
.RE .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" .IP "\fBifname \fIinterface\fR"
True if the packet was logged as coming from the specified interface (applies True if the packet was logged as coming from the specified interface (applies
only to packets logged by OpenBSD's or FreeBSD's only to packets logged by OpenBSD's or FreeBSD's
@ -567,7 +569,7 @@ are:
and and
.B block .B block
and, with later versions of and, with later versions of
.BR pf (4)), .BR pf (4),
.BR nat , .BR nat ,
.BR rdr , .BR rdr ,
.B binat .B binat

View File

@ -86,7 +86,12 @@ extern "C" {
* 2) small enough not to cause attempts to allocate huge amounts of * 2) small enough not to cause attempts to allocate huge amounts of
* memory; some applications might use the snapshot length in a * memory; some applications might use the snapshot length in a
* savefile header to control the size of the buffer they allocate, * 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. * 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 * "pcap_open_offline_common()" allocates and fills in a pcap_t, for use
* by pcap_open_offline routines. * 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 * "sf_cleanup()" closes the file handle associated with a pcap_t, if
* appropriate, and frees all data common to all modules for handling * appropriate, and frees all data common to all modules for handling
* savefile types. * savefile types.
*/ */
pcap_t *pcap_open_offline_common(char *ebuf, size_t size); 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); 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 * Internal interfaces for both "pcap_create()" and routines that
* open savefiles. * open savefiles.
@ -488,10 +518,6 @@ void sf_cleanup(pcap_t *p);
*/ */
void pcap_oneshot(u_char *, const struct pcap_pkthdr *, const u_char *); void pcap_oneshot(u_char *, const struct pcap_pkthdr *, const u_char *);
#ifdef _WIN32
void pcap_win32_err_to_str(DWORD, char *);
#endif
int install_bpf_program(pcap_t *, struct bpf_program *); int install_bpf_program(pcap_t *, struct bpf_program *);
int pcap_strcasecmp(const char *, const char *); int pcap_strcasecmp(const char *, const char *);

View File

@ -80,7 +80,7 @@ list_interfaces(const char *linkname, void *arg)
lwp->lw_err = ENOMEM; lwp->lw_err = ENOMEM;
return (B_TRUE); 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) { if (lwp->lw_list == NULL) {
lwp->lw_list = entry; lwp->lw_list = entry;

View File

@ -43,6 +43,6 @@ The names for those values begin with
.BR LINKTYPE_ . .BR LINKTYPE_ .
.PP .PP
The link-layer header types supported by libpcap are described at The link-layer header types supported by libpcap are described at
http://www.tcpdump.org/linktypes.html. https://www.tcpdump.org/linktypes.html.
.SH SEE ALSO .SH SEE ALSO
pcap_datalink(3PCAP) pcap(3PCAP)

File diff suppressed because it is too large Load Diff

View File

@ -301,7 +301,8 @@ netfilter_stats_linux(pcap_t *handle, struct pcap_stat *stats)
static int static int
netfilter_inject_linux(pcap_t *handle, const void *buf _U_, size_t size _U_) netfilter_inject_linux(pcap_t *handle, const void *buf _U_, 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); 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) 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)); char buf[1024] __attribute__ ((aligned));
memset(buf, 0, sizeof(buf));
struct nlmsghdr *nlh = (struct nlmsghdr *) buf; struct nlmsghdr *nlh = (struct nlmsghdr *) buf;
struct nfgenmsg *nfg = (struct nfgenmsg *) (buf + sizeof(struct nlmsghdr)); struct nfgenmsg *nfg = (struct nfgenmsg *) (buf + sizeof(struct nlmsghdr));

View File

@ -67,7 +67,7 @@ pcap_netmap_stats(pcap_t *p, struct pcap_stat *ps)
{ {
struct pcap_netmap *pn = p->priv; 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_drop = 0;
ps->ps_ifdrop = 0; ps->ps_ifdrop = 0;
return 0; return 0;

View File

@ -35,6 +35,8 @@
#include <config.h> #include <config.h>
#endif #endif
#include "ftmacros.h"
/* /*
* sockutils.h may include <crtdbg.h> on Windows, and pcap-int.h will * sockutils.h may include <crtdbg.h> on Windows, and pcap-int.h will
* include portability.h, and portability.h, on Windows, expects that * include portability.h, and portability.h, on Windows, expects that
@ -54,11 +56,14 @@
/* String identifier to be used in the pcap_findalldevs_ex() */ /* String identifier to be used in the pcap_findalldevs_ex() */
#define PCAP_TEXT_SOURCE_FILE "File" #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() */ /* String identifier to be used in the pcap_findalldevs_ex() */
#define PCAP_TEXT_SOURCE_ADAPTER "Network adapter" #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() */ /* 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 "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; int type;
char name[PCAP_BUF_SIZE], path[PCAP_BUF_SIZE], filename[PCAP_BUF_SIZE]; char name[PCAP_BUF_SIZE], path[PCAP_BUF_SIZE], filename[PCAP_BUF_SIZE];
size_t pathlen;
size_t stringlen;
pcap_t *fp; pcap_t *fp;
char tmpstring[PCAP_BUF_SIZE + 1]; /* Needed to convert names and descriptions from 'old' syntax to the 'new' one */ 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 */ 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) if (*alldevs == NULL)
{ {
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, 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."); " on the local machine.");
return -1; return -1;
} }
@ -123,6 +130,8 @@ int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **all
dev = *alldevs; dev = *alldevs;
while (dev) while (dev)
{ {
char *localdesc, *desc;
/* Create the new device identifier */ /* Create the new device identifier */
if (pcap_createsrcstr(tmpstring, PCAP_SRC_IFLOCAL, NULL, NULL, dev->name, errbuf) == -1) if (pcap_createsrcstr(tmpstring, PCAP_SRC_IFLOCAL, NULL, NULL, dev->name, errbuf) == -1)
return -1; return -1;
@ -141,20 +150,16 @@ int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **all
return -1; return -1;
} }
/* Create the new device description */ /*
* Create the description.
*/
if ((dev->description == NULL) || (dev->description[0] == 0)) if ((dev->description == NULL) || (dev->description[0] == 0))
pcap_snprintf(tmpstring, sizeof(tmpstring) - 1, "%s '%s' %s", PCAP_TEXT_SOURCE_ADAPTER, localdesc = dev->name;
dev->name, PCAP_TEXT_SOURCE_ON_LOCAL_HOST);
else else
pcap_snprintf(tmpstring, sizeof(tmpstring) - 1, "%s '%s' %s", PCAP_TEXT_SOURCE_ADAPTER, localdesc = dev->description;
dev->description, PCAP_TEXT_SOURCE_ON_LOCAL_HOST); if (pcap_asprintf(&desc, "%s '%s' %s",
PCAP_TEXT_SOURCE_ADAPTER, localdesc,
/* Delete the old pointer */ PCAP_TEXT_SOURCE_ON_LOCAL_HOST) == -1)
free(dev->description);
/* Make a copy of the description */
dev->description = strdup(tmpstring);
if (dev->description == NULL)
{ {
pcap_fmt_errmsg_for_errno(errbuf, pcap_fmt_errmsg_for_errno(errbuf,
PCAP_ERRBUF_SIZE, errno, PCAP_ERRBUF_SIZE, errno,
@ -163,6 +168,10 @@ int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **all
return -1; return -1;
} }
/* Now overwrite the description */
free(dev->description);
dev->description = desc;
dev = dev->next; 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: case PCAP_SRC_FILE:
{ {
size_t stringlen;
#ifdef _WIN32 #ifdef _WIN32
WIN32_FIND_DATA filedata; WIN32_FIND_DATA filedata;
HANDLE filehandle; 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 */ /* Save the path for future reference */
pcap_snprintf(path, sizeof(path), "%s", name); pcap_snprintf(path, sizeof(path), "%s", name);
pathlen = strlen(path);
#ifdef _WIN32 #ifdef _WIN32
/* To perform directory listing, Win32 must have an 'asterisk' as ending char */ /* 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. */ /* Add all files we find to the list. */
do do
{ {
#ifdef _WIN32 #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); pcap_snprintf(filename, sizeof(filename), "%s%s", path, filedata.cFileName);
#else #else
if (pathlen + strlen(filedata->d_name) >= sizeof(filename))
continue;
pcap_snprintf(filename, sizeof(filename), "%s%s", path, filedata->d_name); pcap_snprintf(filename, sizeof(filename), "%s%s", path, filedata->d_name);
#endif #endif
@ -287,9 +300,7 @@ int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **all
return -1; return -1;
} }
stringlen = strlen(tmpstring); dev->name = strdup(tmpstring);
dev->name = (char *)malloc(stringlen + 1);
if (dev->name == NULL) if (dev->name == NULL)
{ {
pcap_fmt_errmsg_for_errno(errbuf, 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; return -1;
} }
strlcpy(dev->name, tmpstring, stringlen); /*
* Create the description.
dev->name[stringlen] = 0; */
if (pcap_asprintf(&dev->description,
/* Create the description */ "%s '%s' %s", PCAP_TEXT_SOURCE_FILE,
pcap_snprintf(tmpstring, sizeof(tmpstring) - 1, "%s '%s' %s", PCAP_TEXT_SOURCE_FILE, filename, PCAP_TEXT_SOURCE_ON_LOCAL_HOST) == -1)
filename, PCAP_TEXT_SOURCE_ON_LOCAL_HOST);
stringlen = strlen(tmpstring);
dev->description = (char *)malloc(stringlen + 1);
if (dev->description == NULL)
{ {
pcap_fmt_errmsg_for_errno(errbuf, pcap_fmt_errmsg_for_errno(errbuf,
PCAP_ERRBUF_SIZE, errno, PCAP_ERRBUF_SIZE, errno,
@ -320,9 +324,6 @@ int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **all
return -1; return -1;
} }
/* Copy the new device description into the correct memory location */
strlcpy(dev->description, tmpstring, stringlen + 1);
pcap_close(fp); 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); return pcap_findalldevs_ex_remote(source, auth, alldevs, errbuf);
default: default:
strlcpy(errbuf, "Source type not supported", PCAP_ERRBUF_SIZE); pcap_strlcpy(errbuf, "Source type not supported", PCAP_ERRBUF_SIZE);
return -1; return -1;
} }
} }
@ -357,6 +358,16 @@ pcap_t *pcap_open(const char *source, int snaplen, int flags, int read_timeout,
pcap_t *fp; pcap_t *fp;
int status; 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) if (strlen(source) > PCAP_BUF_SIZE)
{ {
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "The source string is too long. Cannot handle it correctly."); 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); return pcap_open_rpcap(source, snaplen, flags, read_timeout, auth, errbuf);
default: default:
strlcpy(errbuf, "Source type not supported", PCAP_ERRBUF_SIZE); pcap_strlcpy(errbuf, "Source type not supported", PCAP_ERRBUF_SIZE);
return NULL; return NULL;
} }

View File

@ -70,7 +70,7 @@ static int pcap_setnonblock_npf(pcap_t *, int);
#define SWAPS(_X) ((_X & 0xff) << 8) | (_X >> 8) #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 { struct pcap_win {
ADAPTER *adapter; /* the packet32 ADAPTER for the device */ 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 * or NDIS_STATUS_NOT_RECOGNIZED if the OID request isn't
* supported by the OS or the driver, but that doesn't seem * supported by the OS or the driver, but that doesn't seem
* to make it to the caller of PacketRequest() in a * to make it to the caller of PacketRequest() in a
* reiable fashion. * reliable fashion.
*/ */
#define NDIS_STATUS_INVALID_OID 0xc0010017 #define NDIS_STATUS_INVALID_OID 0xc0010017
#define NDIS_STATUS_NOT_SUPPORTED 0xc00000bb /* STATUS_NOT_SUPPORTED */ #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->Oid = oid;
oid_data_arg->Length = (ULONG)(*lenp); /* XXX - check for ridiculously large value? */ oid_data_arg->Length = (ULONG)(*lenp); /* XXX - check for ridiculously large value? */
if (!PacketRequest(adapter, FALSE, oid_data_arg)) { if (!PacketRequest(adapter, FALSE, oid_data_arg)) {
char errmsgbuf[PCAP_ERRBUF_SIZE+1]; pcap_fmt_errmsg_for_win32_err(errbuf, PCAP_ERRBUF_SIZE,
GetLastError(), "Error calling PacketRequest");
pcap_win32_err_to_str(GetLastError(), errmsgbuf);
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"Error calling PacketRequest: %s", errmsgbuf);
free(oid_data_arg); free(oid_data_arg);
return (-1); return (-1);
} }
@ -193,7 +190,6 @@ pcap_stats_npf(pcap_t *p, struct pcap_stat *ps)
{ {
struct pcap_win *pw = p->priv; struct pcap_win *pw = p->priv;
struct bpf_stat bstats; struct bpf_stat bstats;
char errbuf[PCAP_ERRBUF_SIZE+1];
/* /*
* Try to get statistics. * Try to get statistics.
@ -209,9 +205,8 @@ pcap_stats_npf(pcap_t *p, struct pcap_stat *ps)
* to us. * to us.
*/ */
if (!PacketGetStats(pw->adapter, &bstats)) { if (!PacketGetStats(pw->adapter, &bstats)) {
pcap_win32_err_to_str(GetLastError(), errbuf); pcap_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE,
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, GetLastError(), "PacketGetStats error");
"PacketGetStats error: %s", errbuf);
return (-1); return (-1);
} }
ps->ps_recv = bstats.bs_recv; 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 pcap_win *pw = p->priv;
struct bpf_stat bstats; struct bpf_stat bstats;
char errbuf[PCAP_ERRBUF_SIZE+1];
*pcap_stat_size = sizeof (p->stat); *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.) * same layout, but let's not cheat.)
*/ */
if (!PacketGetStatsEx(pw->adapter, &bstats)) { if (!PacketGetStatsEx(pw->adapter, &bstats)) {
pcap_win32_err_to_str(GetLastError(), errbuf); pcap_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE,
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, GetLastError(), "PacketGetStatsEx error");
"PacketGetStatsEx error: %s", errbuf);
return (NULL); return (NULL);
} }
p->stat.ps_recv = bstats.bs_recv; 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; struct pcap_win *pw = p->priv;
PACKET_OID_DATA *oid_data_arg; PACKET_OID_DATA *oid_data_arg;
char errbuf[PCAP_ERRBUF_SIZE+1];
/* /*
* Allocate a PACKET_OID_DATA structure to hand to PacketRequest(). * 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? */ oid_data_arg->Length = (ULONG)(*lenp); /* XXX - check for ridiculously large value? */
memcpy(oid_data_arg->Data, data, *lenp); memcpy(oid_data_arg->Data, data, *lenp);
if (!PacketRequest(pw->adapter, TRUE, oid_data_arg)) { if (!PacketRequest(pw->adapter, TRUE, oid_data_arg)) {
pcap_win32_err_to_str(GetLastError(), errbuf); pcap_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE,
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, GetLastError(), "Error calling PacketRequest");
"Error calling PacketRequest: %s", errbuf);
free(oid_data_arg); free(oid_data_arg);
return (PCAP_ERROR); 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; struct pcap_win *pw = p->priv;
u_int res; u_int res;
char errbuf[PCAP_ERRBUF_SIZE+1];
if (pw->adapter==NULL) { if (pw->adapter==NULL) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 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); (BOOLEAN)sync);
if(res != queue->len){ if(res != queue->len){
pcap_win32_err_to_str(GetLastError(), errbuf); pcap_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE,
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, GetLastError(), "Error opening adapter");
"Error opening adapter: %s", errbuf);
} }
return (res); 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); PacketInitPacket(&Packet, (BYTE *)p->buffer, p->bufsize);
if (!PacketReceivePacket(pw->adapter, &Packet, TRUE)) { if (!PacketReceivePacket(pw->adapter, &Packet, TRUE)) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read error: PacketReceivePacket failed"); /*
* 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); return (PCAP_ERROR);
} }
@ -873,7 +889,7 @@ pcap_activate_npf(pcap_t *p)
struct pcap_win *pw = p->priv; struct pcap_win *pw = p->priv;
NetType type; NetType type;
int res; int res;
char errbuf[PCAP_ERRBUF_SIZE+1]; int status = 0;
if (p->opt.rfmon) { if (p->opt.rfmon) {
/* /*
@ -912,23 +928,35 @@ pcap_activate_npf(pcap_t *p)
if (pw->adapter == NULL) if (pw->adapter == NULL)
{ {
/* Adapter detected but we are not able to open it. Return failure. */ DWORD errcode = GetLastError();
pcap_win32_err_to_str(GetLastError(), errbuf);
/*
* 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) if (pw->rfmon_selfstart)
{ {
PacketSetMonitorMode(p->opt.device, 0); PacketSetMonitorMode(p->opt.device, 0);
} }
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"Error opening adapter: %s", errbuf);
return (PCAP_ERROR); return (PCAP_ERROR);
} }
}
/*get network type*/ /*get network type*/
if(PacketGetNetType (pw->adapter,&type) == FALSE) if(PacketGetNetType (pw->adapter,&type) == FALSE)
{ {
pcap_win32_err_to_str(GetLastError(), errbuf); pcap_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE,
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, GetLastError(), "Cannot determine the network type");
"Cannot determine the network type: %s", errbuf);
goto bad; goto bad;
} }
@ -1006,8 +1034,29 @@ pcap_activate_npf(pcap_t *p)
p->linktype = DLT_PPI; p->linktype = DLT_PPI;
break; break;
#ifdef NdisMediumWirelessWan
case NdisMediumWirelessWan:
p->linktype = DLT_RAW;
break;
#endif
default: 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; break;
} }
@ -1085,10 +1134,9 @@ pcap_activate_npf(pcap_t *p)
/* tell the driver to copy the buffer as soon as data arrives */ /* tell the driver to copy the buffer as soon as data arrives */
if(PacketSetMinToCopy(pw->adapter,0)==FALSE) if(PacketSetMinToCopy(pw->adapter,0)==FALSE)
{ {
pcap_win32_err_to_str(GetLastError(), errbuf); pcap_fmt_errmsg_for_win32_err(p->errbuf,
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, PCAP_ERRBUF_SIZE, GetLastError(),
"Error calling PacketSetMinToCopy: %s", "Error calling PacketSetMinToCopy");
errbuf);
goto bad; 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 */ /* tell the driver to copy the buffer only if it contains at least 16K */
if(PacketSetMinToCopy(pw->adapter,16000)==FALSE) if(PacketSetMinToCopy(pw->adapter,16000)==FALSE)
{ {
pcap_win32_err_to_str(GetLastError(), errbuf); pcap_fmt_errmsg_for_win32_err(p->errbuf,
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, PCAP_ERRBUF_SIZE, GetLastError(),
"Error calling PacketSetMinToCopy: %s", "Error calling PacketSetMinToCopy");
errbuf);
goto bad; goto bad;
} }
} }
@ -1221,7 +1268,7 @@ pcap_activate_npf(pcap_t *p)
*/ */
p->handle = pw->adapter->hFile; p->handle = pw->adapter->hFile;
return (0); return (status);
bad: bad:
pcap_cleanup_npf(p); pcap_cleanup_npf(p);
return (PCAP_ERROR); return (PCAP_ERROR);
@ -1316,7 +1363,7 @@ pcap_setfilter_win32_dag(pcap_t *p, struct bpf_program *fp) {
if(!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); return (-1);
} }
@ -1345,7 +1392,6 @@ pcap_setnonblock_npf(pcap_t *p, int nonblock)
{ {
struct pcap_win *pw = p->priv; struct pcap_win *pw = p->priv;
int newtimeout; int newtimeout;
char win_errbuf[PCAP_ERRBUF_SIZE+1];
if (nonblock) { if (nonblock) {
/* /*
@ -1365,9 +1411,8 @@ pcap_setnonblock_npf(pcap_t *p, int nonblock)
newtimeout = p->opt.timeout; newtimeout = p->opt.timeout;
} }
if (!PacketSetReadTimeout(pw->adapter, newtimeout)) { if (!PacketSetReadTimeout(pw->adapter, newtimeout)) {
pcap_win32_err_to_str(GetLastError(), win_errbuf); pcap_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE,
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, GetLastError(), "PacketSetReadTimeout");
"PacketSetReadTimeout: %s", win_errbuf);
return (-1); return (-1);
} }
pw->nonblock = (newtimeout == -1); pw->nonblock = (newtimeout == -1);
@ -1684,7 +1729,6 @@ pcap_platform_finddevs(pcap_if_list_t *devlistp, char *errbuf)
char *AdaptersName; char *AdaptersName;
ULONG NameLength; ULONG NameLength;
char *name; char *name;
char our_errbuf[PCAP_ERRBUF_SIZE+1];
/* /*
* Find out how big a buffer we need. * 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) if (last_error != ERROR_INSUFFICIENT_BUFFER)
{ {
pcap_win32_err_to_str(last_error, our_errbuf); pcap_fmt_errmsg_for_win32_err(errbuf, PCAP_ERRBUF_SIZE,
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, last_error, "PacketGetAdapterNames");
"PacketGetAdapterNames: %s", our_errbuf);
return (-1); return (-1);
} }
} }
@ -1727,9 +1770,8 @@ pcap_platform_finddevs(pcap_if_list_t *devlistp, char *errbuf)
} }
if (!PacketGetAdapterNames(AdaptersName, &NameLength)) { if (!PacketGetAdapterNames(AdaptersName, &NameLength)) {
pcap_win32_err_to_str(GetLastError(), our_errbuf); pcap_fmt_errmsg_for_win32_err(errbuf, PCAP_ERRBUF_SIZE,
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "PacketGetAdapterNames: %s", GetLastError(), "PacketGetAdapterNames");
our_errbuf);
free(AdaptersName); free(AdaptersName);
return (-1); return (-1);
} }
@ -1818,7 +1860,6 @@ pcap_lookupdev(char *errbuf)
{ {
DWORD dwVersion; DWORD dwVersion;
DWORD dwWindowsMajorVersion; DWORD dwWindowsMajorVersion;
char our_errbuf[PCAP_ERRBUF_SIZE+1];
#pragma warning (push) #pragma warning (push)
#pragma warning (disable: 4996) /* disable MSVC's GetVersion() deprecated warning here */ #pragma warning (disable: 4996) /* disable MSVC's GetVersion() deprecated warning here */
@ -1860,9 +1901,8 @@ pcap_lookupdev(char *errbuf)
if ( !PacketGetAdapterNames((PTSTR)TAdaptersName,&NameLength) ) if ( !PacketGetAdapterNames((PTSTR)TAdaptersName,&NameLength) )
{ {
pcap_win32_err_to_str(GetLastError(), our_errbuf); pcap_fmt_errmsg_for_win32_err(errbuf, PCAP_ERRBUF_SIZE,
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, GetLastError(), "PacketGetAdapterNames");
"PacketGetAdapterNames: %s", our_errbuf);
free(TAdaptersName); free(TAdaptersName);
return NULL; return NULL;
} }
@ -2000,60 +2040,49 @@ static const char *pcap_lib_version_string;
* tree. Include version.h from that source tree to get the WinPcap/Npcap * tree. Include version.h from that source tree to get the WinPcap/Npcap
* version. * version.
* *
* XXX - it'd be nice if we could somehow generate the WinPcap version number * XXX - it'd be nice if we could somehow generate the WinPcap/Npcap version
* when building WinPcap. (It'd be nice to do so for the packet.dll version * number when building as part of WinPcap/Npcap. (It'd be nice to do so
* number as well.) * for the packet.dll version number as well.)
*/ */
#include "../../version.h" #include "../../version.h"
static const char pcap_version_string[] = static const char pcap_version_string[] =
WINPCAP_PRODUCT_NAME " version " WINPCAP_VER_STRING ", based on " 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 * const char *
pcap_lib_version(void) 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) { if (pcap_lib_version_string == NULL) {
/* /*
* Generate the version string. * Generate the version string.
*/ */
packet_version_string = PacketGetVersion(); char *packet_version_string = PacketGetVersion();
if (strcmp(WINPCAP_VER_STRING, packet_version_string) == 0) { if (strcmp(WINPCAP_VER_STRING, packet_version_string) == 0) {
/* /*
* WinPcap version string and packet.dll version * WinPcap/Npcap version string and packet.dll version
* string are the same; just report the WinPcap * string are the same; just report the WinPcap/Npcap
* version. * version.
*/ */
pcap_lib_version_string = pcap_version_string; pcap_lib_version_string = pcap_version_string;
} else { } else {
/* /*
* WinPcap version string and packet.dll version * WinPcap/Npcap version string and packet.dll version
* string are different; that shouldn't be the * string are different; that shouldn't be the
* case (the two libraries should come from 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. * versions.
*
* The -2 is for the %s in the format string,
* which will be replaced by packet_version_string.
*/ */
full_pcap_version_string_len = char *full_pcap_version_string;
(sizeof pcap_version_string_packet_dll_fmt - 2) +
strlen(packet_version_string); if (pcap_asprintf(&full_pcap_version_string,
full_pcap_version_string = malloc(full_pcap_version_string_len); WINPCAP_PRODUCT_NAME " version " WINPCAP_VER_STRING " (packet.dll version %s), based on " PCAP_VERSION_STRING,
if (full_pcap_version_string == NULL) packet_version_string) != -1) {
return (NULL); /* Success */
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; pcap_lib_version_string = full_pcap_version_string;
} }
}
}
return (pcap_lib_version_string); return (pcap_lib_version_string);
} }
@ -2063,36 +2092,23 @@ pcap_lib_version(void)
* libpcap being built for Windows, not as part of a WinPcap/Npcap source * libpcap being built for Windows, not as part of a WinPcap/Npcap source
* tree. * tree.
*/ */
static const char pcap_version_string_packet_dll_fmt[] =
PCAP_VERSION_STRING " (packet.dll version %s)";
const char * const char *
pcap_lib_version(void) 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) { if (pcap_lib_version_string == NULL) {
/* /*
* Generate the version string. Report the packet.dll * Generate the version string. Report the packet.dll
* version. * version.
*
* The -2 is for the %s in the format string, which will
* be replaced by packet_version_string.
*/ */
packet_version_string = PacketGetVersion(); char *full_pcap_version_string;
full_pcap_version_string_len =
(sizeof pcap_version_string_packet_dll_fmt - 2) + if (pcap_asprintf(&full_pcap_version_string,
strlen(packet_version_string); PCAP_VERSION_STRING " (packet.dll version %s)",
full_pcap_version_string = malloc(full_pcap_version_string_len); PacketGetVersion()) != -1) {
if (full_pcap_version_string == NULL) /* Success */
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; pcap_lib_version_string = full_pcap_version_string;
} }
}
return (pcap_lib_version_string); return (pcap_lib_version_string);
} }
#endif /* HAVE_VERSION_H */ #endif /* HAVE_VERSION_H */

View File

@ -32,12 +32,12 @@ static char nosup[] = "live packet capture not supported on this system";
pcap_t * pcap_t *
pcap_create_interface(const char *device _U_, char *ebuf) 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); return (NULL);
} }
int 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. * 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_, pcap_lookupnet(const char *device _U_, bpf_u_int32 *netp _U_,
bpf_u_int32 *maskp _U_, char *errbuf) bpf_u_int32 *maskp _U_, char *errbuf)
{ {
(void)strlcpy(errbuf, nosup, PCAP_ERRBUF_SIZE); (void)pcap_strlcpy(errbuf, nosup, PCAP_ERRBUF_SIZE);
return (-1); return (-1);
} }
#endif #endif

View File

@ -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_setfilter_rpcap(pcap_t *fp, struct bpf_program *prog);
static int pcap_setsampling_remote(pcap_t *fp); static int pcap_setsampling_remote(pcap_t *fp);
static int pcap_startcapture_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_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_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); 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; return 0;
} }
#endif #endif
sock_geterror("select(): ", p->errbuf, PCAP_ERRBUF_SIZE); sock_geterror("select()", p->errbuf, PCAP_ERRBUF_SIZE);
return -1; return -1;
} }
@ -763,6 +762,8 @@ static void pcap_cleanup_rpcap(pcap_t *fp)
pr->currentfilter = NULL; pr->currentfilter = NULL;
} }
pcap_cleanup_live_common(fp);
/* To avoid inconsistencies in the number of sock_init() */ /* To avoid inconsistencies in the number of sock_init() */
sock_cleanup(); 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. */ /* Discard the rest of the message. */
if (rpcap_discard(pr->rmt_sockctrl, plen, p->errbuf) == -1) if (rpcap_discard(pr->rmt_sockctrl, plen, p->errbuf) == -1)
goto error; goto error_nodiscard;
return ps; 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); (void)rpcap_discard(pr->rmt_sockctrl, plen, NULL);
error_nodiscard:
return NULL; return NULL;
} }
@ -1068,7 +1070,7 @@ static int pcap_startcapture_remote(pcap_t *fp)
saddrlen = sizeof(struct sockaddr_storage); saddrlen = sizeof(struct sockaddr_storage);
if (getpeername(pr->rmt_sockctrl, (struct sockaddr *) &saddr, &saddrlen) == -1) 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; goto error_nodiscard;
} }
ai_family = ((struct sockaddr_storage *) &saddr)->ss_family; 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, if (getnameinfo((struct sockaddr *) &saddr, saddrlen, host,
sizeof(host), NULL, 0, NI_NUMERICHOST)) 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; goto error_nodiscard;
} }
@ -1115,7 +1117,7 @@ static int pcap_startcapture_remote(pcap_t *fp)
saddrlen = sizeof(struct sockaddr_storage); saddrlen = sizeof(struct sockaddr_storage);
if (getsockname(sockdata, (struct sockaddr *) &saddr, &saddrlen) == -1) 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; goto error_nodiscard;
} }
@ -1123,7 +1125,7 @@ static int pcap_startcapture_remote(pcap_t *fp)
if (getnameinfo((struct sockaddr *) &saddr, saddrlen, NULL, if (getnameinfo((struct sockaddr *) &saddr, saddrlen, NULL,
0, portdata, sizeof(portdata), NI_NUMERICSERV)) 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; goto error_nodiscard;
} }
} }
@ -1233,7 +1235,7 @@ static int pcap_startcapture_remote(pcap_t *fp)
if (socktemp == INVALID_SOCKET) if (socktemp == INVALID_SOCKET)
{ {
sock_geterror("accept(): ", fp->errbuf, PCAP_ERRBUF_SIZE); sock_geterror("accept()", fp->errbuf, PCAP_ERRBUF_SIZE);
goto error; goto error;
} }
@ -1259,8 +1261,8 @@ static int pcap_startcapture_remote(pcap_t *fp)
res = getsockopt(sockdata, SOL_SOCKET, SO_RCVBUF, (char *)&sockbufsize, &itemp); res = getsockopt(sockdata, SOL_SOCKET, SO_RCVBUF, (char *)&sockbufsize, &itemp);
if (res == -1) if (res == -1)
{ {
sock_geterror("pcap_startcapture_remote()", fp->errbuf, PCAP_ERRBUF_SIZE); sock_geterror("pcap_startcapture_remote(): getsockopt() failed", fp->errbuf, PCAP_ERRBUF_SIZE);
SOCK_DEBUG_MESSAGE(fp->errbuf); goto error;
} }
/* /*
@ -1334,7 +1336,7 @@ static int pcap_startcapture_remote(pcap_t *fp)
/* Discard the rest of the message. */ /* Discard the rest of the message. */
if (rpcap_discard(pr->rmt_sockctrl, plen, fp->errbuf) == -1) 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 * 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 peeraddress[128];
char peerctrlport[128]; char peerctrlport[128];
char *newfilter; char *newfilter;
const int newstringsize = 1024;
size_t currentfiltersize;
/* Get the name/port of our peer */ /* Get the name/port of our peer */
saddrlen = sizeof(struct sockaddr_storage); saddrlen = sizeof(struct sockaddr_storage);
if (getpeername(pr->rmt_sockctrl, (struct sockaddr *) &saddr, &saddrlen) == -1) 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; return -1;
} }
if (getnameinfo((struct sockaddr *) &saddr, saddrlen, peeraddress, if (getnameinfo((struct sockaddr *) &saddr, saddrlen, peeraddress,
sizeof(peeraddress), peerctrlport, sizeof(peerctrlport), NI_NUMERICHOST | NI_NUMERICSERV)) 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; 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 */ /* Get the name/port of the current host */
if (getsockname(pr->rmt_sockctrl, (struct sockaddr *) &saddr, &saddrlen) == -1) 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; return -1;
} }
@ -1641,42 +1641,59 @@ static int pcap_createfilter_norpcappkt(pcap_t *fp, struct bpf_program *prog)
if (getnameinfo((struct sockaddr *) &saddr, saddrlen, myaddress, if (getnameinfo((struct sockaddr *) &saddr, saddrlen, myaddress,
sizeof(myaddress), myctrlport, sizeof(myctrlport), NI_NUMERICHOST | NI_NUMERICSERV)) 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; return -1;
} }
/* Let's now check the data port */ /* Let's now check the data port */
if (getsockname(pr->rmt_sockdata, (struct sockaddr *) &saddr, &saddrlen) == -1) 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; return -1;
} }
/* Get the local port the system picked up */ /* Get the local port the system picked up */
if (getnameinfo((struct sockaddr *) &saddr, saddrlen, NULL, 0, mydataport, sizeof(mydataport), NI_NUMERICSERV)) 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; return -1;
} }
currentfiltersize = pr->currentfilter ? strlen(pr->currentfilter) : 0; if (pr->currentfilter && pr->currentfilter[0] != '\0')
newfilter = (char *)malloc(currentfiltersize + newstringsize + 1);
if (currentfiltersize)
{ {
pcap_snprintf(newfilter, currentfiltersize + newstringsize, /*
* 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)", "(%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); 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 else
{ {
pcap_snprintf(newfilter, currentfiltersize + newstringsize, /*
* 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)", "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); 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 * This is only an hack to prevent the save_current_filter
@ -1784,16 +1801,25 @@ static int pcap_setsampling_remote(pcap_t *fp)
/* /*
* This function performs authentication and protocol version * This function performs authentication and protocol version
* negotiation. It first tries to authenticate with the maximum * negotiation. It is required in order to open the connection
* version we support and, if that fails with an "I don't support * with the other end party.
* that version" error from the server, and the version number in *
* the reply from the server is one we support, tries again with * It sends authentication parameters on the control socket and
* that version. * 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 sock: the socket we are currently using.
* *
* \param ver: pointer to variable holding protocol version number to send * \param ver: pointer to variable to which to set the protocol version
* and to set to the protocol version number in the reply. * number we selected.
* *
* \param auth: authentication parameters that have to be sent. * \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. * an error message string is returned in the 'errbuf' variable.
*/ */
static int rpcap_doauth(SOCKET sockctrl, uint8 *ver, struct pcap_rmtauth *auth, char *errbuf) 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 */ 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 */ int sendbufidx = 0; /* index which keeps the number of bytes currently buffered */
uint16 length; /* length of the payload of this message */ uint16 length; /* length of the payload of this message */
uint16 errcode;
struct rpcap_auth *rpauth; struct rpcap_auth *rpauth;
uint16 auth_type; uint16 auth_type;
struct rpcap_header header; struct rpcap_header header;
size_t str_length; size_t str_length;
uint32 plen;
struct rpcap_authreply authreply; /* authentication reply message */
uint8 ourvers;
if (auth) if (auth)
{ {
@ -1942,12 +1889,11 @@ static int rpcap_sendauth(SOCKET sock, uint8 *ver, struct pcap_rmtauth *auth, ch
length = sizeof(struct rpcap_auth); length = sizeof(struct rpcap_auth);
} }
if (sock_bufferize(NULL, sizeof(struct rpcap_header), NULL, if (sock_bufferize(NULL, sizeof(struct rpcap_header), NULL,
&sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errbuf, PCAP_ERRBUF_SIZE)) &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errbuf, PCAP_ERRBUF_SIZE))
return -1; return -1;
rpcap_createhdr((struct rpcap_header *) sendbuf, *ver, rpcap_createhdr((struct rpcap_header *) sendbuf, 0,
RPCAP_MSG_AUTH_REQ, 0, length); RPCAP_MSG_AUTH_REQ, 0, length);
rpauth = (struct rpcap_auth *) &sendbuf[sendbufidx]; 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); 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; return -1;
/* Receive the reply */ /* Receive and process the reply message header */
if (rpcap_recv_msg_header(sock, &header, errbuf) == -1) if (rpcap_process_msg_header(sockctrl, 0, RPCAP_MSG_AUTH_REQ,
&header, errbuf) == -1)
return -1; return -1;
if (rpcap_check_msg_type(sock, RPCAP_MSG_AUTH_REQ, &header,
&errcode, errbuf) == -1)
{
/* Error message - or something else, which is a protocol error. */
if (header.type == RPCAP_MSG_ERROR &&
errcode == PCAP_ERR_WRONGVER)
{
/* /*
* The server didn't support the version we sent, * OK, it's an authentication reply, so we're logged in.
* 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? * Did it send any additional information?
*/ */
if (!RPCAP_VERSION_IS_SUPPORTED(header.ver)) plen = header.plen;
if (plen != 0)
{
/* Yes - is it big enough to be version information? */
if (plen < sizeof(struct rpcap_authreply))
{
/* 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;
/*
* Check the minimum and maximum versions for sanity;
* the minimum must be <= the maximum.
*/
if (authreply.minvers > authreply.maxvers)
{ {
/* /*
* No, so there's no version we both support. * Bogus - give up on this server.
* This is an unrecoverable error.
*/ */
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "The server doesn't support any protocol version that we support"); pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"The server's minimum supported protocol version is greater than its maximum supported protocol version");
return -1; return -1;
} }
}
else
{
/* No - it supports only version 0. */
authreply.minvers = 0;
authreply.maxvers = 0;
}
/* /*
* OK, use that version, and tell our caller to * OK, let's start with the maximum version the server supports.
* try again.
*/ */
*ver = header.ver; ourvers = authreply.maxvers;
return -2;
} #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
/* /*
* Other error - unrecoverable. * If that's greater than the maximum version we support,
* choose the maximum version we support.
*/ */
return -1; if (ourvers > RPCAP_MAX_VERSION)
} {
ourvers = RPCAP_MAX_VERSION;
/* /*
* OK, it's an authentication reply, so they're OK with the * If that's less than the minimum version they
* protocol version we sent. * support, we can't communicate.
*
* Discard the rest of it.
*/ */
if (rpcap_discard(sock, header.plen, errbuf) == -1) if (ourvers < authreply.minvers)
return -1; goto novers;
}
*ver = ourvers;
return 0; 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. */ /* We don't currently support non-blocking mode. */
@ -2059,6 +2047,103 @@ pcap_setnonblock_rpcap(pcap_t *p, int nonblock _U_)
return (-1); 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 * This function opens a remote adapter by opening an RPCAP connection and
* so on. * so on.
@ -2104,15 +2189,12 @@ pcap_t *pcap_open_rpcap(const char *source, int snaplen, int flags, int read_tim
char *source_str; char *source_str;
struct pcap_rpcap *pr; /* structure used when doing a remote live capture */ 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]; 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; SOCKET sockctrl;
uint8 protocol_version; /* negotiated protocol version */ uint8 protocol_version; /* negotiated protocol version */
int active; int active;
uint32 plen; uint32 plen;
char sendbuf[RPCAP_NETBUF_SIZE]; /* temporary buffer in which data to be sent is buffered */ 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 sendbufidx = 0; /* index which keeps the number of bytes currently buffered */
int retval; /* store the return value of the functions */
/* RPCAP-related variables */ /* RPCAP-related variables */
struct rpcap_header header; /* header of the RPCAP packet */ 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; pr->rmt_flags = flags;
/* /*
* determine the type of the source (NULL, file, local, remote) * Attempt to set up the session with the server.
* 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(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); pcap_close(fp);
return NULL; 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 * Now it's time to start playing with the RPCAP protocol
* RPCAP open command: create the request message * 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; goto error;
/* Discard the rest of the message, if there is any. */ /* 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; goto error_nodiscard;
/* Set proper fields into the pcap_t struct */ /* 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 * We already reported an error; if this gets an error, just
* drive on. * drive on.
*/ */
(void)rpcap_discard(pr->rmt_sockctrl, plen, NULL); (void)rpcap_discard(sockctrl, plen, NULL);
error_nodiscard: error_nodiscard:
if (!active) 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() */ /* String identifier to be used in the pcap_findalldevs_ex() */
#define PCAP_TEXT_SOURCE_ADAPTER "Network adapter" #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() */ /* 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 "on remote node"
#define PCAP_TEXT_SOURCE_ON_REMOTE_HOST_LEN (sizeof PCAP_TEXT_SOURCE_ON_REMOTE_HOST - 1)
static void static void
freeaddr(struct pcap_addr *addr) freeaddr(struct pcap_addr *addr)
@ -2340,10 +2340,8 @@ freeaddr(struct pcap_addr *addr)
} }
int 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 */ uint8 protocol_version; /* protocol version */
SOCKET sockctrl; /* socket descriptor of the control connection */ SOCKET sockctrl; /* socket descriptor of the control connection */
uint32 plen; 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 i, j; /* temp variables */
int nif; /* Number of interfaces listed */ int nif; /* Number of interfaces listed */
int active; /* 'true' if we the other end-party is in active mode */ 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 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 */ 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 */ pcap_if_t *lastdev; /* Last device in the pcap_if_t list */
@ -2361,73 +2358,15 @@ pcap_findalldevs_ex_remote(char *source, struct pcap_rmtauth *auth, pcap_if_t **
(*alldevs) = NULL; (*alldevs) = NULL;
lastdev = 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)
{
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. * Attempt to set up the session with the server.
*/ */
return -1; if (rpcap_setup_session(source, auth, &active, &sockctrl,
} &protocol_version, host, port, NULL, errbuf) == -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 */ /* Session setup failed. */
if (sock_initaddress(host, RPCAP_DEFAULT_NETPORT, &hints, &addrinfo, errbuf, PCAP_ERRBUF_SIZE) == -1)
return -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;
}
/* RPCAP findalldevs command */ /* RPCAP findalldevs command */
rpcap_createhdr(&header, protocol_version, RPCAP_MSG_FINDALLIF_REQ, rpcap_createhdr(&header, protocol_version, RPCAP_MSG_FINDALLIF_REQ,
@ -2452,7 +2391,6 @@ pcap_findalldevs_ex_remote(char *source, struct pcap_rmtauth *auth, pcap_if_t **
{ {
struct rpcap_findalldevs_if findalldevs_if; 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 */ 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; struct pcap_addr *addr, *prevaddr;
tmpstring2[PCAP_BUF_SIZE] = 0; 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; tmpstring[findalldevs_if.namelen] = 0;
/* Create the new device identifier */ /* Create the new device identifier */
if (pcap_createsrcstr(tmpstring2, PCAP_SRC_IFREMOTE, host, port, tmpstring, errbuf) == -1) if (pcap_createsrcstr(tmpstring2, PCAP_SRC_IFREMOTE,
return -1; host, port, tmpstring, errbuf) == -1)
goto error;
stringlen = strlen(tmpstring2); dev->name = strdup(tmpstring2);
dev->name = (char *)malloc(stringlen + 1);
if (dev->name == NULL) if (dev->name == NULL)
{ {
pcap_fmt_errmsg_for_errno(errbuf, pcap_fmt_errmsg_for_errno(errbuf,
PCAP_ERRBUF_SIZE, errno, "malloc() failed"); PCAP_ERRBUF_SIZE, errno, "malloc() failed");
goto error; goto error;
} }
/* Copy the new device name into the correct memory location */
strlcpy(dev->name, tmpstring2, stringlen + 1);
} }
if (findalldevs_if.desclen) 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; tmpstring[findalldevs_if.desclen] = 0;
pcap_snprintf(tmpstring2, sizeof(tmpstring2) - 1, "%s '%s' %s %s", PCAP_TEXT_SOURCE_ADAPTER, if (pcap_asprintf(&dev->description,
tmpstring, PCAP_TEXT_SOURCE_ON_REMOTE_HOST, host); "%s '%s' %s %s", PCAP_TEXT_SOURCE_ADAPTER,
tmpstring, PCAP_TEXT_SOURCE_ON_REMOTE_HOST, host) == -1)
stringlen = strlen(tmpstring2);
dev->description = (char *)malloc(stringlen + 1);
if (dev->description == NULL)
{ {
pcap_fmt_errmsg_for_errno(errbuf, pcap_fmt_errmsg_for_errno(errbuf,
PCAP_ERRBUF_SIZE, errno, "malloc() failed"); PCAP_ERRBUF_SIZE, errno, "malloc() failed");
goto error; goto error;
} }
/* Copy the new device description into the correct memory location */
strlcpy(dev->description, tmpstring2, stringlen + 1);
} }
dev->flags = ntohl(findalldevs_if.flags); 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. */ /* Discard the rest of the message. */
if (rpcap_discard(sockctrl, plen, errbuf) == 1) 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 */ /* Control connection has to be closed only in case the remote machine is in passive mode */
if (!active) 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) if (sock_initaddress(address, RPCAP_DEFAULT_NETPORT_ACTIVE, &hints, &addrinfo, errbuf, PCAP_ERRBUF_SIZE) == -1)
{ {
SOCK_DEBUG_MESSAGE(errbuf);
return (SOCKET)-2; 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) if (sock_initaddress(address, port, &hints, &addrinfo, errbuf, PCAP_ERRBUF_SIZE) == -1)
{ {
SOCK_DEBUG_MESSAGE(errbuf);
return (SOCKET)-2; 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) if ((sockmain = sock_open(addrinfo, SOCKOPEN_SERVER, 1, errbuf, PCAP_ERRBUF_SIZE)) == INVALID_SOCKET)
{ {
SOCK_DEBUG_MESSAGE(errbuf);
freeaddrinfo(addrinfo); freeaddrinfo(addrinfo);
return (SOCKET)-2; return (SOCKET)-2;
} }
@ -2764,14 +2687,14 @@ SOCKET pcap_remoteact_accept(const char *address, const char *port, const char *
if (sockctrl == INVALID_SOCKET) if (sockctrl == INVALID_SOCKET)
{ {
sock_geterror("accept(): ", errbuf, PCAP_ERRBUF_SIZE); sock_geterror("accept()", errbuf, PCAP_ERRBUF_SIZE);
return (SOCKET)-2; return (SOCKET)-2;
} }
/* Get the numeric for of the name of the connecting host */ /* 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)) 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); rpcap_senderror(sockctrl, 0, PCAP_ERR_REMOTEACCEPT, errbuf, NULL);
sock_close(sockctrl, NULL, 0); sock_close(sockctrl, NULL, 0);
return (SOCKET)-1; 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, */ /* if (getnameinfo( (struct sockaddr *) &temp->host, sizeof (struct sockaddr_storage), hoststr, */
/* RPCAP_HOSTLIST_SIZE, NULL, 0, NI_NUMERICHOST) ) */ /* RPCAP_HOSTLIST_SIZE, NULL, 0, NI_NUMERICHOST) ) */
{ {
/* sock_geterror("getnameinfo(): ", errbuf, PCAP_ERRBUF_SIZE); */ /* sock_geterror("getnameinfo()", errbuf, PCAP_ERRBUF_SIZE); */
return -1; return -1;
} }
@ -2983,7 +2906,7 @@ int pcap_remoteact_list(char *hostlist, char sep, int size, char *errbuf)
return -1; return -1;
} }
strlcat(hostlist, hoststr, PCAP_ERRBUF_SIZE); pcap_strlcat(hostlist, hoststr, PCAP_ERRBUF_SIZE);
hostlist[len - 1] = sep; hostlist[len - 1] = sep;
hostlist[len] = 0; hostlist[len] = 0;

View File

@ -43,7 +43,7 @@ pcap_t *pcap_open_rpcap(const char *source, int snaplen, int flags,
/* /*
* Internal interfaces for "pcap_findalldevs_ex()". * Internal interfaces for "pcap_findalldevs_ex()".
*/ */
int pcap_findalldevs_ex_remote(char *source, struct pcap_rmtauth *auth, int pcap_findalldevs_ex_remote(const char *source,
pcap_if_t **alldevs, char *errbuf); struct pcap_rmtauth *auth, pcap_if_t **alldevs, char *errbuf);
#endif #endif

View File

@ -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 will be equal if the number of bytes of packet data are less than or
equal to the snapshot length. equal to the snapshot length.
.SH SEE ALSO .SH SEE ALSO
pcap(3PCAP), pcap-linktype(@MAN_MISC_INFO@) pcap(3PCAP)

View File

@ -1,15 +1,6 @@
/* /*
* pcap-septel.c: Packet capture interface for Intel/Septel card. * 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 * Authors: Gilbert HOYEK (gil_hoyek@hotmail.com), Elias M. KHOURY
* (+961 3 485243) * (+961 3 485243)
*/ */
@ -182,7 +173,7 @@ static int septel_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
static int static int
septel_inject(pcap_t *handle, const void *buf _U_, size_t size _U_) septel_inject(pcap_t *handle, const void *buf _U_, 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); PCAP_ERRBUF_SIZE);
return (-1); return (-1);
} }

View File

@ -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_) { 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); PCAP_ERRBUF_SIZE);
return (-1); return (-1);
} }

View File

@ -411,7 +411,7 @@ A { text-decoration:none }
<TR> <TR>
<TD VALIGN=TOP>Interface ID</TD> <TD VALIGN=TOP>Interface ID</TD>
<TD VALIGN=TOP ALIGN=CENTER>1</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> </TR>
</TABLE> </TABLE>
</TD> </TD>

View File

@ -182,8 +182,8 @@ snf_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
hdr.caplen = caplen; hdr.caplen = caplen;
hdr.len = req.length; hdr.len = req.length;
callback(user, &hdr, req.pkt_addr); callback(user, &hdr, req.pkt_addr);
}
n++; n++;
}
/* After one successful packet is received, we won't block /* After one successful packet is received, we won't block
* again for that timeout. */ * again for that timeout. */
@ -237,7 +237,7 @@ snf_inject(pcap_t *p, const void *buf _U_, size_t size _U_)
return (-1); return (-1);
} }
#else #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); PCAP_ERRBUF_SIZE);
return (-1); return (-1);
#endif #endif

View File

@ -123,7 +123,7 @@ static int TcSetDatalink(pcap_t *p, int dlt);
static int TcGetNonBlock(pcap_t *p); static int TcGetNonBlock(pcap_t *p);
static int TcSetNonBlock(pcap_t *p, int nonblock); static int TcSetNonBlock(pcap_t *p, int nonblock);
static void TcCleanup(pcap_t *p); 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 TcRead(pcap_t *p, int cnt, pcap_handler callback, u_char *user);
static int TcStats(pcap_t *p, struct pcap_stat *ps); static int TcStats(pcap_t *p, struct pcap_stat *ps);
static int TcSetFilter(pcap_t *p, struct bpf_program *fp); 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; PTC_PORT pPorts = NULL;
TC_STATUS status; TC_STATUS status;
int result = 0; int result = 0;
pcap_if_t *dev, *cursor; pcap_if_t *dev;
ULONG i; ULONG i;
do do
@ -472,22 +472,7 @@ TcFindAllDevs(pcap_if_list_t *devlist, char *errbuf)
dev = TcCreatePcapIfFromPort(pPorts[i]); dev = TcCreatePcapIfFromPort(pPorts[i]);
if (dev != NULL) if (dev != NULL)
{ add_dev(devlist, dev->name, dev->flags, dev->description, errbuf);
/*
* 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;
}
}
} }
if (numPorts > 0) if (numPorts > 0)
@ -846,7 +831,7 @@ static void TcCleanup(pcap_t *p)
} }
/* Send a packet to the network */ /* 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; struct pcap_tc *pt = p->priv;
TC_STATUS status; TC_STATUS status;

View File

@ -93,9 +93,9 @@ call and before a
call to specify the type of time stamp to be used on the device. call to specify the type of time stamp to be used on the device.
The time stamp types are listed here; the first value is the #define to The time stamp types are listed here; the first value is the #define to
use in code, the second value is the value returned by use in code, the second value is the value returned by
.B pcap_tstamp_type_val_to_name() .B pcap_tstamp_type_val_to_name(3PCAP)
and accepted by and accepted by
.BR pcap_tstamp_type_name_to_val() . .BR pcap_tstamp_type_name_to_val(3PCAP) .
.RS 5 .RS 5
.TP 5 .TP 5
.BR PCAP_TSTAMP_HOST " - " host .BR PCAP_TSTAMP_HOST " - " host
@ -149,9 +149,9 @@ call will fail, and the time stamps supplied after the
call will have microsecond resolution. call will have microsecond resolution.
.LP .LP
When opening a savefile, the When opening a savefile, the
.BR pcap_open_offline_with_tstamp_precision (3PCAP) .BR \%pcap_open_offline_with_tstamp_precision (3PCAP)
and 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 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, from the file; if the time stamps in the file have a lower resolution,
the fraction-of-a-second portion of the time stamps will be scaled to the 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 reading a savefile, this does not indicate the actual precision of time
stamps in the file. stamps in the file.
.SH SEE ALSO .SH SEE ALSO
.na pcap(3PCAP)
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

View File

@ -50,6 +50,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <fcntl.h> #include <fcntl.h>
#include <limits.h>
#include <string.h> #include <string.h>
#include <dirent.h> #include <dirent.h>
#include <byteswap.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, if (add_dev(devlistp, dev_name,
PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE, PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE,
"All USB buses", err_str) == NULL) "Raw USB traffic, all USB buses", err_str) == NULL)
return -1; return -1;
} else { } 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_CONNECTED or
* PCAP_IF_CONNECTION_STATUS_DISCONNECTED? * 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) if (add_dev(devlistp, dev_name, 0, dev_descr, err_str) == NULL)
return -1; 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 * Split LINUX_USB_MON_DEV into a directory that we'll
* scan and a file name prefix that we'll check for. * 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, '/'); usb_mon_prefix = strrchr(usb_mon_dir, '/');
if (usb_mon_prefix == NULL) { 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 static
int usb_mmap(pcap_t* handle) int usb_mmap(pcap_t* handle)
{ {
struct pcap_usb_linux *handlep = handle->priv; struct pcap_usb_linux *handlep = handle->priv;
int len = ioctl(handle->fd, MON_IOCQ_RING_SIZE); int len;
if (len < 0)
/*
* 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; return 0;
}
handlep->mmapbuflen = len; handlep->mmapbuflen = len;
handlep->mmapbuf = mmap(0, handlep->mmapbuflen, PROT_READ, handlep->mmapbuf = mmap(0, handlep->mmapbuflen, PROT_READ,
MAP_SHARED, handle->fd, 0); 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 #ifdef HAVE_LINUX_USBDEVICE_FS_H
@ -514,6 +599,7 @@ usb_activate(pcap_t* handle)
{ {
struct pcap_usb_linux *handlep = handle->priv; struct pcap_usb_linux *handlep = handle->priv;
char full_path[USB_LINE_LEN]; char full_path[USB_LINE_LEN];
int ret;
/* /*
* Turn a negative snapshot value (invalid), a snapshot value of * Turn a negative snapshot value (invalid), a snapshot value of
@ -604,6 +690,7 @@ usb_activate(pcap_t* handle)
/* try to use fast mmap access */ /* try to use fast mmap access */
if (usb_mmap(handle)) if (usb_mmap(handle))
{ {
/* We succeeded. */
handle->linktype = DLT_USB_LINUX_MMAPPED; handle->linktype = DLT_USB_LINUX_MMAPPED;
handle->stats_op = usb_stats_linux_bin; handle->stats_op = usb_stats_linux_bin;
handle->read_op = usb_read_linux_mmap; handle->read_op = usb_read_linux_mmap;
@ -620,7 +707,19 @@ usb_activate(pcap_t* handle)
return 0; 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->stats_op = usb_stats_linux_bin;
handle->read_op = usb_read_linux_bin; handle->read_op = usb_read_linux_bin;
#ifdef HAVE_LINUX_USBDEVICE_FS_H #ifdef HAVE_LINUX_USBDEVICE_FS_H
@ -646,38 +745,38 @@ usb_activate(pcap_t* handle)
handle->fd = open(full_path, O_RDONLY, 0); handle->fd = open(full_path, O_RDONLY, 0);
} }
if (handle->fd < 0) { if (handle->fd < 0) {
if (errno == ENOENT)
{
/* /*
* Is the problem that we didn't have * The problem is that the file
* sufficient permission to open it? * doesn't exist. Report that as
* "no such device". (That could
* mean "no such USB bus" or
* "monitoring not supported".)
*/ */
if (errno == EACCES) { ret = PCAP_ERROR_NO_SUCH_DEVICE;
/*
* Yes - return that error.
*/
return PCAP_ERROR_PERM_DENIED;
} }
else if (errno == EACCES)
{
/* /*
* No - was the problem something other * The problem is that we don't
* than "it doesn't exist"? * have sufficient permission to
* open the file. Report that.
*/ */
if (errno != ENOENT) { ret = PCAP_ERROR_PERM_DENIED;
}
else
{
/* /*
* Yes - return *that* error. * Some other error.
*/ */
ret = PCAP_ERROR;
}
pcap_fmt_errmsg_for_errno(handle->errbuf, pcap_fmt_errmsg_for_errno(handle->errbuf,
PCAP_ERRBUF_SIZE, errno, PCAP_ERRBUF_SIZE, errno,
"Can't open USB bus file %s", "Can't open USB bus file %s",
full_path); full_path);
return PCAP_ERROR; return ret;
}
/*
* No. Report that as "no such device".
* (That could mean "no such USB bus"
* or "monitoring not supported".)
*/
return PCAP_ERROR_NO_SUCH_DEVICE;
} }
} }
@ -923,8 +1022,8 @@ usb_read_linux(pcap_t *handle, int max_packets _U_, pcap_handler callback, u_cha
static int static int
usb_inject_linux(pcap_t *handle, const void *buf _U_, size_t size _U_) 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 " pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"USB devices"); "Packet injection is not supported on USB devices");
return (-1); return (-1);
} }
@ -973,6 +1072,10 @@ usb_stats_linux(pcap_t *handle, struct pcap_stat *stats)
} }
string[ret] = 0; 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 */ /* extract info on dropped urbs */
for (consumed=0; consumed < ret; ) { for (consumed=0; consumed < ret; ) {
/* from the sscanf man page: /* from the sscanf man page:
@ -989,18 +1092,16 @@ usb_stats_linux(pcap_t *handle, struct pcap_stat *stats)
break; break;
consumed += cnt; consumed += cnt;
ptr += cnt; ptr += cnt;
if (strcmp(token, "nreaders") == 0) if (strcmp(token, "text_lost") == 0)
ret = sscanf(ptr, "%d", &stats->ps_drop); ntok = sscanf(ptr, "%d%n", &stats->ps_drop, &cnt);
else else
ret = sscanf(ptr, "%d", &dummy); ntok = sscanf(ptr, "%d%n", &dummy, &cnt);
if (ntok != 1) if ((ntok != 1) || (cnt < 0))
break; break;
consumed += cnt; consumed += cnt;
ptr += cnt; ptr += cnt;
} }
stats->ps_recv = handlep->packets_read;
stats->ps_ifdrop = 0;
return 0; return 0;
} }
@ -1069,13 +1170,44 @@ usb_read_linux_bin(pcap_t *handle, int max_packets _U_, pcap_handler callback, u
return -1; 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) if (info.hdr->data_len < clen)
clen = info.hdr->data_len; clen = info.hdr->data_len;
info.hdr->data_len = clen; info.hdr->data_len = clen;
pkth.caplen = clen + sizeof(pcap_usb_header); pkth.caplen = sizeof(pcap_usb_header) + clen;
pkth.len = info.hdr->data_len + sizeof(pcap_usb_header); 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_sec = info.hdr->ts_sec;
pkth.ts.tv_usec = info.hdr->ts_usec; 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; struct mon_bin_mfetch fetch;
int32_t vec[VEC_SIZE]; int32_t vec[VEC_SIZE];
struct pcap_pkthdr pkth; struct pcap_pkthdr pkth;
pcap_usb_header* hdr; pcap_usb_header_mmapped* hdr;
int nflush = 0; int nflush = 0;
int packets = 0; int packets = 0;
u_int clen, max_clen; u_int clen, max_clen;
max_clen = handle->snapshot - sizeof(pcap_usb_header); max_clen = handle->snapshot - sizeof(pcap_usb_header_mmapped);
for (;;) { for (;;) {
int i, ret; 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; nflush = fetch.nfetch;
for (i=0; i<fetch.nfetch; ++i) { for (i=0; i<fetch.nfetch; ++i) {
/* discard filler */ /* discard filler */
hdr = (pcap_usb_header*) &handlep->mmapbuf[vec[i]]; hdr = (pcap_usb_header_mmapped*) &handlep->mmapbuf[vec[i]];
if (hdr->event_type == '@') if (hdr->event_type == '@')
continue; continue;
/* we can get less that than really captured from kernel, depending on /*
* 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; clen = max_clen;
if (hdr->data_len < clen) if (hdr->data_len < clen)
clen = hdr->data_len; clen = hdr->data_len;
pkth.caplen = sizeof(pcap_usb_header_mmapped) + clen;
/* get packet info from header*/ if (hdr->data_flag) {
pkth.caplen = clen + sizeof(pcap_usb_header_mmapped); /*
pkth.len = hdr->data_len + sizeof(pcap_usb_header_mmapped); * 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_sec = hdr->ts_sec;
pkth.ts.tv_usec = hdr->ts_usec; pkth.ts.tv_usec = hdr->ts_usec;

View File

@ -17,7 +17,7 @@
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF .\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\" .\"
.TH PCAP 3PCAP "20 January 2017" .TH PCAP 3PCAP "25 July 2018"
.SH NAME .SH NAME
pcap \- Packet Capture library pcap \- Packet Capture library
.SH SYNOPSIS .SH SYNOPSIS
@ -191,6 +191,10 @@ expires even if no packets have arrived.
.IP .IP
The packet buffer timeout is set with The packet buffer timeout is set with
.BR pcap_set_timeout (). .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" .IP "buffer size"
Packets that arrive for a capture are stored in a buffer, so that they 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 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 interfaces. To determine the format of the packets supplied by the
handle, call handle, call
.BR pcap_datalink (); .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 lists the values it returns and describes the packet formats that
correspond to those values. correspond to those values.
.PP .PP
@ -396,7 +400,7 @@ set promiscuous mode for a not-yet-activated
.B pcap_t .B pcap_t
for live capture for live capture
.TP .TP
.BR pcap_set_protocol (3PCAP) .BR pcap_set_protocol_linux (3PCAP)
set capture protocol for a not-yet-activated set capture protocol for a not-yet-activated
.B pcap_t .B pcap_t
for live capture (Linux only) for live capture (Linux only)
@ -416,6 +420,11 @@ set packet buffer timeout for a not-yet-activated
.B pcap_t .B pcap_t
for live capture for live capture
.TP .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) .BR pcap_set_buffer_size (3PCAP)
set buffer size for a not-yet-activated set buffer size for a not-yet-activated
.B pcap_t .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 descriptors to be ready to read. To obtain, for a handle, a descriptor
that can be used in those routines, call that can be used in those routines, call
.BR pcap_get_selectable_fd (). .BR pcap_get_selectable_fd ().
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; Not all handles have such a descriptor available;
.BR pcap_get_selectable_fd () .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 reasons, one or more of those routines will not work properly with the
descriptor; the documentation for descriptor; the documentation for
.BR pcap_get_selectable_fd () .BR pcap_get_selectable_fd ()
@ -693,6 +721,15 @@ that can be used in calls such as
.BR select (2) .BR select (2)
and and
.BR poll (2) .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 .RE
.SS Filters .SS Filters
In order to cause only certain packets to be returned when reading In order to cause only certain packets to be returned when reading
@ -890,7 +927,7 @@ To get a string giving version information about libpcap, call
.BR pcap_lib_version (3PCAP) .BR pcap_lib_version (3PCAP)
get library version string get library version string
.RE .RE
.SH BACKWARDS COMPATIBILITY .SH BACKWARD COMPATIBILITY
.PP .PP
In versions of libpcap prior to 1.0, the In versions of libpcap prior to 1.0, the
.B pcap.h .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 The current version is available from "The Tcpdump Group"'s Web site at
.LP .LP
.RS .RS
.I http://www.tcpdump.org/ .I https://www.tcpdump.org/
.RE .RE
.SH BUGS .SH BUGS
To report a security issue please send an e-mail to security@tcpdump.org. To report a security issue please send an e-mail to security@tcpdump.org.

View File

@ -139,7 +139,7 @@ BOOL WINAPI DllMain(
/* /*
* Start WinSock. * 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. * even though it wasn't exported.
*/ */
int int
@ -186,76 +186,165 @@ pcap_wsockinit(void)
PCAP_API char pcap_version[]; PCAP_API char pcap_version[];
PCAP_API_DEF char pcap_version[] = PACKAGE_VERSION; PCAP_API_DEF char pcap_version[] = PACKAGE_VERSION;
static int static void
pcap_not_initialized(pcap_t *pcap) pcap_set_not_initialized_message(pcap_t *pcap)
{ {
if (pcap->activated) { if (pcap->activated) {
/* A module probably forgot to set the function pointer */ /* A module probably forgot to set the function pointer */
(void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf), (void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf),
"This operation isn't properly handled by that device"); "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 */ /* in case the caller doesn't check for PCAP_ERROR_NOT_ACTIVATED */
(void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf), (void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf),
"This handle hasn't been activated yet"); "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' */ /* this means 'not initialized' */
return (PCAP_ERROR_NOT_ACTIVATED); return (PCAP_ERROR_NOT_ACTIVATED);
} }
#ifdef _WIN32 #ifdef _WIN32
static void * struct pcap_stat *
pcap_not_initialized_ptr(pcap_t *pcap) pcap_stats_ex_not_initialized(pcap_t *pcap, int *pcap_stat_size _U_)
{ {
if (pcap->activated) { pcap_set_not_initialized_message(pcap);
/* 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");
return (NULL); 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 static HANDLE
pcap_getevent_not_initialized(pcap_t *pcap) pcap_getevent_not_initialized(pcap_t *pcap)
{ {
if (pcap->activated) { pcap_set_not_initialized_message(pcap);
/* 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");
return (INVALID_HANDLE_VALUE); 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 static u_int
pcap_sendqueue_transmit_not_initialized(pcap_t *pcap, pcap_send_queue* queue, int sync) pcap_sendqueue_transmit_not_initialized(pcap_t *pcap, pcap_send_queue* queue, int sync)
{ {
if (pcap->activated) { pcap_set_not_initialized_message(pcap);
/* 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");
return (0); 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 static PAirpcapHandle
pcap_get_airpcap_handle_not_initialized(pcap_t *pcap) pcap_get_airpcap_handle_not_initialized(pcap_t *pcap)
{ {
if (pcap->activated) { pcap_set_not_initialized_message(pcap);
/* 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");
return (NULL); return (NULL);
} }
#endif #endif
@ -296,8 +385,17 @@ pcap_list_tstamp_types(pcap_t *p, int **tstamp_typesp)
if (p->tstamp_type_count == 0) { if (p->tstamp_type_count == 0) {
/* /*
* We don't support multiple time stamp types. * 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 { } else {
*tstamp_typesp = (int*)calloc(sizeof(**tstamp_typesp), *tstamp_typesp = (int*)calloc(sizeof(**tstamp_typesp),
p->tstamp_type_count); 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, (void)memcpy(*tstamp_typesp, p->tstamp_type_list,
sizeof(**tstamp_typesp) * p->tstamp_type_count); 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. * Get the description for the interface.
*/ */
memset(&ifrdesc, 0, sizeof ifrdesc); 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); s = socket(AF_INET, SOCK_DGRAM, 0);
if (s >= 0) { if (s >= 0) {
#ifdef __FreeBSD__ #ifdef __FreeBSD__
@ -710,7 +808,7 @@ get_if_description(const char *name)
} }
#endif /* __FreeBSD__ */ #endif /* __FreeBSD__ */
close(s); close(s);
if (description != NULL && strlen(description) == 0) { if (description != NULL && description[0] == '\0') {
/* /*
* Description is empty, so discard it. * 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 * OK, it's a valid number that's not
* bigger than INT_MAX. Construct * bigger than INT_MAX. Construct
* a description from it. * 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 "; if (pcap_asprintf(&description,
size_t descr_size; "USB bus number %ld", busnum) == -1) {
/* Failed. */
/* description = NULL;
* 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);
} }
} }
} }
@ -1292,14 +1383,14 @@ pcap_lookupdev(char *errbuf)
* on the list, there aren't any non-loopback devices, * on the list, there aren't any non-loopback devices,
* so why not just supply it as the default device? * 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); PCAP_ERRBUF_SIZE);
ret = NULL; ret = NULL;
} else { } else {
/* /*
* Return the name of the first device on the list. * 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; 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 */ /* XXX Work around Linux kernel bug */
ifr.ifr_addr.sa_family = AF_INET; ifr.ifr_addr.sa_family = AF_INET;
#endif #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 (ioctl(fd, SIOCGIFADDR, (char *)&ifr) < 0) {
if (errno == EADDRNOTAVAIL) { if (errno == EADDRNOTAVAIL) {
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, (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 */ /* XXX Work around Linux kernel bug */
ifr.ifr_addr.sa_family = AF_INET; ifr.ifr_addr.sa_family = AF_INET;
#endif #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) { if (ioctl(fd, SIOCGIFNETMASK, (char *)&ifr) < 0) {
pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
errno, "SIOCGIFNETMASK: %s", device); errno, "SIOCGIFNETMASK: %s", device);
@ -1575,13 +1666,14 @@ pcap_parse_source(const char *source, char **schemep, char **userinfop,
* the pathname. * the pathname.
*/ */
if (pcap_strcasecmp(scheme, "file") == 0) { if (pcap_strcasecmp(scheme, "file") == 0) {
*schemep = scheme;
*pathp = strdup(colonp + 3); *pathp = strdup(colonp + 3);
if (*pathp == NULL) { if (*pathp == NULL) {
pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE, pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
errno, "malloc"); errno, "malloc");
free(scheme);
return (-1); return (-1);
} }
*schemep = scheme;
return (0); return (0);
} }
@ -1684,7 +1776,12 @@ pcap_parse_source(const char *source, char **schemep, char **userinfop,
* Treat verything up to the closing square * Treat verything up to the closing square
* bracket as the IP-Literal; we don't worry * bracket as the IP-Literal; we don't worry
* about whether it's a valid IPv6address or * 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, ']'); bracketp = strchr(parsep, ']');
if (bracketp == NULL) { if (bracketp == NULL) {
@ -1805,9 +1902,9 @@ pcap_createsrcstr(char *source, int type, const char *host, const char *port,
switch (type) { switch (type) {
case PCAP_SRC_FILE: 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') { if (name != NULL && *name != '\0') {
strlcat(source, name, PCAP_BUF_SIZE); pcap_strlcat(source, name, PCAP_BUF_SIZE);
return (0); return (0);
} else { } else {
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, 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: 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 (host != NULL && *host != '\0') {
if (strchr(host, ':') != NULL) { 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 * probably an IPv6 address, and needs to
* be included in square brackets. * be included in square brackets.
*/ */
strlcat(source, "[", PCAP_BUF_SIZE); pcap_strlcat(source, "[", PCAP_BUF_SIZE);
strlcat(source, host, PCAP_BUF_SIZE); pcap_strlcat(source, host, PCAP_BUF_SIZE);
strlcat(source, "]", PCAP_BUF_SIZE); pcap_strlcat(source, "]", PCAP_BUF_SIZE);
} else } else
strlcat(source, host, PCAP_BUF_SIZE); pcap_strlcat(source, host, PCAP_BUF_SIZE);
if (port != NULL && *port != '\0') { if (port != NULL && *port != '\0') {
strlcat(source, ":", PCAP_BUF_SIZE); pcap_strlcat(source, ":", PCAP_BUF_SIZE);
strlcat(source, port, PCAP_BUF_SIZE); pcap_strlcat(source, port, PCAP_BUF_SIZE);
} }
strlcat(source, "/", PCAP_BUF_SIZE); pcap_strlcat(source, "/", PCAP_BUF_SIZE);
} else { } else {
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"The host name cannot be NULL."); "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') if (name != NULL && *name != '\0')
strlcat(source, name, PCAP_BUF_SIZE); pcap_strlcat(source, name, PCAP_BUF_SIZE);
return (0); return (0);
case PCAP_SRC_IFLOCAL: 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') if (name != NULL && *name != '\0')
strlcat(source, name, PCAP_BUF_SIZE); pcap_strlcat(source, name, PCAP_BUF_SIZE);
return (0); return (0);
@ -1890,7 +1987,7 @@ pcap_parsesrcstr(const char *source, int *type, char *host, char *port,
* Local device. * Local device.
*/ */
if (name && tmppath) if (name && tmppath)
strlcpy(name, tmppath, PCAP_BUF_SIZE); pcap_strlcpy(name, tmppath, PCAP_BUF_SIZE);
if (type) if (type)
*type = PCAP_SRC_IFLOCAL; *type = PCAP_SRC_IFLOCAL;
free(tmppath); 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", pcap_snprintf(host, PCAP_BUF_SIZE, "%s@%s",
tmpuserinfo, tmphost); tmpuserinfo, tmphost);
else else
strlcpy(host, tmphost, PCAP_BUF_SIZE); pcap_strlcpy(host, tmphost, PCAP_BUF_SIZE);
} }
if (port && tmpport) if (port && tmpport)
strlcpy(port, tmpport, PCAP_BUF_SIZE); pcap_strlcpy(port, tmpport, PCAP_BUF_SIZE);
if (name && tmppath) if (name && tmppath)
strlcpy(name, tmppath, PCAP_BUF_SIZE); pcap_strlcpy(name, tmppath, PCAP_BUF_SIZE);
if (type) if (type)
*type = PCAP_SRC_IFREMOTE; *type = PCAP_SRC_IFREMOTE;
free(tmppath); free(tmppath);
@ -1933,7 +2030,7 @@ pcap_parsesrcstr(const char *source, int *type, char *host, char *port,
* file:// * file://
*/ */
if (name && tmppath) if (name && tmppath)
strlcpy(name, tmppath, PCAP_BUF_SIZE); pcap_strlcpy(name, tmppath, PCAP_BUF_SIZE);
if (type) if (type)
*type = PCAP_SRC_FILE; *type = PCAP_SRC_FILE;
free(tmppath); free(tmppath);
@ -1949,7 +2046,7 @@ pcap_parsesrcstr(const char *source, int *type, char *host, char *port,
* as a local device. * as a local device.
*/ */
if (name) if (name)
strlcpy(name, source, PCAP_BUF_SIZE); pcap_strlcpy(name, source, PCAP_BUF_SIZE);
if (type) if (type)
*type = PCAP_SRC_IFLOCAL; *type = PCAP_SRC_IFLOCAL;
free(tmppath); free(tmppath);
@ -1981,11 +2078,28 @@ pcap_create(const char *device, char *errbuf)
else { else {
#ifdef _WIN32 #ifdef _WIN32
/* /*
* If the string appears to be little-endian UCS-2/UTF-16, * On Windows, for backwards compatibility reasons,
* convert it to ASCII. * 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 * This means that if a program uses pcap_lookupdev()
* character isn't ASCII? * 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') { if (device[0] != '\0' && device[1] == '\0') {
size_t length; size_t length;
@ -2077,25 +2191,25 @@ initialize_ops(pcap_t *p)
* an activated pcap_t to point to a routine that returns * an activated pcap_t to point to a routine that returns
* a "this isn't activated" error. * a "this isn't activated" error.
*/ */
p->read_op = (read_op_t)pcap_not_initialized; p->read_op = pcap_read_not_initialized;
p->inject_op = (inject_op_t)pcap_not_initialized; p->inject_op = pcap_inject_not_initialized;
p->setfilter_op = (setfilter_op_t)pcap_not_initialized; p->setfilter_op = pcap_setfilter_not_initialized;
p->setdirection_op = (setdirection_op_t)pcap_not_initialized; p->setdirection_op = pcap_setdirection_not_initialized;
p->set_datalink_op = (set_datalink_op_t)pcap_not_initialized; p->set_datalink_op = pcap_set_datalink_not_initialized;
p->getnonblock_op = (getnonblock_op_t)pcap_not_initialized; p->getnonblock_op = pcap_getnonblock_not_initialized;
p->stats_op = (stats_op_t)pcap_not_initialized; p->stats_op = pcap_stats_not_initialized;
#ifdef _WIN32 #ifdef _WIN32
p->stats_ex_op = (stats_ex_op_t)pcap_not_initialized_ptr; p->stats_ex_op = pcap_stats_ex_not_initialized;
p->setbuff_op = (setbuff_op_t)pcap_not_initialized; p->setbuff_op = pcap_setbuff_not_initialized;
p->setmode_op = (setmode_op_t)pcap_not_initialized; p->setmode_op = pcap_setmode_not_initialized;
p->setmintocopy_op = (setmintocopy_op_t)pcap_not_initialized; p->setmintocopy_op = pcap_setmintocopy_not_initialized;
p->getevent_op = pcap_getevent_not_initialized; p->getevent_op = pcap_getevent_not_initialized;
p->oid_get_request_op = (oid_get_request_op_t)pcap_not_initialized; p->oid_get_request_op = pcap_oid_get_request_not_initialized;
p->oid_set_request_op = (oid_set_request_op_t)pcap_not_initialized; p->oid_set_request_op = pcap_oid_set_request_not_initialized;
p->sendqueue_transmit_op = pcap_sendqueue_transmit_not_initialized; p->sendqueue_transmit_op = pcap_sendqueue_transmit_not_initialized;
p->setuserbuffer_op = (setuserbuffer_op_t)pcap_not_initialized; p->setuserbuffer_op = pcap_setuserbuffer_not_initialized;
p->live_dump_op = (live_dump_op_t)pcap_not_initialized; p->live_dump_op = pcap_live_dump_not_initialized;
p->live_dump_ended_op = (live_dump_ended_op_t)pcap_not_initialized; p->live_dump_ended_op = pcap_live_dump_ended_not_initialized;
p->get_airpcap_handle_op = pcap_get_airpcap_handle_not_initialized; p->get_airpcap_handle_op = pcap_get_airpcap_handle_not_initialized;
#endif #endif
@ -2124,14 +2238,23 @@ pcap_alloc_pcap_t(char *ebuf, size_t size)
* plus a structure following it of size "size". The * plus a structure following it of size "size". The
* structure following it is a private data structure * structure following it is a private data structure
* for the routines that handle this pcap_t. * 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) { if (chunk == NULL) {
pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE, pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
errno, "malloc"); errno, "malloc");
return (NULL); 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. * 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 * Set the pointer to the private data; that's the structure
* of size "size" following the pcap_t. * of size "size" following the pcap_t.
*/ */
p->priv = (void *)(chunk + sizeof (pcap_t)); p->priv = (void *)(chunk + PCAP_T_ALIGNED_SIZE);
} }
return (p); 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]; char name[PCAP_BUF_SIZE + 1];
int srctype; 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 * Retrofit - we have to make older applications compatible with
* remote capture. * remote capture.
@ -2522,13 +2655,13 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, char *er
return (p); return (p);
fail: fail:
if (status == PCAP_ERROR) if (status == PCAP_ERROR)
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", device, pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %.*s", device,
p->errbuf); PCAP_ERRBUF_SIZE - 3, p->errbuf);
else if (status == PCAP_ERROR_NO_SUCH_DEVICE || else if (status == PCAP_ERROR_NO_SUCH_DEVICE ||
status == PCAP_ERROR_PERM_DENIED || status == PCAP_ERROR_PERM_DENIED ||
status == PCAP_ERROR_PROMISC_PERM_DENIED) status == PCAP_ERROR_PROMISC_PERM_DENIED)
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s (%s)", device, pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s (%.*s)", device,
pcap_statustostr(status), p->errbuf); pcap_statustostr(status), PCAP_ERRBUF_SIZE - 6, p->errbuf);
else else
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", device, pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", device,
pcap_statustostr(status)); pcap_statustostr(status));
@ -2841,7 +2974,7 @@ static struct dlt_choice dlt_choices[] = {
DLT_CHOICE(FRELAY, "Frame Relay"), DLT_CHOICE(FRELAY, "Frame Relay"),
DLT_CHOICE(LOOP, "OpenBSD loopback"), DLT_CHOICE(LOOP, "OpenBSD loopback"),
DLT_CHOICE(ENC, "OpenBSD encapsulated IP"), 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(LTALK, "Localtalk"),
DLT_CHOICE(PFLOG, "OpenBSD pflog file"), DLT_CHOICE(PFLOG, "OpenBSD pflog file"),
DLT_CHOICE(PFSYNC, "Packet filter state syncing"), DLT_CHOICE(PFSYNC, "Packet filter state syncing"),
@ -2899,10 +3032,11 @@ static struct dlt_choice dlt_choices[] = {
DLT_CHOICE(SITA, "SITA pseudo-header"), DLT_CHOICE(SITA, "SITA pseudo-header"),
DLT_CHOICE(ERF, "Endace ERF header"), DLT_CHOICE(ERF, "Endace ERF header"),
DLT_CHOICE(RAIF1, "Ethernet with u10 Networks pseudo-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(JUNIPER_ST, "Juniper Secure Tunnel"),
DLT_CHOICE(BLUETOOTH_HCI_H4_WITH_PHDR, "Bluetooth HCI UART transport layer plus pseudo-header"), 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(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(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(MPLS, "MPLS with label as link-layer header"),
DLT_CHOICE(LINUX_EVDEV, "Linux evdev events"), 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(DOCSIS31_XRA31, "Excentis XRA-31 DOCSIS 3.1 RF sniffer frames"),
DLT_CHOICE(ETHERNET_MPACKET, "802.3br mPackets"), DLT_CHOICE(ETHERNET_MPACKET, "802.3br mPackets"),
DLT_CHOICE(DISPLAYPORT_AUX, "DisplayPort AUX channel monitoring data"), DLT_CHOICE(DISPLAYPORT_AUX, "DisplayPort AUX channel monitoring data"),
DLT_CHOICE(LINUX_SLL2, "Linux cooked v2"),
DLT_CHOICE_SENTINEL DLT_CHOICE_SENTINEL
}; };
@ -2998,6 +3133,21 @@ pcap_datalink_val_to_description(int dlt)
return (NULL); 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 { struct tstamp_type_choice {
const char *name; const char *name;
const char *description; const char *description;
@ -3150,7 +3300,7 @@ pcap_getnonblock(pcap_t *p, char *errbuf)
* We copy the error message to errbuf, so callers * We copy the error message to errbuf, so callers
* can find it in either place. * can find it in either place.
*/ */
strlcpy(errbuf, p->errbuf, PCAP_ERRBUF_SIZE); pcap_strlcpy(errbuf, p->errbuf, PCAP_ERRBUF_SIZE);
} }
return (ret); return (ret);
} }
@ -3194,7 +3344,7 @@ pcap_setnonblock(pcap_t *p, int nonblock, char *errbuf)
* We copy the error message to errbuf, so callers * We copy the error message to errbuf, so callers
* can find it in either place. * can find it in either place.
*/ */
strlcpy(errbuf, p->errbuf, PCAP_ERRBUF_SIZE); pcap_strlcpy(errbuf, p->errbuf, PCAP_ERRBUF_SIZE);
} }
return (ret); return (ret);
} }
@ -3230,35 +3380,6 @@ pcap_setnonblock_fd(pcap_t *p, int nonblock)
} }
#endif #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. * 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); errno_t err = strerror_s(errbuf, PCAP_ERRBUF_SIZE, errnum);
if (err != 0) /* err = 0 if successful */ 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); return (errbuf);
#else #else
return (strerror(errnum)); return (strerror(errnum));
@ -3552,7 +3673,7 @@ pcap_do_addexit(pcap_t *p)
/* /*
* "atexit()" failed; let our caller know. * "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); return (0);
} }
did_atexit = 1; did_atexit = 1;

View File

@ -238,16 +238,6 @@ struct bpf_insn {
bpf_u_int32 k; 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. * 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 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); 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). * Number of scratch memory words (for BPF_LD|BPF_MEM and BPF_ST).

View File

@ -160,4 +160,4 @@
(__HP_aCC >= ((major)*10000 + (minor)*100)) (__HP_aCC >= ((major)*10000 + (minor)*100))
#endif #endif
#endif /* lib_pcap_funcattrs_h */ #endif /* lib_pcap_compiler_tests_h */

View File

@ -50,7 +50,7 @@
* *
* See * See
* *
* http://www.tcpdump.org/linktypes.html * https://www.tcpdump.org/linktypes.html
* *
* for detailed descriptions of some of these link-layer header types. * 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 #define DLT_LINUX_SLL 113
@ -769,11 +769,20 @@
#define DLT_RAIF1 198 #define DLT_RAIF1 198
/* /*
* IPMB packet for IPMI, beginning with the I2C slave address, followed * IPMB packet for IPMI, beginning with a 2-byte header, followed by
* by the netFn and LUN, etc.. Requested by Chanthy Toeung * the I2C slave address, followed by the netFn and LUN, etc..
* <chanthy.toeung@ca.kontron.com>. * 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 * Juniper-private data link type, as per request from
@ -805,15 +814,34 @@
#define DLT_LAPD 203 #define DLT_LAPD 203
/* /*
* Variants of various link-layer headers, with a one-byte direction * PPP, with a one-byte direction pseudo-header prepended - zero means
* pseudo-header prepended - zero means "received by this host", * "received by this host", non-zero (any non-zero value) means "sent by
* non-zero (any non-zero value) means "sent by this host" - as per * this host" - as per Will Barker <w.barker@zen.co.uk>.
* Will Barker <w.barker@zen.co.uk>.
*/ */
#define DLT_PPP_WITH_DIR 204 /* PPP - don't confuse with DLT_PPP_WITH_DIRECTION */ #define DLT_PPP_WITH_DIR 204 /* 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 */ * 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 * 208 is reserved for an as-yet-unspecified proprietary link-layer
@ -1367,6 +1395,11 @@
*/ */
#define DLT_DISPLAYPORT_AUX 275 #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) * In case the code that includes this file (directly or indirectly)
* has also included OS files that happen to define DLT_MATCHING_MAX, * has also included OS files that happen to define DLT_MATCHING_MAX,
@ -1377,7 +1410,7 @@
#ifdef DLT_MATCHING_MAX #ifdef DLT_MATCHING_MAX
#undef DLT_MATCHING_MAX #undef DLT_MATCHING_MAX
#endif #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 * DLT and savefile link type values are split into a class and

View File

@ -164,10 +164,11 @@
|| PCAP_IS_AT_LEAST_XL_C_VERSION(10,1) \ || PCAP_IS_AT_LEAST_XL_C_VERSION(10,1) \
|| PCAP_IS_AT_LEAST_HP_C_VERSION(6,10) || PCAP_IS_AT_LEAST_HP_C_VERSION(6,10)
/* /*
* Compiler with support for __attribute((noreturn)), or GCC 2.5 and * Compiler with support for __attribute((noreturn)), or GCC 2.5 or
* later, or Solaris Studio 12 (Sun C 5.9) and later, or IBM XL C 10.1 * later, or some compiler asserting compatibility with GCC 2.5 or
* and later (do any earlier versions of XL C support this?), or * later, or Solaris Studio 12 (Sun C 5.9) or later, or IBM XL C 10.1
* HP aCC A.06.10 and later. * 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 __attribute((noreturn))
#define PCAP_NORETURN_DEF __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_XL_C_VERSION(10,1) \
|| PCAP_IS_AT_LEAST_HP_C_VERSION(6,10) || 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?), * and later (do any earlier versions of XL C support this?),
* or HP aCC A.06.10 and later. * or HP aCC A.06.10 and later.
*/ */
@ -216,7 +218,7 @@
|| PCAP_IS_AT_LEAST_SUNC_VERSION(5,13) || PCAP_IS_AT_LEAST_SUNC_VERSION(5,13)
/* /*
* Compiler that supports __has_attribute and __attribute__((deprecated)), * 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 * Those support __attribute__((deprecated(msg))) (we assume, perhaps
* incorrectly, that anything that supports __has_attribute() is * incorrectly, that anything that supports __has_attribute() is

View File

@ -32,7 +32,7 @@
/* /*
* Structure of an NFLOG header and TLV parts, as described at * 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. * The NFLOG header is big-endian.
* *

View File

@ -106,12 +106,23 @@
#define PRIu64 "llu" #define PRIu64 "llu"
#endif #endif
#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) #elif defined(__MINGW32__) || !defined(_WIN32)
/* /*
* Compiler is MinGW or target is UN*X or MS-DOS. Just use * Compiler is MinGW or target is UN*X or MS-DOS. Just use
* <inttypes.h>. * <inttypes.h>.
*/ */
#include <inttypes.h> #include <inttypes.h>
/*
* Assume the support library supports %zu; it's required by C99.
*/
#define PRIsize "zu"
#endif #endif
#endif /* pcap/pcap-inttypes.h */ #endif /* pcap/pcap-inttypes.h */

View File

@ -84,6 +84,7 @@
#include <sys/time.h> #include <sys/time.h>
#endif /* _WIN32/MSDOS/UN*X */ #endif /* _WIN32/MSDOS/UN*X */
#include <pcap/socket.h> /* for SOCKET, as the active-mode rpcap APIs use it */
#include <net/bpf.h> #include <net/bpf.h>
#include <stdio.h> #include <stdio.h>
@ -346,7 +347,7 @@ PCAP_API const char *pcap_tstamp_type_val_to_name(int);
PCAP_API const char *pcap_tstamp_type_val_to_description(int); PCAP_API const char *pcap_tstamp_type_val_to_description(int);
#ifdef __linux__ #ifdef __linux__
PCAP_API int pcap_set_protocol(pcap_t *, int); PCAP_API int pcap_set_protocol_linux(pcap_t *, int);
#endif #endif
/* /*
@ -466,6 +467,7 @@ PCAP_API void pcap_free_datalinks(int *);
PCAP_API int pcap_datalink_name_to_val(const char *); 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_name(int);
PCAP_API const char *pcap_datalink_val_to_description(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_snapshot(pcap_t *);
PCAP_API int pcap_is_swapped(pcap_t *); PCAP_API int pcap_is_swapped(pcap_t *);
PCAP_API int pcap_major_version(pcap_t *); PCAP_API int pcap_major_version(pcap_t *);
@ -481,7 +483,28 @@ PCAP_API int pcap_fileno(pcap_t *);
#endif #endif
PCAP_API pcap_dumper_t *pcap_dump_open(pcap_t *, const char *); 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 pcap_dumper_t *pcap_dump_open_append(pcap_t *, const char *);
PCAP_API FILE *pcap_dump_file(pcap_dumper_t *); PCAP_API FILE *pcap_dump_file(pcap_dumper_t *);
PCAP_API long pcap_dump_ftell(pcap_dumper_t *); PCAP_API long pcap_dump_ftell(pcap_dumper_t *);
@ -857,8 +880,8 @@ PCAP_API int pcap_parsesrcstr(const char *source, int *type, char *host,
* For listing remote capture devices, pcap_findalldevs_ex() is currently * For listing remote capture devices, pcap_findalldevs_ex() is currently
* the only API available. * the only API available.
*/ */
PCAP_API int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, PCAP_API int pcap_findalldevs_ex(const char *source,
pcap_if_t **alldevs, char *errbuf); struct pcap_rmtauth *auth, pcap_if_t **alldevs, char *errbuf);
/* /*
* Sampling methods. * Sampling methods.
@ -936,27 +959,6 @@ PCAP_API struct pcap_samp *pcap_setsampling(pcap_t *p);
/* Maximum length of an host name (needed for the RPCAP active mode) */ /* Maximum length of an host name (needed for the RPCAP active mode) */
#define RPCAP_HOSTLIST_SIZE 1024 #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, PCAP_API SOCKET pcap_remoteact_accept(const char *address, const char *port,
const char *hostlist, char *connectinghost, const char *hostlist, char *connectinghost,
struct pcap_rmtauth *auth, char *errbuf); struct pcap_rmtauth *auth, char *errbuf);

View File

@ -74,14 +74,14 @@
#ifndef lib_pcap_sll_h #ifndef lib_pcap_sll_h
#define lib_pcap_sll_h #define lib_pcap_sll_h
#include <pcap/pcap-inttypes.h>
/* /*
* A DLT_LINUX_SLL fake link-layer header. * A DLT_LINUX_SLL fake link-layer header.
*/ */
#define SLL_HDR_LEN 16 /* total header length */ #define SLL_HDR_LEN 16 /* total header length */
#define SLL_ADDRLEN 8 /* length of address field */ #define SLL_ADDRLEN 8 /* length of address field */
#include <pcap/pcap-inttypes.h>
struct sll_header { struct sll_header {
uint16_t sll_pkttype; /* packet type */ uint16_t sll_pkttype; /* packet type */
uint16_t sll_hatype; /* link-layer address type */ uint16_t sll_hatype; /* link-layer address type */
@ -91,10 +91,27 @@ struct sll_header {
}; };
/* /*
* The LINUX_SLL_ values for "sll_pkttype"; these correspond to the * A DLT_LINUX_SLL2 fake link-layer header.
* PACKET_ values on Linux, but are defined here so that they're */
* available even on systems other than Linux, and so that they #define SLL2_HDR_LEN 20 /* total header length */
* don't change even if the PACKET_ values change.
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_HOST 0
#define LINUX_SLL_BROADCAST 1 #define LINUX_SLL_BROADCAST 1
@ -103,10 +120,11 @@ struct sll_header {
#define LINUX_SLL_OUTGOING 4 #define LINUX_SLL_OUTGOING 4
/* /*
* The LINUX_SLL_ values for "sll_protocol"; these correspond to the * The LINUX_SLL_ values for "sll_protocol" and LINUX_SLL2_ values for
* ETH_P_ values on Linux, but are defined here so that they're * "sll2_protocol"; these correspond to the ETH_P_ values on Linux, but
* available even on systems other than Linux. We assume, for now, * are defined here so that they're available even on systems other than
* that the ETH_P_ values won't change in Linux; if they do, then: * 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 * if we don't translate them in "pcap-linux.c", capture files
* won't necessarily be readable if captured on a system that * won't necessarily be readable if captured on a system that

View 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 */

View File

@ -17,7 +17,7 @@
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF .\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\" .\"
.TH PCAP_ACTIVATE 3PCAP "7 April 2014" .TH PCAP_ACTIVATE 3PCAP "31 July 2016"
.SH NAME .SH NAME
pcap_activate \- activate a capture handle pcap_activate \- activate a capture handle
.SH SYNOPSIS .SH SYNOPSIS
@ -50,15 +50,15 @@ promiscuous mode.
.TP .TP
.B PCAP_WARNING_TSTAMP_TYPE_NOTSUP .B PCAP_WARNING_TSTAMP_TYPE_NOTSUP
The time stamp type specified in a previous 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 call isn't supported by the capture source (the time stamp type is
left as the default), left as the default),
.TP .TP
.B PCAP_WARNING .B PCAP_WARNING
Another warning condition occurred; Another warning condition occurred;
.B pcap_geterr() .B pcap_geterr(3PCAP)
or or
.B pcap_perror() .B pcap_perror(3PCAP)
may be called with may be called with
.I p .I p
as an argument to fetch or display a message describing the warning 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 should check for positive, negative, and zero return codes, and treat
all positive return codes as warnings and all negative return all positive return codes as warnings and all negative return
codes as errors. 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 can be called, with a warning or error code as an argument, to fetch a
message describing the warning or error code. message describing the warning or error code.
.SH SEE ALSO .SH SEE ALSO

View File

@ -17,7 +17,7 @@
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF .\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\" .\"
.TH PCAP_BREAKLOOP 3PCAP "8 March 2015" .TH PCAP_BREAKLOOP 3PCAP "25 July 2018"
.SH NAME .SH NAME
pcap_breakloop \- force a pcap_dispatch() or pcap_loop() call to return pcap_breakloop \- force a pcap_dispatch() or pcap_loop() call to return
.SH SYNOPSIS .SH SYNOPSIS
@ -33,12 +33,13 @@ void pcap_breakloop(pcap_t *);
.SH DESCRIPTION .SH DESCRIPTION
.B pcap_breakloop() .B pcap_breakloop()
sets a flag that will force sets a flag that will force
.B pcap_dispatch() .B pcap_dispatch(3PCAP)
or or
.B pcap_loop() .B pcap_loop(3PCAP)
to return rather than looping; they will return the number of packets 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 that have been processed so far, or
processed so far. .B PCAP_ERROR_BREAK
if no packets have been processed so far.
.PP .PP
This routine is safe to use inside a signal handler on UNIX or a console 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 control handler on Windows, as it merely sets a flag that is checked
@ -60,7 +61,7 @@ packets arrive and the call completes.
.PP .PP
.ft B .ft B
Note also that, in a multi-threaded application, if one thread is 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 a call to pcap_breakloop() in a different thread will not unblock that
thread. thread.
.ft R .ft R
@ -99,12 +100,16 @@ or
.B pcap_loop() .B pcap_loop()
after it is called; at most one more packet might be processed. after it is called; at most one more packet might be processed.
.PP .PP
If \-2 is returned from If
.B PCAP_ERROR_BREAK
is returned from
.B pcap_dispatch() .B pcap_dispatch()
or or
.BR pcap_loop() , .BR pcap_loop() ,
the flag is cleared, so a subsequent call will resume reading packets. 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 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 .SH SEE ALSO
pcap(3PCAP), pcap_loop(3PCAP), pcap_next_ex(3PCAP) pcap(3PCAP)

View File

@ -17,7 +17,7 @@
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF .\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\" .\"
.TH PCAP_CAN_SET_RFMON 3PCAP "3 January 2014" .TH PCAP_CAN_SET_RFMON 3PCAP "31 July 2016"
.SH NAME .SH NAME
pcap_can_set_rfmon \- check whether monitor mode can be set for a pcap_can_set_rfmon \- check whether monitor mode can be set for a
not-yet-activated capture handle not-yet-activated capture handle
@ -54,9 +54,9 @@ The capture handle has already been activated.
.TP .TP
.B PCAP_ERROR .B PCAP_ERROR
Another error occurred. Another error occurred.
.B pcap_geterr() .B pcap_geterr(3PCAP)
or or
.B pcap_perror() .B \%pcap_perror(3PCAP)
may be called with may be called with
.I p .I p
as an argument to fetch or display a message describing the error. 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 Additional error codes may be added in the future; a program should
check for 0, 1, and negative, return codes, and treat all negative check for 0, 1, and negative, return codes, and treat all negative
return codes as errors. 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 can be called, with a warning or error code as an argument, to fetch a
message describing the warning or error code. message describing the warning or error code.
.SH SEE ALSO .SH SEE ALSO

View File

@ -17,7 +17,7 @@
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF .\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\" .\"
.TH PCAP_COMPILE 3PCAP "7 April 2014" .TH PCAP_COMPILE 3PCAP "22 August 2018"
.SH NAME .SH NAME
pcap_compile \- compile a filter expression pcap_compile \- compile a filter expression
.SH SYNOPSIS .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 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 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 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 for IPv4 broadcast addresses will fail to compile, but all other tests in
the filter program will be OK. the filter program will be OK.
.LP .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. exclusion allowing only one thread to call it at any given time.
.SH RETURN VALUE .SH RETURN VALUE
.B pcap_compile() .B pcap_compile()
returns 0 on success and \-1 on failure. returns 0 on success and
If \-1 is returned, .B PCAP_ERROR
.B pcap_geterr() on failure. If
.B PCAP_ERROR
is returned,
.B pcap_geterr(3PCAP)
or or
.B pcap_perror() .B pcap_perror(3PCAP)
may be called with may be called with
.I p .I p
as an argument to fetch or display the error text. 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 .SH SEE ALSO
pcap(3PCAP), pcap_setfilter(3PCAP), pcap_freecode(3PCAP), pcap(3PCAP), pcap_setfilter(3PCAP), pcap_freecode(3PCAP),
pcap_geterr(3PCAP), pcap-filter(@MAN_MISC_INFO@)

View File

@ -48,7 +48,7 @@ argument of "any" or
can be used to capture packets from all interfaces. can be used to capture packets from all interfaces.
.PP .PP
The returned handle must be activated with The returned handle must be activated with
.B pcap_activate() .B pcap_activate(3PCAP)
before packets can be captured before packets can be captured
with it; options for the capture, such as promiscuous mode, can be set with it; options for the capture, such as promiscuous mode, can be set
on the handle before activating it. on the handle before activating it.
@ -69,4 +69,4 @@ is assumed to be able to hold at least
.B PCAP_ERRBUF_SIZE .B PCAP_ERRBUF_SIZE
chars. chars.
.SH SEE ALSO .SH SEE ALSO
pcap(3PCAP), pcap_activate(3PCAP) pcap(3PCAP)

View File

@ -37,11 +37,11 @@ specified by
.IR p . .IR p .
.PP .PP
It must not be called on a pcap descriptor created by 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 that has not yet been activated by
.BR pcap_activate() . .BR \%pcap_activate(3PCAP) .
.PP .PP
.I http://www.tcpdump.org/linktypes.html .I https://www.tcpdump.org/linktypes.html
lists the values lists the values
.B pcap_datalink() .B pcap_datalink()
can return and describes the packet formats that can return and describes the packet formats that

View File

@ -17,7 +17,7 @@
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF .\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\" .\"
.TH PCAP_DATALINK_NAME_TO_VAL 3PCAP "5 December 2014" .TH PCAP_DATALINK_NAME_TO_VAL 3PCAP "25 July 2018"
.SH NAME .SH NAME
pcap_datalink_name_to_val \- get the link-layer header type value pcap_datalink_name_to_val \- get the link-layer header type value
corresponding to a header type name corresponding to a header type name
@ -41,7 +41,9 @@ removed, to the corresponding link-layer header type value. The
translation is case-insensitive. translation is case-insensitive.
.SH RETURN VALUE .SH RETURN VALUE
.B pcap_datalink_name_to_val() .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.. type name..
.SH SEE ALSO .SH SEE ALSO
pcap(3PCAP) pcap(3PCAP)

View File

@ -17,9 +17,10 @@
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF .\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\" .\"
.TH PCAP_DATALINK_VAL_TO_NAME 3PCAP "3 January 2014" .TH PCAP_DATALINK_VAL_TO_NAME 3PCAP "12 October 2016"
.SH NAME .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 name or description for a link-layer header type value
.SH SYNOPSIS .SH SYNOPSIS
.nf .nf
@ -30,6 +31,7 @@ name or description for a link-layer header type value
.ft B .ft B
const char *pcap_datalink_val_to_name(int dlt); 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(int dlt);
const char *pcap_datalink_val_to_description_or_dlt(int dlt);
.ft .ft
.fi .fi
.SH DESCRIPTION .SH DESCRIPTION
@ -52,3 +54,13 @@ link-layer header type.
is returned if the type value does not correspond to a known is returned if the type value does not correspond to a known
.B DLT_ .B DLT_
value. 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)

View File

@ -35,11 +35,11 @@ u_char *sp);
.SH DESCRIPTION .SH DESCRIPTION
.B pcap_dump() .B pcap_dump()
outputs a packet to the ``savefile'' opened with 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 Note that its calling arguments are suitable for use with
.B pcap_dispatch() .B pcap_dispatch(3PCAP)
or or
.BR pcap_loop() . .BR pcap_loop(3PCAP) .
If called directly, the If called directly, the
.I user .I user
parameter is of type parameter is of type
@ -47,5 +47,4 @@ parameter is of type
as returned by as returned by
.BR pcap_dump_open() . .BR pcap_dump_open() .
.SH SEE ALSO .SH SEE ALSO
pcap(3PCAP), pcap_dump_open(3PCAP), pcap_dispatch(3PCAP), pcap(3PCAP)
pcap_loop(3PCAP)

View File

@ -33,6 +33,6 @@ FILE *pcap_dump_file(pcap_dumper_t *p);
.SH DESCRIPTION .SH DESCRIPTION
.B pcap_dump_file() .B pcap_dump_file()
returns the standard I/O stream of the ``savefile'' opened by returns the standard I/O stream of the ``savefile'' opened by
.BR pcap_dump_open() . .BR pcap_dump_open(3PCAP) .
.SH SEE ALSO .SH SEE ALSO
pcap(3PCAP) pcap(3PCAP)

View File

@ -17,7 +17,7 @@
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF .\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\" .\"
.TH PCAP_DUMP_FLUSH 3PCAP "3 January 2014" .TH PCAP_DUMP_FLUSH 3PCAP "25 July 2018"
.SH NAME .SH NAME
pcap_dump_flush \- flush to a savefile packets dumped pcap_dump_flush \- flush to a savefile packets dumped
.SH SYNOPSIS .SH SYNOPSIS
@ -34,10 +34,12 @@ int pcap_dump_flush(pcap_dumper_t *p);
.B pcap_dump_flush() .B pcap_dump_flush()
flushes the output buffer to the ``savefile,'' so that any packets flushes the output buffer to the ``savefile,'' so that any packets
written with written with
.B pcap_dump() .B pcap_dump(3PCAP)
but not yet written to the ``savefile'' will be written. but not yet written to the ``savefile'' will be written.
.SH RETURN VALUE .SH RETURN VALUE
.B pcap_dump_flush() .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 .SH SEE ALSO
pcap(3PCAP), pcap_dump_open(3PCAP), pcap_dump(3PCAP) pcap(3PCAP), pcap_dump_open(3PCAP)

View File

@ -17,7 +17,7 @@
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF .\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\" .\"
.TH PCAP_DUMP_FTELL 3PCAP "3 January 2014" .TH PCAP_DUMP_FTELL 3PCAP "25 July 2018"
.SH NAME .SH NAME
pcap_dump_ftell, pcap_dump_ftell64 \- get the current file offset for a savefile being written pcap_dump_ftell, pcap_dump_ftell64 \- get the current file offset for a savefile being written
.SH SYNOPSIS .SH SYNOPSIS
@ -36,11 +36,11 @@ int64_t pcap_dump_ftell64(pcap_dumper_t *p);
.B pcap_dump_ftell() .B pcap_dump_ftell()
returns the current file position for the ``savefile'', representing the returns the current file position for the ``savefile'', representing the
number of bytes written by number of bytes written by
.B pcap_dump_open() .B pcap_dump_open(3PCAP)
and and
.BR pcap_dump() . .BR pcap_dump(3PCAP) .
\-1 is returned on error. .B PCAP_ERROR
If the current file position does not fit in a is returned on error. If the current file position does not fit in a
.BR long , .BR long ,
it will be truncated; this can happen on 32-bit UNIX-like systems with it will be truncated; this can happen on 32-bit UNIX-like systems with
large file support and on Windows. 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 but that fit in a
.B int64_t .B int64_t
are supported, this will return the file offset without truncation. 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 .SH SEE ALSO
pcap(3PCAP), pcap_dump_open(3PCAP), pcap_dump(3PCAP) pcap(3PCAP)

View File

@ -17,7 +17,7 @@
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF .\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\" .\"
.TH PCAP_DUMP_OPEN 3PCAP "16 February 2015" .TH PCAP_DUMP_OPEN 3PCAP "22 August 2018"
.SH NAME .SH NAME
pcap_dump_open, pcap_dump_fopen \- open a file to which to write packets pcap_dump_open, pcap_dump_fopen \- open a file to which to write packets
.SH SYNOPSIS .SH SYNOPSIS
@ -48,26 +48,28 @@ for
.PP .PP
.B pcap_dump_fopen() .B pcap_dump_fopen()
is called to write data to an existing open stream 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. Note that on Windows, that stream should be opened in binary mode.
.PP .PP
.I p .I p
is a capture or ``savefile'' handle returned by an earlier call to 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 and activated by an earlier call to
.BR pcap_activate() , .BR \%pcap_activate(3PCAP) ,
or returned by an earlier call to or returned by an earlier call to
.BR pcap_open_offline() , .BR \%pcap_open_offline(3PCAP) ,
.BR pcap_open_live() , .BR pcap_open_live(3PCAP) ,
or or
.BR pcap_open_dead() . .BR pcap_open_dead(3PCAP) .
The time stamp precision, link-layer type, and snapshot length from The time stamp precision, link-layer type, and snapshot length from
.I p .I p
are used as the link-layer type and snapshot length of the output file. are used as the link-layer type and snapshot length of the output file.
.PP .PP
.B pcap_dump_open_append() .B pcap_dump_open_append()
is like 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 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 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 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 A pointer to a
.B pcap_dumper_t .B pcap_dumper_t
structure to use in subsequent structure to use in subsequent
.B pcap_dump() .B pcap_dump(3PCAP)
and and
.B pcap_dump_close() .B pcap_dump_close(3PCAP)
calls is returned on success. calls is returned on success.
.B NULL .B NULL
is returned on failure. is returned on failure.
If If
.B NULL .B NULL
is returned, is returned,
.B pcap_geterr(\fIp\fB) .B pcap_geterr(3PCAP)
can be used to get the error text. 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 .SH SEE ALSO
pcap(3PCAP), pcap_create(3PCAP), pcap_activate(3PCAP), pcap(3PCAP),
\%pcap_open_offline(3PCAP), pcap_open_live(3PCAP), pcap_open_dead(3PCAP),
pcap_dump(3PCAP), pcap_dump_close(3PCAP), pcap_geterr(3PCAP),
\%pcap-savefile(@MAN_FILE_FORMATS@) \%pcap-savefile(@MAN_FILE_FORMATS@)

View File

@ -34,13 +34,15 @@ FILE *pcap_file(pcap_t *p);
.B pcap_file() .B pcap_file()
returns the standard I/O stream of the ``savefile,'' if a ``savefile'' returns the standard I/O stream of the ``savefile,'' if a ``savefile''
was opened with was opened with
.BR pcap_open_offline() , .BR pcap_open_offline(3PCAP) ,
or NULL, if a network device was opened with or
.B pcap_create() .BR NULL ,
if a network device was opened with
.B pcap_create(3PCAP)
and and
.BR pcap_activate() , .BR \%pcap_activate(3PCAP) ,
or with or with
.BR pcap_open_live() . .BR pcap_open_live(3PCAP) .
.PP .PP
Note that the Packet Capture library is usually built with large file 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 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 value of
.B pcap_file() .B pcap_file()
or the value returned by or the value returned by
.B fileno() .B fileno(3)
when passed the return value of when passed the return value of
.BR pcap_file() . .BR pcap_file() .
.SH SEE ALSO .SH SEE ALSO
pcap(3PCAP), pcap_open_offline(3PCAP) pcap(3PCAP)

View File

@ -17,7 +17,7 @@
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF .\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\" .\"
.TH PCAP_FILENO 3PCAP "7 April 2014" .TH PCAP_FILENO 3PCAP "25 July 2018"
.SH NAME .SH NAME
pcap_fileno \- get the file descriptor for a live capture pcap_fileno \- get the file descriptor for a live capture
.SH SYNOPSIS .SH SYNOPSIS
@ -35,32 +35,31 @@ If
.I p .I p
refers to a network device that was opened for a live capture using refers to a network device that was opened for a live capture using
a combination of a combination of
.B pcap_create() .B pcap_create(3PCAP)
and and
.BR pcap_activate() , .BR pcap_activate(3PCAP) ,
or using or using
.BR pcap_open_live() , .BR pcap_open_live(3PCAP) ,
.B pcap_fileno() .B pcap_fileno()
returns the file descriptor from which captured packets are read. returns the file descriptor from which captured packets are read.
.LP .LP
If If
.I p .I p
refers to a ``savefile'' that was opened using functions such as refers to a ``savefile'' that was opened using functions such as
.BR pcap_open_offline() .BR pcap_open_offline(3PCAP)
or or
.BR pcap_fopen_offline() , .BR pcap_fopen_offline(3PCAP) ,
a ``dead'' a ``dead''
.B pcap_t .B pcap_t
opened using opened using
.BR pcap_open_dead() , .BR pcap_open_dead(3PCAP) ,
or a or a
.B pcap_t .B pcap_t
that was created with that was created with
.B pcap_create() .B pcap_create()
but that has not yet been activated with but that has not yet been activated with
.BR pcap_activate() , .BR pcap_activate() ,
it returns \-1. it returns
.BR PCAP_ERROR .
.SH SEE ALSO .SH SEE ALSO
pcap(3PCAP), pcap_create(3PCAP), pcap_activate(3PCAP), pcap(3PCAP)
pcap_open_live(3PCAP), pcap_open_offline(3PCAP),
\%pcap_fopen_offline(3PCAP), pcap_open_dead(3PCAP)

View File

@ -17,7 +17,7 @@
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF .\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\" .\"
.TH PCAP_FINDALLDEVS 3PCAP "7 April 2014" .TH PCAP_FINDALLDEVS 3PCAP "22 August 2018"
.SH NAME .SH NAME
pcap_findalldevs, pcap_freealldevs \- get a list of capture devices, and pcap_findalldevs, pcap_freealldevs \- get a list of capture devices, and
free that list free that list
@ -40,11 +40,11 @@ void pcap_freealldevs(pcap_if_t *alldevs);
.SH DESCRIPTION .SH DESCRIPTION
.B pcap_findalldevs() .B pcap_findalldevs()
constructs a list of network devices that can be opened with constructs a list of network devices that can be opened with
.B pcap_create() .B pcap_create(3PCAP)
and and
.B pcap_activate() .B pcap_activate(3PCAP)
or with or with
.BR pcap_open_live() . .BR pcap_open_live(3PCAP) .
(Note that there may be network devices that cannot be opened by the (Note that there may be network devices that cannot be opened by the
process calling process calling
.BR pcap_findalldevs() , .BR pcap_findalldevs() ,
@ -194,21 +194,38 @@ for IPv6 addresses, it can be interpreted as if it pointed to a
.BR "struct sockaddr_in6". .BR "struct sockaddr_in6".
.PP .PP
The list of devices must be freed with The list of devices must be freed with
.BR pcap_freealldevs() , .BR pcap_freealldevs(3PCAP) ,
which frees the list pointed to by which frees the list pointed to by
.IR alldevs . .IR alldevs .
.SH RETURN VALUE .SH RETURN VALUE
.B pcap_findalldevs() .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 devices is considered success, rather than failure, so 0 will be
returned in that case. returned in that case. If
If \-1 is returned, .B PCAP_ERROR
is returned,
.I errbuf .I errbuf
is filled in with an appropriate error message. is filled in with an appropriate error message.
.I errbuf .I errbuf
is assumed to be able to hold at least is assumed to be able to hold at least
.B PCAP_ERRBUF_SIZE .B PCAP_ERRBUF_SIZE
chars. 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 .SH SEE ALSO
pcap(3PCAP), pcap_create(3PCAP), pcap_activate(3PCAP), pcap(3PCAP)
pcap_open_live(3PCAP)

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