mirror of
https://github.com/nmap/nmap.git
synced 2025-12-06 04:31:29 +00:00
Update to libpcap 1.9.1 (initial commit, no Nmap-specific patches)
This commit is contained in:
@@ -1,3 +1,75 @@
|
||||
Sunday, July 22, 2018
|
||||
Summary for 1.9.1 libpcap release
|
||||
Mention pcap_get_required_select_timeout() in the main pcap man page
|
||||
Fix pcap-usb-linux.c build on systems with musl
|
||||
Fix assorted man page and other documentation issues
|
||||
Plug assorted memory leaks
|
||||
Documentation changes to use https:
|
||||
Changes to how time stamp calculations are done
|
||||
Lots of tweaks to make newer compilers happier and warning-free and
|
||||
to fix instances of C undefined behavior
|
||||
Warn if AC_PROG_CC_C99 can't enable C99 support
|
||||
Rename pcap_set_protocol() to pcap_set_protocol_linux().
|
||||
Align pcap_t private data on an 8-byte boundary.
|
||||
Fix various error messages
|
||||
Use 64-bit clean API in dag_findalldevs()
|
||||
Fix cleaning up after some errors
|
||||
Work around some ethtool ioctl bugs in newer Linux kernels (GitHub
|
||||
issue #689)
|
||||
Add backwards compatibility sections to some man pages (GitHub issue
|
||||
#745)
|
||||
Fix autotool configuration on AIX and macOS
|
||||
Don't export bpf_filter_with_aux_data() or struct bpf_aux_data;
|
||||
they're internal-only and subject to change
|
||||
Fix pcapng block size checking
|
||||
On macOS, don't build rpcapd or test programs any fatter than they
|
||||
need to be
|
||||
Fix reading of capture statistics for Linux USB
|
||||
Fix packet size values for Linux USB packets (GitHub issue #808)
|
||||
Check only VID in VLAN test in filterss (GitHub issue #461)
|
||||
Fix pcap_list_datalinks on 802.11 devices on macOS
|
||||
Fix overflows with very large snapshot length in pcap file
|
||||
Improve parsing of rpcapd configuration file (GitHub issue #767)
|
||||
Handle systems without strlcpy() or strlcat() better
|
||||
Fix crashes and other errors with invalid filter expressions
|
||||
Fix use of uninitialized file descriptor in remote capture
|
||||
Fix some CMake issues
|
||||
Fix some divide-by-zero issues with the filter compiler
|
||||
Work around a GNU libc bug in pcap_nametonetaddr()
|
||||
Add support for DLT_LINUX_SLL2
|
||||
Fix handling of the packet-count argument for Myricom SNF devices
|
||||
Fix --disable-rdma in configure script (GitHub issue #782)
|
||||
Fix compilation of TurboCap support (GitHub issue #764)
|
||||
Constify first argument to pcap_findalldevs_ex()
|
||||
Fix a number of issues when running rpcapd as an inetd-style daemon
|
||||
Fix CMake issues with D-Bus libraries
|
||||
In rpcapd, clean up termination of a capture session
|
||||
Redo remote capture protocol negotiation
|
||||
In rpcapd, report the same error for "invalid user name" and
|
||||
"invalid password", to make brute-forcing harder
|
||||
For remote captures, add an error code for "the server requires TLS"
|
||||
Fix pcap_dump_fopen() on Windows to avoid clashes between
|
||||
{Win,N}Pcap and application C runtimes
|
||||
Fix exporting of functions from Windows DLLs (GitHub issue #810)
|
||||
Fix building as part of Npcap
|
||||
Allow rpcapd to rebind more rapidly
|
||||
Fix building shared libpcap library on midipix (midipix.org)
|
||||
Fix hack to detect UTF-16LE adapter names on Windows not to go past
|
||||
the end of the string
|
||||
Fix handling of "wireless WAN" (mobile phone network modems) on
|
||||
Windows with WinPcap/Npcap (GitHub issue #824)
|
||||
Have pcap_dump_open_append() create the dump file if it doesn't
|
||||
exists (GitHub issue #247)
|
||||
Fix the maxmum snapshot length for DLT_USBPCAP
|
||||
Use -fPIC when building for 64-bit SPARC on Linux (GitHub issue #837)
|
||||
Fix CMake 64-bit library installation directory on some Linux
|
||||
distributions
|
||||
Boost the TPACKET_V3 timeout to the maximum if a timeout of 0 was
|
||||
specified
|
||||
Five CVE-2019-15161, CVE-2019-15162, CVE-2019-15163, CVE-2019-15164, CVE-2019-15165
|
||||
Fixes for CVE-2018-16301, errors in pcapng reading.
|
||||
PCAPNG reader applies some sanity checks before doing malloc().
|
||||
|
||||
Sunday, June 24, 2018, by mcr@sandelman.ca
|
||||
Summary for 1.9.0 libpcap release
|
||||
Added testing system to libpcap, independent of tcpdump
|
||||
|
||||
@@ -9,7 +9,7 @@ if(POLICY CMP0042)
|
||||
cmake_policy(SET CMP0042 OLD)
|
||||
endif()
|
||||
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/Modules)
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules)
|
||||
|
||||
project(pcap)
|
||||
|
||||
@@ -135,83 +135,6 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
option(BUILD_WITH_LIBNL "Build with libnl" ON)
|
||||
endif()
|
||||
|
||||
#
|
||||
# By default, build universal with the appropriate set of architectures
|
||||
# for the OS on which we're doing the build.
|
||||
#
|
||||
if(APPLE AND "${CMAKE_OSX_ARCHITECTURES}" STREQUAL "")
|
||||
#
|
||||
# Get the major version of Darwin.
|
||||
#
|
||||
string(REGEX MATCH "^([0-9]+)" SYSTEM_VERSION_MAJOR "${CMAKE_SYSTEM_VERSION}")
|
||||
|
||||
if(SYSTEM_VERSION_MAJOR LESS 8)
|
||||
#
|
||||
# Pre-Tiger. Build only for 32-bit PowerPC.
|
||||
#
|
||||
set(CMAKE_OSX_ARCHITECTURES "ppc")
|
||||
elseif(SYSTEM_VERSION_MAJOR EQUAL 8)
|
||||
#
|
||||
# Tiger. Is this prior to, or with, Intel support?
|
||||
#
|
||||
# Get the minor version of Darwin.
|
||||
#
|
||||
string(REPLACE "${SYSTEM_VERSION_MAJOR}." "" SYSTEM_MINOR_AND_PATCH_VERSION ${CMAKE_SYSTEM_VERSION})
|
||||
string(REGEX MATCH "^([0-9]+)" SYSTEM_VERSION_MINOR "${SYSTEM_MINOR_AND_PATCH_VERSION}")
|
||||
if(SYSTEM_VERSION_MINOR LESS 4)
|
||||
#
|
||||
# Prior to Intel support. Build for 32-bit
|
||||
# PowerPC and 64-bit PowerPC, with 32-bit PowerPC
|
||||
# first. (I'm guessing that's what Apple does.)
|
||||
#
|
||||
set(CMAKE_OSX_ARCHITECTURES "ppc;ppc64")
|
||||
elseif(SYSTEM_VERSION_MINOR LESS 7)
|
||||
#
|
||||
# With Intel support but prior to x86-64 support.
|
||||
# Build for 32-bit PowerPC, 64-bit PowerPC, and x86,
|
||||
# with 32-bit PowerPC first.
|
||||
# (I'm guessing that's what Apple does.)
|
||||
#
|
||||
set(CMAKE_OSX_ARCHITECTURES "ppc;ppc64;i386")
|
||||
else()
|
||||
#
|
||||
# With Intel support including x86-64 support.
|
||||
# Build for 32-bit PowerPC, 64-bit PowerPC, x86,
|
||||
# and x86-64, with 32-bit PowerPC first.
|
||||
# (I'm guessing that's what Apple does.)
|
||||
#
|
||||
set(CMAKE_OSX_ARCHITECTURES "ppc;ppc64;i386;x86_64")
|
||||
endif()
|
||||
elseif(SYSTEM_VERSION_MAJOR EQUAL 9)
|
||||
#
|
||||
# Leopard. Build for 32-bit PowerPC, 64-bit
|
||||
# PowerPC, x86, and x86-64, with 32-bit PowerPC
|
||||
# first. (That's what Apple does.)
|
||||
#
|
||||
set(CMAKE_OSX_ARCHITECTURES "ppc;ppc64;i386;x86_64")
|
||||
elseif(SYSTEM_VERSION_MAJOR EQUAL 10)
|
||||
#
|
||||
# Snow Leopard. Build for x86-64, x86, and
|
||||
# 32-bit PowerPC, with x86-64 first. (That's
|
||||
# what Apple does, even though Snow Leopard
|
||||
# doesn't run on PPC, so PPC libpcap runs under
|
||||
# Rosetta, and Rosetta doesn't support BPF
|
||||
# ioctls, so PPC programs can't do live
|
||||
# captures.)
|
||||
#
|
||||
set(CMAKE_OSX_ARCHITECTURES "x86_64;i386;ppc")
|
||||
else()
|
||||
#
|
||||
# Post-Snow Leopard. Build for x86-64 and
|
||||
# x86, with x86-64 first. (That's probably what
|
||||
# Apple does, given that Rosetta is gone.)
|
||||
# XXX - update if and when Apple drops support
|
||||
# for 32-bit x86 code.
|
||||
#
|
||||
set(CMAKE_OSX_ARCHITECTURES "x86_64;i386")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
#
|
||||
# Additional capture modules.
|
||||
#
|
||||
@@ -233,7 +156,7 @@ option(DISABLE_RDMA "Disable RDMA sniffing support" OFF)
|
||||
option(DISABLE_DAG "Disable Endace DAG card support" OFF)
|
||||
|
||||
option(DISABLE_SEPTEL "Disable Septel card support" OFF)
|
||||
set(SEPTEL_ROOT "${CMAKE_SOURCE_DIR}/../septel" CACHE PATH "Path to directory with include and lib subdirectories for Septel API")
|
||||
set(SEPTEL_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/../septel" CACHE PATH "Path to directory with include and lib subdirectories for Septel API")
|
||||
|
||||
option(DISABLE_SNF "Disable Myricom SNF support" OFF)
|
||||
|
||||
@@ -289,6 +212,7 @@ include_directories(
|
||||
|
||||
include(CheckFunctionExists)
|
||||
include(CMakePushCheckState)
|
||||
include(CheckSymbolExists)
|
||||
|
||||
if(WIN32)
|
||||
|
||||
@@ -310,6 +234,14 @@ if(WIN32)
|
||||
cmake_pop_check_state()
|
||||
endif(PACKET_FOUND)
|
||||
|
||||
message(STATUS "checking for Npcap's version.h")
|
||||
check_symbol_exists(WINPCAP_PRODUCT_NAME "../../version.h" HAVE_VERSION_H)
|
||||
if(HAVE_VERSION_H)
|
||||
message(STATUS "HAVE version.h")
|
||||
else(HAVE_VERSION_H)
|
||||
message(STATUS "MISSING version.h")
|
||||
endif(HAVE_VERSION_H)
|
||||
|
||||
endif(WIN32)
|
||||
|
||||
if(MSVC)
|
||||
@@ -343,6 +275,11 @@ include(CheckIncludeFiles)
|
||||
include(CheckStructHasMember)
|
||||
include(CheckTypeSize)
|
||||
|
||||
#
|
||||
# Tests are a bit expensive with Visual Studio on Windows, so, on
|
||||
# Windows, we skip tests for UN*X-only headers and functions.
|
||||
#
|
||||
|
||||
#
|
||||
# Header files.
|
||||
#
|
||||
@@ -395,12 +332,44 @@ endif(NOT WIN32)
|
||||
#
|
||||
check_function_exists(strerror HAVE_STRERROR)
|
||||
check_function_exists(strerror_r HAVE_STRERROR_R)
|
||||
check_function_exists(strerror_s HAVE_STRERROR_S)
|
||||
if(HAVE_STRERROR_R)
|
||||
#
|
||||
# We have strerror_r; if we define _GNU_SOURCE, is it a
|
||||
# POSIX-compliant strerror_r() or a GNU strerror_r()?
|
||||
#
|
||||
check_c_source_compiles(
|
||||
"#define _GNU_SOURCE
|
||||
#include <string.h>
|
||||
|
||||
/* Define it GNU-style; that will cause an error if it's not GNU-style */
|
||||
extern char *strerror_r(int, char *, size_t);
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
"
|
||||
HAVE_GNU_STRERROR_R)
|
||||
if(NOT HAVE_GNU_STRERROR_R)
|
||||
set(HAVE_POSIX_STRERROR_R YES)
|
||||
endif(NOT HAVE_GNU_STRERROR_R)
|
||||
else(HAVE_STRERROR_R)
|
||||
#
|
||||
# We don't have strerror_r; do we have strerror_s?
|
||||
#
|
||||
check_function_exists(strerror_s HAVE_STRERROR_S)
|
||||
endif(HAVE_STRERROR_R)
|
||||
check_function_exists(strlcpy HAVE_STRLCPY)
|
||||
check_function_exists(strlcat HAVE_STRLCAT)
|
||||
check_function_exists(snprintf HAVE_SNPRINTF)
|
||||
check_function_exists(vsnprintf HAVE_VSNPRINTF)
|
||||
check_function_exists(asprintf HAVE_ASPRINTF)
|
||||
check_function_exists(vasprintf HAVE_VASPRINTF)
|
||||
check_function_exists(strtok_r HAVE_STRTOK_R)
|
||||
if(NOT WIN32)
|
||||
check_function_exists(vsyslog HAVE_VSYSLOG)
|
||||
endif()
|
||||
|
||||
#
|
||||
# These tests are for network applications that need socket functions
|
||||
@@ -429,7 +398,6 @@ check_function_exists(strtok_r HAVE_STRTOK_R)
|
||||
#
|
||||
set(PCAP_LINK_LIBRARIES "")
|
||||
include(CheckLibraryExists)
|
||||
include(CheckSymbolExists)
|
||||
if(WIN32)
|
||||
#
|
||||
# We need winsock2.h and ws2tcpip.h.
|
||||
@@ -865,11 +833,61 @@ set(PROJECT_SOURCE_LIST_C
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} missing/win_snprintf.c)
|
||||
#
|
||||
# For now, we assume we don't have snprintf() or that it's not one
|
||||
# that behaves enough like C99's snprintf() for our purposes (i.e.,
|
||||
# it doesn't null-terminate the string if it truncates it to fit in
|
||||
# the buffer), so we have to provide our own (a wrapper around
|
||||
# _snprintf() that null-terminates the buffer).
|
||||
#
|
||||
# We also assume we don't have asprintf(), and provide an implementation
|
||||
# that uses _vscprintf() to determine how big the string needs to be.
|
||||
#
|
||||
set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C}
|
||||
missing/win_snprintf.c missing/win_asprintf.c)
|
||||
else()
|
||||
#
|
||||
# Either:
|
||||
#
|
||||
# we have snprintf() and vsnprintf(), and have asprintf() and
|
||||
# vasprintf();
|
||||
#
|
||||
# we have snprintf() and vsnprintf(), but don't have asprintf()
|
||||
# or vasprintf();
|
||||
#
|
||||
# we have neither snprintf() nor vsnprintf(), and don't have
|
||||
# asprintf() or vasprintf(), either.
|
||||
#
|
||||
# We assume that if we have asprintf() we have vasprintf(), as well
|
||||
# as snprintf() and vsnprintf(), and that if we have snprintf() we
|
||||
# have vsnprintf().
|
||||
#
|
||||
# For the first case, we don't need any replacement routines.
|
||||
# For the second case, we need replacement asprintf()/vasprintf()
|
||||
# routines.
|
||||
# For the third case, we need replacement snprintf()/vsnprintf() and
|
||||
# asprintf()/vasprintf() routines.
|
||||
#
|
||||
if(NOT HAVE_SNPRINTF)
|
||||
#
|
||||
# We assume we have none of them; missing/snprintf.c supplies
|
||||
# all of them.
|
||||
#
|
||||
set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} missing/snprintf.c)
|
||||
endif(NOT HAVE_SNPRINTF)
|
||||
elif(NOT HAVE_ASPRINTF)
|
||||
#
|
||||
# We assume we have snprintf()/vsnprintf() but lack
|
||||
# asprintf()/vasprintf(); missing/asprintf.c supplies
|
||||
# the latter (using vsnprintf()).
|
||||
#
|
||||
set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} missing/asprintf.c)
|
||||
endif()
|
||||
if(NOT HAVE_STRLCAT)
|
||||
set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} missing/strlcat.c)
|
||||
endif(NOT HAVE_STRLCAT)
|
||||
if(NOT HAVE_STRLCPY)
|
||||
set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} missing/strlcpy.c)
|
||||
endif(NOT HAVE_STRLCPY)
|
||||
if(NOT HAVE_STRTOK_R)
|
||||
set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} missing/strtok_r.c)
|
||||
endif(NOT HAVE_STRTOK_R)
|
||||
@@ -931,13 +949,16 @@ else()
|
||||
# as it's a Linux, it should use packet sockets,
|
||||
# instead.
|
||||
#
|
||||
#
|
||||
# We need:
|
||||
#
|
||||
# sys/types.h, because FreeBSD 10's net/bpf.h
|
||||
# requires that various BSD-style integer types
|
||||
# be defined;
|
||||
#
|
||||
# sys/time.h, because AIX 5.2 and 5.3's net/bpf.h
|
||||
# doesn't include it but does use struct timeval
|
||||
# in ioctl definitions;
|
||||
#
|
||||
# sys/ioctl.h and, if we have it, sys/ioccom.h,
|
||||
# because net/bpf.h defines ioctls;
|
||||
#
|
||||
@@ -952,9 +973,9 @@ else()
|
||||
# of those headers itself.
|
||||
#
|
||||
if(HAVE_SYS_IOCCOM_H)
|
||||
check_symbol_exists(BIOCSETIF "sys/types.h;sys/ioctl.h;sys/socket.h;sys/ioccom.h;net/bpf.h;net/if.h" BPF_H_DEFINES_BIOCSETIF)
|
||||
check_symbol_exists(BIOCSETIF "sys/types.h;sys/time.h;sys/ioctl.h;sys/socket.h;sys/ioccom.h;net/bpf.h;net/if.h" BPF_H_DEFINES_BIOCSETIF)
|
||||
else(HAVE_SYS_IOCCOM_H)
|
||||
check_symbol_exists(BIOCSETIF "sys/types.h;sys/ioctl.h;sys/socket.h;net/bpf.h;net/if.h" BPF_H_DEFINES_BIOCSETIF)
|
||||
check_symbol_exists(BIOCSETIF "sys/types.h;sys/time.h;sys/ioctl.h;sys/socket.h;net/bpf.h;net/if.h" BPF_H_DEFINES_BIOCSETIF)
|
||||
endif(HAVE_SYS_IOCCOM_H)
|
||||
endif(HAVE_NET_BPF_H)
|
||||
check_include_file(net/pfilt.h HAVE_NET_PFILT_H)
|
||||
@@ -1436,7 +1457,28 @@ if(NOT DISABLE_DBUS)
|
||||
set(PCAP_SUPPORT_DBUS TRUE)
|
||||
set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} pcap-dbus.c)
|
||||
include_directories(${DBUS_INCLUDE_DIRS})
|
||||
set(PCAP_LINK_LIBRARIES ${PCAP_LINK_LIBRARIES} ${DBUS_LIBRARIES})
|
||||
|
||||
#
|
||||
# This "helpfully" supplies DBUS_LIBRARIES as a bunch of
|
||||
# library names - not paths - and DBUS_LIBRARY_DIRS as
|
||||
# a bunch of directories.
|
||||
#
|
||||
# CMake *really* doesn't like the notion of specifying "here are
|
||||
# the directories in which to look for libraries" except in
|
||||
# find_library() calls; it *really* prefers using full paths to
|
||||
# library files, rather than library names.
|
||||
#
|
||||
# Find the libraries and add their full paths.
|
||||
#
|
||||
set(DBUS_LIBRARY_FULLPATHS)
|
||||
foreach(_lib IN LISTS DBUS_LIBRARIES)
|
||||
#
|
||||
# Try to find this library, so we get its full path.
|
||||
#
|
||||
find_library(_libfullpath ${_lib} HINTS ${DBUS_LIBRARY_DIRS})
|
||||
list(APPEND DBUS_LIBRARY_FULLPATHS ${_libfullpath})
|
||||
endforeach()
|
||||
set(PCAP_LINK_LIBRARIES ${PCAP_LINK_LIBRARIES} ${DBUS_LIBRARY_FULLPATHS})
|
||||
endif(DBUS_FOUND)
|
||||
endif(NOT DISABLE_DBUS)
|
||||
|
||||
@@ -1582,7 +1624,7 @@ if(ENABLE_REMOTE)
|
||||
# the check.
|
||||
#
|
||||
cmake_push_check_state()
|
||||
set(CMAKE_REQUIRED_INCLUDES ${CMAKE_SOURCE_DIR})
|
||||
set(CMAKE_REQUIRED_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
check_struct_has_member("struct msghdr" msg_control "ftmacros.h;sys/socket.h" HAVE_STRUCT_MSGHDR_MSG_CONTROL)
|
||||
check_struct_has_member("struct msghdr" msg_flags "ftmacros.h;sys/socket.h" HAVE_STRUCT_MSGHDR_MSG_FLAGS)
|
||||
cmake_pop_check_state()
|
||||
@@ -1597,7 +1639,7 @@ endif(ENABLE_REMOTE)
|
||||
#
|
||||
# Check and add warning options if we have a .devel file.
|
||||
#
|
||||
if(EXISTS ${CMAKE_SOURCE_DIR}/.devel OR EXISTS ${CMAKE_BINARY_DIR}/.devel)
|
||||
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/.devel OR EXISTS ${CMAKE_BINARY_DIR}/.devel)
|
||||
#
|
||||
# Warning options.
|
||||
#
|
||||
@@ -1808,10 +1850,12 @@ set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/grammar.c PROPERTIES
|
||||
|
||||
#
|
||||
# Assume, by default, no support for shared libraries and V7/BSD
|
||||
# convention for man pages (file formats in section 5, miscellaneous
|
||||
# info in section 7, administrative commands and daemons in section 8).
|
||||
# convention for man pages (devices in section 4, file formats in
|
||||
# section 5, miscellaneous info in section 7, administrative commands
|
||||
# and daemons in section 8). Individual cases can override this.
|
||||
# Individual cases can override this.
|
||||
#
|
||||
set(MAN_DEVICES 4)
|
||||
set(MAN_FILE_FORMATS 5)
|
||||
set(MAN_MISC_INFO 7)
|
||||
set(MAN_ADMIN_COMMANDS 8)
|
||||
@@ -1869,6 +1913,7 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "OSF1")
|
||||
#
|
||||
set(MAN_FILE_FORMATS 4)
|
||||
set(MAN_MISC_INFO 5)
|
||||
set(MAN_DEVICES 7)
|
||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "SunOS" AND CMAKE_SYSTEM_VERSION MATCHES "5[.][0-9.]*")
|
||||
#
|
||||
# SunOS 5.x.
|
||||
@@ -1892,6 +1937,7 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "SunOS" AND CMAKE_SYSTEM_VERSION MATCHES "5[.]
|
||||
set(MAN_ADMIN_COMMANDS 1m)
|
||||
set(MAN_FILE_FORMATS 4)
|
||||
set(MAN_MISC_INFO 5)
|
||||
set(MAN_DEVICES 7D)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -1944,6 +1990,16 @@ if(BUILD_SHARED_LIBS)
|
||||
add_dependencies(${LIBRARY_NAME} SerializeTarget)
|
||||
set_target_properties(${LIBRARY_NAME} PROPERTIES
|
||||
COMPILE_DEFINITIONS BUILDING_PCAP)
|
||||
#
|
||||
# No matter what the library is called - it might be called "wpcap"
|
||||
# in a Windows build - the symbol to define to indicate that we're
|
||||
# building the library, rather than a program using the library,
|
||||
# and thus that we're exporting functions defined in our public
|
||||
# header files, rather than importing those functions, is
|
||||
# pcap_EXPORTS.
|
||||
#
|
||||
set_target_properties(${LIBRARY_NAME} PROPERTIES
|
||||
DEFINE_SYMBOL pcap_EXPORTS)
|
||||
endif(BUILD_SHARED_LIBS)
|
||||
|
||||
add_library(${LIBRARY_NAME}_static STATIC
|
||||
@@ -2020,6 +2076,118 @@ if(NOT C_ADDITIONAL_FLAGS STREQUAL "")
|
||||
set_target_properties(${LIBRARY_NAME}_static PROPERTIES COMPILE_FLAGS ${C_ADDITIONAL_FLAGS})
|
||||
endif()
|
||||
|
||||
#
|
||||
# On macOS, build libpcap for the appropriate architectures, if
|
||||
# CMAKE_OSX_ARCHITECTURES isn't set (if it is, let that control
|
||||
# the architectures for which to build it).
|
||||
#
|
||||
if(APPLE AND "${CMAKE_OSX_ARCHITECTURES}" STREQUAL "")
|
||||
#
|
||||
# Get the major version of Darwin.
|
||||
#
|
||||
string(REGEX MATCH "^([0-9]+)" SYSTEM_VERSION_MAJOR "${CMAKE_SYSTEM_VERSION}")
|
||||
|
||||
if(SYSTEM_VERSION_MAJOR LESS 8)
|
||||
#
|
||||
# Pre-Tiger. Build only for 32-bit PowerPC.
|
||||
#
|
||||
set(OSX_LIBRARY_ARCHITECTURES "ppc")
|
||||
elseif(SYSTEM_VERSION_MAJOR EQUAL 8)
|
||||
#
|
||||
# Tiger. Is this prior to, or with, Intel support?
|
||||
#
|
||||
# Get the minor version of Darwin.
|
||||
#
|
||||
string(REPLACE "${SYSTEM_VERSION_MAJOR}." "" SYSTEM_MINOR_AND_PATCH_VERSION ${CMAKE_SYSTEM_VERSION})
|
||||
string(REGEX MATCH "^([0-9]+)" SYSTEM_VERSION_MINOR "${SYSTEM_MINOR_AND_PATCH_VERSION}")
|
||||
if(SYSTEM_VERSION_MINOR LESS 4)
|
||||
#
|
||||
# Prior to Intel support. Build for 32-bit
|
||||
# PowerPC and 64-bit PowerPC, with 32-bit PowerPC
|
||||
# first. (I'm guessing that's what Apple does.)
|
||||
#
|
||||
set(OSX_LIBRARY_ARCHITECTURES "ppc;ppc64")
|
||||
elseif(SYSTEM_VERSION_MINOR LESS 7)
|
||||
#
|
||||
# With Intel support but prior to x86-64 support.
|
||||
# Build for 32-bit PowerPC, 64-bit PowerPC, and 32-bit x86,
|
||||
# with 32-bit PowerPC first.
|
||||
# (I'm guessing that's what Apple does.)
|
||||
#
|
||||
set(OSX_LIBRARY_ARCHITECTURES "ppc;ppc64;i386")
|
||||
else()
|
||||
#
|
||||
# With Intel support including x86-64 support.
|
||||
# Build for 32-bit PowerPC, 64-bit PowerPC, 32-bit x86,
|
||||
# and x86-64, with 32-bit PowerPC first.
|
||||
# (I'm guessing that's what Apple does.)
|
||||
#
|
||||
set(OSX_LIBRARY_ARCHITECTURES "ppc;ppc64;i386;x86_64")
|
||||
endif()
|
||||
elseif(SYSTEM_VERSION_MAJOR EQUAL 9)
|
||||
#
|
||||
# Leopard. Build for 32-bit PowerPC, 64-bit
|
||||
# PowerPC, 32-bit x86, and x86-64, with 32-bit PowerPC
|
||||
# first. (That's what Apple does.)
|
||||
#
|
||||
set(OSX_LIBRARY_ARCHITECTURES "ppc;ppc64;i386;x86_64")
|
||||
elseif(SYSTEM_VERSION_MAJOR EQUAL 10)
|
||||
#
|
||||
# Snow Leopard. Build for x86-64, 32-bit x86, and
|
||||
# 32-bit PowerPC, with x86-64 first. (That's
|
||||
# what Apple does, even though Snow Leopard
|
||||
# doesn't run on PPC, so PPC libpcap runs under
|
||||
# Rosetta, and Rosetta doesn't support BPF
|
||||
# ioctls, so PPC programs can't do live
|
||||
# captures.)
|
||||
#
|
||||
set(OSX_LIBRARY_ARCHITECTURES "x86_64;i386;ppc")
|
||||
else()
|
||||
#
|
||||
# Post-Snow Leopard. Build for x86-64 and 32-bit x86,
|
||||
# with x86-64 first. (That's what Apple does)
|
||||
# XXX - update if and when Apple drops support
|
||||
# for 32-bit x86 code and if and when Apple adds
|
||||
# ARM-based Macs. (You're on your own for iOS etc.)
|
||||
#
|
||||
# XXX - check whether we *can* build for i386 and, if not,
|
||||
# suggest that the user install the /usr/include headers if
|
||||
# they want to build fat.
|
||||
#
|
||||
cmake_push_check_state()
|
||||
set(CMAKE_REQUIRED_FLAGS "-arch i386")
|
||||
check_c_source_compiles(
|
||||
"int
|
||||
main(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
"
|
||||
X86_32_BIT_SUPPORTED)
|
||||
cmake_pop_check_state()
|
||||
if(X86_32_BIT_SUPPORTED)
|
||||
set(OSX_LIBRARY_ARCHITECTURES "x86_64;i386")
|
||||
else()
|
||||
set(OSX_LIBRARY_ARCHITECTURES "x86_64")
|
||||
if(SYSTEM_VERSION_MAJOR LESS 18)
|
||||
#
|
||||
# Pre-Mojave; the command-line tools should be sufficient to
|
||||
# enable 32-bit x86 builds.
|
||||
#
|
||||
message(WARNING "Compiling for 32-bit x86 gives an error; try installing the command-line tools")
|
||||
else()
|
||||
message(WARNING "Compiling for 32-bit x86 gives an error; try installing the command-line tools and, after that, installing the /usr/include headers from the /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg package")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
if(BUILD_SHARED_LIBS)
|
||||
set_target_properties(${LIBRARY_NAME} PROPERTIES
|
||||
OSX_ARCHITECTURES "${OSX_LIBRARY_ARCHITECTURES}")
|
||||
endif(BUILD_SHARED_LIBS)
|
||||
set_target_properties(${LIBRARY_NAME}_static PROPERTIES
|
||||
OSX_ARCHITECTURES "${OSX_LIBRARY_ARCHITECTURES}")
|
||||
endif()
|
||||
|
||||
######################################
|
||||
# Write out the config.h file
|
||||
######################################
|
||||
@@ -2079,6 +2247,7 @@ set(MAN3PCAP_EXPAND
|
||||
pcap_list_tstamp_types.3pcap.in
|
||||
pcap_open_dead.3pcap.in
|
||||
pcap_open_offline.3pcap.in
|
||||
pcap_set_immediate_mode.3pcap.in
|
||||
pcap_set_tstamp_precision.3pcap.in
|
||||
pcap_set_tstamp_type.3pcap.in
|
||||
)
|
||||
@@ -2114,7 +2283,6 @@ set(MAN3PCAP_NOEXPAND
|
||||
pcap_open_live.3pcap
|
||||
pcap_set_buffer_size.3pcap
|
||||
pcap_set_datalink.3pcap
|
||||
pcap_set_immediate_mode.3pcap
|
||||
pcap_set_promisc.3pcap
|
||||
pcap_set_protocol_linux.3pcap
|
||||
pcap_set_rfmon.3pcap
|
||||
@@ -2179,7 +2347,7 @@ if(WIN32)
|
||||
endif(NOT MINGW)
|
||||
endif(MSVC AND CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
else(WIN32)
|
||||
install(TARGETS ${LIBRARY_NAME} ${LIBRARY_NAME_STATIC} DESTINATION lib)
|
||||
install(TARGETS ${LIBRARY_NAME} ${LIBRARY_NAME_STATIC} DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR})
|
||||
endif(WIN32)
|
||||
|
||||
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/pcap/ DESTINATION include/pcap)
|
||||
@@ -2225,8 +2393,8 @@ if(NOT MSVC)
|
||||
foreach(LIB ${PCAP_LINK_LIBRARIES})
|
||||
set(LIBS "${LIBS} -l${LIB}")
|
||||
endforeach(LIB)
|
||||
configure_file(${CMAKE_SOURCE_DIR}/pcap-config.in ${CMAKE_CURRENT_BINARY_DIR}/pcap-config @ONLY)
|
||||
configure_file(${CMAKE_SOURCE_DIR}/libpcap.pc.in ${CMAKE_CURRENT_BINARY_DIR}/libpcap.pc @ONLY)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/pcap-config.in ${CMAKE_CURRENT_BINARY_DIR}/pcap-config @ONLY)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libpcap.pc.in ${CMAKE_CURRENT_BINARY_DIR}/libpcap.pc @ONLY)
|
||||
install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/pcap-config DESTINATION bin)
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libpcap.pc DESTINATION lib/pkgconfig)
|
||||
|
||||
@@ -2238,17 +2406,17 @@ if(NOT MSVC)
|
||||
#
|
||||
set(MAN1 "")
|
||||
foreach(MANPAGE ${MAN1_NOEXPAND})
|
||||
set(MAN1 ${MAN1} ${CMAKE_SOURCE_DIR}/${MANPAGE})
|
||||
set(MAN1 ${MAN1} ${CMAKE_CURRENT_SOURCE_DIR}/${MANPAGE})
|
||||
endforeach(MANPAGE)
|
||||
install(FILES ${MAN1} DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
|
||||
|
||||
set(MAN3PCAP "")
|
||||
foreach(MANPAGE ${MAN3PCAP_NOEXPAND})
|
||||
set(MAN3PCAP ${MAN3PCAP} ${CMAKE_SOURCE_DIR}/${MANPAGE})
|
||||
set(MAN3PCAP ${MAN3PCAP} ${CMAKE_CURRENT_SOURCE_DIR}/${MANPAGE})
|
||||
endforeach(MANPAGE)
|
||||
foreach(TEMPLATE_MANPAGE ${MAN3PCAP_EXPAND})
|
||||
string(REPLACE ".in" "" MANPAGE ${TEMPLATE_MANPAGE})
|
||||
configure_file(${CMAKE_SOURCE_DIR}/${TEMPLATE_MANPAGE} ${CMAKE_CURRENT_BINARY_DIR}/${MANPAGE} @ONLY)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/${TEMPLATE_MANPAGE} ${CMAKE_CURRENT_BINARY_DIR}/${MANPAGE} @ONLY)
|
||||
set(MAN3PCAP ${MAN3PCAP} ${CMAKE_CURRENT_BINARY_DIR}/${MANPAGE})
|
||||
endforeach(TEMPLATE_MANPAGE)
|
||||
install(FILES ${MAN3PCAP} DESTINATION ${CMAKE_INSTALL_MANDIR}/man3)
|
||||
@@ -2272,7 +2440,7 @@ if(NOT MSVC)
|
||||
set(MANFILE "")
|
||||
foreach(TEMPLATE_MANPAGE ${MANFILE_EXPAND})
|
||||
string(REPLACE ".manfile.in" ".${MAN_FILE_FORMATS}" MANPAGE ${TEMPLATE_MANPAGE})
|
||||
configure_file(${CMAKE_SOURCE_DIR}/${TEMPLATE_MANPAGE} ${CMAKE_CURRENT_BINARY_DIR}/${MANPAGE} @ONLY)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/${TEMPLATE_MANPAGE} ${CMAKE_CURRENT_BINARY_DIR}/${MANPAGE} @ONLY)
|
||||
set(MANFILE ${MANFILE} ${CMAKE_CURRENT_BINARY_DIR}/${MANPAGE})
|
||||
endforeach(TEMPLATE_MANPAGE)
|
||||
install(FILES ${MANFILE} DESTINATION ${CMAKE_INSTALL_MANDIR}/man${MAN_FILE_FORMATS})
|
||||
@@ -2280,7 +2448,7 @@ if(NOT MSVC)
|
||||
set(MANMISC "")
|
||||
foreach(TEMPLATE_MANPAGE ${MANMISC_EXPAND})
|
||||
string(REPLACE ".manmisc.in" ".${MAN_MISC_INFO}" MANPAGE ${TEMPLATE_MANPAGE})
|
||||
configure_file(${CMAKE_SOURCE_DIR}/${TEMPLATE_MANPAGE} ${CMAKE_CURRENT_BINARY_DIR}/${MANPAGE} @ONLY)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/${TEMPLATE_MANPAGE} ${CMAKE_CURRENT_BINARY_DIR}/${MANPAGE} @ONLY)
|
||||
set(MANMISC ${MANMISC} ${CMAKE_CURRENT_BINARY_DIR}/${MANPAGE})
|
||||
endforeach(TEMPLATE_MANPAGE)
|
||||
install(FILES ${MANMISC} DESTINATION ${CMAKE_INSTALL_MANDIR}/man${MAN_MISC_INFO})
|
||||
|
||||
@@ -129,7 +129,7 @@ Additional people who have contributed patches (in alphabetical order):
|
||||
Olaf Kirch <okir at caldera dot de>
|
||||
Ollie Wild <aaw at users dot sourceforge dot net>
|
||||
Onno van der Linden <onno at simplex dot nl>
|
||||
Paolo Abeni <paolo dot abeni at email dot it> and redhat dot com
|
||||
Paolo Abeni <pabeni at redhat dot com>
|
||||
Patrick Marie <mycroft at virgaria dot org>
|
||||
Patrick McHardy <kaber at trash not net>
|
||||
Paul Mundt <lethal at linux-sh dot org>
|
||||
|
||||
@@ -266,15 +266,14 @@ doc/README.macos - notes on using libpcap on macOS
|
||||
doc/README.septel - notes on using libpcap to capture on Intel/Septel devices
|
||||
doc/README.sita - notes on using libpcap to capture on SITA devices
|
||||
doc/README.tru64 - notes on using libpcap on Digital/Tru64 UNIX
|
||||
doc/README.Win32 - notes on using libpcap on Win32 systems (with WinPcap)
|
||||
doc/README.Win32 - notes on using libpcap on Win32 systems (with Npcap)
|
||||
VERSION - version of this release
|
||||
acconfig.h - support for post-2.13 autoconf
|
||||
aclocal.m4 - autoconf macros
|
||||
arcnet.h - ARCNET definitions
|
||||
atmuni31.h - ATM Q.2931 definitions
|
||||
bpf/net - copy of bpf_filter.c
|
||||
bpf_dump.c - BPF program printing routines
|
||||
bpf_filter.c - symlink to bpf/net/bpf_filter.c
|
||||
bpf_filter.c - BPF filtering routines
|
||||
bpf_image.c - BPF disassembly routine
|
||||
config.guess - autoconf support
|
||||
config.h.in - autoconf input
|
||||
|
||||
@@ -69,13 +69,16 @@ INSTALL_RPCAPD=@INSTALL_RPCAPD@
|
||||
EXTRA_NETWORK_LIBS=@EXTRA_NETWORK_LIBS@
|
||||
|
||||
# Standard CFLAGS for building members of a shared library
|
||||
FULL_CFLAGS = $(CCOPT) $(SHLIB_CCOPT) $(INCLS) $(DEFS) $(CFLAGS)
|
||||
FULL_CFLAGS = $(CCOPT) @V_LIB_CCOPT_FAT@ $(SHLIB_CCOPT) $(INCLS) $(DEFS) $(CFLAGS)
|
||||
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
RANLIB = @RANLIB@
|
||||
|
||||
LEX = @LEX@
|
||||
YACC = @YACC@
|
||||
|
||||
# Explicitly define compilation rule since SunOS 4's make doesn't like gcc.
|
||||
# Also, gcc does not remove the .o before forking 'as', which can be a
|
||||
# problem if you don't own the file but can write to the directory.
|
||||
@@ -114,6 +117,7 @@ PUBHDR = \
|
||||
pcap/nflog.h \
|
||||
pcap/pcap.h \
|
||||
pcap/sll.h \
|
||||
pcap/socket.h \
|
||||
pcap/vlan.h \
|
||||
pcap/usb.h
|
||||
|
||||
@@ -150,7 +154,7 @@ TAGFILES = \
|
||||
$(SRC) $(HDR)
|
||||
|
||||
CLEANFILES = $(OBJ) libpcap.a libpcap.so.`cat $(srcdir)/VERSION` \
|
||||
$(PROG)-`cat $(srcdir)/VERSION`.tar.gz \
|
||||
$(PROG)-`cat $(srcdir)/VERSION`.tar.gz $(GENSRC) $(GENHDR) \
|
||||
lex.yy.c pcap-config libpcap.pc
|
||||
|
||||
MAN1 = pcap-config.1
|
||||
@@ -165,6 +169,7 @@ MAN3PCAP_EXPAND = \
|
||||
pcap_list_tstamp_types.3pcap.in \
|
||||
pcap_open_dead.3pcap.in \
|
||||
pcap_open_offline.3pcap.in \
|
||||
pcap_set_immediate_mode.3pcap.in \
|
||||
pcap_set_tstamp_precision.3pcap.in \
|
||||
pcap_set_tstamp_type.3pcap.in
|
||||
|
||||
@@ -200,7 +205,6 @@ MAN3PCAP_NOEXPAND = \
|
||||
pcap_open_live.3pcap \
|
||||
pcap_set_buffer_size.3pcap \
|
||||
pcap_set_datalink.3pcap \
|
||||
pcap_set_immediate_mode.3pcap \
|
||||
pcap_set_promisc.3pcap \
|
||||
pcap_set_protocol_linux.3pcap \
|
||||
pcap_set_rfmon.3pcap \
|
||||
@@ -273,10 +277,14 @@ EXTRA_DIST = \
|
||||
lbl/os-sunos4.h \
|
||||
lbl/os-ultrix4.h \
|
||||
libpcap.pc.in \
|
||||
missing/asprintf.c \
|
||||
missing/getopt.c \
|
||||
missing/getopt.h \
|
||||
missing/snprintf.c \
|
||||
missing/strlcat.c \
|
||||
missing/strlcpy.c \
|
||||
missing/strtok_r.c \
|
||||
missing/win_asprintf.c \
|
||||
missing/win_snprintf.c \
|
||||
mkdep \
|
||||
msdos/bin2c.c \
|
||||
@@ -344,12 +352,13 @@ EXTRA_DIST = \
|
||||
rpcapd/fileconf.c \
|
||||
rpcapd/fileconf.h \
|
||||
rpcapd/log.h \
|
||||
rpcapd/log-stderr.c \
|
||||
rpcapd/log.c \
|
||||
rpcapd/org.tcpdump.rpcapd.plist \
|
||||
rpcapd/rpcapd.c \
|
||||
rpcapd/rpcapd.h \
|
||||
rpcapd/rpcapd.inetd.conf \
|
||||
rpcapd/rpcapd.manadmin.in \
|
||||
rpcapd/rpcapd-config.manfile.in \
|
||||
rpcapd/rpcapd.rc \
|
||||
rpcapd/rpcapd.socket \
|
||||
rpcapd/rpcapd.xinetd.conf \
|
||||
@@ -378,15 +387,6 @@ EXTRA_DIST = \
|
||||
|
||||
all: libpcap.a shared $(BUILD_RPCAPD) libpcap.pc pcap-config
|
||||
|
||||
# Inhibit implicit rule Make seems to have for using yacc/lex to
|
||||
# recompile new scanner.c/grammar.c -- we ship ones which we want to
|
||||
# use instead.
|
||||
grammar.c:
|
||||
echo "Not rebuilding grammar.c"
|
||||
|
||||
scanner.c:
|
||||
echo "Not rebuilding scanner.c"
|
||||
|
||||
libpcap.a: $(OBJ)
|
||||
@rm -f $@
|
||||
$(AR) rc $@ $(OBJ) $(ADDLARCHIVEOBJS)
|
||||
@@ -423,7 +423,7 @@ libpcap.dylib: $(OBJ)
|
||||
MAJOR_VER=A; \
|
||||
COMPAT_VER=1; \
|
||||
CURRENT_VER=`sed 's/[^0-9.].*$$//' $(srcdir)/VERSION`; \
|
||||
$(CC) -dynamiclib -undefined error $(LDFLAGS) \
|
||||
$(CC) -dynamiclib -undefined error $(LDFLAGS) @V_LIB_LDFLAGS_FAT@ \
|
||||
-o libpcap.$$VER.dylib $(OBJ) $(ADDLOBJS) $(LIBS) \
|
||||
-install_name $(libdir)/libpcap.$$MAJOR_VER.dylib \
|
||||
-compatibility_version $$COMPAT_VER \
|
||||
@@ -468,18 +468,45 @@ libpcap.shareda: $(OBJ)
|
||||
#
|
||||
libpcap.none:
|
||||
|
||||
scanner.c: $(srcdir)/scanner.l
|
||||
$(LEX) -P pcap_ --header-file=scanner.h --nounput -o scanner.c $<
|
||||
scanner.h: scanner.c
|
||||
## Recover from the removal of $@
|
||||
@if test -f $@; then :; else \
|
||||
rm -f scanner.c; \
|
||||
$(MAKE) $(MAKEFLAGS) scanner.c; \
|
||||
fi
|
||||
|
||||
scanner.o: scanner.c grammar.h
|
||||
$(CC) $(FULL_CFLAGS) -c scanner.c
|
||||
|
||||
grammar.c: $(srcdir)/grammar.y
|
||||
$(YACC) -p pcap_ -o grammar.c -d $<
|
||||
grammar.h: grammar.c
|
||||
## Recover from the removal of $@
|
||||
@if test -f $@; then :; else \
|
||||
rm -f grammar.c; \
|
||||
$(MAKE) $(MAKEFLAGS) grammar.c; \
|
||||
fi
|
||||
|
||||
grammar.o: grammar.c scanner.h
|
||||
$(CC) $(FULL_CFLAGS) -c grammar.c
|
||||
|
||||
gencode.o: $(srcdir)/gencode.c grammar.h scanner.h
|
||||
$(CC) $(FULL_CFLAGS) -c $(srcdir)/gencode.c
|
||||
|
||||
asprintf.o: $(srcdir)/missing/asprintf.c
|
||||
$(CC) $(FULL_CFLAGS) -o $@ -c $(srcdir)/missing/asprintf.c
|
||||
|
||||
snprintf.o: $(srcdir)/missing/snprintf.c
|
||||
$(CC) $(FULL_CFLAGS) -o $@ -c $(srcdir)/missing/snprintf.c
|
||||
|
||||
strlcat.o: $(srcdir)/missing/strlcat.c
|
||||
$(CC) $(FULL_CFLAGS) -o $@ -c $(srcdir)/missing/strlcat.c
|
||||
|
||||
strlcpy.o: $(srcdir)/missing/strlcpy.c
|
||||
$(CC) $(FULL_CFLAGS) -o $@ -c $(srcdir)/missing/strlcpy.c
|
||||
|
||||
strtok_r.o: $(srcdir)/missing/strtok_r.c
|
||||
$(CC) $(FULL_CFLAGS) -o $@ -c $(srcdir)/missing/strtok_r.c
|
||||
|
||||
@@ -563,6 +590,9 @@ install: install-shared install-archive libpcap.pc pcap-config @INSTALL_RPCAPD@
|
||||
rm -f pcap_datalink_val_to_description.3pcap && \
|
||||
$(LN_S) pcap_datalink_val_to_name.3pcap \
|
||||
pcap_datalink_val_to_description.3pcap && \
|
||||
rm -f pcap_datalink_val_to_description_or_dlt.3pcap && \
|
||||
$(LN_S) pcap_datalink_val_to_name.3pcap \
|
||||
pcap_datalink_val_to_description_or_dlt.3pcap && \
|
||||
rm -f pcap_dump_fopen.3pcap && \
|
||||
$(LN_S) pcap_dump_open.3pcap pcap_dump_fopen.3pcap && \
|
||||
rm -f pcap_freealldevs.3pcap && \
|
||||
@@ -711,8 +741,8 @@ uninstall-rpcapd:
|
||||
|
||||
clean:
|
||||
rm -f $(CLEANFILES)
|
||||
cd rpcapd && $(MAKE) clean
|
||||
cd testprogs && $(MAKE) clean
|
||||
cd rpcapd; $(MAKE) clean
|
||||
cd testprogs; $(MAKE) clean
|
||||
|
||||
distclean: clean
|
||||
rm -f Makefile config.cache config.log config.status \
|
||||
|
||||
@@ -1,103 +0,0 @@
|
||||
diff --git a/libpcap/Makefile.in b/libpcap/Makefile.in
|
||||
index dff75ec..38e7bb1 100644
|
||||
--- a/libpcap/Makefile.in
|
||||
+++ b/libpcap/Makefile.in
|
||||
@@ -76,9 +76,6 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
RANLIB = @RANLIB@
|
||||
|
||||
-LEX = @LEX@
|
||||
-YACC = @YACC@
|
||||
-
|
||||
# Explicitly define compilation rule since SunOS 4's make doesn't like gcc.
|
||||
# Also, gcc does not remove the .o before forking 'as', which can be a
|
||||
# problem if you don't own the file but can write to the directory.
|
||||
@@ -153,7 +150,7 @@ TAGFILES = \
|
||||
$(SRC) $(HDR)
|
||||
|
||||
CLEANFILES = $(OBJ) libpcap.a libpcap.so.`cat $(srcdir)/VERSION` \
|
||||
- $(PROG)-`cat $(srcdir)/VERSION`.tar.gz $(GENSRC) $(GENHDR) \
|
||||
+ $(PROG)-`cat $(srcdir)/VERSION`.tar.gz \
|
||||
lex.yy.c pcap-config libpcap.pc
|
||||
|
||||
MAN1 = pcap-config.1
|
||||
@@ -381,6 +378,15 @@ EXTRA_DIST = \
|
||||
|
||||
all: libpcap.a shared $(BUILD_RPCAPD) libpcap.pc pcap-config
|
||||
|
||||
+# Inhibit implicit rule Make seems to have for using yacc/lex to
|
||||
+# recompile new scanner.c/grammar.c -- we ship ones which we want to
|
||||
+# use instead.
|
||||
+grammar.c:
|
||||
+ echo "Not rebuilding grammar.c"
|
||||
+
|
||||
+scanner.c:
|
||||
+ echo "Not rebuilding scanner.c"
|
||||
+
|
||||
libpcap.a: $(OBJ)
|
||||
@rm -f $@
|
||||
$(AR) rc $@ $(OBJ) $(ADDLARCHIVEOBJS)
|
||||
@@ -462,27 +468,9 @@ libpcap.shareda: $(OBJ)
|
||||
#
|
||||
libpcap.none:
|
||||
|
||||
-scanner.c: $(srcdir)/scanner.l
|
||||
- $(LEX) -P pcap_ --header-file=scanner.h --nounput -o scanner.c $<
|
||||
-scanner.h: scanner.c
|
||||
-## Recover from the removal of $@
|
||||
- @if test -f $@; then :; else \
|
||||
- rm -f scanner.c; \
|
||||
- $(MAKE) $(MAKEFLAGS) scanner.c; \
|
||||
- fi
|
||||
-
|
||||
scanner.o: scanner.c grammar.h
|
||||
$(CC) $(FULL_CFLAGS) -c scanner.c
|
||||
|
||||
-grammar.c: $(srcdir)/grammar.y
|
||||
- $(YACC) -p pcap_ -o grammar.c -d $<
|
||||
-grammar.h: grammar.c
|
||||
-## Recover from the removal of $@
|
||||
- @if test -f $@; then :; else \
|
||||
- rm -f grammar.c; \
|
||||
- $(MAKE) $(MAKEFLAGS) grammar.c; \
|
||||
- fi
|
||||
-
|
||||
grammar.o: grammar.c scanner.h
|
||||
$(CC) $(FULL_CFLAGS) -c grammar.c
|
||||
|
||||
diff --git a/libpcap/configure.ac b/libpcap/configure.ac
|
||||
index eff6eb8..0127f0a 100644
|
||||
--- a/libpcap/configure.ac
|
||||
+++ b/libpcap/configure.ac
|
||||
@@ -1462,7 +1462,7 @@ yes) AC_MSG_RESULT(yes)
|
||||
#include "ftmacros.h"
|
||||
#include <sys/socket.h>
|
||||
])
|
||||
-
|
||||
+ AC_CONFIG_FILES([rpcapd/Makefile rpcapd/rpcapd.manadmin])
|
||||
AC_DEFINE(ENABLE_REMOTE,,
|
||||
[Define to 1 if remote packet capture is to be supported])
|
||||
SSRC="$SSRC pcap-new.c pcap-rpcap.c rpcap-protocol.c sockutils.c"
|
||||
@@ -1867,14 +1867,12 @@ AC_SUBST(V_CCOPT)
|
||||
AC_SUBST(V_DEFS)
|
||||
AC_SUBST(V_FINDALLDEVS)
|
||||
AC_SUBST(V_INCLS)
|
||||
-AC_SUBST(V_LEX)
|
||||
AC_SUBST(V_PCAP)
|
||||
AC_SUBST(V_SHLIB_CCOPT)
|
||||
AC_SUBST(V_SHLIB_CMD)
|
||||
AC_SUBST(V_SHLIB_OPT)
|
||||
AC_SUBST(V_SONAME_OPT)
|
||||
AC_SUBST(V_RPATH_OPT)
|
||||
-AC_SUBST(V_YACC)
|
||||
AC_SUBST(ADDLOBJS)
|
||||
AC_SUBST(ADDLARCHIVEOBJS)
|
||||
AC_SUBST(SSRC)
|
||||
@@ -2275,6 +2273,6 @@ AC_OUTPUT(Makefile pcap-filter.manmisc pcap-linktype.manmisc
|
||||
pcap_get_tstamp_precision.3pcap pcap_list_datalinks.3pcap
|
||||
pcap_list_tstamp_types.3pcap pcap_open_dead.3pcap
|
||||
pcap_open_offline.3pcap pcap_set_tstamp_precision.3pcap
|
||||
- pcap_set_tstamp_type.3pcap rpcapd/Makefile rpcapd/rpcapd.manadmin
|
||||
+ pcap_set_tstamp_type.3pcap
|
||||
testprogs/Makefile)
|
||||
exit 0
|
||||
@@ -1,64 +0,0 @@
|
||||
diff --git a/libpcap/configure.ac b/libpcap/configure.ac
|
||||
index 0127f0a..4b35daa 100644
|
||||
--- a/libpcap/configure.ac
|
||||
+++ b/libpcap/configure.ac
|
||||
@@ -743,10 +743,10 @@ linux)
|
||||
# Do we have libnl?
|
||||
#
|
||||
AC_ARG_WITH(libnl,
|
||||
- AC_HELP_STRING([--without-libnl],[disable libnl support @<:@default=yes, on Linux, if present@:>@]),
|
||||
+ AC_HELP_STRING([--without-libnl],[disable libnl support @<:@default=disabled@:>@]),
|
||||
with_libnl=$withval,with_libnl=if_available)
|
||||
|
||||
- if test x$with_libnl != xno ; then
|
||||
+ if test x$with_libnl = xyes ; then
|
||||
have_any_nl="no"
|
||||
|
||||
incdir=-I/usr/include/libnl3
|
||||
@@ -1814,8 +1814,8 @@ solaris*)
|
||||
esac
|
||||
|
||||
AC_ARG_ENABLE(shared,
|
||||
-AC_HELP_STRING([--enable-shared],[build shared libraries @<:@default=yes, if support available@:>@]))
|
||||
-test "x$enable_shared" = "xno" && DYEXT="none"
|
||||
+AC_HELP_STRING([--enable-shared],[build shared libraries @<:@default=no@:>@]))
|
||||
+test "x$enable_shared" != "xyes" && DYEXT="none"
|
||||
|
||||
AC_PROG_RANLIB
|
||||
AC_CHECK_TOOL([AR], [ar])
|
||||
@@ -1887,9 +1887,9 @@ AC_SUBST(RPCAPD_LIBS)
|
||||
AC_SUBST(EXTRA_NETWORK_LIBS)
|
||||
|
||||
AC_ARG_ENABLE([usb],
|
||||
-[AC_HELP_STRING([--enable-usb],[enable USB capture support @<:@default=yes, if support available@:>@])],
|
||||
+[AC_HELP_STRING([--enable-usb],[enable USB capture support @<:@default=no@:>@])],
|
||||
[],
|
||||
- [enable_usb=yes])
|
||||
+ [enable_usb=no])
|
||||
|
||||
if test "xxx_only" = yes; then
|
||||
# User requested something-else-only pcap, so they don't
|
||||
@@ -2035,9 +2035,9 @@ fi
|
||||
|
||||
|
||||
AC_ARG_ENABLE([bluetooth],
|
||||
-[AC_HELP_STRING([--enable-bluetooth],[enable Bluetooth support @<:@default=yes, if support available@:>@])],
|
||||
+[AC_HELP_STRING([--enable-bluetooth],[enable Bluetooth support @<:@default=no@:>@])],
|
||||
[],
|
||||
- [enable_bluetooth=ifsupportavailable])
|
||||
+ [enable_bluetooth=no])
|
||||
|
||||
if test "xxx_only" = yes; then
|
||||
# User requested something-else-only pcap, so they don't
|
||||
@@ -2120,9 +2120,9 @@ if test "x$enable_bluetooth" != "xno" ; then
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE([dbus],
|
||||
-[AC_HELP_STRING([--enable-dbus],[enable D-Bus capture support @<:@default=yes, if support available@:>@])],
|
||||
+[AC_HELP_STRING([--enable-dbus],[enable D-Bus capture support @<:@default=no@:>@])],
|
||||
[],
|
||||
- [enable_dbus=ifavailable])
|
||||
+ [enable_dbus=no])
|
||||
|
||||
if test "xxx_only" = yes; then
|
||||
# User requested something-else-only pcap, so they don't
|
||||
@@ -1,25 +0,0 @@
|
||||
Download libpcap-X.Y.tar.gz from http://www.tcpdump.org/#latest-release
|
||||
and verify the signature.
|
||||
|
||||
cd
|
||||
# Make a copy of this directory.
|
||||
cp -r ~/nmap/libpcap/NMAP_MODIFICATIONS .
|
||||
tar xzvf libpcap-X.Y.tar.gz
|
||||
cd nmap
|
||||
rsync -rv --delete ~/libpcap-X.Y/ ~/nmap/libpcap/
|
||||
git add -A libpcap
|
||||
cd libpcap
|
||||
./configure
|
||||
make grammar.c scanner.c scanner.h
|
||||
git add grammar.c scanner.c scanner.h
|
||||
cd ..
|
||||
# Apply patches.
|
||||
git apply ~/NMAP_MODIFICATIONS/000*
|
||||
# Make changes as necessary and update the patch files
|
||||
cd libpcap
|
||||
autoconf
|
||||
cd ..
|
||||
git add -u libpcap
|
||||
mv ~/NMAP_MODIFICATIONS libpcap/
|
||||
git add libpcap/NMAP_MODIFICATIONS
|
||||
git commit -m "Upgrade libpcap to X.Y."
|
||||
@@ -1 +1 @@
|
||||
1.9.0
|
||||
1.9.1
|
||||
|
||||
25
libpcap/aclocal.m4
vendored
25
libpcap/aclocal.m4
vendored
@@ -484,7 +484,7 @@ AC_DEFUN(AC_LBL_SHLIBS_INIT,
|
||||
aix*)
|
||||
;;
|
||||
|
||||
freebsd*|netbsd*|openbsd*|dragonfly*|linux*|osf*)
|
||||
freebsd*|netbsd*|openbsd*|dragonfly*|linux*|osf*|midipix*)
|
||||
#
|
||||
# Platforms where the linker is the GNU linker
|
||||
# or accepts command-line arguments like
|
||||
@@ -501,7 +501,7 @@ AC_DEFUN(AC_LBL_SHLIBS_INIT,
|
||||
sparc64*)
|
||||
case "$host_os" in
|
||||
|
||||
freebsd*|openbsd*)
|
||||
freebsd*|openbsd*|linux*)
|
||||
PIC_OPT=-fPIC
|
||||
;;
|
||||
esac
|
||||
@@ -878,22 +878,23 @@ AC_DEFUN(AC_LBL_DEVEL,
|
||||
#
|
||||
if test "$ac_lbl_cc_dont_try_gcc_dashW" != yes; then
|
||||
AC_LBL_CHECK_UNKNOWN_WARNING_OPTION_ERROR()
|
||||
AC_LBL_CHECK_COMPILER_OPT($1, -W)
|
||||
AC_LBL_CHECK_COMPILER_OPT($1, -Wall)
|
||||
AC_LBL_CHECK_COMPILER_OPT($1, -Wsign-compare)
|
||||
AC_LBL_CHECK_COMPILER_OPT($1, -Wmissing-prototypes)
|
||||
AC_LBL_CHECK_COMPILER_OPT($1, -Wstrict-prototypes)
|
||||
AC_LBL_CHECK_COMPILER_OPT($1, -Wshadow)
|
||||
AC_LBL_CHECK_COMPILER_OPT($1, -Wdeclaration-after-statement)
|
||||
AC_LBL_CHECK_COMPILER_OPT($1, -Wused-but-marked-unused)
|
||||
AC_LBL_CHECK_COMPILER_OPT($1, -Wdocumentation)
|
||||
AC_LBL_CHECK_COMPILER_OPT($1, -Wcomma)
|
||||
AC_LBL_CHECK_COMPILER_OPT($1, -Wdeclaration-after-statement)
|
||||
AC_LBL_CHECK_COMPILER_OPT($1, -Wdocumentation)
|
||||
AC_LBL_CHECK_COMPILER_OPT($1, -Wformat-nonliteral)
|
||||
AC_LBL_CHECK_COMPILER_OPT($1, -Wmissing-noreturn)
|
||||
AC_LBL_CHECK_COMPILER_OPT($1, -Wmissing-prototypes)
|
||||
AC_LBL_CHECK_COMPILER_OPT($1, -Wmissing-variable-declarations)
|
||||
AC_LBL_CHECK_COMPILER_OPT($1, -Wshadow)
|
||||
AC_LBL_CHECK_COMPILER_OPT($1, -Wsign-compare)
|
||||
AC_LBL_CHECK_COMPILER_OPT($1, -Wstrict-prototypes)
|
||||
AC_LBL_CHECK_COMPILER_OPT($1, -Wunused-parameter)
|
||||
AC_LBL_CHECK_COMPILER_OPT($1, -Wused-but-marked-unused)
|
||||
# Warns about safeguards added in case the enums are
|
||||
# extended
|
||||
# AC_LBL_CHECK_COMPILER_OPT($1, -Wcovered-switch-default)
|
||||
AC_LBL_CHECK_COMPILER_OPT($1, -Wmissing-variable-declarations)
|
||||
AC_LBL_CHECK_COMPILER_OPT($1, -Wunused-parameter)
|
||||
AC_LBL_CHECK_COMPILER_OPT($1, -Wformat-nonliteral)
|
||||
#
|
||||
# This can cause problems with ntohs(), ntohl(),
|
||||
# htons(), and htonl() on some platforms, such
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
#include <sys/time.h>
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#include <pcap/bpf.h>
|
||||
#include <pcap-int.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
@@ -328,11 +328,17 @@ bpf_filter_with_aux_data(const struct bpf_insn *pc, const u_char *p,
|
||||
continue;
|
||||
|
||||
case BPF_ALU|BPF_LSH|BPF_X:
|
||||
A <<= X;
|
||||
if (X < 32)
|
||||
A <<= X;
|
||||
else
|
||||
A = 0;
|
||||
continue;
|
||||
|
||||
case BPF_ALU|BPF_RSH|BPF_X:
|
||||
A >>= X;
|
||||
if (X < 32)
|
||||
A >>= X;
|
||||
else
|
||||
A = 0;
|
||||
continue;
|
||||
|
||||
case BPF_ALU|BPF_ADD|BPF_K:
|
||||
@@ -378,10 +384,13 @@ bpf_filter_with_aux_data(const struct bpf_insn *pc, const u_char *p,
|
||||
case BPF_ALU|BPF_NEG:
|
||||
/*
|
||||
* Most BPF arithmetic is unsigned, but negation
|
||||
* can't be unsigned; throw some casts to
|
||||
* specify what we're trying to do.
|
||||
* can't be unsigned; respecify it as subtracting
|
||||
* the accumulator from 0U, so that 1) we don't
|
||||
* get compiler warnings about negating an unsigned
|
||||
* value and 2) don't get UBSan warnings about
|
||||
* the result of negating 0x80000000 being undefined.
|
||||
*/
|
||||
A = (u_int32)(-(int32)A);
|
||||
A = (0U - A);
|
||||
continue;
|
||||
|
||||
case BPF_MISC|BPF_TAX:
|
||||
|
||||
@@ -49,9 +49,17 @@
|
||||
#
|
||||
|
||||
# The 64-bit Packet.lib is located under /x64
|
||||
set(64BIT_SUBDIR "")
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set(64BIT_SUBDIR "/x64")
|
||||
#
|
||||
# For the WinPcap and Npcap SDKs, the Lib subdirectory of the top-level
|
||||
# directory contains 32-bit libraries; the 64-bit libraries are in the
|
||||
# Lib/x64 directory.
|
||||
#
|
||||
# The only way to *FORCE* CMake to look in the Lib/x64 directory
|
||||
# without searching in the Lib directory first appears to be to set
|
||||
# CMAKE_LIBRARY_ARCHITECTURE to "x64".
|
||||
#
|
||||
set(CMAKE_LIBRARY_ARCHITECTURE "x64")
|
||||
endif()
|
||||
|
||||
# Find the header
|
||||
@@ -64,7 +72,6 @@ find_path(PACKET_INCLUDE_DIR Packet32.h
|
||||
find_library(PACKET_LIBRARY
|
||||
NAMES Packet packet
|
||||
HINTS "${PACKET_DLL_DIR}" ENV PACKET_DLL_DIR
|
||||
PATH_SUFFIXES Lib${64BIT_SUBDIR} lib${64BIT_SUBDIR}
|
||||
)
|
||||
|
||||
# Set PACKET_FOUND to TRUE if PACKET_INCLUDE_DIR and PACKET_LIBRARY are TRUE.
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
/* define if we have the AIX getprotobyname_r() */
|
||||
#cmakedefine HAVE_AIX_GETPROTOBYNAME_R 1
|
||||
|
||||
/* Define to 1 if you have the `asprintf' function. */
|
||||
#cmakedefine HAVE_ASPRINTF 1
|
||||
|
||||
/* define if you have the DAG API */
|
||||
#cmakedefine HAVE_DAG_API 1
|
||||
|
||||
@@ -48,6 +51,9 @@
|
||||
/* Define to 1 if you have the `getspnam' function. */
|
||||
#cmakedefine HAVE_GETSPNAM 1
|
||||
|
||||
/* Define to 1 if you have a GNU-style `strerror_r' function. */
|
||||
#cmakedefine HAVE_GNU_STRERROR_R 1
|
||||
|
||||
/* on HP-UX 10.20 or later */
|
||||
#cmakedefine HAVE_HPUX10_20_OR_LATER 1
|
||||
|
||||
@@ -138,9 +144,15 @@
|
||||
/* if there's an os_proto.h for this platform, to use additional prototypes */
|
||||
#cmakedefine HAVE_OS_PROTO_H 1
|
||||
|
||||
/* Define to 1 if Packet32 API (WinPcap NPF driver) is available */
|
||||
/* Define to 1 if Packet32 API (Npcap driver) is available */
|
||||
#cmakedefine HAVE_PACKET32 1
|
||||
|
||||
/* Define to 1 if NPcap's version.h is available */
|
||||
#cmakedefine HAVE_VERSION_H 1
|
||||
|
||||
/* Define to 1 if you have a POSIX-style `strerror_r' function. */
|
||||
#cmakedefine HAVE_POSIX_STRERROR_R 1
|
||||
|
||||
/* define if net/pfvar.h defines PF_NAT through PF_NORDR */
|
||||
#cmakedefine HAVE_PF_NAT_THROUGH_PF_NORDR 1
|
||||
|
||||
@@ -174,9 +186,6 @@
|
||||
/* Define to 1 if you have the `strerror' function. */
|
||||
#cmakedefine HAVE_STRERROR 1
|
||||
|
||||
/* Define to 1 if you have the `strerror_r' function. */
|
||||
#cmakedefine HAVE_STRERROR_R 1
|
||||
|
||||
/* Define to 1 if you have the `strerror_s' function. */
|
||||
#cmakedefine HAVE_STRERROR_S 1
|
||||
|
||||
@@ -256,9 +265,15 @@
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#cmakedefine HAVE_UNISTD_H 1
|
||||
|
||||
/* Define to 1 if you have the `vasprintf' function. */
|
||||
#cmakedefine HAVE_VASPRINTF 1
|
||||
|
||||
/* Define to 1 if you have the `vsnprintf' function. */
|
||||
#cmakedefine HAVE_VSNPRINTF 1
|
||||
|
||||
/* Define to 1 if you have the `vsyslog' function. */
|
||||
#undef HAVE_VSYSLOG
|
||||
|
||||
/* Define to 1 if you have the `PacketIsLoopbackAdapter' function. */
|
||||
#cmakedefine HAVE_PACKET_IS_LOOPBACK_ADAPTER 1
|
||||
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
/* define if we have the AIX getprotobyname_r() */
|
||||
#undef HAVE_AIX_GETPROTOBYNAME_R
|
||||
|
||||
/* Define to 1 if you have the `asprintf' function. */
|
||||
#undef HAVE_ASPRINTF
|
||||
|
||||
/* Define to 1 if you have the <dagapi.h> header file. */
|
||||
#undef HAVE_DAGAPI_H
|
||||
|
||||
@@ -54,6 +57,9 @@
|
||||
/* Define to 1 if you have the `getspnam' function. */
|
||||
#undef HAVE_GETSPNAM
|
||||
|
||||
/* Define to 1 if you have a GNU-style `strerror_r' function. */
|
||||
#undef HAVE_GNU_STRERROR_R
|
||||
|
||||
/* on HP-UX 10.20 or later */
|
||||
#undef HAVE_HPUX10_20_OR_LATER
|
||||
|
||||
@@ -150,6 +156,9 @@
|
||||
/* define if net/pfvar.h defines PF_NAT through PF_NORDR */
|
||||
#undef HAVE_PF_NAT_THROUGH_PF_NORDR
|
||||
|
||||
/* Define to 1 if you have a POSIX-style `strerror_r' function. */
|
||||
#undef HAVE_POSIX_STRERROR_R
|
||||
|
||||
/* define if you have the Septel API */
|
||||
#undef HAVE_SEPTEL_API
|
||||
|
||||
@@ -180,9 +189,6 @@
|
||||
/* Define to 1 if you have the `strerror' function. */
|
||||
#undef HAVE_STRERROR
|
||||
|
||||
/* Define to 1 if you have the `strerror_r' function. */
|
||||
#undef HAVE_STRERROR_R
|
||||
|
||||
/* Define to 1 if you have the `strerror_s' function. */
|
||||
#undef HAVE_STRERROR_S
|
||||
|
||||
@@ -262,9 +268,15 @@
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#undef HAVE_UNISTD_H
|
||||
|
||||
/* Define to 1 if you have the `vasprintf' function. */
|
||||
#undef HAVE_VASPRINTF
|
||||
|
||||
/* Define to 1 if you have the `vsnprintf' function. */
|
||||
#undef HAVE_VSNPRINTF
|
||||
|
||||
/* Define to 1 if you have the `vsyslog' function. */
|
||||
#undef HAVE_VSYSLOG
|
||||
|
||||
/* IPv6 */
|
||||
#undef INET6
|
||||
|
||||
|
||||
1990
libpcap/configure
vendored
1990
libpcap/configure
vendored
File diff suppressed because it is too large
Load Diff
@@ -28,6 +28,9 @@ AC_LBL_C_INIT_BEFORE_CC(V_CCOPT, V_INCLS)
|
||||
# At minimum, we want C++/C99-style // comments.
|
||||
#
|
||||
AC_PROG_CC_C99
|
||||
if test "$ac_cv_prog_cc_c99" = "no"; then
|
||||
AC_MSG_WARN([The C compiler does not support C99; there may be compiler errors])
|
||||
fi
|
||||
AC_LBL_C_INIT(V_CCOPT, V_INCLS)
|
||||
AC_LBL_SHLIBS_INIT
|
||||
AC_LBL_C_INLINE
|
||||
@@ -83,13 +86,109 @@ esac
|
||||
|
||||
AC_LBL_FIXINCLUDES
|
||||
|
||||
AC_CHECK_FUNCS(strerror strerror_r strerror_s strlcpy strlcat)
|
||||
AC_CHECK_FUNCS(strerror)
|
||||
AC_CHECK_FUNC(strerror_r,
|
||||
[
|
||||
#
|
||||
# We have strerror_r; if we define _GNU_SOURCE, is it a
|
||||
# POSIX-compliant strerror_r() or a GNU strerror_r()?
|
||||
#
|
||||
AC_MSG_CHECKING(whether strerror_r is GNU-style)
|
||||
AC_COMPILE_IFELSE(
|
||||
[
|
||||
AC_LANG_SOURCE(
|
||||
#define _GNU_SOURCE
|
||||
#include <string.h>
|
||||
|
||||
/* Define it GNU-style; that will cause an error if it's not GNU-style */
|
||||
extern char *strerror_r(int, char *, size_t);
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
)
|
||||
],
|
||||
[
|
||||
# GNU-style
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_GNU_STRERROR_R,,
|
||||
[Define to 1 if you have a GNU-style `strerror_r' function.])
|
||||
],
|
||||
[
|
||||
AC_MSG_RESULT(no)
|
||||
AC_DEFINE(HAVE_POSIX_STRERROR_R,,
|
||||
[Define to 1 if you have a POSIX-style `strerror_r' function.])
|
||||
])
|
||||
],
|
||||
[
|
||||
#
|
||||
# We don't have strerror_r; do we have strerror_s?
|
||||
#
|
||||
AC_CHECK_FUNCS(strerror_s)
|
||||
])
|
||||
|
||||
#
|
||||
# Thanks, IBM, for not providing vsyslog() in AIX!
|
||||
#
|
||||
AC_CHECK_FUNCS(vsyslog)
|
||||
|
||||
#
|
||||
# Either:
|
||||
#
|
||||
# we have snprintf() and vsnprintf(), and have asprintf() and
|
||||
# vasprintf();
|
||||
#
|
||||
# we have snprintf() and vsnprintf(), but don't have asprintf()
|
||||
# or vasprintf();
|
||||
#
|
||||
# we have neither snprintf() nor vsnprintf(), and don't have
|
||||
# asprintf() or vasprintf(), either.
|
||||
#
|
||||
# We assume that if we have asprintf() we have vasprintf(), as well
|
||||
# as snprintf() and vsnprintf(), and that if we have snprintf() we
|
||||
# have vsnprintf().
|
||||
#
|
||||
# For the first case, we don't need any replacement routines.
|
||||
# For the second case, we need replacement asprintf()/vasprintf()
|
||||
# routines.
|
||||
# For the third case, we need replacement snprintf()/vsnprintf() and
|
||||
# asprintf()/vasprintf() routines.
|
||||
#
|
||||
needsnprintf=no
|
||||
AC_CHECK_FUNCS(vsnprintf snprintf,,
|
||||
[needsnprintf=yes])
|
||||
needasprintf=no
|
||||
AC_CHECK_FUNCS(vasprintf asprintf,,
|
||||
[needasprintf=yes])
|
||||
if test $needsnprintf = yes; then
|
||||
#
|
||||
# We assume we have none of them; missing/snprintf.c supplies
|
||||
# all of them.
|
||||
#
|
||||
AC_LIBOBJ([snprintf])
|
||||
elif test $needasprintf = yes; then
|
||||
#
|
||||
# We assume we have snprintf()/vsnprintf() but lack
|
||||
# asprintf()/vasprintf(); missing/asprintf.c supplies
|
||||
# the latter (using vsnprintf()).
|
||||
#
|
||||
AC_LIBOBJ([asprintf])
|
||||
fi
|
||||
|
||||
needstrlcat=no
|
||||
AC_CHECK_FUNCS(strlcat,,
|
||||
[needstrlcat=yes])
|
||||
if test $needstrlcat = yes; then
|
||||
AC_LIBOBJ([strlcat])
|
||||
fi
|
||||
|
||||
needstrlcpy=no
|
||||
AC_CHECK_FUNCS(strlcpy,,
|
||||
[needstrlcpy=yes])
|
||||
if test $needstrlcpy = yes; then
|
||||
AC_LIBOBJ([strlcpy])
|
||||
fi
|
||||
|
||||
needstrtok_r=no
|
||||
@@ -550,6 +649,10 @@ else
|
||||
# requires that various BSD-style integer types
|
||||
# be defined;
|
||||
#
|
||||
# sys/time.h, because AIX 5.2 and 5.3's net/bpf.h
|
||||
# doesn't include it but does use struct timeval
|
||||
# in ioctl definitions;
|
||||
#
|
||||
# sys/ioctl.h and, if we have it, sys/ioccom.h,
|
||||
# because net/bpf.h defines ioctls;
|
||||
#
|
||||
@@ -568,6 +671,7 @@ else
|
||||
AC_TRY_COMPILE(
|
||||
[
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#ifdef HAVE_SYS_IOCCOM_H
|
||||
@@ -743,10 +847,10 @@ linux)
|
||||
# Do we have libnl?
|
||||
#
|
||||
AC_ARG_WITH(libnl,
|
||||
AC_HELP_STRING([--without-libnl],[disable libnl support @<:@default=disabled@:>@]),
|
||||
AC_HELP_STRING([--without-libnl],[disable libnl support @<:@default=yes, on Linux, if present@:>@]),
|
||||
with_libnl=$withval,with_libnl=if_available)
|
||||
|
||||
if test x$with_libnl = xyes ; then
|
||||
if test x$with_libnl != xno ; then
|
||||
have_any_nl="no"
|
||||
|
||||
incdir=-I/usr/include/libnl3
|
||||
@@ -1462,7 +1566,7 @@ yes) AC_MSG_RESULT(yes)
|
||||
#include "ftmacros.h"
|
||||
#include <sys/socket.h>
|
||||
])
|
||||
AC_CONFIG_FILES([rpcapd/Makefile rpcapd/rpcapd.manadmin])
|
||||
|
||||
AC_DEFINE(ENABLE_REMOTE,,
|
||||
[Define to 1 if remote packet capture is to be supported])
|
||||
SSRC="$SSRC pcap-new.c pcap-rpcap.c rpcap-protocol.c sockutils.c"
|
||||
@@ -1489,15 +1593,60 @@ if test "$enable_yydebug" = "yes"; then
|
||||
fi
|
||||
AC_MSG_RESULT(${enable_yydebug-no})
|
||||
|
||||
#
|
||||
# Look for {f}lex.
|
||||
#
|
||||
AC_PROG_LEX
|
||||
if test "$LEX" = ":"; then
|
||||
AC_MSG_ERROR([Neither flex nor lex was found.])
|
||||
fi
|
||||
|
||||
#
|
||||
# Make sure {f}lex supports the -P, --header-file, and --nounput flags
|
||||
# and supports processing our scanner.l.
|
||||
#
|
||||
AC_CACHE_CHECK([for capable lex], tcpdump_cv_capable_lex,
|
||||
if $LEX -P pcap_ --header-file=/dev/null --nounput -t $srcdir/scanner.l > /dev/null 2>&1; then
|
||||
tcpdump_cv_capable_lex=yes
|
||||
else
|
||||
tcpdump_cv_capable_lex=insufficient
|
||||
fi)
|
||||
if test $tcpdump_cv_capable_lex = insufficient ; then
|
||||
AC_MSG_ERROR([$LEX is insufficient to compile libpcap.
|
||||
libpcap requires Flex 2.5.31 or later, or a compatible version of lex.])
|
||||
fi
|
||||
|
||||
#
|
||||
# Look for yacc/bison/byacc.
|
||||
#
|
||||
AC_PROG_YACC
|
||||
|
||||
#
|
||||
# Make sure it supports the -p flag and supports processing our
|
||||
# grammar.y.
|
||||
#
|
||||
AC_CACHE_CHECK([for capable yacc/bison], tcpdump_cv_capable_yacc,
|
||||
if $YACC -p pcap_ -o /dev/null $srcdir/grammar.y >/dev/null 2>&1; then
|
||||
tcpdump_cv_capable_yacc=yes
|
||||
else
|
||||
tcpdump_cv_capable_yacc=insufficient
|
||||
fi)
|
||||
if test $tcpdump_cv_capable_yacc = insufficient ; then
|
||||
AC_MSG_ERROR([$YACC is insufficient to compile libpcap.
|
||||
libpcap requires Bison, a newer version of Berkeley YACC with support
|
||||
for reentrant parsers, or another YACC compatible with them.])
|
||||
fi
|
||||
|
||||
#
|
||||
# Do various checks for various OSes and versions of those OSes.
|
||||
#
|
||||
# Assume, by default, no support for shared libraries and V7/BSD
|
||||
# convention for man pages (file formats in section 5, miscellaneous
|
||||
# info in section 7, administrative commands and daemons in section 8).
|
||||
# Individual cases can override this.
|
||||
# convention for man pages (devices in section 4, file formats in
|
||||
# section 5, miscellaneous info in section 7, administrative commands
|
||||
# and daemons in section 8). Individual cases can override this.
|
||||
#
|
||||
DYEXT="none"
|
||||
MAN_DEVICES=4
|
||||
MAN_FILE_FORMATS=5
|
||||
MAN_MISC_INFO=7
|
||||
MAN_ADMIN_COMMANDS=8
|
||||
@@ -1553,79 +1702,151 @@ darwin*)
|
||||
if test "$enable_universal" != "no"; then
|
||||
case "$host_os" in
|
||||
|
||||
darwin[0-7].*)
|
||||
darwin[[0-7]].*)
|
||||
#
|
||||
# Pre-Tiger. Build only for 32-bit PowerPC; no
|
||||
# need for any special compiler or linker flags.
|
||||
#
|
||||
;;
|
||||
|
||||
darwin8.[0123]*)
|
||||
darwin8.[[0123]]|darwin8.[[0123]].*)
|
||||
#
|
||||
# Tiger, prior to Intel support. Build for 32-bit
|
||||
# PowerPC and 64-bit PowerPC, with 32-bit PowerPC
|
||||
# first. (I'm guessing that's what Apple does.)
|
||||
#
|
||||
V_CCOPT="$V_CCOPT -arch ppc -arch ppc64"
|
||||
LDFLAGS="$LDFLAGS -arch ppc -arch ppc64"
|
||||
;;
|
||||
|
||||
darwin8.[456]*)
|
||||
#
|
||||
# Tiger, subsequent to Intel support but prior to
|
||||
# x86-64 support. Build for 32-bit PowerPC, 64-bit
|
||||
# PowerPC, and x86, with 32-bit PowerPC first.
|
||||
# Tiger, prior to Intel support. Build
|
||||
# libraries and executables for 32-bit PowerPC
|
||||
# and 64-bit PowerPC, with 32-bit PowerPC first.
|
||||
# (I'm guessing that's what Apple does.)
|
||||
#
|
||||
V_CCOPT="$V_CCOPT -arch ppc -arch ppc64 -arch i386"
|
||||
LDFLAGS="$LDFLAGS -arch ppc -arch ppc64 -arch i386"
|
||||
# (The double brackets are needed because
|
||||
# autotools/m4 use brackets as a quoting
|
||||
# character; the double brackets turn into
|
||||
# single brackets in the generated configure
|
||||
# file.)
|
||||
#
|
||||
V_LIB_CCOPT_FAT="-arch ppc -arch ppc64"
|
||||
V_LIB_LDFLAGS_FAT="-arch ppc -arch ppc64"
|
||||
V_PROG_CCOPT_FAT="-arch ppc -arch ppc64"
|
||||
V_PROG_LDFLAGS_FAT="-arch ppc -arch ppc64"
|
||||
;;
|
||||
|
||||
darwin8.[[456]]|darwin.[[456]].*)
|
||||
#
|
||||
# Tiger, subsequent to Intel support but prior
|
||||
# to x86-64 support. Build libraries and
|
||||
# executables for 32-bit PowerPC, 64-bit
|
||||
# PowerPC, and 32-bit x86, with 32-bit PowerPC
|
||||
# first. (I'm guessing that's what Apple does.)
|
||||
#
|
||||
# (The double brackets are needed because
|
||||
# autotools/m4 use brackets as a quoting
|
||||
# character; the double brackets turn into
|
||||
# single brackets in the generated configure
|
||||
# file.)
|
||||
#
|
||||
V_LIB_CCOPT_FAT="-arch ppc -arch ppc64 -arch i386"
|
||||
V_LIB_LDFLAGS_FAT="-arch ppc -arch ppc64 -arch i386"
|
||||
V_PROG_CCOPT_FAT="-arch ppc -arch ppc64 -arch i386"
|
||||
V_PROG_LDFLAGS_FAT="-arch ppc -arch ppc64 -arch i386"
|
||||
;;
|
||||
|
||||
darwin8.*)
|
||||
#
|
||||
# All other Tiger, so subsequent to x86-64
|
||||
# support. Build for 32-bit PowerPC, 64-bit
|
||||
# PowerPC, x86, and x86-64, and with 32-bit PowerPC
|
||||
# first. (I'm guessing that's what Apple does.)
|
||||
# support. Build libraries and executables for
|
||||
# 32-bit PowerPC, 64-bit PowerPC, 32-bit x86,
|
||||
# and x86-64, with 32-bit PowerPC first. (I'm
|
||||
# guessing that's what Apple does.)
|
||||
#
|
||||
V_CCOPT="$V_CCOPT -arch ppc -arch ppc64 -arch i386 -arch x86_64"
|
||||
LDFLAGS="$LDFLAGS -arch ppc -arch ppc64 -arch i386 -arch x86_64"
|
||||
V_LIB_CCOPT_FAT="-arch ppc -arch ppc64 -arch i386 -arch x86_64"
|
||||
V_LIB_LDFLAGS_FAT="-arch ppc -arch ppc64 -arch i386 -arch x86_64"
|
||||
V_PROG_CCOPT_FAT="-arch ppc -arch ppc64 -arch i386 -arch x86_64"
|
||||
V_PROG_LDFLAGS_FAT="-arch ppc -arch ppc64 -arch i386 -arch x86_64"
|
||||
;;
|
||||
|
||||
darwin9.*)
|
||||
#
|
||||
# Leopard. Build for 32-bit PowerPC, 64-bit
|
||||
# PowerPC, x86, and x86-64, with 32-bit PowerPC
|
||||
# first. (That's what Apple does.)
|
||||
# Leopard. Build libraries for 32-bit PowerPC,
|
||||
# 64-bit PowerPC, 32-bit x86, and x86-64, with
|
||||
# 32-bit PowerPC first, and build executables
|
||||
# for 32-bit x86 and 32-bit PowerPC, with 32-bit
|
||||
# x86 first. (That's what Apple does.)
|
||||
#
|
||||
V_CCOPT="$V_CCOPT -arch ppc -arch ppc64 -arch i386 -arch x86_64"
|
||||
LDFLAGS="$LDFLAGS -arch ppc -arch ppc64 -arch i386 -arch x86_64"
|
||||
V_LIB_CCOPT_FAT="-arch ppc -arch ppc64 -arch i386 -arch x86_64"
|
||||
V_LIB_LDFLAGS_FAT="-arch ppc -arch ppc64 -arch i386 -arch x86_64"
|
||||
V_PROG_CCOPT_FAT="-arch i386 -arch ppc"
|
||||
V_PROG_LDFLAGS_FAT="-arch i386 -arch ppc"
|
||||
;;
|
||||
|
||||
darwin10.*)
|
||||
#
|
||||
# Snow Leopard. Build for x86-64, x86, and
|
||||
# 32-bit PowerPC, with x86-64 first. (That's
|
||||
# what Apple does, even though Snow Leopard
|
||||
# doesn't run on PPC, so PPC libpcap runs under
|
||||
# Rosetta, and Rosetta doesn't support BPF
|
||||
# ioctls, so PPC programs can't do live
|
||||
# captures.)
|
||||
# Snow Leopard. Build libraries for x86-64,
|
||||
# 32-bit x86, and 32-bit PowerPC, with x86-64
|
||||
# first, and build executables for x86-64 and
|
||||
# 32-bit x86, with x86-64 first. (That's what
|
||||
# Apple does, even though Snow Leopard doesn't
|
||||
# run on PPC, so PPC libpcap runs under Rosetta,
|
||||
# and Rosetta doesn't support BPF ioctls, so PPC
|
||||
# programs can't do live captures.)
|
||||
#
|
||||
V_CCOPT="$V_CCOPT -arch x86_64 -arch i386 -arch ppc"
|
||||
LDFLAGS="$LDFLAGS -arch x86_64 -arch i386 -arch ppc"
|
||||
V_LIB_CCOPT_FAT="-arch x86_64 -arch i386 -arch ppc"
|
||||
V_LIB_LDFLAGS_FAT="-arch x86_64 -arch i386 -arch ppc"
|
||||
V_PROG_CCOPT_FAT="-arch x86_64 -arch i386"
|
||||
V_PROG_LDFLAGS_FAT="-arch x86_64 -arch i386"
|
||||
;;
|
||||
|
||||
darwin*)
|
||||
#
|
||||
# Post-Snow Leopard. Build for x86-64 and
|
||||
# x86, with x86-64 first. (That's probably what
|
||||
# Apple does, given that Rosetta is gone.)
|
||||
# Post-Snow Leopard. Build libraries for x86-64
|
||||
# and 32-bit x86, with x86-64 first, and build
|
||||
# executables only for x86-64. (That's what
|
||||
# Apple does.) This requires no special flags
|
||||
# for programs.
|
||||
# XXX - update if and when Apple drops support
|
||||
# for 32-bit x86 code.
|
||||
# for 32-bit x86 code and if and when Apple adds
|
||||
# ARM-based Macs. (You're on your own for iOS
|
||||
# etc.)
|
||||
#
|
||||
V_CCOPT="$V_CCOPT -arch x86_64 -arch i386"
|
||||
LDFLAGS="$LDFLAGS -arch x86_64 -arch i386"
|
||||
# XXX - check whether we *can* build for
|
||||
# i386 and, if not, suggest that the user
|
||||
# install the /usr/include headers if they
|
||||
# want to build fat.
|
||||
#
|
||||
AC_MSG_CHECKING(whether building for 32-bit x86 is supported)
|
||||
save_CFLAGS="$CFLAGS"
|
||||
CFLAGS="$CFLAGS -arch i386"
|
||||
AC_TRY_COMPILE(
|
||||
[],
|
||||
[return 0;],
|
||||
[
|
||||
AC_MSG_RESULT(yes)
|
||||
V_LIB_CCOPT_FAT="-arch x86_64 -arch i386"
|
||||
V_LIB_LDFLAGS_FAT="-arch x86_64 -arch i386"
|
||||
],
|
||||
[
|
||||
AC_MSG_RESULT(no)
|
||||
V_LIB_CCOPT_FAT="-arch x86_64"
|
||||
V_LIB_LDFLAGS_FAT="-arch x86_64"
|
||||
case "$host_os" in
|
||||
|
||||
darwin18.*)
|
||||
#
|
||||
# Mojave; you need to install the
|
||||
# /usr/include headers to get
|
||||
# 32-bit x86 builds to work.
|
||||
#
|
||||
AC_MSG_WARN([Compiling for 32-bit x86 gives an error; try installing the command-line tools and, after that, installing the /usr/include headers from the /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg package])
|
||||
;;
|
||||
|
||||
*)
|
||||
#
|
||||
# Pre-Mojave; the command-line
|
||||
# tools should be sufficient to
|
||||
# enable 32-bit x86 builds.
|
||||
#
|
||||
AC_MSG_WARN([Compiling for 32-bit x86 gives an error; try installing the command-line tools])
|
||||
;;
|
||||
esac
|
||||
])
|
||||
CFLAGS="$save_CFLAGS"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
@@ -1699,7 +1920,7 @@ irix*)
|
||||
MAN_MISC_INFO=5
|
||||
;;
|
||||
|
||||
linux*|freebsd*|netbsd*|openbsd*|dragonfly*|kfreebsd*|gnu*)
|
||||
linux*|freebsd*|netbsd*|openbsd*|dragonfly*|kfreebsd*|gnu*|midipix*)
|
||||
DYEXT="so"
|
||||
|
||||
#
|
||||
@@ -1722,6 +1943,7 @@ osf*)
|
||||
#
|
||||
MAN_FILE_FORMATS=4
|
||||
MAN_MISC_INFO=5
|
||||
MAN_DEVICES=7
|
||||
;;
|
||||
|
||||
sinix*)
|
||||
@@ -1765,13 +1987,14 @@ solaris*)
|
||||
MAN_ADMIN_COMMANDS=1m
|
||||
MAN_FILE_FORMATS=4
|
||||
MAN_MISC_INFO=5
|
||||
MAN_DEVICES=7D
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_ARG_ENABLE(shared,
|
||||
AC_HELP_STRING([--enable-shared],[build shared libraries @<:@default=no@:>@]))
|
||||
test "x$enable_shared" != "xyes" && DYEXT="none"
|
||||
AC_HELP_STRING([--enable-shared],[build shared libraries @<:@default=yes, if support available@:>@]))
|
||||
test "x$enable_shared" = "xno" && DYEXT="none"
|
||||
|
||||
AC_PROG_RANLIB
|
||||
AC_CHECK_TOOL([AR], [ar])
|
||||
@@ -1820,19 +2043,26 @@ AC_CHECK_MEMBERS([dl_hp_ppa_info_t.dl_module_id_1],,,
|
||||
AC_LBL_UNALIGNED_ACCESS
|
||||
|
||||
AC_SUBST(V_CCOPT)
|
||||
AC_SUBST(V_LIB_CCOPT_FAT)
|
||||
AC_SUBST(V_LIB_LDFLAGS_FAT)
|
||||
AC_SUBST(V_PROG_CCOPT_FAT)
|
||||
AC_SUBST(V_PROG_LDFLAGS_FAT)
|
||||
AC_SUBST(V_DEFS)
|
||||
AC_SUBST(V_FINDALLDEVS)
|
||||
AC_SUBST(V_INCLS)
|
||||
AC_SUBST(V_LEX)
|
||||
AC_SUBST(V_PCAP)
|
||||
AC_SUBST(V_SHLIB_CCOPT)
|
||||
AC_SUBST(V_SHLIB_CMD)
|
||||
AC_SUBST(V_SHLIB_OPT)
|
||||
AC_SUBST(V_SONAME_OPT)
|
||||
AC_SUBST(V_RPATH_OPT)
|
||||
AC_SUBST(V_YACC)
|
||||
AC_SUBST(ADDLOBJS)
|
||||
AC_SUBST(ADDLARCHIVEOBJS)
|
||||
AC_SUBST(SSRC)
|
||||
AC_SUBST(DYEXT)
|
||||
AC_SUBST(MAN_DEVICES)
|
||||
AC_SUBST(MAN_FILE_FORMATS)
|
||||
AC_SUBST(MAN_MISC_INFO)
|
||||
AC_SUBST(MAN_ADMIN_COMMANDS)
|
||||
@@ -1843,9 +2073,9 @@ AC_SUBST(RPCAPD_LIBS)
|
||||
AC_SUBST(EXTRA_NETWORK_LIBS)
|
||||
|
||||
AC_ARG_ENABLE([usb],
|
||||
[AC_HELP_STRING([--enable-usb],[enable USB capture support @<:@default=no@:>@])],
|
||||
[AC_HELP_STRING([--enable-usb],[enable USB capture support @<:@default=yes, if support available@:>@])],
|
||||
[],
|
||||
[enable_usb=no])
|
||||
[enable_usb=yes])
|
||||
|
||||
if test "xxx_only" = yes; then
|
||||
# User requested something-else-only pcap, so they don't
|
||||
@@ -1991,9 +2221,9 @@ fi
|
||||
|
||||
|
||||
AC_ARG_ENABLE([bluetooth],
|
||||
[AC_HELP_STRING([--enable-bluetooth],[enable Bluetooth support @<:@default=no@:>@])],
|
||||
[AC_HELP_STRING([--enable-bluetooth],[enable Bluetooth support @<:@default=yes, if support available@:>@])],
|
||||
[],
|
||||
[enable_bluetooth=no])
|
||||
[enable_bluetooth=ifsupportavailable])
|
||||
|
||||
if test "xxx_only" = yes; then
|
||||
# User requested something-else-only pcap, so they don't
|
||||
@@ -2076,9 +2306,9 @@ if test "x$enable_bluetooth" != "xno" ; then
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE([dbus],
|
||||
[AC_HELP_STRING([--enable-dbus],[enable D-Bus capture support @<:@default=no@:>@])],
|
||||
[AC_HELP_STRING([--enable-dbus],[enable D-Bus capture support @<:@default=yes, if support available@:>@])],
|
||||
[],
|
||||
[enable_dbus=no])
|
||||
[enable_dbus=ifavailable])
|
||||
|
||||
if test "xxx_only" = yes; then
|
||||
# User requested something-else-only pcap, so they don't
|
||||
@@ -2167,15 +2397,15 @@ fi
|
||||
AC_ARG_ENABLE([rdma],
|
||||
[AC_HELP_STRING([--enable-rdma],[enable RDMA capture support @<:@default=yes, if support available@:>@])],
|
||||
[],
|
||||
[enable_rdmasniff=ifavailable])
|
||||
[enable_rdma=ifavailable])
|
||||
|
||||
if test "xxx_only" = yes; then
|
||||
# User requested something-else-only pcap, so they don't
|
||||
# want RDMA support.
|
||||
enable_rdmasniff=no
|
||||
enable_rdma=no
|
||||
fi
|
||||
|
||||
if test "x$enable_rdmasniff" != "xno"; then
|
||||
if test "x$enable_rdma" != "xno"; then
|
||||
AC_CHECK_LIB(ibverbs, ibv_get_device_list, [
|
||||
AC_CHECK_HEADER(infiniband/verbs.h, [
|
||||
#
|
||||
@@ -2228,7 +2458,8 @@ AC_OUTPUT(Makefile pcap-filter.manmisc pcap-linktype.manmisc
|
||||
pcap_compile.3pcap pcap_datalink.3pcap pcap_dump_open.3pcap
|
||||
pcap_get_tstamp_precision.3pcap pcap_list_datalinks.3pcap
|
||||
pcap_list_tstamp_types.3pcap pcap_open_dead.3pcap
|
||||
pcap_open_offline.3pcap pcap_set_tstamp_precision.3pcap
|
||||
pcap_set_tstamp_type.3pcap
|
||||
pcap_open_offline.3pcap pcap_set_immediate_mode.3pcap
|
||||
pcap_set_tstamp_precision.3pcap pcap_set_tstamp_type.3pcap
|
||||
rpcapd/Makefile rpcapd/rpcapd.manadmin rpcapd/rpcapd-config.manfile
|
||||
testprogs/Makefile)
|
||||
exit 0
|
||||
|
||||
@@ -65,11 +65,6 @@ pcap_fmt_errmsg_for_errno(char *errbuf, size_t errbuflen, int errnum,
|
||||
size_t msglen;
|
||||
char *p;
|
||||
size_t errbuflen_remaining;
|
||||
#if defined(HAVE_STRERROR_S)
|
||||
errno_t err;
|
||||
#elif defined(HAVE_STRERROR_R)
|
||||
int err;
|
||||
#endif
|
||||
|
||||
va_start(ap, fmt);
|
||||
pcap_vsnprintf(errbuf, errbuflen, fmt, ap);
|
||||
@@ -96,7 +91,10 @@ pcap_fmt_errmsg_for_errno(char *errbuf, size_t errbuflen, int errnum,
|
||||
* Now append the string for the error code.
|
||||
*/
|
||||
#if defined(HAVE_STRERROR_S)
|
||||
err = strerror_s(p, errbuflen_remaining, errnum);
|
||||
/*
|
||||
* We have a Windows-style strerror_s().
|
||||
*/
|
||||
errno_t err = strerror_s(p, errbuflen_remaining, errnum);
|
||||
if (err != 0) {
|
||||
/*
|
||||
* It doesn't appear to be documented anywhere obvious
|
||||
@@ -104,8 +102,24 @@ pcap_fmt_errmsg_for_errno(char *errbuf, size_t errbuflen, int errnum,
|
||||
*/
|
||||
pcap_snprintf(p, errbuflen_remaining, "Error %d", errnum);
|
||||
}
|
||||
#elif defined(HAVE_STRERROR_R)
|
||||
err = strerror_r(errnum, p, errbuflen_remaining);
|
||||
#elif defined(HAVE_GNU_STRERROR_R)
|
||||
/*
|
||||
* We have a GNU-style strerror_r(), which is *not* guaranteed to
|
||||
* do anything to the buffer handed to it, and which returns a
|
||||
* pointer to the error string, which may or may not be in
|
||||
* the buffer.
|
||||
*
|
||||
* It is, however, guaranteed to succeed.
|
||||
*/
|
||||
char strerror_buf[PCAP_ERRBUF_SIZE];
|
||||
char *errstring = strerror_r(errnum, strerror_buf, PCAP_ERRBUF_SIZE);
|
||||
pcap_snprintf(p, errbuflen_remaining, "%s", errstring);
|
||||
#elif defined(HAVE_POSIX_STRERROR_R)
|
||||
/*
|
||||
* We have a POSIX-style strerror_r(), which is guaranteed to fill
|
||||
* in the buffer, but is not guaranteed to succeed.
|
||||
*/
|
||||
int err = strerror_r(errnum, p, errbuflen_remaining);
|
||||
if (err == EINVAL) {
|
||||
/*
|
||||
* UNIX 03 says this isn't guaranteed to produce a
|
||||
@@ -129,3 +143,72 @@ pcap_fmt_errmsg_for_errno(char *errbuf, size_t errbuflen, int errnum,
|
||||
pcap_snprintf(p, errbuflen_remaining, "%s", pcap_strerror(errnum));
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
/*
|
||||
* Generate an error message based on a format, arguments, and a
|
||||
* Win32 error, with a message for the Win32 error after the formatted output.
|
||||
*/
|
||||
void
|
||||
pcap_fmt_errmsg_for_win32_err(char *errbuf, size_t errbuflen, DWORD errnum,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
size_t msglen;
|
||||
char *p;
|
||||
size_t errbuflen_remaining;
|
||||
DWORD retval;
|
||||
char win32_errbuf[PCAP_ERRBUF_SIZE+1];
|
||||
|
||||
va_start(ap, fmt);
|
||||
pcap_vsnprintf(errbuf, errbuflen, fmt, ap);
|
||||
va_end(ap);
|
||||
msglen = strlen(errbuf);
|
||||
|
||||
/*
|
||||
* Do we have enough space to append ": "?
|
||||
* Including the terminating '\0', that's 3 bytes.
|
||||
*/
|
||||
if (msglen + 3 > errbuflen) {
|
||||
/* No - just give them what we've produced. */
|
||||
return;
|
||||
}
|
||||
p = errbuf + msglen;
|
||||
errbuflen_remaining = errbuflen - msglen;
|
||||
*p++ = ':';
|
||||
*p++ = ' ';
|
||||
*p = '\0';
|
||||
msglen += 2;
|
||||
errbuflen_remaining -= 2;
|
||||
|
||||
/*
|
||||
* Now append the string for the error code.
|
||||
*
|
||||
* XXX - what language ID to use?
|
||||
*
|
||||
* For UN*Xes, pcap_strerror() may or may not return localized
|
||||
* strings.
|
||||
*
|
||||
* We currently don't have localized messages for libpcap, but
|
||||
* we might want to do so. On the other hand, if most of these
|
||||
* messages are going to be read by libpcap developers and
|
||||
* perhaps by developers of libpcap-based applications, English
|
||||
* might be a better choice, so the developer doesn't have to
|
||||
* get the message translated if it's in a language they don't
|
||||
* happen to understand.
|
||||
*/
|
||||
retval = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|FORMAT_MESSAGE_MAX_WIDTH_MASK,
|
||||
NULL, errnum, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
win32_errbuf, PCAP_ERRBUF_SIZE, NULL);
|
||||
if (retval == 0) {
|
||||
/*
|
||||
* Failed.
|
||||
*/
|
||||
pcap_snprintf(p, errbuflen_remaining,
|
||||
"Couldn't get error message for error (%lu)", errnum);
|
||||
return;
|
||||
}
|
||||
|
||||
pcap_snprintf(p, errbuflen_remaining, "%s (%lu)", win32_errbuf, errnum);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -43,6 +43,11 @@ extern "C" {
|
||||
void pcap_fmt_errmsg_for_errno(char *, size_t, int,
|
||||
PCAP_FORMAT_STRING(const char *), ...) PCAP_PRINTFLIKE(4, 5);
|
||||
|
||||
#ifdef _WIN32
|
||||
void pcap_fmt_errmsg_for_win32_err(char *, size_t, DWORD,
|
||||
PCAP_FORMAT_STRING(const char *), ...) PCAP_PRINTFLIKE(4, 5);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -85,20 +85,14 @@
|
||||
*/
|
||||
#elif defined(__linux__) || defined(linux) || defined(__linux)
|
||||
/*
|
||||
* We can't turn _GNU_SOURCE on because some versions of GNU Libc
|
||||
* will give the GNU version of strerror_r(), which returns a
|
||||
* string pointer and doesn't necessarily fill in the buffer,
|
||||
* rather than the standard version of strerror_r(), which
|
||||
* returns 0 or an errno and always fills in the buffer. We
|
||||
* require both of the latter behaviors.
|
||||
* Turn on _GNU_SOURCE to get everything GNU libc has to offer,
|
||||
* including asprintf().
|
||||
*
|
||||
* So we try turning everything else on that we can. This includes
|
||||
* defining _XOPEN_SOURCE as 600, because we want to force crypt()
|
||||
* to be declared on systems that use GNU libc, such as most Linux
|
||||
* distributions.
|
||||
* Unfortunately, one thing it has to offer is a strerror_r()
|
||||
* that's not POSIX-compliant, but we deal with that in
|
||||
* pcap_fmt_errmsg_for_errno().
|
||||
*/
|
||||
#define _POSIX_C_SOURCE 200809L
|
||||
#define _XOPEN_SOURCE 600
|
||||
#define _GNU_SOURCE
|
||||
|
||||
/*
|
||||
* We turn on both _DEFAULT_SOURCE and _BSD_SOURCE to try to get
|
||||
|
||||
1883
libpcap/gencode.c
1883
libpcap/gencode.c
File diff suppressed because it is too large
Load Diff
@@ -113,16 +113,14 @@
|
||||
#define Q_ISIS_L2 32
|
||||
/* PDU types */
|
||||
#define Q_ISIS_IIH 33
|
||||
#define Q_ISIS_LAN_IIH 34
|
||||
#define Q_ISIS_PTP_IIH 35
|
||||
#define Q_ISIS_SNP 36
|
||||
#define Q_ISIS_CSNP 37
|
||||
#define Q_ISIS_PSNP 38
|
||||
#define Q_ISIS_LSP 39
|
||||
#define Q_ISIS_SNP 34
|
||||
#define Q_ISIS_CSNP 35
|
||||
#define Q_ISIS_PSNP 36
|
||||
#define Q_ISIS_LSP 37
|
||||
|
||||
#define Q_RADIO 40
|
||||
#define Q_RADIO 38
|
||||
|
||||
#define Q_CARP 41
|
||||
#define Q_CARP 39
|
||||
|
||||
/* Directional qualifiers. */
|
||||
|
||||
@@ -299,8 +297,8 @@ void gen_or(struct block *, struct block *);
|
||||
void gen_not(struct block *);
|
||||
|
||||
struct block *gen_scode(compiler_state_t *, const char *, struct qual);
|
||||
struct block *gen_ecode(compiler_state_t *, const u_char *, struct qual);
|
||||
struct block *gen_acode(compiler_state_t *, const u_char *, struct qual);
|
||||
struct block *gen_ecode(compiler_state_t *, const char *, struct qual);
|
||||
struct block *gen_acode(compiler_state_t *, const char *, struct qual);
|
||||
struct block *gen_mcode(compiler_state_t *, const char *, const char *,
|
||||
unsigned int, struct qual);
|
||||
#ifdef INET6
|
||||
@@ -326,13 +324,13 @@ struct block *gen_llc_u(compiler_state_t *);
|
||||
struct block *gen_llc_s_subtype(compiler_state_t *, bpf_u_int32);
|
||||
struct block *gen_llc_u_subtype(compiler_state_t *, bpf_u_int32);
|
||||
|
||||
struct block *gen_vlan(compiler_state_t *, int);
|
||||
struct block *gen_mpls(compiler_state_t *, int);
|
||||
struct block *gen_vlan(compiler_state_t *, bpf_u_int32, int);
|
||||
struct block *gen_mpls(compiler_state_t *, bpf_u_int32, int);
|
||||
|
||||
struct block *gen_pppoed(compiler_state_t *);
|
||||
struct block *gen_pppoes(compiler_state_t *, int);
|
||||
struct block *gen_pppoes(compiler_state_t *, bpf_u_int32, int);
|
||||
|
||||
struct block *gen_geneve(compiler_state_t *, int);
|
||||
struct block *gen_geneve(compiler_state_t *, bpf_u_int32, int);
|
||||
|
||||
struct block *gen_atmfield_code(compiler_state_t *, int, bpf_int32,
|
||||
bpf_u_int32, int);
|
||||
@@ -343,29 +341,11 @@ struct block *gen_mtp2type_abbrev(compiler_state_t *, int type);
|
||||
struct block *gen_mtp3field_code(compiler_state_t *, int, bpf_u_int32,
|
||||
bpf_u_int32, int);
|
||||
|
||||
#ifndef HAVE_NET_PFVAR_H
|
||||
PCAP_NORETURN
|
||||
#endif
|
||||
struct block *gen_pf_ifname(compiler_state_t *, const char *);
|
||||
#ifndef HAVE_NET_PFVAR_H
|
||||
PCAP_NORETURN
|
||||
#endif
|
||||
struct block *gen_pf_rnr(compiler_state_t *, int);
|
||||
#ifndef HAVE_NET_PFVAR_H
|
||||
PCAP_NORETURN
|
||||
#endif
|
||||
struct block *gen_pf_srnr(compiler_state_t *, int);
|
||||
#ifndef HAVE_NET_PFVAR_H
|
||||
PCAP_NORETURN
|
||||
#endif
|
||||
struct block *gen_pf_ruleset(compiler_state_t *, char *);
|
||||
#ifndef HAVE_NET_PFVAR_H
|
||||
PCAP_NORETURN
|
||||
#endif
|
||||
struct block *gen_pf_reason(compiler_state_t *, int);
|
||||
#ifndef HAVE_NET_PFVAR_H
|
||||
PCAP_NORETURN
|
||||
#endif
|
||||
struct block *gen_pf_action(compiler_state_t *, int);
|
||||
|
||||
struct block *gen_p80211_type(compiler_state_t *, int, int);
|
||||
@@ -386,16 +366,15 @@ struct icode {
|
||||
int cur_mark;
|
||||
};
|
||||
|
||||
void bpf_optimize(compiler_state_t *, struct icode *ic);
|
||||
void PCAP_NORETURN bpf_syntax_error(compiler_state_t *, const char *);
|
||||
void PCAP_NORETURN bpf_error(compiler_state_t *, const char *, ...)
|
||||
int bpf_optimize(struct icode *, char *);
|
||||
void bpf_set_error(compiler_state_t *, const char *, ...)
|
||||
PCAP_PRINTFLIKE(2, 3);
|
||||
|
||||
void finish_parse(compiler_state_t *, struct block *);
|
||||
int finish_parse(compiler_state_t *, struct block *);
|
||||
char *sdup(compiler_state_t *, const char *);
|
||||
|
||||
struct bpf_insn *icode_to_fcode(compiler_state_t *, struct icode *,
|
||||
struct block *, u_int *);
|
||||
struct bpf_insn *icode_to_fcode(struct icode *, struct block *, u_int *,
|
||||
char *);
|
||||
void sappend(struct slist *, struct slist *);
|
||||
|
||||
/*
|
||||
|
||||
3665
libpcap/grammar.c
3665
libpcap/grammar.c
File diff suppressed because it is too large
Load Diff
@@ -1,323 +0,0 @@
|
||||
/* A Bison parser, made by GNU Bison 3.0.4. */
|
||||
|
||||
/* Bison interface for Yacc-like parsers in C
|
||||
|
||||
Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* As a special exception, you may create a larger work that contains
|
||||
part or all of the Bison parser skeleton and distribute that work
|
||||
under terms of your choice, so long as that work isn't itself a
|
||||
parser generator using the skeleton or a modified version thereof
|
||||
as a parser skeleton. Alternatively, if you modify or redistribute
|
||||
the parser skeleton itself, you may (at your option) remove this
|
||||
special exception, which will cause the skeleton and the resulting
|
||||
Bison output files to be licensed under the GNU General Public
|
||||
License without this special exception.
|
||||
|
||||
This special exception was added by the Free Software Foundation in
|
||||
version 2.2 of Bison. */
|
||||
|
||||
#ifndef YY_PCAP_GRAMMAR_H_INCLUDED
|
||||
# define YY_PCAP_GRAMMAR_H_INCLUDED
|
||||
/* Debug traces. */
|
||||
#ifndef YYDEBUG
|
||||
# define YYDEBUG 0
|
||||
#endif
|
||||
#if YYDEBUG
|
||||
extern int pcap_debug;
|
||||
#endif
|
||||
|
||||
/* Token type. */
|
||||
#ifndef YYTOKENTYPE
|
||||
# define YYTOKENTYPE
|
||||
enum yytokentype
|
||||
{
|
||||
DST = 258,
|
||||
SRC = 259,
|
||||
HOST = 260,
|
||||
GATEWAY = 261,
|
||||
NET = 262,
|
||||
NETMASK = 263,
|
||||
PORT = 264,
|
||||
PORTRANGE = 265,
|
||||
LESS = 266,
|
||||
GREATER = 267,
|
||||
PROTO = 268,
|
||||
PROTOCHAIN = 269,
|
||||
CBYTE = 270,
|
||||
ARP = 271,
|
||||
RARP = 272,
|
||||
IP = 273,
|
||||
SCTP = 274,
|
||||
TCP = 275,
|
||||
UDP = 276,
|
||||
ICMP = 277,
|
||||
IGMP = 278,
|
||||
IGRP = 279,
|
||||
PIM = 280,
|
||||
VRRP = 281,
|
||||
CARP = 282,
|
||||
ATALK = 283,
|
||||
AARP = 284,
|
||||
DECNET = 285,
|
||||
LAT = 286,
|
||||
SCA = 287,
|
||||
MOPRC = 288,
|
||||
MOPDL = 289,
|
||||
TK_BROADCAST = 290,
|
||||
TK_MULTICAST = 291,
|
||||
NUM = 292,
|
||||
INBOUND = 293,
|
||||
OUTBOUND = 294,
|
||||
PF_IFNAME = 295,
|
||||
PF_RSET = 296,
|
||||
PF_RNR = 297,
|
||||
PF_SRNR = 298,
|
||||
PF_REASON = 299,
|
||||
PF_ACTION = 300,
|
||||
TYPE = 301,
|
||||
SUBTYPE = 302,
|
||||
DIR = 303,
|
||||
ADDR1 = 304,
|
||||
ADDR2 = 305,
|
||||
ADDR3 = 306,
|
||||
ADDR4 = 307,
|
||||
RA = 308,
|
||||
TA = 309,
|
||||
LINK = 310,
|
||||
GEQ = 311,
|
||||
LEQ = 312,
|
||||
NEQ = 313,
|
||||
ID = 314,
|
||||
EID = 315,
|
||||
HID = 316,
|
||||
HID6 = 317,
|
||||
AID = 318,
|
||||
LSH = 319,
|
||||
RSH = 320,
|
||||
LEN = 321,
|
||||
IPV6 = 322,
|
||||
ICMPV6 = 323,
|
||||
AH = 324,
|
||||
ESP = 325,
|
||||
VLAN = 326,
|
||||
MPLS = 327,
|
||||
PPPOED = 328,
|
||||
PPPOES = 329,
|
||||
GENEVE = 330,
|
||||
ISO = 331,
|
||||
ESIS = 332,
|
||||
CLNP = 333,
|
||||
ISIS = 334,
|
||||
L1 = 335,
|
||||
L2 = 336,
|
||||
IIH = 337,
|
||||
LSP = 338,
|
||||
SNP = 339,
|
||||
CSNP = 340,
|
||||
PSNP = 341,
|
||||
STP = 342,
|
||||
IPX = 343,
|
||||
NETBEUI = 344,
|
||||
LANE = 345,
|
||||
LLC = 346,
|
||||
METAC = 347,
|
||||
BCC = 348,
|
||||
SC = 349,
|
||||
ILMIC = 350,
|
||||
OAMF4EC = 351,
|
||||
OAMF4SC = 352,
|
||||
OAM = 353,
|
||||
OAMF4 = 354,
|
||||
CONNECTMSG = 355,
|
||||
METACONNECT = 356,
|
||||
VPI = 357,
|
||||
VCI = 358,
|
||||
RADIO = 359,
|
||||
FISU = 360,
|
||||
LSSU = 361,
|
||||
MSU = 362,
|
||||
HFISU = 363,
|
||||
HLSSU = 364,
|
||||
HMSU = 365,
|
||||
SIO = 366,
|
||||
OPC = 367,
|
||||
DPC = 368,
|
||||
SLS = 369,
|
||||
HSIO = 370,
|
||||
HOPC = 371,
|
||||
HDPC = 372,
|
||||
HSLS = 373,
|
||||
OR = 374,
|
||||
AND = 375,
|
||||
UMINUS = 376
|
||||
};
|
||||
#endif
|
||||
/* Tokens. */
|
||||
#define DST 258
|
||||
#define SRC 259
|
||||
#define HOST 260
|
||||
#define GATEWAY 261
|
||||
#define NET 262
|
||||
#define NETMASK 263
|
||||
#define PORT 264
|
||||
#define PORTRANGE 265
|
||||
#define LESS 266
|
||||
#define GREATER 267
|
||||
#define PROTO 268
|
||||
#define PROTOCHAIN 269
|
||||
#define CBYTE 270
|
||||
#define ARP 271
|
||||
#define RARP 272
|
||||
#define IP 273
|
||||
#define SCTP 274
|
||||
#define TCP 275
|
||||
#define UDP 276
|
||||
#define ICMP 277
|
||||
#define IGMP 278
|
||||
#define IGRP 279
|
||||
#define PIM 280
|
||||
#define VRRP 281
|
||||
#define CARP 282
|
||||
#define ATALK 283
|
||||
#define AARP 284
|
||||
#define DECNET 285
|
||||
#define LAT 286
|
||||
#define SCA 287
|
||||
#define MOPRC 288
|
||||
#define MOPDL 289
|
||||
#define TK_BROADCAST 290
|
||||
#define TK_MULTICAST 291
|
||||
#define NUM 292
|
||||
#define INBOUND 293
|
||||
#define OUTBOUND 294
|
||||
#define PF_IFNAME 295
|
||||
#define PF_RSET 296
|
||||
#define PF_RNR 297
|
||||
#define PF_SRNR 298
|
||||
#define PF_REASON 299
|
||||
#define PF_ACTION 300
|
||||
#define TYPE 301
|
||||
#define SUBTYPE 302
|
||||
#define DIR 303
|
||||
#define ADDR1 304
|
||||
#define ADDR2 305
|
||||
#define ADDR3 306
|
||||
#define ADDR4 307
|
||||
#define RA 308
|
||||
#define TA 309
|
||||
#define LINK 310
|
||||
#define GEQ 311
|
||||
#define LEQ 312
|
||||
#define NEQ 313
|
||||
#define ID 314
|
||||
#define EID 315
|
||||
#define HID 316
|
||||
#define HID6 317
|
||||
#define AID 318
|
||||
#define LSH 319
|
||||
#define RSH 320
|
||||
#define LEN 321
|
||||
#define IPV6 322
|
||||
#define ICMPV6 323
|
||||
#define AH 324
|
||||
#define ESP 325
|
||||
#define VLAN 326
|
||||
#define MPLS 327
|
||||
#define PPPOED 328
|
||||
#define PPPOES 329
|
||||
#define GENEVE 330
|
||||
#define ISO 331
|
||||
#define ESIS 332
|
||||
#define CLNP 333
|
||||
#define ISIS 334
|
||||
#define L1 335
|
||||
#define L2 336
|
||||
#define IIH 337
|
||||
#define LSP 338
|
||||
#define SNP 339
|
||||
#define CSNP 340
|
||||
#define PSNP 341
|
||||
#define STP 342
|
||||
#define IPX 343
|
||||
#define NETBEUI 344
|
||||
#define LANE 345
|
||||
#define LLC 346
|
||||
#define METAC 347
|
||||
#define BCC 348
|
||||
#define SC 349
|
||||
#define ILMIC 350
|
||||
#define OAMF4EC 351
|
||||
#define OAMF4SC 352
|
||||
#define OAM 353
|
||||
#define OAMF4 354
|
||||
#define CONNECTMSG 355
|
||||
#define METACONNECT 356
|
||||
#define VPI 357
|
||||
#define VCI 358
|
||||
#define RADIO 359
|
||||
#define FISU 360
|
||||
#define LSSU 361
|
||||
#define MSU 362
|
||||
#define HFISU 363
|
||||
#define HLSSU 364
|
||||
#define HMSU 365
|
||||
#define SIO 366
|
||||
#define OPC 367
|
||||
#define DPC 368
|
||||
#define SLS 369
|
||||
#define HSIO 370
|
||||
#define HOPC 371
|
||||
#define HDPC 372
|
||||
#define HSLS 373
|
||||
#define OR 374
|
||||
#define AND 375
|
||||
#define UMINUS 376
|
||||
|
||||
/* Value type. */
|
||||
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
||||
|
||||
union YYSTYPE
|
||||
{
|
||||
#line 286 "grammar.y" /* yacc.c:1909 */
|
||||
|
||||
int i;
|
||||
bpf_u_int32 h;
|
||||
u_char *e;
|
||||
char *s;
|
||||
struct stmt *stmt;
|
||||
struct arth *a;
|
||||
struct {
|
||||
struct qual q;
|
||||
int atmfieldtype;
|
||||
int mtp3fieldtype;
|
||||
struct block *b;
|
||||
} blk;
|
||||
struct block *rblk;
|
||||
|
||||
#line 312 "grammar.h" /* yacc.c:1909 */
|
||||
};
|
||||
|
||||
typedef union YYSTYPE YYSTYPE;
|
||||
# define YYSTYPE_IS_TRIVIAL 1
|
||||
# define YYSTYPE_IS_DECLARED 1
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
int pcap_parse (void *yyscanner, compiler_state_t *cstate);
|
||||
|
||||
#endif /* !YY_PCAP_GRAMMAR_H_INCLUDED */
|
||||
@@ -216,13 +216,12 @@ str2tok(const char *str, const struct tok *toks)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static struct qual qerr = { Q_UNDEF, Q_UNDEF, Q_UNDEF, Q_UNDEF };
|
||||
static const struct qual qerr = { Q_UNDEF, Q_UNDEF, Q_UNDEF, Q_UNDEF };
|
||||
|
||||
static PCAP_NORETURN_DEF void
|
||||
static void
|
||||
yyerror(void *yyscanner _U_, compiler_state_t *cstate, const char *msg)
|
||||
{
|
||||
bpf_syntax_error(cstate, msg);
|
||||
/* NOTREACHED */
|
||||
bpf_set_error(cstate, "can't parse filter expression: %s", msg);
|
||||
}
|
||||
|
||||
#ifdef HAVE_NET_PFVAR_H
|
||||
@@ -236,8 +235,8 @@ pfreason_to_num(compiler_state_t *cstate, const char *reason)
|
||||
if (pcap_strcasecmp(reason, reasons[i]) == 0)
|
||||
return (i);
|
||||
}
|
||||
bpf_error(cstate, "unknown PF reason");
|
||||
/*NOTREACHED*/
|
||||
bpf_set_error(cstate, "unknown PF reason");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -260,33 +259,38 @@ pfaction_to_num(compiler_state_t *cstate, const char *action)
|
||||
return (PF_NORDR);
|
||||
#endif
|
||||
else {
|
||||
bpf_error(cstate, "unknown PF action");
|
||||
/*NOTREACHED*/
|
||||
bpf_set_error(cstate, "unknown PF action");
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
#else /* !HAVE_NET_PFVAR_H */
|
||||
static PCAP_NORETURN_DEF int
|
||||
static int
|
||||
pfreason_to_num(compiler_state_t *cstate, const char *reason _U_)
|
||||
{
|
||||
bpf_error(cstate, "libpcap was compiled on a machine without pf support");
|
||||
/*NOTREACHED*/
|
||||
bpf_set_error(cstate, "libpcap was compiled on a machine without pf support");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static PCAP_NORETURN_DEF int
|
||||
static int
|
||||
pfaction_to_num(compiler_state_t *cstate, const char *action _U_)
|
||||
{
|
||||
bpf_error(cstate, "libpcap was compiled on a machine without pf support");
|
||||
/*NOTREACHED*/
|
||||
bpf_set_error(cstate, "libpcap was compiled on a machine without pf support");
|
||||
return (-1);
|
||||
}
|
||||
#endif /* HAVE_NET_PFVAR_H */
|
||||
|
||||
/*
|
||||
* For calls that might return an "an error occurred" value.
|
||||
*/
|
||||
#define CHECK_INT_VAL(val) if (val == -1) YYABORT
|
||||
#define CHECK_PTR_VAL(val) if (val == NULL) YYABORT
|
||||
|
||||
DIAG_OFF_BISON_BYACC
|
||||
%}
|
||||
|
||||
%union {
|
||||
int i;
|
||||
bpf_u_int32 h;
|
||||
u_char *e;
|
||||
char *s;
|
||||
struct stmt *stmt;
|
||||
struct arth *a;
|
||||
@@ -340,11 +344,9 @@ DIAG_OFF_BISON_BYACC
|
||||
%token RADIO
|
||||
%token FISU LSSU MSU HFISU HLSSU HMSU
|
||||
%token SIO OPC DPC SLS HSIO HOPC HDPC HSLS
|
||||
%token LEX_ERROR
|
||||
|
||||
|
||||
%type <s> ID
|
||||
%type <e> EID
|
||||
%type <e> AID
|
||||
%type <s> ID EID AID
|
||||
%type <s> HID HID6
|
||||
%type <i> NUM action reason type subtype type_subtype dir
|
||||
|
||||
@@ -359,7 +361,7 @@ DIAG_OFF_BISON_BYACC
|
||||
%%
|
||||
prog: null expr
|
||||
{
|
||||
finish_parse(cstate, $2.b);
|
||||
CHECK_INT_VAL(finish_parse(cstate, $2.b));
|
||||
}
|
||||
| null
|
||||
;
|
||||
@@ -376,64 +378,58 @@ and: AND { $$ = $<blk>0; }
|
||||
or: OR { $$ = $<blk>0; }
|
||||
;
|
||||
id: nid
|
||||
| pnum { $$.b = gen_ncode(cstate, NULL, (bpf_u_int32)$1,
|
||||
$$.q = $<blk>0.q); }
|
||||
| pnum { CHECK_PTR_VAL(($$.b = gen_ncode(cstate, NULL, (bpf_u_int32)$1,
|
||||
$$.q = $<blk>0.q))); }
|
||||
| paren pid ')' { $$ = $2; }
|
||||
;
|
||||
nid: ID { $$.b = gen_scode(cstate, $1, $$.q = $<blk>0.q); }
|
||||
| HID '/' NUM { $$.b = gen_mcode(cstate, $1, NULL, $3,
|
||||
$$.q = $<blk>0.q); }
|
||||
| HID NETMASK HID { $$.b = gen_mcode(cstate, $1, $3, 0,
|
||||
$$.q = $<blk>0.q); }
|
||||
nid: ID { CHECK_PTR_VAL($1); CHECK_PTR_VAL(($$.b = gen_scode(cstate, $1, $$.q = $<blk>0.q))); }
|
||||
| HID '/' NUM { CHECK_PTR_VAL($1); CHECK_PTR_VAL(($$.b = gen_mcode(cstate, $1, NULL, $3,
|
||||
$$.q = $<blk>0.q))); }
|
||||
| HID NETMASK HID { CHECK_PTR_VAL($1); CHECK_PTR_VAL(($$.b = gen_mcode(cstate, $1, $3, 0,
|
||||
$$.q = $<blk>0.q))); }
|
||||
| HID {
|
||||
CHECK_PTR_VAL($1);
|
||||
/* Decide how to parse HID based on proto */
|
||||
$$.q = $<blk>0.q;
|
||||
if ($$.q.addr == Q_PORT)
|
||||
bpf_error(cstate, "'port' modifier applied to ip host");
|
||||
else if ($$.q.addr == Q_PORTRANGE)
|
||||
bpf_error(cstate, "'portrange' modifier applied to ip host");
|
||||
else if ($$.q.addr == Q_PROTO)
|
||||
bpf_error(cstate, "'proto' modifier applied to ip host");
|
||||
else if ($$.q.addr == Q_PROTOCHAIN)
|
||||
bpf_error(cstate, "'protochain' modifier applied to ip host");
|
||||
$$.b = gen_ncode(cstate, $1, 0, $$.q);
|
||||
if ($$.q.addr == Q_PORT) {
|
||||
bpf_set_error(cstate, "'port' modifier applied to ip host");
|
||||
YYABORT;
|
||||
} else if ($$.q.addr == Q_PORTRANGE) {
|
||||
bpf_set_error(cstate, "'portrange' modifier applied to ip host");
|
||||
YYABORT;
|
||||
} else if ($$.q.addr == Q_PROTO) {
|
||||
bpf_set_error(cstate, "'proto' modifier applied to ip host");
|
||||
YYABORT;
|
||||
} else if ($$.q.addr == Q_PROTOCHAIN) {
|
||||
bpf_set_error(cstate, "'protochain' modifier applied to ip host");
|
||||
YYABORT;
|
||||
}
|
||||
CHECK_PTR_VAL(($$.b = gen_ncode(cstate, $1, 0, $$.q)));
|
||||
}
|
||||
| HID6 '/' NUM {
|
||||
CHECK_PTR_VAL($1);
|
||||
#ifdef INET6
|
||||
$$.b = gen_mcode6(cstate, $1, NULL, $3,
|
||||
$$.q = $<blk>0.q);
|
||||
CHECK_PTR_VAL(($$.b = gen_mcode6(cstate, $1, NULL, $3,
|
||||
$$.q = $<blk>0.q)));
|
||||
#else
|
||||
bpf_error(cstate, "'ip6addr/prefixlen' not supported "
|
||||
bpf_set_error(cstate, "'ip6addr/prefixlen' not supported "
|
||||
"in this configuration");
|
||||
YYABORT;
|
||||
#endif /*INET6*/
|
||||
}
|
||||
| HID6 {
|
||||
CHECK_PTR_VAL($1);
|
||||
#ifdef INET6
|
||||
$$.b = gen_mcode6(cstate, $1, 0, 128,
|
||||
$$.q = $<blk>0.q);
|
||||
CHECK_PTR_VAL(($$.b = gen_mcode6(cstate, $1, 0, 128,
|
||||
$$.q = $<blk>0.q)));
|
||||
#else
|
||||
bpf_error(cstate, "'ip6addr' not supported "
|
||||
bpf_set_error(cstate, "'ip6addr' not supported "
|
||||
"in this configuration");
|
||||
YYABORT;
|
||||
#endif /*INET6*/
|
||||
}
|
||||
| EID {
|
||||
$$.b = gen_ecode(cstate, $1, $$.q = $<blk>0.q);
|
||||
/*
|
||||
* $1 was allocated by "pcap_ether_aton()",
|
||||
* so we must free it now that we're done
|
||||
* with it.
|
||||
*/
|
||||
free($1);
|
||||
}
|
||||
| AID {
|
||||
$$.b = gen_acode(cstate, $1, $$.q = $<blk>0.q);
|
||||
/*
|
||||
* $1 was allocated by "pcap_ether_aton()",
|
||||
* so we must free it now that we're done
|
||||
* with it.
|
||||
*/
|
||||
free($1);
|
||||
}
|
||||
| EID { CHECK_PTR_VAL($1); CHECK_PTR_VAL(($$.b = gen_ecode(cstate, $1, $$.q = $<blk>0.q))); }
|
||||
| AID { CHECK_PTR_VAL($1); CHECK_PTR_VAL(($$.b = gen_acode(cstate, $1, $$.q = $<blk>0.q))); }
|
||||
| not id { gen_not($2.b); $$ = $2; }
|
||||
;
|
||||
not: '!' { $$ = $<blk>0; }
|
||||
@@ -444,8 +440,8 @@ pid: nid
|
||||
| qid and id { gen_and($1.b, $3.b); $$ = $3; }
|
||||
| qid or id { gen_or($1.b, $3.b); $$ = $3; }
|
||||
;
|
||||
qid: pnum { $$.b = gen_ncode(cstate, NULL, (bpf_u_int32)$1,
|
||||
$$.q = $<blk>0.q); }
|
||||
qid: pnum { CHECK_PTR_VAL(($$.b = gen_ncode(cstate, NULL, (bpf_u_int32)$1,
|
||||
$$.q = $<blk>0.q))); }
|
||||
| pid
|
||||
;
|
||||
term: rterm
|
||||
@@ -455,21 +451,28 @@ head: pqual dqual aqual { QSET($$.q, $1, $2, $3); }
|
||||
| pqual dqual { QSET($$.q, $1, $2, Q_DEFAULT); }
|
||||
| pqual aqual { QSET($$.q, $1, Q_DEFAULT, $2); }
|
||||
| pqual PROTO { QSET($$.q, $1, Q_DEFAULT, Q_PROTO); }
|
||||
| pqual PROTOCHAIN { QSET($$.q, $1, Q_DEFAULT, Q_PROTOCHAIN); }
|
||||
| pqual PROTOCHAIN {
|
||||
#ifdef NO_PROTOCHAIN
|
||||
bpf_set_error(cstate, "protochain not supported");
|
||||
YYABORT;
|
||||
#else
|
||||
QSET($$.q, $1, Q_DEFAULT, Q_PROTOCHAIN);
|
||||
#endif
|
||||
}
|
||||
| pqual ndaqual { QSET($$.q, $1, Q_DEFAULT, $2); }
|
||||
;
|
||||
rterm: head id { $$ = $2; }
|
||||
| paren expr ')' { $$.b = $2.b; $$.q = $1.q; }
|
||||
| pname { $$.b = gen_proto_abbrev(cstate, $1); $$.q = qerr; }
|
||||
| arth relop arth { $$.b = gen_relation(cstate, $2, $1, $3, 0);
|
||||
| pname { CHECK_PTR_VAL(($$.b = gen_proto_abbrev(cstate, $1))); $$.q = qerr; }
|
||||
| arth relop arth { CHECK_PTR_VAL(($$.b = gen_relation(cstate, $2, $1, $3, 0)));
|
||||
$$.q = qerr; }
|
||||
| arth irelop arth { $$.b = gen_relation(cstate, $2, $1, $3, 1);
|
||||
| arth irelop arth { CHECK_PTR_VAL(($$.b = gen_relation(cstate, $2, $1, $3, 1)));
|
||||
$$.q = qerr; }
|
||||
| other { $$.b = $1; $$.q = qerr; }
|
||||
| atmtype { $$.b = gen_atmtype_abbrev(cstate, $1); $$.q = qerr; }
|
||||
| atmmultitype { $$.b = gen_atmmulti_abbrev(cstate, $1); $$.q = qerr; }
|
||||
| atmtype { CHECK_PTR_VAL(($$.b = gen_atmtype_abbrev(cstate, $1))); $$.q = qerr; }
|
||||
| atmmultitype { CHECK_PTR_VAL(($$.b = gen_atmmulti_abbrev(cstate, $1))); $$.q = qerr; }
|
||||
| atmfield atmvalue { $$.b = $2.b; $$.q = qerr; }
|
||||
| mtp2type { $$.b = gen_mtp2type_abbrev(cstate, $1); $$.q = qerr; }
|
||||
| mtp2type { CHECK_PTR_VAL(($$.b = gen_mtp2type_abbrev(cstate, $1))); $$.q = qerr; }
|
||||
| mtp3field mtp3value { $$.b = $2.b; $$.q = qerr; }
|
||||
;
|
||||
/* protocol level qualifiers */
|
||||
@@ -539,65 +542,69 @@ pname: LINK { $$ = Q_LINK; }
|
||||
| NETBEUI { $$ = Q_NETBEUI; }
|
||||
| RADIO { $$ = Q_RADIO; }
|
||||
;
|
||||
other: pqual TK_BROADCAST { $$ = gen_broadcast(cstate, $1); }
|
||||
| pqual TK_MULTICAST { $$ = gen_multicast(cstate, $1); }
|
||||
| LESS NUM { $$ = gen_less(cstate, $2); }
|
||||
| GREATER NUM { $$ = gen_greater(cstate, $2); }
|
||||
| CBYTE NUM byteop NUM { $$ = gen_byteop(cstate, $3, $2, $4); }
|
||||
| INBOUND { $$ = gen_inbound(cstate, 0); }
|
||||
| OUTBOUND { $$ = gen_inbound(cstate, 1); }
|
||||
| VLAN pnum { $$ = gen_vlan(cstate, $2); }
|
||||
| VLAN { $$ = gen_vlan(cstate, -1); }
|
||||
| MPLS pnum { $$ = gen_mpls(cstate, $2); }
|
||||
| MPLS { $$ = gen_mpls(cstate, -1); }
|
||||
| PPPOED { $$ = gen_pppoed(cstate); }
|
||||
| PPPOES pnum { $$ = gen_pppoes(cstate, $2); }
|
||||
| PPPOES { $$ = gen_pppoes(cstate, -1); }
|
||||
| GENEVE pnum { $$ = gen_geneve(cstate, $2); }
|
||||
| GENEVE { $$ = gen_geneve(cstate, -1); }
|
||||
other: pqual TK_BROADCAST { CHECK_PTR_VAL(($$ = gen_broadcast(cstate, $1))); }
|
||||
| pqual TK_MULTICAST { CHECK_PTR_VAL(($$ = gen_multicast(cstate, $1))); }
|
||||
| LESS NUM { CHECK_PTR_VAL(($$ = gen_less(cstate, $2))); }
|
||||
| GREATER NUM { CHECK_PTR_VAL(($$ = gen_greater(cstate, $2))); }
|
||||
| CBYTE NUM byteop NUM { CHECK_PTR_VAL(($$ = gen_byteop(cstate, $3, $2, $4))); }
|
||||
| INBOUND { CHECK_PTR_VAL(($$ = gen_inbound(cstate, 0))); }
|
||||
| OUTBOUND { CHECK_PTR_VAL(($$ = gen_inbound(cstate, 1))); }
|
||||
| VLAN pnum { CHECK_PTR_VAL(($$ = gen_vlan(cstate, (bpf_u_int32)$2, 1))); }
|
||||
| VLAN { CHECK_PTR_VAL(($$ = gen_vlan(cstate, 0, 0))); }
|
||||
| MPLS pnum { CHECK_PTR_VAL(($$ = gen_mpls(cstate, (bpf_u_int32)$2, 1))); }
|
||||
| MPLS { CHECK_PTR_VAL(($$ = gen_mpls(cstate, 0, 0))); }
|
||||
| PPPOED { CHECK_PTR_VAL(($$ = gen_pppoed(cstate))); }
|
||||
| PPPOES pnum { CHECK_PTR_VAL(($$ = gen_pppoes(cstate, (bpf_u_int32)$2, 1))); }
|
||||
| PPPOES { CHECK_PTR_VAL(($$ = gen_pppoes(cstate, 0, 0))); }
|
||||
| GENEVE pnum { CHECK_PTR_VAL(($$ = gen_geneve(cstate, (bpf_u_int32)$2, 1))); }
|
||||
| GENEVE { CHECK_PTR_VAL(($$ = gen_geneve(cstate, 0, 0))); }
|
||||
| pfvar { $$ = $1; }
|
||||
| pqual p80211 { $$ = $2; }
|
||||
| pllc { $$ = $1; }
|
||||
;
|
||||
|
||||
pfvar: PF_IFNAME ID { $$ = gen_pf_ifname(cstate, $2); }
|
||||
| PF_RSET ID { $$ = gen_pf_ruleset(cstate, $2); }
|
||||
| PF_RNR NUM { $$ = gen_pf_rnr(cstate, $2); }
|
||||
| PF_SRNR NUM { $$ = gen_pf_srnr(cstate, $2); }
|
||||
| PF_REASON reason { $$ = gen_pf_reason(cstate, $2); }
|
||||
| PF_ACTION action { $$ = gen_pf_action(cstate, $2); }
|
||||
pfvar: PF_IFNAME ID { CHECK_PTR_VAL($2); CHECK_PTR_VAL(($$ = gen_pf_ifname(cstate, $2))); }
|
||||
| PF_RSET ID { CHECK_PTR_VAL($2); CHECK_PTR_VAL(($$ = gen_pf_ruleset(cstate, $2))); }
|
||||
| PF_RNR NUM { CHECK_PTR_VAL(($$ = gen_pf_rnr(cstate, $2))); }
|
||||
| PF_SRNR NUM { CHECK_PTR_VAL(($$ = gen_pf_srnr(cstate, $2))); }
|
||||
| PF_REASON reason { CHECK_PTR_VAL(($$ = gen_pf_reason(cstate, $2))); }
|
||||
| PF_ACTION action { CHECK_PTR_VAL(($$ = gen_pf_action(cstate, $2))); }
|
||||
;
|
||||
|
||||
p80211: TYPE type SUBTYPE subtype
|
||||
{ $$ = gen_p80211_type(cstate, $2 | $4,
|
||||
{ CHECK_PTR_VAL(($$ = gen_p80211_type(cstate, $2 | $4,
|
||||
IEEE80211_FC0_TYPE_MASK |
|
||||
IEEE80211_FC0_SUBTYPE_MASK);
|
||||
IEEE80211_FC0_SUBTYPE_MASK)));
|
||||
}
|
||||
| TYPE type { $$ = gen_p80211_type(cstate, $2,
|
||||
IEEE80211_FC0_TYPE_MASK);
|
||||
| TYPE type { CHECK_PTR_VAL(($$ = gen_p80211_type(cstate, $2,
|
||||
IEEE80211_FC0_TYPE_MASK)));
|
||||
}
|
||||
| SUBTYPE type_subtype { $$ = gen_p80211_type(cstate, $2,
|
||||
| SUBTYPE type_subtype { CHECK_PTR_VAL(($$ = gen_p80211_type(cstate, $2,
|
||||
IEEE80211_FC0_TYPE_MASK |
|
||||
IEEE80211_FC0_SUBTYPE_MASK);
|
||||
IEEE80211_FC0_SUBTYPE_MASK)));
|
||||
}
|
||||
| DIR dir { $$ = gen_p80211_fcdir(cstate, $2); }
|
||||
| DIR dir { CHECK_PTR_VAL(($$ = gen_p80211_fcdir(cstate, $2))); }
|
||||
;
|
||||
|
||||
type: NUM
|
||||
| ID { $$ = str2tok($1, ieee80211_types);
|
||||
if ($$ == -1)
|
||||
bpf_error(cstate, "unknown 802.11 type name");
|
||||
| ID { CHECK_PTR_VAL($1);
|
||||
$$ = str2tok($1, ieee80211_types);
|
||||
if ($$ == -1) {
|
||||
bpf_set_error(cstate, "unknown 802.11 type name");
|
||||
YYABORT;
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
subtype: NUM
|
||||
| ID { const struct tok *types = NULL;
|
||||
int i;
|
||||
CHECK_PTR_VAL($1);
|
||||
for (i = 0;; i++) {
|
||||
if (ieee80211_type_subtypes[i].tok == NULL) {
|
||||
/* Ran out of types */
|
||||
bpf_error(cstate, "unknown 802.11 type");
|
||||
break;
|
||||
bpf_set_error(cstate, "unknown 802.11 type");
|
||||
YYABORT;
|
||||
}
|
||||
if ($<i>-1 == ieee80211_type_subtypes[i].type) {
|
||||
types = ieee80211_type_subtypes[i].tok;
|
||||
@@ -606,17 +613,20 @@ subtype: NUM
|
||||
}
|
||||
|
||||
$$ = str2tok($1, types);
|
||||
if ($$ == -1)
|
||||
bpf_error(cstate, "unknown 802.11 subtype name");
|
||||
if ($$ == -1) {
|
||||
bpf_set_error(cstate, "unknown 802.11 subtype name");
|
||||
YYABORT;
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
type_subtype: ID { int i;
|
||||
CHECK_PTR_VAL($1);
|
||||
for (i = 0;; i++) {
|
||||
if (ieee80211_type_subtypes[i].tok == NULL) {
|
||||
/* Ran out of types */
|
||||
bpf_error(cstate, "unknown 802.11 type name");
|
||||
break;
|
||||
bpf_set_error(cstate, "unknown 802.11 type name");
|
||||
YYABORT;
|
||||
}
|
||||
$$ = str2tok($1, ieee80211_type_subtypes[i].tok);
|
||||
if ($$ != -1) {
|
||||
@@ -627,33 +637,37 @@ type_subtype: ID { int i;
|
||||
}
|
||||
;
|
||||
|
||||
pllc: LLC { $$ = gen_llc(cstate); }
|
||||
| LLC ID { if (pcap_strcasecmp($2, "i") == 0)
|
||||
$$ = gen_llc_i(cstate);
|
||||
else if (pcap_strcasecmp($2, "s") == 0)
|
||||
$$ = gen_llc_s(cstate);
|
||||
else if (pcap_strcasecmp($2, "u") == 0)
|
||||
$$ = gen_llc_u(cstate);
|
||||
else {
|
||||
pllc: LLC { CHECK_PTR_VAL(($$ = gen_llc(cstate))); }
|
||||
| LLC ID { CHECK_PTR_VAL($2);
|
||||
if (pcap_strcasecmp($2, "i") == 0) {
|
||||
CHECK_PTR_VAL(($$ = gen_llc_i(cstate)));
|
||||
} else if (pcap_strcasecmp($2, "s") == 0) {
|
||||
CHECK_PTR_VAL(($$ = gen_llc_s(cstate)));
|
||||
} else if (pcap_strcasecmp($2, "u") == 0) {
|
||||
CHECK_PTR_VAL(($$ = gen_llc_u(cstate)));
|
||||
} else {
|
||||
int subtype;
|
||||
|
||||
subtype = str2tok($2, llc_s_subtypes);
|
||||
if (subtype != -1)
|
||||
$$ = gen_llc_s_subtype(cstate, subtype);
|
||||
else {
|
||||
if (subtype != -1) {
|
||||
CHECK_PTR_VAL(($$ = gen_llc_s_subtype(cstate, subtype)));
|
||||
} else {
|
||||
subtype = str2tok($2, llc_u_subtypes);
|
||||
if (subtype == -1)
|
||||
bpf_error(cstate, "unknown LLC type name \"%s\"", $2);
|
||||
$$ = gen_llc_u_subtype(cstate, subtype);
|
||||
if (subtype == -1) {
|
||||
bpf_set_error(cstate, "unknown LLC type name \"%s\"", $2);
|
||||
YYABORT;
|
||||
}
|
||||
CHECK_PTR_VAL(($$ = gen_llc_u_subtype(cstate, subtype)));
|
||||
}
|
||||
}
|
||||
}
|
||||
/* sigh, "rnr" is already a keyword for PF */
|
||||
| LLC PF_RNR { $$ = gen_llc_s_subtype(cstate, LLC_RNR); }
|
||||
| LLC PF_RNR { CHECK_PTR_VAL(($$ = gen_llc_s_subtype(cstate, LLC_RNR))); }
|
||||
;
|
||||
|
||||
dir: NUM
|
||||
| ID { if (pcap_strcasecmp($1, "nods") == 0)
|
||||
| ID { CHECK_PTR_VAL($1);
|
||||
if (pcap_strcasecmp($1, "nods") == 0)
|
||||
$$ = IEEE80211_FC1_DIR_NODS;
|
||||
else if (pcap_strcasecmp($1, "tods") == 0)
|
||||
$$ = IEEE80211_FC1_DIR_TODS;
|
||||
@@ -661,16 +675,18 @@ dir: NUM
|
||||
$$ = IEEE80211_FC1_DIR_FROMDS;
|
||||
else if (pcap_strcasecmp($1, "dstods") == 0)
|
||||
$$ = IEEE80211_FC1_DIR_DSTODS;
|
||||
else
|
||||
bpf_error(cstate, "unknown 802.11 direction");
|
||||
else {
|
||||
bpf_set_error(cstate, "unknown 802.11 direction");
|
||||
YYABORT;
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
reason: NUM { $$ = $1; }
|
||||
| ID { $$ = pfreason_to_num(cstate, $1); }
|
||||
| ID { CHECK_PTR_VAL($1); CHECK_INT_VAL(($$ = pfreason_to_num(cstate, $1))); }
|
||||
;
|
||||
|
||||
action: ID { $$ = pfaction_to_num(cstate, $1); }
|
||||
action: ID { CHECK_PTR_VAL($1); CHECK_INT_VAL(($$ = pfaction_to_num(cstate, $1))); }
|
||||
;
|
||||
|
||||
relop: '>' { $$ = BPF_JGT; }
|
||||
@@ -681,24 +697,24 @@ irelop: LEQ { $$ = BPF_JGT; }
|
||||
| '<' { $$ = BPF_JGE; }
|
||||
| NEQ { $$ = BPF_JEQ; }
|
||||
;
|
||||
arth: pnum { $$ = gen_loadi(cstate, $1); }
|
||||
arth: pnum { CHECK_PTR_VAL(($$ = gen_loadi(cstate, $1))); }
|
||||
| narth
|
||||
;
|
||||
narth: pname '[' arth ']' { $$ = gen_load(cstate, $1, $3, 1); }
|
||||
| pname '[' arth ':' NUM ']' { $$ = gen_load(cstate, $1, $3, $5); }
|
||||
| arth '+' arth { $$ = gen_arth(cstate, BPF_ADD, $1, $3); }
|
||||
| arth '-' arth { $$ = gen_arth(cstate, BPF_SUB, $1, $3); }
|
||||
| arth '*' arth { $$ = gen_arth(cstate, BPF_MUL, $1, $3); }
|
||||
| arth '/' arth { $$ = gen_arth(cstate, BPF_DIV, $1, $3); }
|
||||
| arth '%' arth { $$ = gen_arth(cstate, BPF_MOD, $1, $3); }
|
||||
| arth '&' arth { $$ = gen_arth(cstate, BPF_AND, $1, $3); }
|
||||
| arth '|' arth { $$ = gen_arth(cstate, BPF_OR, $1, $3); }
|
||||
| arth '^' arth { $$ = gen_arth(cstate, BPF_XOR, $1, $3); }
|
||||
| arth LSH arth { $$ = gen_arth(cstate, BPF_LSH, $1, $3); }
|
||||
| arth RSH arth { $$ = gen_arth(cstate, BPF_RSH, $1, $3); }
|
||||
| '-' arth %prec UMINUS { $$ = gen_neg(cstate, $2); }
|
||||
narth: pname '[' arth ']' { CHECK_PTR_VAL(($$ = gen_load(cstate, $1, $3, 1))); }
|
||||
| pname '[' arth ':' NUM ']' { CHECK_PTR_VAL(($$ = gen_load(cstate, $1, $3, $5))); }
|
||||
| arth '+' arth { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_ADD, $1, $3))); }
|
||||
| arth '-' arth { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_SUB, $1, $3))); }
|
||||
| arth '*' arth { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_MUL, $1, $3))); }
|
||||
| arth '/' arth { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_DIV, $1, $3))); }
|
||||
| arth '%' arth { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_MOD, $1, $3))); }
|
||||
| arth '&' arth { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_AND, $1, $3))); }
|
||||
| arth '|' arth { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_OR, $1, $3))); }
|
||||
| arth '^' arth { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_XOR, $1, $3))); }
|
||||
| arth LSH arth { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_LSH, $1, $3))); }
|
||||
| arth RSH arth { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_RSH, $1, $3))); }
|
||||
| '-' arth %prec UMINUS { CHECK_PTR_VAL(($$ = gen_neg(cstate, $2))); }
|
||||
| paren narth ')' { $$ = $2; }
|
||||
| LEN { $$ = gen_loadlen(cstate); }
|
||||
| LEN { CHECK_PTR_VAL(($$ = gen_loadlen(cstate))); }
|
||||
;
|
||||
byteop: '&' { $$ = '&'; }
|
||||
| '|' { $$ = '|'; }
|
||||
@@ -727,15 +743,15 @@ atmfield: VPI { $$.atmfieldtype = A_VPI; }
|
||||
| VCI { $$.atmfieldtype = A_VCI; }
|
||||
;
|
||||
atmvalue: atmfieldvalue
|
||||
| relop NUM { $$.b = gen_atmfield_code(cstate, $<blk>0.atmfieldtype, (bpf_int32)$2, (bpf_u_int32)$1, 0); }
|
||||
| irelop NUM { $$.b = gen_atmfield_code(cstate, $<blk>0.atmfieldtype, (bpf_int32)$2, (bpf_u_int32)$1, 1); }
|
||||
| relop NUM { CHECK_PTR_VAL(($$.b = gen_atmfield_code(cstate, $<blk>0.atmfieldtype, (bpf_int32)$2, (bpf_u_int32)$1, 0))); }
|
||||
| irelop NUM { CHECK_PTR_VAL(($$.b = gen_atmfield_code(cstate, $<blk>0.atmfieldtype, (bpf_int32)$2, (bpf_u_int32)$1, 1))); }
|
||||
| paren atmlistvalue ')' { $$.b = $2.b; $$.q = qerr; }
|
||||
;
|
||||
atmfieldvalue: NUM {
|
||||
$$.atmfieldtype = $<blk>0.atmfieldtype;
|
||||
if ($$.atmfieldtype == A_VPI ||
|
||||
$$.atmfieldtype == A_VCI)
|
||||
$$.b = gen_atmfield_code(cstate, $$.atmfieldtype, (bpf_int32) $1, BPF_JEQ, 0);
|
||||
CHECK_PTR_VAL(($$.b = gen_atmfield_code(cstate, $$.atmfieldtype, (bpf_int32) $1, BPF_JEQ, 0)));
|
||||
}
|
||||
;
|
||||
atmlistvalue: atmfieldvalue
|
||||
@@ -760,8 +776,8 @@ mtp3field: SIO { $$.mtp3fieldtype = M_SIO; }
|
||||
| HSLS { $$.mtp3fieldtype = MH_SLS; }
|
||||
;
|
||||
mtp3value: mtp3fieldvalue
|
||||
| relop NUM { $$.b = gen_mtp3field_code(cstate, $<blk>0.mtp3fieldtype, (u_int)$2, (u_int)$1, 0); }
|
||||
| irelop NUM { $$.b = gen_mtp3field_code(cstate, $<blk>0.mtp3fieldtype, (u_int)$2, (u_int)$1, 1); }
|
||||
| relop NUM { CHECK_PTR_VAL(($$.b = gen_mtp3field_code(cstate, $<blk>0.mtp3fieldtype, (u_int)$2, (u_int)$1, 0))); }
|
||||
| irelop NUM { CHECK_PTR_VAL(($$.b = gen_mtp3field_code(cstate, $<blk>0.mtp3fieldtype, (u_int)$2, (u_int)$1, 1))); }
|
||||
| paren mtp3listvalue ')' { $$.b = $2.b; $$.q = qerr; }
|
||||
;
|
||||
mtp3fieldvalue: NUM {
|
||||
@@ -774,7 +790,7 @@ mtp3fieldvalue: NUM {
|
||||
$$.mtp3fieldtype == MH_OPC ||
|
||||
$$.mtp3fieldtype == MH_DPC ||
|
||||
$$.mtp3fieldtype == MH_SLS)
|
||||
$$.b = gen_mtp3field_code(cstate, $$.mtp3fieldtype, (u_int) $1, BPF_JEQ, 0);
|
||||
CHECK_PTR_VAL(($$.b = gen_mtp3field_code(cstate, $$.mtp3fieldtype, (u_int) $1, BPF_JEQ, 0)));
|
||||
}
|
||||
;
|
||||
mtp3listvalue: mtp3fieldvalue
|
||||
|
||||
101
libpcap/missing/asprintf.c
Normal file
101
libpcap/missing/asprintf.c
Normal file
@@ -0,0 +1,101 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "portability.h"
|
||||
|
||||
/*
|
||||
* vasprintf() and asprintf() for platforms with a C99-compliant
|
||||
* snprintf() - so that, if you format into a 1-byte buffer, it
|
||||
* will return how many characters it would have produced had
|
||||
* it been given an infinite-sized buffer.
|
||||
*/
|
||||
int
|
||||
pcap_vasprintf(char **strp, const char *format, va_list args)
|
||||
{
|
||||
char buf;
|
||||
int len;
|
||||
size_t str_size;
|
||||
char *str;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* XXX - the C99 standard says, in section 7.19.6.5 "Thes
|
||||
* nprintf function":
|
||||
*
|
||||
* The snprintf function is equivalent to fprintf, except that
|
||||
* the output is written into an array (specified by argument s)
|
||||
* rather than to a stream. If n is zero, nothing is written,
|
||||
* and s may be a null pointer. Otherwise, output characters
|
||||
* beyond the n-1st are discarded rather than being written
|
||||
* to the array, and a null character is written at the end
|
||||
* of the characters actually written into the array.
|
||||
*
|
||||
* ...
|
||||
*
|
||||
* The snprintf function returns the number of characters that
|
||||
* would have been written had n been sufficiently large, not
|
||||
* counting the terminating null character, or a negative value
|
||||
* if an encoding error occurred. Thus, the null-terminated
|
||||
* output has been completely written if and only if the returned
|
||||
* value is nonnegative and less than n.
|
||||
*
|
||||
* That doesn't make it entirely clear whether, if a null buffer
|
||||
* pointer and a zero count are passed, it will return the number
|
||||
* of characters that would have been written had a buffer been
|
||||
* passed.
|
||||
*
|
||||
* And, even if C99 *does*, in fact, say it has to work, it
|
||||
* doesn't work in Solaris 8, for example - it returns -1 for
|
||||
* NULL/0, but returns the correct character count for a 1-byte
|
||||
* buffer.
|
||||
*
|
||||
* So we pass a one-character pointer in order to find out how
|
||||
* many characters this format and those arguments will need
|
||||
* without actually generating any more of those characters
|
||||
* than we need.
|
||||
*
|
||||
* (The fact that it might happen to work with GNU libc or with
|
||||
* various BSD libcs is completely uninteresting, as those tend
|
||||
* to have asprintf() already and thus don't even *need* this
|
||||
* code; this is for use in those UN*Xes that *don't* have
|
||||
* asprintf().)
|
||||
*/
|
||||
len = vsnprintf(&buf, sizeof buf, format, args);
|
||||
if (len == -1) {
|
||||
*strp = NULL;
|
||||
return (-1);
|
||||
}
|
||||
str_size = len + 1;
|
||||
str = malloc(str_size);
|
||||
if (str == NULL) {
|
||||
*strp = NULL;
|
||||
return (-1);
|
||||
}
|
||||
ret = vsnprintf(str, str_size, format, args);
|
||||
if (ret == -1) {
|
||||
free(str);
|
||||
*strp = NULL;
|
||||
return (-1);
|
||||
}
|
||||
*strp = str;
|
||||
/*
|
||||
* vsnprintf() shouldn't truncate the string, as we have
|
||||
* allocated a buffer large enough to hold the string, so its
|
||||
* return value should be the number of characters written.
|
||||
*/
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
pcap_asprintf(char **strp, const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
int ret;
|
||||
|
||||
va_start(args, format);
|
||||
ret = pcap_vasprintf(strp, format, args);
|
||||
va_end(args);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1995-1999 Kungliga Tekniska H<EFBFBD>gskolan
|
||||
* Copyright (c) 1995-1999 Kungliga Tekniska Högskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -31,6 +31,10 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* We use this for platforms that don't have snprintf() at all.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
@@ -42,7 +46,7 @@
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <pcap-int.h>
|
||||
#include "portability.h"
|
||||
|
||||
enum format_flags {
|
||||
minus_flag = 1,
|
||||
@@ -525,6 +529,7 @@ pcap_asnprintf (char **ret, size_t max_sz, const char *format, ...)
|
||||
|
||||
va_start(args, format);
|
||||
val = pcap_vasnprintf (ret, max_sz, format, args);
|
||||
va_end(args);
|
||||
|
||||
#ifdef PARANOIA
|
||||
{
|
||||
@@ -534,14 +539,15 @@ pcap_asnprintf (char **ret, size_t max_sz, const char *format, ...)
|
||||
if (tmp == NULL)
|
||||
abort ();
|
||||
|
||||
va_start(args, format);
|
||||
ret2 = pcap_vsprintf (tmp, format, args);
|
||||
va_end(args);
|
||||
if (val != ret2 || strcmp(*ret, tmp))
|
||||
abort ();
|
||||
free (tmp);
|
||||
}
|
||||
#endif
|
||||
|
||||
va_end(args);
|
||||
return val;
|
||||
}
|
||||
#endif
|
||||
|
||||
61
libpcap/missing/strlcat.c
Normal file
61
libpcap/missing/strlcat.c
Normal file
@@ -0,0 +1,61 @@
|
||||
/* $OpenBSD: pcap_strlcat.c,v 1.15 2015/03/02 21:41:08 millert Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998, 2015 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "portability.h"
|
||||
|
||||
/*
|
||||
* Appends src to string dst of size dsize (unlike strncat, dsize is the
|
||||
* full size of dst, not space left). At most dsize-1 characters
|
||||
* will be copied. Always NUL terminates (unless dsize <= strlen(dst)).
|
||||
* Returns strlen(src) + MIN(dsize, strlen(initial dst)).
|
||||
* If retval >= dsize, truncation occurred.
|
||||
*/
|
||||
size_t
|
||||
pcap_strlcat(char * restrict dst, const char * restrict src, size_t dsize)
|
||||
{
|
||||
const char *odst = dst;
|
||||
const char *osrc = src;
|
||||
size_t n = dsize;
|
||||
size_t dlen;
|
||||
|
||||
/* Find the end of dst and adjust bytes left but don't go past end. */
|
||||
while (n-- != 0 && *dst != '\0')
|
||||
dst++;
|
||||
dlen = dst - odst;
|
||||
n = dsize - dlen;
|
||||
|
||||
if (n-- == 0)
|
||||
return(dlen + strlen(src));
|
||||
while (*src != '\0') {
|
||||
if (n != 0) {
|
||||
*dst++ = *src;
|
||||
n--;
|
||||
}
|
||||
src++;
|
||||
}
|
||||
*dst = '\0';
|
||||
|
||||
return(dlen + (src - osrc)); /* count does not include NUL */
|
||||
}
|
||||
56
libpcap/missing/strlcpy.c
Normal file
56
libpcap/missing/strlcpy.c
Normal file
@@ -0,0 +1,56 @@
|
||||
/* $OpenBSD: pcap_strlcpy.c,v 1.12 2015/01/15 03:54:12 millert Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998, 2015 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "portability.h"
|
||||
|
||||
/*
|
||||
* Copy string src to buffer dst of size dsize. At most dsize-1
|
||||
* chars will be copied. Always NUL terminates (unless dsize == 0).
|
||||
* Returns strlen(src); if retval >= dsize, truncation occurred.
|
||||
*/
|
||||
size_t
|
||||
pcap_strlcpy(char * restrict dst, const char * restrict src, size_t dsize)
|
||||
{
|
||||
const char *osrc = src;
|
||||
size_t nleft = dsize;
|
||||
|
||||
/* Copy as many bytes as will fit. */
|
||||
if (nleft != 0) {
|
||||
while (--nleft != 0) {
|
||||
if ((*dst++ = *src++) == '\0')
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Not enough room in dst, add NUL and traverse rest of src. */
|
||||
if (nleft == 0) {
|
||||
if (dsize != 0)
|
||||
*dst = '\0'; /* NUL-terminate dst */
|
||||
while (*src++)
|
||||
;
|
||||
}
|
||||
|
||||
return(src - osrc - 1); /* count does not include NUL */
|
||||
}
|
||||
51
libpcap/missing/win_asprintf.c
Normal file
51
libpcap/missing/win_asprintf.c
Normal file
@@ -0,0 +1,51 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "portability.h"
|
||||
|
||||
int
|
||||
pcap_vasprintf(char **strp, const char *format, va_list args)
|
||||
{
|
||||
int len;
|
||||
size_t str_size;
|
||||
char *str;
|
||||
int ret;
|
||||
|
||||
len = _vscprintf(format, args);
|
||||
if (len == -1) {
|
||||
*strp = NULL;
|
||||
return (-1);
|
||||
}
|
||||
str_size = len + 1;
|
||||
str = malloc(str_size);
|
||||
if (str == NULL) {
|
||||
*strp = NULL;
|
||||
return (-1);
|
||||
}
|
||||
ret = pcap_vsnprintf(str, str_size, format, args);
|
||||
if (ret == -1) {
|
||||
free(str);
|
||||
*strp = NULL;
|
||||
return (-1);
|
||||
}
|
||||
*strp = str;
|
||||
/*
|
||||
* pcap_vsnprintf() shouldn't truncate the string, as we have
|
||||
* allocated a buffer large enough to hold the string, so its
|
||||
* return value should be the number of characters printed.
|
||||
*/
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
pcap_asprintf(char **strp, const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
int ret;
|
||||
|
||||
va_start(args, format);
|
||||
ret = pcap_vasprintf(strp, format, args);
|
||||
va_end(args);
|
||||
return (ret);
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "portability.h"
|
||||
|
||||
int
|
||||
pcap_vsnprintf(char *str, size_t str_size, const char *format, va_list args)
|
||||
{
|
||||
@@ -13,6 +15,16 @@ pcap_vsnprintf(char *str, size_t str_size, const char *format, va_list args)
|
||||
* that str is null-terminated, but C99's vsnprintf()
|
||||
* and snprintf() do, and we want to offer C99 behavior,
|
||||
* so forcibly null-terminate the string.
|
||||
*
|
||||
* We don't, however, offer C99 behavior for the return
|
||||
* value; _vsnprintf_s() returns -1, not the number of
|
||||
* characters that would have been put into the buffer
|
||||
* had it been large enough, if the string is truncated.
|
||||
* The only way to get that value is to use _vscprintf();
|
||||
* getting that count isn't worth the re-formatting.
|
||||
*
|
||||
* XXX - does _vsnprintf_s() return -1 on a formatting
|
||||
* error?
|
||||
*/
|
||||
str[str_size - 1] = '\0';
|
||||
return (ret);
|
||||
|
||||
@@ -231,7 +231,22 @@ pcap_nametonetaddr(const char *name)
|
||||
int h_errnoval;
|
||||
int err;
|
||||
|
||||
err = getnetbyname_r(name, &result_buf, buf, sizeof buf, &np,
|
||||
/*
|
||||
* Apparently, the man page at
|
||||
*
|
||||
* http://man7.org/linux/man-pages/man3/getnetbyname_r.3.html
|
||||
*
|
||||
* lies when it says
|
||||
*
|
||||
* If the function call successfully obtains a network record,
|
||||
* then *result is set pointing to result_buf; otherwise, *result
|
||||
* is set to NULL.
|
||||
*
|
||||
* and, in fact, at least in some versions of GNU libc, it does
|
||||
* *not* always get set if getnetbyname_r() succeeds.
|
||||
*/
|
||||
np = NULL;
|
||||
err = getnetbyname_r(name, &result_buf, buf, sizeof buf, &np,
|
||||
&h_errnoval);
|
||||
if (err != 0) {
|
||||
/*
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
#include <setjmp.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <errno.h>
|
||||
@@ -226,6 +227,16 @@ struct vmapinfo {
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
/*
|
||||
* Place to longjmp to on an error.
|
||||
*/
|
||||
jmp_buf top_ctx;
|
||||
|
||||
/*
|
||||
* The buffer into which to put error message.
|
||||
*/
|
||||
char *errbuf;
|
||||
|
||||
/*
|
||||
* A flag to indicate that further optimization is needed.
|
||||
* Iterative passes are continued until a given pass yields no
|
||||
@@ -252,19 +263,19 @@ typedef struct {
|
||||
* True if a is in uset {p}
|
||||
*/
|
||||
#define SET_MEMBER(p, a) \
|
||||
((p)[(unsigned)(a) / BITS_PER_WORD] & (1 << ((unsigned)(a) % BITS_PER_WORD)))
|
||||
((p)[(unsigned)(a) / BITS_PER_WORD] & ((bpf_u_int32)1 << ((unsigned)(a) % BITS_PER_WORD)))
|
||||
|
||||
/*
|
||||
* Add 'a' to uset p.
|
||||
*/
|
||||
#define SET_INSERT(p, a) \
|
||||
(p)[(unsigned)(a) / BITS_PER_WORD] |= (1 << ((unsigned)(a) % BITS_PER_WORD))
|
||||
(p)[(unsigned)(a) / BITS_PER_WORD] |= ((bpf_u_int32)1 << ((unsigned)(a) % BITS_PER_WORD))
|
||||
|
||||
/*
|
||||
* Delete 'a' from uset p.
|
||||
*/
|
||||
#define SET_DELETE(p, a) \
|
||||
(p)[(unsigned)(a) / BITS_PER_WORD] &= ~(1 << ((unsigned)(a) % BITS_PER_WORD))
|
||||
(p)[(unsigned)(a) / BITS_PER_WORD] &= ~((bpf_u_int32)1 << ((unsigned)(a) % BITS_PER_WORD))
|
||||
|
||||
/*
|
||||
* a := a intersect b
|
||||
@@ -311,6 +322,16 @@ typedef struct {
|
||||
} opt_state_t;
|
||||
|
||||
typedef struct {
|
||||
/*
|
||||
* Place to longjmp to on an error.
|
||||
*/
|
||||
jmp_buf top_ctx;
|
||||
|
||||
/*
|
||||
* The buffer into which to put error message.
|
||||
*/
|
||||
char *errbuf;
|
||||
|
||||
/*
|
||||
* Some pointers used to convert the basic block form of the code,
|
||||
* into the array form that BPF requires. 'fstart' will point to
|
||||
@@ -321,14 +342,16 @@ typedef struct {
|
||||
struct bpf_insn *ftail;
|
||||
} conv_state_t;
|
||||
|
||||
static void opt_init(compiler_state_t *, opt_state_t *, struct icode *);
|
||||
static void opt_init(opt_state_t *, struct icode *);
|
||||
static void opt_cleanup(opt_state_t *);
|
||||
static void PCAP_NORETURN opt_error(opt_state_t *, const char *, ...)
|
||||
PCAP_PRINTFLIKE(2, 3);
|
||||
|
||||
static void intern_blocks(opt_state_t *, struct icode *);
|
||||
|
||||
static void find_inedges(opt_state_t *, struct block *);
|
||||
#ifdef BDEBUG
|
||||
static void opt_dump(compiler_state_t *, struct icode *);
|
||||
static void opt_dump(opt_state_t *, struct icode *);
|
||||
#endif
|
||||
|
||||
#ifndef MAX
|
||||
@@ -699,8 +722,7 @@ vstore(struct stmt *s, int *valp, int newval, int alter)
|
||||
* (Unary operators are handled elsewhere.)
|
||||
*/
|
||||
static void
|
||||
fold_op(compiler_state_t *cstate, opt_state_t *opt_state,
|
||||
struct stmt *s, int v0, int v1)
|
||||
fold_op(opt_state_t *opt_state, struct stmt *s, int v0, int v1)
|
||||
{
|
||||
bpf_u_int32 a, b;
|
||||
|
||||
@@ -722,13 +744,13 @@ fold_op(compiler_state_t *cstate, opt_state_t *opt_state,
|
||||
|
||||
case BPF_DIV:
|
||||
if (b == 0)
|
||||
bpf_error(cstate, "division by zero");
|
||||
opt_error(opt_state, "division by zero");
|
||||
a /= b;
|
||||
break;
|
||||
|
||||
case BPF_MOD:
|
||||
if (b == 0)
|
||||
bpf_error(cstate, "modulus by zero");
|
||||
opt_error(opt_state, "modulus by zero");
|
||||
a %= b;
|
||||
break;
|
||||
|
||||
@@ -745,11 +767,39 @@ fold_op(compiler_state_t *cstate, opt_state_t *opt_state,
|
||||
break;
|
||||
|
||||
case BPF_LSH:
|
||||
a <<= b;
|
||||
/*
|
||||
* A left shift of more than the width of the type
|
||||
* is undefined in C; we'll just treat it as shifting
|
||||
* all the bits out.
|
||||
*
|
||||
* XXX - the BPF interpreter doesn't check for this,
|
||||
* so its behavior is dependent on the behavior of
|
||||
* the processor on which it's running. There are
|
||||
* processors on which it shifts all the bits out
|
||||
* and processors on which it does no shift.
|
||||
*/
|
||||
if (b < 32)
|
||||
a <<= b;
|
||||
else
|
||||
a = 0;
|
||||
break;
|
||||
|
||||
case BPF_RSH:
|
||||
a >>= b;
|
||||
/*
|
||||
* A right shift of more than the width of the type
|
||||
* is undefined in C; we'll just treat it as shifting
|
||||
* all the bits out.
|
||||
*
|
||||
* XXX - the BPF interpreter doesn't check for this,
|
||||
* so its behavior is dependent on the behavior of
|
||||
* the processor on which it's running. There are
|
||||
* processors on which it shifts all the bits out
|
||||
* and processors on which it does no shift.
|
||||
*/
|
||||
if (b < 32)
|
||||
a >>= b;
|
||||
else
|
||||
a = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -1041,8 +1091,7 @@ opt_peep(opt_state_t *opt_state, struct block *b)
|
||||
* evaluation and code transformations weren't folded together.
|
||||
*/
|
||||
static void
|
||||
opt_stmt(compiler_state_t *cstate, opt_state_t *opt_state,
|
||||
struct stmt *s, int val[], int alter)
|
||||
opt_stmt(opt_state_t *opt_state, struct stmt *s, int val[], int alter)
|
||||
{
|
||||
int op;
|
||||
int v;
|
||||
@@ -1094,7 +1143,23 @@ opt_stmt(compiler_state_t *cstate, opt_state_t *opt_state,
|
||||
case BPF_ALU|BPF_NEG:
|
||||
if (alter && opt_state->vmap[val[A_ATOM]].is_const) {
|
||||
s->code = BPF_LD|BPF_IMM;
|
||||
s->k = -opt_state->vmap[val[A_ATOM]].const_val;
|
||||
/*
|
||||
* Do this negation as unsigned arithmetic; that's
|
||||
* what modern BPF engines do, and it guarantees
|
||||
* that all possible values can be negated. (Yeah,
|
||||
* negating 0x80000000, the minimum signed 32-bit
|
||||
* two's-complement value, results in 0x80000000,
|
||||
* so it's still negative, but we *should* be doing
|
||||
* all unsigned arithmetic here, to match what
|
||||
* modern BPF engines do.)
|
||||
*
|
||||
* Express it as 0U - (unsigned value) so that we
|
||||
* don't get compiler warnings about negating an
|
||||
* unsigned value and don't get UBSan warnings
|
||||
* about the result of negating 0x80000000 being
|
||||
* undefined.
|
||||
*/
|
||||
s->k = 0U - (bpf_u_int32)(opt_state->vmap[val[A_ATOM]].const_val);
|
||||
val[A_ATOM] = K(s->k);
|
||||
}
|
||||
else
|
||||
@@ -1114,9 +1179,17 @@ opt_stmt(compiler_state_t *cstate, opt_state_t *opt_state,
|
||||
op = BPF_OP(s->code);
|
||||
if (alter) {
|
||||
if (s->k == 0) {
|
||||
/* don't optimize away "sub #0"
|
||||
/*
|
||||
* Optimize operations where the constant
|
||||
* is zero.
|
||||
*
|
||||
* Don't optimize away "sub #0"
|
||||
* as it may be needed later to
|
||||
* fixup the generated math code */
|
||||
* fixup the generated math code.
|
||||
*
|
||||
* Fail if we're dividing by zero or taking
|
||||
* a modulus by zero.
|
||||
*/
|
||||
if (op == BPF_ADD ||
|
||||
op == BPF_LSH || op == BPF_RSH ||
|
||||
op == BPF_OR || op == BPF_XOR) {
|
||||
@@ -1128,9 +1201,15 @@ opt_stmt(compiler_state_t *cstate, opt_state_t *opt_state,
|
||||
val[A_ATOM] = K(s->k);
|
||||
break;
|
||||
}
|
||||
if (op == BPF_DIV)
|
||||
opt_error(opt_state,
|
||||
"division by zero");
|
||||
if (op == BPF_MOD)
|
||||
opt_error(opt_state,
|
||||
"modulus by zero");
|
||||
}
|
||||
if (opt_state->vmap[val[A_ATOM]].is_const) {
|
||||
fold_op(cstate, opt_state, s, val[A_ATOM], K(s->k));
|
||||
fold_op(opt_state, s, val[A_ATOM], K(s->k));
|
||||
val[A_ATOM] = K(s->k);
|
||||
break;
|
||||
}
|
||||
@@ -1151,12 +1230,22 @@ opt_stmt(compiler_state_t *cstate, opt_state_t *opt_state,
|
||||
op = BPF_OP(s->code);
|
||||
if (alter && opt_state->vmap[val[X_ATOM]].is_const) {
|
||||
if (opt_state->vmap[val[A_ATOM]].is_const) {
|
||||
fold_op(cstate, opt_state, s, val[A_ATOM], val[X_ATOM]);
|
||||
fold_op(opt_state, s, val[A_ATOM], val[X_ATOM]);
|
||||
val[A_ATOM] = K(s->k);
|
||||
}
|
||||
else {
|
||||
s->code = BPF_ALU|BPF_K|op;
|
||||
s->k = opt_state->vmap[val[X_ATOM]].const_val;
|
||||
/*
|
||||
* XXX - we need to make up our minds
|
||||
* as to what integers are signed and
|
||||
* what integers are unsigned in BPF
|
||||
* programs and in our IR.
|
||||
*/
|
||||
if ((op == BPF_LSH || op == BPF_RSH) &&
|
||||
(s->k < 0 || s->k > 31))
|
||||
opt_error(opt_state,
|
||||
"shift by more than 31 bits");
|
||||
opt_state->done = 0;
|
||||
val[A_ATOM] =
|
||||
F(opt_state, s->code, val[A_ATOM], K(s->k));
|
||||
@@ -1275,8 +1364,7 @@ opt_deadstores(opt_state_t *opt_state, register struct block *b)
|
||||
}
|
||||
|
||||
static void
|
||||
opt_blk(compiler_state_t *cstate, opt_state_t *opt_state,
|
||||
struct block *b, int do_stmts)
|
||||
opt_blk(opt_state_t *opt_state, struct block *b, int do_stmts)
|
||||
{
|
||||
struct slist *s;
|
||||
struct edge *p;
|
||||
@@ -1326,7 +1414,7 @@ opt_blk(compiler_state_t *cstate, opt_state_t *opt_state,
|
||||
aval = b->val[A_ATOM];
|
||||
xval = b->val[X_ATOM];
|
||||
for (s = b->stmts; s; s = s->next)
|
||||
opt_stmt(cstate, opt_state, &s->s, b->val, do_stmts);
|
||||
opt_stmt(opt_state, &s->s, b->val, do_stmts);
|
||||
|
||||
/*
|
||||
* This is a special case: if we don't use anything from this
|
||||
@@ -1480,7 +1568,7 @@ opt_j(opt_state_t *opt_state, struct edge *ep)
|
||||
|
||||
while (x != 0) {
|
||||
k = lowest_set_bit(x);
|
||||
x &=~ (1 << k);
|
||||
x &=~ ((bpf_u_int32)1 << k);
|
||||
k += i * BITS_PER_WORD;
|
||||
|
||||
target = fold_edge(ep->succ, opt_state->edges[k]);
|
||||
@@ -1687,8 +1775,7 @@ and_pullup(opt_state_t *opt_state, struct block *b)
|
||||
}
|
||||
|
||||
static void
|
||||
opt_blks(compiler_state_t *cstate, opt_state_t *opt_state, struct icode *ic,
|
||||
int do_stmts)
|
||||
opt_blks(opt_state_t *opt_state, struct icode *ic, int do_stmts)
|
||||
{
|
||||
int i, maxlevel;
|
||||
struct block *p;
|
||||
@@ -1699,7 +1786,7 @@ opt_blks(compiler_state_t *cstate, opt_state_t *opt_state, struct icode *ic,
|
||||
find_inedges(opt_state, ic->root);
|
||||
for (i = maxlevel; i >= 0; --i)
|
||||
for (p = opt_state->levels[i]; p; p = p->link)
|
||||
opt_blk(cstate, opt_state, p, do_stmts);
|
||||
opt_blk(opt_state, p, do_stmts);
|
||||
|
||||
if (do_stmts)
|
||||
/*
|
||||
@@ -1777,14 +1864,13 @@ opt_root(struct block **b)
|
||||
}
|
||||
|
||||
static void
|
||||
opt_loop(compiler_state_t *cstate, opt_state_t *opt_state, struct icode *ic,
|
||||
int do_stmts)
|
||||
opt_loop(opt_state_t *opt_state, struct icode *ic, int do_stmts)
|
||||
{
|
||||
|
||||
#ifdef BDEBUG
|
||||
if (pcap_optimizer_debug > 1 || pcap_print_dot_graph) {
|
||||
printf("opt_loop(root, %d) begin\n", do_stmts);
|
||||
opt_dump(cstate, ic);
|
||||
opt_dump(opt_state, ic);
|
||||
}
|
||||
#endif
|
||||
do {
|
||||
@@ -1794,11 +1880,11 @@ opt_loop(compiler_state_t *cstate, opt_state_t *opt_state, struct icode *ic,
|
||||
find_closure(opt_state, ic->root);
|
||||
find_ud(opt_state, ic->root);
|
||||
find_edom(opt_state, ic->root);
|
||||
opt_blks(cstate, opt_state, ic, do_stmts);
|
||||
opt_blks(opt_state, ic, do_stmts);
|
||||
#ifdef BDEBUG
|
||||
if (pcap_optimizer_debug > 1 || pcap_print_dot_graph) {
|
||||
printf("opt_loop(root, %d) bottom, done=%d\n", do_stmts, opt_state->done);
|
||||
opt_dump(cstate, ic);
|
||||
opt_dump(opt_state, ic);
|
||||
}
|
||||
#endif
|
||||
} while (!opt_state->done);
|
||||
@@ -1806,30 +1892,38 @@ opt_loop(compiler_state_t *cstate, opt_state_t *opt_state, struct icode *ic,
|
||||
|
||||
/*
|
||||
* Optimize the filter code in its dag representation.
|
||||
* Return 0 on success, -1 on error.
|
||||
*/
|
||||
void
|
||||
bpf_optimize(compiler_state_t *cstate, struct icode *ic)
|
||||
int
|
||||
bpf_optimize(struct icode *ic, char *errbuf)
|
||||
{
|
||||
opt_state_t opt_state;
|
||||
|
||||
opt_init(cstate, &opt_state, ic);
|
||||
opt_loop(cstate, &opt_state, ic, 0);
|
||||
opt_loop(cstate, &opt_state, ic, 1);
|
||||
memset(&opt_state, 0, sizeof(opt_state));
|
||||
opt_state.errbuf = errbuf;
|
||||
if (setjmp(opt_state.top_ctx)) {
|
||||
opt_cleanup(&opt_state);
|
||||
return -1;
|
||||
}
|
||||
opt_init(&opt_state, ic);
|
||||
opt_loop(&opt_state, ic, 0);
|
||||
opt_loop(&opt_state, ic, 1);
|
||||
intern_blocks(&opt_state, ic);
|
||||
#ifdef BDEBUG
|
||||
if (pcap_optimizer_debug > 1 || pcap_print_dot_graph) {
|
||||
printf("after intern_blocks()\n");
|
||||
opt_dump(cstate, ic);
|
||||
opt_dump(&opt_state, ic);
|
||||
}
|
||||
#endif
|
||||
opt_root(&ic->root);
|
||||
#ifdef BDEBUG
|
||||
if (pcap_optimizer_debug > 1 || pcap_print_dot_graph) {
|
||||
printf("after opt_root()\n");
|
||||
opt_dump(cstate, ic);
|
||||
opt_dump(&opt_state, ic);
|
||||
}
|
||||
#endif
|
||||
opt_cleanup(&opt_state);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1943,6 +2037,24 @@ opt_cleanup(opt_state_t *opt_state)
|
||||
free((void *)opt_state->blocks);
|
||||
}
|
||||
|
||||
/*
|
||||
* For optimizer errors.
|
||||
*/
|
||||
static void PCAP_NORETURN
|
||||
opt_error(opt_state_t *opt_state, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (opt_state->errbuf != NULL) {
|
||||
va_start(ap, fmt);
|
||||
(void)pcap_vsnprintf(opt_state->errbuf,
|
||||
PCAP_ERRBUF_SIZE, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
longjmp(opt_state->top_ctx, 1);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the number of stmts in 's'.
|
||||
*/
|
||||
@@ -2027,7 +2139,7 @@ count_stmts(struct icode *ic, struct block *p)
|
||||
* from the total number of blocks and/or statements.
|
||||
*/
|
||||
static void
|
||||
opt_init(compiler_state_t *cstate, opt_state_t *opt_state, struct icode *ic)
|
||||
opt_init(opt_state_t *opt_state, struct icode *ic)
|
||||
{
|
||||
bpf_u_int32 *p;
|
||||
int i, n, max_stmts;
|
||||
@@ -2040,22 +2152,24 @@ opt_init(compiler_state_t *cstate, opt_state_t *opt_state, struct icode *ic)
|
||||
n = count_blocks(ic, ic->root);
|
||||
opt_state->blocks = (struct block **)calloc(n, sizeof(*opt_state->blocks));
|
||||
if (opt_state->blocks == NULL)
|
||||
bpf_error(cstate, "malloc");
|
||||
opt_error(opt_state, "malloc");
|
||||
unMarkAll(ic);
|
||||
opt_state->n_blocks = 0;
|
||||
number_blks_r(opt_state, ic, ic->root);
|
||||
|
||||
opt_state->n_edges = 2 * opt_state->n_blocks;
|
||||
opt_state->edges = (struct edge **)calloc(opt_state->n_edges, sizeof(*opt_state->edges));
|
||||
if (opt_state->edges == NULL)
|
||||
bpf_error(cstate, "malloc");
|
||||
if (opt_state->edges == NULL) {
|
||||
opt_error(opt_state, "malloc");
|
||||
}
|
||||
|
||||
/*
|
||||
* The number of levels is bounded by the number of nodes.
|
||||
*/
|
||||
opt_state->levels = (struct block **)calloc(opt_state->n_blocks, sizeof(*opt_state->levels));
|
||||
if (opt_state->levels == NULL)
|
||||
bpf_error(cstate, "malloc");
|
||||
if (opt_state->levels == NULL) {
|
||||
opt_error(opt_state, "malloc");
|
||||
}
|
||||
|
||||
opt_state->edgewords = opt_state->n_edges / (8 * sizeof(bpf_u_int32)) + 1;
|
||||
opt_state->nodewords = opt_state->n_blocks / (8 * sizeof(bpf_u_int32)) + 1;
|
||||
@@ -2063,8 +2177,9 @@ opt_init(compiler_state_t *cstate, opt_state_t *opt_state, struct icode *ic)
|
||||
/* XXX */
|
||||
opt_state->space = (bpf_u_int32 *)malloc(2 * opt_state->n_blocks * opt_state->nodewords * sizeof(*opt_state->space)
|
||||
+ opt_state->n_edges * opt_state->edgewords * sizeof(*opt_state->space));
|
||||
if (opt_state->space == NULL)
|
||||
bpf_error(cstate, "malloc");
|
||||
if (opt_state->space == NULL) {
|
||||
opt_error(opt_state, "malloc");
|
||||
}
|
||||
p = opt_state->space;
|
||||
opt_state->all_dom_sets = p;
|
||||
for (i = 0; i < n; ++i) {
|
||||
@@ -2101,9 +2216,13 @@ opt_init(compiler_state_t *cstate, opt_state_t *opt_state, struct icode *ic)
|
||||
*/
|
||||
opt_state->maxval = 3 * max_stmts;
|
||||
opt_state->vmap = (struct vmapinfo *)calloc(opt_state->maxval, sizeof(*opt_state->vmap));
|
||||
if (opt_state->vmap == NULL) {
|
||||
opt_error(opt_state, "malloc");
|
||||
}
|
||||
opt_state->vnode_base = (struct valnode *)calloc(opt_state->maxval, sizeof(*opt_state->vnode_base));
|
||||
if (opt_state->vmap == NULL || opt_state->vnode_base == NULL)
|
||||
bpf_error(cstate, "malloc");
|
||||
if (opt_state->vnode_base == NULL) {
|
||||
opt_error(opt_state, "malloc");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2115,6 +2234,9 @@ opt_init(compiler_state_t *cstate, opt_state_t *opt_state, struct icode *ic)
|
||||
int bids[NBIDS];
|
||||
#endif
|
||||
|
||||
static void PCAP_NORETURN conv_error(conv_state_t *, const char *, ...)
|
||||
PCAP_PRINTFLIKE(2, 3);
|
||||
|
||||
/*
|
||||
* Returns true if successful. Returns false if a branch has
|
||||
* an offset that is too large. If so, we have marked that
|
||||
@@ -2122,8 +2244,7 @@ int bids[NBIDS];
|
||||
* properly.
|
||||
*/
|
||||
static int
|
||||
convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state,
|
||||
struct icode *ic, struct block *p)
|
||||
convert_code_r(conv_state_t *conv_state, struct icode *ic, struct block *p)
|
||||
{
|
||||
struct bpf_insn *dst;
|
||||
struct slist *src;
|
||||
@@ -2136,9 +2257,9 @@ convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state,
|
||||
return (1);
|
||||
Mark(ic, p);
|
||||
|
||||
if (convert_code_r(cstate, conv_state, ic, JF(p)) == 0)
|
||||
if (convert_code_r(conv_state, ic, JF(p)) == 0)
|
||||
return (0);
|
||||
if (convert_code_r(cstate, conv_state, ic, JT(p)) == 0)
|
||||
if (convert_code_r(conv_state, ic, JT(p)) == 0)
|
||||
return (0);
|
||||
|
||||
slen = slength(p->stmts);
|
||||
@@ -2151,7 +2272,7 @@ convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state,
|
||||
if (slen) {
|
||||
offset = (struct slist **)calloc(slen, sizeof(struct slist *));
|
||||
if (!offset) {
|
||||
bpf_error(cstate, "not enough core");
|
||||
conv_error(conv_state, "not enough core");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
}
|
||||
@@ -2175,7 +2296,8 @@ convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state,
|
||||
if (BPF_CLASS(src->s.code) != BPF_JMP || src->s.code == (BPF_JMP|BPF_JA)) {
|
||||
#if 0
|
||||
if (src->s.jt || src->s.jf) {
|
||||
bpf_error(cstate, "illegal jmp destination");
|
||||
free(offset);
|
||||
conv_error(conv_state, "illegal jmp destination");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
#endif
|
||||
@@ -2195,7 +2317,8 @@ convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state,
|
||||
#endif
|
||||
|
||||
if (!src->s.jt || !src->s.jf) {
|
||||
bpf_error(cstate, ljerr, "no jmp destination", off);
|
||||
free(offset);
|
||||
conv_error(conv_state, ljerr, "no jmp destination", off);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
@@ -2203,12 +2326,14 @@ convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state,
|
||||
for (i = 0; i < slen; i++) {
|
||||
if (offset[i] == src->s.jt) {
|
||||
if (jt) {
|
||||
bpf_error(cstate, ljerr, "multiple matches", off);
|
||||
free(offset);
|
||||
conv_error(conv_state, ljerr, "multiple matches", off);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
if (i - off - 1 >= 256) {
|
||||
bpf_error(cstate, ljerr, "out-of-range jump", off);
|
||||
free(offset);
|
||||
conv_error(conv_state, ljerr, "out-of-range jump", off);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
dst->jt = (u_char)(i - off - 1);
|
||||
@@ -2216,11 +2341,13 @@ convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state,
|
||||
}
|
||||
if (offset[i] == src->s.jf) {
|
||||
if (jf) {
|
||||
bpf_error(cstate, ljerr, "multiple matches", off);
|
||||
free(offset);
|
||||
conv_error(conv_state, ljerr, "multiple matches", off);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
if (i - off - 1 >= 256) {
|
||||
bpf_error(cstate, ljerr, "out-of-range jump", off);
|
||||
free(offset);
|
||||
conv_error(conv_state, ljerr, "out-of-range jump", off);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
dst->jf = (u_char)(i - off - 1);
|
||||
@@ -2228,7 +2355,8 @@ convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state,
|
||||
}
|
||||
}
|
||||
if (!jt || !jf) {
|
||||
bpf_error(cstate, ljerr, "no destination found", off);
|
||||
free(offset);
|
||||
conv_error(conv_state, ljerr, "no destination found", off);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
}
|
||||
@@ -2257,7 +2385,7 @@ filled:
|
||||
}
|
||||
/* branch if T to following jump */
|
||||
if (extrajmps >= 256) {
|
||||
bpf_error(cstate, "too many extra jumps");
|
||||
conv_error(conv_state, "too many extra jumps");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
dst->jt = (u_char)extrajmps;
|
||||
@@ -2278,7 +2406,7 @@ filled:
|
||||
/* branch if F to following jump */
|
||||
/* if two jumps are inserted, F goes to second one */
|
||||
if (extrajmps >= 256) {
|
||||
bpf_error(cstate, "too many extra jumps");
|
||||
conv_error(conv_state, "too many extra jumps");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
dst->jf = (u_char)extrajmps;
|
||||
@@ -2312,13 +2440,20 @@ filled:
|
||||
* done with the filter program. See the pcap man page.
|
||||
*/
|
||||
struct bpf_insn *
|
||||
icode_to_fcode(compiler_state_t *cstate, struct icode *ic,
|
||||
struct block *root, u_int *lenp)
|
||||
icode_to_fcode(struct icode *ic, struct block *root, u_int *lenp,
|
||||
char *errbuf)
|
||||
{
|
||||
u_int n;
|
||||
struct bpf_insn *fp;
|
||||
conv_state_t conv_state;
|
||||
|
||||
conv_state.fstart = NULL;
|
||||
conv_state.errbuf = errbuf;
|
||||
if (setjmp(conv_state.top_ctx) != 0) {
|
||||
free(conv_state.fstart);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Loop doing convert_code_r() until no branches remain
|
||||
* with too-large offsets.
|
||||
@@ -2328,14 +2463,18 @@ icode_to_fcode(compiler_state_t *cstate, struct icode *ic,
|
||||
n = *lenp = count_stmts(ic, root);
|
||||
|
||||
fp = (struct bpf_insn *)malloc(sizeof(*fp) * n);
|
||||
if (fp == NULL)
|
||||
bpf_error(cstate, "malloc");
|
||||
if (fp == NULL) {
|
||||
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"malloc");
|
||||
free(fp);
|
||||
return NULL;
|
||||
}
|
||||
memset((char *)fp, 0, sizeof(*fp) * n);
|
||||
conv_state.fstart = fp;
|
||||
conv_state.ftail = fp + n;
|
||||
|
||||
unMarkAll(ic);
|
||||
if (convert_code_r(cstate, &conv_state, ic, root))
|
||||
if (convert_code_r(&conv_state, ic, root))
|
||||
break;
|
||||
free(fp);
|
||||
}
|
||||
@@ -2343,6 +2482,22 @@ icode_to_fcode(compiler_state_t *cstate, struct icode *ic,
|
||||
return fp;
|
||||
}
|
||||
|
||||
/*
|
||||
* For iconv_to_fconv() errors.
|
||||
*/
|
||||
static void PCAP_NORETURN
|
||||
conv_error(conv_state_t *conv_state, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
(void)pcap_vsnprintf(conv_state->errbuf,
|
||||
PCAP_ERRBUF_SIZE, fmt, ap);
|
||||
va_end(ap);
|
||||
longjmp(conv_state->top_ctx, 1);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/*
|
||||
* Make a copy of a BPF program and put it in the "fcode" member of
|
||||
* a "pcap_t".
|
||||
@@ -2452,14 +2607,16 @@ dot_dump_edge(struct icode *ic, struct block *block, FILE *out)
|
||||
* After install graphviz on http://www.graphviz.org/, save it as bpf.dot
|
||||
* and run `dot -Tpng -O bpf.dot' to draw the graph.
|
||||
*/
|
||||
static void
|
||||
dot_dump(compiler_state_t *cstate, struct icode *ic)
|
||||
static int
|
||||
dot_dump(struct icode *ic, char *errbuf)
|
||||
{
|
||||
struct bpf_program f;
|
||||
FILE *out = stdout;
|
||||
|
||||
memset(bids, 0, sizeof bids);
|
||||
f.bf_insns = icode_to_fcode(cstate, ic, ic->root, &f.bf_len);
|
||||
f.bf_insns = icode_to_fcode(ic, ic->root, &f.bf_len, errbuf);
|
||||
if (f.bf_insns == NULL)
|
||||
return -1;
|
||||
|
||||
fprintf(out, "digraph BPF {\n");
|
||||
unMarkAll(ic);
|
||||
@@ -2469,30 +2626,39 @@ dot_dump(compiler_state_t *cstate, struct icode *ic)
|
||||
fprintf(out, "}\n");
|
||||
|
||||
free((char *)f.bf_insns);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
plain_dump(compiler_state_t *cstate, struct icode *ic)
|
||||
static int
|
||||
plain_dump(struct icode *ic, char *errbuf)
|
||||
{
|
||||
struct bpf_program f;
|
||||
|
||||
memset(bids, 0, sizeof bids);
|
||||
f.bf_insns = icode_to_fcode(cstate, ic, ic->root, &f.bf_len);
|
||||
f.bf_insns = icode_to_fcode(ic, ic->root, &f.bf_len, errbuf);
|
||||
if (f.bf_insns == NULL)
|
||||
return -1;
|
||||
bpf_dump(&f, 1);
|
||||
putchar('\n');
|
||||
free((char *)f.bf_insns);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
opt_dump(compiler_state_t *cstate, struct icode *ic)
|
||||
opt_dump(opt_state_t *opt_state, struct icode *ic)
|
||||
{
|
||||
int status;
|
||||
char errbuf[PCAP_ERRBUF_SIZE];
|
||||
|
||||
/*
|
||||
* If the CFG, in DOT format, is requested, output it rather than
|
||||
* the code that would be generated from that graph.
|
||||
*/
|
||||
if (pcap_print_dot_graph)
|
||||
dot_dump(cstate, ic);
|
||||
status = dot_dump(ic, errbuf);
|
||||
else
|
||||
plain_dump(cstate, ic);
|
||||
status = plain_dump(ic, errbuf);
|
||||
if (status == -1)
|
||||
opt_error(opt_state, "opt_dump: icode_to_fcode failed: %s", errbuf);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -206,7 +206,7 @@ static int monitor_mode(pcap_t *, int);
|
||||
# endif
|
||||
|
||||
# if defined(__APPLE__)
|
||||
static void remove_en(pcap_t *);
|
||||
static void remove_non_802_11(pcap_t *);
|
||||
static void remove_802_11(pcap_t *);
|
||||
# endif
|
||||
|
||||
@@ -737,10 +737,10 @@ get_dlt_list(int fd, int v, struct bpf_dltlist *bdlp, char *ebuf)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__)
|
||||
static int
|
||||
pcap_can_set_rfmon_bpf(pcap_t *p)
|
||||
{
|
||||
#if defined(__APPLE__)
|
||||
struct utsname osinfo;
|
||||
struct ifreq ifr;
|
||||
int fd;
|
||||
@@ -799,8 +799,8 @@ pcap_can_set_rfmon_bpf(pcap_t *p)
|
||||
errno, "socket");
|
||||
return (PCAP_ERROR);
|
||||
}
|
||||
strlcpy(ifr.ifr_name, "wlt", sizeof(ifr.ifr_name));
|
||||
strlcat(ifr.ifr_name, p->opt.device + 2, sizeof(ifr.ifr_name));
|
||||
pcap_strlcpy(ifr.ifr_name, "wlt", sizeof(ifr.ifr_name));
|
||||
pcap_strlcat(ifr.ifr_name, p->opt.device + 2, sizeof(ifr.ifr_name));
|
||||
if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifr) < 0) {
|
||||
/*
|
||||
* No such device?
|
||||
@@ -880,7 +880,11 @@ pcap_can_set_rfmon_bpf(pcap_t *p)
|
||||
close(fd);
|
||||
#endif /* BIOCGDLTLIST */
|
||||
return (0);
|
||||
}
|
||||
#elif defined(HAVE_BSD_IEEE80211)
|
||||
static int
|
||||
pcap_can_set_rfmon_bpf(pcap_t *p)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = monitor_mode(p, 0);
|
||||
@@ -889,10 +893,14 @@ pcap_can_set_rfmon_bpf(pcap_t *p)
|
||||
if (ret == 0)
|
||||
return (1); /* success */
|
||||
return (ret);
|
||||
#else
|
||||
return (0);
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
static int
|
||||
pcap_can_set_rfmon_bpf(pcap_t *p _U_)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
pcap_stats_bpf(pcap_t *p, struct pcap_stat *ps)
|
||||
@@ -1012,18 +1020,21 @@ pcap_read_bpf(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
case EWOULDBLOCK:
|
||||
return (0);
|
||||
|
||||
case ENXIO:
|
||||
case ENXIO: /* FreeBSD, DragonFly BSD, and Darwin */
|
||||
case EIO: /* OpenBSD */
|
||||
/* NetBSD appears not to return an error in this case */
|
||||
/*
|
||||
* The device on which we're capturing
|
||||
* went away.
|
||||
*
|
||||
* XXX - we should really return
|
||||
* PCAP_ERROR_IFACE_NOT_UP, but
|
||||
* pcap_dispatch() etc. aren't
|
||||
* defined to retur that.
|
||||
* an appropriate error for that,
|
||||
* but pcap_dispatch() etc. aren't
|
||||
* documented as having error returns
|
||||
* other than PCAP_ERROR or PCAP_ERROR_BREAK.
|
||||
*/
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"The interface went down");
|
||||
"The interface disappeared");
|
||||
return (PCAP_ERROR);
|
||||
|
||||
#if defined(sun) && !defined(BSD) && !defined(__svr4__) && !defined(__SVR4)
|
||||
@@ -1358,8 +1369,8 @@ bpf_load(char *errbuf)
|
||||
|
||||
/* Check if the driver is loaded */
|
||||
memset(&cfg_ld, 0x0, sizeof(cfg_ld));
|
||||
pcap_snprintf(buf, sizeof(buf), "%s/%s", DRIVER_PATH, BPF_NAME);
|
||||
cfg_ld.path = buf;
|
||||
pcap_snprintf(cfg_ld.path, sizeof(cfg_ld.path), "%s/%s", DRIVER_PATH, BPF_NAME);
|
||||
if ((sysconfig(SYS_QUERYLOAD, (void *)&cfg_ld, sizeof(cfg_ld)) == -1) ||
|
||||
(cfg_ld.kmid == 0)) {
|
||||
/* Driver isn't loaded, load it now */
|
||||
@@ -1469,7 +1480,7 @@ pcap_cleanup_bpf(pcap_t *p)
|
||||
|
||||
s = socket(AF_LOCAL, SOCK_DGRAM, 0);
|
||||
if (s >= 0) {
|
||||
strlcpy(ifr.ifr_name, pb->device,
|
||||
pcap_strlcpy(ifr.ifr_name, pb->device,
|
||||
sizeof(ifr.ifr_name));
|
||||
ioctl(s, SIOCIFDESTROY, &ifr);
|
||||
close(s);
|
||||
@@ -1532,9 +1543,9 @@ check_setif_failure(pcap_t *p, int error)
|
||||
*/
|
||||
fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (fd != -1) {
|
||||
strlcpy(ifr.ifr_name, "en",
|
||||
pcap_strlcpy(ifr.ifr_name, "en",
|
||||
sizeof(ifr.ifr_name));
|
||||
strlcat(ifr.ifr_name, p->opt.device + 3,
|
||||
pcap_strlcat(ifr.ifr_name, p->opt.device + 3,
|
||||
sizeof(ifr.ifr_name));
|
||||
if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifr) < 0) {
|
||||
/*
|
||||
@@ -1721,7 +1732,7 @@ pcap_activate_bpf(pcap_t *p)
|
||||
goto bad;
|
||||
}
|
||||
znamelen = zonesep - p->opt.device;
|
||||
(void) strlcpy(path_zname, p->opt.device, znamelen + 1);
|
||||
(void) pcap_strlcpy(path_zname, p->opt.device, znamelen + 1);
|
||||
ifr.lifr_zoneid = getzoneidbyname(path_zname);
|
||||
if (ifr.lifr_zoneid == -1) {
|
||||
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
@@ -1786,7 +1797,7 @@ pcap_activate_bpf(pcap_t *p)
|
||||
*/
|
||||
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (sockfd != -1) {
|
||||
strlcpy(ifrname,
|
||||
pcap_strlcpy(ifrname,
|
||||
p->opt.device, ifnamsiz);
|
||||
if (ioctl(sockfd, SIOCGIFFLAGS,
|
||||
(char *)&ifr) < 0) {
|
||||
@@ -1888,7 +1899,7 @@ pcap_activate_bpf(pcap_t *p)
|
||||
/*
|
||||
* Create the interface.
|
||||
*/
|
||||
strlcpy(ifr.ifr_name, p->opt.device, sizeof(ifr.ifr_name));
|
||||
pcap_strlcpy(ifr.ifr_name, p->opt.device, sizeof(ifr.ifr_name));
|
||||
if (ioctl(s, SIOCIFCREATE2, &ifr) < 0) {
|
||||
if (errno == EINVAL) {
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
@@ -2187,7 +2198,7 @@ pcap_activate_bpf(pcap_t *p)
|
||||
* of link-layer types, as selecting
|
||||
* it will keep monitor mode off.
|
||||
*/
|
||||
remove_en(p);
|
||||
remove_non_802_11(p);
|
||||
|
||||
/*
|
||||
* If the new mode we want isn't
|
||||
@@ -2748,12 +2759,21 @@ get_if_flags(const char *name, bpf_u_int32 *flags, char *errbuf)
|
||||
strncpy(req.ifm_name, name, sizeof(req.ifm_name));
|
||||
if (ioctl(sock, SIOCGIFMEDIA, &req) < 0) {
|
||||
if (errno == EOPNOTSUPP || errno == EINVAL || errno == ENOTTY ||
|
||||
errno == ENODEV) {
|
||||
errno == ENODEV || errno == EPERM) {
|
||||
/*
|
||||
* Not supported, so we can't provide any
|
||||
* additional information. Assume that
|
||||
* this means that "connected" vs.
|
||||
* "disconnected" doesn't apply.
|
||||
*
|
||||
* The ioctl routine for Apple's pktap devices,
|
||||
* annoyingly, checks for "are you root?" before
|
||||
* checking whether the ioctl is valid, so it
|
||||
* returns EPERM, rather than ENOTSUP, for the
|
||||
* invalid SIOCGIFMEDIA, unless you're root.
|
||||
* So, just as we do for some ethtool ioctls
|
||||
* on Linux, which makes the same mistake, we
|
||||
* also treat EPERM as meaning "not supported".
|
||||
*/
|
||||
*flags |= PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE;
|
||||
close(sock);
|
||||
@@ -2890,7 +2910,7 @@ monitor_mode(pcap_t *p, int set)
|
||||
|
||||
default:
|
||||
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
errno, "SIOCGIFMEDIA 1");
|
||||
errno, "SIOCGIFMEDIA");
|
||||
close(sock);
|
||||
return (PCAP_ERROR);
|
||||
}
|
||||
@@ -3032,8 +3052,12 @@ find_802_11(struct bpf_dltlist *bdlp)
|
||||
new_dlt = bdlp->bfl_list[i];
|
||||
break;
|
||||
|
||||
#ifdef DLT_PRISM_HEADER
|
||||
case DLT_PRISM_HEADER:
|
||||
#endif
|
||||
#ifdef DLT_AIRONET_HEADER
|
||||
case DLT_AIRONET_HEADER:
|
||||
#endif
|
||||
case DLT_IEEE802_11_RADIO_AVS:
|
||||
/*
|
||||
* 802.11 with radio, but not radiotap.
|
||||
@@ -3068,24 +3092,25 @@ find_802_11(struct bpf_dltlist *bdlp)
|
||||
|
||||
#if defined(__APPLE__) && defined(BIOCGDLTLIST)
|
||||
/*
|
||||
* Remove DLT_EN10MB from the list of DLT_ values, as we're in monitor mode,
|
||||
* and DLT_EN10MB isn't supported in monitor mode.
|
||||
* Remove non-802.11 header types from the list of DLT_ values, as we're in
|
||||
* monitor mode, and those header types aren't supported in monitor mode.
|
||||
*/
|
||||
static void
|
||||
remove_en(pcap_t *p)
|
||||
remove_non_802_11(pcap_t *p)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
/*
|
||||
* Scan the list of DLT_ values and discard DLT_EN10MB.
|
||||
* Scan the list of DLT_ values and discard non-802.11 ones.
|
||||
*/
|
||||
j = 0;
|
||||
for (i = 0; i < p->dlt_count; i++) {
|
||||
switch (p->dlt_list[i]) {
|
||||
|
||||
case DLT_EN10MB:
|
||||
case DLT_RAW:
|
||||
/*
|
||||
* Don't offer this one.
|
||||
* Not 802.11. Don't offer this one.
|
||||
*/
|
||||
continue;
|
||||
|
||||
@@ -3127,10 +3152,17 @@ remove_802_11(pcap_t *p)
|
||||
switch (p->dlt_list[i]) {
|
||||
|
||||
case DLT_IEEE802_11:
|
||||
#ifdef DLT_PRISM_HEADER
|
||||
case DLT_PRISM_HEADER:
|
||||
#endif
|
||||
#ifdef DLT_AIRONET_HEADER
|
||||
case DLT_AIRONET_HEADER:
|
||||
#endif
|
||||
case DLT_IEEE802_11_RADIO:
|
||||
case DLT_IEEE802_11_RADIO_AVS:
|
||||
#ifdef DLT_PPI
|
||||
case DLT_PPI:
|
||||
#endif
|
||||
/*
|
||||
* 802.11. Don't offer this one.
|
||||
*/
|
||||
@@ -3222,10 +3254,10 @@ pcap_setfilter_bpf(pcap_t *p, struct bpf_program *fp)
|
||||
* Set direction flag: Which packets do we accept on a forwarding
|
||||
* single device? IN, OUT or both?
|
||||
*/
|
||||
#if defined(BIOCSDIRECTION)
|
||||
static int
|
||||
pcap_setdirection_bpf(pcap_t *p, pcap_direction_t d)
|
||||
{
|
||||
#if defined(BIOCSDIRECTION)
|
||||
u_int direction;
|
||||
|
||||
direction = (d == PCAP_D_IN) ? BPF_D_IN :
|
||||
@@ -3238,7 +3270,11 @@ pcap_setdirection_bpf(pcap_t *p, pcap_direction_t d)
|
||||
return (-1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
#elif defined(BIOCSSEESENT)
|
||||
static int
|
||||
pcap_setdirection_bpf(pcap_t *p, pcap_direction_t d)
|
||||
{
|
||||
u_int seesent;
|
||||
|
||||
/*
|
||||
@@ -3258,25 +3294,35 @@ pcap_setdirection_bpf(pcap_t *p, pcap_direction_t d)
|
||||
return (-1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
#else
|
||||
static int
|
||||
pcap_setdirection_bpf(pcap_t *p, pcap_direction_t d _U_)
|
||||
{
|
||||
(void) pcap_snprintf(p->errbuf, sizeof(p->errbuf),
|
||||
"This system doesn't support BIOCSSEESENT, so the direction can't be set");
|
||||
return (-1);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BIOCSDLT
|
||||
static int
|
||||
pcap_set_datalink_bpf(pcap_t *p, int dlt)
|
||||
{
|
||||
#ifdef BIOCSDLT
|
||||
if (ioctl(p->fd, BIOCSDLT, &dlt) == -1) {
|
||||
pcap_fmt_errmsg_for_errno(p->errbuf, sizeof(p->errbuf),
|
||||
errno, "Cannot set DLT %d", dlt);
|
||||
return (-1);
|
||||
}
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
#else
|
||||
static int
|
||||
pcap_set_datalink_bpf(pcap_t *p _U_, int dlt _U_)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Platform-specific information.
|
||||
|
||||
@@ -74,13 +74,14 @@ bt_findalldevs(pcap_if_list_t *devlistp, char *err_str)
|
||||
{
|
||||
struct hci_dev_list_req *dev_list;
|
||||
struct hci_dev_req *dev_req;
|
||||
int i, sock;
|
||||
int sock;
|
||||
unsigned i;
|
||||
int ret = 0;
|
||||
|
||||
sock = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
|
||||
if (sock < 0)
|
||||
{
|
||||
/* if bluetooth is not supported this this is not fatal*/
|
||||
/* if bluetooth is not supported this is not fatal*/
|
||||
if (errno == EAFNOSUPPORT)
|
||||
return 0;
|
||||
pcap_fmt_errmsg_for_errno(err_str, PCAP_ERRBUF_SIZE,
|
||||
@@ -109,10 +110,10 @@ bt_findalldevs(pcap_if_list_t *devlistp, char *err_str)
|
||||
|
||||
dev_req = dev_list->dev_req;
|
||||
for (i = 0; i < dev_list->dev_num; i++, dev_req++) {
|
||||
char dev_name[20], dev_descr[30];
|
||||
char dev_name[20], dev_descr[40];
|
||||
|
||||
pcap_snprintf(dev_name, 20, BT_IFACE"%d", dev_req->dev_id);
|
||||
pcap_snprintf(dev_descr, 30, "Bluetooth adapter number %d", i);
|
||||
pcap_snprintf(dev_name, sizeof(dev_name), BT_IFACE"%u", dev_req->dev_id);
|
||||
pcap_snprintf(dev_descr, sizeof(dev_descr), "Bluetooth adapter number %u", i);
|
||||
|
||||
/*
|
||||
* Bluetooth is a wireless technology.
|
||||
@@ -379,8 +380,8 @@ bt_read_linux(pcap_t *handle, int max_packets _U_, pcap_handler callback, u_char
|
||||
static int
|
||||
bt_inject_linux(pcap_t *handle, const void *buf _U_, size_t size _U_)
|
||||
{
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "inject not supported on "
|
||||
"bluetooth devices");
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Packet injection is not supported on Bluetooth devices");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
|
||||
@@ -149,7 +149,8 @@ bt_monitor_read(pcap_t *handle, int max_packets _U_, pcap_handler callback, u_ch
|
||||
static int
|
||||
bt_monitor_inject(pcap_t *handle, const void *buf _U_, size_t size _U_)
|
||||
{
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "inject not supported yet");
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Packet injection is not supported yet on Bluetooth monitor devices");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -514,11 +514,20 @@
|
||||
#define LINKTYPE_RAIF1 198
|
||||
|
||||
/*
|
||||
* IPMB packet for IPMI, beginning with the I2C slave address, followed
|
||||
* by the netFn and LUN, etc.. Requested by Chanthy Toeung
|
||||
* <chanthy.toeung@ca.kontron.com>.
|
||||
* IPMB packet for IPMI, beginning with a 2-byte header, followed by
|
||||
* the I2C slave address, followed by the netFn and LUN, etc..
|
||||
* Requested by Chanthy Toeung <chanthy.toeung@ca.kontron.com>.
|
||||
*
|
||||
* XXX - its DLT_ value used to be called DLT_IPMB, back when we got the
|
||||
* impression from the email thread requesting it that the packet
|
||||
* had no extra 2-byte header. We've renamed it; if anybody used
|
||||
* DLT_IPMB and assumed no 2-byte header, this will cause the compile
|
||||
* to fail, at which point we'll have to figure out what to do about
|
||||
* the two header types using the same DLT_/LINKTYPE_ value. If that
|
||||
* doesn't happen, we'll assume nobody used it and that the redefinition
|
||||
* is safe.
|
||||
*/
|
||||
#define LINKTYPE_IPMB 199
|
||||
#define LINKTYPE_IPMB_KONTRON 199
|
||||
|
||||
/*
|
||||
* Juniper-private data link type, as per request from
|
||||
@@ -549,15 +558,35 @@
|
||||
*/
|
||||
#define LINKTYPE_LAPD 203
|
||||
|
||||
|
||||
/*
|
||||
* Variants of various link-layer headers, with a one-byte direction
|
||||
* pseudo-header prepended - zero means "received by this host",
|
||||
* non-zero (any non-zero value) means "sent by this host" - as per
|
||||
* Will Barker <w.barker@zen.co.uk>.
|
||||
* PPP, with a one-byte direction pseudo-header prepended - zero means
|
||||
* "received by this host", non-zero (any non-zero value) means "sent by
|
||||
* this host" - as per Will Barker <w.barker@zen.co.uk>.
|
||||
*/
|
||||
#define LINKTYPE_PPP_WITH_DIR 204 /* Don't confuse with LINKTYPE_PPP_PPPD */
|
||||
|
||||
/*
|
||||
* Cisco HDLC, with a one-byte direction pseudo-header prepended - zero
|
||||
* means "received by this host", non-zero (any non-zero value) means
|
||||
* "sent by this host" - as per Will Barker <w.barker@zen.co.uk>.
|
||||
*/
|
||||
#define LINKTYPE_PPP_WITH_DIR 204 /* PPP */
|
||||
#define LINKTYPE_C_HDLC_WITH_DIR 205 /* Cisco HDLC */
|
||||
|
||||
/*
|
||||
* Frame Relay, with a one-byte direction pseudo-header prepended - zero
|
||||
* means "received by this host" (DCE -> DTE), non-zero (any non-zero
|
||||
* value) means "sent by this host" (DTE -> DCE) - as per Will Barker
|
||||
* <w.barker@zen.co.uk>.
|
||||
*/
|
||||
#define LINKTYPE_FRELAY_WITH_DIR 206 /* Frame Relay */
|
||||
|
||||
/*
|
||||
* LAPB, with a one-byte direction pseudo-header prepended - zero means
|
||||
* "received by this host" (DCE -> DTE), non-zero (any non-zero value)
|
||||
* means "sent by this host" (DTE -> DCE)- as per Will Barker
|
||||
* <w.barker@zen.co.uk>.
|
||||
*/
|
||||
#define LINKTYPE_LAPB_WITH_DIR 207 /* LAPB */
|
||||
|
||||
/*
|
||||
@@ -1081,7 +1110,12 @@
|
||||
*/
|
||||
#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
|
||||
@@ -1240,18 +1274,30 @@ linktype_to_dlt(int linktype)
|
||||
/*
|
||||
* Return the maximum snapshot length for a given DLT_ value.
|
||||
*
|
||||
* For most link-layer types, we use MAXIMUM_SNAPLEN, but for DLT_DBUS,
|
||||
* the maximum is 134217728, as per
|
||||
* For most link-layer types, we use MAXIMUM_SNAPLEN.
|
||||
*
|
||||
* For DLT_DBUS, the maximum is 128MiB, as per
|
||||
*
|
||||
* https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-messages
|
||||
*
|
||||
* For DLT_USBPCAP, the maximum is 1MiB, as per
|
||||
*
|
||||
* https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=15985
|
||||
*/
|
||||
u_int
|
||||
max_snaplen_for_dlt(int dlt)
|
||||
{
|
||||
if (dlt == DLT_DBUS)
|
||||
return 134217728;
|
||||
else
|
||||
switch (dlt) {
|
||||
|
||||
case DLT_DBUS:
|
||||
return 128*1024*1024;
|
||||
|
||||
case DLT_USBPCAP:
|
||||
return 1024*1024;
|
||||
|
||||
default:
|
||||
return MAXIMUM_SNAPLEN;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -1,14 +1,6 @@
|
||||
/*
|
||||
* 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)
|
||||
* Modifications: Jesper Peterson
|
||||
* Koryn Grant
|
||||
@@ -258,12 +250,18 @@ dag_platform_cleanup(pcap_t *p)
|
||||
|
||||
if(pd->dag_ref != NULL) {
|
||||
dag_config_dispose(pd->dag_ref);
|
||||
/*
|
||||
* Note: we don't need to call close(p->fd) or
|
||||
* dag_close(p->fd), as dag_config_dispose(pd->dag_ref)
|
||||
* does this.
|
||||
*
|
||||
* Set p->fd to -1 to make sure that's not done.
|
||||
*/
|
||||
p->fd = -1;
|
||||
pd->dag_ref = NULL;
|
||||
}
|
||||
delete_pcap_dag(p);
|
||||
pcap_cleanup_live_common(p);
|
||||
/* Note: don't need to call close(p->fd) or dag_close(p->fd) as dag_config_dispose(pd->dag_ref) does this. */
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -722,7 +720,7 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
static int
|
||||
dag_inject(pcap_t *p, const void *buf _U_, size_t size _U_)
|
||||
{
|
||||
strlcpy(p->errbuf, "Sending packets isn't supported on DAG cards",
|
||||
pcap_strlcpy(p->errbuf, "Sending packets isn't supported on DAG cards",
|
||||
PCAP_ERRBUF_SIZE);
|
||||
return (-1);
|
||||
}
|
||||
@@ -746,18 +744,20 @@ static int dag_activate(pcap_t* p)
|
||||
daginf_t* daginf;
|
||||
char * newDev = NULL;
|
||||
char * device = p->opt.device;
|
||||
int ret;
|
||||
dag_size_t mindata;
|
||||
struct timeval maxwait;
|
||||
struct timeval poll;
|
||||
|
||||
if (device == NULL) {
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "device is NULL");
|
||||
return -1;
|
||||
return PCAP_ERROR;
|
||||
}
|
||||
|
||||
/* Initialize some components of the pcap structure. */
|
||||
newDev = (char *)malloc(strlen(device) + 16);
|
||||
if (newDev == NULL) {
|
||||
ret = PCAP_ERROR;
|
||||
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
errno, "Can't allocate string for device name");
|
||||
goto fail;
|
||||
@@ -765,6 +765,13 @@ static int dag_activate(pcap_t* p)
|
||||
|
||||
/* Parse input name to get dag device and stream number if provided */
|
||||
if (dag_parse_name(device, newDev, strlen(device) + 16, &pd->dag_stream) < 0) {
|
||||
/*
|
||||
* XXX - it'd be nice if this indicated what was wrong
|
||||
* with the name. Does this reliably set errno?
|
||||
* Should this return PCAP_ERROR_NO_SUCH_DEVICE in some
|
||||
* cases?
|
||||
*/
|
||||
ret = PCAP_ERROR;
|
||||
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
errno, "dag_parse_name");
|
||||
goto fail;
|
||||
@@ -772,25 +779,40 @@ static int dag_activate(pcap_t* p)
|
||||
device = newDev;
|
||||
|
||||
if (pd->dag_stream%2) {
|
||||
ret = PCAP_ERROR;
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "dag_parse_name: tx (even numbered) streams not supported for capture");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* setup device parameters */
|
||||
if((pd->dag_ref = dag_config_init((char *)device)) == NULL) {
|
||||
/*
|
||||
* XXX - does this reliably set errno?
|
||||
*/
|
||||
if (errno == ENOENT)
|
||||
ret = PCAP_ERROR_NO_SUCH_DEVICE;
|
||||
else if (errno == EPERM || errno == EACCES)
|
||||
ret = PCAP_ERROR_PERM_DENIED;
|
||||
else
|
||||
ret = PCAP_ERROR;
|
||||
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
errno, "dag_config_init %s", device);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if((p->fd = dag_config_get_card_fd(pd->dag_ref)) < 0) {
|
||||
/*
|
||||
* XXX - does this reliably set errno?
|
||||
*/
|
||||
ret = PCAP_ERROR;
|
||||
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
errno, "dag_config_get_card_fd %s", device);
|
||||
goto fail;
|
||||
goto failclose;
|
||||
}
|
||||
|
||||
/* Open requested stream. Can fail if already locked or on error */
|
||||
if (dag_attach_stream64(p->fd, pd->dag_stream, 0, 0) < 0) {
|
||||
ret = PCAP_ERROR;
|
||||
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
errno, "dag_attach_stream");
|
||||
goto failclose;
|
||||
@@ -809,6 +831,7 @@ static int dag_activate(pcap_t* p)
|
||||
*/
|
||||
if (dag_get_stream_poll64(p->fd, pd->dag_stream,
|
||||
&mindata, &maxwait, &poll) < 0) {
|
||||
ret = PCAP_ERROR;
|
||||
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
errno, "dag_get_stream_poll");
|
||||
goto faildetach;
|
||||
@@ -853,6 +876,7 @@ static int dag_activate(pcap_t* p)
|
||||
|
||||
if (dag_set_stream_poll64(p->fd, pd->dag_stream,
|
||||
mindata, &maxwait, &poll) < 0) {
|
||||
ret = PCAP_ERROR;
|
||||
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
errno, "dag_set_stream_poll");
|
||||
goto faildetach;
|
||||
@@ -875,6 +899,7 @@ static int dag_activate(pcap_t* p)
|
||||
#endif
|
||||
|
||||
if(dag_start_stream(p->fd, pd->dag_stream) < 0) {
|
||||
ret = PCAP_ERROR;
|
||||
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
errno, "dag_start_stream %s", device);
|
||||
goto faildetach;
|
||||
@@ -910,6 +935,7 @@ static int dag_activate(pcap_t* p)
|
||||
if ((n = atoi(s)) == 0 || n == 16 || n == 32) {
|
||||
pd->dag_fcs_bits = n;
|
||||
} else {
|
||||
ret = PCAP_ERROR;
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"pcap_activate %s: bad ERF_FCS_BITS value (%d) in environment", device, n);
|
||||
goto failstop;
|
||||
@@ -932,12 +958,15 @@ static int dag_activate(pcap_t* p)
|
||||
pd->dag_timeout = p->opt.timeout;
|
||||
|
||||
p->linktype = -1;
|
||||
if (dag_get_datalink(p) < 0)
|
||||
if (dag_get_datalink(p) < 0) {
|
||||
ret = PCAP_ERROR;
|
||||
goto failstop;
|
||||
}
|
||||
|
||||
p->bufsize = 0;
|
||||
|
||||
if (new_pcap_dag(p) < 0) {
|
||||
ret = PCAP_ERROR;
|
||||
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
errno, "new_pcap_dag %s", device);
|
||||
goto failstop;
|
||||
@@ -977,6 +1006,14 @@ faildetach:
|
||||
|
||||
failclose:
|
||||
dag_config_dispose(pd->dag_ref);
|
||||
/*
|
||||
* Note: we don't need to call close(p->fd) or dag_close(p->fd),
|
||||
* as dag_config_dispose(pd->dag_ref) does this.
|
||||
*
|
||||
* Set p->fd to -1 to make sure that's not done.
|
||||
*/
|
||||
p->fd = -1;
|
||||
pd->dag_ref = NULL;
|
||||
delete_pcap_dag(p);
|
||||
|
||||
fail:
|
||||
@@ -985,7 +1022,7 @@ fail:
|
||||
free((char *)newDev);
|
||||
}
|
||||
|
||||
return PCAP_ERROR;
|
||||
return ret;
|
||||
}
|
||||
|
||||
pcap_t *dag_create(const char *device, char *ebuf, int *is_ours)
|
||||
@@ -1137,7 +1174,7 @@ dag_findalldevs(pcap_if_list_t *devlistp, char *errbuf)
|
||||
}
|
||||
rxstreams = dag_rx_get_stream_count(dagfd);
|
||||
for(stream=0;stream<DAG_STREAM_MAX;stream+=2) {
|
||||
if (0 == dag_attach_stream(dagfd, stream, 0, 0)) {
|
||||
if (0 == dag_attach_stream64(dagfd, stream, 0, 0)) {
|
||||
dag_detach_stream(dagfd, stream);
|
||||
|
||||
pcap_snprintf(name, 10, "dag%d:%d", c, stream);
|
||||
|
||||
@@ -307,7 +307,7 @@ pcap_inject_dlpi(pcap_t *p, const void *buf, size_t size)
|
||||
* it should check "p->linktype" and reject the send request if
|
||||
* it's anything other than DLT_EN10MB.
|
||||
*/
|
||||
strlcpy(p->errbuf, "send: Not supported on this version of this OS",
|
||||
pcap_strlcpy(p->errbuf, "send: Not supported on this version of this OS",
|
||||
PCAP_ERRBUF_SIZE);
|
||||
ret = -1;
|
||||
#endif /* raw mode */
|
||||
@@ -363,9 +363,9 @@ open_dlpi_device(const char *name, u_int *ppa, char *errbuf)
|
||||
*/
|
||||
cp = strrchr(name, '/');
|
||||
if (cp == NULL)
|
||||
strlcpy(dname, name, sizeof(dname));
|
||||
pcap_strlcpy(dname, name, sizeof(dname));
|
||||
else
|
||||
strlcpy(dname, cp + 1, sizeof(dname));
|
||||
pcap_strlcpy(dname, cp + 1, sizeof(dname));
|
||||
|
||||
/*
|
||||
* Split the device name into a device type name and a unit number;
|
||||
@@ -415,7 +415,7 @@ open_dlpi_device(const char *name, u_int *ppa, char *errbuf)
|
||||
* device name.
|
||||
*/
|
||||
if (*name == '/')
|
||||
strlcpy(dname, name, sizeof(dname));
|
||||
pcap_strlcpy(dname, name, sizeof(dname));
|
||||
else
|
||||
pcap_snprintf(dname, sizeof(dname), "%s/%s", PCAP_DEV_PREFIX,
|
||||
name);
|
||||
@@ -432,7 +432,7 @@ open_dlpi_device(const char *name, u_int *ppa, char *errbuf)
|
||||
* Make a copy of the device pathname, and then remove the unit
|
||||
* number from the device pathname.
|
||||
*/
|
||||
strlcpy(dname2, dname, sizeof(dname));
|
||||
pcap_strlcpy(dname2, dname, sizeof(dname));
|
||||
*cp = '\0';
|
||||
|
||||
/* Try device without unit number */
|
||||
@@ -968,7 +968,7 @@ dl_dohpuxbind(int fd, char *ebuf)
|
||||
*ebuf = '\0';
|
||||
hpsap++;
|
||||
if (hpsap > 100) {
|
||||
strlcpy(ebuf,
|
||||
pcap_strlcpy(ebuf,
|
||||
"All SAPs from 22 through 100 are in use",
|
||||
PCAP_ERRBUF_SIZE);
|
||||
return (-1);
|
||||
@@ -1547,7 +1547,7 @@ get_release(char *buf, size_t bufsize, bpf_u_int32 *majorp,
|
||||
*minorp = 0;
|
||||
*microp = 0;
|
||||
if (sysinfo(SI_RELEASE, buf, bufsize) < 0) {
|
||||
strlcpy(buf, "?", bufsize);
|
||||
pcap_strlcpy(buf, "?", bufsize);
|
||||
return;
|
||||
}
|
||||
cp = buf;
|
||||
|
||||
@@ -413,14 +413,14 @@ int pcap_stats_ex (pcap_t *p, struct pcap_stat_ex *se)
|
||||
|
||||
if (!dev || !dev->get_stats)
|
||||
{
|
||||
strlcpy (p->errbuf, "detailed device statistics not available",
|
||||
pcap_strlcpy (p->errbuf, "detailed device statistics not available",
|
||||
PCAP_ERRBUF_SIZE);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (!strnicmp(dev->name,"pkt",3))
|
||||
{
|
||||
strlcpy (p->errbuf, "pktdrvr doesn't have detailed statistics",
|
||||
pcap_strlcpy (p->errbuf, "pktdrvr doesn't have detailed statistics",
|
||||
PCAP_ERRBUF_SIZE);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
@@ -29,11 +29,11 @@ pcap-filter \- packet filter syntax
|
||||
is used to compile a string into a filter program.
|
||||
The resulting filter program can then be applied to
|
||||
some stream of packets to determine which packets will be supplied to
|
||||
.BR pcap_loop() ,
|
||||
.BR pcap_dispatch() ,
|
||||
.BR pcap_next() ,
|
||||
.BR pcap_loop(3PCAP) ,
|
||||
.BR pcap_dispatch(3PCAP) ,
|
||||
.BR pcap_next(3PCAP) ,
|
||||
or
|
||||
.BR pcap_next_ex() .
|
||||
.BR pcap_next_ex(3PCAP) .
|
||||
.LP
|
||||
The \fIfilter expression\fP consists of one or more
|
||||
.IR primitives .
|
||||
@@ -86,12 +86,6 @@ The
|
||||
and
|
||||
.B addr4
|
||||
qualifiers are only valid for IEEE 802.11 Wireless LAN link layers.
|
||||
For some link layers, such as SLIP and the ``cooked'' Linux capture mode
|
||||
used for the ``any'' device and for some other device types, the
|
||||
.B inbound
|
||||
and
|
||||
.B outbound
|
||||
qualifiers can be used to specify a desired direction.
|
||||
.IP \fIproto\fP
|
||||
.I proto
|
||||
qualifiers restrict the match to a particular protocol.
|
||||
@@ -466,8 +460,6 @@ Token Ring packets (no check is done for LLC frames);
|
||||
FDDI packets (no check is done for LLC frames);
|
||||
.IP
|
||||
LLC-encapsulated ATM packets, for SunATM on Solaris.
|
||||
.IP
|
||||
|
||||
.IP "\fBllc\fP \Fitype\fR"
|
||||
True if the packet has an 802.2 LLC header and has the specified
|
||||
.IR type .
|
||||
@@ -514,6 +506,16 @@ Exchange Identification (XID) U PDUs
|
||||
\fBfrmr\fR
|
||||
Frame Reject (FRMR) U PDUs
|
||||
.RE
|
||||
.IP \fBinbound\fP
|
||||
Packet was received by the host performing the capture rather than being
|
||||
sent by that host. This is only supported for certain link-layer types,
|
||||
such as SLIP and the ``cooked'' Linux capture mode
|
||||
used for the ``any'' device and for some other device types.
|
||||
.IP \fBoutbound\fP
|
||||
Packet was sent by the host performing the capture rather than being
|
||||
received by that host. This is only supported for certain link-layer types,
|
||||
such as SLIP and the ``cooked'' Linux capture mode
|
||||
used for the ``any'' device and for some other device types.
|
||||
.IP "\fBifname \fIinterface\fR"
|
||||
True if the packet was logged as coming from the specified interface (applies
|
||||
only to packets logged by OpenBSD's or FreeBSD's
|
||||
|
||||
@@ -86,7 +86,12 @@ extern "C" {
|
||||
* 2) small enough not to cause attempts to allocate huge amounts of
|
||||
* memory; some applications might use the snapshot length in a
|
||||
* savefile header to control the size of the buffer they allocate,
|
||||
* so a size of, say, 2^31-1 might not work well.
|
||||
* so a size of, say, 2^31-1 might not work well. (libpcap uses it
|
||||
* as a hint, but doesn't start out allocating a buffer bigger than
|
||||
* 2 KiB, and grows the buffer as necessary, but not beyond the
|
||||
* per-linktype maximum snapshot length. Other code might naively
|
||||
* use it; we want to avoid writing a too-large snapshot length,
|
||||
* in order not to cause that code problems.)
|
||||
*
|
||||
* We don't enforce this in pcap_set_snaplen(), but we use it internally.
|
||||
*/
|
||||
@@ -472,13 +477,38 @@ int add_addr_to_if(pcap_if_list_t *, const char *, bpf_u_int32,
|
||||
* "pcap_open_offline_common()" allocates and fills in a pcap_t, for use
|
||||
* by pcap_open_offline routines.
|
||||
*
|
||||
* "pcap_adjust_snapshot()" adjusts the snapshot to be non-zero and
|
||||
* fit within an int.
|
||||
*
|
||||
* "sf_cleanup()" closes the file handle associated with a pcap_t, if
|
||||
* appropriate, and frees all data common to all modules for handling
|
||||
* savefile types.
|
||||
*/
|
||||
pcap_t *pcap_open_offline_common(char *ebuf, size_t size);
|
||||
bpf_u_int32 pcap_adjust_snapshot(bpf_u_int32 linktype, bpf_u_int32 snaplen);
|
||||
void sf_cleanup(pcap_t *p);
|
||||
|
||||
/*
|
||||
* Internal interfaces for doing user-mode filtering of packets and
|
||||
* validating filter programs.
|
||||
*/
|
||||
/*
|
||||
* Auxiliary data, for use when interpreting a filter intended for the
|
||||
* Linux kernel when the kernel rejects the filter (requiring us to
|
||||
* run it in userland). It contains VLAN tag information.
|
||||
*/
|
||||
struct bpf_aux_data {
|
||||
u_short vlan_tag_present;
|
||||
u_short vlan_tag;
|
||||
};
|
||||
|
||||
/*
|
||||
* Filtering routine that takes the auxiliary data as an additional
|
||||
* argument.
|
||||
*/
|
||||
u_int bpf_filter_with_aux_data(const struct bpf_insn *,
|
||||
const u_char *, u_int, u_int, const struct bpf_aux_data *);
|
||||
|
||||
/*
|
||||
* Internal interfaces for both "pcap_create()" and routines that
|
||||
* open savefiles.
|
||||
@@ -488,10 +518,6 @@ void sf_cleanup(pcap_t *p);
|
||||
*/
|
||||
void pcap_oneshot(u_char *, const struct pcap_pkthdr *, const u_char *);
|
||||
|
||||
#ifdef _WIN32
|
||||
void pcap_win32_err_to_str(DWORD, char *);
|
||||
#endif
|
||||
|
||||
int install_bpf_program(pcap_t *, struct bpf_program *);
|
||||
|
||||
int pcap_strcasecmp(const char *, const char *);
|
||||
|
||||
@@ -80,7 +80,7 @@ list_interfaces(const char *linkname, void *arg)
|
||||
lwp->lw_err = ENOMEM;
|
||||
return (B_TRUE);
|
||||
}
|
||||
(void) strlcpy(entry->linkname, linkname, DLPI_LINKNAME_MAX);
|
||||
(void) pcap_strlcpy(entry->linkname, linkname, DLPI_LINKNAME_MAX);
|
||||
|
||||
if (lwp->lw_list == NULL) {
|
||||
lwp->lw_list = entry;
|
||||
|
||||
@@ -45,4 +45,4 @@ The names for those values begin with
|
||||
The link-layer header types supported by libpcap are described at
|
||||
https://www.tcpdump.org/linktypes.html.
|
||||
.SH SEE ALSO
|
||||
pcap_datalink(3PCAP)
|
||||
pcap(3PCAP)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -301,7 +301,8 @@ netfilter_stats_linux(pcap_t *handle, struct pcap_stat *stats)
|
||||
static int
|
||||
netfilter_inject_linux(pcap_t *handle, const void *buf _U_, size_t size _U_)
|
||||
{
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "inject not supported on netfilter devices");
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Packet injection is not supported on netfilter devices");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
@@ -315,6 +316,7 @@ static int
|
||||
netfilter_send_config_msg(const pcap_t *handle, uint16_t msg_type, int ack, u_int8_t family, u_int16_t res_id, const struct my_nfattr *mynfa)
|
||||
{
|
||||
char buf[1024] __attribute__ ((aligned));
|
||||
memset(buf, 0, sizeof(buf));
|
||||
|
||||
struct nlmsghdr *nlh = (struct nlmsghdr *) buf;
|
||||
struct nfgenmsg *nfg = (struct nfgenmsg *) (buf + sizeof(struct nlmsghdr));
|
||||
|
||||
@@ -67,7 +67,7 @@ pcap_netmap_stats(pcap_t *p, struct pcap_stat *ps)
|
||||
{
|
||||
struct pcap_netmap *pn = p->priv;
|
||||
|
||||
ps->ps_recv = pn->rx_pkts;
|
||||
ps->ps_recv = (u_int)pn->rx_pkts;
|
||||
ps->ps_drop = 0;
|
||||
ps->ps_ifdrop = 0;
|
||||
return 0;
|
||||
|
||||
@@ -35,6 +35,8 @@
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "ftmacros.h"
|
||||
|
||||
/*
|
||||
* sockutils.h may include <crtdbg.h> on Windows, and pcap-int.h will
|
||||
* include portability.h, and portability.h, on Windows, expects that
|
||||
@@ -54,11 +56,14 @@
|
||||
|
||||
/* String identifier to be used in the pcap_findalldevs_ex() */
|
||||
#define PCAP_TEXT_SOURCE_FILE "File"
|
||||
#define PCAP_TEXT_SOURCE_FILE_LEN (sizeof PCAP_TEXT_SOURCE_FILE - 1)
|
||||
/* String identifier to be used in the pcap_findalldevs_ex() */
|
||||
#define PCAP_TEXT_SOURCE_ADAPTER "Network adapter"
|
||||
#define PCAP_TEXT_SOURCE_ADAPTER_LEN (sizeof "Network adapter" - 1)
|
||||
|
||||
/* String identifier to be used in the pcap_findalldevs_ex() */
|
||||
#define PCAP_TEXT_SOURCE_ON_LOCAL_HOST "on local host"
|
||||
#define PCAP_TEXT_SOURCE_ON_LOCAL_HOST_LEN (sizeof PCAP_TEXT_SOURCE_ON_LOCAL_HOST + 1)
|
||||
|
||||
/****************************************************
|
||||
* *
|
||||
@@ -66,10 +71,12 @@
|
||||
* *
|
||||
****************************************************/
|
||||
|
||||
int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **alldevs, char *errbuf)
|
||||
int pcap_findalldevs_ex(const char *source, struct pcap_rmtauth *auth, pcap_if_t **alldevs, char *errbuf)
|
||||
{
|
||||
int type;
|
||||
char name[PCAP_BUF_SIZE], path[PCAP_BUF_SIZE], filename[PCAP_BUF_SIZE];
|
||||
size_t pathlen;
|
||||
size_t stringlen;
|
||||
pcap_t *fp;
|
||||
char tmpstring[PCAP_BUF_SIZE + 1]; /* Needed to convert names and descriptions from 'old' syntax to the 'new' one */
|
||||
pcap_if_t *lastdev; /* Last device in the pcap_if_t list */
|
||||
@@ -113,7 +120,7 @@ int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **all
|
||||
if (*alldevs == NULL)
|
||||
{
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"No interfaces found! Make sure libpcap/WinPcap is properly installed"
|
||||
"No interfaces found! Make sure libpcap/Npcap is properly installed"
|
||||
" on the local machine.");
|
||||
return -1;
|
||||
}
|
||||
@@ -123,6 +130,8 @@ int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **all
|
||||
dev = *alldevs;
|
||||
while (dev)
|
||||
{
|
||||
char *localdesc, *desc;
|
||||
|
||||
/* Create the new device identifier */
|
||||
if (pcap_createsrcstr(tmpstring, PCAP_SRC_IFLOCAL, NULL, NULL, dev->name, errbuf) == -1)
|
||||
return -1;
|
||||
@@ -141,20 +150,16 @@ int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **all
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Create the new device description */
|
||||
/*
|
||||
* Create the description.
|
||||
*/
|
||||
if ((dev->description == NULL) || (dev->description[0] == 0))
|
||||
pcap_snprintf(tmpstring, sizeof(tmpstring) - 1, "%s '%s' %s", PCAP_TEXT_SOURCE_ADAPTER,
|
||||
dev->name, PCAP_TEXT_SOURCE_ON_LOCAL_HOST);
|
||||
localdesc = dev->name;
|
||||
else
|
||||
pcap_snprintf(tmpstring, sizeof(tmpstring) - 1, "%s '%s' %s", PCAP_TEXT_SOURCE_ADAPTER,
|
||||
dev->description, PCAP_TEXT_SOURCE_ON_LOCAL_HOST);
|
||||
|
||||
/* Delete the old pointer */
|
||||
free(dev->description);
|
||||
|
||||
/* Make a copy of the description */
|
||||
dev->description = strdup(tmpstring);
|
||||
if (dev->description == NULL)
|
||||
localdesc = dev->description;
|
||||
if (pcap_asprintf(&desc, "%s '%s' %s",
|
||||
PCAP_TEXT_SOURCE_ADAPTER, localdesc,
|
||||
PCAP_TEXT_SOURCE_ON_LOCAL_HOST) == -1)
|
||||
{
|
||||
pcap_fmt_errmsg_for_errno(errbuf,
|
||||
PCAP_ERRBUF_SIZE, errno,
|
||||
@@ -163,6 +168,10 @@ int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **all
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Now overwrite the description */
|
||||
free(dev->description);
|
||||
dev->description = desc;
|
||||
|
||||
dev = dev->next;
|
||||
}
|
||||
|
||||
@@ -170,7 +179,6 @@ int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **all
|
||||
|
||||
case PCAP_SRC_FILE:
|
||||
{
|
||||
size_t stringlen;
|
||||
#ifdef _WIN32
|
||||
WIN32_FIND_DATA filedata;
|
||||
HANDLE filehandle;
|
||||
@@ -202,6 +210,7 @@ int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **all
|
||||
|
||||
/* Save the path for future reference */
|
||||
pcap_snprintf(path, sizeof(path), "%s", name);
|
||||
pathlen = strlen(path);
|
||||
|
||||
#ifdef _WIN32
|
||||
/* To perform directory listing, Win32 must have an 'asterisk' as ending char */
|
||||
@@ -236,10 +245,14 @@ int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **all
|
||||
/* Add all files we find to the list. */
|
||||
do
|
||||
{
|
||||
|
||||
#ifdef _WIN32
|
||||
/* Skip the file if the pathname won't fit in the buffer */
|
||||
if (pathlen + strlen(filedata.cFileName) >= sizeof(filename))
|
||||
continue;
|
||||
pcap_snprintf(filename, sizeof(filename), "%s%s", path, filedata.cFileName);
|
||||
#else
|
||||
if (pathlen + strlen(filedata->d_name) >= sizeof(filename))
|
||||
continue;
|
||||
pcap_snprintf(filename, sizeof(filename), "%s%s", path, filedata->d_name);
|
||||
#endif
|
||||
|
||||
@@ -287,9 +300,7 @@ int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **all
|
||||
return -1;
|
||||
}
|
||||
|
||||
stringlen = strlen(tmpstring);
|
||||
|
||||
dev->name = (char *)malloc(stringlen + 1);
|
||||
dev->name = strdup(tmpstring);
|
||||
if (dev->name == NULL)
|
||||
{
|
||||
pcap_fmt_errmsg_for_errno(errbuf,
|
||||
@@ -299,19 +310,12 @@ int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **all
|
||||
return -1;
|
||||
}
|
||||
|
||||
strlcpy(dev->name, tmpstring, stringlen);
|
||||
|
||||
dev->name[stringlen] = 0;
|
||||
|
||||
/* Create the description */
|
||||
pcap_snprintf(tmpstring, sizeof(tmpstring) - 1, "%s '%s' %s", PCAP_TEXT_SOURCE_FILE,
|
||||
filename, PCAP_TEXT_SOURCE_ON_LOCAL_HOST);
|
||||
|
||||
stringlen = strlen(tmpstring);
|
||||
|
||||
dev->description = (char *)malloc(stringlen + 1);
|
||||
|
||||
if (dev->description == NULL)
|
||||
/*
|
||||
* Create the description.
|
||||
*/
|
||||
if (pcap_asprintf(&dev->description,
|
||||
"%s '%s' %s", PCAP_TEXT_SOURCE_FILE,
|
||||
filename, PCAP_TEXT_SOURCE_ON_LOCAL_HOST) == -1)
|
||||
{
|
||||
pcap_fmt_errmsg_for_errno(errbuf,
|
||||
PCAP_ERRBUF_SIZE, errno,
|
||||
@@ -320,9 +324,6 @@ int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **all
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Copy the new device description into the correct memory location */
|
||||
strlcpy(dev->description, tmpstring, stringlen + 1);
|
||||
|
||||
pcap_close(fp);
|
||||
}
|
||||
}
|
||||
@@ -345,7 +346,7 @@ int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **all
|
||||
return pcap_findalldevs_ex_remote(source, auth, alldevs, errbuf);
|
||||
|
||||
default:
|
||||
strlcpy(errbuf, "Source type not supported", PCAP_ERRBUF_SIZE);
|
||||
pcap_strlcpy(errbuf, "Source type not supported", PCAP_ERRBUF_SIZE);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -357,6 +358,16 @@ pcap_t *pcap_open(const char *source, int snaplen, int flags, int read_timeout,
|
||||
pcap_t *fp;
|
||||
int status;
|
||||
|
||||
/*
|
||||
* A null device name is equivalent to the "any" device -
|
||||
* which might not be supported on this platform, but
|
||||
* this means that you'll get a "not supported" error
|
||||
* rather than, say, a crash when we try to dereference
|
||||
* the null pointer.
|
||||
*/
|
||||
if (source == NULL)
|
||||
source = "any";
|
||||
|
||||
if (strlen(source) > PCAP_BUF_SIZE)
|
||||
{
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "The source string is too long. Cannot handle it correctly.");
|
||||
@@ -389,7 +400,7 @@ pcap_t *pcap_open(const char *source, int snaplen, int flags, int read_timeout,
|
||||
return pcap_open_rpcap(source, snaplen, flags, read_timeout, auth, errbuf);
|
||||
|
||||
default:
|
||||
strlcpy(errbuf, "Source type not supported", PCAP_ERRBUF_SIZE);
|
||||
pcap_strlcpy(errbuf, "Source type not supported", PCAP_ERRBUF_SIZE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ static int pcap_setnonblock_npf(pcap_t *, int);
|
||||
#define SWAPS(_X) ((_X & 0xff) << 8) | (_X >> 8)
|
||||
|
||||
/*
|
||||
* Private data for capturing on WinPcap devices.
|
||||
* Private data for capturing on WinPcap/Npcap devices.
|
||||
*/
|
||||
struct pcap_win {
|
||||
ADAPTER *adapter; /* the packet32 ADAPTER for the device */
|
||||
@@ -166,11 +166,8 @@ oid_get_request(ADAPTER *adapter, bpf_u_int32 oid, void *data, size_t *lenp,
|
||||
oid_data_arg->Oid = oid;
|
||||
oid_data_arg->Length = (ULONG)(*lenp); /* XXX - check for ridiculously large value? */
|
||||
if (!PacketRequest(adapter, FALSE, oid_data_arg)) {
|
||||
char errmsgbuf[PCAP_ERRBUF_SIZE+1];
|
||||
|
||||
pcap_win32_err_to_str(GetLastError(), errmsgbuf);
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Error calling PacketRequest: %s", errmsgbuf);
|
||||
pcap_fmt_errmsg_for_win32_err(errbuf, PCAP_ERRBUF_SIZE,
|
||||
GetLastError(), "Error calling PacketRequest");
|
||||
free(oid_data_arg);
|
||||
return (-1);
|
||||
}
|
||||
@@ -193,7 +190,6 @@ pcap_stats_npf(pcap_t *p, struct pcap_stat *ps)
|
||||
{
|
||||
struct pcap_win *pw = p->priv;
|
||||
struct bpf_stat bstats;
|
||||
char errbuf[PCAP_ERRBUF_SIZE+1];
|
||||
|
||||
/*
|
||||
* Try to get statistics.
|
||||
@@ -209,9 +205,8 @@ pcap_stats_npf(pcap_t *p, struct pcap_stat *ps)
|
||||
* to us.
|
||||
*/
|
||||
if (!PacketGetStats(pw->adapter, &bstats)) {
|
||||
pcap_win32_err_to_str(GetLastError(), errbuf);
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"PacketGetStats error: %s", errbuf);
|
||||
pcap_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
GetLastError(), "PacketGetStats error");
|
||||
return (-1);
|
||||
}
|
||||
ps->ps_recv = bstats.bs_recv;
|
||||
@@ -256,7 +251,6 @@ pcap_stats_ex_npf(pcap_t *p, int *pcap_stat_size)
|
||||
{
|
||||
struct pcap_win *pw = p->priv;
|
||||
struct bpf_stat bstats;
|
||||
char errbuf[PCAP_ERRBUF_SIZE+1];
|
||||
|
||||
*pcap_stat_size = sizeof (p->stat);
|
||||
|
||||
@@ -268,9 +262,8 @@ pcap_stats_ex_npf(pcap_t *p, int *pcap_stat_size)
|
||||
* same layout, but let's not cheat.)
|
||||
*/
|
||||
if (!PacketGetStatsEx(pw->adapter, &bstats)) {
|
||||
pcap_win32_err_to_str(GetLastError(), errbuf);
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"PacketGetStatsEx error: %s", errbuf);
|
||||
pcap_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
GetLastError(), "PacketGetStatsEx error");
|
||||
return (NULL);
|
||||
}
|
||||
p->stat.ps_recv = bstats.bs_recv;
|
||||
@@ -347,7 +340,6 @@ pcap_oid_set_request_npf(pcap_t *p, bpf_u_int32 oid, const void *data,
|
||||
{
|
||||
struct pcap_win *pw = p->priv;
|
||||
PACKET_OID_DATA *oid_data_arg;
|
||||
char errbuf[PCAP_ERRBUF_SIZE+1];
|
||||
|
||||
/*
|
||||
* Allocate a PACKET_OID_DATA structure to hand to PacketRequest().
|
||||
@@ -367,9 +359,8 @@ pcap_oid_set_request_npf(pcap_t *p, bpf_u_int32 oid, const void *data,
|
||||
oid_data_arg->Length = (ULONG)(*lenp); /* XXX - check for ridiculously large value? */
|
||||
memcpy(oid_data_arg->Data, data, *lenp);
|
||||
if (!PacketRequest(pw->adapter, TRUE, oid_data_arg)) {
|
||||
pcap_win32_err_to_str(GetLastError(), errbuf);
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Error calling PacketRequest: %s", errbuf);
|
||||
pcap_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
GetLastError(), "Error calling PacketRequest");
|
||||
free(oid_data_arg);
|
||||
return (PCAP_ERROR);
|
||||
}
|
||||
@@ -391,7 +382,6 @@ pcap_sendqueue_transmit_npf(pcap_t *p, pcap_send_queue *queue, int sync)
|
||||
{
|
||||
struct pcap_win *pw = p->priv;
|
||||
u_int res;
|
||||
char errbuf[PCAP_ERRBUF_SIZE+1];
|
||||
|
||||
if (pw->adapter==NULL) {
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
@@ -405,9 +395,8 @@ pcap_sendqueue_transmit_npf(pcap_t *p, pcap_send_queue *queue, int sync)
|
||||
(BOOLEAN)sync);
|
||||
|
||||
if(res != queue->len){
|
||||
pcap_win32_err_to_str(GetLastError(), errbuf);
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Error opening adapter: %s", errbuf);
|
||||
pcap_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
GetLastError(), "Error opening adapter");
|
||||
}
|
||||
|
||||
return (res);
|
||||
@@ -534,7 +523,34 @@ pcap_read_npf(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
*/
|
||||
PacketInitPacket(&Packet, (BYTE *)p->buffer, p->bufsize);
|
||||
if (!PacketReceivePacket(pw->adapter, &Packet, TRUE)) {
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read error: PacketReceivePacket failed");
|
||||
/*
|
||||
* Did the device go away?
|
||||
* If so, the error we get is ERROR_GEN_FAILURE.
|
||||
*/
|
||||
DWORD errcode = GetLastError();
|
||||
|
||||
if (errcode == ERROR_GEN_FAILURE) {
|
||||
/*
|
||||
* The device on which we're capturing
|
||||
* went away, or it became unusable
|
||||
* by NPF due to a suspend/resume.
|
||||
*
|
||||
* XXX - hopefully no other error
|
||||
* conditions are indicated by this.
|
||||
*
|
||||
* XXX - we really should return an
|
||||
* appropriate error for that, but
|
||||
* pcap_dispatch() etc. aren't
|
||||
* documented as having error returns
|
||||
* other than PCAP_ERROR or PCAP_ERROR_BREAK.
|
||||
*/
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"The interface disappeared");
|
||||
} else {
|
||||
pcap_fmt_errmsg_for_win32_err(p->errbuf,
|
||||
PCAP_ERRBUF_SIZE, errcode,
|
||||
"PacketReceivePacket error");
|
||||
}
|
||||
return (PCAP_ERROR);
|
||||
}
|
||||
|
||||
@@ -873,7 +889,7 @@ pcap_activate_npf(pcap_t *p)
|
||||
struct pcap_win *pw = p->priv;
|
||||
NetType type;
|
||||
int res;
|
||||
char errbuf[PCAP_ERRBUF_SIZE+1];
|
||||
int status = 0;
|
||||
|
||||
if (p->opt.rfmon) {
|
||||
/*
|
||||
@@ -912,23 +928,35 @@ pcap_activate_npf(pcap_t *p)
|
||||
|
||||
if (pw->adapter == NULL)
|
||||
{
|
||||
/* Adapter detected but we are not able to open it. Return failure. */
|
||||
pcap_win32_err_to_str(GetLastError(), errbuf);
|
||||
if (pw->rfmon_selfstart)
|
||||
{
|
||||
PacketSetMonitorMode(p->opt.device, 0);
|
||||
DWORD errcode = GetLastError();
|
||||
|
||||
/*
|
||||
* What error did we get when trying to open the adapter?
|
||||
*/
|
||||
if (errcode == ERROR_BAD_UNIT) {
|
||||
/*
|
||||
* There's no such device.
|
||||
*/
|
||||
return (PCAP_ERROR_NO_SUCH_DEVICE);
|
||||
} else {
|
||||
/*
|
||||
* Unknown - report details.
|
||||
*/
|
||||
pcap_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
errcode, "Error opening adapter");
|
||||
if (pw->rfmon_selfstart)
|
||||
{
|
||||
PacketSetMonitorMode(p->opt.device, 0);
|
||||
}
|
||||
return (PCAP_ERROR);
|
||||
}
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Error opening adapter: %s", errbuf);
|
||||
return (PCAP_ERROR);
|
||||
}
|
||||
|
||||
/*get network type*/
|
||||
if(PacketGetNetType (pw->adapter,&type) == FALSE)
|
||||
{
|
||||
pcap_win32_err_to_str(GetLastError(), errbuf);
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Cannot determine the network type: %s", errbuf);
|
||||
pcap_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
GetLastError(), "Cannot determine the network type");
|
||||
goto bad;
|
||||
}
|
||||
|
||||
@@ -1006,8 +1034,29 @@ pcap_activate_npf(pcap_t *p)
|
||||
p->linktype = DLT_PPI;
|
||||
break;
|
||||
|
||||
#ifdef NdisMediumWirelessWan
|
||||
case NdisMediumWirelessWan:
|
||||
p->linktype = DLT_RAW;
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
p->linktype = DLT_EN10MB; /*an unknown adapter is assumed to be ethernet*/
|
||||
/*
|
||||
* An unknown medium type is assumed to supply Ethernet
|
||||
* headers; if not, the user will have to report it,
|
||||
* so that the medium type and link-layer header type
|
||||
* can be determined. If we were to fail here, we
|
||||
* might get the link-layer type in the error, but
|
||||
* the user wouldn't get a capture, so we wouldn't
|
||||
* be able to determine the link-layer type; we report
|
||||
* a warning with the link-layer type, so at least
|
||||
* some programs will report the warning.
|
||||
*/
|
||||
p->linktype = DLT_EN10MB;
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Unknown NdisMedium value %d, defaulting to DLT_EN10MB",
|
||||
type.LinkType);
|
||||
status = PCAP_WARNING;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1085,10 +1134,9 @@ pcap_activate_npf(pcap_t *p)
|
||||
/* tell the driver to copy the buffer as soon as data arrives */
|
||||
if(PacketSetMinToCopy(pw->adapter,0)==FALSE)
|
||||
{
|
||||
pcap_win32_err_to_str(GetLastError(), errbuf);
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Error calling PacketSetMinToCopy: %s",
|
||||
errbuf);
|
||||
pcap_fmt_errmsg_for_win32_err(p->errbuf,
|
||||
PCAP_ERRBUF_SIZE, GetLastError(),
|
||||
"Error calling PacketSetMinToCopy");
|
||||
goto bad;
|
||||
}
|
||||
}
|
||||
@@ -1097,10 +1145,9 @@ pcap_activate_npf(pcap_t *p)
|
||||
/* tell the driver to copy the buffer only if it contains at least 16K */
|
||||
if(PacketSetMinToCopy(pw->adapter,16000)==FALSE)
|
||||
{
|
||||
pcap_win32_err_to_str(GetLastError(), errbuf);
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Error calling PacketSetMinToCopy: %s",
|
||||
errbuf);
|
||||
pcap_fmt_errmsg_for_win32_err(p->errbuf,
|
||||
PCAP_ERRBUF_SIZE, GetLastError(),
|
||||
"Error calling PacketSetMinToCopy");
|
||||
goto bad;
|
||||
}
|
||||
}
|
||||
@@ -1221,7 +1268,7 @@ pcap_activate_npf(pcap_t *p)
|
||||
*/
|
||||
p->handle = pw->adapter->hFile;
|
||||
|
||||
return (0);
|
||||
return (status);
|
||||
bad:
|
||||
pcap_cleanup_npf(p);
|
||||
return (PCAP_ERROR);
|
||||
@@ -1316,7 +1363,7 @@ pcap_setfilter_win32_dag(pcap_t *p, struct bpf_program *fp) {
|
||||
|
||||
if(!fp)
|
||||
{
|
||||
strlcpy(p->errbuf, "setfilter: No filter specified", sizeof(p->errbuf));
|
||||
pcap_strlcpy(p->errbuf, "setfilter: No filter specified", sizeof(p->errbuf));
|
||||
return (-1);
|
||||
}
|
||||
|
||||
@@ -1345,7 +1392,6 @@ pcap_setnonblock_npf(pcap_t *p, int nonblock)
|
||||
{
|
||||
struct pcap_win *pw = p->priv;
|
||||
int newtimeout;
|
||||
char win_errbuf[PCAP_ERRBUF_SIZE+1];
|
||||
|
||||
if (nonblock) {
|
||||
/*
|
||||
@@ -1365,9 +1411,8 @@ pcap_setnonblock_npf(pcap_t *p, int nonblock)
|
||||
newtimeout = p->opt.timeout;
|
||||
}
|
||||
if (!PacketSetReadTimeout(pw->adapter, newtimeout)) {
|
||||
pcap_win32_err_to_str(GetLastError(), win_errbuf);
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"PacketSetReadTimeout: %s", win_errbuf);
|
||||
pcap_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
GetLastError(), "PacketSetReadTimeout");
|
||||
return (-1);
|
||||
}
|
||||
pw->nonblock = (newtimeout == -1);
|
||||
@@ -1684,7 +1729,6 @@ pcap_platform_finddevs(pcap_if_list_t *devlistp, char *errbuf)
|
||||
char *AdaptersName;
|
||||
ULONG NameLength;
|
||||
char *name;
|
||||
char our_errbuf[PCAP_ERRBUF_SIZE+1];
|
||||
|
||||
/*
|
||||
* Find out how big a buffer we need.
|
||||
@@ -1710,9 +1754,8 @@ pcap_platform_finddevs(pcap_if_list_t *devlistp, char *errbuf)
|
||||
|
||||
if (last_error != ERROR_INSUFFICIENT_BUFFER)
|
||||
{
|
||||
pcap_win32_err_to_str(last_error, our_errbuf);
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"PacketGetAdapterNames: %s", our_errbuf);
|
||||
pcap_fmt_errmsg_for_win32_err(errbuf, PCAP_ERRBUF_SIZE,
|
||||
last_error, "PacketGetAdapterNames");
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
@@ -1727,9 +1770,8 @@ pcap_platform_finddevs(pcap_if_list_t *devlistp, char *errbuf)
|
||||
}
|
||||
|
||||
if (!PacketGetAdapterNames(AdaptersName, &NameLength)) {
|
||||
pcap_win32_err_to_str(GetLastError(), our_errbuf);
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "PacketGetAdapterNames: %s",
|
||||
our_errbuf);
|
||||
pcap_fmt_errmsg_for_win32_err(errbuf, PCAP_ERRBUF_SIZE,
|
||||
GetLastError(), "PacketGetAdapterNames");
|
||||
free(AdaptersName);
|
||||
return (-1);
|
||||
}
|
||||
@@ -1818,7 +1860,6 @@ pcap_lookupdev(char *errbuf)
|
||||
{
|
||||
DWORD dwVersion;
|
||||
DWORD dwWindowsMajorVersion;
|
||||
char our_errbuf[PCAP_ERRBUF_SIZE+1];
|
||||
|
||||
#pragma warning (push)
|
||||
#pragma warning (disable: 4996) /* disable MSVC's GetVersion() deprecated warning here */
|
||||
@@ -1860,9 +1901,8 @@ pcap_lookupdev(char *errbuf)
|
||||
|
||||
if ( !PacketGetAdapterNames((PTSTR)TAdaptersName,&NameLength) )
|
||||
{
|
||||
pcap_win32_err_to_str(GetLastError(), our_errbuf);
|
||||
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"PacketGetAdapterNames: %s", our_errbuf);
|
||||
pcap_fmt_errmsg_for_win32_err(errbuf, PCAP_ERRBUF_SIZE,
|
||||
GetLastError(), "PacketGetAdapterNames");
|
||||
free(TAdaptersName);
|
||||
return NULL;
|
||||
}
|
||||
@@ -2000,59 +2040,48 @@ static const char *pcap_lib_version_string;
|
||||
* tree. Include version.h from that source tree to get the WinPcap/Npcap
|
||||
* version.
|
||||
*
|
||||
* XXX - it'd be nice if we could somehow generate the WinPcap version number
|
||||
* when building WinPcap. (It'd be nice to do so for the packet.dll version
|
||||
* number as well.)
|
||||
* XXX - it'd be nice if we could somehow generate the WinPcap/Npcap version
|
||||
* number when building as part of WinPcap/Npcap. (It'd be nice to do so
|
||||
* for the packet.dll version number as well.)
|
||||
*/
|
||||
#include "../../version.h"
|
||||
|
||||
static const char pcap_version_string[] =
|
||||
WINPCAP_PRODUCT_NAME " version " WINPCAP_VER_STRING ", based on " PCAP_VERSION_STRING;
|
||||
static const char pcap_version_string_packet_dll_fmt[] =
|
||||
WINPCAP_PRODUCT_NAME " version " WINPCAP_VER_STRING " (packet.dll version %s), based on " PCAP_VERSION_STRING;
|
||||
|
||||
const char *
|
||||
pcap_lib_version(void)
|
||||
{
|
||||
char *packet_version_string;
|
||||
size_t full_pcap_version_string_len;
|
||||
char *full_pcap_version_string;
|
||||
|
||||
if (pcap_lib_version_string == NULL) {
|
||||
/*
|
||||
* Generate the version string.
|
||||
*/
|
||||
packet_version_string = PacketGetVersion();
|
||||
char *packet_version_string = PacketGetVersion();
|
||||
|
||||
if (strcmp(WINPCAP_VER_STRING, packet_version_string) == 0) {
|
||||
/*
|
||||
* WinPcap version string and packet.dll version
|
||||
* string are the same; just report the WinPcap
|
||||
* WinPcap/Npcap version string and packet.dll version
|
||||
* string are the same; just report the WinPcap/Npcap
|
||||
* version.
|
||||
*/
|
||||
pcap_lib_version_string = pcap_version_string;
|
||||
} else {
|
||||
/*
|
||||
* WinPcap version string and packet.dll version
|
||||
* WinPcap/Npcap version string and packet.dll version
|
||||
* string are different; that shouldn't be the
|
||||
* case (the two libraries should come from the
|
||||
* same version of WinPcap), so we report both
|
||||
* same version of WinPcap/Npcap), so we report both
|
||||
* versions.
|
||||
*
|
||||
* The -2 is for the %s in the format string,
|
||||
* which will be replaced by packet_version_string.
|
||||
*/
|
||||
full_pcap_version_string_len =
|
||||
(sizeof pcap_version_string_packet_dll_fmt - 2) +
|
||||
strlen(packet_version_string);
|
||||
full_pcap_version_string = malloc(full_pcap_version_string_len);
|
||||
if (full_pcap_version_string == NULL)
|
||||
return (NULL);
|
||||
pcap_snprintf(full_pcap_version_string,
|
||||
full_pcap_version_string_len,
|
||||
pcap_version_string_packet_dll_fmt,
|
||||
packet_version_string);
|
||||
char *full_pcap_version_string;
|
||||
|
||||
if (pcap_asprintf(&full_pcap_version_string,
|
||||
WINPCAP_PRODUCT_NAME " version " WINPCAP_VER_STRING " (packet.dll version %s), based on " PCAP_VERSION_STRING,
|
||||
packet_version_string) != -1) {
|
||||
/* Success */
|
||||
pcap_lib_version_string = full_pcap_version_string;
|
||||
}
|
||||
}
|
||||
pcap_lib_version_string = full_pcap_version_string;
|
||||
}
|
||||
return (pcap_lib_version_string);
|
||||
}
|
||||
@@ -2063,35 +2092,22 @@ pcap_lib_version(void)
|
||||
* libpcap being built for Windows, not as part of a WinPcap/Npcap source
|
||||
* tree.
|
||||
*/
|
||||
static const char pcap_version_string_packet_dll_fmt[] =
|
||||
PCAP_VERSION_STRING " (packet.dll version %s)";
|
||||
const char *
|
||||
pcap_lib_version(void)
|
||||
{
|
||||
char *packet_version_string;
|
||||
size_t full_pcap_version_string_len;
|
||||
char *full_pcap_version_string;
|
||||
|
||||
if (pcap_lib_version_string == NULL) {
|
||||
/*
|
||||
* Generate the version string. Report the packet.dll
|
||||
* version.
|
||||
*
|
||||
* The -2 is for the %s in the format string, which will
|
||||
* be replaced by packet_version_string.
|
||||
*/
|
||||
packet_version_string = PacketGetVersion();
|
||||
full_pcap_version_string_len =
|
||||
(sizeof pcap_version_string_packet_dll_fmt - 2) +
|
||||
strlen(packet_version_string);
|
||||
full_pcap_version_string = malloc(full_pcap_version_string_len);
|
||||
if (full_pcap_version_string == NULL)
|
||||
return (NULL);
|
||||
pcap_snprintf(full_pcap_version_string,
|
||||
full_pcap_version_string_len,
|
||||
pcap_version_string_packet_dll_fmt,
|
||||
packet_version_string);
|
||||
pcap_lib_version_string = full_pcap_version_string;
|
||||
char *full_pcap_version_string;
|
||||
|
||||
if (pcap_asprintf(&full_pcap_version_string,
|
||||
PCAP_VERSION_STRING " (packet.dll version %s)",
|
||||
PacketGetVersion()) != -1) {
|
||||
/* Success */
|
||||
pcap_lib_version_string = full_pcap_version_string;
|
||||
}
|
||||
}
|
||||
return (pcap_lib_version_string);
|
||||
}
|
||||
|
||||
@@ -32,12 +32,12 @@ static char nosup[] = "live packet capture not supported on this system";
|
||||
pcap_t *
|
||||
pcap_create_interface(const char *device _U_, char *ebuf)
|
||||
{
|
||||
(void)strlcpy(ebuf, nosup, PCAP_ERRBUF_SIZE);
|
||||
(void)pcap_strlcpy(ebuf, nosup, PCAP_ERRBUF_SIZE);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
int
|
||||
pcap_platform_finddevs(pcap_if_list_t *devlistp, char *errbuf)
|
||||
pcap_platform_finddevs(pcap_if_list_t *devlistp _U_, char *errbuf _U_)
|
||||
{
|
||||
/*
|
||||
* There are no interfaces on which we can capture.
|
||||
@@ -50,7 +50,7 @@ int
|
||||
pcap_lookupnet(const char *device _U_, bpf_u_int32 *netp _U_,
|
||||
bpf_u_int32 *maskp _U_, char *errbuf)
|
||||
{
|
||||
(void)strlcpy(errbuf, nosup, PCAP_ERRBUF_SIZE);
|
||||
(void)pcap_strlcpy(errbuf, nosup, PCAP_ERRBUF_SIZE);
|
||||
return (-1);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -155,7 +155,6 @@ static void pcap_save_current_filter_rpcap(pcap_t *fp, const char *filter);
|
||||
static int pcap_setfilter_rpcap(pcap_t *fp, struct bpf_program *prog);
|
||||
static int pcap_setsampling_remote(pcap_t *fp);
|
||||
static int pcap_startcapture_remote(pcap_t *fp);
|
||||
static int rpcap_sendauth(SOCKET sock, uint8 *ver, struct pcap_rmtauth *auth, char *errbuf);
|
||||
static int rpcap_recv_msg_header(SOCKET sock, struct rpcap_header *header, char *errbuf);
|
||||
static int rpcap_check_msg_ver(SOCKET sock, uint8 expected_ver, struct rpcap_header *header, char *errbuf);
|
||||
static int rpcap_check_msg_type(SOCKET sock, uint8 request_type, struct rpcap_header *header, uint16 *errcode, char *errbuf);
|
||||
@@ -409,7 +408,7 @@ static int pcap_read_nocb_remote(pcap_t *p, struct pcap_pkthdr *pkt_header, u_ch
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
sock_geterror("select(): ", p->errbuf, PCAP_ERRBUF_SIZE);
|
||||
sock_geterror("select()", p->errbuf, PCAP_ERRBUF_SIZE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -763,6 +762,8 @@ static void pcap_cleanup_rpcap(pcap_t *fp)
|
||||
pr->currentfilter = NULL;
|
||||
}
|
||||
|
||||
pcap_cleanup_live_common(fp);
|
||||
|
||||
/* To avoid inconsistencies in the number of sock_init() */
|
||||
sock_cleanup();
|
||||
}
|
||||
@@ -1069,7 +1070,7 @@ static int pcap_startcapture_remote(pcap_t *fp)
|
||||
saddrlen = sizeof(struct sockaddr_storage);
|
||||
if (getpeername(pr->rmt_sockctrl, (struct sockaddr *) &saddr, &saddrlen) == -1)
|
||||
{
|
||||
sock_geterror("getsockname(): ", fp->errbuf, PCAP_ERRBUF_SIZE);
|
||||
sock_geterror("getsockname()", fp->errbuf, PCAP_ERRBUF_SIZE);
|
||||
goto error_nodiscard;
|
||||
}
|
||||
ai_family = ((struct sockaddr_storage *) &saddr)->ss_family;
|
||||
@@ -1078,7 +1079,7 @@ static int pcap_startcapture_remote(pcap_t *fp)
|
||||
if (getnameinfo((struct sockaddr *) &saddr, saddrlen, host,
|
||||
sizeof(host), NULL, 0, NI_NUMERICHOST))
|
||||
{
|
||||
sock_geterror("getnameinfo(): ", fp->errbuf, PCAP_ERRBUF_SIZE);
|
||||
sock_geterror("getnameinfo()", fp->errbuf, PCAP_ERRBUF_SIZE);
|
||||
goto error_nodiscard;
|
||||
}
|
||||
|
||||
@@ -1116,7 +1117,7 @@ static int pcap_startcapture_remote(pcap_t *fp)
|
||||
saddrlen = sizeof(struct sockaddr_storage);
|
||||
if (getsockname(sockdata, (struct sockaddr *) &saddr, &saddrlen) == -1)
|
||||
{
|
||||
sock_geterror("getsockname(): ", fp->errbuf, PCAP_ERRBUF_SIZE);
|
||||
sock_geterror("getsockname()", fp->errbuf, PCAP_ERRBUF_SIZE);
|
||||
goto error_nodiscard;
|
||||
}
|
||||
|
||||
@@ -1124,7 +1125,7 @@ static int pcap_startcapture_remote(pcap_t *fp)
|
||||
if (getnameinfo((struct sockaddr *) &saddr, saddrlen, NULL,
|
||||
0, portdata, sizeof(portdata), NI_NUMERICSERV))
|
||||
{
|
||||
sock_geterror("getnameinfo(): ", fp->errbuf, PCAP_ERRBUF_SIZE);
|
||||
sock_geterror("getnameinfo()", fp->errbuf, PCAP_ERRBUF_SIZE);
|
||||
goto error_nodiscard;
|
||||
}
|
||||
}
|
||||
@@ -1234,7 +1235,7 @@ static int pcap_startcapture_remote(pcap_t *fp)
|
||||
|
||||
if (socktemp == INVALID_SOCKET)
|
||||
{
|
||||
sock_geterror("accept(): ", fp->errbuf, PCAP_ERRBUF_SIZE);
|
||||
sock_geterror("accept()", fp->errbuf, PCAP_ERRBUF_SIZE);
|
||||
goto error;
|
||||
}
|
||||
|
||||
@@ -1260,8 +1261,8 @@ static int pcap_startcapture_remote(pcap_t *fp)
|
||||
res = getsockopt(sockdata, SOL_SOCKET, SO_RCVBUF, (char *)&sockbufsize, &itemp);
|
||||
if (res == -1)
|
||||
{
|
||||
sock_geterror("pcap_startcapture_remote()", fp->errbuf, PCAP_ERRBUF_SIZE);
|
||||
SOCK_DEBUG_MESSAGE(fp->errbuf);
|
||||
sock_geterror("pcap_startcapture_remote(): getsockopt() failed", fp->errbuf, PCAP_ERRBUF_SIZE);
|
||||
goto error;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1612,21 +1613,19 @@ static int pcap_createfilter_norpcappkt(pcap_t *fp, struct bpf_program *prog)
|
||||
char peeraddress[128];
|
||||
char peerctrlport[128];
|
||||
char *newfilter;
|
||||
const int newstringsize = 1024;
|
||||
size_t currentfiltersize;
|
||||
|
||||
/* Get the name/port of our peer */
|
||||
saddrlen = sizeof(struct sockaddr_storage);
|
||||
if (getpeername(pr->rmt_sockctrl, (struct sockaddr *) &saddr, &saddrlen) == -1)
|
||||
{
|
||||
sock_geterror("getpeername(): ", fp->errbuf, PCAP_ERRBUF_SIZE);
|
||||
sock_geterror("getpeername()", fp->errbuf, PCAP_ERRBUF_SIZE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (getnameinfo((struct sockaddr *) &saddr, saddrlen, peeraddress,
|
||||
sizeof(peeraddress), peerctrlport, sizeof(peerctrlport), NI_NUMERICHOST | NI_NUMERICSERV))
|
||||
{
|
||||
sock_geterror("getnameinfo(): ", fp->errbuf, PCAP_ERRBUF_SIZE);
|
||||
sock_geterror("getnameinfo()", fp->errbuf, PCAP_ERRBUF_SIZE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1634,7 +1633,7 @@ static int pcap_createfilter_norpcappkt(pcap_t *fp, struct bpf_program *prog)
|
||||
/* Get the name/port of the current host */
|
||||
if (getsockname(pr->rmt_sockctrl, (struct sockaddr *) &saddr, &saddrlen) == -1)
|
||||
{
|
||||
sock_geterror("getsockname(): ", fp->errbuf, PCAP_ERRBUF_SIZE);
|
||||
sock_geterror("getsockname()", fp->errbuf, PCAP_ERRBUF_SIZE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1642,43 +1641,60 @@ static int pcap_createfilter_norpcappkt(pcap_t *fp, struct bpf_program *prog)
|
||||
if (getnameinfo((struct sockaddr *) &saddr, saddrlen, myaddress,
|
||||
sizeof(myaddress), myctrlport, sizeof(myctrlport), NI_NUMERICHOST | NI_NUMERICSERV))
|
||||
{
|
||||
sock_geterror("getnameinfo(): ", fp->errbuf, PCAP_ERRBUF_SIZE);
|
||||
sock_geterror("getnameinfo()", fp->errbuf, PCAP_ERRBUF_SIZE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Let's now check the data port */
|
||||
if (getsockname(pr->rmt_sockdata, (struct sockaddr *) &saddr, &saddrlen) == -1)
|
||||
{
|
||||
sock_geterror("getsockname(): ", fp->errbuf, PCAP_ERRBUF_SIZE);
|
||||
sock_geterror("getsockname()", fp->errbuf, PCAP_ERRBUF_SIZE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Get the local port the system picked up */
|
||||
if (getnameinfo((struct sockaddr *) &saddr, saddrlen, NULL, 0, mydataport, sizeof(mydataport), NI_NUMERICSERV))
|
||||
{
|
||||
sock_geterror("getnameinfo(): ", fp->errbuf, PCAP_ERRBUF_SIZE);
|
||||
sock_geterror("getnameinfo()", fp->errbuf, PCAP_ERRBUF_SIZE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
currentfiltersize = pr->currentfilter ? strlen(pr->currentfilter) : 0;
|
||||
|
||||
newfilter = (char *)malloc(currentfiltersize + newstringsize + 1);
|
||||
|
||||
if (currentfiltersize)
|
||||
if (pr->currentfilter && pr->currentfilter[0] != '\0')
|
||||
{
|
||||
pcap_snprintf(newfilter, currentfiltersize + newstringsize,
|
||||
"(%s) and not (host %s and host %s and port %s and port %s) and not (host %s and host %s and port %s)",
|
||||
pr->currentfilter, myaddress, peeraddress, myctrlport, peerctrlport, myaddress, peeraddress, mydataport);
|
||||
/*
|
||||
* We have a current filter; add items to it to
|
||||
* filter out this rpcap session.
|
||||
*/
|
||||
if (pcap_asprintf(&newfilter,
|
||||
"(%s) and not (host %s and host %s and port %s and port %s) and not (host %s and host %s and port %s)",
|
||||
pr->currentfilter, myaddress, peeraddress,
|
||||
myctrlport, peerctrlport, myaddress, peeraddress,
|
||||
mydataport) == -1)
|
||||
{
|
||||
/* Failed. */
|
||||
pcap_snprintf(fp->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Can't allocate memory for new filter");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pcap_snprintf(newfilter, currentfiltersize + newstringsize,
|
||||
"not (host %s and host %s and port %s and port %s) and not (host %s and host %s and port %s)",
|
||||
myaddress, peeraddress, myctrlport, peerctrlport, myaddress, peeraddress, mydataport);
|
||||
/*
|
||||
* We have no current filter; construct a filter to
|
||||
* filter out this rpcap session.
|
||||
*/
|
||||
if (pcap_asprintf(&newfilter,
|
||||
"not (host %s and host %s and port %s and port %s) and not (host %s and host %s and port %s)",
|
||||
myaddress, peeraddress, myctrlport, peerctrlport,
|
||||
myaddress, peeraddress, mydataport) == -1)
|
||||
{
|
||||
/* Failed. */
|
||||
pcap_snprintf(fp->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Can't allocate memory for new filter");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
newfilter[currentfiltersize + newstringsize] = 0;
|
||||
|
||||
/*
|
||||
* This is only an hack to prevent the save_current_filter
|
||||
* routine, which will be called when we call pcap_compile(),
|
||||
@@ -1785,16 +1801,25 @@ static int pcap_setsampling_remote(pcap_t *fp)
|
||||
|
||||
/*
|
||||
* This function performs authentication and protocol version
|
||||
* negotiation. It first tries to authenticate with the maximum
|
||||
* version we support and, if that fails with an "I don't support
|
||||
* that version" error from the server, and the version number in
|
||||
* the reply from the server is one we support, tries again with
|
||||
* that version.
|
||||
* negotiation. It is required in order to open the connection
|
||||
* with the other end party.
|
||||
*
|
||||
* It sends authentication parameters on the control socket and
|
||||
* reads the reply. If the reply is a success indication, it
|
||||
* checks whether the reply includes minimum and maximum supported
|
||||
* versions from the server; if not, it assumes both are 0, as
|
||||
* that means it's an older server that doesn't return supported
|
||||
* version numbers in authentication replies, so it only supports
|
||||
* version 0. It then tries to determine the maximum version
|
||||
* supported both by us and by the server. If it can find such a
|
||||
* version, it sets us up to use that version; otherwise, it fails,
|
||||
* indicating that there is no version supported by us and by the
|
||||
* server.
|
||||
*
|
||||
* \param sock: the socket we are currently using.
|
||||
*
|
||||
* \param ver: pointer to variable holding protocol version number to send
|
||||
* and to set to the protocol version number in the reply.
|
||||
* \param ver: pointer to variable to which to set the protocol version
|
||||
* number we selected.
|
||||
*
|
||||
* \param auth: authentication parameters that have to be sent.
|
||||
*
|
||||
@@ -1807,96 +1832,17 @@ static int pcap_setsampling_remote(pcap_t *fp)
|
||||
* an error message string is returned in the 'errbuf' variable.
|
||||
*/
|
||||
static int rpcap_doauth(SOCKET sockctrl, uint8 *ver, struct pcap_rmtauth *auth, char *errbuf)
|
||||
{
|
||||
int status;
|
||||
|
||||
/*
|
||||
* Send authentication to the remote machine.
|
||||
*
|
||||
* First try with the maximum version number we support.
|
||||
*/
|
||||
*ver = RPCAP_MAX_VERSION;
|
||||
status = rpcap_sendauth(sockctrl, ver, auth, errbuf);
|
||||
if (status == 0)
|
||||
{
|
||||
//
|
||||
// Success.
|
||||
//
|
||||
return 0;
|
||||
}
|
||||
if (status == -1)
|
||||
{
|
||||
/* Unrecoverable error. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* The server doesn't support the version we used in the initial
|
||||
* message, and it sent us back a reply either with the maximum
|
||||
* version they do support, or with the version we sent, and we
|
||||
* support that version. *ver has been set to that version; try
|
||||
* authenticating again with that version.
|
||||
*/
|
||||
status = rpcap_sendauth(sockctrl, ver, auth, errbuf);
|
||||
if (status == 0)
|
||||
{
|
||||
//
|
||||
// Success.
|
||||
//
|
||||
return 0;
|
||||
}
|
||||
if (status == -1)
|
||||
{
|
||||
/* Unrecoverable error. */
|
||||
return -1;
|
||||
}
|
||||
if (status == -2)
|
||||
{
|
||||
/*
|
||||
* The server doesn't support that version, which
|
||||
* means there is no version we both support, so
|
||||
* this is a fatal error.
|
||||
*/
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "The server doesn't support any protocol version that we support");
|
||||
return -1;
|
||||
}
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "rpcap_sendauth() returned %d", status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function sends the authentication message.
|
||||
*
|
||||
* It sends the authentication parameters on the control socket.
|
||||
* It is required in order to open the connection with the other end party.
|
||||
*
|
||||
* \param sock: the socket we are currently using.
|
||||
*
|
||||
* \param ver: pointer to variable holding protocol version number to send
|
||||
* and to set to the protocol version number in the reply.
|
||||
*
|
||||
* \param auth: authentication parameters that have to be sent.
|
||||
*
|
||||
* \param errbuf: a pointer to a user-allocated buffer (of size
|
||||
* PCAP_ERRBUF_SIZE) that will contain the error message (in case there
|
||||
* is one). It could be a network problem or the fact that the authorization
|
||||
* failed.
|
||||
*
|
||||
* \return '0' if everything is fine, '-2' if the server didn't reply with
|
||||
* the protocol version we requested but replied with a version we do
|
||||
* support, or '-1' for other errors. For errors, an error message string
|
||||
* is returned in the 'errbuf' variable.
|
||||
*/
|
||||
static int rpcap_sendauth(SOCKET sock, uint8 *ver, struct pcap_rmtauth *auth, char *errbuf)
|
||||
{
|
||||
char sendbuf[RPCAP_NETBUF_SIZE]; /* temporary buffer in which data that has to be sent is buffered */
|
||||
int sendbufidx = 0; /* index which keeps the number of bytes currently buffered */
|
||||
uint16 length; /* length of the payload of this message */
|
||||
uint16 errcode;
|
||||
struct rpcap_auth *rpauth;
|
||||
uint16 auth_type;
|
||||
struct rpcap_header header;
|
||||
size_t str_length;
|
||||
uint32 plen;
|
||||
struct rpcap_authreply authreply; /* authentication reply message */
|
||||
uint8 ourvers;
|
||||
|
||||
if (auth)
|
||||
{
|
||||
@@ -1943,12 +1889,11 @@ static int rpcap_sendauth(SOCKET sock, uint8 *ver, struct pcap_rmtauth *auth, ch
|
||||
length = sizeof(struct rpcap_auth);
|
||||
}
|
||||
|
||||
|
||||
if (sock_bufferize(NULL, sizeof(struct rpcap_header), NULL,
|
||||
&sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errbuf, PCAP_ERRBUF_SIZE))
|
||||
return -1;
|
||||
|
||||
rpcap_createhdr((struct rpcap_header *) sendbuf, *ver,
|
||||
rpcap_createhdr((struct rpcap_header *) sendbuf, 0,
|
||||
RPCAP_MSG_AUTH_REQ, 0, length);
|
||||
|
||||
rpauth = (struct rpcap_auth *) &sendbuf[sendbufidx];
|
||||
@@ -1985,62 +1930,104 @@ static int rpcap_sendauth(SOCKET sock, uint8 *ver, struct pcap_rmtauth *auth, ch
|
||||
rpauth->slen2 = htons(rpauth->slen2);
|
||||
}
|
||||
|
||||
if (sock_send(sock, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) < 0)
|
||||
if (sock_send(sockctrl, sendbuf, sendbufidx, errbuf,
|
||||
PCAP_ERRBUF_SIZE) < 0)
|
||||
return -1;
|
||||
|
||||
/* Receive the reply */
|
||||
if (rpcap_recv_msg_header(sock, &header, errbuf) == -1)
|
||||
/* Receive and process the reply message header */
|
||||
if (rpcap_process_msg_header(sockctrl, 0, RPCAP_MSG_AUTH_REQ,
|
||||
&header, errbuf) == -1)
|
||||
return -1;
|
||||
|
||||
if (rpcap_check_msg_type(sock, RPCAP_MSG_AUTH_REQ, &header,
|
||||
&errcode, errbuf) == -1)
|
||||
/*
|
||||
* OK, it's an authentication reply, so we're logged in.
|
||||
*
|
||||
* Did it send any additional information?
|
||||
*/
|
||||
plen = header.plen;
|
||||
if (plen != 0)
|
||||
{
|
||||
/* Error message - or something else, which is a protocol error. */
|
||||
if (header.type == RPCAP_MSG_ERROR &&
|
||||
errcode == PCAP_ERR_WRONGVER)
|
||||
/* Yes - is it big enough to be version information? */
|
||||
if (plen < sizeof(struct rpcap_authreply))
|
||||
{
|
||||
/*
|
||||
* The server didn't support the version we sent,
|
||||
* and replied with the maximum version it supports
|
||||
* if our version was too big or with the version
|
||||
* we sent if out version was too small.
|
||||
*
|
||||
* Do we also support it?
|
||||
*/
|
||||
if (!RPCAP_VERSION_IS_SUPPORTED(header.ver))
|
||||
{
|
||||
/*
|
||||
* No, so there's no version we both support.
|
||||
* This is an unrecoverable error.
|
||||
*/
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "The server doesn't support any protocol version that we support");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* OK, use that version, and tell our caller to
|
||||
* try again.
|
||||
*/
|
||||
*ver = header.ver;
|
||||
return -2;
|
||||
/* No - discard it and fail. */
|
||||
(void)rpcap_discard(sockctrl, plen, NULL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Read the reply body */
|
||||
if (rpcap_recv(sockctrl, (char *)&authreply,
|
||||
sizeof(struct rpcap_authreply), &plen, errbuf) == -1)
|
||||
{
|
||||
(void)rpcap_discard(sockctrl, plen, NULL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Discard the rest of the message, if there is any. */
|
||||
if (rpcap_discard(sockctrl, plen, errbuf) == -1)
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* Other error - unrecoverable.
|
||||
* Check the minimum and maximum versions for sanity;
|
||||
* the minimum must be <= the maximum.
|
||||
*/
|
||||
return -1;
|
||||
if (authreply.minvers > authreply.maxvers)
|
||||
{
|
||||
/*
|
||||
* Bogus - give up on this server.
|
||||
*/
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"The server's minimum supported protocol version is greater than its maximum supported protocol version");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No - it supports only version 0. */
|
||||
authreply.minvers = 0;
|
||||
authreply.maxvers = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* OK, it's an authentication reply, so they're OK with the
|
||||
* protocol version we sent.
|
||||
*
|
||||
* Discard the rest of it.
|
||||
* OK, let's start with the maximum version the server supports.
|
||||
*/
|
||||
if (rpcap_discard(sock, header.plen, errbuf) == -1)
|
||||
return -1;
|
||||
ourvers = authreply.maxvers;
|
||||
|
||||
#if RPCAP_MIN_VERSION != 0
|
||||
/*
|
||||
* If that's less than the minimum version we support, we
|
||||
* can't communicate.
|
||||
*/
|
||||
if (ourvers < RPCAP_MIN_VERSION)
|
||||
goto novers;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If that's greater than the maximum version we support,
|
||||
* choose the maximum version we support.
|
||||
*/
|
||||
if (ourvers > RPCAP_MAX_VERSION)
|
||||
{
|
||||
ourvers = RPCAP_MAX_VERSION;
|
||||
|
||||
/*
|
||||
* If that's less than the minimum version they
|
||||
* support, we can't communicate.
|
||||
*/
|
||||
if (ourvers < authreply.minvers)
|
||||
goto novers;
|
||||
}
|
||||
|
||||
*ver = ourvers;
|
||||
return 0;
|
||||
|
||||
novers:
|
||||
/*
|
||||
* There is no version we both support; that is a fatal error.
|
||||
*/
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"The server doesn't support any protocol version that we support");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* We don't currently support non-blocking mode. */
|
||||
@@ -2060,6 +2047,103 @@ pcap_setnonblock_rpcap(pcap_t *p, int nonblock _U_)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static int
|
||||
rpcap_setup_session(const char *source, struct pcap_rmtauth *auth,
|
||||
int *activep, SOCKET *sockctrlp, uint8 *protocol_versionp,
|
||||
char *host, char *port, char *iface, char *errbuf)
|
||||
{
|
||||
int type;
|
||||
struct activehosts *activeconn; /* active connection, if there is one */
|
||||
int error; /* 1 if rpcap_remoteact_getsock got an error */
|
||||
|
||||
/*
|
||||
* Determine the type of the source (NULL, file, local, remote).
|
||||
* You must have a valid source string even if we're in active mode,
|
||||
* because otherwise the call to the following function will fail.
|
||||
*/
|
||||
if (pcap_parsesrcstr(source, &type, host, port, iface, errbuf) == -1)
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* It must be remote.
|
||||
*/
|
||||
if (type != PCAP_SRC_IFREMOTE)
|
||||
{
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Non-remote interface passed to remote capture routine");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Warning: this call can be the first one called by the user. */
|
||||
/* For this reason, we have to initialize the WinSock support. */
|
||||
if (sock_init(errbuf, PCAP_ERRBUF_SIZE) == -1)
|
||||
return -1;
|
||||
|
||||
/* Check for active mode */
|
||||
activeconn = rpcap_remoteact_getsock(host, &error, errbuf);
|
||||
if (activeconn != NULL)
|
||||
{
|
||||
*activep = 1;
|
||||
*sockctrlp = activeconn->sockctrl;
|
||||
*protocol_versionp = activeconn->protocol_version;
|
||||
}
|
||||
else
|
||||
{
|
||||
*activep = 0;
|
||||
struct addrinfo hints; /* temp variable needed to resolve hostnames into to socket representation */
|
||||
struct addrinfo *addrinfo; /* temp variable needed to resolve hostnames into to socket representation */
|
||||
|
||||
if (error)
|
||||
{
|
||||
/*
|
||||
* Call failed.
|
||||
*/
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* We're not in active mode; let's try to open a new
|
||||
* control connection.
|
||||
*/
|
||||
memset(&hints, 0, sizeof(struct addrinfo));
|
||||
hints.ai_family = PF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
|
||||
if (port[0] == 0)
|
||||
{
|
||||
/* the user chose not to specify the port */
|
||||
if (sock_initaddress(host, RPCAP_DEFAULT_NETPORT,
|
||||
&hints, &addrinfo, errbuf, PCAP_ERRBUF_SIZE) == -1)
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sock_initaddress(host, port, &hints, &addrinfo,
|
||||
errbuf, PCAP_ERRBUF_SIZE) == -1)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((*sockctrlp = sock_open(addrinfo, SOCKOPEN_CLIENT, 0,
|
||||
errbuf, PCAP_ERRBUF_SIZE)) == INVALID_SOCKET)
|
||||
{
|
||||
freeaddrinfo(addrinfo);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* addrinfo is no longer used */
|
||||
freeaddrinfo(addrinfo);
|
||||
addrinfo = NULL;
|
||||
|
||||
if (rpcap_doauth(*sockctrlp, protocol_versionp, auth,
|
||||
errbuf) == -1)
|
||||
{
|
||||
sock_close(*sockctrlp, NULL, 0);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function opens a remote adapter by opening an RPCAP connection and
|
||||
* so on.
|
||||
@@ -2105,15 +2189,12 @@ pcap_t *pcap_open_rpcap(const char *source, int snaplen, int flags, int read_tim
|
||||
char *source_str;
|
||||
struct pcap_rpcap *pr; /* structure used when doing a remote live capture */
|
||||
char host[PCAP_BUF_SIZE], ctrlport[PCAP_BUF_SIZE], iface[PCAP_BUF_SIZE];
|
||||
struct activehosts *activeconn; /* active connection, if there is one */
|
||||
int error; /* '1' if rpcap_remoteact_getsock returned an error */
|
||||
SOCKET sockctrl;
|
||||
uint8 protocol_version; /* negotiated protocol version */
|
||||
int active;
|
||||
uint32 plen;
|
||||
char sendbuf[RPCAP_NETBUF_SIZE]; /* temporary buffer in which data to be sent is buffered */
|
||||
int sendbufidx = 0; /* index which keeps the number of bytes currently buffered */
|
||||
int retval; /* store the return value of the functions */
|
||||
|
||||
/* RPCAP-related variables */
|
||||
struct rpcap_header header; /* header of the RPCAP packet */
|
||||
@@ -2152,100 +2233,16 @@ pcap_t *pcap_open_rpcap(const char *source, int snaplen, int flags, int read_tim
|
||||
pr->rmt_flags = flags;
|
||||
|
||||
/*
|
||||
* determine the type of the source (NULL, file, local, remote)
|
||||
* You must have a valid source string even if we're in active mode, because otherwise
|
||||
* the call to the following function will fail.
|
||||
* Attempt to set up the session with the server.
|
||||
*/
|
||||
if (pcap_parsesrcstr(fp->opt.device, &retval, host, ctrlport, iface, errbuf) == -1)
|
||||
if (rpcap_setup_session(fp->opt.device, auth, &active, &sockctrl,
|
||||
&protocol_version, host, ctrlport, iface, errbuf) == -1)
|
||||
{
|
||||
/* Session setup failed. */
|
||||
pcap_close(fp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (retval != PCAP_SRC_IFREMOTE)
|
||||
{
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "This function is able to open only remote interfaces");
|
||||
pcap_close(fp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Warning: this call can be the first one called by the user.
|
||||
* For this reason, we have to initialize the WinSock support.
|
||||
*/
|
||||
if (sock_init(errbuf, PCAP_ERRBUF_SIZE) == -1)
|
||||
{
|
||||
pcap_close(fp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Check for active mode */
|
||||
activeconn = rpcap_remoteact_getsock(host, &error, errbuf);
|
||||
if (activeconn != NULL)
|
||||
{
|
||||
sockctrl = activeconn->sockctrl;
|
||||
protocol_version = activeconn->protocol_version;
|
||||
active = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
struct addrinfo hints; /* temp, needed to open a socket connection */
|
||||
struct addrinfo *addrinfo; /* temp, needed to open a socket connection */
|
||||
|
||||
if (error)
|
||||
{
|
||||
/*
|
||||
* Call failed.
|
||||
*/
|
||||
pcap_close(fp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* We're not in active mode; let's try to open a new
|
||||
* control connection.
|
||||
*/
|
||||
memset(&hints, 0, sizeof(struct addrinfo));
|
||||
hints.ai_family = PF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
|
||||
if (ctrlport[0] == 0)
|
||||
{
|
||||
/* the user chose not to specify the port */
|
||||
if (sock_initaddress(host, RPCAP_DEFAULT_NETPORT, &hints, &addrinfo, errbuf, PCAP_ERRBUF_SIZE) == -1)
|
||||
{
|
||||
pcap_close(fp);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sock_initaddress(host, ctrlport, &hints, &addrinfo, errbuf, PCAP_ERRBUF_SIZE) == -1)
|
||||
{
|
||||
pcap_close(fp);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if ((sockctrl = sock_open(addrinfo, SOCKOPEN_CLIENT, 0, errbuf, PCAP_ERRBUF_SIZE)) == INVALID_SOCKET)
|
||||
{
|
||||
freeaddrinfo(addrinfo);
|
||||
pcap_close(fp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* addrinfo is no longer used */
|
||||
freeaddrinfo(addrinfo);
|
||||
|
||||
if (rpcap_doauth(sockctrl, &protocol_version, auth, errbuf) == -1)
|
||||
{
|
||||
sock_close(sockctrl, NULL, 0);
|
||||
pcap_close(fp);
|
||||
return NULL;
|
||||
}
|
||||
active = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now it's time to start playing with the RPCAP protocol
|
||||
* RPCAP open command: create the request message
|
||||
@@ -2277,7 +2274,7 @@ pcap_t *pcap_open_rpcap(const char *source, int snaplen, int flags, int read_tim
|
||||
goto error;
|
||||
|
||||
/* Discard the rest of the message, if there is any. */
|
||||
if (rpcap_discard(pr->rmt_sockctrl, plen, errbuf) == -1)
|
||||
if (rpcap_discard(sockctrl, plen, errbuf) == -1)
|
||||
goto error_nodiscard;
|
||||
|
||||
/* Set proper fields into the pcap_t struct */
|
||||
@@ -2315,7 +2312,7 @@ error:
|
||||
* We already reported an error; if this gets an error, just
|
||||
* drive on.
|
||||
*/
|
||||
(void)rpcap_discard(pr->rmt_sockctrl, plen, NULL);
|
||||
(void)rpcap_discard(sockctrl, plen, NULL);
|
||||
|
||||
error_nodiscard:
|
||||
if (!active)
|
||||
@@ -2327,8 +2324,10 @@ error_nodiscard:
|
||||
|
||||
/* String identifier to be used in the pcap_findalldevs_ex() */
|
||||
#define PCAP_TEXT_SOURCE_ADAPTER "Network adapter"
|
||||
#define PCAP_TEXT_SOURCE_ADAPTER_LEN (sizeof PCAP_TEXT_SOURCE_ADAPTER - 1)
|
||||
/* String identifier to be used in the pcap_findalldevs_ex() */
|
||||
#define PCAP_TEXT_SOURCE_ON_REMOTE_HOST "on remote node"
|
||||
#define PCAP_TEXT_SOURCE_ON_REMOTE_HOST_LEN (sizeof PCAP_TEXT_SOURCE_ON_REMOTE_HOST - 1)
|
||||
|
||||
static void
|
||||
freeaddr(struct pcap_addr *addr)
|
||||
@@ -2341,10 +2340,8 @@ freeaddr(struct pcap_addr *addr)
|
||||
}
|
||||
|
||||
int
|
||||
pcap_findalldevs_ex_remote(char *source, struct pcap_rmtauth *auth, pcap_if_t **alldevs, char *errbuf)
|
||||
pcap_findalldevs_ex_remote(const char *source, struct pcap_rmtauth *auth, pcap_if_t **alldevs, char *errbuf)
|
||||
{
|
||||
struct activehosts *activeconn; /* active connection, if there is one */
|
||||
int error; /* '1' if rpcap_remoteact_getsock returned an error */
|
||||
uint8 protocol_version; /* protocol version */
|
||||
SOCKET sockctrl; /* socket descriptor of the control connection */
|
||||
uint32 plen;
|
||||
@@ -2352,7 +2349,6 @@ pcap_findalldevs_ex_remote(char *source, struct pcap_rmtauth *auth, pcap_if_t **
|
||||
int i, j; /* temp variables */
|
||||
int nif; /* Number of interfaces listed */
|
||||
int active; /* 'true' if we the other end-party is in active mode */
|
||||
int type;
|
||||
char host[PCAP_BUF_SIZE], port[PCAP_BUF_SIZE];
|
||||
char tmpstring[PCAP_BUF_SIZE + 1]; /* Needed to convert names and descriptions from 'old' syntax to the 'new' one */
|
||||
pcap_if_t *lastdev; /* Last device in the pcap_if_t list */
|
||||
@@ -2362,72 +2358,14 @@ pcap_findalldevs_ex_remote(char *source, struct pcap_rmtauth *auth, pcap_if_t **
|
||||
(*alldevs) = NULL;
|
||||
lastdev = NULL;
|
||||
|
||||
/* Retrieve the needed data for getting adapter list */
|
||||
if (pcap_parsesrcstr(source, &type, host, port, NULL, errbuf) == -1)
|
||||
return -1;
|
||||
|
||||
/* Warning: this call can be the first one called by the user. */
|
||||
/* For this reason, we have to initialize the WinSock support. */
|
||||
if (sock_init(errbuf, PCAP_ERRBUF_SIZE) == -1)
|
||||
return -1;
|
||||
|
||||
/* Check for active mode */
|
||||
activeconn = rpcap_remoteact_getsock(host, &error, errbuf);
|
||||
if (activeconn != NULL)
|
||||
/*
|
||||
* Attempt to set up the session with the server.
|
||||
*/
|
||||
if (rpcap_setup_session(source, auth, &active, &sockctrl,
|
||||
&protocol_version, host, port, NULL, errbuf) == -1)
|
||||
{
|
||||
sockctrl = activeconn->sockctrl;
|
||||
protocol_version = activeconn->protocol_version;
|
||||
active = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
struct addrinfo hints; /* temp variable needed to resolve hostnames into to socket representation */
|
||||
struct addrinfo *addrinfo; /* temp variable needed to resolve hostnames into to socket representation */
|
||||
|
||||
if (error)
|
||||
{
|
||||
/*
|
||||
* Call failed.
|
||||
*/
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* We're not in active mode; let's try to open a new
|
||||
* control connection.
|
||||
*/
|
||||
memset(&hints, 0, sizeof(struct addrinfo));
|
||||
hints.ai_family = PF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
|
||||
if (port[0] == 0)
|
||||
{
|
||||
/* the user chose not to specify the port */
|
||||
if (sock_initaddress(host, RPCAP_DEFAULT_NETPORT, &hints, &addrinfo, errbuf, PCAP_ERRBUF_SIZE) == -1)
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sock_initaddress(host, port, &hints, &addrinfo, errbuf, PCAP_ERRBUF_SIZE) == -1)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((sockctrl = sock_open(addrinfo, SOCKOPEN_CLIENT, 0, errbuf, PCAP_ERRBUF_SIZE)) == INVALID_SOCKET)
|
||||
{
|
||||
freeaddrinfo(addrinfo);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* addrinfo is no longer used */
|
||||
freeaddrinfo(addrinfo);
|
||||
addrinfo = NULL;
|
||||
|
||||
if (rpcap_doauth(sockctrl, &protocol_version, auth, errbuf) == -1)
|
||||
{
|
||||
sock_close(sockctrl, NULL, 0);
|
||||
return -1;
|
||||
}
|
||||
active = 0;
|
||||
/* Session setup failed. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* RPCAP findalldevs command */
|
||||
@@ -2453,7 +2391,6 @@ pcap_findalldevs_ex_remote(char *source, struct pcap_rmtauth *auth, pcap_if_t **
|
||||
{
|
||||
struct rpcap_findalldevs_if findalldevs_if;
|
||||
char tmpstring2[PCAP_BUF_SIZE + 1]; /* Needed to convert names and descriptions from 'old' syntax to the 'new' one */
|
||||
size_t stringlen;
|
||||
struct pcap_addr *addr, *prevaddr;
|
||||
|
||||
tmpstring2[PCAP_BUF_SIZE] = 0;
|
||||
@@ -2515,21 +2452,17 @@ pcap_findalldevs_ex_remote(char *source, struct pcap_rmtauth *auth, pcap_if_t **
|
||||
tmpstring[findalldevs_if.namelen] = 0;
|
||||
|
||||
/* Create the new device identifier */
|
||||
if (pcap_createsrcstr(tmpstring2, PCAP_SRC_IFREMOTE, host, port, tmpstring, errbuf) == -1)
|
||||
return -1;
|
||||
if (pcap_createsrcstr(tmpstring2, PCAP_SRC_IFREMOTE,
|
||||
host, port, tmpstring, errbuf) == -1)
|
||||
goto error;
|
||||
|
||||
stringlen = strlen(tmpstring2);
|
||||
|
||||
dev->name = (char *)malloc(stringlen + 1);
|
||||
dev->name = strdup(tmpstring2);
|
||||
if (dev->name == NULL)
|
||||
{
|
||||
pcap_fmt_errmsg_for_errno(errbuf,
|
||||
PCAP_ERRBUF_SIZE, errno, "malloc() failed");
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Copy the new device name into the correct memory location */
|
||||
strlcpy(dev->name, tmpstring2, stringlen + 1);
|
||||
}
|
||||
|
||||
if (findalldevs_if.desclen)
|
||||
@@ -2547,22 +2480,14 @@ pcap_findalldevs_ex_remote(char *source, struct pcap_rmtauth *auth, pcap_if_t **
|
||||
|
||||
tmpstring[findalldevs_if.desclen] = 0;
|
||||
|
||||
pcap_snprintf(tmpstring2, sizeof(tmpstring2) - 1, "%s '%s' %s %s", PCAP_TEXT_SOURCE_ADAPTER,
|
||||
tmpstring, PCAP_TEXT_SOURCE_ON_REMOTE_HOST, host);
|
||||
|
||||
stringlen = strlen(tmpstring2);
|
||||
|
||||
dev->description = (char *)malloc(stringlen + 1);
|
||||
|
||||
if (dev->description == NULL)
|
||||
if (pcap_asprintf(&dev->description,
|
||||
"%s '%s' %s %s", PCAP_TEXT_SOURCE_ADAPTER,
|
||||
tmpstring, PCAP_TEXT_SOURCE_ON_REMOTE_HOST, host) == -1)
|
||||
{
|
||||
pcap_fmt_errmsg_for_errno(errbuf,
|
||||
PCAP_ERRBUF_SIZE, errno, "malloc() failed");
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Copy the new device description into the correct memory location */
|
||||
strlcpy(dev->description, tmpstring2, stringlen + 1);
|
||||
}
|
||||
|
||||
dev->flags = ntohl(findalldevs_if.flags);
|
||||
@@ -2731,7 +2656,6 @@ SOCKET pcap_remoteact_accept(const char *address, const char *port, const char *
|
||||
{
|
||||
if (sock_initaddress(address, RPCAP_DEFAULT_NETPORT_ACTIVE, &hints, &addrinfo, errbuf, PCAP_ERRBUF_SIZE) == -1)
|
||||
{
|
||||
SOCK_DEBUG_MESSAGE(errbuf);
|
||||
return (SOCKET)-2;
|
||||
}
|
||||
}
|
||||
@@ -2739,7 +2663,6 @@ SOCKET pcap_remoteact_accept(const char *address, const char *port, const char *
|
||||
{
|
||||
if (sock_initaddress(address, port, &hints, &addrinfo, errbuf, PCAP_ERRBUF_SIZE) == -1)
|
||||
{
|
||||
SOCK_DEBUG_MESSAGE(errbuf);
|
||||
return (SOCKET)-2;
|
||||
}
|
||||
}
|
||||
@@ -2747,7 +2670,6 @@ SOCKET pcap_remoteact_accept(const char *address, const char *port, const char *
|
||||
|
||||
if ((sockmain = sock_open(addrinfo, SOCKOPEN_SERVER, 1, errbuf, PCAP_ERRBUF_SIZE)) == INVALID_SOCKET)
|
||||
{
|
||||
SOCK_DEBUG_MESSAGE(errbuf);
|
||||
freeaddrinfo(addrinfo);
|
||||
return (SOCKET)-2;
|
||||
}
|
||||
@@ -2765,14 +2687,14 @@ SOCKET pcap_remoteact_accept(const char *address, const char *port, const char *
|
||||
|
||||
if (sockctrl == INVALID_SOCKET)
|
||||
{
|
||||
sock_geterror("accept(): ", errbuf, PCAP_ERRBUF_SIZE);
|
||||
sock_geterror("accept()", errbuf, PCAP_ERRBUF_SIZE);
|
||||
return (SOCKET)-2;
|
||||
}
|
||||
|
||||
/* Get the numeric for of the name of the connecting host */
|
||||
if (getnameinfo((struct sockaddr *) &from, fromlen, connectinghost, RPCAP_HOSTLIST_SIZE, NULL, 0, NI_NUMERICHOST))
|
||||
{
|
||||
sock_geterror("getnameinfo(): ", errbuf, PCAP_ERRBUF_SIZE);
|
||||
sock_geterror("getnameinfo()", errbuf, PCAP_ERRBUF_SIZE);
|
||||
rpcap_senderror(sockctrl, 0, PCAP_ERR_REMOTEACCEPT, errbuf, NULL);
|
||||
sock_close(sockctrl, NULL, 0);
|
||||
return (SOCKET)-1;
|
||||
@@ -2971,7 +2893,7 @@ int pcap_remoteact_list(char *hostlist, char sep, int size, char *errbuf)
|
||||
/* if (getnameinfo( (struct sockaddr *) &temp->host, sizeof (struct sockaddr_storage), hoststr, */
|
||||
/* RPCAP_HOSTLIST_SIZE, NULL, 0, NI_NUMERICHOST) ) */
|
||||
{
|
||||
/* sock_geterror("getnameinfo(): ", errbuf, PCAP_ERRBUF_SIZE); */
|
||||
/* sock_geterror("getnameinfo()", errbuf, PCAP_ERRBUF_SIZE); */
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -2984,7 +2906,7 @@ int pcap_remoteact_list(char *hostlist, char sep, int size, char *errbuf)
|
||||
return -1;
|
||||
}
|
||||
|
||||
strlcat(hostlist, hoststr, PCAP_ERRBUF_SIZE);
|
||||
pcap_strlcat(hostlist, hoststr, PCAP_ERRBUF_SIZE);
|
||||
hostlist[len - 1] = sep;
|
||||
hostlist[len] = 0;
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ pcap_t *pcap_open_rpcap(const char *source, int snaplen, int flags,
|
||||
/*
|
||||
* Internal interfaces for "pcap_findalldevs_ex()".
|
||||
*/
|
||||
int pcap_findalldevs_ex_remote(char *source, struct pcap_rmtauth *auth,
|
||||
pcap_if_t **alldevs, char *errbuf);
|
||||
int pcap_findalldevs_ex_remote(const char *source,
|
||||
struct pcap_rmtauth *auth, pcap_if_t **alldevs, char *errbuf);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -130,4 +130,4 @@ the packet not been truncated by the snapshot length. The two lengths
|
||||
will be equal if the number of bytes of packet data are less than or
|
||||
equal to the snapshot length.
|
||||
.SH SEE ALSO
|
||||
pcap(3PCAP), pcap-linktype(@MAN_MISC_INFO@)
|
||||
pcap(3PCAP)
|
||||
|
||||
@@ -1,15 +1,6 @@
|
||||
/*
|
||||
* pcap-septel.c: Packet capture interface for Intel/Septel card.
|
||||
*
|
||||
* The functionality of this code attempts to mimic that of pcap-linux as much
|
||||
* as possible. This code is compiled in several different ways depending on
|
||||
* whether SEPTEL_ONLY and HAVE_SEPTEL_API are defined. If HAVE_SEPTEL_API is
|
||||
* not defined it should not get compiled in, otherwise if SEPTEL_ONLY is
|
||||
* defined then the 'septel_' function calls are renamed to 'pcap_'
|
||||
* equivalents. If SEPTEL_ONLY is not defined then nothing is altered - the
|
||||
* septel_ functions will be called as required from their
|
||||
* pcap-linux/equivalents.
|
||||
*
|
||||
* Authors: Gilbert HOYEK (gil_hoyek@hotmail.com), Elias M. KHOURY
|
||||
* (+961 3 485243)
|
||||
*/
|
||||
@@ -182,7 +173,7 @@ loop:
|
||||
static int
|
||||
septel_inject(pcap_t *handle, const void *buf _U_, size_t size _U_)
|
||||
{
|
||||
strlcpy(handle->errbuf, "Sending packets isn't supported on Septel cards",
|
||||
pcap_strlcpy(handle->errbuf, "Sending packets isn't supported on Septel cards",
|
||||
PCAP_ERRBUF_SIZE);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
@@ -884,7 +884,7 @@ static void acn_start_monitor(int fd, int snaplen, int timeout, int promiscuous,
|
||||
}
|
||||
|
||||
static int pcap_inject_acn(pcap_t *p, const void *buf _U_, size_t size _U_) {
|
||||
strlcpy(p->errbuf, "Sending packets isn't supported on ACN adapters",
|
||||
pcap_strlcpy(p->errbuf, "Sending packets isn't supported on ACN adapters",
|
||||
PCAP_ERRBUF_SIZE);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
@@ -411,7 +411,7 @@ A { text-decoration:none }
|
||||
<TR>
|
||||
<TD VALIGN=TOP>Interface ID</TD>
|
||||
<TD VALIGN=TOP ALIGN=CENTER>1</TD>
|
||||
<TD VALIGN=TOP>A NULL to indicate an an empty 'interface ID'.</TD>
|
||||
<TD VALIGN=TOP>A NULL to indicate an empty 'interface ID'.</TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
</TD>
|
||||
|
||||
@@ -182,8 +182,8 @@ snf_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
hdr.caplen = caplen;
|
||||
hdr.len = req.length;
|
||||
callback(user, &hdr, req.pkt_addr);
|
||||
n++;
|
||||
}
|
||||
n++;
|
||||
|
||||
/* After one successful packet is received, we won't block
|
||||
* again for that timeout. */
|
||||
@@ -237,7 +237,7 @@ snf_inject(pcap_t *p, const void *buf _U_, size_t size _U_)
|
||||
return (-1);
|
||||
}
|
||||
#else
|
||||
strlcpy(p->errbuf, "Sending packets isn't supported with this snf version",
|
||||
pcap_strlcpy(p->errbuf, "Sending packets isn't supported with this snf version",
|
||||
PCAP_ERRBUF_SIZE);
|
||||
return (-1);
|
||||
#endif
|
||||
|
||||
@@ -123,7 +123,7 @@ static int TcSetDatalink(pcap_t *p, int dlt);
|
||||
static int TcGetNonBlock(pcap_t *p);
|
||||
static int TcSetNonBlock(pcap_t *p, int nonblock);
|
||||
static void TcCleanup(pcap_t *p);
|
||||
static int TcInject(pcap_t *p, const void *buf, size_t size);
|
||||
static int TcInject(pcap_t *p, const void *buf, int size);
|
||||
static int TcRead(pcap_t *p, int cnt, pcap_handler callback, u_char *user);
|
||||
static int TcStats(pcap_t *p, struct pcap_stat *ps);
|
||||
static int TcSetFilter(pcap_t *p, struct bpf_program *fp);
|
||||
@@ -440,7 +440,7 @@ TcFindAllDevs(pcap_if_list_t *devlist, char *errbuf)
|
||||
PTC_PORT pPorts = NULL;
|
||||
TC_STATUS status;
|
||||
int result = 0;
|
||||
pcap_if_t *dev, *cursor;
|
||||
pcap_if_t *dev;
|
||||
ULONG i;
|
||||
|
||||
do
|
||||
@@ -472,22 +472,7 @@ TcFindAllDevs(pcap_if_list_t *devlist, char *errbuf)
|
||||
dev = TcCreatePcapIfFromPort(pPorts[i]);
|
||||
|
||||
if (dev != NULL)
|
||||
{
|
||||
/*
|
||||
* append it at the end
|
||||
*/
|
||||
if (devlistp->beginning == NULL)
|
||||
{
|
||||
devlistp->beginning = dev;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (cursor = devlistp->beginning;
|
||||
cursor->next != NULL;
|
||||
cursor = cursor->next);
|
||||
cursor->next = dev;
|
||||
}
|
||||
}
|
||||
add_dev(devlist, dev->name, dev->flags, dev->description, errbuf);
|
||||
}
|
||||
|
||||
if (numPorts > 0)
|
||||
@@ -846,7 +831,7 @@ static void TcCleanup(pcap_t *p)
|
||||
}
|
||||
|
||||
/* Send a packet to the network */
|
||||
static int TcInject(pcap_t *p, const void *buf, size_t size)
|
||||
static int TcInject(pcap_t *p, const void *buf, int size)
|
||||
{
|
||||
struct pcap_tc *pt = p->priv;
|
||||
TC_STATUS status;
|
||||
|
||||
@@ -93,9 +93,9 @@ call and before a
|
||||
call to specify the type of time stamp to be used on the device.
|
||||
The time stamp types are listed here; the first value is the #define to
|
||||
use in code, the second value is the value returned by
|
||||
.B pcap_tstamp_type_val_to_name()
|
||||
.B pcap_tstamp_type_val_to_name(3PCAP)
|
||||
and accepted by
|
||||
.BR pcap_tstamp_type_name_to_val() .
|
||||
.BR pcap_tstamp_type_name_to_val(3PCAP) .
|
||||
.RS 5
|
||||
.TP 5
|
||||
.BR PCAP_TSTAMP_HOST " - " host
|
||||
@@ -149,9 +149,9 @@ call will fail, and the time stamps supplied after the
|
||||
call will have microsecond resolution.
|
||||
.LP
|
||||
When opening a savefile, the
|
||||
.BR pcap_open_offline_with_tstamp_precision (3PCAP)
|
||||
.BR \%pcap_open_offline_with_tstamp_precision (3PCAP)
|
||||
and
|
||||
.BR pcap_fopen_offline_with_tstamp_precision (3PCAP)
|
||||
.BR \%pcap_fopen_offline_with_tstamp_precision (3PCAP)
|
||||
routines can be used to specify the resolution of time stamps to be read
|
||||
from the file; if the time stamps in the file have a lower resolution,
|
||||
the fraction-of-a-second portion of the time stamps will be scaled to
|
||||
@@ -165,13 +165,4 @@ the time stamp supplied by the hardware or operating system and, when
|
||||
reading a savefile, this does not indicate the actual precision of time
|
||||
stamps in the file.
|
||||
.SH SEE ALSO
|
||||
.na
|
||||
pcap_set_tstamp_type(3PCAP),
|
||||
pcap_list_tstamp_types(3PCAP),
|
||||
pcap_tstamp_type_val_to_name(3PCAP),
|
||||
pcap_tstamp_type_name_to_val(3PCAP),
|
||||
pcap_set_tstamp_precision(3PCAP),
|
||||
pcap_open_offline_with_tstamp_precision(3PCAP),
|
||||
\%pcap_fopen_offline_with_tstamp_precision(3PCAP),
|
||||
\%pcap_get_tstamp_precision(3PCAP)
|
||||
.ad
|
||||
pcap(3PCAP)
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <dirent.h>
|
||||
#include <byteswap.h>
|
||||
@@ -241,7 +242,7 @@ usb_dev_add(pcap_if_list_t *devlistp, int n, char *err_str)
|
||||
*/
|
||||
if (add_dev(devlistp, dev_name,
|
||||
PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE,
|
||||
"All USB buses", err_str) == NULL)
|
||||
"Raw USB traffic, all USB buses", err_str) == NULL)
|
||||
return -1;
|
||||
} else {
|
||||
/*
|
||||
@@ -250,7 +251,7 @@ usb_dev_add(pcap_if_list_t *devlistp, int n, char *err_str)
|
||||
* PCAP_IF_CONNECTION_STATUS_CONNECTED or
|
||||
* PCAP_IF_CONNECTION_STATUS_DISCONNECTED?
|
||||
*/
|
||||
pcap_snprintf(dev_descr, 30, "USB bus number %d", n);
|
||||
pcap_snprintf(dev_descr, 30, "Raw USB traffic, bus number %d", n);
|
||||
if (add_dev(devlistp, dev_name, 0, dev_descr, err_str) == NULL)
|
||||
return -1;
|
||||
}
|
||||
@@ -278,7 +279,7 @@ usb_findalldevs(pcap_if_list_t *devlistp, char *err_str)
|
||||
* Split LINUX_USB_MON_DEV into a directory that we'll
|
||||
* scan and a file name prefix that we'll check for.
|
||||
*/
|
||||
strlcpy(usb_mon_dir, LINUX_USB_MON_DEV, sizeof usb_mon_dir);
|
||||
pcap_strlcpy(usb_mon_dir, LINUX_USB_MON_DEV, sizeof usb_mon_dir);
|
||||
usb_mon_prefix = strrchr(usb_mon_dir, '/');
|
||||
if (usb_mon_prefix == NULL) {
|
||||
/*
|
||||
@@ -380,18 +381,102 @@ usb_findalldevs(pcap_if_list_t *devlistp, char *err_str)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Matches what's in mon_bin.c in the Linux kernel.
|
||||
*/
|
||||
#define MIN_RING_SIZE (8*1024)
|
||||
#define MAX_RING_SIZE (1200*1024)
|
||||
|
||||
static int
|
||||
usb_set_ring_size(pcap_t* handle, int header_size)
|
||||
{
|
||||
/*
|
||||
* A packet from binary usbmon has:
|
||||
*
|
||||
* 1) a fixed-length header, of size header_size;
|
||||
* 2) descriptors, for isochronous transfers;
|
||||
* 3) the payload.
|
||||
*
|
||||
* The kernel buffer has a size, defaulting to 300KB, with a
|
||||
* minimum of 8KB and a maximum of 1200KB. The size is set with
|
||||
* the MON_IOCT_RING_SIZE ioctl; the size passed in is rounded up
|
||||
* to a page size.
|
||||
*
|
||||
* No more than {buffer size}/5 bytes worth of payload is saved.
|
||||
* Therefore, if we subtract the fixed-length size from the
|
||||
* snapshot length, we have the biggest payload we want (we
|
||||
* don't worry about the descriptors - if we have descriptors,
|
||||
* we'll just discard the last bit of the payload to get it
|
||||
* to fit). We multiply that result by 5 and set the buffer
|
||||
* size to that value.
|
||||
*/
|
||||
int ring_size;
|
||||
|
||||
if (handle->snapshot < header_size)
|
||||
handle->snapshot = header_size;
|
||||
/* The maximum snapshot size is small enough that this won't overflow */
|
||||
ring_size = (handle->snapshot - header_size) * 5;
|
||||
|
||||
/*
|
||||
* Will this get an error?
|
||||
* (There's no wqy to query the minimum or maximum, so we just
|
||||
* copy the value from the kernel source. We don't round it
|
||||
* up to a multiple of the page size.)
|
||||
*/
|
||||
if (ring_size > MAX_RING_SIZE) {
|
||||
/*
|
||||
* Yes. Lower the ring size to the maximum, and set the
|
||||
* snapshot length to the value that would give us a
|
||||
* maximum-size ring.
|
||||
*/
|
||||
ring_size = MAX_RING_SIZE;
|
||||
handle->snapshot = header_size + (MAX_RING_SIZE/5);
|
||||
} else if (ring_size < MIN_RING_SIZE) {
|
||||
/*
|
||||
* Yes. Raise the ring size to the minimum, but leave
|
||||
* the snapshot length unchanged, so we show the
|
||||
* callback no more data than specified by the
|
||||
* snapshot length.
|
||||
*/
|
||||
ring_size = MIN_RING_SIZE;
|
||||
}
|
||||
|
||||
if (ioctl(handle->fd, MON_IOCT_RING_SIZE, ring_size) == -1) {
|
||||
pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
errno, "Can't set ring size from fd %d", handle->fd);
|
||||
return -1;
|
||||
}
|
||||
return ring_size;
|
||||
}
|
||||
|
||||
static
|
||||
int usb_mmap(pcap_t* handle)
|
||||
{
|
||||
struct pcap_usb_linux *handlep = handle->priv;
|
||||
int len = ioctl(handle->fd, MON_IOCQ_RING_SIZE);
|
||||
if (len < 0)
|
||||
int len;
|
||||
|
||||
/*
|
||||
* Attempt to set the ring size as appropriate for the snapshot
|
||||
* length, reducing the snapshot length if that'd make the ring
|
||||
* bigger than the kernel supports.
|
||||
*/
|
||||
len = usb_set_ring_size(handle, (int)sizeof(pcap_usb_header_mmapped));
|
||||
if (len == -1) {
|
||||
/* Failed. Fall back on non-memory-mapped access. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
handlep->mmapbuflen = len;
|
||||
handlep->mmapbuf = mmap(0, handlep->mmapbuflen, PROT_READ,
|
||||
MAP_SHARED, handle->fd, 0);
|
||||
return handlep->mmapbuf != MAP_FAILED;
|
||||
if (handlep->mmapbuf == MAP_FAILED) {
|
||||
/*
|
||||
* Failed. We don't treat that as a fatal error, we
|
||||
* just try to fall back on non-memory-mapped access.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LINUX_USBDEVICE_FS_H
|
||||
@@ -514,6 +599,7 @@ usb_activate(pcap_t* handle)
|
||||
{
|
||||
struct pcap_usb_linux *handlep = handle->priv;
|
||||
char full_path[USB_LINE_LEN];
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Turn a negative snapshot value (invalid), a snapshot value of
|
||||
@@ -604,6 +690,7 @@ usb_activate(pcap_t* handle)
|
||||
/* try to use fast mmap access */
|
||||
if (usb_mmap(handle))
|
||||
{
|
||||
/* We succeeded. */
|
||||
handle->linktype = DLT_USB_LINUX_MMAPPED;
|
||||
handle->stats_op = usb_stats_linux_bin;
|
||||
handle->read_op = usb_read_linux_mmap;
|
||||
@@ -620,7 +707,19 @@ usb_activate(pcap_t* handle)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* can't mmap, use plain binary interface access */
|
||||
/*
|
||||
* We failed; try plain binary interface access.
|
||||
*
|
||||
* Attempt to set the ring size as appropriate for
|
||||
* the snapshot length, reducing the snapshot length
|
||||
* if that'd make the ring bigger than the kernel
|
||||
* supports.
|
||||
*/
|
||||
if (usb_set_ring_size(handle, (int)sizeof(pcap_usb_header)) == -1) {
|
||||
/* Failed. */
|
||||
close(handle->fd);
|
||||
return PCAP_ERROR;
|
||||
}
|
||||
handle->stats_op = usb_stats_linux_bin;
|
||||
handle->read_op = usb_read_linux_bin;
|
||||
#ifdef HAVE_LINUX_USBDEVICE_FS_H
|
||||
@@ -646,38 +745,38 @@ usb_activate(pcap_t* handle)
|
||||
handle->fd = open(full_path, O_RDONLY, 0);
|
||||
}
|
||||
if (handle->fd < 0) {
|
||||
/*
|
||||
* Is the problem that we didn't have
|
||||
* sufficient permission to open it?
|
||||
*/
|
||||
if (errno == EACCES) {
|
||||
if (errno == ENOENT)
|
||||
{
|
||||
/*
|
||||
* Yes - return that error.
|
||||
* The problem is that the file
|
||||
* doesn't exist. Report that as
|
||||
* "no such device". (That could
|
||||
* mean "no such USB bus" or
|
||||
* "monitoring not supported".)
|
||||
*/
|
||||
return PCAP_ERROR_PERM_DENIED;
|
||||
ret = PCAP_ERROR_NO_SUCH_DEVICE;
|
||||
}
|
||||
|
||||
/*
|
||||
* No - was the problem something other
|
||||
* than "it doesn't exist"?
|
||||
*/
|
||||
if (errno != ENOENT) {
|
||||
else if (errno == EACCES)
|
||||
{
|
||||
/*
|
||||
* Yes - return *that* error.
|
||||
* The problem is that we don't
|
||||
* have sufficient permission to
|
||||
* open the file. Report that.
|
||||
*/
|
||||
pcap_fmt_errmsg_for_errno(handle->errbuf,
|
||||
PCAP_ERRBUF_SIZE, errno,
|
||||
"Can't open USB bus file %s",
|
||||
full_path);
|
||||
return PCAP_ERROR;
|
||||
ret = PCAP_ERROR_PERM_DENIED;
|
||||
}
|
||||
|
||||
/*
|
||||
* No. Report that as "no such device".
|
||||
* (That could mean "no such USB bus"
|
||||
* or "monitoring not supported".)
|
||||
*/
|
||||
return PCAP_ERROR_NO_SUCH_DEVICE;
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Some other error.
|
||||
*/
|
||||
ret = PCAP_ERROR;
|
||||
}
|
||||
pcap_fmt_errmsg_for_errno(handle->errbuf,
|
||||
PCAP_ERRBUF_SIZE, errno,
|
||||
"Can't open USB bus file %s",
|
||||
full_path);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -923,8 +1022,8 @@ got:
|
||||
static int
|
||||
usb_inject_linux(pcap_t *handle, const void *buf _U_, size_t size _U_)
|
||||
{
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "inject not supported on "
|
||||
"USB devices");
|
||||
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Packet injection is not supported on USB devices");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
@@ -973,6 +1072,10 @@ usb_stats_linux(pcap_t *handle, struct pcap_stat *stats)
|
||||
}
|
||||
string[ret] = 0;
|
||||
|
||||
stats->ps_recv = handlep->packets_read;
|
||||
stats->ps_drop = 0; /* unless we find text_lost */
|
||||
stats->ps_ifdrop = 0;
|
||||
|
||||
/* extract info on dropped urbs */
|
||||
for (consumed=0; consumed < ret; ) {
|
||||
/* from the sscanf man page:
|
||||
@@ -989,18 +1092,16 @@ usb_stats_linux(pcap_t *handle, struct pcap_stat *stats)
|
||||
break;
|
||||
consumed += cnt;
|
||||
ptr += cnt;
|
||||
if (strcmp(token, "nreaders") == 0)
|
||||
ret = sscanf(ptr, "%d", &stats->ps_drop);
|
||||
if (strcmp(token, "text_lost") == 0)
|
||||
ntok = sscanf(ptr, "%d%n", &stats->ps_drop, &cnt);
|
||||
else
|
||||
ret = sscanf(ptr, "%d", &dummy);
|
||||
if (ntok != 1)
|
||||
ntok = sscanf(ptr, "%d%n", &dummy, &cnt);
|
||||
if ((ntok != 1) || (cnt < 0))
|
||||
break;
|
||||
consumed += cnt;
|
||||
ptr += cnt;
|
||||
}
|
||||
|
||||
stats->ps_recv = handlep->packets_read;
|
||||
stats->ps_ifdrop = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1069,13 +1170,44 @@ usb_read_linux_bin(pcap_t *handle, int max_packets _U_, pcap_handler callback, u
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* we can get less that than really captured from kernel, depending on
|
||||
* snaplen, so adjust header accordingly */
|
||||
/*
|
||||
* info.hdr->data_len is the number of bytes of isochronous
|
||||
* descriptors (if any) plus the number of bytes of data
|
||||
* provided. There are no isochronous descriptors here,
|
||||
* because we're using the old 48-byte header.
|
||||
*
|
||||
* If info.hdr->data_flag is non-zero, there's no URB data;
|
||||
* info.hdr->urb_len is the size of the buffer into which
|
||||
* data is to be placed; it does not represent the amount
|
||||
* of data transferred. If info.hdr->data_flag is zero,
|
||||
* there is URB data, and info.hdr->urb_len is the number
|
||||
* of bytes transmitted or received; it doesn't include
|
||||
* isochronous descriptors.
|
||||
*
|
||||
* The kernel may give us more data than the snaplen; if it did,
|
||||
* reduce the data length so that the total number of bytes we
|
||||
* tell our client we have is not greater than the snaplen.
|
||||
*/
|
||||
if (info.hdr->data_len < clen)
|
||||
clen = info.hdr->data_len;
|
||||
info.hdr->data_len = clen;
|
||||
pkth.caplen = clen + sizeof(pcap_usb_header);
|
||||
pkth.len = info.hdr->data_len + sizeof(pcap_usb_header);
|
||||
pkth.caplen = sizeof(pcap_usb_header) + clen;
|
||||
if (info.hdr->data_flag) {
|
||||
/*
|
||||
* No data; just base the on-the-wire length on
|
||||
* info.hdr->data_len (so that it's >= the captured
|
||||
* length).
|
||||
*/
|
||||
pkth.len = sizeof(pcap_usb_header) + info.hdr->data_len;
|
||||
} else {
|
||||
/*
|
||||
* We got data; base the on-the-wire length on
|
||||
* info.hdr->urb_len, so that it includes data
|
||||
* discarded by the USB monitor device due to
|
||||
* its buffer being too small.
|
||||
*/
|
||||
pkth.len = sizeof(pcap_usb_header) + info.hdr->urb_len;
|
||||
}
|
||||
pkth.ts.tv_sec = info.hdr->ts_sec;
|
||||
pkth.ts.tv_usec = info.hdr->ts_usec;
|
||||
|
||||
@@ -1102,12 +1234,12 @@ usb_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback, u_ch
|
||||
struct mon_bin_mfetch fetch;
|
||||
int32_t vec[VEC_SIZE];
|
||||
struct pcap_pkthdr pkth;
|
||||
pcap_usb_header* hdr;
|
||||
pcap_usb_header_mmapped* hdr;
|
||||
int nflush = 0;
|
||||
int packets = 0;
|
||||
u_int clen, max_clen;
|
||||
|
||||
max_clen = handle->snapshot - sizeof(pcap_usb_header);
|
||||
max_clen = handle->snapshot - sizeof(pcap_usb_header_mmapped);
|
||||
|
||||
for (;;) {
|
||||
int i, ret;
|
||||
@@ -1145,19 +1277,52 @@ usb_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback, u_ch
|
||||
nflush = fetch.nfetch;
|
||||
for (i=0; i<fetch.nfetch; ++i) {
|
||||
/* discard filler */
|
||||
hdr = (pcap_usb_header*) &handlep->mmapbuf[vec[i]];
|
||||
hdr = (pcap_usb_header_mmapped*) &handlep->mmapbuf[vec[i]];
|
||||
if (hdr->event_type == '@')
|
||||
continue;
|
||||
|
||||
/* we can get less that than really captured from kernel, depending on
|
||||
* snaplen, so adjust header accordingly */
|
||||
/*
|
||||
* hdr->data_len is the number of bytes of
|
||||
* isochronous descriptors (if any) plus the
|
||||
* number of bytes of data provided.
|
||||
*
|
||||
* If hdr->data_flag is non-zero, there's no
|
||||
* URB data; hdr->urb_len is the size of the
|
||||
* buffer into which data is to be placed; it does
|
||||
* not represent the amount of data transferred.
|
||||
* If hdr->data_flag is zero, there is URB data,
|
||||
* and hdr->urb_len is the number of bytes
|
||||
* transmitted or received; it doesn't include
|
||||
* isochronous descriptors.
|
||||
*
|
||||
* The kernel may give us more data than the
|
||||
* snaplen; if it did, reduce the data length
|
||||
* so that the total number of bytes we
|
||||
* tell our client we have is not greater than
|
||||
* the snaplen.
|
||||
*/
|
||||
clen = max_clen;
|
||||
if (hdr->data_len < clen)
|
||||
clen = hdr->data_len;
|
||||
|
||||
/* get packet info from header*/
|
||||
pkth.caplen = clen + sizeof(pcap_usb_header_mmapped);
|
||||
pkth.len = hdr->data_len + sizeof(pcap_usb_header_mmapped);
|
||||
pkth.caplen = sizeof(pcap_usb_header_mmapped) + clen;
|
||||
if (hdr->data_flag) {
|
||||
/*
|
||||
* No data; just base the on-the-wire length
|
||||
* on hdr->data_len (so that it's >= the
|
||||
* captured length).
|
||||
*/
|
||||
pkth.len = sizeof(pcap_usb_header_mmapped) +
|
||||
hdr->data_len;
|
||||
} else {
|
||||
/*
|
||||
* We got data; base the on-the-wire length
|
||||
* on hdr->urb_len, so that it includes
|
||||
* data discarded by the USB monitor device
|
||||
* due to its buffer being too small.
|
||||
*/
|
||||
pkth.len = sizeof(pcap_usb_header_mmapped) +
|
||||
(hdr->ndesc * sizeof (usb_isodesc)) + hdr->urb_len;
|
||||
}
|
||||
pkth.ts.tv_sec = hdr->ts_sec;
|
||||
pkth.ts.tv_usec = hdr->ts_usec;
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
.\"
|
||||
.TH PCAP 3PCAP "20 April 2018"
|
||||
.TH PCAP 3PCAP "25 July 2018"
|
||||
.SH NAME
|
||||
pcap \- Packet Capture library
|
||||
.SH SYNOPSIS
|
||||
@@ -191,6 +191,10 @@ expires even if no packets have arrived.
|
||||
.IP
|
||||
The packet buffer timeout is set with
|
||||
.BR pcap_set_timeout ().
|
||||
.IP "immediate mode"
|
||||
In immediate mode, packets are always delivered as soon as they arrive,
|
||||
with no buffering. Immediate mode is set with
|
||||
.BR pcap_set_immediate_mode ().
|
||||
.IP "buffer size"
|
||||
Packets that arrive for a capture are stored in a buffer, so that they
|
||||
do not have to be read by the application as soon as they arrive. On
|
||||
@@ -416,6 +420,11 @@ set packet buffer timeout for a not-yet-activated
|
||||
.B pcap_t
|
||||
for live capture
|
||||
.TP
|
||||
.BR pcap_set_immediate_mode (3PCAP)
|
||||
set immediate mode for a not-yet-activated
|
||||
.B pcap_t
|
||||
for live capture
|
||||
.TP
|
||||
.BR pcap_set_buffer_size (3PCAP)
|
||||
set buffer size for a not-yet-activated
|
||||
.B pcap_t
|
||||
@@ -632,9 +641,28 @@ or other routines a platform offers to wait for any of a set of
|
||||
descriptors to be ready to read. To obtain, for a handle, a descriptor
|
||||
that can be used in those routines, call
|
||||
.BR pcap_get_selectable_fd ().
|
||||
If the routine indicates that data is
|
||||
available to read on the descriptor, an attempt should be made to read
|
||||
from the device.
|
||||
.PP
|
||||
Not all handles have such a descriptor available;
|
||||
.BR pcap_get_selectable_fd ()
|
||||
will return \-1 if no such descriptor exists. In addition, for various
|
||||
will return
|
||||
.B PCAP_ERROR
|
||||
if no such descriptor is available. If no such
|
||||
descriptor is available, this may be because the device must be polled
|
||||
periodically for packets; in that case,
|
||||
.BR pcap_get_required_select_timeout ()
|
||||
will return a pointer to a
|
||||
.B struct timeval
|
||||
whose value can be used as a timeout in those routines. When the
|
||||
routine returns, an attmept should be made to read packets from the
|
||||
device. If
|
||||
.BR pcap_get_required_select_timeout ()
|
||||
returns NULL, no such timeout is available, and those routines cannot be
|
||||
used with the device.
|
||||
.PP
|
||||
In addition, for various
|
||||
reasons, one or more of those routines will not work properly with the
|
||||
descriptor; the documentation for
|
||||
.BR pcap_get_selectable_fd ()
|
||||
@@ -693,6 +721,15 @@ that can be used in calls such as
|
||||
.BR select (2)
|
||||
and
|
||||
.BR poll (2)
|
||||
.TP
|
||||
.BR pcap_get_required_select_timeout (3PCAP)
|
||||
if no descriptor usable with
|
||||
.BR select (2)
|
||||
and
|
||||
.BR poll (2)
|
||||
is available for the
|
||||
.BR pcap_t ,
|
||||
attempt to get a timeout usable with those routines
|
||||
.RE
|
||||
.SS Filters
|
||||
In order to cause only certain packets to be returned when reading
|
||||
@@ -890,7 +927,7 @@ To get a string giving version information about libpcap, call
|
||||
.BR pcap_lib_version (3PCAP)
|
||||
get library version string
|
||||
.RE
|
||||
.SH BACKWARDS COMPATIBILITY
|
||||
.SH BACKWARD COMPATIBILITY
|
||||
.PP
|
||||
In versions of libpcap prior to 1.0, the
|
||||
.B pcap.h
|
||||
|
||||
394
libpcap/pcap.c
394
libpcap/pcap.c
@@ -139,7 +139,7 @@ BOOL WINAPI DllMain(
|
||||
|
||||
/*
|
||||
* Start WinSock.
|
||||
* Exported in case some applications using WinPcap called it,
|
||||
* Exported in case some applications using WinPcap/Npcap called it,
|
||||
* even though it wasn't exported.
|
||||
*/
|
||||
int
|
||||
@@ -186,76 +186,165 @@ pcap_wsockinit(void)
|
||||
PCAP_API char pcap_version[];
|
||||
PCAP_API_DEF char pcap_version[] = PACKAGE_VERSION;
|
||||
|
||||
static int
|
||||
pcap_not_initialized(pcap_t *pcap)
|
||||
static void
|
||||
pcap_set_not_initialized_message(pcap_t *pcap)
|
||||
{
|
||||
if (pcap->activated) {
|
||||
/* A module probably forgot to set the function pointer */
|
||||
(void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf),
|
||||
"This operation isn't properly handled by that device");
|
||||
return (PCAP_ERROR);
|
||||
return;
|
||||
}
|
||||
/* in case the caller doesn't check for PCAP_ERROR_NOT_ACTIVATED */
|
||||
(void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf),
|
||||
"This handle hasn't been activated yet");
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_read_not_initialized(pcap_t *pcap, int cnt _U_, pcap_handler callback _U_,
|
||||
u_char *user _U_)
|
||||
{
|
||||
pcap_set_not_initialized_message(pcap);
|
||||
/* this means 'not initialized' */
|
||||
return (PCAP_ERROR_NOT_ACTIVATED);
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_inject_not_initialized(pcap_t *pcap, const void * buf _U_, size_t size _U_)
|
||||
{
|
||||
pcap_set_not_initialized_message(pcap);
|
||||
/* this means 'not initialized' */
|
||||
return (PCAP_ERROR_NOT_ACTIVATED);
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_setfilter_not_initialized(pcap_t *pcap, struct bpf_program *fp _U_)
|
||||
{
|
||||
pcap_set_not_initialized_message(pcap);
|
||||
/* this means 'not initialized' */
|
||||
return (PCAP_ERROR_NOT_ACTIVATED);
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_setdirection_not_initialized(pcap_t *pcap, pcap_direction_t d _U_)
|
||||
{
|
||||
pcap_set_not_initialized_message(pcap);
|
||||
/* this means 'not initialized' */
|
||||
return (PCAP_ERROR_NOT_ACTIVATED);
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_set_datalink_not_initialized(pcap_t *pcap, int dlt _U_)
|
||||
{
|
||||
pcap_set_not_initialized_message(pcap);
|
||||
/* this means 'not initialized' */
|
||||
return (PCAP_ERROR_NOT_ACTIVATED);
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_getnonblock_not_initialized(pcap_t *pcap)
|
||||
{
|
||||
pcap_set_not_initialized_message(pcap);
|
||||
/* this means 'not initialized' */
|
||||
return (PCAP_ERROR_NOT_ACTIVATED);
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_stats_not_initialized(pcap_t *pcap, struct pcap_stat *ps _U_)
|
||||
{
|
||||
pcap_set_not_initialized_message(pcap);
|
||||
/* this means 'not initialized' */
|
||||
return (PCAP_ERROR_NOT_ACTIVATED);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
static void *
|
||||
pcap_not_initialized_ptr(pcap_t *pcap)
|
||||
struct pcap_stat *
|
||||
pcap_stats_ex_not_initialized(pcap_t *pcap, int *pcap_stat_size _U_)
|
||||
{
|
||||
if (pcap->activated) {
|
||||
/* A module probably forgot to set the function pointer */
|
||||
(void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf),
|
||||
"This operation isn't properly handled by that device");
|
||||
return (NULL);
|
||||
}
|
||||
(void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf),
|
||||
"This handle hasn't been activated yet");
|
||||
pcap_set_not_initialized_message(pcap);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_setbuff_not_initialized(pcap_t *pcap, int dim _U_)
|
||||
{
|
||||
pcap_set_not_initialized_message(pcap);
|
||||
/* this means 'not initialized' */
|
||||
return (PCAP_ERROR_NOT_ACTIVATED);
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_setmode_not_initialized(pcap_t *pcap, int mode _U_)
|
||||
{
|
||||
pcap_set_not_initialized_message(pcap);
|
||||
/* this means 'not initialized' */
|
||||
return (PCAP_ERROR_NOT_ACTIVATED);
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_setmintocopy_not_initialized(pcap_t *pcap, int size _U_)
|
||||
{
|
||||
pcap_set_not_initialized_message(pcap);
|
||||
/* this means 'not initialized' */
|
||||
return (PCAP_ERROR_NOT_ACTIVATED);
|
||||
}
|
||||
|
||||
static HANDLE
|
||||
pcap_getevent_not_initialized(pcap_t *pcap)
|
||||
{
|
||||
if (pcap->activated) {
|
||||
/* A module probably forgot to set the function pointer */
|
||||
(void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf),
|
||||
"This operation isn't properly handled by that device");
|
||||
return (INVALID_HANDLE_VALUE);
|
||||
}
|
||||
(void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf),
|
||||
"This handle hasn't been activated yet");
|
||||
pcap_set_not_initialized_message(pcap);
|
||||
return (INVALID_HANDLE_VALUE);
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_oid_get_request_not_initialized(pcap_t *pcap, bpf_u_int32 oid _U_,
|
||||
void *data _U_, size_t *lenp _U_)
|
||||
{
|
||||
pcap_set_not_initialized_message(pcap);
|
||||
return (PCAP_ERROR_NOT_ACTIVATED);
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_oid_set_request_not_initialized(pcap_t *pcap, bpf_u_int32 oid _U_,
|
||||
const void *data _U_, size_t *lenp _U_)
|
||||
{
|
||||
pcap_set_not_initialized_message(pcap);
|
||||
return (PCAP_ERROR_NOT_ACTIVATED);
|
||||
}
|
||||
|
||||
static u_int
|
||||
pcap_sendqueue_transmit_not_initialized(pcap_t *pcap, pcap_send_queue* queue, int sync)
|
||||
{
|
||||
if (pcap->activated) {
|
||||
/* A module probably forgot to set the function pointer */
|
||||
(void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf),
|
||||
"This operation isn't properly handled by that device");
|
||||
return (0);
|
||||
}
|
||||
(void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf),
|
||||
"This handle hasn't been activated yet");
|
||||
pcap_set_not_initialized_message(pcap);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_setuserbuffer_not_initialized(pcap_t *pcap, int size _U_)
|
||||
{
|
||||
pcap_set_not_initialized_message(pcap);
|
||||
return (PCAP_ERROR_NOT_ACTIVATED);
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_live_dump_not_initialized(pcap_t *pcap, char *filename _U_, int maxsize _U_,
|
||||
int maxpacks _U_)
|
||||
{
|
||||
pcap_set_not_initialized_message(pcap);
|
||||
return (PCAP_ERROR_NOT_ACTIVATED);
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_live_dump_ended_not_initialized(pcap_t *pcap, int sync _U_)
|
||||
{
|
||||
pcap_set_not_initialized_message(pcap);
|
||||
return (PCAP_ERROR_NOT_ACTIVATED);
|
||||
}
|
||||
|
||||
static PAirpcapHandle
|
||||
pcap_get_airpcap_handle_not_initialized(pcap_t *pcap)
|
||||
{
|
||||
if (pcap->activated) {
|
||||
/* A module probably forgot to set the function pointer */
|
||||
(void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf),
|
||||
"This operation isn't properly handled by that device");
|
||||
return (NULL);
|
||||
}
|
||||
(void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf),
|
||||
"This handle hasn't been activated yet");
|
||||
pcap_set_not_initialized_message(pcap);
|
||||
return (NULL);
|
||||
}
|
||||
#endif
|
||||
@@ -296,8 +385,17 @@ pcap_list_tstamp_types(pcap_t *p, int **tstamp_typesp)
|
||||
if (p->tstamp_type_count == 0) {
|
||||
/*
|
||||
* We don't support multiple time stamp types.
|
||||
* That means the only type we support is PCAP_TSTAMP_HOST;
|
||||
* set up a list containing only that type.
|
||||
*/
|
||||
*tstamp_typesp = NULL;
|
||||
*tstamp_typesp = (int*)malloc(sizeof(**tstamp_typesp));
|
||||
if (*tstamp_typesp == NULL) {
|
||||
pcap_fmt_errmsg_for_errno(p->errbuf, sizeof(p->errbuf),
|
||||
errno, "malloc");
|
||||
return (PCAP_ERROR);
|
||||
}
|
||||
**tstamp_typesp = PCAP_TSTAMP_HOST;
|
||||
return (1);
|
||||
} else {
|
||||
*tstamp_typesp = (int*)calloc(sizeof(**tstamp_typesp),
|
||||
p->tstamp_type_count);
|
||||
@@ -308,8 +406,8 @@ pcap_list_tstamp_types(pcap_t *p, int **tstamp_typesp)
|
||||
}
|
||||
(void)memcpy(*tstamp_typesp, p->tstamp_type_list,
|
||||
sizeof(**tstamp_typesp) * p->tstamp_type_count);
|
||||
return (p->tstamp_type_count);
|
||||
}
|
||||
return (p->tstamp_type_count);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -659,7 +757,7 @@ get_if_description(const char *name)
|
||||
* Get the description for the interface.
|
||||
*/
|
||||
memset(&ifrdesc, 0, sizeof ifrdesc);
|
||||
strlcpy(ifrdesc.ifr_name, name, sizeof ifrdesc.ifr_name);
|
||||
pcap_strlcpy(ifrdesc.ifr_name, name, sizeof ifrdesc.ifr_name);
|
||||
s = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (s >= 0) {
|
||||
#ifdef __FreeBSD__
|
||||
@@ -710,7 +808,7 @@ get_if_description(const char *name)
|
||||
}
|
||||
#endif /* __FreeBSD__ */
|
||||
close(s);
|
||||
if (description != NULL && strlen(description) == 0) {
|
||||
if (description != NULL && description[0] == '\0') {
|
||||
/*
|
||||
* Description is empty, so discard it.
|
||||
*/
|
||||
@@ -741,20 +839,13 @@ get_if_description(const char *name)
|
||||
* OK, it's a valid number that's not
|
||||
* bigger than INT_MAX. Construct
|
||||
* a description from it.
|
||||
* (If that fails, we don't worry about
|
||||
* it, we just return NULL.)
|
||||
*/
|
||||
static const char descr_prefix[] = "USB bus number ";
|
||||
size_t descr_size;
|
||||
|
||||
/*
|
||||
* Allow enough room for a 32-bit bus number.
|
||||
* sizeof (descr_prefix) includes the
|
||||
* terminating NUL.
|
||||
*/
|
||||
descr_size = sizeof (descr_prefix) + 10;
|
||||
description = malloc(descr_size);
|
||||
if (description != NULL) {
|
||||
pcap_snprintf(description, descr_size,
|
||||
"%s%ld", descr_prefix, busnum);
|
||||
if (pcap_asprintf(&description,
|
||||
"USB bus number %ld", busnum) == -1) {
|
||||
/* Failed. */
|
||||
description = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1292,14 +1383,14 @@ pcap_lookupdev(char *errbuf)
|
||||
* on the list, there aren't any non-loopback devices,
|
||||
* so why not just supply it as the default device?
|
||||
*/
|
||||
(void)strlcpy(errbuf, "no suitable device found",
|
||||
(void)pcap_strlcpy(errbuf, "no suitable device found",
|
||||
PCAP_ERRBUF_SIZE);
|
||||
ret = NULL;
|
||||
} else {
|
||||
/*
|
||||
* Return the name of the first device on the list.
|
||||
*/
|
||||
(void)strlcpy(device, alldevs->name, sizeof(device));
|
||||
(void)pcap_strlcpy(device, alldevs->name, sizeof(device));
|
||||
ret = device;
|
||||
}
|
||||
|
||||
@@ -1366,7 +1457,7 @@ pcap_lookupnet(const char *device, bpf_u_int32 *netp, bpf_u_int32 *maskp,
|
||||
/* XXX Work around Linux kernel bug */
|
||||
ifr.ifr_addr.sa_family = AF_INET;
|
||||
#endif
|
||||
(void)strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
|
||||
(void)pcap_strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
|
||||
if (ioctl(fd, SIOCGIFADDR, (char *)&ifr) < 0) {
|
||||
if (errno == EADDRNOTAVAIL) {
|
||||
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
@@ -1385,7 +1476,7 @@ pcap_lookupnet(const char *device, bpf_u_int32 *netp, bpf_u_int32 *maskp,
|
||||
/* XXX Work around Linux kernel bug */
|
||||
ifr.ifr_addr.sa_family = AF_INET;
|
||||
#endif
|
||||
(void)strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
|
||||
(void)pcap_strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
|
||||
if (ioctl(fd, SIOCGIFNETMASK, (char *)&ifr) < 0) {
|
||||
pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
|
||||
errno, "SIOCGIFNETMASK: %s", device);
|
||||
@@ -1575,13 +1666,14 @@ pcap_parse_source(const char *source, char **schemep, char **userinfop,
|
||||
* the pathname.
|
||||
*/
|
||||
if (pcap_strcasecmp(scheme, "file") == 0) {
|
||||
*schemep = scheme;
|
||||
*pathp = strdup(colonp + 3);
|
||||
if (*pathp == NULL) {
|
||||
pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
|
||||
errno, "malloc");
|
||||
free(scheme);
|
||||
return (-1);
|
||||
}
|
||||
*schemep = scheme;
|
||||
return (0);
|
||||
}
|
||||
|
||||
@@ -1684,7 +1776,12 @@ pcap_parse_source(const char *source, char **schemep, char **userinfop,
|
||||
* Treat verything up to the closing square
|
||||
* bracket as the IP-Literal; we don't worry
|
||||
* about whether it's a valid IPv6address or
|
||||
* IPvFuture.
|
||||
* IPvFuture (or an IPv4address, for that
|
||||
* matter, just in case we get handed a
|
||||
* URL with an IPv4 IP-Literal, of the sort
|
||||
* that pcap_createsrcstr() used to generate,
|
||||
* and that pcap_parsesrcstr(), in the original
|
||||
* WinPcap code, accepted).
|
||||
*/
|
||||
bracketp = strchr(parsep, ']');
|
||||
if (bracketp == NULL) {
|
||||
@@ -1805,9 +1902,9 @@ pcap_createsrcstr(char *source, int type, const char *host, const char *port,
|
||||
switch (type) {
|
||||
|
||||
case PCAP_SRC_FILE:
|
||||
strlcpy(source, PCAP_SRC_FILE_STRING, PCAP_BUF_SIZE);
|
||||
pcap_strlcpy(source, PCAP_SRC_FILE_STRING, PCAP_BUF_SIZE);
|
||||
if (name != NULL && *name != '\0') {
|
||||
strlcat(source, name, PCAP_BUF_SIZE);
|
||||
pcap_strlcat(source, name, PCAP_BUF_SIZE);
|
||||
return (0);
|
||||
} else {
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
@@ -1816,7 +1913,7 @@ pcap_createsrcstr(char *source, int type, const char *host, const char *port,
|
||||
}
|
||||
|
||||
case PCAP_SRC_IFREMOTE:
|
||||
strlcpy(source, PCAP_SRC_IF_STRING, PCAP_BUF_SIZE);
|
||||
pcap_strlcpy(source, PCAP_SRC_IF_STRING, PCAP_BUF_SIZE);
|
||||
if (host != NULL && *host != '\0') {
|
||||
if (strchr(host, ':') != NULL) {
|
||||
/*
|
||||
@@ -1824,18 +1921,18 @@ pcap_createsrcstr(char *source, int type, const char *host, const char *port,
|
||||
* probably an IPv6 address, and needs to
|
||||
* be included in square brackets.
|
||||
*/
|
||||
strlcat(source, "[", PCAP_BUF_SIZE);
|
||||
strlcat(source, host, PCAP_BUF_SIZE);
|
||||
strlcat(source, "]", PCAP_BUF_SIZE);
|
||||
pcap_strlcat(source, "[", PCAP_BUF_SIZE);
|
||||
pcap_strlcat(source, host, PCAP_BUF_SIZE);
|
||||
pcap_strlcat(source, "]", PCAP_BUF_SIZE);
|
||||
} else
|
||||
strlcat(source, host, PCAP_BUF_SIZE);
|
||||
pcap_strlcat(source, host, PCAP_BUF_SIZE);
|
||||
|
||||
if (port != NULL && *port != '\0') {
|
||||
strlcat(source, ":", PCAP_BUF_SIZE);
|
||||
strlcat(source, port, PCAP_BUF_SIZE);
|
||||
pcap_strlcat(source, ":", PCAP_BUF_SIZE);
|
||||
pcap_strlcat(source, port, PCAP_BUF_SIZE);
|
||||
}
|
||||
|
||||
strlcat(source, "/", PCAP_BUF_SIZE);
|
||||
pcap_strlcat(source, "/", PCAP_BUF_SIZE);
|
||||
} else {
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"The host name cannot be NULL.");
|
||||
@@ -1843,15 +1940,15 @@ pcap_createsrcstr(char *source, int type, const char *host, const char *port,
|
||||
}
|
||||
|
||||
if (name != NULL && *name != '\0')
|
||||
strlcat(source, name, PCAP_BUF_SIZE);
|
||||
pcap_strlcat(source, name, PCAP_BUF_SIZE);
|
||||
|
||||
return (0);
|
||||
|
||||
case PCAP_SRC_IFLOCAL:
|
||||
strlcpy(source, PCAP_SRC_IF_STRING, PCAP_BUF_SIZE);
|
||||
pcap_strlcpy(source, PCAP_SRC_IF_STRING, PCAP_BUF_SIZE);
|
||||
|
||||
if (name != NULL && *name != '\0')
|
||||
strlcat(source, name, PCAP_BUF_SIZE);
|
||||
pcap_strlcat(source, name, PCAP_BUF_SIZE);
|
||||
|
||||
return (0);
|
||||
|
||||
@@ -1890,7 +1987,7 @@ pcap_parsesrcstr(const char *source, int *type, char *host, char *port,
|
||||
* Local device.
|
||||
*/
|
||||
if (name && tmppath)
|
||||
strlcpy(name, tmppath, PCAP_BUF_SIZE);
|
||||
pcap_strlcpy(name, tmppath, PCAP_BUF_SIZE);
|
||||
if (type)
|
||||
*type = PCAP_SRC_IFLOCAL;
|
||||
free(tmppath);
|
||||
@@ -1912,12 +2009,12 @@ pcap_parsesrcstr(const char *source, int *type, char *host, char *port,
|
||||
pcap_snprintf(host, PCAP_BUF_SIZE, "%s@%s",
|
||||
tmpuserinfo, tmphost);
|
||||
else
|
||||
strlcpy(host, tmphost, PCAP_BUF_SIZE);
|
||||
pcap_strlcpy(host, tmphost, PCAP_BUF_SIZE);
|
||||
}
|
||||
if (port && tmpport)
|
||||
strlcpy(port, tmpport, PCAP_BUF_SIZE);
|
||||
pcap_strlcpy(port, tmpport, PCAP_BUF_SIZE);
|
||||
if (name && tmppath)
|
||||
strlcpy(name, tmppath, PCAP_BUF_SIZE);
|
||||
pcap_strlcpy(name, tmppath, PCAP_BUF_SIZE);
|
||||
if (type)
|
||||
*type = PCAP_SRC_IFREMOTE;
|
||||
free(tmppath);
|
||||
@@ -1933,7 +2030,7 @@ pcap_parsesrcstr(const char *source, int *type, char *host, char *port,
|
||||
* file://
|
||||
*/
|
||||
if (name && tmppath)
|
||||
strlcpy(name, tmppath, PCAP_BUF_SIZE);
|
||||
pcap_strlcpy(name, tmppath, PCAP_BUF_SIZE);
|
||||
if (type)
|
||||
*type = PCAP_SRC_FILE;
|
||||
free(tmppath);
|
||||
@@ -1949,7 +2046,7 @@ pcap_parsesrcstr(const char *source, int *type, char *host, char *port,
|
||||
* as a local device.
|
||||
*/
|
||||
if (name)
|
||||
strlcpy(name, source, PCAP_BUF_SIZE);
|
||||
pcap_strlcpy(name, source, PCAP_BUF_SIZE);
|
||||
if (type)
|
||||
*type = PCAP_SRC_IFLOCAL;
|
||||
free(tmppath);
|
||||
@@ -1981,11 +2078,28 @@ pcap_create(const char *device, char *errbuf)
|
||||
else {
|
||||
#ifdef _WIN32
|
||||
/*
|
||||
* If the string appears to be little-endian UCS-2/UTF-16,
|
||||
* convert it to ASCII.
|
||||
* On Windows, for backwards compatibility reasons,
|
||||
* pcap_lookupdev() returns a pointer to a sequence of
|
||||
* pairs of UTF-16LE device names and local code page
|
||||
* description strings.
|
||||
*
|
||||
* XXX - to UTF-8 instead? Or report an error if any
|
||||
* character isn't ASCII?
|
||||
* This means that if a program uses pcap_lookupdev()
|
||||
* to get a default device, and hands that to an API
|
||||
* that opens devices, we'll get handed a UTF-16LE
|
||||
* string, not a string in the local code page.
|
||||
*
|
||||
* To work around that, we check whether the string
|
||||
* looks as if it might be a UTF-16LE strinh and, if
|
||||
* so, convert it back to the local code page's
|
||||
* extended ASCII.
|
||||
*
|
||||
* XXX - you *cannot* reliably detect whether a
|
||||
* string is UTF-16LE or not; "a" could either
|
||||
* be a one-character ASCII string or the first
|
||||
* character of a UTF-16LE string. This particular
|
||||
* version of this heuristic dates back to WinPcap
|
||||
* 4.1.1; PacketOpenAdapter() does uses the same
|
||||
* heuristic, with the exact same vulnerability.
|
||||
*/
|
||||
if (device[0] != '\0' && device[1] == '\0') {
|
||||
size_t length;
|
||||
@@ -2077,25 +2191,25 @@ initialize_ops(pcap_t *p)
|
||||
* an activated pcap_t to point to a routine that returns
|
||||
* a "this isn't activated" error.
|
||||
*/
|
||||
p->read_op = (read_op_t)pcap_not_initialized;
|
||||
p->inject_op = (inject_op_t)pcap_not_initialized;
|
||||
p->setfilter_op = (setfilter_op_t)pcap_not_initialized;
|
||||
p->setdirection_op = (setdirection_op_t)pcap_not_initialized;
|
||||
p->set_datalink_op = (set_datalink_op_t)pcap_not_initialized;
|
||||
p->getnonblock_op = (getnonblock_op_t)pcap_not_initialized;
|
||||
p->stats_op = (stats_op_t)pcap_not_initialized;
|
||||
p->read_op = pcap_read_not_initialized;
|
||||
p->inject_op = pcap_inject_not_initialized;
|
||||
p->setfilter_op = pcap_setfilter_not_initialized;
|
||||
p->setdirection_op = pcap_setdirection_not_initialized;
|
||||
p->set_datalink_op = pcap_set_datalink_not_initialized;
|
||||
p->getnonblock_op = pcap_getnonblock_not_initialized;
|
||||
p->stats_op = pcap_stats_not_initialized;
|
||||
#ifdef _WIN32
|
||||
p->stats_ex_op = (stats_ex_op_t)pcap_not_initialized_ptr;
|
||||
p->setbuff_op = (setbuff_op_t)pcap_not_initialized;
|
||||
p->setmode_op = (setmode_op_t)pcap_not_initialized;
|
||||
p->setmintocopy_op = (setmintocopy_op_t)pcap_not_initialized;
|
||||
p->stats_ex_op = pcap_stats_ex_not_initialized;
|
||||
p->setbuff_op = pcap_setbuff_not_initialized;
|
||||
p->setmode_op = pcap_setmode_not_initialized;
|
||||
p->setmintocopy_op = pcap_setmintocopy_not_initialized;
|
||||
p->getevent_op = pcap_getevent_not_initialized;
|
||||
p->oid_get_request_op = (oid_get_request_op_t)pcap_not_initialized;
|
||||
p->oid_set_request_op = (oid_set_request_op_t)pcap_not_initialized;
|
||||
p->oid_get_request_op = pcap_oid_get_request_not_initialized;
|
||||
p->oid_set_request_op = pcap_oid_set_request_not_initialized;
|
||||
p->sendqueue_transmit_op = pcap_sendqueue_transmit_not_initialized;
|
||||
p->setuserbuffer_op = (setuserbuffer_op_t)pcap_not_initialized;
|
||||
p->live_dump_op = (live_dump_op_t)pcap_not_initialized;
|
||||
p->live_dump_ended_op = (live_dump_ended_op_t)pcap_not_initialized;
|
||||
p->setuserbuffer_op = pcap_setuserbuffer_not_initialized;
|
||||
p->live_dump_op = pcap_live_dump_not_initialized;
|
||||
p->live_dump_ended_op = pcap_live_dump_ended_not_initialized;
|
||||
p->get_airpcap_handle_op = pcap_get_airpcap_handle_not_initialized;
|
||||
#endif
|
||||
|
||||
@@ -2133,7 +2247,7 @@ pcap_alloc_pcap_t(char *ebuf, size_t size)
|
||||
* require 8-byte alignment even on platforms with 32-bit
|
||||
* integers.
|
||||
*/
|
||||
#define PCAP_T_ALIGNED_SIZE ((sizeof(pcap_t) + 7) & ~0x7)
|
||||
#define PCAP_T_ALIGNED_SIZE ((sizeof(pcap_t) + 7U) & ~0x7U)
|
||||
chunk = malloc(PCAP_T_ALIGNED_SIZE + size);
|
||||
if (chunk == NULL) {
|
||||
pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
|
||||
@@ -2460,6 +2574,16 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, char *er
|
||||
char name[PCAP_BUF_SIZE + 1];
|
||||
int srctype;
|
||||
|
||||
/*
|
||||
* A null device name is equivalent to the "any" device -
|
||||
* which might not be supported on this platform, but
|
||||
* this means that you'll get a "not supported" error
|
||||
* rather than, say, a crash when we try to dereference
|
||||
* the null pointer.
|
||||
*/
|
||||
if (device == NULL)
|
||||
device = "any";
|
||||
|
||||
/*
|
||||
* Retrofit - we have to make older applications compatible with
|
||||
* remote capture.
|
||||
@@ -2531,13 +2655,13 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, char *er
|
||||
return (p);
|
||||
fail:
|
||||
if (status == PCAP_ERROR)
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", device,
|
||||
p->errbuf);
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %.*s", device,
|
||||
PCAP_ERRBUF_SIZE - 3, p->errbuf);
|
||||
else if (status == PCAP_ERROR_NO_SUCH_DEVICE ||
|
||||
status == PCAP_ERROR_PERM_DENIED ||
|
||||
status == PCAP_ERROR_PROMISC_PERM_DENIED)
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s (%s)", device,
|
||||
pcap_statustostr(status), p->errbuf);
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s (%.*s)", device,
|
||||
pcap_statustostr(status), PCAP_ERRBUF_SIZE - 6, p->errbuf);
|
||||
else
|
||||
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", device,
|
||||
pcap_statustostr(status));
|
||||
@@ -2850,7 +2974,7 @@ static struct dlt_choice dlt_choices[] = {
|
||||
DLT_CHOICE(FRELAY, "Frame Relay"),
|
||||
DLT_CHOICE(LOOP, "OpenBSD loopback"),
|
||||
DLT_CHOICE(ENC, "OpenBSD encapsulated IP"),
|
||||
DLT_CHOICE(LINUX_SLL, "Linux cooked"),
|
||||
DLT_CHOICE(LINUX_SLL, "Linux cooked v1"),
|
||||
DLT_CHOICE(LTALK, "Localtalk"),
|
||||
DLT_CHOICE(PFLOG, "OpenBSD pflog file"),
|
||||
DLT_CHOICE(PFSYNC, "Packet filter state syncing"),
|
||||
@@ -2884,7 +3008,7 @@ static struct dlt_choice dlt_choices[] = {
|
||||
DLT_CHOICE(GPF_T, "GPF-T"),
|
||||
DLT_CHOICE(GPF_F, "GPF-F"),
|
||||
DLT_CHOICE(JUNIPER_PIC_PEER, "Juniper PIC Peer"),
|
||||
DLT_CHOICE(ERF_ETH, "Ethernet with Endace ERF header"),
|
||||
DLT_CHOICE(ERF_ETH, "Ethernet with Endace ERF header"),
|
||||
DLT_CHOICE(ERF_POS, "Packet-over-SONET with Endace ERF header"),
|
||||
DLT_CHOICE(LINUX_LAPD, "Linux vISDN LAPD"),
|
||||
DLT_CHOICE(JUNIPER_ETHER, "Juniper Ethernet"),
|
||||
@@ -2908,10 +3032,11 @@ static struct dlt_choice dlt_choices[] = {
|
||||
DLT_CHOICE(SITA, "SITA pseudo-header"),
|
||||
DLT_CHOICE(ERF, "Endace ERF header"),
|
||||
DLT_CHOICE(RAIF1, "Ethernet with u10 Networks pseudo-header"),
|
||||
DLT_CHOICE(IPMB, "IPMB"),
|
||||
DLT_CHOICE(IPMB_KONTRON, "IPMB with Kontron pseudo-header"),
|
||||
DLT_CHOICE(JUNIPER_ST, "Juniper Secure Tunnel"),
|
||||
DLT_CHOICE(BLUETOOTH_HCI_H4_WITH_PHDR, "Bluetooth HCI UART transport layer plus pseudo-header"),
|
||||
DLT_CHOICE(AX25_KISS, "AX.25 with KISS header"),
|
||||
DLT_CHOICE(IPMB_LINUX, "IPMB with Linux/Pigeon Point pseudo-header"),
|
||||
DLT_CHOICE(IEEE802_15_4_NONASK_PHY, "IEEE 802.15.4 with non-ASK PHY data"),
|
||||
DLT_CHOICE(MPLS, "MPLS with label as link-layer header"),
|
||||
DLT_CHOICE(LINUX_EVDEV, "Linux evdev events"),
|
||||
@@ -2968,6 +3093,7 @@ static struct dlt_choice dlt_choices[] = {
|
||||
DLT_CHOICE(DOCSIS31_XRA31, "Excentis XRA-31 DOCSIS 3.1 RF sniffer frames"),
|
||||
DLT_CHOICE(ETHERNET_MPACKET, "802.3br mPackets"),
|
||||
DLT_CHOICE(DISPLAYPORT_AUX, "DisplayPort AUX channel monitoring data"),
|
||||
DLT_CHOICE(LINUX_SLL2, "Linux cooked v2"),
|
||||
DLT_CHOICE_SENTINEL
|
||||
};
|
||||
|
||||
@@ -3007,6 +3133,21 @@ pcap_datalink_val_to_description(int dlt)
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
const char *
|
||||
pcap_datalink_val_to_description_or_dlt(int dlt)
|
||||
{
|
||||
static char unkbuf[40];
|
||||
const char *description;
|
||||
|
||||
description = pcap_datalink_val_to_description(dlt);
|
||||
if (description != NULL) {
|
||||
return description;
|
||||
} else {
|
||||
(void)pcap_snprintf(unkbuf, sizeof(unkbuf), "DLT %u", dlt);
|
||||
return unkbuf;
|
||||
}
|
||||
}
|
||||
|
||||
struct tstamp_type_choice {
|
||||
const char *name;
|
||||
const char *description;
|
||||
@@ -3159,7 +3300,7 @@ pcap_getnonblock(pcap_t *p, char *errbuf)
|
||||
* We copy the error message to errbuf, so callers
|
||||
* can find it in either place.
|
||||
*/
|
||||
strlcpy(errbuf, p->errbuf, PCAP_ERRBUF_SIZE);
|
||||
pcap_strlcpy(errbuf, p->errbuf, PCAP_ERRBUF_SIZE);
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
@@ -3203,7 +3344,7 @@ pcap_setnonblock(pcap_t *p, int nonblock, char *errbuf)
|
||||
* We copy the error message to errbuf, so callers
|
||||
* can find it in either place.
|
||||
*/
|
||||
strlcpy(errbuf, p->errbuf, PCAP_ERRBUF_SIZE);
|
||||
pcap_strlcpy(errbuf, p->errbuf, PCAP_ERRBUF_SIZE);
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
@@ -3239,35 +3380,6 @@ pcap_setnonblock_fd(pcap_t *p, int nonblock)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
/*
|
||||
* Generate a string for a Win32-specific error (i.e. an error generated when
|
||||
* calling a Win32 API).
|
||||
* For errors occurred during standard C calls, we still use pcap_strerror()
|
||||
*/
|
||||
void
|
||||
pcap_win32_err_to_str(DWORD error, char *errbuf)
|
||||
{
|
||||
size_t errlen;
|
||||
char *p;
|
||||
|
||||
FormatMessageA(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.
|
||||
*/
|
||||
@@ -3339,7 +3451,7 @@ pcap_strerror(int errnum)
|
||||
errno_t err = strerror_s(errbuf, PCAP_ERRBUF_SIZE, errnum);
|
||||
|
||||
if (err != 0) /* err = 0 if successful */
|
||||
strlcpy(errbuf, "strerror_s() error", PCAP_ERRBUF_SIZE);
|
||||
pcap_strlcpy(errbuf, "strerror_s() error", PCAP_ERRBUF_SIZE);
|
||||
return (errbuf);
|
||||
#else
|
||||
return (strerror(errnum));
|
||||
@@ -3561,7 +3673,7 @@ pcap_do_addexit(pcap_t *p)
|
||||
/*
|
||||
* "atexit()" failed; let our caller know.
|
||||
*/
|
||||
strlcpy(p->errbuf, "atexit failed", PCAP_ERRBUF_SIZE);
|
||||
pcap_strlcpy(p->errbuf, "atexit failed", PCAP_ERRBUF_SIZE);
|
||||
return (0);
|
||||
}
|
||||
did_atexit = 1;
|
||||
|
||||
@@ -238,16 +238,6 @@ struct bpf_insn {
|
||||
bpf_u_int32 k;
|
||||
};
|
||||
|
||||
/*
|
||||
* Auxiliary data, for use when interpreting a filter intended for the
|
||||
* Linux kernel when the kernel rejects the filter (requiring us to
|
||||
* run it in userland). It contains VLAN tag information.
|
||||
*/
|
||||
struct bpf_aux_data {
|
||||
u_short vlan_tag_present;
|
||||
u_short vlan_tag;
|
||||
};
|
||||
|
||||
/*
|
||||
* Macros for insn array initializers.
|
||||
*/
|
||||
@@ -256,7 +246,6 @@ struct bpf_aux_data {
|
||||
|
||||
PCAP_API int bpf_validate(const struct bpf_insn *, int);
|
||||
PCAP_API u_int bpf_filter(const struct bpf_insn *, const u_char *, u_int, u_int);
|
||||
extern u_int bpf_filter_with_aux_data(const struct bpf_insn *, const u_char *, u_int, u_int, const struct bpf_aux_data *);
|
||||
|
||||
/*
|
||||
* Number of scratch memory words (for BPF_LD|BPF_MEM and BPF_ST).
|
||||
|
||||
@@ -160,4 +160,4 @@
|
||||
(__HP_aCC >= ((major)*10000 + (minor)*100))
|
||||
#endif
|
||||
|
||||
#endif /* lib_pcap_funcattrs_h */
|
||||
#endif /* lib_pcap_compiler_tests_h */
|
||||
|
||||
@@ -246,7 +246,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is for Linux cooked sockets.
|
||||
* Linux cooked sockets.
|
||||
*/
|
||||
#define DLT_LINUX_SLL 113
|
||||
|
||||
@@ -769,11 +769,20 @@
|
||||
#define DLT_RAIF1 198
|
||||
|
||||
/*
|
||||
* IPMB packet for IPMI, beginning with the I2C slave address, followed
|
||||
* by the netFn and LUN, etc.. Requested by Chanthy Toeung
|
||||
* <chanthy.toeung@ca.kontron.com>.
|
||||
* IPMB packet for IPMI, beginning with a 2-byte header, followed by
|
||||
* the I2C slave address, followed by the netFn and LUN, etc..
|
||||
* Requested by Chanthy Toeung <chanthy.toeung@ca.kontron.com>.
|
||||
*
|
||||
* XXX - this used to be called DLT_IPMB, back when we got the
|
||||
* impression from the email thread requesting it that the packet
|
||||
* had no extra 2-byte header. We've renamed it; if anybody used
|
||||
* DLT_IPMB and assumed no 2-byte header, this will cause the compile
|
||||
* to fail, at which point we'll have to figure out what to do about
|
||||
* the two header types using the same DLT_/LINKTYPE_ value. If that
|
||||
* doesn't happen, we'll assume nobody used it and that the redefinition
|
||||
* is safe.
|
||||
*/
|
||||
#define DLT_IPMB 199
|
||||
#define DLT_IPMB_KONTRON 199
|
||||
|
||||
/*
|
||||
* Juniper-private data link type, as per request from
|
||||
@@ -805,15 +814,34 @@
|
||||
#define DLT_LAPD 203
|
||||
|
||||
/*
|
||||
* Variants of various link-layer headers, with a one-byte direction
|
||||
* pseudo-header prepended - zero means "received by this host",
|
||||
* non-zero (any non-zero value) means "sent by this host" - as per
|
||||
* Will Barker <w.barker@zen.co.uk>.
|
||||
* PPP, with a one-byte direction pseudo-header prepended - zero means
|
||||
* "received by this host", non-zero (any non-zero value) means "sent by
|
||||
* this host" - as per Will Barker <w.barker@zen.co.uk>.
|
||||
*/
|
||||
#define DLT_PPP_WITH_DIR 204 /* PPP - don't confuse with DLT_PPP_WITH_DIRECTION */
|
||||
#define DLT_C_HDLC_WITH_DIR 205 /* Cisco HDLC */
|
||||
#define DLT_FRELAY_WITH_DIR 206 /* Frame Relay */
|
||||
#define DLT_LAPB_WITH_DIR 207 /* LAPB */
|
||||
#define DLT_PPP_WITH_DIR 204 /* Don't confuse with DLT_PPP_WITH_DIRECTION */
|
||||
|
||||
/*
|
||||
* Cisco HDLC, with a one-byte direction pseudo-header prepended - zero
|
||||
* means "received by this host", non-zero (any non-zero value) means
|
||||
* "sent by this host" - as per Will Barker <w.barker@zen.co.uk>.
|
||||
*/
|
||||
#define DLT_C_HDLC_WITH_DIR 205
|
||||
|
||||
/*
|
||||
* Frame Relay, with a one-byte direction pseudo-header prepended - zero
|
||||
* means "received by this host" (DCE -> DTE), non-zero (any non-zero
|
||||
* value) means "sent by this host" (DTE -> DCE) - as per Will Barker
|
||||
* <w.barker@zen.co.uk>.
|
||||
*/
|
||||
#define DLT_FRELAY_WITH_DIR 206
|
||||
|
||||
/*
|
||||
* LAPB, with a one-byte direction pseudo-header prepended - zero means
|
||||
* "received by this host" (DCE -> DTE), non-zero (any non-zero value)
|
||||
* means "sent by this host" (DTE -> DCE)- as per Will Barker
|
||||
* <w.barker@zen.co.uk>.
|
||||
*/
|
||||
#define DLT_LAPB_WITH_DIR 207
|
||||
|
||||
/*
|
||||
* 208 is reserved for an as-yet-unspecified proprietary link-layer
|
||||
@@ -1367,6 +1395,11 @@
|
||||
*/
|
||||
#define DLT_DISPLAYPORT_AUX 275
|
||||
|
||||
/*
|
||||
* Linux cooked sockets v2.
|
||||
*/
|
||||
#define DLT_LINUX_SLL2 276
|
||||
|
||||
/*
|
||||
* In case the code that includes this file (directly or indirectly)
|
||||
* has also included OS files that happen to define DLT_MATCHING_MAX,
|
||||
@@ -1377,7 +1410,7 @@
|
||||
#ifdef DLT_MATCHING_MAX
|
||||
#undef DLT_MATCHING_MAX
|
||||
#endif
|
||||
#define DLT_MATCHING_MAX 275 /* highest value in the "matching" range */
|
||||
#define DLT_MATCHING_MAX 276 /* highest value in the "matching" range */
|
||||
|
||||
/*
|
||||
* DLT and savefile link type values are split into a class and
|
||||
|
||||
@@ -164,10 +164,11 @@
|
||||
|| PCAP_IS_AT_LEAST_XL_C_VERSION(10,1) \
|
||||
|| PCAP_IS_AT_LEAST_HP_C_VERSION(6,10)
|
||||
/*
|
||||
* Compiler with support for __attribute((noreturn)), or GCC 2.5 and
|
||||
* later, or Solaris Studio 12 (Sun C 5.9) and later, or IBM XL C 10.1
|
||||
* and later (do any earlier versions of XL C support this?), or
|
||||
* HP aCC A.06.10 and later.
|
||||
* Compiler with support for __attribute((noreturn)), or GCC 2.5 or
|
||||
* later, or some compiler asserting compatibility with GCC 2.5 or
|
||||
* later, or Solaris Studio 12 (Sun C 5.9) or later, or IBM XL C 10.1
|
||||
* or later (do any earlier versions of XL C support this?), or HP aCC
|
||||
* A.06.10 or later.
|
||||
*/
|
||||
#define PCAP_NORETURN __attribute((noreturn))
|
||||
#define PCAP_NORETURN_DEF __attribute((noreturn))
|
||||
@@ -193,7 +194,8 @@
|
||||
|| PCAP_IS_AT_LEAST_XL_C_VERSION(10,1) \
|
||||
|| PCAP_IS_AT_LEAST_HP_C_VERSION(6,10)
|
||||
/*
|
||||
* Compiler with support for it, or GCC 2.3 and later, or IBM XL C 10.1
|
||||
* Compiler with support for it, or GCC 2.3 or later, or some compiler
|
||||
* asserting compatibility with GCC 2.3 or later, or IBM XL C 10.1
|
||||
* and later (do any earlier versions of XL C support this?),
|
||||
* or HP aCC A.06.10 and later.
|
||||
*/
|
||||
@@ -216,7 +218,7 @@
|
||||
|| PCAP_IS_AT_LEAST_SUNC_VERSION(5,13)
|
||||
/*
|
||||
* Compiler that supports __has_attribute and __attribute__((deprecated)),
|
||||
* or GCC 4.5 and later, or Sun/Oracle C 12.4 (Sun C 5.13) or later.
|
||||
* or GCC 4.5 or later, or Sun/Oracle C 12.4 (Sun C 5.13) or later.
|
||||
*
|
||||
* Those support __attribute__((deprecated(msg))) (we assume, perhaps
|
||||
* incorrectly, that anything that supports __has_attribute() is
|
||||
|
||||
@@ -106,12 +106,23 @@
|
||||
#define PRIu64 "llu"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* MSVC's support library doesn't support %zu to print a size_t until
|
||||
* Visual Studio 2017, but supports %Iu earlier, so use that.
|
||||
*/
|
||||
#define PRIsize "Iu"
|
||||
#elif defined(__MINGW32__) || !defined(_WIN32)
|
||||
/*
|
||||
* Compiler is MinGW or target is UN*X or MS-DOS. Just use
|
||||
* <inttypes.h>.
|
||||
*/
|
||||
#include <inttypes.h>
|
||||
|
||||
/*
|
||||
* Assume the support library supports %zu; it's required by C99.
|
||||
*/
|
||||
#define PRIsize "zu"
|
||||
#endif
|
||||
|
||||
#endif /* pcap/pcap-inttypes.h */
|
||||
|
||||
@@ -84,6 +84,8 @@
|
||||
#include <sys/time.h>
|
||||
#endif /* _WIN32/MSDOS/UN*X */
|
||||
|
||||
#include <pcap/socket.h> /* for SOCKET, as the active-mode rpcap APIs use it */
|
||||
|
||||
#ifndef PCAP_DONT_INCLUDE_PCAP_BPF_H
|
||||
#include <pcap/bpf.h>
|
||||
#endif
|
||||
@@ -468,6 +470,7 @@ PCAP_API void pcap_free_datalinks(int *);
|
||||
PCAP_API int pcap_datalink_name_to_val(const char *);
|
||||
PCAP_API const char *pcap_datalink_val_to_name(int);
|
||||
PCAP_API const char *pcap_datalink_val_to_description(int);
|
||||
PCAP_API const char *pcap_datalink_val_to_description_or_dlt(int);
|
||||
PCAP_API int pcap_snapshot(pcap_t *);
|
||||
PCAP_API int pcap_is_swapped(pcap_t *);
|
||||
PCAP_API int pcap_major_version(pcap_t *);
|
||||
@@ -483,7 +486,28 @@ PCAP_API int pcap_fileno(pcap_t *);
|
||||
#endif
|
||||
|
||||
PCAP_API pcap_dumper_t *pcap_dump_open(pcap_t *, const char *);
|
||||
PCAP_API pcap_dumper_t *pcap_dump_fopen(pcap_t *, FILE *fp);
|
||||
#ifdef _WIN32
|
||||
PCAP_API pcap_dumper_t *pcap_dump_hopen(pcap_t *, intptr_t);
|
||||
/*
|
||||
* If we're building libpcap, this is an internal routine in sf-pcap.c, so
|
||||
* we must not define it as a macro.
|
||||
*
|
||||
* If we're not building libpcap, given that the version of the C runtime
|
||||
* with which libpcap was built might be different from the version
|
||||
* of the C runtime with which an application using libpcap was built,
|
||||
* and that a FILE structure may differ between the two versions of the
|
||||
* C runtime, calls to _fileno() must use the version of _fileno() in
|
||||
* the C runtime used to open the FILE *, not the version in the C
|
||||
* runtime with which libpcap was built. (Maybe once the Universal CRT
|
||||
* rules the world, this will cease to be a problem.)
|
||||
*/
|
||||
#ifndef BUILDING_PCAP
|
||||
#define pcap_dump_fopen(p,f) \
|
||||
pcap_dump_hopen(p, _get_osfhandle(_fileno(f)))
|
||||
#endif
|
||||
#else /*_WIN32*/
|
||||
PCAP_API pcap_dumper_t *pcap_dump_fopen(pcap_t *, FILE *fp);
|
||||
#endif /*_WIN32*/
|
||||
PCAP_API pcap_dumper_t *pcap_dump_open_append(pcap_t *, const char *);
|
||||
PCAP_API FILE *pcap_dump_file(pcap_dumper_t *);
|
||||
PCAP_API long pcap_dump_ftell(pcap_dumper_t *);
|
||||
@@ -858,8 +882,8 @@ PCAP_API int pcap_parsesrcstr(const char *source, int *type, char *host,
|
||||
* For listing remote capture devices, pcap_findalldevs_ex() is currently
|
||||
* the only API available.
|
||||
*/
|
||||
PCAP_API int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth,
|
||||
pcap_if_t **alldevs, char *errbuf);
|
||||
PCAP_API int pcap_findalldevs_ex(const char *source,
|
||||
struct pcap_rmtauth *auth, pcap_if_t **alldevs, char *errbuf);
|
||||
|
||||
/*
|
||||
* Sampling methods.
|
||||
@@ -937,27 +961,6 @@ PCAP_API struct pcap_samp *pcap_setsampling(pcap_t *p);
|
||||
/* Maximum length of an host name (needed for the RPCAP active mode) */
|
||||
#define RPCAP_HOSTLIST_SIZE 1024
|
||||
|
||||
/*
|
||||
* Some minor differences between UN*X sockets and and Winsock sockets.
|
||||
*/
|
||||
#ifndef _WIN32
|
||||
/*!
|
||||
* \brief In Winsock, a socket handle is of type SOCKET; in UN*X, it's
|
||||
* a file descriptor, and therefore a signed integer.
|
||||
* We define SOCKET to be a signed integer on UN*X, so that it can
|
||||
* be used on both platforms.
|
||||
*/
|
||||
#define SOCKET int
|
||||
|
||||
/*!
|
||||
* \brief In Winsock, the error return if socket() fails is INVALID_SOCKET;
|
||||
* in UN*X, it's -1.
|
||||
* We define INVALID_SOCKET to be -1 on UN*X, so that it can be used on
|
||||
* both platforms.
|
||||
*/
|
||||
#define INVALID_SOCKET -1
|
||||
#endif
|
||||
|
||||
PCAP_API SOCKET pcap_remoteact_accept(const char *address, const char *port,
|
||||
const char *hostlist, char *connectinghost,
|
||||
struct pcap_rmtauth *auth, char *errbuf);
|
||||
|
||||
@@ -74,27 +74,44 @@
|
||||
#ifndef lib_pcap_sll_h
|
||||
#define lib_pcap_sll_h
|
||||
|
||||
#include <pcap/pcap-inttypes.h>
|
||||
|
||||
/*
|
||||
* A DLT_LINUX_SLL fake link-layer header.
|
||||
*/
|
||||
#define SLL_HDR_LEN 16 /* total header length */
|
||||
#define SLL_ADDRLEN 8 /* length of address field */
|
||||
|
||||
#include <pcap/pcap-inttypes.h>
|
||||
|
||||
struct sll_header {
|
||||
uint16_t sll_pkttype; /* packet type */
|
||||
uint16_t sll_hatype; /* link-layer address type */
|
||||
uint16_t sll_halen; /* link-layer address length */
|
||||
uint8_t sll_addr[SLL_ADDRLEN]; /* link-layer address */
|
||||
uint8_t sll_addr[SLL_ADDRLEN]; /* link-layer address */
|
||||
uint16_t sll_protocol; /* protocol */
|
||||
};
|
||||
|
||||
/*
|
||||
* The LINUX_SLL_ values for "sll_pkttype"; these correspond to the
|
||||
* PACKET_ values on Linux, but are defined here so that they're
|
||||
* available even on systems other than Linux, and so that they
|
||||
* don't change even if the PACKET_ values change.
|
||||
* A DLT_LINUX_SLL2 fake link-layer header.
|
||||
*/
|
||||
#define SLL2_HDR_LEN 20 /* total header length */
|
||||
|
||||
struct sll2_header {
|
||||
uint16_t sll2_protocol; /* protocol */
|
||||
uint16_t sll2_reserved_mbz; /* reserved - must be zero */
|
||||
uint32_t sll2_if_index; /* 1-based interface index */
|
||||
uint16_t sll2_hatype; /* link-layer address type */
|
||||
uint8_t sll2_pkttype; /* packet type */
|
||||
uint8_t sll2_halen; /* link-layer address length */
|
||||
uint8_t sll2_addr[SLL_ADDRLEN]; /* link-layer address */
|
||||
};
|
||||
|
||||
/*
|
||||
* The LINUX_SLL_ values for "sll_pkttype" and LINUX_SLL2_ values for
|
||||
* "sll2_pkttype"; these correspond to the PACKET_ values on Linux,
|
||||
* which are defined by a header under include/uapi in the current
|
||||
* kernel source, and are thus not going to change on Linux. We
|
||||
* define them here so that they're available even on systems other
|
||||
* than Linux.
|
||||
*/
|
||||
#define LINUX_SLL_HOST 0
|
||||
#define LINUX_SLL_BROADCAST 1
|
||||
@@ -103,10 +120,11 @@ struct sll_header {
|
||||
#define LINUX_SLL_OUTGOING 4
|
||||
|
||||
/*
|
||||
* The LINUX_SLL_ values for "sll_protocol"; these correspond to the
|
||||
* ETH_P_ values on Linux, but are defined here so that they're
|
||||
* available even on systems other than Linux. We assume, for now,
|
||||
* that the ETH_P_ values won't change in Linux; if they do, then:
|
||||
* The LINUX_SLL_ values for "sll_protocol" and LINUX_SLL2_ values for
|
||||
* "sll2_protocol"; these correspond to the ETH_P_ values on Linux, but
|
||||
* are defined here so that they're available even on systems other than
|
||||
* Linux. We assume, for now, that the ETH_P_ values won't change in
|
||||
* Linux; if they do, then:
|
||||
*
|
||||
* if we don't translate them in "pcap-linux.c", capture files
|
||||
* won't necessarily be readable if captured on a system that
|
||||
|
||||
93
libpcap/pcap/socket.h
Normal file
93
libpcap/pcap/socket.h
Normal file
@@ -0,0 +1,93 @@
|
||||
/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */
|
||||
/*
|
||||
* Copyright (c) 1993, 1994, 1995, 1996, 1997
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the Computer Systems
|
||||
* Engineering Group at Lawrence Berkeley Laboratory.
|
||||
* 4. Neither the name of the University nor of the Laboratory may be used
|
||||
* to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef lib_pcap_socket_h
|
||||
#define lib_pcap_socket_h
|
||||
|
||||
/*
|
||||
* Some minor differences between sockets on various platforms.
|
||||
* We include whatever sockets are needed for Internet-protocol
|
||||
* socket access on UN*X and Windows.
|
||||
*/
|
||||
#ifdef _WIN32
|
||||
/* Need windef.h for defines used in winsock2.h under MingW32 */
|
||||
#ifdef __MINGW32__
|
||||
#include <windef.h>
|
||||
#endif
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
|
||||
/*
|
||||
* Winsock doesn't have this UN*X type; it's used in the UN*X
|
||||
* sockets API.
|
||||
*
|
||||
* XXX - do we need to worry about UN*Xes so old that *they*
|
||||
* don't have it, either?
|
||||
*/
|
||||
typedef int socklen_t;
|
||||
|
||||
/*
|
||||
* Winsock doesn't have this POSIX type; it's used for the
|
||||
* tv_usec value of struct timeval.
|
||||
*/
|
||||
typedef long suseconds_t;
|
||||
#else /* _WIN32 */
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h> /* for struct addrinfo/getaddrinfo() */
|
||||
#include <netinet/in.h> /* for sockaddr_in, in BSD at least */
|
||||
#include <arpa/inet.h>
|
||||
|
||||
/*!
|
||||
* \brief In Winsock, a socket handle is of type SOCKET; in UN*X, it's
|
||||
* a file descriptor, and therefore a signed integer.
|
||||
* We define SOCKET to be a signed integer on UN*X, so that it can
|
||||
* be used on both platforms.
|
||||
*/
|
||||
#ifndef SOCKET
|
||||
#define SOCKET int
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* \brief In Winsock, the error return if socket() fails is INVALID_SOCKET;
|
||||
* in UN*X, it's -1.
|
||||
* We define INVALID_SOCKET to be -1 on UN*X, so that it can be used on
|
||||
* both platforms.
|
||||
*/
|
||||
#ifndef INVALID_SOCKET
|
||||
#define INVALID_SOCKET -1
|
||||
#endif
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#endif /* lib_pcap_socket_h */
|
||||
@@ -50,15 +50,15 @@ promiscuous mode.
|
||||
.TP
|
||||
.B PCAP_WARNING_TSTAMP_TYPE_NOTSUP
|
||||
The time stamp type specified in a previous
|
||||
.B pcap_set_tstamp_type()
|
||||
.B pcap_set_tstamp_type(3PCAP)
|
||||
call isn't supported by the capture source (the time stamp type is
|
||||
left as the default),
|
||||
.TP
|
||||
.B PCAP_WARNING
|
||||
Another warning condition occurred;
|
||||
.B pcap_geterr()
|
||||
.B pcap_geterr(3PCAP)
|
||||
or
|
||||
.B pcap_perror()
|
||||
.B pcap_perror(3PCAP)
|
||||
may be called with
|
||||
.I p
|
||||
as an argument to fetch or display a message describing the warning
|
||||
@@ -115,7 +115,7 @@ Additional warning and error codes may be added in the future; a program
|
||||
should check for positive, negative, and zero return codes, and treat
|
||||
all positive return codes as warnings and all negative return
|
||||
codes as errors.
|
||||
.B pcap_statustostr()
|
||||
.B pcap_statustostr(3PCAP)
|
||||
can be called, with a warning or error code as an argument, to fetch a
|
||||
message describing the warning or error code.
|
||||
.SH SEE ALSO
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
.\"
|
||||
.TH PCAP_BREAKLOOP 3PCAP "8 November 2017"
|
||||
.TH PCAP_BREAKLOOP 3PCAP "25 July 2018"
|
||||
.SH NAME
|
||||
pcap_breakloop \- force a pcap_dispatch() or pcap_loop() call to return
|
||||
.SH SYNOPSIS
|
||||
@@ -33,12 +33,13 @@ void pcap_breakloop(pcap_t *);
|
||||
.SH DESCRIPTION
|
||||
.B pcap_breakloop()
|
||||
sets a flag that will force
|
||||
.B pcap_dispatch()
|
||||
.B pcap_dispatch(3PCAP)
|
||||
or
|
||||
.B pcap_loop()
|
||||
.B pcap_loop(3PCAP)
|
||||
to return rather than looping; they will return the number of packets
|
||||
that have been processed so far, or \-2 if no packets have been
|
||||
processed so far.
|
||||
that have been processed so far, or
|
||||
.B PCAP_ERROR_BREAK
|
||||
if no packets have been processed so far.
|
||||
.PP
|
||||
This routine is safe to use inside a signal handler on UNIX or a console
|
||||
control handler on Windows, as it merely sets a flag that is checked
|
||||
@@ -60,7 +61,7 @@ packets arrive and the call completes.
|
||||
.PP
|
||||
.ft B
|
||||
Note also that, in a multi-threaded application, if one thread is
|
||||
blocked in pcap_dispatch(), pcap_loop(), pcap_next(), or pcap_next_ex(),
|
||||
blocked in pcap_dispatch(), pcap_loop(), pcap_next(3PCAP), or pcap_next_ex(3PCAP),
|
||||
a call to pcap_breakloop() in a different thread will not unblock that
|
||||
thread.
|
||||
.ft R
|
||||
@@ -99,12 +100,16 @@ or
|
||||
.B pcap_loop()
|
||||
after it is called; at most one more packet might be processed.
|
||||
.PP
|
||||
If \-2 is returned from
|
||||
If
|
||||
.B PCAP_ERROR_BREAK
|
||||
is returned from
|
||||
.B pcap_dispatch()
|
||||
or
|
||||
.BR pcap_loop() ,
|
||||
the flag is cleared, so a subsequent call will resume reading packets.
|
||||
If a positive number is returned, the flag is not cleared, so a
|
||||
subsequent call will return \-2 and clear the flag.
|
||||
subsequent call will return
|
||||
.B PCAP_ERROR_BREAK
|
||||
and clear the flag.
|
||||
.SH SEE ALSO
|
||||
pcap(3PCAP), pcap_loop(3PCAP), pcap_next_ex(3PCAP)
|
||||
pcap(3PCAP)
|
||||
|
||||
@@ -54,9 +54,9 @@ The capture handle has already been activated.
|
||||
.TP
|
||||
.B PCAP_ERROR
|
||||
Another error occurred.
|
||||
.B pcap_geterr()
|
||||
.B pcap_geterr(3PCAP)
|
||||
or
|
||||
.B pcap_perror()
|
||||
.B \%pcap_perror(3PCAP)
|
||||
may be called with
|
||||
.I p
|
||||
as an argument to fetch or display a message describing the error.
|
||||
@@ -64,7 +64,7 @@ as an argument to fetch or display a message describing the error.
|
||||
Additional error codes may be added in the future; a program should
|
||||
check for 0, 1, and negative, return codes, and treat all negative
|
||||
return codes as errors.
|
||||
.B pcap_statustostr()
|
||||
.B pcap_statustostr(3PCAP)
|
||||
can be called, with a warning or error code as an argument, to fetch a
|
||||
message describing the warning or error code.
|
||||
.SH SEE ALSO
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
.\"
|
||||
.TH PCAP_COMPILE 3PCAP "24 March 2017"
|
||||
.TH PCAP_COMPILE 3PCAP "22 August 2018"
|
||||
.SH NAME
|
||||
pcap_compile \- compile a filter expression
|
||||
.SH SYNOPSIS
|
||||
@@ -52,7 +52,9 @@ captured; it is used only when checking for IPv4 broadcast addresses in
|
||||
the filter program. If the netmask of the network on which packets are
|
||||
being captured isn't known to the program, or if packets are being
|
||||
captured on the Linux "any" pseudo-interface that can capture on more
|
||||
than one network, a value of PCAP_NETMASK_UNKNOWN can be supplied; tests
|
||||
than one network, a value of
|
||||
.B PCAP_NETMASK_UNKNOWN
|
||||
can be supplied; tests
|
||||
for IPv4 broadcast addresses will fail to compile, but all other tests in
|
||||
the filter program will be OK.
|
||||
.LP
|
||||
@@ -67,14 +69,21 @@ in multiple threads in a single process without some form of mutual
|
||||
exclusion allowing only one thread to call it at any given time.
|
||||
.SH RETURN VALUE
|
||||
.B pcap_compile()
|
||||
returns 0 on success and \-1 on failure.
|
||||
If \-1 is returned,
|
||||
.B pcap_geterr()
|
||||
returns 0 on success and
|
||||
.B PCAP_ERROR
|
||||
on failure. If
|
||||
.B PCAP_ERROR
|
||||
is returned,
|
||||
.B pcap_geterr(3PCAP)
|
||||
or
|
||||
.B pcap_perror()
|
||||
.B pcap_perror(3PCAP)
|
||||
may be called with
|
||||
.I p
|
||||
as an argument to fetch or display the error text.
|
||||
.SH BACKWARD COMPATIBILITY
|
||||
.PP
|
||||
The
|
||||
.B PCAP_NETMASK_UNKNOWN
|
||||
constant became available in libpcap release 1.1.0.
|
||||
.SH SEE ALSO
|
||||
pcap(3PCAP), pcap_setfilter(3PCAP), pcap_freecode(3PCAP),
|
||||
pcap_geterr(3PCAP), pcap-filter(@MAN_MISC_INFO@)
|
||||
|
||||
@@ -48,7 +48,7 @@ argument of "any" or
|
||||
can be used to capture packets from all interfaces.
|
||||
.PP
|
||||
The returned handle must be activated with
|
||||
.B pcap_activate()
|
||||
.B pcap_activate(3PCAP)
|
||||
before packets can be captured
|
||||
with it; options for the capture, such as promiscuous mode, can be set
|
||||
on the handle before activating it.
|
||||
@@ -69,4 +69,4 @@ is assumed to be able to hold at least
|
||||
.B PCAP_ERRBUF_SIZE
|
||||
chars.
|
||||
.SH SEE ALSO
|
||||
pcap(3PCAP), pcap_activate(3PCAP)
|
||||
pcap(3PCAP)
|
||||
|
||||
@@ -37,9 +37,9 @@ specified by
|
||||
.IR p .
|
||||
.PP
|
||||
It must not be called on a pcap descriptor created by
|
||||
.B pcap_create()
|
||||
.B \%pcap_create(3PCAP)
|
||||
that has not yet been activated by
|
||||
.BR pcap_activate() .
|
||||
.BR \%pcap_activate(3PCAP) .
|
||||
.PP
|
||||
.I https://www.tcpdump.org/linktypes.html
|
||||
lists the values
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
.\"
|
||||
.TH PCAP_DATALINK_NAME_TO_VAL 3PCAP "12 October 2016"
|
||||
.TH PCAP_DATALINK_NAME_TO_VAL 3PCAP "25 July 2018"
|
||||
.SH NAME
|
||||
pcap_datalink_name_to_val \- get the link-layer header type value
|
||||
corresponding to a header type name
|
||||
@@ -41,7 +41,9 @@ removed, to the corresponding link-layer header type value. The
|
||||
translation is case-insensitive.
|
||||
.SH RETURN VALUE
|
||||
.B pcap_datalink_name_to_val()
|
||||
returns the type value on success and \-1 if the name is not a known
|
||||
returns the type value on success and
|
||||
.B PCAP_ERROR
|
||||
if the name is not a known
|
||||
type name..
|
||||
.SH SEE ALSO
|
||||
pcap(3PCAP)
|
||||
|
||||
@@ -19,7 +19,8 @@
|
||||
.\"
|
||||
.TH PCAP_DATALINK_VAL_TO_NAME 3PCAP "12 October 2016"
|
||||
.SH NAME
|
||||
pcap_datalink_val_to_name, pcap_datalink_val_to_description \- get a
|
||||
pcap_datalink_val_to_name, pcap_datalink_val_to_description,
|
||||
pcap_datalink_val_to_description_or_dlt \- get a
|
||||
name or description for a link-layer header type value
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
@@ -30,6 +31,7 @@ name or description for a link-layer header type value
|
||||
.ft B
|
||||
const char *pcap_datalink_val_to_name(int dlt);
|
||||
const char *pcap_datalink_val_to_description(int dlt);
|
||||
const char *pcap_datalink_val_to_description_or_dlt(int dlt);
|
||||
.ft
|
||||
.fi
|
||||
.SH DESCRIPTION
|
||||
@@ -52,3 +54,13 @@ link-layer header type.
|
||||
is returned if the type value does not correspond to a known
|
||||
.B DLT_
|
||||
value.
|
||||
.PP
|
||||
.B pcap_datalink_val_to_description_or_dlt()
|
||||
translates a link-layer header type value to a short description of that
|
||||
link-layer header type just like pcap_datalink_val_to_description.
|
||||
If the type value does not correspond to a known
|
||||
.B DLT_
|
||||
value, the string "DLT n" is returned, where n is the value of
|
||||
the dlt argument.
|
||||
.SH SEE ALSO
|
||||
pcap(3PCAP)
|
||||
|
||||
@@ -35,11 +35,11 @@ u_char *sp);
|
||||
.SH DESCRIPTION
|
||||
.B pcap_dump()
|
||||
outputs a packet to the ``savefile'' opened with
|
||||
.BR pcap_dump_open() .
|
||||
.BR pcap_dump_open(3PCAP) .
|
||||
Note that its calling arguments are suitable for use with
|
||||
.B pcap_dispatch()
|
||||
.B pcap_dispatch(3PCAP)
|
||||
or
|
||||
.BR pcap_loop() .
|
||||
.BR pcap_loop(3PCAP) .
|
||||
If called directly, the
|
||||
.I user
|
||||
parameter is of type
|
||||
@@ -47,5 +47,4 @@ parameter is of type
|
||||
as returned by
|
||||
.BR pcap_dump_open() .
|
||||
.SH SEE ALSO
|
||||
pcap(3PCAP), pcap_dump_open(3PCAP), pcap_dispatch(3PCAP),
|
||||
pcap_loop(3PCAP)
|
||||
pcap(3PCAP)
|
||||
|
||||
@@ -33,6 +33,6 @@ FILE *pcap_dump_file(pcap_dumper_t *p);
|
||||
.SH DESCRIPTION
|
||||
.B pcap_dump_file()
|
||||
returns the standard I/O stream of the ``savefile'' opened by
|
||||
.BR pcap_dump_open() .
|
||||
.BR pcap_dump_open(3PCAP) .
|
||||
.SH SEE ALSO
|
||||
pcap(3PCAP)
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
.\"
|
||||
.TH PCAP_DUMP_FLUSH 3PCAP "3 January 2014"
|
||||
.TH PCAP_DUMP_FLUSH 3PCAP "25 July 2018"
|
||||
.SH NAME
|
||||
pcap_dump_flush \- flush to a savefile packets dumped
|
||||
.SH SYNOPSIS
|
||||
@@ -34,10 +34,12 @@ int pcap_dump_flush(pcap_dumper_t *p);
|
||||
.B pcap_dump_flush()
|
||||
flushes the output buffer to the ``savefile,'' so that any packets
|
||||
written with
|
||||
.B pcap_dump()
|
||||
.B pcap_dump(3PCAP)
|
||||
but not yet written to the ``savefile'' will be written.
|
||||
.SH RETURN VALUE
|
||||
.B pcap_dump_flush()
|
||||
returns 0 on success and \-1 on failure.
|
||||
returns 0 on success and
|
||||
.B PCAP_ERROR
|
||||
on failure.
|
||||
.SH SEE ALSO
|
||||
pcap(3PCAP), pcap_dump_open(3PCAP), pcap_dump(3PCAP)
|
||||
pcap(3PCAP), pcap_dump_open(3PCAP)
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
.\"
|
||||
.TH PCAP_DUMP_FTELL 3PCAP "29 September 2017"
|
||||
.TH PCAP_DUMP_FTELL 3PCAP "25 July 2018"
|
||||
.SH NAME
|
||||
pcap_dump_ftell, pcap_dump_ftell64 \- get the current file offset for a savefile being written
|
||||
.SH SYNOPSIS
|
||||
@@ -36,11 +36,11 @@ int64_t pcap_dump_ftell64(pcap_dumper_t *p);
|
||||
.B pcap_dump_ftell()
|
||||
returns the current file position for the ``savefile'', representing the
|
||||
number of bytes written by
|
||||
.B pcap_dump_open()
|
||||
.B pcap_dump_open(3PCAP)
|
||||
and
|
||||
.BR pcap_dump() .
|
||||
\-1 is returned on error.
|
||||
If the current file position does not fit in a
|
||||
.BR pcap_dump(3PCAP) .
|
||||
.B PCAP_ERROR
|
||||
is returned on error. If the current file position does not fit in a
|
||||
.BR long ,
|
||||
it will be truncated; this can happen on 32-bit UNIX-like systems with
|
||||
large file support and on Windows.
|
||||
@@ -52,6 +52,7 @@ so if file offsets that don't fit in a
|
||||
but that fit in a
|
||||
.B int64_t
|
||||
are supported, this will return the file offset without truncation.
|
||||
\-1 is returned on error.
|
||||
.B PCAP_ERROR
|
||||
is returned on error.
|
||||
.SH SEE ALSO
|
||||
pcap(3PCAP), pcap_dump_open(3PCAP), pcap_dump(3PCAP)
|
||||
pcap(3PCAP)
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
.\"
|
||||
.TH PCAP_DUMP_OPEN 3PCAP "22 June 2018"
|
||||
.TH PCAP_DUMP_OPEN 3PCAP "22 August 2018"
|
||||
.SH NAME
|
||||
pcap_dump_open, pcap_dump_fopen \- open a file to which to write packets
|
||||
.SH SYNOPSIS
|
||||
@@ -50,26 +50,26 @@ for
|
||||
is called to write data to an existing open stream
|
||||
.IR fp ;
|
||||
this stream will be closed by a subsequent call to
|
||||
.BR pcap_dump_close() .
|
||||
.BR pcap_dump_close(3PCAP) .
|
||||
Note that on Windows, that stream should be opened in binary mode.
|
||||
.PP
|
||||
.I p
|
||||
is a capture or ``savefile'' handle returned by an earlier call to
|
||||
.B pcap_create()
|
||||
.B pcap_create(3PCAP)
|
||||
and activated by an earlier call to
|
||||
.BR pcap_activate() ,
|
||||
.BR \%pcap_activate(3PCAP) ,
|
||||
or returned by an earlier call to
|
||||
.BR pcap_open_offline() ,
|
||||
.BR pcap_open_live() ,
|
||||
.BR \%pcap_open_offline(3PCAP) ,
|
||||
.BR pcap_open_live(3PCAP) ,
|
||||
or
|
||||
.BR pcap_open_dead() .
|
||||
.BR pcap_open_dead(3PCAP) .
|
||||
The time stamp precision, link-layer type, and snapshot length from
|
||||
.I p
|
||||
are used as the link-layer type and snapshot length of the output file.
|
||||
.PP
|
||||
.B pcap_dump_open_append()
|
||||
is like
|
||||
.B pcap_dump_open
|
||||
.B pcap_dump_open()
|
||||
but does not create the file if it does not exist and, if it does
|
||||
already exist, and is a pcap file with the same byte order as the host
|
||||
opening the file, and has the same time stamp precision, link-layer
|
||||
@@ -80,19 +80,24 @@ it will write new packets at the end of the file.
|
||||
A pointer to a
|
||||
.B pcap_dumper_t
|
||||
structure to use in subsequent
|
||||
.B pcap_dump()
|
||||
.B pcap_dump(3PCAP)
|
||||
and
|
||||
.B pcap_dump_close()
|
||||
.B pcap_dump_close(3PCAP)
|
||||
calls is returned on success.
|
||||
.B NULL
|
||||
is returned on failure.
|
||||
If
|
||||
.B NULL
|
||||
is returned,
|
||||
.B pcap_geterr(\fIp\fB)
|
||||
.B pcap_geterr(3PCAP)
|
||||
can be used to get the error text.
|
||||
.SH BACKWARD COMPATIBILITY
|
||||
.PP
|
||||
The
|
||||
.B pcap_dump_open_append()
|
||||
function became available in libpcap release 1.7.2. In previous
|
||||
releases, there is no support for appending packets to an existing
|
||||
savefile.
|
||||
.SH SEE ALSO
|
||||
pcap(3PCAP), pcap_create(3PCAP), pcap_activate(3PCAP),
|
||||
\%pcap_open_offline(3PCAP), pcap_open_live(3PCAP), pcap_open_dead(3PCAP),
|
||||
pcap_dump(3PCAP), pcap_dump_close(3PCAP), pcap_geterr(3PCAP),
|
||||
pcap(3PCAP),
|
||||
\%pcap-savefile(@MAN_FILE_FORMATS@)
|
||||
|
||||
@@ -34,13 +34,15 @@ FILE *pcap_file(pcap_t *p);
|
||||
.B pcap_file()
|
||||
returns the standard I/O stream of the ``savefile,'' if a ``savefile''
|
||||
was opened with
|
||||
.BR pcap_open_offline() ,
|
||||
or NULL, if a network device was opened with
|
||||
.B pcap_create()
|
||||
.BR pcap_open_offline(3PCAP) ,
|
||||
or
|
||||
.BR NULL ,
|
||||
if a network device was opened with
|
||||
.B pcap_create(3PCAP)
|
||||
and
|
||||
.BR pcap_activate() ,
|
||||
.BR \%pcap_activate(3PCAP) ,
|
||||
or with
|
||||
.BR pcap_open_live() .
|
||||
.BR pcap_open_live(3PCAP) .
|
||||
.PP
|
||||
Note that the Packet Capture library is usually built with large file
|
||||
support, so the standard I/O stream of the ``savefile'' might refer to
|
||||
@@ -50,8 +52,8 @@ should, if possible, use calls that support large files on the return
|
||||
value of
|
||||
.B pcap_file()
|
||||
or the value returned by
|
||||
.B fileno()
|
||||
.B fileno(3)
|
||||
when passed the return value of
|
||||
.BR pcap_file() .
|
||||
.SH SEE ALSO
|
||||
pcap(3PCAP), pcap_open_offline(3PCAP)
|
||||
pcap(3PCAP)
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
.\"
|
||||
.TH PCAP_FILENO 3PCAP "7 April 2014"
|
||||
.TH PCAP_FILENO 3PCAP "25 July 2018"
|
||||
.SH NAME
|
||||
pcap_fileno \- get the file descriptor for a live capture
|
||||
.SH SYNOPSIS
|
||||
@@ -35,32 +35,31 @@ If
|
||||
.I p
|
||||
refers to a network device that was opened for a live capture using
|
||||
a combination of
|
||||
.B pcap_create()
|
||||
.B pcap_create(3PCAP)
|
||||
and
|
||||
.BR pcap_activate() ,
|
||||
.BR pcap_activate(3PCAP) ,
|
||||
or using
|
||||
.BR pcap_open_live() ,
|
||||
.BR pcap_open_live(3PCAP) ,
|
||||
.B pcap_fileno()
|
||||
returns the file descriptor from which captured packets are read.
|
||||
.LP
|
||||
If
|
||||
.I p
|
||||
refers to a ``savefile'' that was opened using functions such as
|
||||
.BR pcap_open_offline()
|
||||
.BR pcap_open_offline(3PCAP)
|
||||
or
|
||||
.BR pcap_fopen_offline() ,
|
||||
.BR pcap_fopen_offline(3PCAP) ,
|
||||
a ``dead''
|
||||
.B pcap_t
|
||||
opened using
|
||||
.BR pcap_open_dead() ,
|
||||
.BR pcap_open_dead(3PCAP) ,
|
||||
or a
|
||||
.B pcap_t
|
||||
that was created with
|
||||
.B pcap_create()
|
||||
but that has not yet been activated with
|
||||
.BR pcap_activate() ,
|
||||
it returns \-1.
|
||||
it returns
|
||||
.BR PCAP_ERROR .
|
||||
.SH SEE ALSO
|
||||
pcap(3PCAP), pcap_create(3PCAP), pcap_activate(3PCAP),
|
||||
pcap_open_live(3PCAP), pcap_open_offline(3PCAP),
|
||||
\%pcap_fopen_offline(3PCAP), pcap_open_dead(3PCAP)
|
||||
pcap(3PCAP)
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
.\"
|
||||
.TH PCAP_FINDALLDEVS 3PCAP "29 April 2018"
|
||||
.TH PCAP_FINDALLDEVS 3PCAP "22 August 2018"
|
||||
.SH NAME
|
||||
pcap_findalldevs, pcap_freealldevs \- get a list of capture devices, and
|
||||
free that list
|
||||
@@ -40,11 +40,11 @@ void pcap_freealldevs(pcap_if_t *alldevs);
|
||||
.SH DESCRIPTION
|
||||
.B pcap_findalldevs()
|
||||
constructs a list of network devices that can be opened with
|
||||
.B pcap_create()
|
||||
.B pcap_create(3PCAP)
|
||||
and
|
||||
.B pcap_activate()
|
||||
.B pcap_activate(3PCAP)
|
||||
or with
|
||||
.BR pcap_open_live() .
|
||||
.BR pcap_open_live(3PCAP) .
|
||||
(Note that there may be network devices that cannot be opened by the
|
||||
process calling
|
||||
.BR pcap_findalldevs() ,
|
||||
@@ -194,21 +194,38 @@ for IPv6 addresses, it can be interpreted as if it pointed to a
|
||||
.BR "struct sockaddr_in6".
|
||||
.PP
|
||||
The list of devices must be freed with
|
||||
.BR pcap_freealldevs() ,
|
||||
.BR pcap_freealldevs(3PCAP) ,
|
||||
which frees the list pointed to by
|
||||
.IR alldevs .
|
||||
.SH RETURN VALUE
|
||||
.B pcap_findalldevs()
|
||||
returns 0 on success and \-1 on failure; as indicated, finding no
|
||||
returns 0 on success and
|
||||
.B PCAP_ERROR
|
||||
on failure; as indicated, finding no
|
||||
devices is considered success, rather than failure, so 0 will be
|
||||
returned in that case.
|
||||
If \-1 is returned,
|
||||
returned in that case. If
|
||||
.B PCAP_ERROR
|
||||
is returned,
|
||||
.I errbuf
|
||||
is filled in with an appropriate error message.
|
||||
.I errbuf
|
||||
is assumed to be able to hold at least
|
||||
.B PCAP_ERRBUF_SIZE
|
||||
chars.
|
||||
.SH BACKWARD COMPATIBILITY
|
||||
.PP
|
||||
The
|
||||
.B PCAP_IF_UP
|
||||
and
|
||||
.B PCAP_IF_RUNNING
|
||||
constants became available in libpcap release 1.6.1. The
|
||||
.BR PCAP_IF_WIRELESS ,
|
||||
.BR PCAP_IF_CONNECTION_STATUS ,
|
||||
.BR PCAP_IF_CONNECTION_STATUS_UNKNOWN ,
|
||||
.BR PCAP_IF_CONNECTION_STATUS_CONNECTED ,
|
||||
.BR PCAP_IF_CONNECTION_STATUS_DISCONNECTED ,
|
||||
and
|
||||
.B PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE
|
||||
constants became available in libpcap release 1.9.0.
|
||||
.SH SEE ALSO
|
||||
pcap(3PCAP), pcap_create(3PCAP), pcap_activate(3PCAP),
|
||||
pcap_open_live(3PCAP)
|
||||
pcap(3PCAP)
|
||||
|
||||
@@ -35,9 +35,9 @@ void pcap_freecode(struct bpf_program *);
|
||||
is used to free up allocated memory pointed to by a
|
||||
.I bpf_program
|
||||
struct generated by
|
||||
.B pcap_compile()
|
||||
.B pcap_compile(3PCAP)
|
||||
when that BPF program is no longer needed, for example after it
|
||||
has been made the filter program for a pcap structure by a call to
|
||||
.BR pcap_setfilter() .
|
||||
.BR pcap_setfilter(3PCAP) .
|
||||
.SH SEE ALSO
|
||||
pcap(3PCAP), pcap_compile(3PCAP), pcap_setfilter(3PCAP)
|
||||
pcap(3PCAP)
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
.\"
|
||||
.TH PCAP_GET_SELECTABLE_FD 3PCAP "20 January 2018"
|
||||
.TH PCAP_GET_SELECTABLE_FD 3PCAP "25 July 2018"
|
||||
.SH NAME
|
||||
pcap_get_selectable_fd \- get a file descriptor on which a select() can
|
||||
be done for a live capture
|
||||
@@ -36,32 +36,38 @@ int pcap_get_selectable_fd(pcap_t *p);
|
||||
returns, on UNIX, a file descriptor number for a file descriptor on
|
||||
which one can
|
||||
do a
|
||||
.BR select() ,
|
||||
.BR poll() ,
|
||||
.BR epoll_wait() ,
|
||||
.BR select(2) ,
|
||||
.BR poll(2) ,
|
||||
.BR epoll_wait(2) ,
|
||||
.BR kevent() ,
|
||||
or other such call
|
||||
to wait for it to be possible to read packets without blocking, if such
|
||||
a descriptor exists, or \-1, if no such descriptor exists.
|
||||
a descriptor exists, or
|
||||
.BR PCAP_ERROR ,
|
||||
if no such descriptor exists.
|
||||
.PP
|
||||
Some network devices opened with
|
||||
.B pcap_create()
|
||||
.B pcap_create(3PCAP)
|
||||
and
|
||||
.BR pcap_activate() ,
|
||||
.BR pcap_activate(3PCAP) ,
|
||||
or with
|
||||
.BR pcap_open_live() ,
|
||||
.BR pcap_open_live(3PCAP) ,
|
||||
do not support those calls (for example, regular network devices on
|
||||
FreeBSD 4.3 and 4.4, and Endace DAG devices), so \-1 is returned for
|
||||
FreeBSD 4.3 and 4.4, and Endace DAG devices), so
|
||||
.B PCAP_ERROR
|
||||
is returned for
|
||||
those devices. In that case, those calls must be given a timeout less
|
||||
than or equal to the timeout returned by
|
||||
.B pcap_get_required_select_timeout()
|
||||
.B pcap_get_required_select_timeout(3PCAP)
|
||||
for the device for which
|
||||
.B pcap_get_selectable_fd()
|
||||
returned \-1, the device must be put in non-blocking mode with a call to
|
||||
.BR pcap_setnonblock() ,
|
||||
returned
|
||||
.BR PCAP_ERROR ,
|
||||
the device must be put in non-blocking mode with a call to
|
||||
.BR \%pcap_setnonblock(3PCAP) ,
|
||||
and an attempt must always be made to read packets from the device
|
||||
when the call returns. If
|
||||
.B pcap_get_required_select_timeout()
|
||||
.B \%pcap_get_required_select_timeout()
|
||||
returns
|
||||
.BR NULL ,
|
||||
it is not possible to wait for packets to arrive on the device in an
|
||||
@@ -70,9 +76,9 @@ event loop.
|
||||
Note that a device on which a read can be done without blocking may,
|
||||
on some platforms, not have any packets to read if the packet buffer
|
||||
timeout has expired. A call to
|
||||
.B pcap_dispatch()
|
||||
.B pcap_dispatch(3PCAP)
|
||||
or
|
||||
.B pcap_next_ex()
|
||||
.B pcap_next_ex(3PCAP)
|
||||
will return 0 in this case, but will not block.
|
||||
.PP
|
||||
Note that in:
|
||||
@@ -138,8 +144,8 @@ work on that descriptor in Mac OS X 10.6 and later.
|
||||
.B pcap_get_selectable_fd()
|
||||
is not available on Windows.
|
||||
.SH RETURN VALUE
|
||||
A selectable file descriptor is returned if one exists; otherwise, \-1
|
||||
A selectable file descriptor is returned if one exists; otherwise,
|
||||
.B PCAP_ERROR
|
||||
is returned.
|
||||
.SH SEE ALSO
|
||||
pcap(3PCAP), pcap_get_required_select_timeout(3PCAP),
|
||||
pcap_setnonblock(3PCAP), select(2), poll(2), epoll_wait(2), kqueue(2)
|
||||
pcap(3PCAP), kqueue(2)
|
||||
|
||||
@@ -46,6 +46,10 @@ or
|
||||
which indicates
|
||||
that pcap captures contains time stamps in microseconds or nanoseconds
|
||||
respectively.
|
||||
.SH BACKWARD COMPATIBILITY
|
||||
This function became available in libpcap release 1.5.1. In previous
|
||||
releases, time stamps from a capture device or savefile are always given
|
||||
in seconds and microseconds.
|
||||
.SH SEE ALSO
|
||||
pcap(3PCAP),
|
||||
pcap_set_tstamp_precision(3PCAP),
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
.\"
|
||||
.TH PCAP_INJECT 3PCAP "3 January 2014"
|
||||
.TH PCAP_INJECT 3PCAP "25 July 2018"
|
||||
.SH NAME
|
||||
pcap_inject, pcap_sendpacket \- transmit a packet
|
||||
.SH SYNOPSIS
|
||||
@@ -42,7 +42,7 @@ is the number of bytes in the packet.
|
||||
Note that, even if you successfully open the network interface, you
|
||||
might not have permission to send packets on it, or it might not support
|
||||
sending packets; as
|
||||
.I pcap_open_live()
|
||||
.B pcap_open_live(3PCAP)
|
||||
doesn't have a flag to indicate whether to open for capturing, sending,
|
||||
or capturing and sending, you cannot request an open that supports
|
||||
sending and be notified at open time whether sending will be possible.
|
||||
@@ -72,17 +72,23 @@ comes from OpenBSD;
|
||||
comes from WinPcap. Both are provided for compatibility.)
|
||||
.SH RETURN VALUE
|
||||
.B pcap_inject()
|
||||
returns the number of bytes written on success and \-1 on failure.
|
||||
returns the number of bytes written on success and
|
||||
.B PCAP_ERROR
|
||||
on failure.
|
||||
.PP
|
||||
.B pcap_sendpacket()
|
||||
returns 0 on success and \-1 on failure.
|
||||
returns 0 on success and
|
||||
.B PCAP_ERROR
|
||||
on failure.
|
||||
.PP
|
||||
If \-1 is returned,
|
||||
.B pcap_geterr()
|
||||
If
|
||||
.B PCAP_ERROR
|
||||
is returned,
|
||||
.B pcap_geterr(3PCAP)
|
||||
or
|
||||
.B pcap_perror()
|
||||
.B pcap_perror(3PCAP)
|
||||
may be called with
|
||||
.I p
|
||||
as an argument to fetch or display the error text.
|
||||
.SH SEE ALSO
|
||||
pcap(3PCAP), pcap_geterr(3PCAP)
|
||||
pcap(3PCAP)
|
||||
|
||||
@@ -39,9 +39,9 @@ than the current system. For a live capture, it always returns false
|
||||
(0).
|
||||
.PP
|
||||
It must not be called on a pcap descriptor created by
|
||||
.B pcap_create()
|
||||
.B \%pcap_create(3PCAP)
|
||||
that has not yet been activated by
|
||||
.BR pcap_activate() .
|
||||
.BR \%pcap_activate(3PCAP) .
|
||||
.SH RETURN VALUE
|
||||
.B pcap_is_swapped()
|
||||
returns true (1) or false (0) on success and
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
.\"
|
||||
.TH PCAP_LIST_DATALINKS 3PCAP "8 March 2015"
|
||||
.TH PCAP_LIST_DATALINKS 3PCAP "25 July 2018"
|
||||
.SH NAME
|
||||
pcap_list_datalinks, pcap_free_datalinks \- get a list of link-layer header
|
||||
types supported by a capture device, and free that list
|
||||
@@ -47,9 +47,9 @@ which frees the list of link-layer header types pointed to by
|
||||
.IR dlt_list .
|
||||
.LP
|
||||
It must not be called on a pcap descriptor created by
|
||||
.B pcap_create()
|
||||
.B \%pcap_create(3PCAP)
|
||||
that has not yet been activated by
|
||||
.BR pcap_activate() .
|
||||
.BR \%pcap_activate(3PCAP) .
|
||||
.SH RETURN VALUE
|
||||
.B pcap_list_datalinks()
|
||||
returns the number of link-layer header types in the array on success,
|
||||
@@ -57,17 +57,17 @@ returns the number of link-layer header types in the array on success,
|
||||
if called on a capture handle that has been created but not activated,
|
||||
and
|
||||
.B PCAP_ERROR
|
||||
(\-1) on other errors.
|
||||
on other errors.
|
||||
If
|
||||
.B PCAP_ERROR
|
||||
is returned,
|
||||
.B pcap_geterr()
|
||||
.B pcap_geterr(3PCAP)
|
||||
or
|
||||
.B pcap_perror()
|
||||
.B \%pcap_perror(3PCAP)
|
||||
may be called with
|
||||
.I p
|
||||
as an argument to fetch or display the error text.
|
||||
.SH SEE ALSO
|
||||
pcap(3PCAP), pcap_geterr(3PCAP),
|
||||
pcap(3PCAP),
|
||||
pcap_datalink_val_to_name(3PCAP),
|
||||
pcap-linktype(@MAN_MISC_INFO@)
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
.\"
|
||||
.TH PCAP_LIST_TSTAMP_TYPES 3PCAP "22 August 2010"
|
||||
.TH PCAP_LIST_TSTAMP_TYPES 3PCAP "22 August 2018"
|
||||
.SH NAME
|
||||
pcap_list_tstamp_types, pcap_free_tstamp_types \- get a list of time
|
||||
stamp types supported by a capture device, and free that list
|
||||
@@ -54,17 +54,28 @@ which frees the list pointed to by
|
||||
returns the number of time stamp types in the array on success and
|
||||
.B PCAP_ERROR
|
||||
on failure.
|
||||
A return value of zero means that you cannot specify a time stamp type;
|
||||
you are limited to the capture device's default time stamp type.
|
||||
A return value of one means that the only time stamp type supported is
|
||||
the one in the list, which is the capture device's default time stamp
|
||||
type. A return value of zero means that the only time stamp type
|
||||
supported is
|
||||
.BR PCAP_TSTAMP_HOST ,
|
||||
which is the capture device's default time stamp type (only older
|
||||
versions of libpcap will return that; newer versions will always return
|
||||
one or more types).
|
||||
If
|
||||
.B PCAP_ERROR
|
||||
is returned,
|
||||
.B pcap_geterr()
|
||||
.B pcap_geterr(3PCAP)
|
||||
or
|
||||
.B pcap_perror()
|
||||
.B pcap_perror(3PCAP)
|
||||
may be called with
|
||||
.I p
|
||||
as an argument to fetch or display the error text.
|
||||
.SH BACKWARD COMPATIBILITY
|
||||
.PP
|
||||
These functions became available in libpcap release 1.2.1. In previous
|
||||
releases, the time stamp type cannot be set; only the default time stamp
|
||||
type offered by a capture source is available.
|
||||
.SH SEE ALSO
|
||||
pcap(3PCAP), pcap_geterr(3PCAP), pcap_tstamp_type_val_to_name(3PCAP),
|
||||
pcap(3PCAP), pcap_tstamp_type_val_to_name(3PCAP),
|
||||
pcap-tstamp(@MAN_MISC_INFO@)
|
||||
|
||||
@@ -47,13 +47,13 @@ possible.)
|
||||
.B pcap_lookupdev()
|
||||
returns a pointer to a string giving the name of a network device
|
||||
suitable for use with
|
||||
.B pcap_create()
|
||||
.B pcap_create(3PCAP)
|
||||
and
|
||||
.BR pcap_activate() ,
|
||||
.BR \%pcap_activate(3PCAP) ,
|
||||
or with
|
||||
.BR pcap_open_live() ,
|
||||
.BR pcap_open_live(3PCAP) ,
|
||||
and with
|
||||
.BR pcap_lookupnet() .
|
||||
.BR pcap_lookupnet(3PCAP) .
|
||||
If there is an error,
|
||||
.B NULL
|
||||
is returned and
|
||||
@@ -64,8 +64,7 @@ is assumed to be able to hold at least
|
||||
.B PCAP_ERRBUF_SIZE
|
||||
chars.
|
||||
.SH SEE ALSO
|
||||
pcap(3PCAP), pcap_create(3PCAP), pcap_activate(3PCAP),
|
||||
pcap_open_live(3PCAP), pcap_lookupnet(3PCAP)
|
||||
pcap(3PCAP)
|
||||
.SH BUGS
|
||||
The pointer returned by
|
||||
.B pcap_lookupdev()
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
.\"
|
||||
.TH PCAP_LOOKUPNET 3PCAP "3 January 2014"
|
||||
.TH PCAP_LOOKUPNET 3PCAP "25 July 2018"
|
||||
.SH NAME
|
||||
pcap_lookupnet \- find the IPv4 network number and netmask for a device
|
||||
.SH SYNOPSIS
|
||||
@@ -51,8 +51,11 @@ are
|
||||
pointers.
|
||||
.SH RETURN VALUE
|
||||
.B pcap_lookupnet()
|
||||
returns 0 on success and \-1 on failure.
|
||||
If \-1 is returned,
|
||||
returns 0 on success and
|
||||
.B PCAP_ERROR
|
||||
on failure. If
|
||||
.B PCAP_ERROR
|
||||
is returned,
|
||||
.I errbuf
|
||||
is filled in with an appropriate error message.
|
||||
.I errbuf
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
.\"
|
||||
.TH PCAP_LOOP 3PCAP "20 January 2017"
|
||||
.TH PCAP_LOOP 3PCAP "25 July 2018"
|
||||
.SH NAME
|
||||
pcap_loop, pcap_dispatch \- process packets from a live capture or savefile
|
||||
.SH SYNOPSIS
|
||||
@@ -47,7 +47,7 @@ processes packets from a live capture or ``savefile'' until
|
||||
.I cnt
|
||||
packets are processed, the end of the ``savefile'' is
|
||||
reached when reading from a ``savefile'',
|
||||
.B pcap_breakloop()
|
||||
.B pcap_breakloop(3PCAP)
|
||||
is called, or an error occurs.
|
||||
It does
|
||||
.B not
|
||||
@@ -123,7 +123,7 @@ them.
|
||||
.PP
|
||||
The bytes of data from the packet begin with a link-layer header. The
|
||||
format of the link-layer header is indicated by the return value of the
|
||||
.B pcap_datalink()
|
||||
.B pcap_datalink(3PCAP)
|
||||
routine when handed the
|
||||
.B pcap_t
|
||||
value also passed to
|
||||
@@ -136,7 +136,7 @@ lists the values
|
||||
can return and describes the packet formats that
|
||||
correspond to those values. The value it returns will be valid for all
|
||||
packets received unless and until
|
||||
.B pcap_set_datalink()
|
||||
.B pcap_set_datalink(3PCAP)
|
||||
is called; after a successful call to
|
||||
.BR pcap_set_datalink() ,
|
||||
all subsequent packets will have a link-layer header of the type
|
||||
@@ -160,8 +160,11 @@ for Ethernet.
|
||||
returns 0 if
|
||||
.I cnt
|
||||
is exhausted or if, when reading from a ``savefile'', no more packets
|
||||
are available. It returns \-1 if an error occurs or \-2 if the loop
|
||||
terminated due to a call to
|
||||
are available. It returns
|
||||
.B PCAP_ERROR
|
||||
if an error occurs or
|
||||
.B PCAP_ERROR_BREAK
|
||||
if the loop terminated due to a call to
|
||||
.B pcap_breakloop()
|
||||
before any packets were processed.
|
||||
It does
|
||||
@@ -177,23 +180,27 @@ platforms that support a packet buffer timeout that starts before any
|
||||
packets arrive, the timeout expires before any packets arrive, or if the
|
||||
file descriptor for the capture device is in non-blocking mode and no
|
||||
packets were available to be read) or if no more packets are available
|
||||
in a ``savefile.'' It returns \-1 if an error occurs or \-2 if the loop
|
||||
terminated due to a call to
|
||||
in a ``savefile.'' It returns
|
||||
.B PCAP_ERROR
|
||||
if an error occurs or
|
||||
.B PCAP_ERROR_BREAK
|
||||
if the loop terminated due to a call to
|
||||
.B pcap_breakloop()
|
||||
before any packets were processed.
|
||||
.ft B
|
||||
If your application uses pcap_breakloop(),
|
||||
make sure that you explicitly check for \-1 and \-2, rather than just
|
||||
checking for a return value < 0.
|
||||
make sure that you explicitly check for PCAP_ERROR and PCAP_ERROR_BREAK,
|
||||
rather than just checking for a return value < 0.
|
||||
.ft R
|
||||
.PP
|
||||
If \-1 is returned,
|
||||
.B pcap_geterr()
|
||||
If
|
||||
.B PCAP_ERROR
|
||||
is returned,
|
||||
.B pcap_geterr(3PCAP)
|
||||
or
|
||||
.B pcap_perror()
|
||||
.B pcap_perror(3PCAP)
|
||||
may be called with
|
||||
.I p
|
||||
as an argument to fetch or display the error text.
|
||||
.SH SEE ALSO
|
||||
pcap(3PCAP), pcap_geterr(3PCAP), pcap_breakloop(3PCAP),
|
||||
pcap_datalink(3PCAP)
|
||||
pcap(3PCAP)
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
.\"
|
||||
.TH PCAP_NEXT_EX 3PCAP "20 January 2017"
|
||||
.TH PCAP_NEXT_EX 3PCAP "25 July 2018"
|
||||
.SH NAME
|
||||
pcap_next_ex, pcap_next \- read the next packet from a pcap_t
|
||||
.SH SYNOPSIS
|
||||
@@ -49,9 +49,9 @@ and the packet data are not to be freed by the caller, and are not
|
||||
guaranteed to be valid after the next call to
|
||||
.BR pcap_next_ex() ,
|
||||
.BR pcap_next() ,
|
||||
.BR pcap_loop() ,
|
||||
.BR pcap_loop(3PCAP) ,
|
||||
or
|
||||
.BR pcap_dispatch() ;
|
||||
.BR pcap_dispatch(3PCAP) ;
|
||||
if the code needs them to remain valid, it must make a copy of them.
|
||||
.PP
|
||||
.B pcap_next()
|
||||
@@ -78,7 +78,7 @@ is filled in with the appropriate values for the packet.
|
||||
.PP
|
||||
The bytes of data from the packet begin with a link-layer header. The
|
||||
format of the link-layer header is indicated by the return value of the
|
||||
.B pcap_datalink()
|
||||
.B pcap_datalink(PCAP)
|
||||
routine when handed the
|
||||
.B pcap_t
|
||||
value also passed to
|
||||
@@ -91,7 +91,7 @@ lists the values
|
||||
can return and describes the packet formats that
|
||||
correspond to those values. The value it returns will be valid for all
|
||||
packets received unless and until
|
||||
.B pcap_set_datalink()
|
||||
.B pcap_set_datalink(3PCAP)
|
||||
is called; after a successful call to
|
||||
.BR pcap_set_datalink() ,
|
||||
all subsequent packets will have a link-layer header of the type
|
||||
@@ -114,12 +114,17 @@ for Ethernet.
|
||||
.B pcap_next_ex()
|
||||
returns 1 if the packet was read without problems, 0 if packets are
|
||||
being read from a live capture and the packet buffer timeout expired,
|
||||
\-1 if an error occurred while reading the packet, and \-2 if packets
|
||||
.B PCAP_ERROR
|
||||
if an error occurred while reading the packet, and
|
||||
.B PCAP_ERROR_BREAK
|
||||
if packets
|
||||
are being read from a ``savefile'' and there are no more packets to read
|
||||
from the savefile. If \-1 is returned,
|
||||
.B pcap_geterr()
|
||||
from the savefile. If
|
||||
.B PCAP_ERROR
|
||||
is returned,
|
||||
.B pcap_geterr(3PCAP)
|
||||
or
|
||||
.B pcap_perror()
|
||||
.B pcap_perror(3PCAP)
|
||||
may be called with
|
||||
.I p
|
||||
as an argument to fetch or display the error text.
|
||||
@@ -136,5 +141,4 @@ non-blocking mode and no packets were available to be read), or if no
|
||||
more packets are available in a ``savefile.'' Unfortunately, there is no
|
||||
way to determine whether an error occurred or not.
|
||||
.SH SEE ALSO
|
||||
pcap(3PCAP), pcap_geterr(3PCAP), pcap_dispatch(3PCAP),
|
||||
pcap_datalink(3PCAP)
|
||||
pcap(3PCAP)
|
||||
|
||||
@@ -39,7 +39,7 @@ checks whether a filter matches a packet.
|
||||
is a pointer to a
|
||||
.I bpf_program
|
||||
struct, usually the result of a call to
|
||||
.BR pcap_compile() .
|
||||
.BR pcap_compile(3PCAP) .
|
||||
.I h
|
||||
points to the
|
||||
.I pcap_pkthdr
|
||||
@@ -52,4 +52,4 @@ returns the return value of the filter program. This will be zero if
|
||||
the packet doesn't match the filter and non-zero if the packet matches
|
||||
the filter.
|
||||
.SH SEE ALSO
|
||||
pcap(3PCAP), pcap_compile(3PCAP)
|
||||
pcap(3PCAP)
|
||||
|
||||
@@ -43,10 +43,10 @@ are used for creating a
|
||||
structure to use when calling the other functions in libpcap. It is
|
||||
typically used when just using libpcap for compiling BPF code; it can
|
||||
also be used if using
|
||||
.BR pcap_dump_open() ,
|
||||
.BR pcap_dump() ,
|
||||
.BR pcap_dump_open(3PCAP) ,
|
||||
.BR pcap_dump(3PCAP) ,
|
||||
and
|
||||
.B pcap_dump_close()
|
||||
.B pcap_dump_close(3PCAP)
|
||||
to write a savefile if there is no
|
||||
.B pcap_t
|
||||
that supplies the packets to be written.
|
||||
@@ -73,7 +73,6 @@ seconds and microseconds, and
|
||||
.B PCAP_TSTAMP_PRECISION_NANO
|
||||
should be specified if the packets to be written have time stamps in
|
||||
seconds and nanoseconds. Its value does not affect
|
||||
.BR pcap_compile() .
|
||||
.BR pcap_compile(3PCAP) .
|
||||
.SH SEE ALSO
|
||||
pcap(3PCAP), pcap_compile(3PCAP), pcap_dump_open(3PCAP),
|
||||
\%pcap-linktype(@MAN_MISC_INFO@)
|
||||
pcap(3PCAP), \%pcap-linktype(@MAN_MISC_INFO@)
|
||||
|
||||
@@ -87,4 +87,4 @@ is assumed to be able to hold at least
|
||||
.B PCAP_ERRBUF_SIZE
|
||||
chars.
|
||||
.SH SEE ALSO
|
||||
pcap(3PCAP), pcap_create(3PCAP), pcap_activate(3PCAP)
|
||||
pcap_create(3PCAP), pcap_activate(3PCAP)
|
||||
|
||||
@@ -81,7 +81,8 @@ or
|
||||
.B pcap_fopen_offline_with_tstamp_precision()
|
||||
to read dumped data from an existing open stream
|
||||
.IR fp .
|
||||
.B pcap_fopen_offline_with_tstamp_precision() takes an additional
|
||||
.B pcap_fopen_offline_with_tstamp_precision()
|
||||
takes an additional
|
||||
.I precision
|
||||
argument as described above.
|
||||
Note that on Windows, that stream should be opened in binary mode.
|
||||
@@ -105,5 +106,11 @@ is filled in with an appropriate error message.
|
||||
is assumed to be able to hold at least
|
||||
.B PCAP_ERRBUF_SIZE
|
||||
chars.
|
||||
.SH BACKWARD COMPATIBILITY
|
||||
.B pcap_open_offline_with_tstamp_precision
|
||||
and
|
||||
.B pcap_fopen_offline_with_tstamp_precision
|
||||
became available in libpcap release 1.5.1. In previous releases, time
|
||||
stamps from a savefile are always given in seconds and microseconds.
|
||||
.SH SEE ALSO
|
||||
pcap(3PCAP), pcap-savefile(@MAN_FILE_FORMATS@)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user