summaryrefslogtreecommitdiff
path: root/contrib/libpcap
diff options
context:
space:
mode:
authorHans Petter Selasky <hselasky@FreeBSD.org>2018-05-28 08:12:18 +0000
committerHans Petter Selasky <hselasky@FreeBSD.org>2018-05-28 08:12:18 +0000
commitb00ab7548b418624b6719ab8a2e8aaeade767a70 (patch)
treea300b8fb3f3e9cbbd48c47fde148dcb40453e7de /contrib/libpcap
parent7e3d9013f2ff9291970339df66a18ad9343ed433 (diff)
parentd109bf9e4b609b5a0626b433e56db4a47dc530bb (diff)
downloadsrc-test-b00ab7548b418624b6719ab8a2e8aaeade767a70.tar.gz
src-test-b00ab7548b418624b6719ab8a2e8aaeade767a70.zip
MFV r333789: libpcap 1.9.0 (pre-release)
MFC after: 1 month Sponsored by: Mellanox Technologies
Notes
Notes: svn path=/head/; revision=334277
Diffstat (limited to 'contrib/libpcap')
-rw-r--r--contrib/libpcap/.cvsignore13
-rw-r--r--contrib/libpcap/CHANGES27
-rw-r--r--contrib/libpcap/CMakeLists.txt2294
-rw-r--r--contrib/libpcap/CONTRIBUTING29
-rw-r--r--contrib/libpcap/CREDITS2
-rwxr-xr-xcontrib/libpcap/ChmodBPF/ChmodBPF33
-rw-r--r--contrib/libpcap/ChmodBPF/StartupParameters.plist4
-rw-r--r--contrib/libpcap/INSTALL.txt25
-rw-r--r--contrib/libpcap/Makefile.in265
-rw-r--r--contrib/libpcap/README53
-rw-r--r--contrib/libpcap/README.Win3246
-rw-r--r--contrib/libpcap/README.aix88
-rw-r--r--contrib/libpcap/README.dag122
-rw-r--r--contrib/libpcap/README.hpux254
-rw-r--r--contrib/libpcap/README.linux108
-rw-r--r--contrib/libpcap/README.macos74
-rw-r--r--contrib/libpcap/README.septel50
-rw-r--r--contrib/libpcap/README.sita64
-rw-r--r--contrib/libpcap/README.tru6449
-rw-r--r--contrib/libpcap/VERSION2
-rw-r--r--contrib/libpcap/Win32/Prj/wpcap.sln28
-rw-r--r--contrib/libpcap/Win32/Prj/wpcap.vcxproj233
-rw-r--r--contrib/libpcap/Win32/Prj/wpcap.vcxproj.filters107
-rw-r--r--contrib/libpcap/acconfig.h7
-rw-r--r--contrib/libpcap/aclocal.m41006
-rw-r--r--contrib/libpcap/bpf_dump.c7
-rw-r--r--contrib/libpcap/bpf_filter.c (renamed from contrib/libpcap/bpf/net/bpf_filter.c)296
-rw-r--r--contrib/libpcap/bpf_image.c158
-rwxr-xr-xcontrib/libpcap/chmod_bpf2
-rw-r--r--contrib/libpcap/cmake/Modules/FindDAG.cmake32
-rw-r--r--contrib/libpcap/cmake/Modules/FindFseeko.cmake85
-rw-r--r--contrib/libpcap/cmake/Modules/FindLFS.cmake153
-rw-r--r--contrib/libpcap/cmake/Modules/FindPacket.cmake81
-rw-r--r--contrib/libpcap/cmake/Modules/FindPthreads-w32.cmake152
-rw-r--r--contrib/libpcap/cmake/Modules/FindSNF.cmake24
-rw-r--r--contrib/libpcap/cmake/Modules/FindTC.cmake24
-rw-r--r--contrib/libpcap/cmake/have_siocglifconf.c (renamed from contrib/libpcap/config/have_siocglifconf.c)0
-rw-r--r--contrib/libpcap/cmake_uninstall.cmake.in21
-rw-r--r--contrib/libpcap/cmakeconfig.h.in366
-rw-r--r--contrib/libpcap/config.h.in203
-rwxr-xr-xcontrib/libpcap/configure3857
-rw-r--r--contrib/libpcap/configure.ac1428
-rw-r--r--contrib/libpcap/diag-control.h215
-rw-r--r--contrib/libpcap/dlpisubs.c18
-rw-r--r--contrib/libpcap/etherent.c79
-rw-r--r--contrib/libpcap/extract.h16
-rw-r--r--contrib/libpcap/fad-getad.c40
-rw-r--r--contrib/libpcap/fad-gifc.c89
-rw-r--r--contrib/libpcap/fad-glifc.c73
-rw-r--r--contrib/libpcap/fad-helpers.c884
-rw-r--r--contrib/libpcap/fad-win32.c248
-rw-r--r--contrib/libpcap/fmtutils.c131
-rw-r--r--contrib/libpcap/fmtutils.h50
-rw-r--r--contrib/libpcap/ftmacros.h115
-rwxr-xr-xcontrib/libpcap/gen_version_c.sh11
-rwxr-xr-xcontrib/libpcap/gen_version_header.sh19
-rw-r--r--contrib/libpcap/gencode.c809
-rw-r--r--contrib/libpcap/gencode.h42
-rw-r--r--contrib/libpcap/grammar.y66
-rw-r--r--contrib/libpcap/ieee80211.h2
-rw-r--r--contrib/libpcap/inet.c407
-rw-r--r--contrib/libpcap/libpcap.pc.in18
-rw-r--r--contrib/libpcap/missing/getopt.c5
-rw-r--r--contrib/libpcap/missing/getopt.h2
-rw-r--r--contrib/libpcap/missing/strtok_r.c2
-rw-r--r--contrib/libpcap/msdos/bin2c.c43
-rw-r--r--contrib/libpcap/msdos/makefile180
-rw-r--r--contrib/libpcap/msdos/makefile.dj127
-rw-r--r--contrib/libpcap/msdos/makefile.wc132
-rw-r--r--contrib/libpcap/msdos/pkt_rx0.asm197
-rw-r--r--contrib/libpcap/msdos/pkt_rx1.s155
-rw-r--r--contrib/libpcap/msdos/pktdrvr.c1436
-rw-r--r--contrib/libpcap/msdos/pktdrvr.h153
-rw-r--r--contrib/libpcap/msdos/readme.dos166
-rw-r--r--contrib/libpcap/nametoaddr.c440
-rw-r--r--contrib/libpcap/nomkdep6
-rw-r--r--contrib/libpcap/optimize.c266
-rw-r--r--contrib/libpcap/optimize.h28
-rw-r--r--contrib/libpcap/org.tcpdump.chmod_bpf.plist16
-rw-r--r--contrib/libpcap/packaging/pcap.spec.in77
-rw-r--r--contrib/libpcap/pcap-bpf.c626
-rw-r--r--contrib/libpcap/pcap-bt-linux.c83
-rw-r--r--contrib/libpcap/pcap-bt-linux.h2
-rw-r--r--contrib/libpcap/pcap-bt-monitor-linux.c48
-rw-r--r--contrib/libpcap/pcap-bt-monitor-linux.h2
-rw-r--r--contrib/libpcap/pcap-common.c132
-rw-r--r--contrib/libpcap/pcap-common.h24
-rw-r--r--contrib/libpcap/pcap-config.in9
-rw-r--r--contrib/libpcap/pcap-dag.c743
-rw-r--r--contrib/libpcap/pcap-dag.h2
-rw-r--r--contrib/libpcap/pcap-dbus.c88
-rw-r--r--contrib/libpcap/pcap-dbus.h2
-rw-r--r--contrib/libpcap/pcap-dll.rc36
-rw-r--r--contrib/libpcap/pcap-dlpi.c246
-rw-r--r--contrib/libpcap/pcap-dos.c70
-rw-r--r--contrib/libpcap/pcap-enet.c2
-rw-r--r--contrib/libpcap/pcap-filter.manmisc1017
-rw-r--r--contrib/libpcap/pcap-filter.manmisc.in35
-rw-r--r--contrib/libpcap/pcap-int.h156
-rw-r--r--contrib/libpcap/pcap-libdlpi.c72
-rw-r--r--contrib/libpcap/pcap-linktype.manmisc48
-rw-r--r--contrib/libpcap/pcap-linux.c850
-rw-r--r--contrib/libpcap/pcap-netfilter-linux.c207
-rw-r--r--contrib/libpcap/pcap-netfilter-linux.h2
-rw-r--r--contrib/libpcap/pcap-netmap.c306
-rw-r--r--contrib/libpcap/pcap-netmap.h2
-rw-r--r--contrib/libpcap/pcap-new.c1085
-rw-r--r--contrib/libpcap/pcap-nit.c61
-rw-r--r--contrib/libpcap/pcap-npf.c (renamed from contrib/libpcap/pcap-win32.c)1140
-rw-r--r--contrib/libpcap/pcap-null.c30
-rw-r--r--contrib/libpcap/pcap-pf.c113
-rw-r--r--contrib/libpcap/pcap-rdmasniff.c436
-rw-r--r--contrib/libpcap/pcap-rdmasniff.h2
-rw-r--r--contrib/libpcap/pcap-rpcap-int.h75
-rw-r--r--contrib/libpcap/pcap-rpcap.c3325
-rw-r--r--contrib/libpcap/pcap-rpcap.h478
-rw-r--r--contrib/libpcap/pcap-savefile.manfile133
-rw-r--r--contrib/libpcap/pcap-septel.c70
-rw-r--r--contrib/libpcap/pcap-septel.h2
-rw-r--r--contrib/libpcap/pcap-sita.c72
-rw-r--r--contrib/libpcap/pcap-snf.c355
-rw-r--r--contrib/libpcap/pcap-snf.h2
-rw-r--r--contrib/libpcap/pcap-snit.c102
-rw-r--r--contrib/libpcap/pcap-snoop.c80
-rw-r--r--contrib/libpcap/pcap-stdinc.h126
-rw-r--r--contrib/libpcap/pcap-tc.c71
-rw-r--r--contrib/libpcap/pcap-tc.h2
-rw-r--r--contrib/libpcap/pcap-tstamp.manmisc132
-rw-r--r--contrib/libpcap/pcap-tstamp.manmisc.in6
-rw-r--r--contrib/libpcap/pcap-types.h50
-rw-r--r--contrib/libpcap/pcap-usb-linux.c443
-rw-r--r--contrib/libpcap/pcap-usb-linux.h2
-rw-r--r--contrib/libpcap/pcap.3pcap905
-rw-r--r--contrib/libpcap/pcap.3pcap.in88
-rw-r--r--contrib/libpcap/pcap.c2375
-rw-r--r--contrib/libpcap/pcap/bluetooth.h9
-rw-r--r--contrib/libpcap/pcap/bpf.h8
-rw-r--r--contrib/libpcap/pcap/can_socketcan.h12
-rw-r--r--contrib/libpcap/pcap/compiler-tests.h163
-rw-r--r--contrib/libpcap/pcap/dlt.h99
-rw-r--r--contrib/libpcap/pcap/export-defs.h108
-rw-r--r--contrib/libpcap/pcap/funcattrs.h261
-rw-r--r--contrib/libpcap/pcap/namedb.h2
-rw-r--r--contrib/libpcap/pcap/nflog.h28
-rw-r--r--contrib/libpcap/pcap/pcap-inttypes.h117
-rw-r--r--contrib/libpcap/pcap/pcap.h473
-rw-r--r--contrib/libpcap/pcap/sll.h12
-rw-r--r--contrib/libpcap/pcap/usb.h54
-rw-r--r--contrib/libpcap/pcap/vlan.h6
-rw-r--r--contrib/libpcap/pcap_breakloop.3pcap16
-rw-r--r--contrib/libpcap/pcap_compile.3pcap70
-rw-r--r--contrib/libpcap/pcap_compile.3pcap.in10
-rw-r--r--contrib/libpcap/pcap_datalink.3pcap68
-rw-r--r--contrib/libpcap/pcap_dump_ftell.3pcap17
-rw-r--r--contrib/libpcap/pcap_dump_open.3pcap85
-rw-r--r--contrib/libpcap/pcap_dump_open.3pcap.in4
-rw-r--r--contrib/libpcap/pcap_fileno.3pcap2
-rw-r--r--contrib/libpcap/pcap_findalldevs.3pcap24
-rw-r--r--contrib/libpcap/pcap_get_required_select_timeout.3pcap84
-rw-r--r--contrib/libpcap/pcap_get_selectable_fd.3pcap96
-rw-r--r--contrib/libpcap/pcap_get_tstamp_precision.3pcap52
-rw-r--r--contrib/libpcap/pcap_list_datalinks.3pcap73
-rw-r--r--contrib/libpcap/pcap_list_tstamp_types.3pcap70
-rw-r--r--contrib/libpcap/pcap_lookupdev.3pcap22
-rw-r--r--contrib/libpcap/pcap_loop.3pcap18
-rw-r--r--contrib/libpcap/pcap_major_version.3pcap2
-rw-r--r--contrib/libpcap/pcap_next_ex.3pcap27
-rw-r--r--contrib/libpcap/pcap_open_dead.3pcap79
-rw-r--r--contrib/libpcap/pcap_open_dead.3pcap.in2
-rw-r--r--contrib/libpcap/pcap_open_live.3pcap7
-rw-r--r--contrib/libpcap/pcap_open_offline.3pcap109
-rw-r--r--contrib/libpcap/pcap_open_offline.3pcap.in2
-rw-r--r--contrib/libpcap/pcap_set_protocol.3pcap67
-rw-r--r--contrib/libpcap/pcap_set_timeout.3pcap19
-rw-r--r--contrib/libpcap/pcap_set_tstamp_precision.3pcap61
-rw-r--r--contrib/libpcap/pcap_set_tstamp_type.3pcap65
-rw-r--r--contrib/libpcap/pcap_set_tstamp_type.3pcap.in2
-rw-r--r--contrib/libpcap/pcap_version.h.in13
-rw-r--r--contrib/libpcap/portability.h114
-rw-r--r--contrib/libpcap/remote-ext.h467
-rw-r--r--contrib/libpcap/rpcap-protocol.c195
-rw-r--r--contrib/libpcap/rpcap-protocol.h450
-rw-r--r--contrib/libpcap/savefile.c69
-rw-r--r--contrib/libpcap/scanner.l93
-rw-r--r--contrib/libpcap/sf-pcap.c302
-rw-r--r--contrib/libpcap/sf-pcapng.c (renamed from contrib/libpcap/sf-pcap-ng.c)172
-rw-r--r--contrib/libpcap/sf-pcapng.h (renamed from contrib/libpcap/sf-pcap-ng.h)8
-rw-r--r--contrib/libpcap/sockutils.c471
-rw-r--r--contrib/libpcap/sockutils.h79
-rw-r--r--contrib/libpcap/tests/can_set_rfmon_test.c92
-rw-r--r--contrib/libpcap/tests/capturetest.c334
-rw-r--r--contrib/libpcap/tests/filtertest.c364
-rw-r--r--contrib/libpcap/tests/findalldevstest.c161
-rw-r--r--contrib/libpcap/tests/opentest.c273
-rw-r--r--contrib/libpcap/tests/reactivatetest.c84
-rw-r--r--contrib/libpcap/tests/selpolltest.c407
-rw-r--r--contrib/libpcap/tests/shb-option-too-long.pcapngbin0 -> 180 bytes
-rw-r--r--contrib/libpcap/tests/valgrindtest.c470
-rw-r--r--contrib/libpcap/varattrs.h (renamed from contrib/libpcap/fad-null.c)45
199 files changed, 26219 insertions, 16155 deletions
diff --git a/contrib/libpcap/.cvsignore b/contrib/libpcap/.cvsignore
deleted file mode 100644
index 138c28814a089..0000000000000
--- a/contrib/libpcap/.cvsignore
+++ /dev/null
@@ -1,13 +0,0 @@
-config.log
-config.cache
-config.status
-config.h
-.devel
-stamp-h
-stamp-h.in
-Makefile
-scanner.c
-grammar.c
-tokdefs.h
-version.c
-version.h
diff --git a/contrib/libpcap/CHANGES b/contrib/libpcap/CHANGES
index 1784096593056..8c72dbe9cd423 100644
--- a/contrib/libpcap/CHANGES
+++ b/contrib/libpcap/CHANGES
@@ -1,3 +1,30 @@
+Wednesday, Jan. 25, 2017 guy@alum.mit.edu
+ Summary for 1.9.0 libpcap release
+ Man page improvements
+ Fix Linux cooked mode userspace filtering (GitHub pull request #429)
+ Fix compilation if IPv6 support not enabled
+ Fix some Linux memory-mapped capture buffer size issues
+ Don't fail if kernel filter can't be set on Linux (GitHub issue
+ #549)
+ Improve sorting of interfaces for pcap_findalldevs()
+ Don't list Linux usbmon devices if usbmon module isn't loaded
+ Report PCAP_ERROR_PERM_DENIED if no permission to open Linux usbmon
+ devices
+ Fix DLT_ type for Solaris IPNET devices
+ Always return an error message for errors finding DAG or Myricom
+ devices
+ If possible, don't require that a device be openable when
+ enumerating them for pcap_findalldevs()
+ Don't put incompletely-initialized addresses in the address list for
+ When finding Myricom devices, update description for regular
+ interfaces that are Myricom devices and handle SNF_FLAGS=0x2(port
+ aggregation enabled)
+ Fix compilation error in DAG support
+ Fix issues with CMake configuration
+ Add support for stream buffers larger than 2GB on newer DAG cards
+ Remove support for building against DAG versions without STREAMS
+ support (before dag-3.0.0 2007)
+
Tuesday, Oct. 25, 2016 mcr@sandelman.ca
Summary for 1.8.1 libpcap release
Add a target in Makefile.in for Exuberant Ctags use: 'extags'.
diff --git a/contrib/libpcap/CMakeLists.txt b/contrib/libpcap/CMakeLists.txt
new file mode 100644
index 0000000000000..ce69155120459
--- /dev/null
+++ b/contrib/libpcap/CMakeLists.txt
@@ -0,0 +1,2294 @@
+cmake_minimum_required(VERSION 2.8.6)
+
+#
+# Apple doesn't build with an install_name starting with @rpath, and
+# neither do we with autotools; don't do so with CMake, either, and
+# suppress warnings about that.
+#
+if(POLICY CMP0042)
+ cmake_policy(SET CMP0042 OLD)
+endif()
+
+set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/Modules)
+
+project(pcap)
+
+#
+# Try to enable as many C99 features as we can.
+# At minimum, we want C++/C99-style // comments.
+#
+# Newer versions of compilers might default to supporting C99, but older
+# versions may require a special flag.
+#
+# Prior to CMake 3.1, setting CMAKE_C_STANDARD will not have any effect,
+# so, unless and until we require CMake 3.1 or later, we have to do it
+# ourselves on pre-3.1 CMake, so we just do it ourselves on all versions
+# of CMake.
+#
+# Note: with CMake 3.1 through 3.5, the only compilers for which CMake
+# handles CMAKE_C_STANDARD are GCC and Clang. 3.6 adds support only
+# for Intel C; 3.9 adds support for PGI C, Sun C, and IBM XL C, and
+# 3.10 adds support for Cray C and IAR C, but no version of CMake has
+# support for HP C. Therefore, even if we use CMAKE_C_STANDARD with
+# compilers for which CMake supports it, we may still have to do it
+# ourselves on other compilers.
+#
+# See the CMake documentation for the CMAKE_<LANG>_COMPILER_ID variables
+# for a list of compiler IDs.
+#
+# We don't worry about MSVC; it doesn't have such a flag - either it
+# doesn't support the C99 features we need at all, or it supports them
+# regardless of the compiler flag.
+#
+# XXX - this just tests whether the option works and adds it if it does.
+# We don't test whether it's necessary in order to get the C99 features
+# that we use; if we ever have a user who tries to compile with a compiler
+# that can't be made to support those features, we can add a test to make
+# sure we actually *have* C99 support.
+#
+include(CheckCCompilerFlag)
+macro(check_and_add_compiler_option _option)
+ message(STATUS "Checking C compiler flag ${_option}")
+ string(REPLACE "=" "-" _temp_option_variable ${_option})
+ string(REGEX REPLACE "^-" "" _option_variable ${_temp_option_variable})
+ check_c_compiler_flag("${_option}" ${_option_variable})
+ if(${${_option_variable}})
+ set(C_ADDITIONAL_FLAGS "${C_ADDITIONAL_FLAGS} ${_option}")
+ endif()
+endmacro()
+
+set(C_ADDITIONAL_FLAGS "")
+if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR
+ CMAKE_C_COMPILER_ID MATCHES "Clang")
+ check_and_add_compiler_option("-std=gnu99")
+elseif(CMAKE_C_COMPILER_ID MATCHES "XL")
+ #
+ # We want support for extensions picked up for GNU C compatibility,
+ # so we use -qlanglvl=extc99.
+ #
+ check_and_add_compiler_option("-qlanglvl=extc99")
+elseif(CMAKE_C_COMPILER_ID MATCHES "HP")
+ check_and_add_compiler_option("-AC99")
+elseif(CMAKE_C_COMPILER_ID MATCHES "Sun")
+ check_and_add_compiler_option("-xc99")
+elseif(CMAKE_C_COMPILER_ID MATCHES "Intel")
+ check_and_add_compiler_option("-c99")
+endif()
+
+#
+# Build all runtimes in the top-level binary directory; that way,
+# on Windows, the executables will be in the same directory as
+# the DLLs, so the system will find pcap.dll when any of the
+# executables are run.
+#
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/run)
+
+###################################################################
+# Parameters
+###################################################################
+
+if(WIN32)
+ #
+ # On Windows, allow the library name to be overridden, for the
+ # benefit of projects that combine libpcap with their own
+ # kernel-mode code to support capturing.
+ #
+ set(LIBRARY_NAME pcap CACHE STRING "Library name")
+else()
+ #
+ # On UN*X, it's always been libpcap.
+ #
+ set(LIBRARY_NAME pcap)
+endif()
+
+option(INET6 "Enable IPv6" ON)
+if(WIN32)
+ option(USE_STATIC_RT "Use static Runtime" ON)
+endif(WIN32)
+option(BUILD_SHARED_LIBS "Build shared libraries" ON)
+if(WIN32)
+ set(PACKET_DLL_DIR "" CACHE PATH "Path to directory with include and lib subdirectories for packet.dll")
+endif(WIN32)
+
+# To pacify those who hate the protochain instruction
+option(NO_PROTOCHAIN "Disable protochain instruction" OFF)
+
+#
+# Start out with the capture mechanism type unspecified; the user
+# can explicitly specify it and, if they don't, we'll pick an
+# appropriate one.
+#
+set(PCAP_TYPE "" CACHE STRING "Packet capture type")
+
+#
+# Default to having remote capture support on Windows and, for now, to
+# not having it on UN*X.
+#
+if(WIN32)
+ option(ENABLE_REMOTE "Enable remote capture" ON)
+else()
+ option(ENABLE_REMOTE "Enable remote capture" OFF)
+endif(WIN32)
+
+if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
+ option(PCAP_SUPPORT_PACKET_RING "Enable Linux packet ring support" ON)
+ 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.
+#
+option(DISABLE_USB "Disable USB sniffing support" OFF)
+option(DISABLE_BLUETOOTH "Disable Bluetooth sniffing support" OFF)
+option(DISABLE_NETMAP "Disable netmap support" OFF)
+#
+# We don't support D-Bus sniffing on macOS; see
+#
+# https://bugs.freedesktop.org/show_bug.cgi?id=74029
+#
+if(APPLE)
+ option(DISABLE_DBUS "Disable D-Bus sniffing support" ON)
+else(APPLE)
+ option(DISABLE_DBUS "Disable D-Bus sniffing support" OFF)
+endif(APPLE)
+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")
+
+option(DISABLE_SNF "Disable Myricom SNF support" OFF)
+
+option(DISABLE_TC "Disable Riverbed TurboCap support" OFF)
+
+#
+# Debugging options.
+#
+option(BDEBUG "Build optimizer debugging code" OFF)
+option(YYDEBUG "Build parser debugging code" OFF)
+
+###################################################################
+# Versioning
+###################################################################
+
+# Get, parse, format and set pcap's version string from [pcap_root]/VERSION
+# for later use.
+
+# Get MAJOR, MINOR, PATCH & SUFFIX
+file(STRINGS ${pcap_SOURCE_DIR}/VERSION
+ PACKAGE_VERSION
+ LIMIT_COUNT 1 # Read only the first line
+)
+
+# Get "just" MAJOR
+string(REGEX MATCH "^([0-9]+)" PACKAGE_VERSION_MAJOR "${PACKAGE_VERSION}")
+
+# Get MAJOR, MINOR & PATCH
+string(REGEX MATCH "^([0-9]+.)?([0-9]+.)?([0-9]+)" PACKAGE_VERSION_NOSUFFIX "${PACKAGE_VERSION}")
+
+if(WIN32)
+ # Convert PCAP_VERSION_NOSUFFIX to Windows preferred version format
+ string(REPLACE "." "," PACKAGE_VERSION_PREDLL ${PACKAGE_VERSION_NOSUFFIX})
+
+ # Append NANO (used for Windows internal versioning) to PCAP_VERSION_PREDLL
+ # 0 means unused.
+ set(PACKAGE_VERSION_DLL ${PACKAGE_VERSION_PREDLL},0)
+endif(WIN32)
+
+set(PACKAGE_NAME "${LIBRARY_NAME}")
+set(PACKAGE_STRING "${LIBRARY_NAME} ${PACKAGE_VERSION}")
+
+######################################
+# Project settings
+######################################
+
+add_definitions(-DHAVE_CONFIG_H)
+
+include_directories(
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${pcap_SOURCE_DIR}
+)
+
+include(CheckFunctionExists)
+include(CMakePushCheckState)
+
+if(WIN32)
+
+ if(IS_DIRECTORY ${CMAKE_HOME_DIRECTORY}/../../Common)
+ include_directories(${CMAKE_HOME_DIRECTORY}/../../Common)
+ endif(IS_DIRECTORY ${CMAKE_HOME_DIRECTORY}/../../Common)
+
+ find_package(Packet)
+ if(PACKET_FOUND)
+ set(HAVE_PACKET32 TRUE)
+ include_directories(${PACKET_INCLUDE_DIRS})
+ #
+ # Check whether we have the NPcap PacketIsLoopbackAdapter()
+ # function.
+ #
+ cmake_push_check_state()
+ set(CMAKE_REQUIRED_LIBRARIES ${PACKET_LIBRARIES})
+ check_function_exists(PacketIsLoopbackAdapter HAVE_PACKET_IS_LOOPBACK_ADAPTER)
+ cmake_pop_check_state()
+ endif(PACKET_FOUND)
+
+endif(WIN32)
+
+if(MSVC)
+ add_definitions(-D__STDC__)
+ add_definitions(-D_CRT_SECURE_NO_WARNINGS)
+endif(MSVC)
+
+if(USE_STATIC_RT)
+ message(STATUS "Use STATIC runtime")
+ if(MSVC)
+ foreach(RT_FLAG
+ CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
+ CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO
+ CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
+ CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
+ string(REGEX REPLACE "/MD" "/MT" ${RT_FLAG} "${${RT_FLAG}}")
+ endforeach(RT_FLAG)
+ elseif(MINGW)
+ set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -static-libgcc")
+ endif()
+else (USE_STATIC_RT)
+ message(STATUS "Use DYNAMIC runtime")
+endif(USE_STATIC_RT)
+
+###################################################################
+# Detect available platform features
+###################################################################
+
+include(CheckIncludeFile)
+include(CheckIncludeFiles)
+include(CheckStructHasMember)
+include(CheckTypeSize)
+
+#
+# Header files.
+#
+check_include_file(inttypes.h HAVE_INTTYPES_H)
+check_include_file(stdint.h HAVE_STDINT_H)
+check_include_file(unistd.h HAVE_UNISTD_H)
+if(NOT HAVE_UNISTD_H)
+ add_definitions(-DYY_NO_UNISTD_H)
+endif(NOT HAVE_UNISTD_H)
+check_include_file(bitypes.h HAVE_SYS_BITYPES_H)
+if(NOT WIN32)
+ check_include_file(sys/ioccom.h HAVE_SYS_IOCCOM_H)
+ check_include_file(sys/sockio.h HAVE_SYS_SOCKIO_H)
+ check_include_file(sys/select.h HAVE_SYS_SELECT_H)
+endif(NOT WIN32)
+check_include_file(limits.h HAVE_LIMITS_H)
+if(NOT WIN32)
+ check_include_file(netpacket/packet.h HAVE_NETPACKET_PACKET_H)
+ check_include_files("sys/types.h;sys/socket.h;net/if.h;net/pfvar.h" HAVE_NET_PFVAR_H)
+ if(HAVE_NET_PFVAR_H)
+ #
+ # Check for various PF actions.
+ #
+ check_c_source_compiles(
+"#include <sys/types.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <net/pfvar.h>
+
+int
+main(void)
+{
+ return PF_NAT+PF_NONAT+PF_BINAT+PF_NOBINAT+PF_RDR+PF_NORDR;
+}
+"
+ HAVE_PF_NAT_THROUGH_PF_NORDR)
+ endif(HAVE_NET_PFVAR_H)
+ check_include_file(netinet/if_ether.h HAVE_NETINET_IF_ETHER_H)
+ if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
+ check_include_file(linux/sockios.h HAVE_LINUX_SOCKIOS_H)
+ #
+ # linux/if_bonding.h requires sys/socket.h.
+ #
+ check_include_files("sys/socket.h;linux/if_bonding.h" HAVE_LINUX_IF_BONDING_H)
+ endif()
+endif(NOT WIN32)
+
+#
+# Functions.
+#
+check_function_exists(strerror HAVE_STRERROR)
+check_function_exists(strerror_r HAVE_STRERROR_R)
+check_function_exists(strerror_s HAVE_STRERROR_S)
+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(strtok_r HAVE_STRTOK_R)
+
+#
+# These tests are for network applications that need socket functions
+# and getaddrinfo()/getnameinfo()-ish functions. We now require
+# getaddrinfo() and getnameinfo(). On UN*X systems, we also prefer
+# versions of recvmsg() that conform to the Single UNIX Specification,
+# so that we can check whether a datagram received with recvmsg() was
+# truncated when received due to the buffer being too small.
+#
+# On Windows, getaddrinfo() is in the ws2_32 library.
+
+# On most UN*X systems, they're available in the system library.
+#
+# Under Solaris, we need to link with libsocket and libnsl to get
+# getaddrinfo() and getnameinfo() and, if we have libxnet, we need to
+# link with libxnet before libsocket to get a version of recvmsg()
+# that conforms to the Single UNIX Specification.
+#
+# We use getaddrinfo() because we want a portable thread-safe way
+# of getting information for a host name or port; there exist _r
+# versions of gethostbyname() and getservbyname() on some platforms,
+# but not on all platforms.
+#
+# NOTE: if you hand check_library_exists as its last argument a variable
+# that's been set, it skips the test, so we need different variables.
+#
+set(PCAP_LINK_LIBRARIES "")
+include(CheckLibraryExists)
+include(CheckSymbolExists)
+if(WIN32)
+ #
+ # We need winsock2.h and ws2tcpip.h.
+ #
+ cmake_push_check_state()
+ set(CMAKE_REQUIRED_LIBRARIES ws2_32)
+ check_symbol_exists(getaddrinfo "winsock2.h;ws2tcpip.h" LIBWS2_32_HAS_GETADDRINFO)
+ cmake_pop_check_state()
+ if(LIBWS2_32_HAS_GETADDRINFO)
+ set(PCAP_LINK_LIBRARIES ws2_32 ${PCAP_LINK_LIBRARIES})
+ else(LIBWS2_32_HAS_GETADDRINFO)
+ message(FATAL_ERROR "getaddrinfo is required, but wasn't found")
+ endif(LIBWS2_32_HAS_GETADDRINFO)
+else(WIN32)
+ #
+ # UN*X. First try the system libraries, then try the libraries
+ # for Solaris and possibly other systems that picked up the
+ # System V library split.
+ #
+ check_function_exists(getaddrinfo STDLIBS_HAVE_GETADDRINFO)
+ if(NOT STDLIBS_HAVE_GETADDRINFO)
+ #
+ # Not found in the standard system libraries.
+ # Try libsocket, which requires libnsl.
+ #
+ cmake_push_check_state()
+ set(CMAKE_REQUIRED_LIBRARIES nsl)
+ check_library_exists(socket getaddrinfo "" LIBSOCKET_HAS_GETADDRINFO)
+ cmake_pop_check_state()
+ if(LIBSOCKET_HAS_GETADDRINFO)
+ #
+ # OK, we found it in libsocket.
+ #
+ set(PCAP_LINK_LIBRARIES socket nsl ${PCAP_LINK_LIBRARIES})
+ else(LIBSOCKET_HAS_GETADDRINFO)
+ #
+ # We didn't find it.
+ #
+ message(FATAL_ERROR "getaddrinfo is required, but wasn't found")
+ endif(LIBSOCKET_HAS_GETADDRINFO)
+
+ #
+ # OK, do we have recvmsg() in libxnet?
+ # We also link with libsocket and libnsl.
+ #
+ cmake_push_check_state()
+ set(CMAKE_REQUIRED_LIBRARIES socket nsl)
+ check_library_exists(xnet recvmsg "" LIBXNET_HAS_RECVMSG)
+ cmake_pop_check_state()
+ if(LIBXNET_HAS_RECVMSG)
+ #
+ # Yes - link with it as well.
+ #
+ set(PCAP_LINK_LIBRARIES xnet ${PCAP_LINK_LIBRARIES})
+ endif(LIBXNET_HAS_RECVMSG)
+ endif(NOT STDLIBS_HAVE_GETADDRINFO)
+
+ # DLPI needs putmsg under HPUX so test for -lstr while we're at it
+ check_function_exists(putmsg STDLIBS_HAVE_PUTMSG)
+ if(NOT STDLIBS_HAVE_PUTMSG)
+ check_library_exists(str putmsg "" LIBSTR_HAS_PUTMSG)
+ if(LIBSTR_HAS_PUTMSG)
+ set(PCAP_LINK_LIBRARIES str ${PCAP_LINK_LIBRARIES})
+ endif(LIBSTR_HAS_PUTMSG)
+ endif(NOT STDLIBS_HAVE_PUTMSG)
+endif(WIN32)
+
+#
+# Check for reentrant versions of getnetbyname_r(), as provided by
+# Linux (glibc), Solaris/IRIX, and AIX (with three different APIs!).
+# If we don't find one, we just use getnetbyname(), which uses
+# thread-specific data on many platforms, but doesn't use it on
+# NetBSD or OpenBSD, and may not use it on older versions of other
+# platforms.
+#
+# Only do the check if we have a declaration of getnetbyname_r();
+# without it, we can't check which API it has. (We assume that
+# if there's a declaration, it has a prototype, so that the API
+# can be checked.)
+#
+cmake_push_check_state()
+set(CMAKE_REQUIRED_LIBRARIES ${PCAP_LINK_LIBRARIES})
+check_symbol_exists(getnetbyname_r netdb.h NETDB_H_DECLARES_GETNETBYNAME_R)
+if(NETDB_H_DECLARES_GETNETBYNAME_R)
+ check_c_source_compiles(
+"#include <netdb.h>
+
+int
+main(void)
+{
+ struct netent netent_buf;
+ char buf[1024];
+ struct netent *resultp;
+ int h_errnoval;
+
+ return getnetbyname_r((const char *)0, &netent_buf, buf, sizeof buf, &resultp, &h_errnoval);
+}
+"
+ HAVE_LINUX_GETNETBYNAME_R)
+ if(NOT HAVE_LINUX_GETNETBYNAME_R)
+ check_c_source_compiles(
+"#include <netdb.h>
+
+int
+main(void)
+{
+ struct netent netent_buf;
+ char buf[1024];
+
+ return getnetbyname_r((const char *)0, &netent_buf, buf, (int)sizeof buf) != NULL;
+}
+"
+ HAVE_SOLARIS_IRIX_GETNETBYNAME_R)
+ if(NOT HAVE_SOLARIS_IRIX_GETNETBYNAME_R)
+ check_c_source_compiles(
+"#include <netdb.h>
+
+int
+main(void)
+{
+ struct netent netent_buf;
+ struct netent_data net_data;
+
+ return getnetbyname_r((const char *)0, &netent_buf, &net_data);
+}
+"
+ HAVE_AIX_GETNETBYNAME_R)
+ endif(NOT HAVE_SOLARIS_IRIX_GETNETBYNAME_R)
+ endif(NOT HAVE_LINUX_GETNETBYNAME_R)
+endif(NETDB_H_DECLARES_GETNETBYNAME_R)
+cmake_pop_check_state()
+
+#
+# Check for reentrant versions of getprotobyname_r(), as provided by
+# Linux (glibc), Solaris/IRIX, and AIX (with three different APIs!).
+# If we don't find one, we just use getprotobyname(), which uses
+# thread-specific data on many platforms, but doesn't use it on
+# NetBSD or OpenBSD, and may not use it on older versions of other
+# platforms.
+#
+# Only do the check if we have a declaration of getprotobyname_r();
+# without it, we can't check which API it has. (We assume that
+# if there's a declaration, it has a prototype, so that the API
+# can be checked.)
+#
+cmake_push_check_state()
+set(CMAKE_REQUIRED_LIBRARIES ${PCAP_LINK_LIBRARIES})
+check_symbol_exists(getprotobyname_r netdb.h NETDB_H_DECLARES_GETPROTOBYNAME_R)
+if(NETDB_H_DECLARES_GETPROTOBYNAME_R)
+ check_c_source_compiles(
+"#include <netdb.h>
+
+int
+main(void)
+{
+ struct protoent protoent_buf;
+ char buf[1024];
+ struct protoent *resultp;
+
+ return getprotobyname_r((const char *)0, &protoent_buf, buf, sizeof buf, &resultp);
+}
+"
+ HAVE_LINUX_GETPROTOBYNAME_R)
+ if(NOT HAVE_LINUX_GETPROTOBYNAME_R)
+ check_c_source_compiles(
+"#include <netdb.h>
+
+int
+main(void)
+{
+ struct protoent protoent_buf;
+ char buf[1024];
+
+ return getprotobyname_r((const char *)0, &protoent_buf, buf, (int)sizeof buf) != NULL;
+}
+"
+ HAVE_SOLARIS_IRIX_GETPROTOBYNAME_R)
+ if(NOT HAVE_SOLARIS_IRIX_GETPROTOBYNAME_R)
+ check_c_source_compiles(
+"#include <netdb.h>
+
+int
+main(void)
+{
+ struct protoent protoent_buf;
+ struct protoent_data proto_data;
+
+ return getprotobyname_r((const char *)0, &protoent_buf, &proto_data);
+}
+"
+ HAVE_AIX_GETPROTOBYNAME_R)
+ endif(NOT HAVE_SOLARIS_IRIX_GETPROTOBYNAME_R)
+ endif(NOT HAVE_LINUX_GETPROTOBYNAME_R)
+endif(NETDB_H_DECLARES_GETPROTOBYNAME_R)
+cmake_pop_check_state()
+
+#
+# Data types.
+#
+# XXX - there's no check_type() macro that's like check_type_size()
+# except that it only checks for the existence of the structure type,
+# so we use check_type_size() and ignore the size.
+#
+cmake_push_check_state()
+if(WIN32)
+ set(CMAKE_EXTRA_INCLUDE_FILES winsock2.h)
+else(WIN32)
+ set(CMAKE_EXTRA_INCLUDE_FILES unistd.h sys/socket.h)
+endif(WIN32)
+check_type_size("struct sockaddr_storage" STRUCT_SOCKADDR_STORAGE)
+check_type_size("socklen_t" SOCKLEN_T)
+cmake_pop_check_state()
+
+#
+# Structure fields.
+#
+if(WIN32)
+ check_struct_has_member("struct sockaddr" sa_len winsock2.h HAVE_STRUCT_SOCKADDR_SA_LEN)
+else(WIN32)
+ check_struct_has_member("struct sockaddr" sa_len sys/socket.h HAVE_STRUCT_SOCKADDR_SA_LEN)
+endif(WIN32)
+
+#
+# Do we have ffs(), and is it declared in <strings.h>?
+#
+check_function_exists(ffs HAVE_FFS)
+if(HAVE_FFS)
+ #
+ # OK, we have ffs(). Is it declared in <strings.h>?
+ #
+ # This test fails if we don't have <strings.h> or if we do
+ # but it doesn't declare ffs().
+ #
+ check_symbol_exists(ffs strings.h STRINGS_H_DECLARES_FFS)
+endif()
+
+#
+# This requires the libraries that we require, as ether_hostton might be
+# in one of those libraries. That means we have to do this after
+# we check for those libraries.
+#
+# You are in a twisty little maze of UN*Xes, all different.
+# Some might not have ether_hostton().
+# Some might have it and declare it in <net/ethernet.h>.
+# Some might have it and declare it in <netinet/ether.h>
+# Some might have it and declare it in <sys/ethernet.h>.
+# Some might have it and declare it in <arpa/inet.h>.
+# Some might have it and declare it in <netinet/if_ether.h>.
+# Some might have it and not declare it in any header file.
+#
+# Before you is a C compiler.
+#
+cmake_push_check_state()
+set(CMAKE_REQUIRED_LIBRARIES ${PCAP_LINK_LIBRARIES})
+check_function_exists(ether_hostton HAVE_ETHER_HOSTTON)
+if(HAVE_ETHER_HOSTTON)
+ #
+ # OK, we have ether_hostton(). Is it declared in <net/ethernet.h>?
+ #
+ # This test fails if we don't have <net/ethernet.h> or if we do
+ # but it doesn't declare ether_hostton().
+ #
+ check_symbol_exists(ether_hostton net/ethernet.h NET_ETHERNET_H_DECLARES_ETHER_HOSTTON)
+ if(NET_ETHERNET_H_DECLARES_ETHER_HOSTTON)
+ #
+ # Yes - we have it declared.
+ #
+ set(HAVE_DECL_ETHER_HOSTTON TRUE)
+ endif()
+ #
+ # Did that succeed?
+ #
+ if(NOT HAVE_DECL_ETHER_HOSTTON)
+ #
+ # No - how about <netinet/ether.h>, as on Linux?
+ #
+ # This test fails if we don't have <netinet/ether.h>
+ # or if we do but it doesn't declare ether_hostton().
+ #
+ check_symbol_exists(ether_hostton netinet/ether.h NETINET_ETHER_H_DECLARES_ETHER_HOSTTON)
+ if(NETINET_ETHER_H_DECLARES_ETHER_HOSTTON)
+ #
+ # Yes - we have it declared.
+ #
+ set(HAVE_DECL_ETHER_HOSTTON TRUE)
+ endif()
+ endif()
+ #
+ # Did that succeed?
+ #
+ if(NOT HAVE_DECL_ETHER_HOSTTON)
+ #
+ # No - how about <sys/ethernet.h>, as on Solaris 10 and later?
+ #
+ # This test fails if we don't have <sys/ethernet.h>
+ # or if we do but it doesn't declare ether_hostton().
+ #
+ check_symbol_exists(ether_hostton sys/ethernet.h SYS_ETHERNET_H_DECLARES_ETHER_HOSTTON)
+ if(SYS_ETHERNET_H_DECLARES_ETHER_HOSTTON)
+ #
+ # Yes - we have it declared.
+ #
+ set(HAVE_DECL_ETHER_HOSTTON TRUE)
+ endif()
+ endif()
+ #
+ # Did that succeed?
+ #
+ if(NOT HAVE_DECL_ETHER_HOSTTON)
+ #
+ # No, how about <arpa/inet.h>, as on AIX?
+ #
+ # This test fails if we don't have <arpa/inet.h>
+ # or if we do but it doesn't declare ether_hostton().
+ #
+ check_symbol_exists(ether_hostton arpa/inet.h ARPA_INET_H_DECLARES_ETHER_HOSTTON)
+ if(ARPA_INET_H_DECLARES_ETHER_HOSTTON)
+ #
+ # Yes - we have it declared.
+ #
+ set(HAVE_DECL_ETHER_HOSTTON TRUE)
+ endif()
+ endif()
+ #
+ # Did that succeed?
+ #
+ if(NOT HAVE_DECL_ETHER_HOSTTON)
+ #
+ # No, how about <netinet/if_ether.h>?
+ # On some platforms, it requires <net/if.h> and
+ # <netinet/in.h>, and we always include it with
+ # both of them, so test it with both of them.
+ #
+ # This test fails if we don't have <netinet/if_ether.h>
+ # and the headers we include before it, or if we do but
+ # <netinet/if_ether.h> doesn't declare ether_hostton().
+ #
+ check_symbol_exists(ether_hostton "sys/types.h;sys/socket.h;net/if.h;netinet/in.h;netinet/if_ether.h" NETINET_IF_ETHER_H_DECLARES_ETHER_HOSTTON)
+ if(NETINET_IF_ETHER_H_DECLARES_ETHER_HOSTTON)
+ #
+ # Yes - we have it declared.
+ #
+ set(HAVE_DECL_ETHER_HOSTTON TRUE)
+ endif()
+ endif()
+ #
+ # After all that, is ether_hostton() declared?
+ #
+ if(NOT HAVE_DECL_ETHER_HOSTTON)
+ #
+ # No, we'll have to declare it ourselves.
+ # Do we have "struct ether_addr" if we include <netinet/if_ether.h>?
+ #
+ # XXX - there's no check_type() macro that's like check_type_size()
+ # except that it only checks for the existence of the structure type,
+ # so we use check_type_size() and ignore the size.
+ #
+ cmake_push_check_state()
+ set(CMAKE_EXTRA_INCLUDE_FILES sys/types.h sys/socket.h net/if.h netinet/in.h netinet/if_ether.h)
+ check_type_size("struct ether_addr" STRUCT_ETHER_ADDR)
+ cmake_pop_check_state()
+ endif()
+endif()
+cmake_pop_check_state()
+
+#
+# Large file support on UN*X, a/k/a LFS.
+#
+if(NOT WIN32)
+ include(FindLFS)
+ if(LFS_FOUND)
+ #
+ # Add the required #defines.
+ #
+ add_definitions(${LFS_DEFINITIONS})
+ endif()
+
+ #
+ # Check for fseeko as well.
+ #
+ include(FindFseeko)
+ if(FSEEKO_FOUND)
+ set(HAVE_FSEEKO ON)
+
+ #
+ # Add the required #defines.
+ #
+ add_definitions(${FSEEKO_DEFINITIONS})
+ endif()
+endif()
+
+if(INET6)
+ message(STATUS "Support IPv6")
+endif(INET6)
+
+#
+# Pthreads.
+# We might need them, because some libraries we use might use them,
+# but we don't necessarily need them.
+# That's only on UN*X; on Windows, if they use threads, we assume
+# they're native Windows threads.
+#
+if(NOT WIN32)
+ set(CMAKE_THREAD_PREFER_PTHREAD ON)
+ find_package(Threads)
+ if(NOT CMAKE_USE_PTHREADS_INIT)
+ #
+ # If it's not pthreads, we won't use it; we use it for libraries
+ # that require it.
+ #
+ set(CMAKE_THREAD_LIBS_INIT "")
+ endif(NOT CMAKE_USE_PTHREADS_INIT)
+endif(NOT WIN32)
+
+######################################
+# Input files
+######################################
+
+set(PROJECT_SOURCE_LIST_C
+ bpf_dump.c
+ bpf_filter.c
+ bpf_image.c
+ etherent.c
+ fmtutils.c
+ gencode.c
+ nametoaddr.c
+ optimize.c
+ pcap-common.c
+ pcap.c
+ savefile.c
+ sf-pcapng.c
+ sf-pcap.c
+)
+
+if(WIN32)
+ set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} missing/win_snprintf.c)
+else()
+ if(NOT HAVE_SNPRINTF)
+ set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} missing/snprintf.c)
+ endif(NOT HAVE_SNPRINTF)
+ if(NOT HAVE_STRTOK_R)
+ set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} missing/strtok_r.c)
+ endif(NOT HAVE_STRTOK_R)
+endif(WIN32)
+
+#
+# Determine the main pcap-XXX.c file to use, and the libraries with
+# which we need to link libpcap, if any.
+#
+if(WIN32)
+ #
+ # Windows.
+ #
+ # Has the user explicitly specified a capture type?
+ #
+ if(PCAP_TYPE STREQUAL "")
+ #
+ # The user didn't explicitly specify a capture mechanism.
+ # Check whether we have packet.dll.
+ #
+ if(HAVE_PACKET32)
+ #
+ # We have packet.dll.
+ # Set the capture type to NPF.
+ #
+ set(PCAP_TYPE npf)
+ else()
+ #
+ # We don't have any capture type we know about, so just use
+ # the null capture type, and only support reading (and writing)
+ # capture files.
+ #
+ set(PCAP_TYPE null)
+ endif()
+ endif()
+else()
+ #
+ # UN*X.
+ #
+ # Figure out what type of packet capture mechanism we have, and
+ # what libraries we'd need to link libpcap with, if any.
+ #
+
+ #
+ # Has the user explicitly specified a capture type?
+ #
+ if(PCAP_TYPE STREQUAL "")
+ #
+ # Check for a bunch of headers for various packet capture mechanisms.
+ #
+ check_include_files("sys/types.h;net/bpf.h" HAVE_NET_BPF_H)
+ if(HAVE_NET_BPF_H)
+ #
+ # Does it define BIOCSETIF?
+ # I.e., is it a header for an LBL/BSD-style capture
+ # mechanism, or is it just a header for a BPF filter
+ # engine? Some versions of Arch Linux, for example,
+ # have a net/bpf.h that doesn't define BIOCSETIF;
+ # 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/ioctl.h and, if we have it, sys/ioccom.h,
+ # because net/bpf.h defines ioctls;
+ #
+ # net/if.h, because it defines some structures
+ # used in ioctls defined by net/bpf.h;
+ #
+ # sys/socket.h, because OpenBSD 5.9's net/bpf.h
+ # defines some structure fields as being
+ # struct sockaddrs;
+ #
+ # and net/bpf.h doesn't necessarily include all
+ # 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)
+ 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)
+ endif(HAVE_SYS_IOCCOM_H)
+ endif(HAVE_NET_BPF_H)
+ check_include_file(net/pfilt.h HAVE_NET_PFILT_H)
+ check_include_file(net/enet.h HAVE_NET_ENET_H)
+ check_include_file(net/nit.h HAVE_NET_NIT_H)
+ check_include_file(sys/net/nit.h HAVE_SYS_NET_NIT_H)
+ check_include_file(linux/socket.h HAVE_LINUX_SOCKET_H)
+ check_include_file(net/raw.h HAVE_NET_RAW_H)
+ check_include_file(sys/dlpi.h HAVE_SYS_DLPI_H)
+
+ if(BPF_H_DEFINES_BIOCSETIF)
+ #
+ # BPF.
+ # Check this before DLPI, so that we pick BPF on
+ # Solaris 11 and later.
+ #
+ set(PCAP_TYPE bpf)
+ elseif(HAVE_LINUX_SOCKET_H)
+ #
+ # No prizes for guessing this one.
+ #
+ set(PCAP_TYPE linux)
+ elseif(HAVE_NET_PFILT_H)
+ #
+ # DEC OSF/1, Digital UNIX, Tru64 UNIX
+ #
+ set(PCAP_TYPE pf)
+ elseif(HAVE_NET_ENET_H)
+ #
+ # Stanford Enetfilter.
+ #
+ set(PCAP_TYPE enet)
+ elseif(HAVE_NET_NIT_H)
+ #
+ # SunOS 4.x STREAMS NIT.
+ #
+ set(PCAP_TYPE snit)
+ elseif(HAVE_SYS_NET_NIT_H)
+ #
+ # Pre-SunOS 4.x non-STREAMS NIT.
+ #
+ set(PCAP_TYPE nit)
+ elseif(HAVE_NET_RAW_H)
+ #
+ # IRIX snoop.
+ #
+ set(PCAP_TYPE snoop)
+ elseif(HAVE_SYS_DLPI_H)
+ #
+ # DLPI on pre-Solaris 11 SunOS 5, HP-UX, possibly others.
+ #
+ set(PCAP_TYPE dlpi)
+ else()
+ #
+ # Nothing we support.
+ #
+ set(PCAP_TYPE null)
+ endif()
+ endif()
+endif(WIN32)
+message(STATUS "Packet capture mechanism type: ${PCAP_TYPE}")
+
+#
+# Do capture-mechanism-dependent tests.
+#
+if(WIN32)
+ if(PCAP_TYPE STREQUAL "npf")
+ #
+ # Link with packet.dll before WinSock2.
+ #
+ set(PCAP_LINK_LIBRARIES ${PACKET_LIBRARIES} ${PCAP_LINK_LIBRARIES})
+ elseif(PCAP_TYPE STREQUAL "null")
+ else()
+ message(ERROR "${PCAP_TYPE} is not a valid pcap type")
+ endif()
+else(WIN32)
+ if(PCAP_TYPE STREQUAL "dlpi")
+ #
+ # Needed for common functions used by pcap-[dlpi,libdlpi].c
+ #
+ set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} dlpisubs.c)
+
+ #
+ # Checks for some header files.
+ #
+ check_include_file(sys/bufmod.h HAVE_SYS_BUFMOD_H)
+ check_include_file(sys/dlpi_ext.h HAVE_SYS_DLPI_EXT_H)
+
+ #
+ # Checks to see if Solaris has the public libdlpi(3LIB) library.
+ # Note: The existence of /usr/include/libdlpi.h does not mean it is the
+ # public libdlpi(3LIB) version. Before libdlpi was made public, a
+ # private version also existed, which did not have the same APIs.
+ # Due to a gcc bug, the default search path for 32-bit libraries does
+ # not include /lib, we add it explicitly here.
+ # [http://bugs.opensolaris.org/view_bug.do?bug_id=6619485].
+ # Also, due to the bug above applications that link to libpcap with
+ # libdlpi will have to add "-L/lib" option to "configure".
+ #
+ cmake_push_check_state()
+ set(CMAKE_REQUIRED_FLAGS "-L/lib")
+ set(CMAKE_REQUIRED_LIBRARIES dlpi)
+ check_function_exists(dlpi_walk HAVE_LIBDLPI)
+ cmake_pop_check_state()
+ if(HAVE_LIBDLPI)
+ #
+ # XXX - add -L/lib
+ #
+ set(PCAP_LINK_LIBRARIES ${PCAP_LINK_LIBRARIES} dlpi)
+ set(PCAP_TYPE libdlpi)
+ endif()
+
+ #
+ # This check is for Solaris with DLPI support for passive modes.
+ # See dlpi(7P) for more details.
+ #
+ # XXX - there's no check_type() macro that's like check_type_size()
+ # except that it only checks for the existence of the structure type,
+ # so we use check_type_size() and ignore the size.
+ #
+ cmake_push_check_state()
+ set(CMAKE_EXTRA_INCLUDE_FILES sys/types.h sys/dlpi.h)
+ check_type_size(dl_passive_req_t DL_PASSIVE_REQ_T)
+ cmake_pop_check_state()
+ elseif(PCAP_TYPE STREQUAL "linux")
+ #
+ # Do we have the wireless extensions?
+ # linux/wireless.h requires sys/socket.h.
+ #
+ check_include_files("sys/socket.h;linux/wireless.h" HAVE_LINUX_WIRELESS_H)
+
+ #
+ # Do we have libnl?
+ #
+ if(BUILD_WITH_LIBNL)
+ #
+ # Try libnl 3.x first.
+ #
+ cmake_push_check_state()
+ set(CMAKE_REQUIRED_LIBRARIES nl-3)
+ check_function_exists(nl_socket_alloc HAVE_LIBNL)
+ cmake_pop_check_state()
+ if(HAVE_LIBNL)
+ #
+ # Yes, we have libnl 3.x.
+ #
+ set(PCAP_LINK_LIBRARIES nl-genl-3 nl-3 ${PCAP_LINK_LIBRARIES})
+ set(HAVE_LIBNL_3_x ON)
+ set(HAVE_LIBNL_NLE ON)
+ set(HAVE_LIBNL_SOCKETS ON)
+ include_directories("/usr/include/libnl3")
+ else()
+ #
+ # Try libnl 2.x.
+ #
+ cmake_push_check_state()
+ set(CMAKE_REQUIRED_LIBRARIES nl)
+ check_function_exists(nl_socket_alloc HAVE_LIBNL)
+ cmake_pop_check_state()
+ if(HAVE_LIBNL)
+ #
+ # Yes, we have libnl 2.x.
+ #
+ set(PCAP_LINK_LIBRARIES nl-genl nl ${PCAP_LINK_LIBRARIES})
+ set(HAVE_LIBNL_2_x ON)
+ set(HAVE_LIBNL_NLE ON)
+ set(HAVE_LIBNL_SOCKETS ON)
+ else()
+ #
+ # No, we don't; do we have libnl 1.x?
+ #
+ cmake_push_check_state()
+ set(CMAKE_REQUIRED_LIBRARIES nl)
+ check_function_exists(nl_handle_alloc HAVE_LIBNL)
+ cmake_pop_check_state()
+ if(HAVE_LIBNL)
+ set(PCAP_LINK_LIBRARIES nl ${PCAP_LINK_LIBRARIES})
+ endif()
+ endif()
+ endif()
+ endif()
+
+ check_include_file(linux/ethtool.h HAVE_LINUX_ETHTOOL_H)
+
+ #
+ # Checks to see if tpacket_stats is defined in linux/if_packet.h
+ # If so then pcap-linux.c can use this to report proper statistics.
+ #
+ # XXX - there's no check_type() macro that's like check_type_size()
+ # except that it only checks for the existence of the structure type,
+ # so we use check_type_size() and ignore the size.
+ #
+ cmake_push_check_state()
+ set(CMAKE_EXTRA_INCLUDE_FILES linux/if_packet.h)
+ check_type_size("struct tpacket_stats" STRUCT_TPACKET_STATS)
+ cmake_pop_check_state()
+
+ check_struct_has_member("struct tpacket_auxdata" tp_vlan_tci linux/if_packet.h HAVE_STRUCT_TPACKET_AUXDATA_TP_VLAN_TCI)
+ elseif(PCAP_TYPE STREQUAL "bpf")
+ #
+ # Check whether we have the *BSD-style ioctls.
+ #
+ check_include_files("sys/types.h;net/if_media.h" HAVE_NET_IF_MEDIA_H)
+
+ #
+ # Check whether we have struct BPF_TIMEVAL.
+ #
+ # XXX - there's no check_type() macro that's like check_type_size()
+ # except that it only checks for the existence of the structure type,
+ # so we use check_type_size() and ignore the size.
+ #
+ cmake_push_check_state()
+ if(HAVE_SYS_IOCCOM_H)
+ set(CMAKE_EXTRA_INCLUDE_FILES sys/types.h sys/ioccom.h net/bpf.h)
+ check_type_size("struct BPF_TIMEVAL" STRUCT_BPF_TIMEVAL)
+ else()
+ set(CMAKE_EXTRA_INCLUDE_FILES sys/types.h net/bpf.h)
+ check_type_size("struct BPF_TIMEVAL" STRUCT_BPF_TIMEVAL)
+ endif()
+ cmake_pop_check_state()
+ elseif(PCAP_TYPE STREQUAL "null")
+ else()
+ message(FATAL_ERROR "${PCAP_TYPE} is not a valid pcap type")
+ endif()
+endif(WIN32)
+
+set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} pcap-${PCAP_TYPE}.c)
+
+#
+# Now figure out how we get a list of interfaces and addresses,
+# if we support capturing. Don't bother if we don't support
+# capturing.
+#
+if(NOT WIN32)
+ #
+ # UN*X - figure out what type of interface list mechanism we
+ # have.
+ #
+ # If the capture type is null, that means we can't capture,
+ # so we can't open any capture devices, so we won't return
+ # any interfaces.
+ #
+ if(NOT PCAP_TYPE STREQUAL "null")
+ cmake_push_check_state()
+ set(CMAKE_REQUIRED_LIBRARIES ${PCAP_LINK_LIBRARIES})
+ check_function_exists(getifaddrs HAVE_GETIFADDRS)
+ cmake_pop_check_state()
+ if(NOT HAVE_GETIFADDRS)
+ #
+ # It's not in the libraries that, at this point, we've
+ # found we need to link libpcap with.
+ #
+ # It's in libsocket on Solaris and possibly other OSes;
+ # as long as we're not linking with libxnet, check there.
+ #
+ # NOTE: if you hand check_library_exists as its last
+ # argument a variable that's been set, it skips the test,
+ # so we need different variables.
+ #
+ if(NOT LIBXNET_HAS_GETHOSTBYNAME)
+ check_library_exists(socket getifaddrs "" SOCKET_HAS_GETIFADDRS)
+ if(SOCKET_HAS_GETIFADDRS)
+ set(PCAP_LINK_LIBRARIES socket ${PCAP_LINK_LIBRARIES})
+ set(HAVE_GETIFADDRS TRUE)
+ endif()
+ endif()
+ endif()
+ if(HAVE_GETIFADDRS)
+ #
+ # We have "getifaddrs()"; make sure we have <ifaddrs.h>
+ # as well, just in case some platform is really weird.
+ # It may require that sys/types.h be included first,
+ # so include it first.
+ #
+ check_include_files("sys/types.h;ifaddrs.h" HAVE_IFADDRS_H)
+ if(HAVE_IFADDRS_H)
+ #
+ # We have the header, so we use "getifaddrs()" to
+ # get the list of interfaces.
+ #
+ set(FINDALLDEVS_TYPE getad)
+ else()
+ #
+ # We don't have the header - give up.
+ # XXX - we could also fall back on some other
+ # mechanism, but, for now, this'll catch this
+ # problem so that we can at least try to figure
+ # out something to do on systems with "getifaddrs()"
+ # but without "ifaddrs.h", if there is something
+ # we can do on those systems.
+ #
+ message(FATAL_ERROR "Your system has getifaddrs() but doesn't have a usable <ifaddrs.h>.")
+ endif()
+ else()
+ #
+ # Well, we don't have "getifaddrs()", at least not with the
+ # libraries with which we've decided we need to link
+ # libpcap with, so we have to use some other mechanism.
+ #
+ # Note that this may happen on Solaris, which has
+ # getifaddrs(), but in -lsocket, not in -lxnet, so we
+ # won't find it if we link with -lxnet, which we want
+ # to do for other reasons.
+ #
+ # For now, we use either the SIOCGIFCONF ioctl or the
+ # SIOCGLIFCONF ioctl, preferring the latter if we have
+ # it; the latter is a Solarisism that first appeared
+ # in Solaris 8. (Solaris's getifaddrs() appears to
+ # be built atop SIOCGLIFCONF; using it directly
+ # avoids a not-all-that-useful middleman.)
+ #
+ try_compile(HAVE_SIOCGLIFCONF ${CMAKE_CURRENT_BINARY_DIR} "${pcap_SOURCE_DIR}/cmake/have_siocglifconf.c" )
+ if(HAVE_SIOCGLIFCONF)
+ set(FINDALLDEVS_TYPE glifc)
+ else()
+ set(FINDALLDEVS_TYPE gifc)
+ endif()
+ endif()
+ message(STATUS "Find-interfaces mechanism type: ${FINDALLDEVS_TYPE}")
+ set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} fad-${FINDALLDEVS_TYPE}.c)
+ endif()
+endif()
+
+# Check for hardware timestamp support.
+if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
+ check_include_file(linux/net_tstamp.h HAVE_LINUX_NET_TSTAMP_H)
+endif()
+
+#
+# Check for additional native sniffing capabilities.
+#
+
+# Check for USB sniffing support on Linux.
+# On FreeBSD, it uses BPF, so we don't need to do anything special here.
+if(NOT DISABLE_USB)
+ if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
+ set(PCAP_SUPPORT_USB TRUE)
+ set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} pcap-usb-linux.c)
+ set(LINUX_USB_MON_DEV /dev/usbmon)
+ #
+ # Do we have a version of <linux/compiler.h> available?
+ # If so, we might need it for <linux/usbdevice_fs.h>.
+ #
+ check_include_files("linux/compiler.h" HAVE_LINUX_COMPILER_H)
+ if(HAVE_LINUX_COMPILER_H)
+ #
+ # Yes - include it when testing for <linux/usbdevice_fs.h>.
+ #
+ check_include_files("linux/compiler.h;linux/usbdevice_fs.h" HAVE_LINUX_USBDEVICE_FS_H)
+ else(HAVE_LINUX_COMPILER_H)
+ check_include_files("linux/usbdevice_fs.h" HAVE_LINUX_USBDEVICE_FS_H)
+ endif(HAVE_LINUX_COMPILER_H)
+ if(HAVE_LINUX_USBDEVICE_FS_H)
+ #
+ # OK, does it define bRequestType? Older versions of the kernel
+ # define fields with names like "requesttype, "request", and
+ # "value", rather than "bRequestType", "bRequest", and
+ # "wValue".
+ #
+ if(HAVE_LINUX_COMPILER_H)
+ check_struct_has_member("struct usbdevfs_ctrltransfer" bRequestType "linux/compiler.h;linux/usbdevice_fs.h" HAVE_STRUCT_USBDEVFS_CTRLTRANSFER_BREQUESTTYPE)
+ else(HAVE_LINUX_COMPILER_H)
+ check_struct_has_member("struct usbdevfs_ctrltransfer" bRequestType "linux/usbdevice_fs.h" HAVE_STRUCT_USBDEVFS_CTRLTRANSFER_BREQUESTTYPE)
+ endif(HAVE_LINUX_COMPILER_H)
+ endif()
+ endif()
+endif()
+
+# Check for netfilter sniffing support.
+if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
+ #
+ # Life's too short to deal with trying to get this to compile
+ # if you don't get the right types defined with
+ # __KERNEL_STRICT_NAMES getting defined by some other include.
+ #
+ # Check whether the includes Just Work. If not, don't turn on
+ # netfilter support.
+ #
+ check_c_source_compiles(
+"#include <sys/socket.h>
+#include <netinet/in.h>
+#include <linux/types.h>
+
+#include <linux/netlink.h>
+#include <linux/netfilter.h>
+#include <linux/netfilter/nfnetlink.h>
+#include <linux/netfilter/nfnetlink_log.h>
+#include <linux/netfilter/nfnetlink_queue.h>
+
+int
+main(void)
+{
+ return 0;
+}
+"
+ PCAP_SUPPORT_NETFILTER)
+ if(PCAP_SUPPORT_NETFILTER)
+ set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} pcap-netfilter-linux.c)
+ endif(PCAP_SUPPORT_NETFILTER)
+endif()
+
+# Check for netmap sniffing support.
+if(NOT DISABLE_NETMAP)
+ #
+ # Check whether net/netmap_user.h is usable if NETMAP_WITH_LIBS is
+ # defined; it's not usable on DragonFly BSD 4.6 if NETMAP_WITH_LIBS
+ # is defined, for example, as it includes a non-existent malloc.h
+ # header.
+ #
+ check_c_source_compiles(
+"#define NETMAP_WITH_LIBS
+#include <net/netmap_user.h>
+
+int
+main(void)
+{
+ return 0;
+}
+"
+ PCAP_SUPPORT_NETMAP)
+ if(PCAP_SUPPORT_NETMAP)
+ set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} pcap-netmap.c)
+ endif(PCAP_SUPPORT_NETMAP)
+endif()
+
+# Check for Bluetooth sniffing support
+if(NOT DISABLE_BLUETOOTH)
+ if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
+ check_include_file(bluetooth/bluetooth.h HAVE_BLUETOOTH_BLUETOOTH_H)
+ if(HAVE_BLUETOOTH_BLUETOOTH_H)
+ set(PCAP_SUPPORT_BT TRUE)
+ set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} pcap-bt-linux.c)
+ #
+ # OK, does struct sockaddr_hci have an hci_channel
+ # member?
+ #
+ check_struct_has_member("struct sockaddr_hci" hci_channel "bluetooth/bluetooth.h;bluetooth/hci.h" HAVE_STRUCT_SOCKADDR_HCI_HCI_CHANNEL)
+ if(HAVE_STRUCT_SOCKADDR_HCI_HCI_CHANNEL)
+ #
+ # OK, is HCI_CHANNEL_MONITOR defined?
+ #
+ check_c_source_compiles(
+"#include <bluetooth/bluetooth.h>
+#include <bluetooth/hci.h>
+
+int
+main(void)
+{
+ u_int i = HCI_CHANNEL_MONITOR;
+ return 0;
+}
+"
+ PCAP_SUPPORT_BT_MONITOR)
+ if(PCAP_SUPPORT_BT_MONITOR)
+ #
+ # Yes, so we can also support Bluetooth monitor
+ # sniffing.
+ #
+ set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} pcap-bt-monitor-linux.c)
+ endif(PCAP_SUPPORT_BT_MONITOR)
+ endif(HAVE_STRUCT_SOCKADDR_HCI_HCI_CHANNEL)
+ endif(HAVE_BLUETOOTH_BLUETOOTH_H)
+ endif()
+endif()
+
+# Check for Bluetooth sniffing support
+if(NOT DISABLE_DBUS)
+ #
+ # We don't support D-Bus sniffing on macOS; see
+ #
+ # https://bugs.freedesktop.org/show_bug.cgi?id=74029
+ #
+ if(APPLE)
+ message(FATAL_ERROR "Due to freedesktop.org bug 74029, D-Bus capture support is not available on macOS")
+ endif(APPLE)
+ include(FindPkgConfig)
+ pkg_check_modules(DBUS dbus-1)
+ if(DBUS_FOUND)
+ 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})
+ endif(DBUS_FOUND)
+endif(NOT DISABLE_DBUS)
+
+# Check for RDMA sniffing support
+if(NOT DISABLE_RDMA)
+ check_library_exists(ibverbs ibv_get_device_list "" LIBIBVERBS_HAS_IBV_GET_DEVICE_LIST)
+ if(LIBIBVERBS_HAS_IBV_GET_DEVICE_LIST)
+ check_include_file(infiniband/verbs.h HAVE_INFINIBAND_VERBS_H)
+ if(HAVE_INFINIBAND_VERBS_H)
+ check_symbol_exists(ibv_create_flow infiniband/verbs.h PCAP_SUPPORT_RDMASNIFF)
+ if(PCAP_SUPPORT_RDMASNIFF)
+ set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} pcap-rdmasniff.c)
+ set(PCAP_LINK_LIBRARIES ibverbs ${PCAP_LINK_LIBRARIES})
+ endif(PCAP_SUPPORT_RDMASNIFF)
+ endif(HAVE_INFINIBAND_VERBS_H)
+ endif(LIBIBVERBS_HAS_IBV_GET_DEVICE_LIST)
+endif(NOT DISABLE_RDMA)
+
+#
+# Check for sniffing capabilities using third-party APIs.
+#
+
+# Check for Endace DAG card support.
+if(NOT DISABLE_DAG)
+ #
+ # Try to find the DAG header file and library.
+ #
+ find_package(DAG)
+
+ #
+ # Did we succeed?
+ #
+ if(DAG_FOUND)
+ #
+ # Yes.
+ # Check for various DAG API functions.
+ #
+ cmake_push_check_state()
+ set(CMAKE_REQUIRED_INCLUDES ${DAG_INCLUDE_DIRS})
+ set(CMAKE_REQUIRED_LIBRARIES ${DAG_LIBRARIES})
+ check_function_exists(dag_attach_stream HAVE_DAG_STREAMS_API)
+ if(NOT HAVE_DAG_STREAMS_API)
+ message(FATAL_ERROR "DAG library lacks streams support")
+ endif()
+ check_function_exists(dag_attach_stream64 HAVE_DAG_LARGE_STREAMS_API)
+ check_function_exists(dag_get_erf_types HAVE_DAG_GET_ERF_TYPES)
+ check_function_exists(dag_get_stream_erf_types HAVE_DAG_GET_STREAM_ERF_TYPES)
+ cmake_pop_check_state()
+
+ include_directories(AFTER ${DAG_INCLUDE_DIRS})
+ set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} pcap-dag.c)
+ set(HAVE_DAG_API TRUE)
+ set(PCAP_LINK_LIBRARIES ${PCAP_LINK_LIBRARIES} ${DAG_LIBRARIES})
+
+ if(HAVE_DAG_LARGE_STREAMS_API)
+ get_filename_component(DAG_LIBRARY_DIR ${DAG_LIBRARY} PATH)
+ check_library_exists(vdag vdag_set_device_info ${DAG_LIBRARY_DIR} HAVE_DAG_VDAG)
+ if(HAVE_DAG_VDAG)
+ set(PCAP_LINK_LIBRARIES ${PCAP_LINK_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
+ endif()
+ endif()
+ endif()
+endif()
+
+# Check for Septel card support.
+set(PROJECT_EXTERNAL_OBJECT_LIST "")
+if(NOT DISABLE_SEPTEL)
+ #
+ # Do we have the msg.h header?
+ #
+ set(SEPTEL_INCLUDE_DIRS "${SEPTEL_ROOT}/INC")
+ cmake_push_check_state()
+ set(CMAKE_REQUIRED_INCLUDES ${SEPTEL_INCLUDE_DIRS})
+ check_include_file(msg.h HAVE_INC_MSG_H)
+ cmake_pop_check_state()
+ if(HAVE_INC_MSG_H)
+ #
+ # Yes.
+ #
+ include_directories(AFTER ${SEPTEL_INCLUDE_DIRS})
+ set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} pcap-septel.c)
+ set(PROJECT_EXTERNAL_OBJECT_LIST ${PROJECT_EXTERNAL_OBJECT_LIST} "${SEPTEL_ROOT}/asciibin.o ${SEPTEL_ROOT}/bit2byte.o ${SEPTEL_ROOT}/confirm.o ${SEPTEL_ROOT}/fmtmsg.o ${SEPTEL_ROOT}/gct_unix.o ${SEPTEL_ROOT}/hqueue.o ${SEPTEL_ROOT}/ident.o ${SEPTEL_ROOT}/mem.o ${SEPTEL_ROOT}/pack.o ${SEPTEL_ROOT}/parse.o ${SEPTEL_ROOT}/pool.o ${SEPTEL_ROOT}/sdlsig.o ${SEPTEL_ROOT}/strtonum.o ${SEPTEL_ROOT}/timer.o ${SEPTEL_ROOT}/trace.o")
+ set(HAVE_SEPTEL_API TRUE)
+ endif()
+endif()
+
+# Check for Myricom SNF support.
+if(NOT DISABLE_SNF)
+ #
+ # Try to find the SNF header file and library.
+ #
+ find_package(SNF)
+
+ #
+ # Did we succeed?
+ #
+ if(SNF_FOUND)
+ #
+ # Yes.
+ #
+ include_directories(AFTER ${SNF_INCLUDE_DIRS})
+ set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} pcap-snf.c)
+ set(HAVE_SNF_API TRUE)
+ set(PCAP_LINK_LIBRARIES ${PCAP_LINK_LIBRARIES} ${SNF_LIBRARIES})
+ endif()
+endif()
+
+# Check for Riverbed TurboCap support.
+if(NOT DISABLE_TC)
+ #
+ # Try to find the TurboCap header file and library.
+ #
+ find_package(TC)
+
+ #
+ # Did we succeed?
+ #
+ if(TC_FOUND)
+ #
+ # Yes.
+ #
+ include_directories(AFTER ${TC_INCLUDE_DIRS})
+ set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} pcap-tc.c)
+ set(HAVE_TC_API TRUE)
+ set(PCAP_LINK_LIBRARIES "${PCAP_LINK_LIBRARIES} ${TC_LIBRARIES} ${CMAKE_USE_PTHREADS_INIT} stdc++")
+ endif()
+endif()
+
+#
+# Remote capture support.
+#
+
+if(ENABLE_REMOTE)
+ #
+ # Check for various members of struct msghdr.
+ # We need to include ftmacros.h on some platforms, to make sure we
+ # get the POSIX/Single USER Specification version of struct msghdr,
+ # which has those members, rather than the backwards-compatible
+ # version, which doesn't. That's not a system header file, and
+ # at least some versions of CMake include it as <ftmacros.h>, which
+ # won't check the current directory, so we add the top-level
+ # source directory to the list of include directories when we do
+ # the check.
+ #
+ cmake_push_check_state()
+ set(CMAKE_REQUIRED_INCLUDES ${CMAKE_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()
+ set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C}
+ pcap-new.c pcap-rpcap.c rpcap-protocol.c sockutils.c)
+endif(ENABLE_REMOTE)
+
+###################################################################
+# Warning options
+###################################################################
+
+#
+# Check and add warning options if we have a .devel file.
+#
+if(EXISTS ${CMAKE_SOURCE_DIR}/.devel OR EXISTS ${CMAKE_BINARY_DIR}/.devel)
+ #
+ # Warning options.
+ #
+ if(MSVC AND NOT ${CMAKE_C_COMPILER} MATCHES "clang*")
+ #
+ # MSVC, with Microsoft's front end and code generator.
+ # "MSVC" is also set for Microsoft's compiler with a Clang
+ # front end and their code generator ("Clang/C2"), so we
+ # check for clang.exe and treat that differently.
+ #
+ check_and_add_compiler_option(-Wall)
+ #
+ # Disable some pointless warnings that /Wall turns on.
+ #
+ # Unfortunately, MSVC does not appear to have an equivalent
+ # to "__attribute__((unused))" to mark a particular function
+ # parameter as being known to be unused, so that the compiler
+ # won't warn about it (for example, the function might have
+ # that parameter because a pointer to it is being used, and
+ # the signature of that function includes that parameter).
+ # C++ lets you give a parameter a type but no name, but C
+ # doesn't have that.
+ #
+ check_and_add_compiler_option(-wd4100)
+ #
+ # In theory, we care whether somebody uses f() rather than
+ # f(void) to declare a function with no arguments, but, in
+ # practice, there are places in the Windows header files
+ # that appear to do that, so we squelch that warning.
+ #
+ check_and_add_compiler_option(-wd4255)
+ #
+ # Windows FD_SET() generates this, so we suppress it.
+ #
+ check_and_add_compiler_option(-wd4548)
+ #
+ # Perhaps testing something #defined to be 0 with #ifdef is an
+ # error, and it should be tested with #if, but perhaps it's
+ # not, and Microsoft does that in its headers, so we squelch
+ # that warning.
+ #
+ check_and_add_compiler_option(-wd4574)
+ #
+ # The Windows headers also test not-defined values in #if, so
+ # we don't want warnings about that, either.
+ #
+ check_and_add_compiler_option(-wd4668)
+ #
+ # We do *not* care whether some function is, or isn't, going to be
+ # expanded inline.
+ #
+ check_and_add_compiler_option(-wd4710)
+ check_and_add_compiler_option(-wd4711)
+ #
+ # We do *not* care whether we're adding padding bytes after
+ # structure members.
+ #
+ check_and_add_compiler_option(-wd4820)
+ else()
+ #
+ # Other compilers, including MSVC with a Clang front end and
+ # Microsoft's code generator. We currently treat them as if
+ # they might support GCC-style -W options.
+ #
+ check_and_add_compiler_option(-Wall)
+ check_and_add_compiler_option(-Wsign-compare)
+ check_and_add_compiler_option(-Wmissing-prototypes)
+ check_and_add_compiler_option(-Wstrict-prototypes)
+ check_and_add_compiler_option(-Wshadow)
+ check_and_add_compiler_option(-Wdeclaration-after-statement)
+ check_and_add_compiler_option(-Wused-but-marked-unused)
+ check_and_add_compiler_option(-Wdocumentation)
+ check_and_add_compiler_option(-Wcomma)
+ check_and_add_compiler_option(-Wmissing-noreturn)
+ # Warns about safeguards added in case the enums are extended
+ # check_and_add_compiler_option(-Wcovered-switch-default)
+ check_and_add_compiler_option(-Wmissing-variable-declarations)
+ check_and_add_compiler_option(-Wunused-parameter)
+ check_and_add_compiler_option(-Wformat-nonliteral)
+ check_and_add_compiler_option(-Wunreachable-code)
+ endif()
+endif()
+
+#
+# Suppress some warnings we get with MSVC even without /Wall.
+#
+if(MSVC AND NOT ${CMAKE_C_COMPILER} MATCHES "clang*")
+ #
+ # Yes, we have some functions that never return but that
+ # have a non-void return type. That's because, on some
+ # platforms, they *do* return values but, on other
+ # platforms, including Windows, they just fail and
+ # longjmp out by calling bpf_error().
+ #
+ check_and_add_compiler_option(-wd4646)
+endif()
+
+file(GLOB PROJECT_SOURCE_LIST_H
+ *.h
+ pcap/*.h
+)
+
+#
+# Try to have the compiler default to hiding symbols, so that only
+# symbols explicitly exported with PCAP_API will be visible outside
+# (shared) libraries.
+#
+# Not necessary with MSVC, as that's the default.
+#
+# XXX - we don't use ADD_COMPILER_EXPORT_FLAGS, because, as of CMake
+# 2.8.12.2, it doesn't know about Sun C/Oracle Studio, and, as of
+# CMake 2.8.6, it only sets the C++ compiler flags, rather than
+# allowing an arbitrary variable to be set with the "hide symbols
+# not explicitly exported" flag.
+#
+if(NOT MSVC)
+ if(CMAKE_C_COMPILER_ID MATCHES "SunPro")
+ #
+ # Sun C/Oracle Studio.
+ #
+ check_and_add_compiler_option(-xldscope=hidden)
+ else()
+ #
+ # Try this for all other compilers; it's what GCC uses,
+ # and a number of other compilers, such as Clang and Intel C,
+ # use it as well.
+ #
+ check_and_add_compiler_option(-fvisibility=hidden)
+ endif()
+endif(NOT MSVC)
+
+#
+# Flex/Lex and YACC/Berkeley YACC/Bison.
+# From a mail message to the CMake mailing list by Andy Cedilnik of
+# Kitware.
+#
+
+#
+# Try to find Flex, a Windows version of Flex, or Lex.
+#
+find_program(LEX_EXECUTABLE NAMES flex win_flex lex)
+if(LEX_EXECUTABLE STREQUAL "LEX_EXECUTABLE-NOTFOUND")
+ message(FATAL_ERROR "Neither flex nor win_flex nor lex was found.")
+endif()
+message(STATUS "Lexical analyzer generator: ${LEX_EXECUTABLE}")
+
+add_custom_command(
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/scanner.c ${CMAKE_CURRENT_BINARY_DIR}/scanner.h
+ SOURCE ${pcap_SOURCE_DIR}/scanner.l
+ COMMAND ${LEX_EXECUTABLE} -P pcap_ --header-file=scanner.h --nounput -o${CMAKE_CURRENT_BINARY_DIR}/scanner.c ${pcap_SOURCE_DIR}/scanner.l
+ DEPENDS ${pcap_SOURCE_DIR}/scanner.l
+)
+
+#
+# Since scanner.c does not exist yet when cmake is run, mark
+# it as generated.
+#
+# Since scanner.c includes grammar.h, mark that as a dependency.
+#
+set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/scanner.c PROPERTIES
+ GENERATED TRUE
+ OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/grammar.h
+)
+
+#
+# Add scanner.c to the list of sources.
+#
+#set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} ${CMAKE_CURRENT_BINARY_DIR}/scanner.c)
+
+#
+# Try to find YACC or Bison.
+#
+find_program(YACC_EXECUTABLE NAMES bison win_bison byacc yacc)
+if(YACC_EXECUTABLE STREQUAL "YACC_EXECUTABLE-NOTFOUND")
+ message(FATAL_ERROR "Neither bison nor win_bison nor byacc nor yacc was found.")
+endif()
+message(STATUS "Parser generator: ${YACC_EXECUTABLE}")
+
+#
+# Create custom command for the scanner.
+# Find out whether it's Bison or not by looking at the last component
+# of the path (without a .exe extension, if this is Windows).
+#
+get_filename_component(YACC_NAME ${YACC_EXECUTABLE} NAME_WE)
+if("${YACC_NAME}" STREQUAL "bison" OR "${YACC_NAME}" STREQUAL "win_bison")
+ set(YACC_COMPATIBILITY_FLAG "-y")
+endif()
+add_custom_command(
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/grammar.c ${CMAKE_CURRENT_BINARY_DIR}/grammar.h
+ SOURCE ${pcap_SOURCE_DIR}/grammar.y
+ COMMAND ${YACC_EXECUTABLE} ${YACC_COMPATIBILITY_FLAG} -p pcap_ -o ${CMAKE_CURRENT_BINARY_DIR}/grammar.c -d ${pcap_SOURCE_DIR}/grammar.y
+ DEPENDS ${pcap_SOURCE_DIR}/grammar.y
+)
+
+#
+# Since grammar.c does not exists yet when cmake is run, mark
+# it as generated.
+#
+set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/grammar.c PROPERTIES
+ GENERATED TRUE
+ OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/scanner.h
+)
+
+#
+# Add grammar.c to the list of sources.
+#
+#set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} ${CMAKE_CURRENT_BINARY_DIR}/grammar.c)
+
+#
+# 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.
+#
+set(MAN_FILE_FORMATS 5)
+set(MAN_MISC_INFO 7)
+set(MAN_ADMIN_COMMANDS 8)
+if(CMAKE_SYSTEM_NAME STREQUAL "AIX")
+ # Workaround to enable certain features
+ set(_SUN TRUE)
+ if(PCAP_TYPE STREQUAL "bpf")
+ #
+ # If we're using BPF, we need libodm and libcfg, as
+ # we use them to load the BPF module.
+ #
+ set(PCAP_LINK_LIBRARIES ${PCAP_LINK_LIBRARIES} odm cfg)
+ endif()
+elseif(CMAKE_SYSTEM_NAME STREQUAL "HP-UX")
+ if(CMAKE_SYSTEM_VERSION MATCHES "[A-Z.]*9\.[0-9]*")
+ #
+ # HP-UX 9.x.
+ #
+ set(HAVE_HPUX9 TRUE)
+ elseif(CMAKE_SYSTEM_VERSION MATCHES "[A-Z.]*10\.0")
+ #
+ # HP-UX 10.0.
+ #
+ elseif(CMAKE_SYSTEM_VERSION MATCHES "[A-Z.]*10\.1")
+ #
+ # HP-UX 10.1.
+ #
+ else()
+ #
+ # HP-UX 10.20 and later.
+ #
+ set(HAVE_HPUX10_20_OR_LATER TRUE)
+ endif()
+
+ #
+ # Use System V conventions for man pages.
+ #
+ set(MAN_ADMIN_COMMANDS 1m)
+ set(MAN_FILE_FORMATS 4)
+ set(MAN_MISC_INFO 5)
+elseif(CMAKE_SYSTEM_NAME STREQUAL "IRIX" OR CMAKE_SYSTEM_NAME STREQUAL "IRIX64")
+ #
+ # Use IRIX conventions for man pages; they're the same as the
+ # System V conventions, except that they use section 8 for
+ # administrative commands and daemons.
+ #
+ set(MAN_FILE_FORMATS 4)
+ set(MAN_MISC_INFO 5)
+elseif(CMAKE_SYSTEM_NAME STREQUAL "OSF1")
+ #
+ # DEC OSF/1, a/k/a Digial UNIX, a/k/a Tru64 UNIX.
+ # Use Tru64 UNIX conventions for man pages; they're the same as the
+ # System V conventions except that they use section 8 for
+ # administrative commands and daemons.
+ #
+ set(MAN_FILE_FORMATS 4)
+ set(MAN_MISC_INFO 5)
+elseif(CMAKE_SYSTEM_NAME STREQUAL "SunOS" AND CMAKE_SYSTEM_VERSION MATCHES "5[.][0-9.]*")
+ #
+ # SunOS 5.x.
+ #
+ set(HAVE_SOLARIS TRUE)
+ #
+ # Make sure errno is thread-safe, in case we're called in
+ # a multithreaded program. We don't guarantee that two
+ # threads can use the *same* pcap_t safely, but the
+ # current version does guarantee that you can use different
+ # pcap_t's in different threads, and even that pcap_compile()
+ # is thread-safe (it wasn't thread-safe in some older versions).
+ #
+ add_definitions(-D_TS_ERRNO)
+
+ if(CMAKE_SYSTEM_VERSION STREQUAL "5.12")
+ else()
+ #
+ # Use System V conventions for man pages.
+ #
+ set(MAN_ADMIN_COMMANDS 1m)
+ set(MAN_FILE_FORMATS 4)
+ set(MAN_MISC_INFO 5)
+ endif()
+endif()
+
+source_group("Source Files" FILES ${PROJECT_SOURCE_LIST_C})
+source_group("Header Files" FILES ${PROJECT_SOURCE_LIST_H})
+
+if(WIN32)
+ #
+ # Add pcap-dll.rc to the list of sources.
+ #
+ set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} ${pcap_SOURCE_DIR}/pcap-dll.rc)
+endif(WIN32)
+
+#
+# Add subdirectories after we've set various variables, so they pick up
+# pick up those variables.
+#
+if(ENABLE_REMOTE)
+ add_subdirectory(rpcapd)
+endif(ENABLE_REMOTE)
+add_subdirectory(testprogs)
+
+######################################
+# Register targets
+######################################
+
+#
+# Special target to serialize the building of the generated source.
+#
+# See
+#
+# http://public.kitware.com/pipermail/cmake/2013-August/055510.html
+#
+add_custom_target(SerializeTarget
+ DEPENDS
+ ${CMAKE_CURRENT_BINARY_DIR}/grammar.c
+ ${CMAKE_CURRENT_BINARY_DIR}/scanner.c
+)
+
+set_source_files_properties(${PROJECT_EXTERNAL_OBJECT_LIST} PROPERTIES
+ EXTERNAL_OBJECT TRUE)
+
+if(BUILD_SHARED_LIBS)
+ add_library(${LIBRARY_NAME} SHARED
+ ${PROJECT_SOURCE_LIST_C}
+ ${CMAKE_CURRENT_BINARY_DIR}/grammar.c
+ ${CMAKE_CURRENT_BINARY_DIR}/scanner.c
+ ${PROJECT_EXTERNAL_OBJECT_LIST}
+ )
+ add_dependencies(${LIBRARY_NAME} SerializeTarget)
+ set_target_properties(${LIBRARY_NAME} PROPERTIES
+ COMPILE_DEFINITIONS BUILDING_PCAP)
+endif(BUILD_SHARED_LIBS)
+
+add_library(${LIBRARY_NAME}_static STATIC
+ ${PROJECT_SOURCE_LIST_C}
+ ${CMAKE_CURRENT_BINARY_DIR}/grammar.c
+ ${CMAKE_CURRENT_BINARY_DIR}/scanner.c
+ ${PROJECT_EXTERNAL_OBJECT_LIST}
+)
+add_dependencies(${LIBRARY_NAME}_static SerializeTarget)
+set_target_properties(${LIBRARY_NAME}_static PROPERTIES
+ COMPILE_DEFINITIONS BUILDING_PCAP)
+
+if(WIN32)
+ if(BUILD_SHARED_LIBS)
+ set_target_properties(${LIBRARY_NAME} PROPERTIES
+ VERSION ${PACKAGE_VERSION_NOSUFFIX} # only MAJOR and MINOR are needed
+ )
+ endif(BUILD_SHARED_LIBS)
+ if(MSVC)
+ # XXX For DLLs, the TARGET_PDB_FILE generator expression can be used to locate
+ # its PDB file's output directory for installation.
+ # cmake doesn't offer a generator expression for PDB files generated by the
+ # compiler (static libraries).
+ # So instead of considering any possible output there is (there are many),
+ # this will search for the PDB file in the compiler's initial output directory,
+ # which is always ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles\wpcap_static.dir
+ # regardless of architecture, build generator etc.
+ # Quite hackish indeed.
+ set(CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY $<TARGET_FILE_DIR:${LIBRARY_NAME}_static>)
+ set_target_properties(${LIBRARY_NAME}_static PROPERTIES
+ COMPILE_PDB_NAME ${LIBRARY_NAME}_static
+ OUTPUT_NAME "${LIBRARY_NAME}_static"
+ )
+ elseif(MINGW)
+ #
+ # For compatibility, build the shared library without the "lib" prefix on
+ # MinGW as well.
+ #
+ set_target_properties(${LIBRARY_NAME} PROPERTIES
+ PREFIX ""
+ OUTPUT_NAME "${LIBRARY_NAME}"
+ )
+ set_target_properties(${LIBRARY_NAME}_static PROPERTIES
+ OUTPUT_NAME "${LIBRARY_NAME}"
+ )
+ endif()
+else(WIN32) # UN*X
+ if(BUILD_SHARED_LIBS)
+ if(APPLE)
+ set_target_properties(${LIBRARY_NAME} PROPERTIES
+ VERSION ${PACKAGE_VERSION}
+ SOVERSION A
+ )
+ else(APPLE)
+ set_target_properties(${LIBRARY_NAME} PROPERTIES
+ VERSION ${PACKAGE_VERSION}
+ SOVERSION ${PACKAGE_VERSION_MAJOR}
+ )
+ endif(APPLE)
+ endif(BUILD_SHARED_LIBS)
+ set_target_properties(${LIBRARY_NAME}_static PROPERTIES
+ OUTPUT_NAME "${LIBRARY_NAME}"
+ )
+endif(WIN32)
+
+if(BUILD_SHARED_LIBS)
+ if(NOT C_ADDITIONAL_FLAGS STREQUAL "")
+ set_target_properties(${LIBRARY_NAME} PROPERTIES COMPILE_FLAGS ${C_ADDITIONAL_FLAGS})
+ endif()
+ target_link_libraries(${LIBRARY_NAME} ${PCAP_LINK_LIBRARIES})
+endif(BUILD_SHARED_LIBS)
+
+if(NOT C_ADDITIONAL_FLAGS STREQUAL "")
+ set_target_properties(${LIBRARY_NAME}_static PROPERTIES COMPILE_FLAGS ${C_ADDITIONAL_FLAGS})
+endif()
+
+######################################
+# Write out the config.h file
+######################################
+
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmakeconfig.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h)
+
+######################################
+# Install pcap library, include files, and man pages
+######################################
+
+#
+# "Define GNU standard installation directories", which actually
+# are also defined, to some degree, by autotools, and at least
+# some of which are general UN*X conventions.
+#
+include(GNUInstallDirs)
+
+set(LIBRARY_NAME_STATIC ${LIBRARY_NAME}_static)
+
+function(install_manpage_symlink SOURCE TARGET MANDIR)
+ if(MINGW)
+ find_program(LINK_EXECUTABLE ln)
+ if(LINK_EXECUTABLE)
+ set(LINK_COMMAND "\"${LINK_EXECUTABLE}\" \"-s\" \"${SOURCE}\" \"${TARGET}\"")
+ else(LINK_EXECUTABLE)
+ message(FATAL_ERROR "ln (http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ln.html) not found.")
+ endif(LINK_EXECUTABLE)
+ else(MINGW)
+ set(LINK_COMMAND "\"${CMAKE_COMMAND}\" \"-E\" \"create_symlink\" \"${SOURCE}\" \"${TARGET}\"")
+ endif(MINGW)
+
+ install(CODE
+ "message(STATUS \"Symlinking: ${CMAKE_INSTALL_PREFIX}/${MANDIR}/${SOURCE} to ${TARGET}\")
+ execute_process(
+ COMMAND \"${CMAKE_COMMAND}\" \"-E\" \"remove\" \"${TARGET}\"
+ WORKING_DIRECTORY ${CMAKE_INSTALL_PREFIX}/${MANDIR}
+ )
+ execute_process(
+ COMMAND ${LINK_COMMAND}
+ WORKING_DIRECTORY ${CMAKE_INSTALL_PREFIX}/${MANDIR}
+ RESULT_VARIABLE EXIT_STATUS
+ )
+ if(NOT EXIT_STATUS EQUAL 0)
+ message(FATAL_ERROR \"Could not create symbolic link from ${CMAKE_INSTALL_PREFIX}/${MANDIR}/${SOURCE} to ${TARGET}\")
+ endif()
+ set(CMAKE_INSTALL_MANIFEST_FILES \${CMAKE_INSTALL_MANIFEST_FILES} ${CMAKE_INSTALL_PREFIX}/${MANDIR}/${TARGET})")
+endfunction(install_manpage_symlink)
+
+set(MAN1_NOEXPAND pcap-config.1)
+set(MAN3PCAP_EXPAND
+ pcap.3pcap.in
+ pcap_compile.3pcap.in
+ pcap_datalink.3pcap.in
+ pcap_dump_open.3pcap.in
+ pcap_get_tstamp_precision.3pcap.in
+ pcap_list_datalinks.3pcap.in
+ pcap_list_tstamp_types.3pcap.in
+ pcap_open_dead.3pcap.in
+ pcap_open_offline.3pcap.in
+ pcap_set_tstamp_precision.3pcap.in
+ pcap_set_tstamp_type.3pcap.in
+)
+set(MAN3PCAP_NOEXPAND
+ pcap_activate.3pcap
+ pcap_breakloop.3pcap
+ pcap_can_set_rfmon.3pcap
+ pcap_close.3pcap
+ pcap_create.3pcap
+ pcap_datalink_name_to_val.3pcap
+ pcap_datalink_val_to_name.3pcap
+ pcap_dump.3pcap
+ pcap_dump_close.3pcap
+ pcap_dump_file.3pcap
+ pcap_dump_flush.3pcap
+ pcap_dump_ftell.3pcap
+ pcap_file.3pcap
+ pcap_fileno.3pcap
+ pcap_findalldevs.3pcap
+ pcap_freecode.3pcap
+ pcap_get_required_select_timeout.3pcap
+ pcap_get_selectable_fd.3pcap
+ pcap_geterr.3pcap
+ pcap_inject.3pcap
+ pcap_is_swapped.3pcap
+ pcap_lib_version.3pcap
+ pcap_lookupdev.3pcap
+ pcap_lookupnet.3pcap
+ pcap_loop.3pcap
+ pcap_major_version.3pcap
+ pcap_next_ex.3pcap
+ pcap_offline_filter.3pcap
+ pcap_open_live.3pcap
+ pcap_set_buffer_size.3pcap
+ pcap_set_datalink.3pcap
+ pcap_set_immediate_mode.3pcap
+ pcap_set_promisc.3pcap
+ pcap_set_protocol.3pcap
+ pcap_set_rfmon.3pcap
+ pcap_set_snaplen.3pcap
+ pcap_set_timeout.3pcap
+ pcap_setdirection.3pcap
+ pcap_setfilter.3pcap
+ pcap_setnonblock.3pcap
+ pcap_snapshot.3pcap
+ pcap_stats.3pcap
+ pcap_statustostr.3pcap
+ pcap_strerror.3pcap
+ pcap_tstamp_type_name_to_val.3pcap
+ pcap_tstamp_type_val_to_name.3pcap
+)
+set(MANFILE_EXPAND pcap-savefile.manfile.in)
+set(MANMISC_EXPAND
+ pcap-filter.manmisc.in
+ pcap-linktype.manmisc.in
+ pcap-tstamp.manmisc.in
+)
+
+if(NOT BUILD_SHARED_LIBS)
+ unset(LIBRARY_NAME)
+endif(NOT BUILD_SHARED_LIBS)
+
+if(WIN32)
+ if(MSVC AND CMAKE_SIZEOF_VOID_P EQUAL 8)
+ #
+ # Install 64-bit code built with MSVC in the amd64 subdirectories,
+ # as that's where it expects it to be.
+ #
+ install(TARGETS ${LIBRARY_NAME} ${LIBRARY_NAME_STATIC}
+ RUNTIME DESTINATION bin/amd64
+ LIBRARY DESTINATION lib/amd64
+ ARCHIVE DESTINATION lib/amd64)
+ if(NOT MINGW)
+ install(FILES $<TARGET_FILE_DIR:${LIBRARY_NAME_STATIC}>/${LIBRARY_NAME_STATIC}.pdb
+ DESTINATION bin/amd64 OPTIONAL)
+ if(BUILD_SHARED_LIBS)
+ install(FILES $<TARGET_PDB_FILE:${LIBRARY_NAME}>
+ DESTINATION bin/amd64 OPTIONAL)
+ endif(BUILD_SHARED_LIBS)
+ endif(NOT MINGW)
+ else(MSVC AND CMAKE_SIZEOF_VOID_P EQUAL 8)
+ #
+ # Install 32-bit code, and 64-bit code not built with MSVC
+ # in the top-level directories, as those are where they
+ # expect it to be.
+ #
+ install(TARGETS ${LIBRARY_NAME} ${LIBRARY_NAME_STATIC}
+ RUNTIME DESTINATION bin
+ LIBRARY DESTINATION lib
+ ARCHIVE DESTINATION lib)
+ if(NOT MINGW)
+ install(FILES $<TARGET_FILE_DIR:${LIBRARY_NAME_STATIC}>/${LIBRARY_NAME_STATIC}.pdb
+ DESTINATION bin OPTIONAL)
+ if(BUILD_SHARED_LIBS)
+ install(FILES $<TARGET_PDB_FILE:${LIBRARY_NAME}>
+ DESTINATION bin OPTIONAL)
+ endif(BUILD_SHARED_LIBS)
+ endif(NOT MINGW)
+ endif(MSVC AND CMAKE_SIZEOF_VOID_P EQUAL 8)
+else(WIN32)
+ install(TARGETS ${LIBRARY_NAME} ${LIBRARY_NAME_STATIC} DESTINATION lib)
+endif(WIN32)
+
+install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/pcap/ DESTINATION include/pcap)
+install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/pcap.h DESTINATION include)
+
+# On UN*X, and on Windows when not using MSVC, generate libpcap.pc and
+# pcap-config and process man pages and arrange that they be installed.
+if(NOT MSVC)
+ set(PACKAGE_NAME ${LIBRARY_NAME})
+ set(prefix ${CMAKE_INSTALL_PREFIX})
+ set(exec_prefix "\${prefix}")
+ set(includedir "\${prefix}/include")
+ set(libdir "\${exec_prefix}/lib")
+ if(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD" OR
+ CMAKE_SYSTEM_NAME STREQUAL "NetBSD" OR
+ CMAKE_SYSTEM_NAME STREQUAL "OpenBSD" OR
+ CMAKE_SYSTEM_NAME STREQUAL "DragonFly BSD" OR
+ CMAKE_SYSTEM_NAME STREQUAL "Linux" OR
+ CMAKE_SYSTEM_NAME STREQUAL "OSF1")
+ #
+ # Platforms where the linker is the GNU linker
+ # or accepts command-line arguments like
+ # those the GNU linker accepts.
+ #
+ set(V_RPATH_OPT "-Wl,-rpath,")
+ elseif(CMAKE_SYSTEM_NAME STREQUAL "SunOS" AND CMAKE_SYSTEM_VERSION MATCHES "5[.][0-9.]*")
+ #
+ # SunOS 5.x.
+ #
+ # XXX - this assumes GCC is using the Sun linker,
+ # rather than the GNU linker.
+ #
+ set(V_RPATH_OPT "-Wl,-R,")
+ else()
+ #
+ # No option needed to set the RPATH.
+ #
+ set(V_RPATH_OPT "")
+ endif()
+ set(LIBS "")
+ 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)
+ install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/pcap-config DESTINATION bin)
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libpcap.pc DESTINATION lib/pkgconfig)
+
+ #
+ # Man pages.
+ #
+ # For each section of the manual for which we have man pages
+ # that require macro expansion, do the expansion.
+ #
+ set(MAN1 "")
+ foreach(MANPAGE ${MAN1_NOEXPAND})
+ set(MAN1 ${MAN1} ${CMAKE_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})
+ 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)
+ set(MAN3PCAP ${MAN3PCAP} ${CMAKE_CURRENT_BINARY_DIR}/${MANPAGE})
+ endforeach(TEMPLATE_MANPAGE)
+ install(FILES ${MAN3PCAP} DESTINATION ${CMAKE_INSTALL_MANDIR}/man3)
+ install_manpage_symlink(pcap_datalink_val_to_name.3pcap pcap_datalink_val_to_description.3pcap ${CMAKE_INSTALL_MANDIR}/man3)
+ install_manpage_symlink(pcap_dump_open.3pcap pcap_dump_fopen.3pcap ${CMAKE_INSTALL_MANDIR}/man3)
+ install_manpage_symlink(pcap_findalldevs.3pcap pcap_freealldevs.3pcap ${CMAKE_INSTALL_MANDIR}/man3)
+ install_manpage_symlink(pcap_geterr.3pcap pcap_perror.3pcap ${CMAKE_INSTALL_MANDIR}/man3)
+ install_manpage_symlink(pcap_inject.3pcap pcap_sendpacket.3pcap ${CMAKE_INSTALL_MANDIR}/man3)
+ install_manpage_symlink(pcap_list_datalinks.3pcap pcap_free_datalinks.3pcap ${CMAKE_INSTALL_MANDIR}/man3)
+ install_manpage_symlink(pcap_list_tstamp_types.3pcap pcap_free_tstamp_types.3pcap ${CMAKE_INSTALL_MANDIR}/man3)
+ install_manpage_symlink(pcap_loop.3pcap pcap_dispatch.3pcap ${CMAKE_INSTALL_MANDIR}/man3)
+ install_manpage_symlink(pcap_major_version.3pcap pcap_minor_version.3pcap ${CMAKE_INSTALL_MANDIR}/man3)
+ install_manpage_symlink(pcap_next_ex.3pcap pcap_next.3pcap ${CMAKE_INSTALL_MANDIR}/man3)
+ install_manpage_symlink(pcap_open_dead.3pcap pcap_open_dead_with_tstamp_precision.3pcap ${CMAKE_INSTALL_MANDIR}/man3)
+ install_manpage_symlink(pcap_open_offline.3pcap pcap_open_offline_with_tstamp_precision.3pcap ${CMAKE_INSTALL_MANDIR}/man3)
+ install_manpage_symlink(pcap_open_offline.3pcap pcap_fopen_offline.3pcap ${CMAKE_INSTALL_MANDIR}/man3)
+ install_manpage_symlink(pcap_open_offline.3pcap pcap_fopen_offline_with_tstamp_precision.3pcap ${CMAKE_INSTALL_MANDIR}/man3)
+ install_manpage_symlink(pcap_tstamp_type_val_to_name.3pcap pcap_tstamp_type_val_to_description.3pcap ${CMAKE_INSTALL_MANDIR}/man3)
+ install_manpage_symlink(pcap_setnonblock.3pcap pcap_getnonblock.3pcap ${CMAKE_INSTALL_MANDIR}/man3)
+
+ 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)
+ set(MANFILE ${MANFILE} ${CMAKE_CURRENT_BINARY_DIR}/${MANPAGE})
+ endforeach(TEMPLATE_MANPAGE)
+ install(FILES ${MANFILE} DESTINATION ${CMAKE_INSTALL_MANDIR}/man${MAN_FILE_FORMATS})
+
+ 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)
+ set(MANMISC ${MANMISC} ${CMAKE_CURRENT_BINARY_DIR}/${MANPAGE})
+ endforeach(TEMPLATE_MANPAGE)
+ install(FILES ${MANMISC} DESTINATION ${CMAKE_INSTALL_MANDIR}/man${MAN_MISC_INFO})
+endif(NOT MSVC)
+
+# uninstall target
+configure_file(
+ "${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
+ IMMEDIATE @ONLY)
+
+add_custom_target(uninstall
+ COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
diff --git a/contrib/libpcap/CONTRIBUTING b/contrib/libpcap/CONTRIBUTING
new file mode 100644
index 0000000000000..a3c2bd68d027c
--- /dev/null
+++ b/contrib/libpcap/CONTRIBUTING
@@ -0,0 +1,29 @@
+Guidelines for contributing
+===========================
+
+To report a security issue (segfault, buffer overflow, infinite loop, arbitrary
+code execution etc) please send an e-mail to security@tcpdump.org, do not use
+the bug tracker!
+
+To report a non-security problem (failure to compile, failure to capture packets
+properly, missing support for a network interface type or DLT) please check
+first that it reproduces with the latest stable release of libpcap. If it does,
+please check that the problem reproduces with the current git master branch of
+libpcap. If it does (and it is not a security-related problem, otherwise see
+above), please navigate to https://github.com/the-tcpdump-group/libpcap/issues
+and check if the problem has already been reported. If it has not, please open
+a new issue and provide the following details:
+
+* libpcap version (e.g. from tcpdump --version)
+* operating system name and version and any other details that may be relevant
+ (uname -a, compiler name and version, CPU type etc.)
+* configure flags if any were used
+* statement of the problem
+* steps to reproduce
+
+Please note that if you know exactly how to solve the problem and the solution
+would not be too intrusive, it would be best to contribute some development time
+and open a pull request instead.
+
+Still not sure how to do? Feel free to [subscribe](http://www.tcpdump.org/#mailing-lists)
+to the mailing list tcpdump-workers@lists.tcpdump.org and ask!
diff --git a/contrib/libpcap/CREDITS b/contrib/libpcap/CREDITS
index b40152f5e54bb..b959c77c07e81 100644
--- a/contrib/libpcap/CREDITS
+++ b/contrib/libpcap/CREDITS
@@ -64,7 +64,7 @@ Additional people who have contributed patches:
George Neville-Neil <gnn at freebsd dot org>
Gianluca Varenni <gianluca dot varenni at gmail dot com>
Gilbert Hoyek <gil_hoyek at hotmail dot com>
- Gisle Vanem <gvanem at broadpark dot no>
+ Gisle Vanem <gvanem at yahoo dot no>
Graeme Hewson <ghewson at cix dot compulink dot co dot uk>
Gregor Maier <gregor at net dot in dot tum dot de>
Greg Stark <gsstark at mit dot edu>
diff --git a/contrib/libpcap/ChmodBPF/ChmodBPF b/contrib/libpcap/ChmodBPF/ChmodBPF
new file mode 100755
index 0000000000000..ee3712184535f
--- /dev/null
+++ b/contrib/libpcap/ChmodBPF/ChmodBPF
@@ -0,0 +1,33 @@
+#! /bin/sh
+
+. /etc/rc.common
+
+StartService ()
+{
+ #
+ # Unfortunately, Mac OS X's devfs is based on the old FreeBSD
+ # one, not the current one, so there's no way to configure it
+ # to create BPF devices with particular owners or groups.
+ # This startup item will make it owned by the admin group,
+ # with permissions rw-rw----, so that anybody in the admin
+ # group can use programs that capture or send raw packets.
+ #
+ # Change this as appropriate for your site, e.g. to make
+ # it owned by a particular user without changing the permissions,
+ # so only that user and the super-user can capture or send raw
+ # packets, or give it the permissions rw-r-----, so that
+ # only the super-user can send raw packets but anybody in the
+ # admin group can capture packets.
+ #
+ chgrp admin /dev/bpf*
+ chmod g+rw /dev/bpf*
+}
+
+StopService ()
+{
+ return 0;
+}
+
+RestartService () { StartService; }
+
+RunService "$1"
diff --git a/contrib/libpcap/ChmodBPF/StartupParameters.plist b/contrib/libpcap/ChmodBPF/StartupParameters.plist
new file mode 100644
index 0000000000000..cba21664fea29
--- /dev/null
+++ b/contrib/libpcap/ChmodBPF/StartupParameters.plist
@@ -0,0 +1,4 @@
+{
+ Description = "Change BPF permissions";
+ Provides = ("ChmodBPF");
+}
diff --git a/contrib/libpcap/INSTALL.txt b/contrib/libpcap/INSTALL.txt
index f305aa2b7929c..e39c122a341b7 100644
--- a/contrib/libpcap/INSTALL.txt
+++ b/contrib/libpcap/INSTALL.txt
@@ -250,28 +250,13 @@ libpcap program and it dies with:
You must add streams NIT support to your kernel configuration, run
config and boot the new kernel.
-If you are running a version of SunOS earlier than 4.1, you will need
-to replace the Sun supplied /sys/sun{3,4,4c}/OBJ/nit_if.o with the
-appropriate version from this distribution's SUNOS4 subdirectory and
-build a new kernel:
-
- nit_if.o.sun3-sunos4 (any flavor of sun3)
- nit_if.o.sun4c-sunos4.0.3c (SS1, SS1+, IPC, SLC, etc.)
- nit_if.o.sun4-sunos4 (Sun4's not covered by
- nit_if.o.sun4c-sunos4.0.3c)
-
-These nit replacements fix a bug that makes nit essentially unusable in
-pre-SunOS 4.1. In addition, our sun4c-sunos4.0.3c nit gives you
-timestamps to the resolution of the SS-1 clock (1 us) rather than the
-lousy 20ms timestamps Sun gives you (tcpdump will print out the full
-timestamp resolution if it finds it's running on a SS-1).
-
FILES
-----
CHANGES - description of differences between releases
-ChmodBPF/* - Mac OS X startup item to set ownership and permissions
+ChmodBPF/* - macOS startup item to set ownership and permissions
on /dev/bpf*
CMakeLists.txt - CMake file
+CONTRIBUTING - guidelines for contributing
CREDITS - people that have helped libpcap along
INSTALL.txt - this file
LICENSE - the license under which tcpdump is distributed
@@ -281,12 +266,11 @@ README.aix - notes on using libpcap on AIX
README.dag - notes on using libpcap to capture on Endace DAG devices
README.hpux - notes on using libpcap on HP-UX
README.linux - notes on using libpcap on Linux
-README.macosx - notes on using libpcap on Mac OS X
+README.macos - notes on using libpcap on macOS
README.septel - notes on using libpcap to capture on Intel/Septel devices
README.sita - notes on using libpcap to capture on SITA devices
README.tru64 - notes on using libpcap on Digital/Tru64 UNIX
README.Win32 - notes on using libpcap on Win32 systems (with WinPcap)
-SUNOS4 - pre-SunOS 4.1 replacement kernel nit modules
VERSION - version of this release
acconfig.h - support for post-2.13 autoconf
aclocal.m4 - autoconf macros
@@ -314,7 +298,6 @@ gencode.c - BPF code generation routines
gencode.h - BPF code generation definitions
grammar.y - filter string grammar
ieee80211.h - 802.11 definitions
-inet.c - network routines
install-sh - BSD style install script
lbl/os-*.h - OS-dependent defines and prototypes
llc.h - 802.2 LLC SAP definitions
@@ -347,6 +330,7 @@ pcap-linux.c - Linux packet socket support
pcap-namedb.h - header for backwards compatibility
pcap-nit.c - SunOS Network Interface Tap support
pcap-nit.h - SunOS Network Interface Tap definitions
+pcap-npf.c - WinPcap capture support
pcap-null.c - dummy monitor support (allows offline use of libpcap)
pcap-pf.c - Ultrix and Digital/Tru64 UNIX Packet Filter support
pcap-pf.h - Ultrix and Digital/Tru64 UNIX Packet Filter definitions
@@ -360,7 +344,6 @@ pcap-snit.c - SunOS 4.x STREAMS-based Network Interface Tap support
pcap-snoop.c - IRIX Snoop network monitoring support
pcap-usb-linux.c - USB capture support for Linux
pcap-usb-linux.h - USB capture support for Linux
-pcap-win32.c - WinPcap capture support
pcap.3pcap - manual entry for the library
pcap.c - pcap utility routines
pcap.h - header for backwards compatibility
diff --git a/contrib/libpcap/Makefile.in b/contrib/libpcap/Makefile.in
index e71d973ca448c..6fcd3afc4e006 100644
--- a/contrib/libpcap/Makefile.in
+++ b/contrib/libpcap/Makefile.in
@@ -27,6 +27,8 @@ exec_prefix = @exec_prefix@
datarootdir = @datarootdir@
# Pathname of directory to install the configure program
bindir = @bindir@
+# Pathname of directory to install the rpcapd daemon
+sbindir = @sbindir@
# Pathname of directory to install the include files
includedir = @includedir@
# Pathname of directory to install the library
@@ -48,8 +50,9 @@ AR = @AR@
LN_S = @LN_S@
MKDEP = @MKDEP@
CCOPT = @V_CCOPT@
+SHLIB_CCOPT = @V_SHLIB_CCOPT@
INCLS = -I. @V_INCLS@
-DEFS = -DBUILDING_PCAP @DEFS@ @V_DEFS@
+DEFS = -DBUILDING_PCAP -Dpcap_EXPORTS @DEFS@ @V_DEFS@
ADDLOBJS = @ADDLOBJS@
ADDLARCHIVEOBJS = @ADDLARCHIVEOBJS@
LIBS = @LIBS@
@@ -60,9 +63,13 @@ DYEXT = @DYEXT@
V_RPATH_OPT = @V_RPATH_OPT@
DEPENDENCY_CFLAG = @DEPENDENCY_CFLAG@
PROG=libpcap
+PTHREAD_LIBS=@PTHREAD_LIBS@
+BUILD_RPCAPD=@BUILD_RPCAPD@
+INSTALL_RPCAPD=@INSTALL_RPCAPD@
+EXTRA_NETWORK_LIBS=@EXTRA_NETWORK_LIBS@
-# Standard CFLAGS
-FULL_CFLAGS = $(CCOPT) $(INCLS) $(DEFS) $(CFLAGS)
+# Standard CFLAGS for building members of a shared library
+FULL_CFLAGS = $(CCOPT) $(SHLIB_CCOPT) $(INCLS) $(DEFS) $(CFLAGS)
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
@@ -79,13 +86,14 @@ YACC = @YACC@
@rm -f $@
$(CC) $(FULL_CFLAGS) -c $(srcdir)/$*.c
-PSRC = pcap-@V_PCAP@.c @USB_SRC@ @BT_SRC@ @BT_MONITOR_SRC@ @NETFILTER_SRC@ @DBUS_SRC@
+PSRC = pcap-@V_PCAP@.c @USB_SRC@ @BT_SRC@ @BT_MONITOR_SRC@ @NETFILTER_SRC@ @DBUS_SRC@ @NETMAP_SRC@ @RDMA_SRC@
FSRC = @V_FINDALLDEVS@
SSRC = @SSRC@
-CSRC = pcap.c inet.c fad-helpers.c gencode.c optimize.c nametoaddr.c \
- etherent.c savefile.c sf-pcap.c sf-pcap-ng.c pcap-common.c \
- bpf_image.c bpf_dump.c
-GENSRC = scanner.c grammar.c bpf_filter.c version.c
+CSRC = pcap.c gencode.c optimize.c nametoaddr.c etherent.c \
+ fmtutils.c \
+ savefile.c sf-pcap.c sf-pcapng.c pcap-common.c \
+ bpf_image.c bpf_filter.c bpf_dump.c
+GENSRC = scanner.c grammar.c
LIBOBJS = @LIBOBJS@
SRC = $(PSRC) $(FSRC) $(CSRC) $(SSRC) $(GENSRC)
@@ -100,8 +108,10 @@ PUBHDR = \
pcap/bpf.h \
pcap/bluetooth.h \
pcap/can_socketcan.h \
+ pcap/compiler-tests.h \
pcap/dlt.h \
- pcap/export-defs.h \
+ pcap/funcattrs.h \
+ pcap/pcap-inttypes.h \
pcap/ipnet.h \
pcap/namedb.h \
pcap/nflog.h \
@@ -113,51 +123,38 @@ PUBHDR = \
HDR = $(PUBHDR) \
arcnet.h \
atmuni31.h \
+ diag-control.h \
ethertype.h \
extract.h \
+ fmtutils.h \
+ ftmacros.h \
gencode.h \
ieee80211.h \
llc.h \
nametoaddr.h \
nlpid.h \
+ optimize.h \
pcap-common.h \
pcap-int.h \
- pcap-stdinc.h \
+ pcap-rpcap.h \
+ pcap-types.h \
portability.h \
ppp.h \
+ rpcap-protocol.h \
sf-pcap.h \
- sf-pcap-ng.h \
- sunatmpos.h
-
-TESTS = \
- @VALGRINDTEST@ \
- capturetest \
- can_set_rfmon_test \
- filtertest \
- findalldevstest \
- opentest \
- reactivatetest \
- selpolltest
-
-TESTS_SRC = \
- tests/valgrindtest.c \
- tests/capturetest.c \
- tests/can_set_rfmon_test.c \
- tests/filtertest.c \
- tests/findalldevstest.c \
- tests/opentest.c \
- tests/reactivatetest.c \
- tests/selpolltest.c
+ sf-pcapng.h \
+ sunatmpos.h \
+ varattrs.h
GENHDR = \
- scanner.h grammar.h pcap_version.h
+ scanner.h grammar.h
TAGFILES = \
$(SRC) $(HDR)
-CLEANFILES = $(OBJ) libpcap.* $(TESTS) \
+CLEANFILES = $(OBJ) libpcap.a libpcap.so.`cat $(srcdir)/VERSION` \
$(PROG)-`cat $(srcdir)/VERSION`.tar.gz $(GENSRC) $(GENHDR) \
- lex.yy.c pcap-config
+ lex.yy.c pcap-config libpcap.pc
MAN1 = pcap-config.1
@@ -191,6 +188,7 @@ MAN3PCAP_NOEXPAND = \
pcap_fileno.3pcap \
pcap_findalldevs.3pcap \
pcap_freecode.3pcap \
+ pcap_get_required_select_timeout.3pcap \
pcap_get_selectable_fd.3pcap \
pcap_geterr.3pcap \
pcap_inject.3pcap \
@@ -207,6 +205,7 @@ MAN3PCAP_NOEXPAND = \
pcap_set_datalink.3pcap \
pcap_set_immediate_mode.3pcap \
pcap_set_promisc.3pcap \
+ pcap_set_protocol.3pcap \
pcap_set_rfmon.3pcap \
pcap_set_snaplen.3pcap \
pcap_set_timeout.3pcap \
@@ -231,13 +230,11 @@ MANMISC = \
pcap-tstamp.manmisc.in
EXTRA_DIST = \
- $(TESTS_SRC) \
CHANGES \
ChmodBPF/ChmodBPF \
ChmodBPF/StartupParameters.plist \
CREDITS \
CMakeLists.txt \
- GenVersion.bat \
INSTALL.txt \
LICENSE \
Makefile.in \
@@ -247,22 +244,25 @@ EXTRA_DIST = \
README.dag \
README.hpux \
README.linux \
- README.macosx \
+ README.macos \
README.septel \
README.sita \
README.tru64 \
README.Win32 \
- SUNOS4/nit_if.o.sparc \
- SUNOS4/nit_if.o.sun3 \
- SUNOS4/nit_if.o.sun4c.4.0.3c \
+ CONTRIBUTING \
TODO \
VERSION \
aclocal.m4 \
- bpf/net/bpf_filter.c \
chmod_bpf \
+ cmake_uninstall.cmake.in \
cmakeconfig.h.in \
- cmake/preconfigure.cmake \
- config/have_siocglifconf.c \
+ cmake/Modules/FindDAG.cmake \
+ cmake/Modules/FindFseeko.cmake \
+ cmake/Modules/FindLFS.cmake \
+ cmake/Modules/FindPacket.cmake \
+ cmake/Modules/FindSNF.cmake \
+ cmake/Modules/FindTC.cmake \
+ cmake/have_siocglifconf.c \
config.guess \
config.h.in \
config.sub \
@@ -273,9 +273,6 @@ EXTRA_DIST = \
fad-getad.c \
fad-gifc.c \
fad-glifc.c \
- fad-helpers.c \
- gen_version_c.sh \
- gen_version_header.sh \
grammar.y \
install-sh \
lbl/os-aix4.h \
@@ -286,6 +283,7 @@ EXTRA_DIST = \
lbl/os-solaris2.h \
lbl/os-sunos4.h \
lbl/os-ultrix4.h \
+ libpcap.pc.in \
missing/getopt.c \
missing/getopt.h \
missing/snprintf.c \
@@ -293,18 +291,15 @@ EXTRA_DIST = \
missing/win_snprintf.c \
mkdep \
msdos/bin2c.c \
- msdos/common.dj \
msdos/makefile \
msdos/makefile.dj \
msdos/makefile.wc \
- msdos/ndis2.c \
- msdos/ndis2.h \
- msdos/ndis_0.asm \
msdos/pkt_rx0.asm \
msdos/pkt_rx1.s \
msdos/pktdrvr.c \
msdos/pktdrvr.h \
msdos/readme.dos \
+ nomkdep \
org.tcpdump.chmod_bpf.plist \
pcap-bpf.c \
pcap-bt-linux.c \
@@ -316,6 +311,7 @@ EXTRA_DIST = \
pcap-dag.h \
pcap-dbus.c \
pcap-dbus.h \
+ pcap-dll.rc \
pcap-dlpi.c \
pcap-dos.c \
pcap-dos.h \
@@ -327,11 +323,16 @@ EXTRA_DIST = \
pcap-new.c \
pcap-netfilter-linux.c \
pcap-netfilter-linux.h \
+ pcap-netmap.c \
+ pcap-netmap.h \
pcap-nit.c \
+ pcap-npf.c \
pcap-null.c \
pcap-pf.c \
+ pcap-rdmasniff.c \
+ pcap-rdmasniff.h \
pcap-rpcap.c \
- pcap-rpcap.h \
+ pcap-rpcap-int.h \
pcap-septel.c \
pcap-septel.h \
pcap-sita.h \
@@ -345,20 +346,47 @@ EXTRA_DIST = \
pcap-tc.h \
pcap-usb-linux.c \
pcap-usb-linux.h \
- pcap-win32.c \
- remote-ext.h \
+ rpcap-protocol.c \
+ rpcapd/CMakeLists.txt \
+ rpcapd/Makefile.in \
+ rpcapd/config_params.h \
+ rpcapd/daemon.h \
+ rpcapd/daemon.c \
+ rpcapd/fileconf.c \
+ rpcapd/fileconf.h \
+ rpcapd/log.h \
+ rpcapd/log-stderr.c \
+ rpcapd/org.tcpdump.rpcapd.plist \
+ rpcapd/rpcapd.c \
+ rpcapd/rpcapd.h \
+ rpcapd/rpcapd.inetd.conf \
+ rpcapd/rpcapd.manadmin.in \
+ rpcapd/rpcapd.rc \
+ rpcapd/rpcapd.socket \
+ rpcapd/rpcapd.xinetd.conf \
+ rpcapd/rpcapd@.service \
+ rpcapd/win32-svc.h \
sockutils.c \
sockutils.h \
scanner.l \
- tests/CMakeLists.txt \
- pcap_version.h.in \
- Win32/Include/Gnuc.h \
- Win32/Include/net/if.h \
+ testprogs/CMakeLists.txt \
+ testprogs/Makefile.in \
+ testprogs/can_set_rfmon_test.c \
+ testprogs/capturetest.c \
+ testprogs/filtertest.c \
+ testprogs/findalldevstest.c \
+ testprogs/opentest.c \
+ testprogs/reactivatetest.c \
+ testprogs/selpolltest.c \
+ testprogs/threadsignaltest.c \
+ testprogs/unix.h \
+ testprogs/valgrindtest.c \
+ tests/shb-option-too-long.pcapng \
Win32/Prj/wpcap.sln \
Win32/Prj/wpcap.vcxproj \
Win32/Prj/wpcap.vcxproj.filters
-all: libpcap.a shared pcap-config
+all: libpcap.a shared $(BUILD_RPCAPD) libpcap.pc pcap-config
libpcap.a: $(OBJ)
@rm -f $@
@@ -371,20 +399,18 @@ libpcap.so: $(OBJ)
@rm -f $@
VER=`cat $(srcdir)/VERSION`; \
MAJOR_VER=`sed 's/\([0-9][0-9]*\)\..*/\1/' $(srcdir)/VERSION`; \
- @V_SHLIB_CMD@ @V_SHLIB_OPT@ @V_SONAME_OPT@$@.$$MAJOR_VER $(LDFLAGS) \
+ @V_SHLIB_CMD@ $(LDFLAGS) @V_SHLIB_OPT@ @V_SONAME_OPT@$@.$$MAJOR_VER \
-o $@.$$VER $(OBJ) $(ADDLOBJS) $(LIBS)
#
# The following rule succeeds, but the result is untested.
#
-# In Mac OS X, the libpcap dylib has the name "libpcap.A.dylib", with
-# its full path as the install_name, and with the compatibility and
-# current version both set to 1. The compatibility version is set to
-# 1 so that programs built with a newer version of the library will run
-# against older versions; multi-platform software probably will fail if
-# it uses APIs added in the newer version, but Mac OS X-specific software
-# will use weak linking and check at run time whether those APIs are
-# available.
+# In macOS, the libpcap dylib has the name "libpcap.A.dylib", with its
+# full path as the install_name, and with the compatibility and current
+# version both set to 1. The compatibility version is set to 1 so that
+# programs built with a newer version of the library will run against
+# older versions if they don't use APIs available in the newer version
+# but not in the older version.
#
# We also use "A" as the major version, and 1 as the compatibility version,
# but set the current version to the value in VERSION, with any non-numeric
@@ -434,7 +460,7 @@ libpcap.sl: $(OBJ)
#
libpcap.shareda: $(OBJ)
@rm -f $@ shr.o
- $(CC) @V_SHLIB_OPT@ -o shr.o $(OBJ) $(ADDLOBJS) $(LDFLAGS) $(LIBS)
+ $(CC) $(LDFLAGS) @V_SHLIB_OPT@ -o shr.o $(OBJ) $(ADDLOBJS) $(LIBS)
$(AR) rc $@ shr.o
#
@@ -455,8 +481,6 @@ scanner.h: scanner.c
scanner.o: scanner.c grammar.h
$(CC) $(FULL_CFLAGS) -c scanner.c
-pcap.o: pcap_version.h
-
grammar.c: $(srcdir)/grammar.y
$(YACC) -p pcap_ -o grammar.c -d $<
grammar.h: grammar.c
@@ -466,43 +490,20 @@ grammar.h: grammar.c
$(MAKE) $(MAKEFLAGS) grammar.c; \
fi
-grammar.o: grammar.c
+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
-version.o: version.c
- $(CC) $(FULL_CFLAGS) -c version.c
-
snprintf.o: $(srcdir)/missing/snprintf.c
$(CC) $(FULL_CFLAGS) -o $@ -c $(srcdir)/missing/snprintf.c
strtok_r.o: $(srcdir)/missing/strtok_r.c
$(CC) $(FULL_CFLAGS) -o $@ -c $(srcdir)/missing/strtok_r.c
-version.c: $(srcdir)/VERSION $(srcdir)/gen_version_c.sh
- #
- # Older programs import this if they want to show the
- # libpcap version number, rather than calling
- # pcap_lib_version(), so we need to export it.
- #
- @rm -f $@
- $(srcdir)/gen_version_c.sh $(srcdir)/VERSION $@
-
-pcap_version.h: $(srcdir)/VERSION $(srcdir)/pcap_version.h.in $(srcdir)/gen_version_header.sh
- @rm -f $@
- $(srcdir)/gen_version_header.sh $(srcdir)/VERSION $(srcdir)/pcap_version.h.in $@
-
-bpf_filter.c: $(srcdir)/bpf/net/bpf_filter.c
- rm -f bpf_filter.c
- ln -s $(srcdir)/bpf/net/bpf_filter.c bpf_filter.c
-
-bpf_filter.o: bpf_filter.c
- $(CC) $(FULL_CFLAGS) -c bpf_filter.c
-
#
-# Generate the pcap-config script.
+# Generate the libpcap.pc file.
#
# Some Makes, e.g. AIX Make and Solaris Make, can't handle "--file=$@.tmp:$<";
# for example, the Solaris 9 make man page says
@@ -513,7 +514,16 @@ bpf_filter.o: bpf_filter.c
#
# and this is an explicit target entry.
#
-# Therefore, instead of using $<, we explicitly put in $(srcdir)/pcap-config.in.
+# Therefore, instead of using $<, we explicitly put in $(srcdir)/libpcap.pc.in.
+#
+libpcap.pc: $(srcdir)/libpcap.pc.in ./config.status
+ @rm -f $@ $@.tmp
+ ./config.status --file=$@.tmp:$(srcdir)/libpcap.pc.in
+ mv $@.tmp $@
+ chmod a+x $@
+
+#
+# Generate the pcap-config script. See above.
#
pcap-config: $(srcdir)/pcap-config.in ./config.status
@rm -f $@ $@.tmp
@@ -522,35 +532,20 @@ pcap-config: $(srcdir)/pcap-config.in ./config.status
chmod a+x $@
#
-# Test programs - not built by default, and not installed.
+# Remote pcap daemon.
#
-tests: $(TESTS)
-
-capturetest: tests/capturetest.c libpcap.a
- $(CC) $(FULL_CFLAGS) -I. -L. -o capturetest $(srcdir)/tests/capturetest.c libpcap.a $(LIBS)
-
-can_set_rfmon_test: tests/can_set_rfmon_test.c libpcap.a
- $(CC) $(FULL_CFLAGS) -I. -L. -o can_set_rfmon_test $(srcdir)/tests/can_set_rfmon_test.c libpcap.a $(LIBS)
-
-filtertest: tests/filtertest.c libpcap.a
- $(CC) $(FULL_CFLAGS) -I. -L. -o filtertest $(srcdir)/tests/filtertest.c libpcap.a $(LIBS)
-
-findalldevstest: tests/findalldevstest.c libpcap.a
- $(CC) $(FULL_CFLAGS) -I. -L. -o findalldevstest $(srcdir)/tests/findalldevstest.c libpcap.a $(LIBS)
+build-rpcapd: libpcap.a
+ cd rpcapd; $(MAKE)
-opentest: tests/opentest.c libpcap.a
- $(CC) $(FULL_CFLAGS) -I. -L. -o opentest $(srcdir)/tests/opentest.c libpcap.a $(LIBS)
-
-reactivatetest: tests/reactivatetest.c libpcap.a
- $(CC) $(FULL_CFLAGS) -I. -L. -o reactivatetest $(srcdir)/tests/reactivatetest.c libpcap.a $(LIBS)
-
-selpolltest: tests/selpolltest.c libpcap.a
- $(CC) $(FULL_CFLAGS) -I. -L. -o selpolltest $(srcdir)/tests/selpolltest.c libpcap.a $(LIBS)
+#
+# Test programs - not built by default, and not installed.
+#
+testprogs: FORCE
+ cd testprogs; $(MAKE)
-valgrindtest: tests/valgrindtest.c libpcap.a
- $(CC) $(FULL_CFLAGS) -I. -L. -o valgrindtest $(srcdir)/tests/valgrindtest.c libpcap.a $(LIBS)
+FORCE:
-install: install-shared install-archive pcap-config
+install: install-shared install-archive libpcap.pc pcap-config @INSTALL_RPCAPD@
[ -d $(DESTDIR)$(libdir) ] || \
(mkdir -p $(DESTDIR)$(libdir); chmod 755 $(DESTDIR)$(libdir))
[ -d $(DESTDIR)$(includedir) ] || \
@@ -571,6 +566,9 @@ install: install-shared install-archive pcap-config
[ -d $(DESTDIR)$(bindir) ] || \
(mkdir -p $(DESTDIR)$(bindir); chmod 755 $(DESTDIR)$(bindir))
$(INSTALL_PROGRAM) pcap-config $(DESTDIR)$(bindir)/pcap-config
+ [ -d $(DESTDIR)$(libdir)/pkgconfig ] || \
+ (mkdir -p $(DESTDIR)$(libdir)/pkgconfig; chmod 755 $(DESTDIR)$(libdir)/pkgconfig)
+ $(INSTALL_DATA) libpcap.pc $(DESTDIR)$(libdir)/pkgconfig/libpcap.pc
for i in $(MAN1); do \
$(INSTALL_DATA) $(srcdir)/$$i \
$(DESTDIR)$(mandir)/man1/$$i; done
@@ -671,11 +669,15 @@ install-archive-shareda:
# library on AIX.
#
-uninstall: uninstall-shared
+install-rpcapd:
+ cd rpcapd; $(MAKE) DESTDIR=$(DESTDIR) install
+
+uninstall: uninstall-shared uninstall-rpcapd
rm -f $(DESTDIR)$(libdir)/libpcap.a
for i in $(PUBHDR); do \
rm -f $(DESTDIR)$(includedir)/$$i; done
-rmdir $(DESTDIR)$(includedir)/pcap
+ rm -f $(DESTDIR)/$(libdir)/pkgconfig/libpcap.pc
rm -f $(DESTDIR)/$(bindir)/pcap-config
for i in $(MAN1); do \
rm -f $(DESTDIR)$(mandir)/man1/$$i; done
@@ -723,15 +725,22 @@ uninstall-shared-shareda:
rm -f $(DESTDIR)$(libdir)/libpcap.a
uninstall-shared-none:
+uninstall-rpcapd:
+ cd rpcapd; $(MAKE) DESTDIR=$(DESTDIR) uninstall
+
clean:
rm -f $(CLEANFILES)
+ cd rpcapd; $(MAKE) clean
+ cd testprogs; $(MAKE) clean
distclean: clean
rm -f Makefile config.cache config.log config.status \
- config.h gnuc.h net os-proto.h bpf_filter.c pcap-config \
- stamp-h stamp-h.in
+ config.h gnuc.h net os-proto.h libpcap.pc \
+ pcap-config stamp-h stamp-h.in
rm -f $(MAN3PCAP_EXPAND:.in=) $(MANFILE:.in=) $(MANMISC:.in=)
rm -rf autom4te.cache
+ cd rpcapd; $(MAKE) distclean
+ cd testprogs; $(MAKE) distclean
extags: $(TAGFILES)
ctags $(TAGFILES)
@@ -748,5 +757,7 @@ releasetar:
tar -c -z -f $$name.tar.gz $$name; \
rm -rf $$name
-depend: $(GENSRC) $(GENHDR) bpf_filter.c
- $(MKDEP) -c $(CC) -m $(CFLAGS) $(DEPENDENCY_CFLAG) $(DEFS) $(INCLS) $(SRC)
+depend: $(GENSRC) $(GENHDR)
+ $(MKDEP) -c "$(CC)" -m "$(DEPENDENCY_CFLAG)" $(CFLAGS) $(DEFS) $(INCLS) $(SRC)
+ cd rpcapd; $(MAKE) depend
+ cd testprogs; $(MAKE) depend
diff --git a/contrib/libpcap/README b/contrib/libpcap/README
index 9f65948d4ef2e..24fdc80d6989c 100644
--- a/contrib/libpcap/README
+++ b/contrib/libpcap/README
@@ -1,19 +1,16 @@
-LIBPCAP 1.x.y
+To report a security issue please send an e-mail to security@tcpdump.org.
-www.tcpdump.org
+To report bugs and other problems, contribute patches, request a
+feature, provide generic feedback etc please see the file
+CONTRIBUTING in the libpcap source tree root.
-Please send inquiries/comments/reports to:
- tcpdump-workers@lists.tcpdump.org
+LIBPCAP 1.x.y
+Now maintained by "The Tcpdump Group"
+https://www.tcpdump.org
Anonymous Git is available via:
git clone git://bpf.tcpdump.org/libpcap
-Please submit patches by forking the branch on GitHub at
-
- http://github.com/the-tcpdump-group/libpcap/tree/master
-
-and issuing a pull request.
-
formerly from Lawrence Berkeley National Laboratory
Network Research Group <libpcap@ee.lbl.gov>
ftp://ftp.ee.lbl.gov/old/libpcap-0.4a7.tar.Z
@@ -43,15 +40,15 @@ found at
or
- http://www.tcpdump.org/papers/bpf-usenix93.ps.Z
+ https://www.tcpdump.org/papers/bpf-usenix93.ps.Z
and a gzipped version can be found at
- http://www.tcpdump.org/papers/bpf-usenix93.ps.gz
+ https://www.tcpdump.org/papers/bpf-usenix93.ps.gz
A PDF version can be found at
- http://www.tcpdump.org/papers/bpf-usenix93.pdf
+ https://www.tcpdump.org/papers/bpf-usenix93.pdf
Although most packet capture interfaces support in-kernel filtering,
libpcap utilizes in-kernel filtering only for the BPF interface.
@@ -62,13 +59,13 @@ would translate BPF filters into a filter program that is compatible
with the underlying kernel subsystem, but this is not yet implemented.
BPF is standard in 4.4BSD, BSD/OS, NetBSD, FreeBSD, OpenBSD, DragonFly
-BSD, and Mac OS X; an older, modified and undocumented version is
-standard in AIX. {DEC OSF/1, Digital UNIX, Tru64 UNIX} uses the
-packetfilter interface but has been extended to accept BPF filters
-(which libpcap utilizes). Also, you can add BPF filter support to
-Ultrix using the kernel source and/or object patches available in:
+BSD, and macOS; an older, modified and undocumented version is standard
+in AIX. {DEC OSF/1, Digital UNIX, Tru64 UNIX} uses the packetfilter
+interface but has been extended to accept BPF filters (which libpcap
+utilizes). Also, you can add BPF filter support to Ultrix using the
+kernel source and/or object patches available in:
- http://www.tcpdump.org/other/bpfext42.tar.Z
+ https://www.tcpdump.org/other/bpfext42.tar.Z
Linux, in the 2.2 kernel and later kernels, has a "Socket Filter"
mechanism that accepts BPF filters; see the README.linux file for
@@ -87,20 +84,6 @@ We've been maintaining binary compatibility between libpcap releases for
quite a while; there's no reason to tie a binary linked with libpcap to
a particular release of libpcap.
-Problems, bugs, questions, desirable enhancements, etc. should be sent
-to the address "tcpdump-workers@lists.tcpdump.org". Bugs, support
-requests, and feature requests may also be submitted on the GitHub issue
-tracker for libpcap at
-
- https://github.com/the-tcpdump-group/libpcap/issues
-
-Source code contributions, etc. should be sent to the email address
-above or submitted by forking the branch on GitHub at
-
- http://github.com/the-tcpdump-group/libpcap/tree/master
-
-and issuing a pull request.
-
-Current versions can be found at www.tcpdump.org.
+Current versions can be found at https://www.tcpdump.org.
- - The TCPdump team
+ - The TCPdump group
diff --git a/contrib/libpcap/README.Win32 b/contrib/libpcap/README.Win32
new file mode 100644
index 0000000000000..0a42dab93d4bd
--- /dev/null
+++ b/contrib/libpcap/README.Win32
@@ -0,0 +1,46 @@
+Under Win32, libpcap is integrated in the WinPcap packet capture system.
+WinPcap provides a framework that allows libpcap to capture the packets
+under Windows 95, Windows 98, Windows ME, Windows NT 4, Windows 2000
+and Windows XP.
+WinPcap binaries and source code can be found at http://winpcap.polito.it:
+they include also a developer's pack with all the necessary to compile
+libpcap-based applications under Windows.
+
+How to compile libpcap with Visual Studio
+-----------------------------------------
+
+In order to compile libpcap you will need:
+
+- version 6 (or higher) of Microsoft Visual Studio
+- The November 2001 (or later) edition of Microsoft Platform
+Software Development Kit (SDK), that contains some necessary includes
+for IPv6 support. You can download it from http://www.microsoft.com/sdk
+- the latest WinPcap sources from http://winpcap.polito.it/install
+
+The WinPcap source code already contains a recent (usually the latest
+stable) version of libpcap. If you need to compile a different one,
+simply download it from www.tcpdump.org and copy the sources in the
+winpcap\wpcap\libpcap folder of the WinPcap distribution. If you want to
+compile a libpcap source retrieved from the tcpdump.org Git, you will
+have to create the scanner and the grammar by hand (with lex and yacc)
+or with the cygnus makefile, since The Visual Studio project is not able
+to build them.
+
+Open the project file winpcap\wpcap\prj\wpcap.dsw with Visual Studio and
+build wpcap.dll. wpcap.lib, the library file to link with the applications,
+will be generated in winpcap\wpcap\lib\. wpcap.dll will be generated in
+winpcap\wpcap\prj\release or winpcap\wpcap\prj\debug depending on the type
+of binary that is being created.
+
+How to compile libpcap with Cygnus
+----------------------------------
+
+To build wpcap.dll, cd to the directory WPCAP/PRJ of the WinPcap source code
+distribution and type "make". libwpcap.a, the library file to link with the
+applications, will be generated in winpcap\wpcap\lib\. wpcap.dll will be
+generated in winpcap\wpcap\prj.
+
+Remember, you CANNOT use the MSVC-generated .lib files with gcc, use
+libwpcap.a instead.
+
+"make install" installs wpcap.dll in the Windows system folder.
diff --git a/contrib/libpcap/README.aix b/contrib/libpcap/README.aix
new file mode 100644
index 0000000000000..92e513ff74138
--- /dev/null
+++ b/contrib/libpcap/README.aix
@@ -0,0 +1,88 @@
+Using BPF:
+
+(1) AIX 4.x's version of BPF is undocumented and somewhat unstandard; the
+ current BPF support code includes changes that should work around
+ that; it appears to compile and work on at least one AIX 4.3.3
+ machine.
+
+ Note that the BPF driver and the "/dev/bpf" devices might not exist
+ on your machine; AIX's tcpdump loads the driver and creates the
+ devices if they don't already exist. Our libpcap should do the
+ same, and the configure script should detect that it's on an AIX
+ system and choose BPF even if the devices aren't there.
+
+ Also note that tcpdump _binary_ compiled on AIX 4 may have a problem
+ doing the initial loading of the BPF driver if copied to AIX 5 and
+ run there (GH #52). tcpdump binary natively compiled on AIX 5 should
+ not have this issue.
+
+(2) If libpcap doesn't compile on your machine when configured to use
+ BPF, or if the workarounds fail to make it work correctly, you
+ should send to tcpdump-workers@lists.tcpdump.org a detailed bug
+ report (if the compile fails, send us the compile error messages;
+ if it compiles but fails to work correctly, send us as detailed as
+ possible a description of the symptoms, including indications of the
+ network link-layer type being wrong or time stamps being wrong).
+
+ If you fix the problems yourself, please submit a patch by forking
+ the branch at
+
+ https://github.com/the-tcpdump-group/libpcap/issues
+
+ and issuing a pull request, so we can incorporate the fixes into the
+ next release.
+
+ If you don't fix the problems yourself, you can, as a workaround,
+ make libpcap use DLPI instead of BPF.
+
+ This can be done by specifying the flag:
+
+ --with-pcap=dlpi
+
+ to the "configure" script for libpcap.
+
+If you use DLPI:
+
+(1) It is a good idea to have the latest version of the DLPI driver on
+ your system, since certain versions may be buggy and cause your AIX
+ system to crash. DLPI is included in the fileset bos.rte.tty. I
+ found that the DLPI driver that came with AIX 4.3.2 was buggy, and
+ had to upgrade to bos.rte.tty 4.3.2.4:
+
+ lslpp -l bos.rte.tty
+
+ bos.rte.tty 4.3.2.4 COMMITTED Base TTY Support and Commands
+
+ Updates for AIX filesets can be obtained from:
+ ftp://service.software.ibm.com/aix/fixes/
+
+ These updates can be installed with the smit program.
+
+(2) After compiling libpcap, you need to make sure that the DLPI driver
+ is loaded. Type:
+
+ strload -q -d dlpi
+
+ If the result is:
+
+ dlpi: yes
+
+ then the DLPI driver is loaded correctly.
+
+ If it is:
+
+ dlpi: no
+
+ Then you need to type:
+
+ strload -f /etc/dlpi.conf
+
+ Check again with strload -q -d dlpi that the dlpi driver is loaded.
+
+ Alternatively, you can uncomment the lines for DLPI in
+ /etc/pse.conf and reboot the machine; this way DLPI will always
+ be loaded when you boot your system.
+
+(3) There appears to be a problem in the DLPI code in some versions of
+ AIX, causing a warning about DL_PROMISC_MULTI failing; this might
+ be responsible for DLPI not being able to capture outgoing packets.
diff --git a/contrib/libpcap/README.dag b/contrib/libpcap/README.dag
new file mode 100644
index 0000000000000..accae7c382767
--- /dev/null
+++ b/contrib/libpcap/README.dag
@@ -0,0 +1,122 @@
+
+The following instructions apply if you have a Linux or FreeBSD platform and
+want libpcap to support the DAG range of passive network monitoring cards from
+Endace (http://www.endace.com, see below for further contact details).
+
+1) Install and build the DAG software distribution by following the
+instructions supplied with that package. Current Endace customers can download
+the DAG software distibution from https://www.endace.com
+
+2) Configure libcap. To allow the 'configure' script to locate the DAG
+software distribution use the '--with-dag' option:
+
+ ./configure --with-dag=DIR
+
+Where DIR is the root of the DAG software distribution, for example
+/var/src/dag. If the DAG software is correctly detected 'configure' will
+report:
+
+ checking whether we have DAG API... yes
+
+If 'configure' reports that there is no DAG API, the directory may have been
+incorrectly specified or the DAG software was not built before configuring
+libpcap.
+
+See also the libpcap INSTALL.txt file for further libpcap configuration
+options.
+
+Building libpcap at this stage will include support for both the native packet
+capture stream (linux or bpf) and for capturing from DAG cards. To build
+libpcap with only DAG support specify the capture type as 'dag' when
+configuring libpcap:
+
+ ./configure --with-dag=DIR --with-pcap=dag
+
+Applications built with libpcap configured in this way will only detect DAG
+cards and will not capture from the native OS packet stream.
+
+----------------------------------------------------------------------
+
+Libpcap when built for DAG cards against dag-2.5.1 or later releases:
+
+Timeouts are supported. pcap_dispatch() will return after to_ms milliseconds
+regardless of how many packets are received. If to_ms is zero pcap_dispatch()
+will block waiting for data indefinitely.
+
+pcap_dispatch() will block on and process a minimum of 64kB of data (before
+filtering) for efficiency. This can introduce high latencies on quiet
+interfaces unless a timeout value is set. The timeout expiring will override
+the 64kB minimum causing pcap_dispatch() to process any available data and
+return.
+
+pcap_setnonblock is supported. When nonblock is set, pcap_dispatch() will
+check once for available data, process any data available up to count, then
+return immediately.
+
+pcap_findalldevs() is supported, e.g. dag0, dag1...
+
+Some DAG cards can provide more than one 'stream' of received data.
+This can be data from different physical ports, or separated by filtering
+or load balancing mechanisms. Receive streams have even numbers, e.g.
+dag0:0, dag0:2 etc. Specifying transmit streams for capture is not supported.
+
+pcap_setfilter() is supported, BPF programs run in userspace.
+
+pcap_setdirection() is not supported. Only received traffic is captured.
+DAG cards normally do not have IP or link layer addresses assigned as
+they are used to passively monitor links.
+
+pcap_breakloop() is supported.
+
+pcap_datalink() and pcap_list_datalinks() are supported. The DAG card does
+not attempt to set the correct datalink type automatically where more than
+one type is possible.
+
+pcap_stats() is supported. ps_drop is the number of packets dropped due to
+RX stream buffer overflow, this count is before filters are applied (it will
+include packets that would have been dropped by the filter). The RX stream
+buffer size is user configurable outside libpcap, typically 16-512MB.
+
+pcap_get_selectable_fd() is not supported, as DAG cards do not support
+poll/select methods.
+
+pcap_inject() and pcap_sendpacket() are not supported.
+
+Some DAG cards now support capturing to multiple virtual interfaces, called
+streams. Capture streams have even numbers. These are available via libpcap
+as separate interfaces, e.g. dag0:0, dag0:2, dag0:4 etc. dag0:0 is the same
+as dag0. These are visible via pcap_findalldevs().
+
+libpcap now does NOT set the card's hardware snaplen (slen). This must now be
+set using the appropriate DAG coniguration program, e.g. dagthree, dagfour,
+dagsix, dagconfig. This is because the snaplen is currently shared between
+all of the streams. In future this may change if per-stream slen is
+implemented.
+
+DAG cards by default capture entire packets including the L2
+CRC/FCS. If the card is not configured to discard the CRC/FCS, this
+can confuse applications that use libpcap if they're not prepared for
+packets to have an FCS.
+
+Libpcap now reads the environment variable ERF_FCS_BITS to determine
+how many bits of CRC/FCS to strip from the end of the captured
+frame. This defaults to 32 for use with Ethernet. If the card is
+configured to strip the CRC/FCS, then set ERF_FCS_BITS=0. If used with
+a HDLC/PoS/PPP/Frame Relay link with 16 bit CRC/FCS, then set
+ERF_FCS_BITS=16.
+
+If you wish to create a pcap file that DOES contain the Ethernet FCS,
+specify the environment variable ERF_DONT_STRIP_FCS. This will cause
+the existing FCS to be captured into the pcap file. Note some
+applications may incorrectly report capture errors or oversize packets
+when reading these files.
+
+----------------------------------------------------------------------
+
+Please submit bug reports via <support@endace.com>.
+
+Please also visit our Web site at:
+
+ http://www.endace.com/
+
+For more information about Endace DAG cards contact <sales@endace.com>.
diff --git a/contrib/libpcap/README.hpux b/contrib/libpcap/README.hpux
new file mode 100644
index 0000000000000..65ecff97c2498
--- /dev/null
+++ b/contrib/libpcap/README.hpux
@@ -0,0 +1,254 @@
+For HP-UX 11i (11.11) and later, there are no known issues with
+promiscuous mode under HP-UX. If you are using a earlier version of
+HP-UX and cannot upgrade, please continue reading.
+
+HP-UX patches to fix packet capture problems
+
+Note that packet-capture programs such as tcpdump may, on HP-UX, not be
+able to see packets sent from the machine on which they're running.
+Some articles on groups.google.com discussing this are:
+
+ http://groups.google.com/groups?selm=82ld3v%2480i%241%40mamenchi.zrz.TU-Berlin.DE
+
+which says:
+
+ Newsgroups: comp.sys.hp.hpux
+ Subject: Re: Did someone made tcpdump working on 10.20 ?
+ Date: 12/08/1999
+ From: Lutz Jaenicke <jaenicke@emserv1.ee.TU-Berlin.DE>
+
+ In article <82ks5i$5vc$1@news1.dti.ne.jp>, mtsat <mtsat@iris.dti.ne.jp>
+ wrote:
+ >Hello,
+ >
+ >I downloaded and compiled tcpdump3.4 a couple of week ago. I tried to use
+ >it, but I can only see incoming data, never outgoing.
+ >Someone (raj) explained me that a patch was missing, and that this patch
+ >must me "patched" (poked) in order to see outbound data in promiscuous mode.
+ >Many things to do .... So the question is : did someone has already this
+ >"ready to use" PHNE_**** patch ?
+
+ Two things:
+ 1. You do need a late "LAN products cumulative patch" (e.g. PHNE_18173
+ for s700/10.20).
+ 2. You must use
+echo 'lanc_outbound_promisc_flag/W1' | /usr/bin/adb -w /stand/vmunix /dev/kmem
+ You can insert this e.g. into /sbin/init.d/lan
+
+ Best regards,
+ Lutz
+
+and
+
+ http://groups.google.com/groups?selm=88cf4t%24p03%241%40web1.cup.hp.com
+
+which says:
+
+ Newsgroups: comp.sys.hp.hpux
+ Subject: Re: tcpdump only shows incoming packets
+ Date: 02/15/2000
+ From: Rick Jones <foo@bar.baz.invalid>
+
+ Harald Skotnes <harald@cc.uit.no> wrote:
+ > I am running HPUX 11.0 on a C200 hanging on a 100Mb switch. I have
+ > compiled libpcap-0.4 an tcpdump-3.4 and it seems to work. But at a
+ > closer look I only get to see the incoming packets not the
+ > outgoing. I have tried tcpflow-0.12 which also uses libpcap and the
+ > same thing happens. Could someone please give me a hint on how to
+ > get this right?
+
+ Search/Read the archives ?-)
+
+ What you are seeing is expected, un-patched, behaviour for an HP-UX
+ system. On 11.00, you need to install the latest lancommon/DLPI
+ patches, and then the latest driver patch for the interface(s) in use.
+ At that point, a miracle happens and you should start seeing outbound
+ traffic.
+
+[That article also mentions the patch that appears below.]
+
+and
+
+ http://groups.google.com/groups?selm=38AA973E.96BE7DF7%40cc.uit.no
+
+which says:
+
+ Newsgroups: comp.sys.hp.hpux
+ Subject: Re: tcpdump only shows incoming packets
+ Date: 02/16/2000
+ From: Harald Skotnes <harald@cc.uit.no>
+
+ Rick Jones wrote:
+
+ ...
+
+ > What you are seeing is expected, un-patched, behaviour for an HP-UX
+ > system. On 11.00, you need to install the latest lancommon/DLPI
+ > patches, and then the latest driver patch for the interface(s) in
+ > use. At that point, a miracle happens and you should start seeing
+ > outbound traffic.
+
+ Thanks a lot. I have this problem on several machines running HPUX
+ 10.20 and 11.00. The machines where patched up before y2k so did not
+ know what to think. Anyway I have now installed PHNE_19766,
+ PHNE_19826, PHNE_20008, PHNE_20735 on the C200 and now I can see the
+ outbound traffic too. Thanks again.
+
+(although those patches may not be the ones to install - there may be
+later patches).
+
+And another message to tcpdump-workers@tcpdump.org, from Rick Jones:
+
+ Date: Mon, 29 Apr 2002 15:59:55 -0700
+ From: Rick Jones
+ To: tcpdump-workers@tcpdump.org
+ Subject: Re: [tcpdump-workers] I Can't Capture the Outbound Traffic
+
+ ...
+
+ http://itrc.hp.com/ would be one place to start in a search for the most
+ up-to-date patches for DLPI and the lan driver(s) used on your system (I
+ cannot guess because 9000/800 is too generic - one hs to use the "model"
+ command these days and/or an ioscan command (see manpage) to guess what
+ the drivers (btlan[3456], gelan, etc) might be involved in addition to
+ DLPI.
+
+ Another option is to upgrade to 11i as outbound promiscuous mode support
+ is there in the base OS, no patches required.
+
+Another posting:
+
+ http://groups.google.com/groups?selm=7d6gvn%24b3%241%40ocean.cup.hp.com
+
+indicates that you need to install the optional STREAMS product to do
+captures on HP-UX 9.x:
+
+ Newsgroups: comp.sys.hp.hpux
+ Subject: Re: tcpdump HP/UX 9.x
+ Date: 03/22/1999
+ From: Rick Jones <foo@bar.baz>
+
+ Dave Barr (barr@cis.ohio-state.edu) wrote:
+ : Has anyone ported tcpdump (or something similar) to HP/UX 9.x?
+
+ I'm reasonably confident that any port of tcpdump to 9.X would require
+ the (then optional) STREAMS product. This would bring DLPI, which is
+ what one uses to access interfaces in promiscuous mode.
+
+ I'm not sure that HP even sells the 9.X STREAMS product any longer,
+ since HP-UX 9.X is off the pricelist (well, maybe 9.10 for the old 68K
+ devices).
+
+ Your best bet is to be up on 10.20 or better if that is at all
+ possible. If your hardware is supported by it, I'd go with HP-UX 11.
+ If you want to see the system's own outbound traffic, you'll never get
+ that functionality on 9.X, but it might happen at some point for 10.20
+ and 11.X.
+
+ rick jones
+
+(as per other messages cited here, the ability to see the system's own
+outbound traffic did happen).
+
+Rick Jones reports that HP-UX 11i needs no patches for outbound
+promiscuous mode support.
+
+An additional note, from Jost Martin, for HP-UX 10.20:
+
+ Q: How do I get ethereral on HPUX to capture the _outgoing_ packets
+ of an interface
+ A: You need to get PHNE_20892,PHNE_20725 and PHCO_10947 (or
+ newer, this is as of 4.4.00) and its dependencies. Then you can
+ enable the feature as descibed below:
+
+ Patch Name: PHNE_20892
+ Patch Description: s700 10.20 PCI 100Base-T cumulative patch
+ To trace the outbound packets, please do the following
+ to turn on a global promiscuous switch before running
+ the promiscuous applications like snoop or tcpdump:
+
+ adb -w /stand/vmunix /dev/mem
+ lanc_outbound_promisc_flag/W 1
+ (adb will echo the result showing that the flag has
+ been changed)
+ $quit
+ (Thanks for this part to HP-support, Ratingen)
+
+ The attached hack does this and some security-related stuff
+ (thanks to hildeb@www.stahl.bau.tu-bs.de (Ralf Hildebrandt) who
+ posted the security-part some time ago)
+
+ <<hack_ip_stack>>
+
+ (Don't switch IP-forwarding off, if you need it !)
+ Install the hack as /sbin/init.d/hacl_ip_stack (adjust
+ permissions !) and make a sequencing-symlink
+ /sbin/rc2.d/S350hack_ip_stack pointing to this script.
+ Now all this is done on every reboot.
+
+According to Rick Jones, the global promiscuous switch also has to be
+turned on for HP-UX 11.00, but not for 11i - and, in fact, the switch
+doesn't even exist on 11i.
+
+Here's the "hack_ip_stack" script:
+
+-----------------------------------Cut Here-------------------------------------
+#!/sbin/sh
+#
+# nettune: hack kernel parms for safety
+
+OKAY=0
+ERROR=-1
+
+# /usr/contrib/bin fuer nettune auf Pfad
+PATH=/sbin:/usr/sbin:/usr/bin:/usr/contrib/bin
+export PATH
+
+
+##########
+# main #
+##########
+
+case $1 in
+ start_msg)
+ print "Tune IP-Stack for security"
+ exit $OKAY
+ ;;
+
+ stop_msg)
+ print "This action is not applicable"
+ exit $OKAY
+ ;;
+
+ stop)
+ exit $OKAY
+ ;;
+
+ start)
+ ;; # fall through
+
+ *)
+ print "USAGE: $0 {start_msg | stop_msg | start | stop}" >&2
+ exit $ERROR
+ ;;
+ esac
+
+###########
+# start #
+###########
+
+#
+# tcp-Sequence-Numbers nicht mehr inkrementieren sondern random
+# Syn-Flood-Protection an
+# ip_forwarding aus
+# Source-Routing aus
+# Ausgehende Packets an ethereal/tcpdump etc.
+
+/usr/contrib/bin/nettune -s tcp_random_seq 2 || exit $ERROR
+/usr/contrib/bin/nettune -s hp_syn_protect 1 || exit $ERROR
+/usr/contrib/bin/nettune -s ip_forwarding 0 || exit $ERROR
+echo 'ip_block_source_routed/W1' | /usr/bin/adb -w /stand/vmunix /dev/kmem || exit $ERROR
+echo 'lanc_outbound_promisc_flag/W 1' | adb -w /stand/vmunix /dev/mem || exit $ERROR
+
+exit $OKAY
+-----------------------------------Cut Here-------------------------------------
diff --git a/contrib/libpcap/README.linux b/contrib/libpcap/README.linux
new file mode 100644
index 0000000000000..ffcb9288ca136
--- /dev/null
+++ b/contrib/libpcap/README.linux
@@ -0,0 +1,108 @@
+In order for libpcap to be able to capture packets on a Linux system,
+the "packet" protocol must be supported by your kernel. If it is not,
+you may get error messages such as
+
+ modprobe: can't locate module net-pf-17
+
+in "/var/adm/messages", or may get messages such as
+
+ socket: Address family not supported by protocol
+
+from applications using libpcap.
+
+You must configure the kernel with the CONFIG_PACKET option for this
+protocol; the following note is from the Linux "Configure.help" file for
+the 2.0[.x] kernel:
+
+ Packet socket
+ CONFIG_PACKET
+ The Packet protocol is used by applications which communicate
+ directly with network devices without an intermediate network
+ protocol implemented in the kernel, e.g. tcpdump. If you want them
+ to work, choose Y.
+
+ This driver is also available as a module called af_packet.o ( =
+ code which can be inserted in and removed from the running kernel
+ whenever you want). If you want to compile it as a module, say M
+ here and read Documentation/modules.txt; if you use modprobe or
+ kmod, you may also want to add "alias net-pf-17 af_packet" to
+ /etc/modules.conf.
+
+and the note for the 2.2[.x] kernel says:
+
+ Packet socket
+ CONFIG_PACKET
+ The Packet protocol is used by applications which communicate
+ directly with network devices without an intermediate network
+ protocol implemented in the kernel, e.g. tcpdump. If you want them
+ to work, choose Y. This driver is also available as a module called
+ af_packet.o ( = code which can be inserted in and removed from the
+ running kernel whenever you want). If you want to compile it as a
+ module, say M here and read Documentation/modules.txt. You will
+ need to add 'alias net-pf-17 af_packet' to your /etc/conf.modules
+ file for the module version to function automatically. If unsure,
+ say Y.
+
+In addition, there is an option that, in 2.2 and later kernels, will
+allow packet capture filters specified to programs such as tcpdump to be
+executed in the kernel, so that packets that don't pass the filter won't
+be copied from the kernel to the program, rather than having all packets
+copied to the program and libpcap doing the filtering in user mode.
+
+Copying packets from the kernel to the program consumes a significant
+amount of CPU, so filtering in the kernel can reduce the overhead of
+capturing packets if a filter has been specified that discards a
+significant number of packets. (If no filter is specified, it makes no
+difference whether the filtering isn't performed in the kernel or isn't
+performed in user mode. :-))
+
+The option for this is the CONFIG_FILTER option; the "Configure.help"
+file says:
+
+ Socket filtering
+ CONFIG_FILTER
+ The Linux Socket Filter is derived from the Berkeley Packet Filter.
+ If you say Y here, user-space programs can attach a filter to any
+ socket and thereby tell the kernel that it should allow or disallow
+ certain types of data to get through the socket. Linux Socket
+ Filtering works on all socket types except TCP for now. See the text
+ file linux/Documentation/networking/filter.txt for more information.
+ If unsure, say N.
+
+Note that, by default, libpcap will, if libnl is present, build with it;
+it uses libnl to support monitor mode on mac80211 devices. There is a
+configuration option to disable building with libnl, but, if that option
+is chosen, the monitor-mode APIs (as used by tcpdump's "-I" flag, and as
+will probably be used by other applications in the future) won't work
+properly on mac80211 devices.
+
+Linux's run-time linker allows shared libraries to be linked with other
+shared libraries, which means that if an older version of a shared
+library doesn't require routines from some other shared library, and a
+later version of the shared library does require those routines, the
+later version of the shared library can be linked with that other shared
+library and, if it's otherwise binary-compatible with the older version,
+can replace that older version without breaking applications built with
+the older version, and without breaking configure scripts or the build
+procedure for applications whose configure script doesn't use the
+pcap-config script if they build with the shared library. (The build
+procedure for applications whose configure scripts use the pcap-config
+script if present will not break even if they build with the static
+library.)
+
+Statistics:
+Statistics reported by pcap are platform specific. The statistics
+reported by pcap_stats on Linux are as follows:
+
+2.2.x
+=====
+ps_recv Number of packets that were accepted by the pcap filter
+ps_drop Always 0, this statistic is not gatherd on this platform
+
+2.4.x
+=====
+ps_recv Number of packets that were accepted by the pcap filter
+ps_drop Number of packets that had passed filtering but were not
+ passed on to pcap due to things like buffer shortage, etc.
+ This is useful because these are packets you are interested in
+ but won't be reported by, for example, tcpdump output.
diff --git a/contrib/libpcap/README.macos b/contrib/libpcap/README.macos
new file mode 100644
index 0000000000000..3cceb23329a10
--- /dev/null
+++ b/contrib/libpcap/README.macos
@@ -0,0 +1,74 @@
+As with other systems using BPF, macOS allows users with read access to
+the BPF devices to capture packets with libpcap and allows users with
+write access to the BPF devices to send packets with libpcap.
+
+On some systems that use BPF, the BPF devices live on the root file
+system, and the permissions and/or ownership on those devices can be
+changed to give users other than root permission to read or write those
+devices.
+
+On newer versions of FreeBSD, the BPF devices live on devfs, and devfs
+can be configured to set the permissions and/or ownership of those
+devices to give users other than root permission to read or write those
+devices.
+
+On macOS, the BPF devices live on devfs, but the macOS version of devfs
+is based on an older (non-default) FreeBSD devfs, and that version of
+devfs cannot be configured to set the permissions and/or ownership of
+those devices.
+
+Therefore, we supply:
+
+ a "startup item" for older versions of macOS;
+
+ a launchd daemon for Tiger and later versions of macOS;
+
+Both of them will change the ownership of the BPF devices so that the
+"admin" group owns them, and will change the permission of the BPF
+devices to rw-rw----, so that all users in the "admin" group - i.e., all
+users with "Allow user to administer this computer" turned on - have
+both read and write access to them.
+
+The startup item is in the ChmodBPF directory in the source tree. A
+/Library/StartupItems directory should be created if it doesn't already
+exist, and the ChmodBPF directory should be copied to the
+/Library/StartupItems directory (copy the entire directory, so that
+there's a /Library/StartupItems/ChmodBPF directory, containing all the
+files in the source tree's ChmodBPF directory; don't copy the individual
+items in that directory to /Library/StartupItems). The ChmodBPF
+directory, and all files under it, must be owned by root. Installing
+the files won't immediately cause the startup item to be executed; it
+will be executed on the next reboot. To change the permissions before
+the reboot, run
+
+ sudo SystemStarter start ChmodBPF
+
+The launchd daemon is the chmod_bpf script, plus the
+org.tcpdump.chmod_bpf.plist launchd plist file. chmod_bpf should be
+installed in /usr/local/bin/chmod_bpf, and org.tcpdump.chmod_bpf.plist
+should be installed in /Library/LaunchDaemons. chmod_bpf, and
+org.tcpdump.chmod_bpf.plist, must be owned by root. Installing the
+script and plist file won't immediately cause the script to be executed;
+it will be executed on the next reboot. To change the permissions
+before the reboot, run
+
+ sudo /usr/local/bin/chmod_bpf
+
+or
+
+ sudo launchctl load /Library/LaunchDaemons/org.tcpdump.chmod_bpf.plist
+
+If you want to give a particular user permission to access the BPF
+devices, rather than giving all administrative users permission to
+access them, you can have the ChmodBPF/ChmodBPF script change the
+ownership of /dev/bpf* without changing the permissions. If you want to
+give a particular user permission to read and write the BPF devices and
+give the administrative users permission to read but not write the BPF
+devices, you can have the script change the owner to that user, the
+group to "admin", and the permissions to rw-r-----. Other possibilities
+are left as an exercise for the reader.
+
+(NOTE: due to a bug in Snow Leopard, if you change the permissions not
+to grant write permission to everybody who should be allowed to capture
+traffic, non-root users who cannot open the BPF devices for writing will
+not be able to capture outgoing packets.)
diff --git a/contrib/libpcap/README.septel b/contrib/libpcap/README.septel
new file mode 100644
index 0000000000000..fa2c0c9a40d91
--- /dev/null
+++ b/contrib/libpcap/README.septel
@@ -0,0 +1,50 @@
+The following instructions apply if you have a Linux platform and want
+libpcap to support the Septel range of passive network monitoring cards
+from Intel (http://www.intel.com)
+
+1) Install and build the Septel software distribution by following the
+instructions supplied with that package.
+
+2) Configure libcap. To allow the 'configure' script to locate the Septel
+software distribution use the '--with-septel' option:
+
+ ./configure --with-septel=DIR
+
+where DIR is the root of the Septel software distribution, for example
+/var/src/septel.
+
+By default (if you write only ./configure --with-septel) it takes
+./../septel as argument for DIR.
+
+If the Septel software is correctly detected 'configure' will
+report:
+
+ checking whether we have Septel API... yes
+
+If 'configure' reports that there is no Septel API, the directory may have been
+incorrectly specified or the Septel software was not built before configuring
+libpcap.
+
+See also the libpcap INSTALL.txt file for further libpcap configuration
+options.
+
+Building libpcap at this stage will include support for both the native
+packet capture stream and for capturing from Septel cards. To build
+libpcap with only Septel support specify the capture type as 'septel'
+when configuring libpcap:
+
+ ./configure --with-septel=DIR --with-pcap=septel
+
+Applications built with libpcap configured in this way will only detect Septel
+cards and will not capture from the native OS packet stream.
+
+Note: As mentioned in pcap-septel.c we should first edit the system.txt
+file to change the user part example (UPE) module id to 0xdd instead of
+0x2d for technical reason. So this change in system.txt is crucial and
+things will go wrong if it's not done. System.txt along with config.txt
+are configuration files that are edited by the user before running the
+gctload program that uses these files for initialising modules and
+configuring parameters.
+
+----------------------------------------------------------------------
+for more information please contact me : gil_hoyek@hotmail.com
diff --git a/contrib/libpcap/README.sita b/contrib/libpcap/README.sita
new file mode 100644
index 0000000000000..5a65822ecedbf
--- /dev/null
+++ b/contrib/libpcap/README.sita
@@ -0,0 +1,64 @@
+The following instructions apply if you have a Linux platform and want
+libpcap to support the 'ACN' WAN/LAN router product from SITA
+(http://www.sita.aero)
+
+This might also work on non-Linux Unix-compatible platforms, but that
+has not been tested.
+
+See also the libpcap INSTALL.txt file for further libpcap configuration
+options.
+
+These additions/extensions have been made to PCAP to allow it to
+capture packets from a SITA ACN device (and potentially others).
+
+To enable its support you need to ensure that the distribution has
+a correct configure.ac file; that can be created if neccessay by
+using the normal autoconf procedure of:
+
+aclocal
+autoconf
+autoheader
+automake
+
+Then run configure with the 'sita' option:
+
+./configure --with-sita
+
+Applications built with libpcap configured in this way will only detect SITA
+ACN interfaces and will not capture from the native OS packet stream.
+
+The SITA extension provides a remote datascope operation for capturing
+both WAN and LAN protocols. It effectively splits the operation of
+PCAP into two halves. The top layer performs the majority of the
+work, but interfaces via a TCP session to remote agents that
+provide the lower layer functionality of actual sniffing and
+filtering. More detailed information regarding the functions and
+inter-device protocol and naming conventions are described in detail
+in 'pcap-sita.html'.
+
+pcap_findalldevs() reads the local system's /etc/hosts file looking
+for host names that match the format of IOP type devices. ie. aaa_I_x_y
+and then queries each associated IP address for a list of its WAN and
+LAN devices. The local system the aggregates the lists obtained from
+each IOP, sorts it, and provides it (to Wireshark et.al) as the
+list of monitorable interfaces.
+
+Once a valid interface has been selected, pcap_open() is called
+which opens a TCP session (to a well known port) on the target IOP
+and tells it to start monitoring.
+
+All captured packets are then forwarded across that TCP session
+back to the local 'top layer' for forwarding to the actual
+sniffing program (wireshark...)
+
+Note that the DLT_SITA link-layer type includes a proprietary header
+that is documented as part of the SITA dissector of Wireshark and is
+also described in 'pcap-sita.html' for posterity sake.
+
+That header provides:
+- Packet direction (in/out) (1 octet)
+- Link layer hardware signal status (1 octet)
+- Transmit/Receive error status (2 octets)
+- Encapsulated WAN protocol ID (1 octet)
+
+
diff --git a/contrib/libpcap/README.tru64 b/contrib/libpcap/README.tru64
new file mode 100644
index 0000000000000..2420d9e121802
--- /dev/null
+++ b/contrib/libpcap/README.tru64
@@ -0,0 +1,49 @@
+The following instructions are applicable to Tru64 UNIX
+(formerly Digital UNIX (formerly DEC OSF/1)) version 4.0, and
+probably to later versions as well; at least some options apply to
+Digital UNIX 3.2 - perhaps all do.
+
+In order to use kernel packet filtering on this system, you have
+to configure it in such a way:
+
+Kernel configuration
+--------------------
+
+The packet filtering kernel option must be enabled at kernel
+installation. If it was not the case, you can rebuild the kernel with
+"doconfig -c" after adding the following line in the kernel
+configuration file (/sys/conf/<HOSTNAME>):
+
+ option PACKETFILTER
+
+or use "doconfig" without any arguments to add the packet filter driver
+option via the kernel option menu (see the system administration
+documentation for information on how to do this).
+
+Device configuration
+--------------------
+
+Devices used for packet filtering must be created thanks to
+the following command (executed in the /dev directory):
+
+ ./MAKEDEV pfilt
+
+Interface configuration
+-----------------------
+
+In order to capture all packets on a network, you may want to allow
+applications to put the interface on that network into "local copy"
+mode, so that tcpdump can see packets sent by the host on which it's
+running as well as packets received by that host, and to put the
+interface into "promiscuous" mode, so that tcpdump can see packets on
+the network segment not sent to the host on which it's running, by using
+the pfconfig(1) command:
+
+ pfconfig +c +p <network_device>
+
+or allow application to put any interface into "local copy" or
+"promiscuous" mode by using the command:
+
+ pfconfig +c +p -a
+
+Note: all instructions given require root privileges.
diff --git a/contrib/libpcap/VERSION b/contrib/libpcap/VERSION
index a8fdfda1c7824..52c56fe398313 100644
--- a/contrib/libpcap/VERSION
+++ b/contrib/libpcap/VERSION
@@ -1 +1 @@
-1.8.1
+1.9.0-PRE-GIT
diff --git a/contrib/libpcap/Win32/Prj/wpcap.sln b/contrib/libpcap/Win32/Prj/wpcap.sln
new file mode 100644
index 0000000000000..5a9fce98ee35e
--- /dev/null
+++ b/contrib/libpcap/Win32/Prj/wpcap.sln
@@ -0,0 +1,28 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2013
+VisualStudioVersion = 12.0.40629.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wpcap", "wpcap.vcxproj", "{8E92D840-6A36-452A-A13C-6E1BA5A2C5A9}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Debug|x64 = Debug|x64
+ Release|Win32 = Release|Win32
+ Release|x64 = Release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {8E92D840-6A36-452A-A13C-6E1BA5A2C5A9}.Debug|Win32.ActiveCfg = Debug|Win32
+ {8E92D840-6A36-452A-A13C-6E1BA5A2C5A9}.Debug|Win32.Build.0 = Debug|Win32
+ {8E92D840-6A36-452A-A13C-6E1BA5A2C5A9}.Debug|x64.ActiveCfg = Debug|x64
+ {8E92D840-6A36-452A-A13C-6E1BA5A2C5A9}.Debug|x64.Build.0 = Debug|x64
+ {8E92D840-6A36-452A-A13C-6E1BA5A2C5A9}.Release|Win32.ActiveCfg = Release|Win32
+ {8E92D840-6A36-452A-A13C-6E1BA5A2C5A9}.Release|Win32.Build.0 = Release|Win32
+ {8E92D840-6A36-452A-A13C-6E1BA5A2C5A9}.Release|x64.ActiveCfg = Release|x64
+ {8E92D840-6A36-452A-A13C-6E1BA5A2C5A9}.Release|x64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/contrib/libpcap/Win32/Prj/wpcap.vcxproj b/contrib/libpcap/Win32/Prj/wpcap.vcxproj
new file mode 100644
index 0000000000000..43b7099b7707c
--- /dev/null
+++ b/contrib/libpcap/Win32/Prj/wpcap.vcxproj
@@ -0,0 +1,233 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <SccProjectName />
+ <SccLocalPath />
+ <ProjectGuid>{8E92D840-6A36-452A-A13C-6E1BA5A2C5A9}</ProjectGuid>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v120</PlatformToolset>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v120</PlatformToolset>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v120</PlatformToolset>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v120</PlatformToolset>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <OutDir>.\Release\</OutDir>
+ <IntDir>.\Release\</IntDir>
+ <LinkIncremental>false</LinkIncremental>
+ <IncludePath>../../../;$(IncludePath)</IncludePath>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ <IncludePath>../../../;$(IncludePath)</IncludePath>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <OutDir>.\Debug\</OutDir>
+ <IntDir>.\Debug\</IntDir>
+ <LinkIncremental>true</LinkIncremental>
+ <IncludePath>../../../;$(IncludePath)</IncludePath>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <LinkIncremental>true</LinkIncremental>
+ <IncludePath>../../../;$(IncludePath)</IncludePath>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <InlineFunctionExpansion>Default</InlineFunctionExpansion>
+ <StringPooling>true</StringPooling>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <Optimization>MaxSpeed</Optimization>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <WarningLevel>Level3</WarningLevel>
+ <AdditionalIncludeDirectories>../../;../../lbl/;../../bpf/;../include/;../../../../common;../../../../dag/include;../../../../dag/drv/windows;../../../Win32-Extensions;./;Win32-Extensions;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>HAVE_VERSION_H;__STDC_VERSION__=199901L;HAVE_PACKET_IS_LOOPBACK_ADAPTER;NDEBUG;YY_NEVER_INTERACTIVE;_USRDLL;pcap_EXPORTS;HAVE_STRERROR;__STDC__;INET6;_WINDOWS;ENABLE_REMOTE;WIN32;_U_=;YY_NO_UNISTD_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x0409</Culture>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>ws2_32.lib;..\..\..\..\packetWin7\Dll\Project\Release No NetMon and AirPcap\Packet.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ <PreBuildEvent>
+ <Command>call ..\..\GenVersion.bat ..\..\VERSION ..\..\pcap_version.h.in ..\..\pcap_version.h
+win_flex -Ppcap_ -7 --outfile=..\..\scanner.c --header-file=..\..\scanner.h ..\..\scanner.l
+win_bison -ppcap_ --yacc --output=..\..\grammar.c --defines ..\..\grammar.y</Command>
+ </PreBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <InlineFunctionExpansion>Default</InlineFunctionExpansion>
+ <StringPooling>true</StringPooling>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <Optimization>MaxSpeed</Optimization>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <WarningLevel>Level3</WarningLevel>
+ <AdditionalIncludeDirectories>../../;../../lbl/;../../bpf/;../include/;../../../../common;../../../../dag/include;../../../../dag/drv/windows;../../../Win32-Extensions;./;Win32-Extensions;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>HAVE_VERSION_H;__STDC_VERSION__=199901L;HAVE_PACKET_IS_LOOPBACK_ADAPTER;NDEBUG;YY_NEVER_INTERACTIVE;_USRDLL;pcap_EXPORTS;HAVE_STRERROR;__STDC__;INET6;_WINDOWS;ENABLE_REMOTE;WIN32;_U_=;YY_NO_UNISTD_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x0409</Culture>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>ws2_32.lib;..\..\..\..\packetWin7\Dll\Project\x64\Release No NetMon and AirPcap\Packet.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ <PreBuildEvent>
+ <Command>call ..\..\GenVersion.bat ..\..\VERSION ..\..\pcap_version.h.in ..\..\pcap_version.h
+win_flex -Ppcap_ -7 --outfile=..\..\scanner.c --header-file=..\..\scanner.h ..\..\scanner.l
+win_bison -ppcap_ --yacc --output=..\..\grammar.c --defines ..\..\grammar.y</Command>
+ </PreBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <InlineFunctionExpansion>Default</InlineFunctionExpansion>
+ <FunctionLevelLinking>false</FunctionLevelLinking>
+ <Optimization>Disabled</Optimization>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <WarningLevel>Level3</WarningLevel>
+ <MinimalRebuild>true</MinimalRebuild>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ <AdditionalIncludeDirectories>../../;../../lbl/;../../bpf/;../include/;../../../../common;../../../../dag/include;../../../../dag/drv/windows;../../../Win32-Extensions;./;Win32-Extensions;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>HAVE_VERSION_H;__STDC_VERSION__=199901L;HAVE_PACKET_IS_LOOPBACK_ADAPTER;_DEBUG;YY_NEVER_INTERACTIVE;_USRDLL;pcap_EXPORTS;HAVE_STRERROR;__STDC__;INET6;_WINDOWS;ENABLE_REMOTE;WIN32;_U_=;YY_NO_UNISTD_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x0409</Culture>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>ws2_32.lib;..\..\..\..\packetWin7\Dll\Project\Release No NetMon and AirPcap\Packet.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ <PreBuildEvent>
+ <Command>call ..\..\GenVersion.bat ..\..\VERSION ..\..\pcap_version.h.in ..\..\pcap_version.h
+win_flex -Ppcap_ -7 --outfile=..\..\scanner.c --header-file=..\..\scanner.h ..\..\scanner.l
+win_bison -ppcap_ --yacc --output=..\..\grammar.c --defines ..\..\grammar.y</Command>
+ </PreBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <InlineFunctionExpansion>Default</InlineFunctionExpansion>
+ <FunctionLevelLinking>false</FunctionLevelLinking>
+ <Optimization>Disabled</Optimization>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <AdditionalIncludeDirectories>../../;../../lbl/;../../bpf/;../include/;../../../../common;../../../../dag/include;../../../../dag/drv/windows;../../../Win32-Extensions;./;Win32-Extensions;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>HAVE_VERSION_H;__STDC_VERSION__=199901L;HAVE_PACKET_IS_LOOPBACK_ADAPTER;_DEBUG;YY_NEVER_INTERACTIVE;_USRDLL;pcap_EXPORTS;HAVE_STRERROR;__STDC__;INET6;_WINDOWS;ENABLE_REMOTE;WIN32;_U_=;YY_NO_UNISTD_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x0409</Culture>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>ws2_32.lib;..\..\..\..\packetWin7\Dll\Project\x64\Release No NetMon and AirPcap\Packet.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ <PreBuildEvent>
+ <Command>call ..\..\GenVersion.bat ..\..\VERSION ..\..\pcap_version.h.in ..\..\pcap_version.h
+win_flex -Ppcap_ -7 --outfile=..\..\scanner.c --header-file=..\..\scanner.h ..\..\scanner.l
+win_bison -ppcap_ --yacc --output=..\..\grammar.c --defines ..\..\grammar.y</Command>
+ </PreBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\bpf\net\bpf_filter.c" />
+ <ClCompile Include="..\..\bpf_dump.c" />
+ <ClCompile Include="..\..\bpf_image.c" />
+ <ClCompile Include="..\..\etherent.c" />
+ <ClCompile Include="..\..\gencode.c" />
+ <ClCompile Include="..\..\grammar.c" />
+ <ClCompile Include="..\..\inet.c" />
+ <ClCompile Include="..\..\missing\win_snprintf.c" />
+ <ClCompile Include="..\..\nametoaddr.c" />
+ <ClCompile Include="..\..\optimize.c" />
+ <ClCompile Include="..\..\pcap-common.c" />
+ <ClCompile Include="..\..\pcap-new.c" />
+ <ClCompile Include="..\..\pcap-rpcap.c" />
+ <ClCompile Include="..\..\pcap-win32.c" />
+ <ClCompile Include="..\..\pcap.c" />
+ <ClCompile Include="..\..\savefile.c" />
+ <ClCompile Include="..\..\scanner.c" />
+ <ClCompile Include="..\..\sf-pcapng.c" />
+ <ClCompile Include="..\..\sf-pcap.c" />
+ <ClCompile Include="..\..\sockutils.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\pcap-common.h" />
+ <ClInclude Include="..\..\pcap-int.h" />
+ <ClInclude Include="..\..\pcap-rpcap.h" />
+ <ClInclude Include="..\..\pcap-stdinc.h" />
+ <ClInclude Include="..\..\pcap.h" />
+ <ClInclude Include="..\..\remote-ext.h" />
+ <ClInclude Include="..\..\sockutils.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="..\..\..\Win32-Extensions\version.rc" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
diff --git a/contrib/libpcap/Win32/Prj/wpcap.vcxproj.filters b/contrib/libpcap/Win32/Prj/wpcap.vcxproj.filters
new file mode 100644
index 0000000000000..6e06ccbce11d9
--- /dev/null
+++ b/contrib/libpcap/Win32/Prj/wpcap.vcxproj.filters
@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <ClCompile Include="..\..\bpf_dump.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\bpf\net\bpf_filter.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\bpf_image.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\etherent.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\gencode.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\grammar.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\inet.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\nametoaddr.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\optimize.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\pcap.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\pcap-win32.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\savefile.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\scanner.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\sf-pcap.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\sf-pcapng.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\pcap-common.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\fad-helpers.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\missing\win_snprintf.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\pcap-new.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\pcap-rpcap.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\sockutils.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{c51dce5e-0da9-4e33-a235-d5c76c76485c}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{5ec9fd4b-10b5-4527-b249-56b53d844fb1}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{c90886f0-8973-436b-a7a1-b9e881544f9a}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\pcap-stdinc.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\pcap-common.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\pcap.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\pcap-int.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\pcap-rpcap.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\remote-ext.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\sockutils.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="..\..\..\Win32-Extensions\version.rc">
+ <Filter>Resource Files</Filter>
+ </ResourceCompile>
+ </ItemGroup>
+</Project>
diff --git a/contrib/libpcap/acconfig.h b/contrib/libpcap/acconfig.h
deleted file mode 100644
index a23f320c2461c..0000000000000
--- a/contrib/libpcap/acconfig.h
+++ /dev/null
@@ -1,7 +0,0 @@
-/* Long story short: aclocal.m4 depends on autoconf 2.13
- * implementation details wrt "const"; newer versions
- * have different implementation details so for now we
- * put "const" here. This may cause duplicate definitions
- * in config.h but that should be OK since they're the same.
- */
-#undef const
diff --git a/contrib/libpcap/aclocal.m4 b/contrib/libpcap/aclocal.m4
new file mode 100644
index 0000000000000..2b63c8842d5f8
--- /dev/null
+++ b/contrib/libpcap/aclocal.m4
@@ -0,0 +1,1006 @@
+dnl Copyright (c) 1995, 1996, 1997, 1998
+dnl The Regents of the University of California. All rights reserved.
+dnl
+dnl Redistribution and use in source and binary forms, with or without
+dnl modification, are permitted provided that: (1) source code distributions
+dnl retain the above copyright notice and this paragraph in its entirety, (2)
+dnl distributions including binary code include the above copyright notice and
+dnl this paragraph in its entirety in the documentation or other materials
+dnl provided with the distribution, and (3) all advertising materials mentioning
+dnl features or use of this software display the following acknowledgement:
+dnl ``This product includes software developed by the University of California,
+dnl Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+dnl the University nor the names of its contributors may be used to endorse
+dnl or promote products derived from this software without specific prior
+dnl written permission.
+dnl THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+dnl WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+dnl MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+dnl
+dnl LBL autoconf macros
+dnl
+
+dnl
+dnl Do whatever AC_LBL_C_INIT work is necessary before using AC_PROG_CC.
+dnl
+dnl It appears that newer versions of autoconf (2.64 and later) will,
+dnl if you use AC_TRY_COMPILE in a macro, stick AC_PROG_CC at the
+dnl beginning of the macro, even if the macro itself calls AC_PROG_CC.
+dnl See the "Prerequisite Macros" and "Expanded Before Required" sections
+dnl in the Autoconf documentation.
+dnl
+dnl This causes a steaming heap of fail in our case, as we were, in
+dnl AC_LBL_C_INIT, doing the tests we now do in AC_LBL_C_INIT_BEFORE_CC,
+dnl calling AC_PROG_CC, and then doing the tests we now do in
+dnl AC_LBL_C_INIT. Now, we run AC_LBL_C_INIT_BEFORE_CC, AC_PROG_CC,
+dnl and AC_LBL_C_INIT at the top level.
+dnl
+AC_DEFUN(AC_LBL_C_INIT_BEFORE_CC,
+[
+ AC_BEFORE([$0], [AC_LBL_C_INIT])
+ AC_BEFORE([$0], [AC_PROG_CC])
+ AC_BEFORE([$0], [AC_LBL_FIXINCLUDES])
+ AC_BEFORE([$0], [AC_LBL_DEVEL])
+ AC_ARG_WITH(gcc, [ --without-gcc don't use gcc])
+ $1=""
+ if test "${srcdir}" != "." ; then
+ $1="-I\$(srcdir)"
+ fi
+ if test "${CFLAGS+set}" = set; then
+ LBL_CFLAGS="$CFLAGS"
+ fi
+ if test -z "$CC" ; then
+ case "$host_os" in
+
+ bsdi*)
+ AC_CHECK_PROG(SHLICC2, shlicc2, yes, no)
+ if test $SHLICC2 = yes ; then
+ CC=shlicc2
+ export CC
+ fi
+ ;;
+ esac
+ fi
+ if test -z "$CC" -a "$with_gcc" = no ; then
+ CC=cc
+ export CC
+ fi
+])
+
+dnl
+dnl Determine which compiler we're using (cc or gcc)
+dnl If using gcc, determine the version number
+dnl If using cc:
+dnl require that it support ansi prototypes
+dnl use -O (AC_PROG_CC will use -g -O2 on gcc, so we don't need to
+dnl do that ourselves for gcc)
+dnl add -g flags, as appropriate
+dnl explicitly specify /usr/local/include
+dnl
+dnl NOTE WELL: with newer versions of autoconf, "gcc" means any compiler
+dnl that defines __GNUC__, which means clang, for example, counts as "gcc".
+dnl
+dnl usage:
+dnl
+dnl AC_LBL_C_INIT(copt, incls)
+dnl
+dnl results:
+dnl
+dnl $1 (copt set)
+dnl $2 (incls set)
+dnl CC
+dnl LDFLAGS
+dnl LBL_CFLAGS
+dnl
+AC_DEFUN(AC_LBL_C_INIT,
+[
+ AC_BEFORE([$0], [AC_LBL_FIXINCLUDES])
+ AC_BEFORE([$0], [AC_LBL_DEVEL])
+ AC_BEFORE([$0], [AC_LBL_SHLIBS_INIT])
+ if test "$GCC" = yes ; then
+ #
+ # -Werror forces warnings to be errors.
+ #
+ ac_lbl_cc_force_warning_errors=-Werror
+
+ #
+ # Try to have the compiler default to hiding symbols,
+ # so that only symbols explicitly exported with
+ # PCAP_API will be visible outside (shared) libraries.
+ #
+ AC_LBL_CHECK_COMPILER_OPT($1, -fvisibility=hidden)
+ else
+ $2="$$2 -I/usr/local/include"
+ LDFLAGS="$LDFLAGS -L/usr/local/lib"
+
+ case "$host_os" in
+
+ darwin*)
+ #
+ # This is assumed either to be GCC or clang, both
+ # of which use -Werror to force warnings to be errors.
+ #
+ ac_lbl_cc_force_warning_errors=-Werror
+
+ #
+ # Try to have the compiler default to hiding symbols,
+ # so that only symbols explicitly exported with
+ # PCAP_API will be visible outside (shared) libraries.
+ #
+ AC_LBL_CHECK_COMPILER_OPT($1, -fvisibility=hidden)
+ ;;
+
+ hpux*)
+ #
+ # HP C, which is what we presume we're using, doesn't
+ # exit with a non-zero exit status if we hand it an
+ # invalid -W flag, can't be forced to do so even with
+ # +We, and doesn't handle GCC-style -W flags, so we
+ # don't want to try using GCC-style -W flags.
+ #
+ ac_lbl_cc_dont_try_gcc_dashW=yes
+ ;;
+
+ irix*)
+ #
+ # MIPS C, which is what we presume we're using, doesn't
+ # necessarily exit with a non-zero exit status if we
+ # hand it an invalid -W flag, can't be forced to do
+ # so, and doesn't handle GCC-style -W flags, so we
+ # don't want to try using GCC-style -W flags.
+ #
+ ac_lbl_cc_dont_try_gcc_dashW=yes
+ #
+ # It also, apparently, defaults to "char" being
+ # unsigned, unlike most other C implementations;
+ # I suppose we could say "signed char" whenever
+ # we want to guarantee a signed "char", but let's
+ # just force signed chars.
+ #
+ # -xansi is normally the default, but the
+ # configure script was setting it; perhaps -cckr
+ # was the default in the Old Days. (Then again,
+ # that would probably be for backwards compatibility
+ # in the days when ANSI C was Shiny and New, i.e.
+ # 1989 and the early '90's, so maybe we can just
+ # drop support for those compilers.)
+ #
+ # -g is equivalent to -g2, which turns off
+ # optimization; we choose -g3, which generates
+ # debugging information but doesn't turn off
+ # optimization (even if the optimization would
+ # cause inaccuracies in debugging).
+ #
+ $1="$$1 -xansi -signed -g3"
+ ;;
+
+ osf*)
+ #
+ # Presumed to be DEC OSF/1, Digital UNIX, or
+ # Tru64 UNIX.
+ #
+ # The DEC C compiler, which is what we presume we're
+ # using, doesn't exit with a non-zero exit status if we
+ # hand it an invalid -W flag, can't be forced to do
+ # so, and doesn't handle GCC-style -W flags, so we
+ # don't want to try using GCC-style -W flags.
+ #
+ ac_lbl_cc_dont_try_gcc_dashW=yes
+ #
+ # -g is equivalent to -g2, which turns off
+ # optimization; we choose -g3, which generates
+ # debugging information but doesn't turn off
+ # optimization (even if the optimization would
+ # cause inaccuracies in debugging).
+ #
+ $1="$$1 -g3"
+ ;;
+
+ solaris*)
+ #
+ # Assumed to be Sun C, which requires -errwarn to force
+ # warnings to be treated as errors.
+ #
+ ac_lbl_cc_force_warning_errors=-errwarn
+
+ #
+ # Try to have the compiler default to hiding symbols,
+ # so that only symbols explicitly exported with
+ # PCAP_API will be visible outside (shared) libraries.
+ #
+ AC_LBL_CHECK_COMPILER_OPT($1, -xldscope=hidden)
+ ;;
+
+ ultrix*)
+ AC_MSG_CHECKING(that Ultrix $CC hacks const in prototypes)
+ AC_CACHE_VAL(ac_cv_lbl_cc_const_proto,
+ AC_TRY_COMPILE(
+ [#include <sys/types.h>],
+ [struct a { int b; };
+ void c(const struct a *)],
+ ac_cv_lbl_cc_const_proto=yes,
+ ac_cv_lbl_cc_const_proto=no))
+ AC_MSG_RESULT($ac_cv_lbl_cc_const_proto)
+ if test $ac_cv_lbl_cc_const_proto = no ; then
+ AC_DEFINE(const,[],
+ [to handle Ultrix compilers that don't support const in prototypes])
+ fi
+ ;;
+ esac
+ $1="$$1 -O"
+ fi
+])
+
+dnl
+dnl Check whether, if you pass an unknown warning option to the
+dnl compiler, it fails or just prints a warning message and succeeds.
+dnl Set ac_lbl_unknown_warning_option_error to the appropriate flag
+dnl to force an error if it would otherwise just print a warning message
+dnl and succeed.
+dnl
+AC_DEFUN(AC_LBL_CHECK_UNKNOWN_WARNING_OPTION_ERROR,
+ [
+ AC_MSG_CHECKING([whether the compiler fails when given an unknown warning option])
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -Wxyzzy-this-will-never-succeed-xyzzy"
+ AC_TRY_COMPILE(
+ [],
+ [return 0],
+ [
+ AC_MSG_RESULT([no])
+ #
+ # We're assuming this is clang, where
+ # -Werror=unknown-warning-option is the appropriate
+ # option to force the compiler to fail.
+ #
+ ac_lbl_unknown_warning_option_error="-Werror=unknown-warning-option"
+ ],
+ [
+ AC_MSG_RESULT([yes])
+ ])
+ CFLAGS="$save_CFLAGS"
+ ])
+
+dnl
+dnl Check whether the compiler option specified as the second argument
+dnl is supported by the compiler and, if so, add it to the macro
+dnl specified as the first argument
+dnl
+AC_DEFUN(AC_LBL_CHECK_COMPILER_OPT,
+ [
+ AC_MSG_CHECKING([whether the compiler supports the $2 option])
+ save_CFLAGS="$CFLAGS"
+ if expr "x$2" : "x-W.*" >/dev/null
+ then
+ CFLAGS="$CFLAGS $ac_lbl_unknown_warning_option_error $2"
+ elif expr "x$2" : "x-f.*" >/dev/null
+ then
+ CFLAGS="$CFLAGS -Werror $2"
+ elif expr "x$2" : "x-m.*" >/dev/null
+ then
+ CFLAGS="$CFLAGS -Werror $2"
+ else
+ CFLAGS="$CFLAGS $2"
+ fi
+ AC_TRY_COMPILE(
+ [],
+ [return 0],
+ [
+ AC_MSG_RESULT([yes])
+ CFLAGS="$save_CFLAGS"
+ $1="$$1 $2"
+ ],
+ [
+ AC_MSG_RESULT([no])
+ CFLAGS="$save_CFLAGS"
+ ])
+ ])
+
+dnl
+dnl Check whether the compiler supports an option to generate
+dnl Makefile-style dependency lines
+dnl
+dnl GCC uses -M for this. Non-GCC compilers that support this
+dnl use a variety of flags, including but not limited to -M.
+dnl
+dnl We test whether the flag in question is supported, as older
+dnl versions of compilers might not support it.
+dnl
+dnl We don't try all the possible flags, just in case some flag means
+dnl "generate dependencies" on one compiler but means something else
+dnl on another compiler.
+dnl
+dnl Most compilers that support this send the output to the standard
+dnl output by default. IBM's XLC, however, supports -M but sends
+dnl the output to {sourcefile-basename}.u, and AIX has no /dev/stdout
+dnl to work around that, so we don't bother with XLC.
+dnl
+AC_DEFUN(AC_LBL_CHECK_DEPENDENCY_GENERATION_OPT,
+ [
+ AC_MSG_CHECKING([whether the compiler supports generating dependencies])
+ if test "$GCC" = yes ; then
+ #
+ # GCC, or a compiler deemed to be GCC by AC_PROG_CC (even
+ # though it's not); we assume that, in this case, the flag
+ # would be -M.
+ #
+ ac_lbl_dependency_flag="-M"
+ else
+ #
+ # Not GCC or a compiler deemed to be GCC; what platform is
+ # this? (We're assuming that if the compiler isn't GCC
+ # it's the compiler from the vendor of the OS; that won't
+ # necessarily be true for x86 platforms, where it might be
+ # the Intel C compiler.)
+ #
+ case "$host_os" in
+
+ irix*|osf*|darwin*)
+ #
+ # MIPS C for IRIX, DEC C, and clang all use -M.
+ #
+ ac_lbl_dependency_flag="-M"
+ ;;
+
+ solaris*)
+ #
+ # Sun C uses -xM.
+ #
+ ac_lbl_dependency_flag="-xM"
+ ;;
+
+ hpux*)
+ #
+ # HP's older C compilers don't support this.
+ # HP's newer C compilers support this with
+ # either +M or +Make; the older compilers
+ # interpret +M as something completely
+ # different, so we use +Make so we don't
+ # think it works with the older compilers.
+ #
+ ac_lbl_dependency_flag="+Make"
+ ;;
+
+ *)
+ #
+ # Not one of the above; assume no support for
+ # generating dependencies.
+ #
+ ac_lbl_dependency_flag=""
+ ;;
+ esac
+ fi
+
+ #
+ # Is ac_lbl_dependency_flag defined and, if so, does the compiler
+ # complain about it?
+ #
+ # Note: clang doesn't seem to exit with an error status when handed
+ # an unknown non-warning error, even if you pass it
+ # -Werror=unknown-warning-option. However, it always supports
+ # -M, so the fact that this test always succeeds with clang
+ # isn't an issue.
+ #
+ if test ! -z "$ac_lbl_dependency_flag"; then
+ AC_LANG_CONFTEST(
+ [AC_LANG_SOURCE([[int main(void) { return 0; }]])])
+ if AC_RUN_LOG([eval "$CC $ac_lbl_dependency_flag conftest.c >/dev/null 2>&1"]); then
+ AC_MSG_RESULT([yes, with $ac_lbl_dependency_flag])
+ DEPENDENCY_CFLAG="$ac_lbl_dependency_flag"
+ MKDEP='${srcdir}/mkdep'
+ else
+ AC_MSG_RESULT([no])
+ #
+ # We can't run mkdep, so have "make depend" do
+ # nothing.
+ #
+ MKDEP='${srcdir}/nomkdep'
+ fi
+ rm -rf conftest*
+ else
+ AC_MSG_RESULT([no])
+ #
+ # We can't run mkdep, so have "make depend" do
+ # nothing.
+ #
+ MKDEP='${srcdir}/nomkdep'
+ fi
+ AC_SUBST(DEPENDENCY_CFLAG)
+ AC_SUBST(MKDEP)
+ ])
+
+dnl
+dnl Determine what options are needed to build a shared library
+dnl
+dnl usage:
+dnl
+dnl AC_LBL_SHLIBS_INIT
+dnl
+dnl results:
+dnl
+dnl V_SHLIB_CCOPT (modified to build position-independent code)
+dnl V_SHLIB_CMD
+dnl V_SHLIB_OPT
+dnl V_SONAME_OPT
+dnl V_RPATH_OPT
+dnl
+AC_DEFUN(AC_LBL_SHLIBS_INIT,
+ [AC_PREREQ(2.50)
+ if test "$GCC" = yes ; then
+ #
+ # On platforms where we build a shared library:
+ #
+ # add options to generate position-independent code,
+ # if necessary (it's the default in AIX and Darwin/macOS);
+ #
+ # define option to set the soname of the shared library,
+ # if the OS supports that;
+ #
+ # add options to specify, at link time, a directory to
+ # add to the run-time search path, if that's necessary.
+ #
+ V_SHLIB_CMD="\$(CC)"
+ V_SHLIB_OPT="-shared"
+ case "$host_os" in
+
+ aix*)
+ ;;
+
+ freebsd*|netbsd*|openbsd*|dragonfly*|linux*|osf*)
+ #
+ # Platforms where the linker is the GNU linker
+ # or accepts command-line arguments like
+ # those the GNU linker accepts.
+ #
+ # Some instruction sets require -fPIC on some
+ # operating systems. Check for them. If you
+ # have a combination that requires it, add it
+ # here.
+ #
+ PIC_OPT=-fpic
+ case "$host_cpu" in
+
+ sparc64*)
+ case "$host_os" in
+
+ freebsd*|openbsd*)
+ PIC_OPT=-fPIC
+ ;;
+ esac
+ ;;
+ esac
+ V_SHLIB_CCOPT="$V_SHLIB_CCOPT $PIC_OPT"
+ V_SONAME_OPT="-Wl,-soname,"
+ V_RPATH_OPT="-Wl,-rpath,"
+ ;;
+
+ hpux*)
+ V_SHLIB_CCOPT="$V_SHLIB_CCOPT -fpic"
+ #
+ # XXX - this assumes GCC is using the HP linker,
+ # rather than the GNU linker, and that the "+h"
+ # option is used on all HP-UX platforms, both .sl
+ # and .so.
+ #
+ V_SONAME_OPT="-Wl,+h,"
+ #
+ # By default, directories specifed with -L
+ # are added to the run-time search path, so
+ # we don't add them in pcap-config.
+ #
+ ;;
+
+ solaris*)
+ V_SHLIB_CCOPT="$V_SHLIB_CCOPT -fpic"
+ #
+ # XXX - this assumes GCC is using the Sun linker,
+ # rather than the GNU linker.
+ #
+ V_SONAME_OPT="-Wl,-h,"
+ V_RPATH_OPT="-Wl,-R,"
+ ;;
+ esac
+ else
+ #
+ # Set the appropriate compiler flags and, on platforms
+ # where we build a shared library:
+ #
+ # add options to generate position-independent code,
+ # if necessary (it's the default in Darwin/macOS);
+ #
+ # if we generate ".so" shared libraries, define the
+ # appropriate options for building the shared library;
+ #
+ # add options to specify, at link time, a directory to
+ # add to the run-time search path, if that's necessary.
+ #
+ # Note: spaces after V_SONAME_OPT are significant; on
+ # some platforms the soname is passed with a GCC-like
+ # "-Wl,-soname,{soname}" option, with the soname part
+ # of the option, while on other platforms the C compiler
+ # driver takes it as a regular option with the soname
+ # following the option. The same applies to V_RPATH_OPT.
+ #
+ case "$host_os" in
+
+ aix*)
+ V_SHLIB_CMD="\$(CC)"
+ V_SHLIB_OPT="-G -bnoentry -bexpall"
+ ;;
+
+ freebsd*|netbsd*|openbsd*|dragonfly*|linux*)
+ #
+ # "cc" is GCC.
+ #
+ V_SHLIB_CCOPT="$V_SHLIB_CCOPT -fpic"
+ V_SHLIB_CMD="\$(CC)"
+ V_SHLIB_OPT="-shared"
+ V_SONAME_OPT="-Wl,-soname,"
+ V_RPATH_OPT="-Wl,-rpath,"
+ ;;
+
+ hpux*)
+ V_SHLIB_CCOPT="$V_SHLIB_CCOPT +z"
+ V_SHLIB_CMD="\$(LD)"
+ V_SHLIB_OPT="-b"
+ V_SONAME_OPT="+h "
+ #
+ # By default, directories specifed with -L
+ # are added to the run-time search path, so
+ # we don't add them in pcap-config.
+ #
+ ;;
+
+ osf*)
+ #
+ # Presumed to be DEC OSF/1, Digital UNIX, or
+ # Tru64 UNIX.
+ #
+ V_SHLIB_CMD="\$(CC)"
+ V_SHLIB_OPT="-shared"
+ V_SONAME_OPT="-soname "
+ V_RPATH_OPT="-rpath "
+ ;;
+
+ solaris*)
+ V_SHLIB_CCOPT="$V_SHLIB_CCOPT -Kpic"
+ V_SHLIB_CMD="\$(CC)"
+ V_SHLIB_OPT="-G"
+ V_SONAME_OPT="-h "
+ V_RPATH_OPT="-R"
+ ;;
+ esac
+ fi
+])
+
+#
+# Try compiling a sample of the type of code that appears in
+# gencode.c with "inline", "__inline__", and "__inline".
+#
+# Autoconf's AC_C_INLINE, at least in autoconf 2.13, isn't good enough,
+# as it just tests whether a function returning "int" can be inlined;
+# at least some versions of HP's C compiler can inline that, but can't
+# inline a function that returns a struct pointer.
+#
+# Make sure we use the V_CCOPT flags, because some of those might
+# disable inlining.
+#
+AC_DEFUN(AC_LBL_C_INLINE,
+ [AC_MSG_CHECKING(for inline)
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$V_CCOPT"
+ AC_CACHE_VAL(ac_cv_lbl_inline, [
+ ac_cv_lbl_inline=""
+ ac_lbl_cc_inline=no
+ for ac_lbl_inline in inline __inline__ __inline
+ do
+ AC_TRY_COMPILE(
+ [#define inline $ac_lbl_inline
+ static inline struct iltest *foo(void);
+ struct iltest {
+ int iltest1;
+ int iltest2;
+ };
+
+ static inline struct iltest *
+ foo()
+ {
+ static struct iltest xxx;
+
+ return &xxx;
+ }],,ac_lbl_cc_inline=yes,)
+ if test "$ac_lbl_cc_inline" = yes ; then
+ break;
+ fi
+ done
+ if test "$ac_lbl_cc_inline" = yes ; then
+ ac_cv_lbl_inline=$ac_lbl_inline
+ fi])
+ CFLAGS="$save_CFLAGS"
+ if test ! -z "$ac_cv_lbl_inline" ; then
+ AC_MSG_RESULT($ac_cv_lbl_inline)
+ else
+ AC_MSG_RESULT(no)
+ fi
+ AC_DEFINE_UNQUOTED(inline, $ac_cv_lbl_inline, [Define as token for inline if inlining supported])])
+
+dnl
+dnl If using gcc, make sure we have ANSI ioctl definitions
+dnl
+dnl usage:
+dnl
+dnl AC_LBL_FIXINCLUDES
+dnl
+AC_DEFUN(AC_LBL_FIXINCLUDES,
+ [if test "$GCC" = yes ; then
+ AC_MSG_CHECKING(for ANSI ioctl definitions)
+ AC_CACHE_VAL(ac_cv_lbl_gcc_fixincludes,
+ AC_TRY_COMPILE(
+ [/*
+ * This generates a "duplicate case value" when fixincludes
+ * has not be run.
+ */
+# include <sys/types.h>
+# include <sys/time.h>
+# include <sys/ioctl.h>
+# ifdef HAVE_SYS_IOCCOM_H
+# include <sys/ioccom.h>
+# endif],
+ [switch (0) {
+ case _IO('A', 1):;
+ case _IO('B', 1):;
+ }],
+ ac_cv_lbl_gcc_fixincludes=yes,
+ ac_cv_lbl_gcc_fixincludes=no))
+ AC_MSG_RESULT($ac_cv_lbl_gcc_fixincludes)
+ if test $ac_cv_lbl_gcc_fixincludes = no ; then
+ # Don't cache failure
+ unset ac_cv_lbl_gcc_fixincludes
+ AC_MSG_ERROR(see the INSTALL for more info)
+ fi
+ fi])
+
+dnl
+dnl Checks to see if union wait is used with WEXITSTATUS()
+dnl
+dnl usage:
+dnl
+dnl AC_LBL_UNION_WAIT
+dnl
+dnl results:
+dnl
+dnl DECLWAITSTATUS (defined)
+dnl
+AC_DEFUN(AC_LBL_UNION_WAIT,
+ [AC_MSG_CHECKING(if union wait is used)
+ AC_CACHE_VAL(ac_cv_lbl_union_wait,
+ AC_TRY_COMPILE([
+# include <sys/types.h>
+# include <sys/wait.h>],
+ [int status;
+ u_int i = WEXITSTATUS(status);
+ u_int j = waitpid(0, &status, 0);],
+ ac_cv_lbl_union_wait=no,
+ ac_cv_lbl_union_wait=yes))
+ AC_MSG_RESULT($ac_cv_lbl_union_wait)
+ if test $ac_cv_lbl_union_wait = yes ; then
+ AC_DEFINE(DECLWAITSTATUS,union wait,[type for wait])
+ else
+ AC_DEFINE(DECLWAITSTATUS,int,[type for wait])
+ fi])
+
+dnl
+dnl Checks to see if -R is used
+dnl
+dnl usage:
+dnl
+dnl AC_LBL_HAVE_RUN_PATH
+dnl
+dnl results:
+dnl
+dnl ac_cv_lbl_have_run_path (yes or no)
+dnl
+AC_DEFUN(AC_LBL_HAVE_RUN_PATH,
+ [AC_MSG_CHECKING(for ${CC-cc} -R)
+ AC_CACHE_VAL(ac_cv_lbl_have_run_path,
+ [echo 'main(){}' > conftest.c
+ ${CC-cc} -o conftest conftest.c -R/a1/b2/c3 >conftest.out 2>&1
+ if test ! -s conftest.out ; then
+ ac_cv_lbl_have_run_path=yes
+ else
+ ac_cv_lbl_have_run_path=no
+ fi
+ rm -f -r conftest*])
+ AC_MSG_RESULT($ac_cv_lbl_have_run_path)
+ ])
+
+dnl
+dnl Checks to see if unaligned memory accesses fail
+dnl
+dnl usage:
+dnl
+dnl AC_LBL_UNALIGNED_ACCESS
+dnl
+dnl results:
+dnl
+dnl LBL_ALIGN (DEFINED)
+dnl
+AC_DEFUN(AC_LBL_UNALIGNED_ACCESS,
+ [AC_MSG_CHECKING(if unaligned accesses fail)
+ AC_CACHE_VAL(ac_cv_lbl_unaligned_fail,
+ [case "$host_cpu" in
+
+ #
+ # These are CPU types where:
+ #
+ # the CPU faults on an unaligned access, but at least some
+ # OSes that support that CPU catch the fault and simulate
+ # the unaligned access (e.g., Alpha/{Digital,Tru64} UNIX) -
+ # the simulation is slow, so we don't want to use it;
+ #
+ # the CPU, I infer (from the old
+ #
+ # XXX: should also check that they don't do weird things (like on arm)
+ #
+ # comment) doesn't fault on unaligned accesses, but doesn't
+ # do a normal unaligned fetch, either (e.g., presumably, ARM);
+ #
+ # for whatever reason, the test program doesn't work
+ # (this has been claimed to be the case for several of those
+ # CPUs - I don't know what the problem is; the problem
+ # was reported as "the test program dumps core" for SuperH,
+ # but that's what the test program is *supposed* to do -
+ # it dumps core before it writes anything, so the test
+ # for an empty output file should find an empty output
+ # file and conclude that unaligned accesses don't work).
+ #
+ # This run-time test won't work if you're cross-compiling, so
+ # in order to support cross-compiling for a particular CPU,
+ # we have to wire in the list of CPU types anyway, as far as
+ # I know, so perhaps we should just have a set of CPUs on
+ # which we know it doesn't work, a set of CPUs on which we
+ # know it does work, and have the script just fail on other
+ # cpu types and update it when such a failure occurs.
+ #
+ alpha*|arm*|bfin*|hp*|mips*|sh*|sparc*|ia64|nv1)
+ ac_cv_lbl_unaligned_fail=yes
+ ;;
+
+ *)
+ cat >conftest.c <<EOF
+# include <sys/types.h>
+# include <sys/wait.h>
+# include <stdio.h>
+ unsigned char a[[5]] = { 1, 2, 3, 4, 5 };
+ main() {
+ unsigned int i;
+ pid_t pid;
+ int status;
+ /* avoid "core dumped" message */
+ pid = fork();
+ if (pid < 0)
+ exit(2);
+ if (pid > 0) {
+ /* parent */
+ pid = waitpid(pid, &status, 0);
+ if (pid < 0)
+ exit(3);
+ exit(!WIFEXITED(status));
+ }
+ /* child */
+ i = *(unsigned int *)&a[[1]];
+ printf("%d\n", i);
+ exit(0);
+ }
+EOF
+ ${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS \
+ conftest.c $LIBS >/dev/null 2>&1
+ if test ! -x conftest ; then
+ dnl failed to compile for some reason
+ ac_cv_lbl_unaligned_fail=yes
+ else
+ ./conftest >conftest.out
+ if test ! -s conftest.out ; then
+ ac_cv_lbl_unaligned_fail=yes
+ else
+ ac_cv_lbl_unaligned_fail=no
+ fi
+ fi
+ rm -f -r conftest* core core.conftest
+ ;;
+ esac])
+ AC_MSG_RESULT($ac_cv_lbl_unaligned_fail)
+ if test $ac_cv_lbl_unaligned_fail = yes ; then
+ AC_DEFINE(LBL_ALIGN,1,[if unaligned access fails])
+ fi])
+
+dnl
+dnl If the file .devel exists:
+dnl Add some warning flags if the compiler supports them
+dnl If an os prototype include exists, symlink os-proto.h to it
+dnl
+dnl usage:
+dnl
+dnl AC_LBL_DEVEL(copt)
+dnl
+dnl results:
+dnl
+dnl $1 (copt appended)
+dnl HAVE_OS_PROTO_H (defined)
+dnl os-proto.h (symlinked)
+dnl
+AC_DEFUN(AC_LBL_DEVEL,
+ [rm -f os-proto.h
+ if test "${LBL_CFLAGS+set}" = set; then
+ $1="$$1 ${LBL_CFLAGS}"
+ fi
+ if test -f .devel ; then
+ #
+ # Skip all the warning option stuff on some compilers.
+ #
+ if test "$ac_lbl_cc_dont_try_gcc_dashW" != yes; then
+ AC_LBL_CHECK_UNKNOWN_WARNING_OPTION_ERROR()
+ 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, -Wmissing-noreturn)
+ # Warns about safeguards added in case the enums are
+ # extended
+ # AC_LBL_CHECK_COMPILER_OPT($1, -Wcovered-switch-default)
+ AC_LBL_CHECK_COMPILER_OPT($1, -Wmissing-variable-declarations)
+ AC_LBL_CHECK_COMPILER_OPT($1, -Wunused-parameter)
+ AC_LBL_CHECK_COMPILER_OPT($1, -Wformat-nonliteral)
+ AC_LBL_CHECK_COMPILER_OPT($1, -Wunreachable-code)
+ fi
+ AC_LBL_CHECK_DEPENDENCY_GENERATION_OPT()
+ #
+ # We used to set -n32 for IRIX 6 when not using GCC (presumed
+ # to mean that we're using MIPS C or MIPSpro C); it specified
+ # the "new" faster 32-bit ABI, introduced in IRIX 6.2. I'm
+ # not sure why that would be something to do *only* with a
+ # .devel file; why should the ABI for which we produce code
+ # depend on .devel?
+ #
+ os=`echo $host_os | sed -e 's/\([[0-9]][[0-9]]*\)[[^0-9]].*$/\1/'`
+ name="lbl/os-$os.h"
+ if test -f $name ; then
+ ln -s $name os-proto.h
+ AC_DEFINE(HAVE_OS_PROTO_H, 1,
+ [if there's an os_proto.h for this platform, to use additional prototypes])
+ else
+ AC_MSG_WARN(can't find $name)
+ fi
+ fi])
+
+dnl
+dnl Improved version of AC_CHECK_LIB
+dnl
+dnl Thanks to John Hawkinson (jhawk@mit.edu)
+dnl
+dnl usage:
+dnl
+dnl AC_LBL_CHECK_LIB(LIBRARY, FUNCTION [, ACTION-IF-FOUND [,
+dnl ACTION-IF-NOT-FOUND [, OTHER-LIBRARIES]]])
+dnl
+dnl results:
+dnl
+dnl LIBS
+dnl
+dnl XXX - "AC_LBL_LIBRARY_NET" was redone to use "AC_SEARCH_LIBS"
+dnl rather than "AC_LBL_CHECK_LIB", so this isn't used any more.
+dnl We keep it around for reference purposes in case it's ever
+dnl useful in the future.
+dnl
+
+define(AC_LBL_CHECK_LIB,
+[AC_MSG_CHECKING([for $2 in -l$1])
+dnl Use a cache variable name containing the library, function
+dnl name, and extra libraries to link with, because the test really is
+dnl for library $1 defining function $2, when linked with potinal
+dnl library $5, not just for library $1. Separate tests with the same
+dnl $1 and different $2's or $5's may have different results.
+ac_lib_var=`echo $1['_']$2['_']$5 | sed 'y%./+- %__p__%'`
+AC_CACHE_VAL(ac_cv_lbl_lib_$ac_lib_var,
+[ac_save_LIBS="$LIBS"
+LIBS="-l$1 $5 $LIBS"
+AC_TRY_LINK(dnl
+ifelse([$2], [main], , dnl Avoid conflicting decl of main.
+[/* Override any gcc2 internal prototype to avoid an error. */
+]ifelse(AC_LANG, CPLUSPLUS, [#ifdef __cplusplus
+extern "C"
+#endif
+])dnl
+[/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $2();
+]),
+ [$2()],
+ eval "ac_cv_lbl_lib_$ac_lib_var=yes",
+ eval "ac_cv_lbl_lib_$ac_lib_var=no")
+LIBS="$ac_save_LIBS"
+])dnl
+if eval "test \"`echo '$ac_cv_lbl_lib_'$ac_lib_var`\" = yes"; then
+ AC_MSG_RESULT(yes)
+ ifelse([$3], ,
+[changequote(, )dnl
+ ac_tr_lib=HAVE_LIB`echo $1 | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+changequote([, ])dnl
+ AC_DEFINE_UNQUOTED($ac_tr_lib)
+ LIBS="-l$1 $LIBS"
+], [$3])
+else
+ AC_MSG_RESULT(no)
+ifelse([$4], , , [$4
+])dnl
+fi
+])
+
+dnl
+dnl AC_LBL_LIBRARY_NET
+dnl
+dnl This test is for network applications that need socket functions and
+dnl getaddrinfo()/getnameinfo()-ish functions. We now require
+dnl getaddrinfo() and getnameinfo(). We also prefer versions of
+dnl recvmsg() that conform to the Single UNIX Specification, so that we
+dnl can check whether a datagram received with recvmsg() was truncated
+dnl when received due to the buffer being too small.
+dnl
+dnl On most operating systems, they're available in the system library.
+dnl
+dnl Under Solaris, we need to link with libsocket and libnsl to get
+dnl getaddrinfo() and getnameinfo() and, if we have libxnet, we need to
+dnl link with libxnet before libsocket to get a version of recvmsg()
+dnl that conforms to the Single UNIX Specification.
+dnl
+dnl We use getaddrinfo() because we want a portable thread-safe way
+dnl of getting information for a host name or port; there exist _r
+dnl versions of gethostbyname() and getservbyname() on some platforms,
+dnl but not on all platforms.
+dnl
+AC_DEFUN(AC_LBL_LIBRARY_NET, [
+ #
+ # Most operating systems have getaddrinfo() in the default searched
+ # libraries (i.e. libc). Check there first.
+ #
+ AC_CHECK_FUNC(getaddrinfo,,
+ [
+ #
+ # Not found in the standard system libraries.
+ # Try libsocket, which requires libnsl.
+ #
+ AC_CHECK_LIB(socket, getaddrinfo,
+ [
+ #
+ # OK, we found it in libsocket.
+ #
+ LIBS="-lsocket -lnsl $LIBS"
+ ],
+ [
+ #
+ # We didn't find it.
+ #
+ AC_MSG_ERROR([getaddrinfo is required, but wasn't found])
+ ], -lnsl)
+
+ #
+ # OK, do we have recvmsg() in libxnet?
+ # We also link with libsocket and libnsl.
+ #
+ AC_CHECK_LIB(xnet, recvmsg,
+ [
+ #
+ # Yes - link with it as well.
+ #
+ LIBS="-lxnet $LIBS"
+ ], , -lsocket -lnsl)
+ ])
+ # DLPI needs putmsg under HPUX so test for -lstr while we're at it
+ AC_SEARCH_LIBS(putmsg, str)
+])
diff --git a/contrib/libpcap/bpf_dump.c b/contrib/libpcap/bpf_dump.c
index d5ab61e5e8ffe..a9c91169fbbba 100644
--- a/contrib/libpcap/bpf_dump.c
+++ b/contrib/libpcap/bpf_dump.c
@@ -20,12 +20,14 @@
*/
#ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
#endif
#include <pcap.h>
#include <stdio.h>
+#include "optimize.h"
+
void
bpf_dump(const struct bpf_program *p, int option)
{
@@ -50,8 +52,7 @@ bpf_dump(const struct bpf_program *p, int option)
}
for (i = 0; i < n; ++insn, ++i) {
#ifdef BDEBUG
- extern int bids[];
- if (bids[i] > 0)
+ if (i < NBIDS && bids[i] > 0)
printf("[%02d]", bids[i] - 1);
else
printf(" -- ");
diff --git a/contrib/libpcap/bpf/net/bpf_filter.c b/contrib/libpcap/bpf_filter.c
index 0a80cdc528831..615ed3fc3d0f5 100644
--- a/contrib/libpcap/bpf/net/bpf_filter.c
+++ b/contrib/libpcap/bpf_filter.c
@@ -39,52 +39,21 @@
*/
#ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
#endif
-#ifdef _WIN32
-
-#include <pcap-stdinc.h>
-
-#else /* _WIN32 */
-
-#if HAVE_INTTYPES_H
-#include <inttypes.h>
-#elif HAVE_STDINT_H
-#include <stdint.h>
-#endif
-#ifdef HAVE_SYS_BITYPES_H
-#include <sys/bitypes.h>
-#endif
+#include <pcap/pcap-inttypes.h>
+#include "pcap-types.h"
+#ifndef _WIN32
#include <sys/param.h>
#include <sys/types.h>
#include <sys/time.h>
-
-#if (defined(sun) && (defined(__SVR4) || defined(__svr4__)))
-#define SOLARIS 1
-#else
-#define SOLARIS 0
-#endif
-
-#if defined(__hpux) || SOLARIS
-# include <sys/sysmacros.h>
-# include <sys/stream.h>
-# define mbuf msgb
-# define m_next b_cont
-# define MLEN(m) ((m)->b_wptr - (m)->b_rptr)
-# define mtod(m,t) ((t)(m)->b_rptr)
-#else /* defined(__hpux) || SOLARIS */
-# define MLEN(m) ((m)->m_len)
-#endif /* defined(__hpux) || SOLARIS */
-
#endif /* _WIN32 */
#include <pcap/bpf.h>
-#if !defined(KERNEL) && !defined(_KERNEL)
#include <stdlib.h>
-#endif
#define int32 bpf_int32
#define u_int32 bpf_u_int32
@@ -122,84 +91,6 @@
(u_int32)*((u_char *)p+3)<<0)
#endif
-#if defined(KERNEL) || defined(_KERNEL)
-# if !defined(__hpux) && !SOLARIS
-#include <sys/mbuf.h>
-# endif
-#define MINDEX(len, _m, _k) \
-{ \
- len = MLEN(m); \
- while ((_k) >= len) { \
- (_k) -= len; \
- (_m) = (_m)->m_next; \
- if ((_m) == 0) \
- return 0; \
- len = MLEN(m); \
- } \
-}
-
-static int
-m_xword(m, k, err)
- register struct mbuf *m;
- register int k, *err;
-{
- register int len;
- register u_char *cp, *np;
- register struct mbuf *m0;
-
- MINDEX(len, m, k);
- cp = mtod(m, u_char *) + k;
- if (len - k >= 4) {
- *err = 0;
- return EXTRACT_LONG(cp);
- }
- m0 = m->m_next;
- if (m0 == 0 || MLEN(m0) + len - k < 4)
- goto bad;
- *err = 0;
- np = mtod(m0, u_char *);
- switch (len - k) {
-
- case 1:
- return (cp[0] << 24) | (np[0] << 16) | (np[1] << 8) | np[2];
-
- case 2:
- return (cp[0] << 24) | (cp[1] << 16) | (np[0] << 8) | np[1];
-
- default:
- return (cp[0] << 24) | (cp[1] << 16) | (cp[2] << 8) | np[0];
- }
- bad:
- *err = 1;
- return 0;
-}
-
-static int
-m_xhalf(m, k, err)
- register struct mbuf *m;
- register int k, *err;
-{
- register int len;
- register u_char *cp;
- register struct mbuf *m0;
-
- MINDEX(len, m, k);
- cp = mtod(m, u_char *) + k;
- if (len - k >= 2) {
- *err = 0;
- return EXTRACT_SHORT(cp);
- }
- m0 = m->m_next;
- if (m0 == 0)
- goto bad;
- *err = 0;
- return (cp[0] << 8) | mtod(m0, u_char *)[0];
- bad:
- *err = 1;
- return 0;
-}
-#endif
-
#ifdef __linux__
#include <linux/types.h>
#include <linux/if_packet.h>
@@ -225,27 +116,12 @@ enum {
* Thanks to Ani Sinha <ani@arista.com> for providing initial implementation
*/
u_int
-bpf_filter_with_aux_data(pc, p, wirelen, buflen, aux_data)
- register const struct bpf_insn *pc;
- register const u_char *p;
- u_int wirelen;
- register u_int buflen;
- register const struct bpf_aux_data *aux_data;
+bpf_filter_with_aux_data(const struct bpf_insn *pc, const u_char *p,
+ u_int wirelen, u_int buflen, const struct bpf_aux_data *aux_data)
{
register u_int32 A, X;
register bpf_u_int32 k;
u_int32 mem[BPF_MEMWORDS];
-#if defined(KERNEL) || defined(_KERNEL)
- struct mbuf *m, *n;
- int merr, len;
-
- if (buflen == 0) {
- m = (struct mbuf *)p;
- p = mtod(m, u_char *);
- buflen = MLEN(m);
- } else
- m = NULL;
-#endif
if (pc == 0)
/*
@@ -255,16 +131,12 @@ bpf_filter_with_aux_data(pc, p, wirelen, buflen, aux_data)
A = 0;
X = 0;
--pc;
- while (1) {
+ for (;;) {
++pc;
switch (pc->code) {
default:
-#if defined(KERNEL) || defined(_KERNEL)
- return 0;
-#else
abort();
-#endif
case BPF_RET|BPF_K:
return (u_int)pc->k;
@@ -274,16 +146,7 @@ bpf_filter_with_aux_data(pc, p, wirelen, buflen, aux_data)
case BPF_LD|BPF_W|BPF_ABS:
k = pc->k;
if (k > buflen || sizeof(int32_t) > buflen - k) {
-#if defined(KERNEL) || defined(_KERNEL)
- if (m == NULL)
- return 0;
- A = m_xword(m, k, &merr);
- if (merr != 0)
- return 0;
- continue;
-#else
return 0;
-#endif
}
A = EXTRACT_LONG(&p[k]);
continue;
@@ -291,65 +154,37 @@ bpf_filter_with_aux_data(pc, p, wirelen, buflen, aux_data)
case BPF_LD|BPF_H|BPF_ABS:
k = pc->k;
if (k > buflen || sizeof(int16_t) > buflen - k) {
-#if defined(KERNEL) || defined(_KERNEL)
- if (m == NULL)
- return 0;
- A = m_xhalf(m, k, &merr);
- if (merr != 0)
- return 0;
- continue;
-#else
return 0;
-#endif
}
A = EXTRACT_SHORT(&p[k]);
continue;
case BPF_LD|BPF_B|BPF_ABS:
- {
-#if defined(SKF_AD_VLAN_TAG) && defined(SKF_AD_VLAN_TAG_PRESENT)
- int code = BPF_S_ANC_NONE;
-#define ANCILLARY(CODE) case SKF_AD_OFF + SKF_AD_##CODE: \
- code = BPF_S_ANC_##CODE; \
- if (!aux_data) \
- return 0; \
- break;
-
- switch (pc->k) {
- ANCILLARY(VLAN_TAG);
- ANCILLARY(VLAN_TAG_PRESENT);
- default :
-#endif
- k = pc->k;
- if (k >= buflen) {
-#if defined(KERNEL) || defined(_KERNEL)
- if (m == NULL)
- return 0;
- n = m;
- MINDEX(len, n, k);
- A = mtod(n, u_char *)[k];
- continue;
-#else
- return 0;
+ switch (pc->k) {
+
+#if defined(SKF_AD_VLAN_TAG_PRESENT)
+ case SKF_AD_OFF + SKF_AD_VLAN_TAG:
+ if (!aux_data)
+ return 0;
+ A = aux_data->vlan_tag;
+ break;
+
+ case SKF_AD_OFF + SKF_AD_VLAN_TAG_PRESENT:
+ if (!aux_data)
+ return 0;
+ A = aux_data->vlan_tag_present;
+ break;
#endif
- }
- A = p[k];
-#if defined(SKF_AD_VLAN_TAG) && defined(SKF_AD_VLAN_TAG_PRESENT)
- }
- switch (code) {
- case BPF_S_ANC_VLAN_TAG:
- if (aux_data)
- A = aux_data->vlan_tag;
- break;
-
- case BPF_S_ANC_VLAN_TAG_PRESENT:
- if (aux_data)
- A = aux_data->vlan_tag_present;
- break;
+ default:
+ k = pc->k;
+ if (k >= buflen) {
+ return 0;
}
-#endif
- continue;
+ A = p[k];
+ break;
}
+ continue;
+
case BPF_LD|BPF_W|BPF_LEN:
A = wirelen;
continue;
@@ -362,16 +197,7 @@ bpf_filter_with_aux_data(pc, p, wirelen, buflen, aux_data)
k = X + pc->k;
if (pc->k > buflen || X > buflen - pc->k ||
sizeof(int32_t) > buflen - k) {
-#if defined(KERNEL) || defined(_KERNEL)
- if (m == NULL)
- return 0;
- A = m_xword(m, k, &merr);
- if (merr != 0)
- return 0;
- continue;
-#else
return 0;
-#endif
}
A = EXTRACT_LONG(&p[k]);
continue;
@@ -380,16 +206,7 @@ bpf_filter_with_aux_data(pc, p, wirelen, buflen, aux_data)
k = X + pc->k;
if (X > buflen || pc->k > buflen - X ||
sizeof(int16_t) > buflen - k) {
-#if defined(KERNEL) || defined(_KERNEL)
- if (m == NULL)
- return 0;
- A = m_xhalf(m, k, &merr);
- if (merr != 0)
- return 0;
- continue;
-#else
return 0;
-#endif
}
A = EXTRACT_SHORT(&p[k]);
continue;
@@ -397,16 +214,7 @@ bpf_filter_with_aux_data(pc, p, wirelen, buflen, aux_data)
case BPF_LD|BPF_B|BPF_IND:
k = X + pc->k;
if (pc->k >= buflen || X >= buflen - pc->k) {
-#if defined(KERNEL) || defined(_KERNEL)
- if (m == NULL)
- return 0;
- n = m;
- MINDEX(len, n, k);
- A = mtod(n, u_char *)[k];
- continue;
-#else
return 0;
-#endif
}
A = p[k];
continue;
@@ -414,16 +222,7 @@ bpf_filter_with_aux_data(pc, p, wirelen, buflen, aux_data)
case BPF_LDX|BPF_MSH|BPF_B:
k = pc->k;
if (k >= buflen) {
-#if defined(KERNEL) || defined(_KERNEL)
- if (m == NULL)
- return 0;
- n = m;
- MINDEX(len, n, k);
- X = (mtod(n, char *)[k] & 0xf) << 2;
- continue;
-#else
return 0;
-#endif
}
X = (p[pc->k] & 0xf) << 2;
continue;
@@ -453,18 +252,11 @@ bpf_filter_with_aux_data(pc, p, wirelen, buflen, aux_data)
continue;
case BPF_JMP|BPF_JA:
-#if defined(KERNEL) || defined(_KERNEL)
- /*
- * No backward jumps allowed.
- */
- pc += pc->k;
-#else
/*
* XXX - we currently implement "ip6 protochain"
* with backward jumps, so sign-extend pc->k.
*/
pc += (bpf_int32)pc->k;
-#endif
continue;
case BPF_JMP|BPF_JGT|BPF_K:
@@ -604,11 +396,8 @@ bpf_filter_with_aux_data(pc, p, wirelen, buflen, aux_data)
}
u_int
-bpf_filter(pc, p, wirelen, buflen)
- register const struct bpf_insn *pc;
- register const u_char *p;
- u_int wirelen;
- register u_int buflen;
+bpf_filter(const struct bpf_insn *pc, const u_char *p, u_int wirelen,
+ u_int buflen)
{
return bpf_filter_with_aux_data(pc, p, wirelen, buflen, NULL);
}
@@ -626,22 +415,13 @@ bpf_filter(pc, p, wirelen, buflen)
* Otherwise, a bogus program could easily crash the system.
*/
int
-bpf_validate(f, len)
- const struct bpf_insn *f;
- int len;
+bpf_validate(const struct bpf_insn *f, int len)
{
u_int i, from;
const struct bpf_insn *p;
if (len < 1)
return 0;
- /*
- * There's no maximum program length in userland.
- */
-#if defined(KERNEL) || defined(_KERNEL)
- if (len > BPF_MAXINSNS)
- return 0;
-#endif
for (i = 0; i < (u_int)len; ++i) {
p = &f[i];
@@ -662,14 +442,6 @@ bpf_validate(f, len)
* in userland. The runtime packet length
* check suffices.
*/
-#if defined(KERNEL) || defined(_KERNEL)
- /*
- * More strict check with actual packet length
- * is done runtime.
- */
- if (p->k >= bpf_maxbufsize)
- return 0;
-#endif
break;
case BPF_MEM:
if (p->k >= BPF_MEMWORDS)
@@ -741,11 +513,7 @@ bpf_validate(f, len)
from = i + 1;
switch (BPF_OP(p->code)) {
case BPF_JA:
-#if defined(KERNEL) || defined(_KERNEL)
- if (from + p->k < from || from + p->k >= len)
-#else
if (from + p->k >= (u_int)len)
-#endif
return 0;
break;
case BPF_JEQ:
diff --git a/contrib/libpcap/bpf_image.c b/contrib/libpcap/bpf_image.c
index 01ec536dfd622..ab41d1ef98bd7 100644
--- a/contrib/libpcap/bpf_image.c
+++ b/contrib/libpcap/bpf_image.c
@@ -20,22 +20,10 @@
*/
#ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
#endif
-#ifdef _WIN32
-#include <pcap-stdinc.h>
-#else /* _WIN32 */
-#if HAVE_INTTYPES_H
-#include <inttypes.h>
-#elif HAVE_STDINT_H
-#include <stdint.h>
-#endif
-#ifdef HAVE_SYS_BITYPES_H
-#include <sys/bitypes.h>
-#endif
-#include <sys/types.h>
-#endif /* _WIN32 */
+#include <pcap-types.h>
#include <stdio.h>
#include <string.h>
@@ -47,266 +35,290 @@
#endif
char *
-bpf_image(p, n)
- const struct bpf_insn *p;
- int n;
+bpf_image(const struct bpf_insn *p, int n)
{
- int v;
- const char *fmt, *op;
+ const char *op;
static char image[256];
- char operand[64];
+ char operand_buf[64];
+ const char *operand;
- v = p->k;
switch (p->code) {
default:
op = "unimp";
- fmt = "0x%x";
- v = p->code;
+ (void)pcap_snprintf(operand_buf, sizeof operand_buf, "0x%x", p->code);
+ operand = operand_buf;
break;
case BPF_RET|BPF_K:
op = "ret";
- fmt = "#%d";
+ (void)pcap_snprintf(operand_buf, sizeof operand_buf, "#%d", p->k);
+ operand = operand_buf;
break;
case BPF_RET|BPF_A:
op = "ret";
- fmt = "";
+ operand = "";
break;
case BPF_LD|BPF_W|BPF_ABS:
op = "ld";
- fmt = "[%d]";
+ (void)pcap_snprintf(operand_buf, sizeof operand_buf, "[%d]", p->k);
+ operand = operand_buf;
break;
case BPF_LD|BPF_H|BPF_ABS:
op = "ldh";
- fmt = "[%d]";
+ (void)pcap_snprintf(operand_buf, sizeof operand_buf, "[%d]", p->k);
+ operand = operand_buf;
break;
case BPF_LD|BPF_B|BPF_ABS:
op = "ldb";
- fmt = "[%d]";
+ (void)pcap_snprintf(operand_buf, sizeof operand_buf, "[%d]", p->k);
+ operand = operand_buf;
break;
case BPF_LD|BPF_W|BPF_LEN:
op = "ld";
- fmt = "#pktlen";
+ operand = "#pktlen";
break;
case BPF_LD|BPF_W|BPF_IND:
op = "ld";
- fmt = "[x + %d]";
+ (void)pcap_snprintf(operand_buf, sizeof operand_buf, "[x + %d]", p->k);
+ operand = operand_buf;
break;
case BPF_LD|BPF_H|BPF_IND:
op = "ldh";
- fmt = "[x + %d]";
+ (void)pcap_snprintf(operand_buf, sizeof operand_buf, "[x + %d]", p->k);
+ operand = operand_buf;
break;
case BPF_LD|BPF_B|BPF_IND:
op = "ldb";
- fmt = "[x + %d]";
+ (void)pcap_snprintf(operand_buf, sizeof operand_buf, "[x + %d]", p->k);
+ operand = operand_buf;
break;
case BPF_LD|BPF_IMM:
op = "ld";
- fmt = "#0x%x";
+ (void)pcap_snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k);
+ operand = operand_buf;
break;
case BPF_LDX|BPF_IMM:
op = "ldx";
- fmt = "#0x%x";
+ (void)pcap_snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k);
+ operand = operand_buf;
break;
case BPF_LDX|BPF_MSH|BPF_B:
op = "ldxb";
- fmt = "4*([%d]&0xf)";
+ (void)pcap_snprintf(operand_buf, sizeof operand_buf, "4*([%d]&0xf)", p->k);
+ operand = operand_buf;
break;
case BPF_LD|BPF_MEM:
op = "ld";
- fmt = "M[%d]";
+ (void)pcap_snprintf(operand_buf, sizeof operand_buf, "M[%d]", p->k);
+ operand = operand_buf;
break;
case BPF_LDX|BPF_MEM:
op = "ldx";
- fmt = "M[%d]";
+ (void)pcap_snprintf(operand_buf, sizeof operand_buf, "M[%d]", p->k);
+ operand = operand_buf;
break;
case BPF_ST:
op = "st";
- fmt = "M[%d]";
+ (void)pcap_snprintf(operand_buf, sizeof operand_buf, "M[%d]", p->k);
+ operand = operand_buf;
break;
case BPF_STX:
op = "stx";
- fmt = "M[%d]";
+ (void)pcap_snprintf(operand_buf, sizeof operand_buf, "M[%d]", p->k);
+ operand = operand_buf;
break;
case BPF_JMP|BPF_JA:
op = "ja";
- fmt = "%d";
- v = n + 1 + p->k;
+ (void)pcap_snprintf(operand_buf, sizeof operand_buf, "%d", n + 1 + p->k);
+ operand = operand_buf;
break;
case BPF_JMP|BPF_JGT|BPF_K:
op = "jgt";
- fmt = "#0x%x";
+ (void)pcap_snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k);
+ operand = operand_buf;
break;
case BPF_JMP|BPF_JGE|BPF_K:
op = "jge";
- fmt = "#0x%x";
+ (void)pcap_snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k);
+ operand = operand_buf;
break;
case BPF_JMP|BPF_JEQ|BPF_K:
op = "jeq";
- fmt = "#0x%x";
+ (void)pcap_snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k);
+ operand = operand_buf;
break;
case BPF_JMP|BPF_JSET|BPF_K:
op = "jset";
- fmt = "#0x%x";
+ (void)pcap_snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k);
+ operand = operand_buf;
break;
case BPF_JMP|BPF_JGT|BPF_X:
op = "jgt";
- fmt = "x";
+ operand = "x";
break;
case BPF_JMP|BPF_JGE|BPF_X:
op = "jge";
- fmt = "x";
+ operand = "x";
break;
case BPF_JMP|BPF_JEQ|BPF_X:
op = "jeq";
- fmt = "x";
+ operand = "x";
break;
case BPF_JMP|BPF_JSET|BPF_X:
op = "jset";
- fmt = "x";
+ operand = "x";
break;
case BPF_ALU|BPF_ADD|BPF_X:
op = "add";
- fmt = "x";
+ operand = "x";
break;
case BPF_ALU|BPF_SUB|BPF_X:
op = "sub";
- fmt = "x";
+ operand = "x";
break;
case BPF_ALU|BPF_MUL|BPF_X:
op = "mul";
- fmt = "x";
+ operand = "x";
break;
case BPF_ALU|BPF_DIV|BPF_X:
op = "div";
- fmt = "x";
+ operand = "x";
break;
case BPF_ALU|BPF_MOD|BPF_X:
op = "mod";
- fmt = "x";
+ operand = "x";
break;
case BPF_ALU|BPF_AND|BPF_X:
op = "and";
- fmt = "x";
+ operand = "x";
break;
case BPF_ALU|BPF_OR|BPF_X:
op = "or";
- fmt = "x";
+ operand = "x";
break;
case BPF_ALU|BPF_XOR|BPF_X:
op = "xor";
- fmt = "x";
+ operand = "x";
break;
case BPF_ALU|BPF_LSH|BPF_X:
op = "lsh";
- fmt = "x";
+ operand = "x";
break;
case BPF_ALU|BPF_RSH|BPF_X:
op = "rsh";
- fmt = "x";
+ operand = "x";
break;
case BPF_ALU|BPF_ADD|BPF_K:
op = "add";
- fmt = "#%d";
+ (void)pcap_snprintf(operand_buf, sizeof operand_buf, "#%d", p->k);
+ operand = operand_buf;
break;
case BPF_ALU|BPF_SUB|BPF_K:
op = "sub";
- fmt = "#%d";
+ (void)pcap_snprintf(operand_buf, sizeof operand_buf, "#%d", p->k);
+ operand = operand_buf;
break;
case BPF_ALU|BPF_MUL|BPF_K:
op = "mul";
- fmt = "#%d";
+ (void)pcap_snprintf(operand_buf, sizeof operand_buf, "#%d", p->k);
+ operand = operand_buf;
break;
case BPF_ALU|BPF_DIV|BPF_K:
op = "div";
- fmt = "#%d";
+ (void)pcap_snprintf(operand_buf, sizeof operand_buf, "#%d", p->k);
+ operand = operand_buf;
break;
case BPF_ALU|BPF_MOD|BPF_K:
op = "mod";
- fmt = "#%d";
+ (void)pcap_snprintf(operand_buf, sizeof operand_buf, "#%d", p->k);
+ operand = operand_buf;
break;
case BPF_ALU|BPF_AND|BPF_K:
op = "and";
- fmt = "#0x%x";
+ (void)pcap_snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k);
+ operand = operand_buf;
break;
case BPF_ALU|BPF_OR|BPF_K:
op = "or";
- fmt = "#0x%x";
+ (void)pcap_snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k);
+ operand = operand_buf;
break;
case BPF_ALU|BPF_XOR|BPF_K:
op = "xor";
- fmt = "#0x%x";
+ (void)pcap_snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k);
+ operand = operand_buf;
break;
case BPF_ALU|BPF_LSH|BPF_K:
op = "lsh";
- fmt = "#%d";
+ (void)pcap_snprintf(operand_buf, sizeof operand_buf, "#%d", p->k);
+ operand = operand_buf;
break;
case BPF_ALU|BPF_RSH|BPF_K:
op = "rsh";
- fmt = "#%d";
+ (void)pcap_snprintf(operand_buf, sizeof operand_buf, "#%d", p->k);
+ operand = operand_buf;
break;
case BPF_ALU|BPF_NEG:
op = "neg";
- fmt = "";
+ operand = "";
break;
case BPF_MISC|BPF_TAX:
op = "tax";
- fmt = "";
+ operand = "";
break;
case BPF_MISC|BPF_TXA:
op = "txa";
- fmt = "";
+ operand = "";
break;
}
- (void)pcap_snprintf(operand, sizeof operand, fmt, v);
if (BPF_CLASS(p->code) == BPF_JMP && BPF_OP(p->code) != BPF_JA) {
(void)pcap_snprintf(image, sizeof image,
"(%03d) %-8s %-16s jt %d\tjf %d",
diff --git a/contrib/libpcap/chmod_bpf b/contrib/libpcap/chmod_bpf
index 0a30d99301e40..946fec37f2c85 100755
--- a/contrib/libpcap/chmod_bpf
+++ b/contrib/libpcap/chmod_bpf
@@ -1,7 +1,7 @@
#! /bin/sh
#
-# Unfortunately, Mac OS X's devfs is based on the old FreeBSD
+# Unfortunately, macOS's devfs is based on the old FreeBSD
# one, not the current one, so there's no way to configure it
# to create BPF devices with particular owners or groups.
# This startup item will make it owned by the admin group,
diff --git a/contrib/libpcap/cmake/Modules/FindDAG.cmake b/contrib/libpcap/cmake/Modules/FindDAG.cmake
new file mode 100644
index 0000000000000..ef13528445585
--- /dev/null
+++ b/contrib/libpcap/cmake/Modules/FindDAG.cmake
@@ -0,0 +1,32 @@
+#
+# Try to find the Endace DAG library.
+#
+
+# Try to find the header
+find_path(DAG_INCLUDE_DIR dagapi.h)
+
+#
+# Try to find the libraries
+#
+# We assume that if we have libdag we have libdagconf, as they're
+# installed at the same time from the same package.
+#
+find_library(DAG_LIBRARY dag)
+find_library(DAGCONF_LIBRARY dagconf)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(DAG
+ DEFAULT_MSG
+ DAG_INCLUDE_DIR
+ DAG_LIBRARY
+ DAGCONF_LIBRARY
+)
+
+mark_as_advanced(
+ DAG_INCLUDE_DIR
+ DAG_LIBRARY
+ DAGCONF_LIBRARY
+)
+
+set(DAG_INCLUDE_DIRS ${DAG_INCLUDE_DIR})
+set(DAG_LIBRARIES ${DAG_LIBRARY} ${DAGCONF_LIBRARY})
diff --git a/contrib/libpcap/cmake/Modules/FindFseeko.cmake b/contrib/libpcap/cmake/Modules/FindFseeko.cmake
new file mode 100644
index 0000000000000..ca53a5a614251
--- /dev/null
+++ b/contrib/libpcap/cmake/Modules/FindFseeko.cmake
@@ -0,0 +1,85 @@
+# CMake support for fseeko
+#
+# Based on FindLFS.cmake by
+# Copyright (C) 2016 Julian Andres Klode <jak@debian.org>.
+#
+# Permission is hereby granted, free of charge, to any person
+# obtaining a copy of this software and associated documentation files
+# (the "Software"), to deal in the Software without restriction,
+# including without limitation the rights to use, copy, modify, merge,
+# publish, distribute, sublicense, and/or sell copies of the Software,
+# and to permit persons to whom the Software is furnished to do so,
+# subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+#
+# This defines the following variables
+#
+# FSEEKO_DEFINITIONS - List of definitions to pass to add_definitions()
+# FSEEKO_COMPILE_OPTIONS - List of definitions to pass to add_compile_options()
+# FSEEKO_LIBRARIES - List of libraries and linker flags
+# FSEEKO_FOUND - If there is Large files support
+#
+
+include(CheckCSourceCompiles)
+include(FindPackageHandleStandardArgs)
+include(CMakePushCheckState)
+
+# Check for the availability of fseeko()
+# The cases handled are:
+#
+# * Native fseeko()
+# * Preprocessor flag -D_LARGEFILE_SOURCE
+#
+function(_fseeko_check)
+ set(_fseeko_cppflags)
+ cmake_push_check_state()
+ set(CMAKE_REQUIRED_QUIET 1)
+ set(CMAKE_REQUIRED_DEFINITIONS ${LFS_DEFINITIONS})
+ message(STATUS "Looking for native fseeko support")
+ check_symbol_exists(fseeko stdio.h fseeko_native)
+ cmake_pop_check_state()
+ if (fseeko_native)
+ message(STATUS "Looking for native fseeko support - found")
+ set(FSEEKO_FOUND TRUE)
+ else()
+ message(STATUS "Looking for native fseeko support - not found")
+ endif()
+
+ if (NOT FSEEKO_FOUND)
+ # See if it's available with _LARGEFILE_SOURCE.
+ cmake_push_check_state()
+ set(CMAKE_REQUIRED_QUIET 1)
+ set(CMAKE_REQUIRED_DEFINITIONS ${LFS_DEFINITIONS} "-D_LARGEFILE_SOURCE")
+ check_symbol_exists(fseeko stdio.h fseeko_need_largefile_source)
+ cmake_pop_check_state()
+ if (fseeko_need_largefile_source)
+ message(STATUS "Looking for fseeko support with _LARGEFILE_SOURCE - found")
+ set(FSEEKO_FOUND TRUE)
+ set(_fseeko_cppflags "-D_LARGEFILE_SOURCE")
+ else()
+ message(STATUS "Looking for fseeko support with _LARGEFILE_SOURCE - not found")
+ endif()
+ endif()
+
+ set(FSEEKO_DEFINITIONS ${_fseeko_cppflags} CACHE STRING "Extra definitions for fseeko support")
+ set(FSEEKO_COMPILE_OPTIONS "" CACHE STRING "Extra compiler options for fseeko support")
+ set(FSEEKO_LIBRARIES "" CACHE STRING "Extra definitions for fseeko support")
+ set(FSEEKO_FOUND ${FSEEKO_FOUND} CACHE INTERNAL "Found fseeko")
+endfunction()
+
+if (NOT FSEEKO_FOUND)
+ _fseeko_check()
+endif()
+
+find_package_handle_standard_args(FSEEKO "Could not find fseeko. Set FSEEKO_DEFINITIONS, FSEEKO_COMPILE_OPTIONS, FSEEKO_LIBRARIES." FSEEKO_FOUND)
diff --git a/contrib/libpcap/cmake/Modules/FindLFS.cmake b/contrib/libpcap/cmake/Modules/FindLFS.cmake
new file mode 100644
index 0000000000000..be5f0d4875a80
--- /dev/null
+++ b/contrib/libpcap/cmake/Modules/FindLFS.cmake
@@ -0,0 +1,153 @@
+# CMake support for large files
+#
+# Copyright (C) 2016 Julian Andres Klode <jak@debian.org>.
+#
+# Permission is hereby granted, free of charge, to any person
+# obtaining a copy of this software and associated documentation files
+# (the "Software"), to deal in the Software without restriction,
+# including without limitation the rights to use, copy, modify, merge,
+# publish, distribute, sublicense, and/or sell copies of the Software,
+# and to permit persons to whom the Software is furnished to do so,
+# subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+#
+# This defines the following variables
+#
+# LFS_DEFINITIONS - List of definitions to pass to add_definitions()
+# LFS_COMPILE_OPTIONS - List of definitions to pass to add_compile_options()
+# LFS_LIBRARIES - List of libraries and linker flags
+# LFS_FOUND - If there is Large files support
+#
+
+include(CheckCSourceCompiles)
+include(FindPackageHandleStandardArgs)
+include(CMakePushCheckState)
+
+# Test program to check for LFS. Requires that off_t has at least 8 byte large
+set(_lfs_test_source
+ "
+ #include <sys/types.h>
+ typedef char my_static_assert[sizeof(off_t) >= 8 ? 1 : -1];
+ int main(void) { return 0; }
+ "
+)
+
+# Check if the given options are needed
+#
+# This appends to the variables _lfs_cppflags, _lfs_cflags, and _lfs_ldflags,
+# it also sets LFS_FOUND to 1 if it works.
+function(_lfs_check_compiler_option var options definitions libraries)
+ cmake_push_check_state()
+ set(CMAKE_REQUIRED_QUIET 1)
+ set(CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS} ${options})
+ set(CMAKE_REQUIRED_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} ${definitions})
+ set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_DEFINITIONS} ${libraries})
+
+ message(STATUS "Looking for LFS support using ${options} ${definitions} ${libraries}")
+ check_c_source_compiles("${_lfs_test_source}" ${var})
+ cmake_pop_check_state()
+
+ if(${var})
+ message(STATUS "Looking for LFS support using ${options} ${definitions} ${libraries} - found")
+ set(_lfs_cppflags ${_lfs_cppflags} ${definitions} PARENT_SCOPE)
+ set(_lfs_cflags ${_lfs_cflags} ${options} PARENT_SCOPE)
+ set(_lfs_ldflags ${_lfs_ldflags} ${libraries} PARENT_SCOPE)
+ set(LFS_FOUND TRUE PARENT_SCOPE)
+ else()
+ message(STATUS "Looking for LFS support using ${options} ${definitions} ${libraries} - not found")
+ endif()
+endfunction()
+
+# Check for the availability of LFS.
+# The cases handled are:
+#
+# * Native LFS
+# * Output of getconf LFS_CFLAGS; getconf LFS_LIBS; getconf LFS_LDFLAGS
+# * Preprocessor flag -D_FILE_OFFSET_BITS=64
+# * Preprocessor flag -D_LARGE_FILES
+#
+function(_lfs_check)
+ set(_lfs_cflags)
+ set(_lfs_cppflags)
+ set(_lfs_ldflags)
+ set(_lfs_libs)
+ cmake_push_check_state()
+ set(CMAKE_REQUIRED_QUIET 1)
+ message(STATUS "Looking for native LFS support")
+ check_c_source_compiles("${_lfs_test_source}" lfs_native)
+ cmake_pop_check_state()
+ if (lfs_native)
+ message(STATUS "Looking for native LFS support - found")
+ set(LFS_FOUND TRUE)
+ else()
+ message(STATUS "Looking for native LFS support - not found")
+ endif()
+
+ if (NOT LFS_FOUND)
+ # Check using getconf. If getconf fails, don't worry, the check in
+ # _lfs_check_compiler_option will fail as well.
+ execute_process(COMMAND getconf LFS_CFLAGS
+ OUTPUT_VARIABLE _lfs_cflags_raw
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_QUIET)
+ execute_process(COMMAND getconf LFS_LIBS
+ OUTPUT_VARIABLE _lfs_libs_tmp
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_QUIET)
+ execute_process(COMMAND getconf LFS_LDFLAGS
+ OUTPUT_VARIABLE _lfs_ldflags_tmp
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_QUIET)
+
+ separate_arguments(_lfs_cflags_raw)
+ separate_arguments(_lfs_ldflags_tmp)
+ separate_arguments(_lfs_libs_tmp)
+
+ # Move -D flags to the place they are supposed to be
+ foreach(flag ${_lfs_cflags_raw})
+ if (flag MATCHES "-D.*")
+ list(APPEND _lfs_cppflags_tmp ${flag})
+ else()
+ list(APPEND _lfs_cflags_tmp ${flag})
+ endif()
+ endforeach()
+
+ # Check if the flags we received (if any) produce working LFS support
+ _lfs_check_compiler_option(lfs_getconf_works
+ "${_lfs_cflags_tmp}"
+ "${_lfs_cppflags_tmp}"
+ "${_lfs_libs_tmp};${_lfs_ldflags_tmp}")
+ endif()
+
+ if(NOT LFS_FOUND) # IRIX stuff
+ _lfs_check_compiler_option(lfs_need_n32 "-n32" "" "")
+ endif()
+ if(NOT LFS_FOUND) # Linux and friends
+ _lfs_check_compiler_option(lfs_need_file_offset_bits "" "-D_FILE_OFFSET_BITS=64" "")
+ endif()
+ if(NOT LFS_FOUND) # AIX
+ _lfs_check_compiler_option(lfs_need_large_files "" "-D_LARGE_FILES=1" "")
+ endif()
+
+ set(LFS_DEFINITIONS ${_lfs_cppflags} CACHE STRING "Extra definitions for large file support")
+ set(LFS_COMPILE_OPTIONS ${_lfs_cflags} CACHE STRING "Extra definitions for large file support")
+ set(LFS_LIBRARIES ${_lfs_libs} ${_lfs_ldflags} CACHE STRING "Extra definitions for large file support")
+ set(LFS_FOUND ${LFS_FOUND} CACHE INTERNAL "Found LFS")
+endfunction()
+
+if (NOT LFS_FOUND)
+ _lfs_check()
+endif()
+
+find_package_handle_standard_args(LFS "Could not find LFS. Set LFS_DEFINITIONS, LFS_COMPILE_OPTIONS, LFS_LIBRARIES." LFS_FOUND)
diff --git a/contrib/libpcap/cmake/Modules/FindPacket.cmake b/contrib/libpcap/cmake/Modules/FindPacket.cmake
new file mode 100644
index 0000000000000..1311cdb94f152
--- /dev/null
+++ b/contrib/libpcap/cmake/Modules/FindPacket.cmake
@@ -0,0 +1,81 @@
+#
+# Copyright (C) 2017 Ali Abdulkadir <autostart.ini@gmail.com>.
+#
+# Permission is hereby granted, free of charge, to any person
+# obtaining a copy of this software and associated documentation files
+# (the "Software"), to deal in the Software without restriction,
+# including without limitation the rights to use, copy, modify, merge,
+# publish, distribute, sub-license, and/or sell copies of the Software,
+# and to permit persons to whom the Software is furnished to do so,
+# subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+#
+# FindPacket
+# ==========
+#
+# Find the Packet library and include files.
+#
+# This module defines the following variables:
+#
+# PACKET_INCLUDE_DIR - absolute path to the directory containing Packet32.h.
+#
+# PACKET_LIBRARY - relative or absolute path to the Packet library to
+# link with. An absolute path is will be used if the
+# Packet library is not located in the compiler's
+# default search path. See e.g. PACKET_DLL_DIR
+# variable below.
+
+# PACKET_FOUND - TRUE if the Packet library *and* header are found.
+#
+# Hints and Backward Compatibility
+# ================================
+#
+# To tell this module where to look, a user may set the environment variable
+# PACKET_DLL_DIR to point cmake to the *root* of a directory with include and
+# lib subdirectories for packet.dll (e.g WpdPack/npcap-sdk).
+# Alternatively, PACKET_DLL_DIR may also be set from cmake command line or GUI
+# (e.g cmake -DPACKET_DLL_DIR=/path/to/packet [...])
+#
+
+# The 64-bit Packet.lib is located under /x64
+set(64BIT_SUBDIR "")
+if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+ set(64BIT_SUBDIR "/x64")
+endif()
+
+# Find the header
+find_path(PACKET_INCLUDE_DIR Packet32.h
+ HINTS "${PACKET_DLL_DIR}" ENV PACKET_DLL_DIR
+ PATH_SUFFIXES include Include
+)
+
+# Find the library
+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.
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(PACKET
+ DEFAULT_MSG
+ PACKET_INCLUDE_DIR
+ PACKET_LIBRARY
+)
+
+mark_as_advanced(PACKET_INCLUDE_DIR PACKET_LIBRARY)
+
+set(PACKET_INCLUDE_DIRS ${PACKET_INCLUDE_DIR})
+set(PACKET_LIBRARIES ${PACKET_LIBRARY})
diff --git a/contrib/libpcap/cmake/Modules/FindPthreads-w32.cmake b/contrib/libpcap/cmake/Modules/FindPthreads-w32.cmake
new file mode 100644
index 0000000000000..ba2a78c2e4049
--- /dev/null
+++ b/contrib/libpcap/cmake/Modules/FindPthreads-w32.cmake
@@ -0,0 +1,152 @@
+# ==============================================================================
+# This is a heavily modified version of FindPthreads.cmake for the pcap project.
+# It's meant to find Pthreads-w32, an implementation of the
+# Threads component of the POSIX 1003.1c 1995 Standard (or later)
+# for Microsoft's WIndows.
+#
+# Apart from this notice, this module "enjoys" the following modifications:
+#
+# - changed its name to FindPthreads-w32.cmake to not conflict with FindThreads.cmake
+#
+# - users may be able to use the environment variable PTHREADS_ROOT to point
+# cmake to the *root* of their Pthreads-w32 installation.
+# Alternatively, PTHREADS_ROOT may also be set from cmake command line or GUI
+# (-DPTHREADS_ROOT=/path/to/Pthreads-w32)
+# Two other variables that can be defined in a similar fashion are
+# PTHREAD_INCLUDE_PATH and PTHREAD_LIBRARY_PATH.
+#
+# - added some additional status/error messages
+#
+# - changed formating (uppercase to lowercare + indentation)
+#
+# - removed some stuff
+#
+# - when searching for Pthreads-win32 libraries, the directory structure of the
+# pre-build binaries folder found in the pthreads-win32 CVS code repository is
+# considered (e.i /Pre-built.2/lib/x64 /Pre-built.2/lib/x86)
+#
+# Send suggestion, patches, gifts and praises to pcap's developers.
+# ==============================================================================
+#
+# Find the Pthreads library
+# This module searches for the Pthreads-win32 library (including the
+# pthreads-win32 port).
+#
+# This module defines these variables:
+#
+# PTHREADS_FOUND - True if the Pthreads library was found
+# PTHREADS_LIBRARY - The location of the Pthreads library
+# PTHREADS_INCLUDE_DIR - The include directory of the Pthreads library
+# PTHREADS_DEFINITIONS - Preprocessor definitions to define (HAVE_PTHREAD_H is a fairly common one)
+#
+# This module responds to the PTHREADS_EXCEPTION_SCHEME
+# variable on Win32 to allow the user to control the
+# library linked against. The Pthreads-win32 port
+# provides the ability to link against a version of the
+# library with exception handling.
+# IT IS NOT RECOMMENDED THAT YOU CHANGE PTHREADS_EXCEPTION_SCHEME
+# TO ANYTHING OTHER THAN "C" because most POSIX thread implementations
+# do not support stack unwinding.
+#
+# PTHREADS_EXCEPTION_SCHEME
+# C = no exceptions (default)
+# (NOTE: This is the default scheme on most POSIX thread
+# implementations and what you should probably be using)
+# CE = C++ Exception Handling
+# SE = Structure Exception Handling (MSVC only)
+#
+
+#
+# Define a default exception scheme to link against
+# and validate user choice.
+#
+#
+if(NOT DEFINED PTHREADS_EXCEPTION_SCHEME)
+ # Assign default if needed
+ set(PTHREADS_EXCEPTION_SCHEME "C")
+else(NOT DEFINED PTHREADS_EXCEPTION_SCHEME)
+ # Validate
+ if(NOT PTHREADS_EXCEPTION_SCHEME STREQUAL "C" AND
+ NOT PTHREADS_EXCEPTION_SCHEME STREQUAL "CE" AND
+ NOT PTHREADS_EXCEPTION_SCHEME STREQUAL "SE")
+
+ message(FATAL_ERROR "See documentation for FindPthreads.cmake, only C, CE, and SE modes are allowed")
+
+ endif(NOT PTHREADS_EXCEPTION_SCHEME STREQUAL "C" AND
+ NOT PTHREADS_EXCEPTION_SCHEME STREQUAL "CE" AND
+ NOT PTHREADS_EXCEPTION_SCHEME STREQUAL "SE")
+
+ if(NOT MSVC AND PTHREADS_EXCEPTION_SCHEME STREQUAL "SE")
+ message(FATAL_ERROR "Structured Exception Handling is only allowed for MSVC")
+ endif(NOT MSVC AND PTHREADS_EXCEPTION_SCHEME STREQUAL "SE")
+
+endif(NOT DEFINED PTHREADS_EXCEPTION_SCHEME)
+
+if(PTHREADS_ROOT)
+ set(PTHREADS_ROOT PATHS ${PTHREADS_ROOT} NO_DEFAULT_PATH)
+else()
+ set(PTHREADS_ROOT $ENV{PTHREADS_ROOT})
+endif(PTHREADS_ROOT)
+
+#
+# Find the header file
+#
+find_path(PTHREADS_INCLUDE_DIR
+ NAMES pthread.h
+ HINTS
+ $ENV{PTHREAD_INCLUDE_PATH}
+ ${PTHREADS_ROOT}/include
+)
+
+if(PTHREADS_INCLUDE_DIR)
+ message(STATUS "Found pthread.h: ${PTHREADS_INCLUDE_DIR}")
+# else()
+# message(FATAL_ERROR "Could not find pthread.h. See README.Win32 for more information.")
+endif(PTHREADS_INCLUDE_DIR)
+
+#
+# Find the library
+#
+set(names)
+if(MSVC)
+ set(names
+ pthreadV${PTHREADS_EXCEPTION_SCHEME}2
+ libpthread
+ )
+elseif(MINGW)
+ set(names
+ pthreadG${PTHREADS_EXCEPTION_SCHEME}2
+ pthread
+ )
+endif(MSVC)
+
+if(CMAKE_SIZEOF_VOID_P EQUAL 4)
+ set(SUBDIR "/x86")
+elseif(CMAKE_SIZEOF_VOID_P EQUAL 8)
+ set(SUBDIR "/x64")
+endif()
+
+find_library(PTHREADS_LIBRARY NAMES ${names}
+ DOC "The Portable Threads Library"
+ HINTS
+ ${CMAKE_SOURCE_DIR}/lib
+ $ENV{PTHREAD_LIBRARY_PATH}
+ ${PTHREADS_ROOT}
+ C:/MinGW/lib/
+ PATH_SUFFIXES lib/${SUBDIR}
+)
+
+if(PTHREADS_LIBRARY)
+message(STATUS "Found PTHREADS library: ${PTHREADS_LIBRARY} (PTHREADS Exception Scheme: ${PTHREADS_EXCEPTION_SCHEME})")
+# else()
+# message(FATAL_ERROR "Could not find PTHREADS LIBRARY. See README.Win32 for more information.")
+endif(PTHREADS_LIBRARY)
+
+if(PTHREADS_INCLUDE_DIR AND PTHREADS_LIBRARY)
+ set(PTHREADS_DEFINITIONS -DHAVE_PTHREAD_H)
+ set(PTHREADS_INCLUDE_DIRS ${PTHREADS_INCLUDE_DIR})
+ set(PTHREADS_LIBRARIES ${PTHREADS_LIBRARY})
+ set(PTHREADS_FOUND TRUE)
+endif(PTHREADS_INCLUDE_DIR AND PTHREADS_LIBRARY)
+
+mark_as_advanced(PTHREADS_INCLUDE_DIR PTHREADS_LIBRARY)
diff --git a/contrib/libpcap/cmake/Modules/FindSNF.cmake b/contrib/libpcap/cmake/Modules/FindSNF.cmake
new file mode 100644
index 0000000000000..76dcced417fea
--- /dev/null
+++ b/contrib/libpcap/cmake/Modules/FindSNF.cmake
@@ -0,0 +1,24 @@
+#
+# Try to find the Myricom SNF library.
+#
+
+# Try to find the header
+find_path(SNF_INCLUDE_DIR snf.h /opt/snf)
+
+# Try to find the library
+find_library(SNF_LIBRARY snf /opt/snf)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(SNF
+ DEFAULT_MSG
+ SNF_INCLUDE_DIR
+ SNF_LIBRARY
+)
+
+mark_as_advanced(
+ SNF_INCLUDE_DIR
+ SNF_LIBRARY
+)
+
+set(SNF_INCLUDE_DIRS ${SNF_INCLUDE_DIR})
+set(SNF_LIBRARIES ${SNF_LIBRARY})
diff --git a/contrib/libpcap/cmake/Modules/FindTC.cmake b/contrib/libpcap/cmake/Modules/FindTC.cmake
new file mode 100644
index 0000000000000..bb24c6671aa3c
--- /dev/null
+++ b/contrib/libpcap/cmake/Modules/FindTC.cmake
@@ -0,0 +1,24 @@
+#
+# Try to find the Riverbed TurboCap library.
+#
+
+# Try to find the header
+find_path(TC_INCLUDE_DIR TcApi.h)
+
+# Try to find the library
+find_library(TC_LIBRARY TcApi)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(TC
+ DEFAULT_MSG
+ TC_INCLUDE_DIR
+ TC_LIBRARY
+)
+
+mark_as_advanced(
+ TC_INCLUDE_DIR
+ TC_LIBRARY
+)
+
+set(TC_INCLUDE_DIRS ${TC_INCLUDE_DIR})
+set(TC_LIBRARIES ${TC_LIBRARY})
diff --git a/contrib/libpcap/config/have_siocglifconf.c b/contrib/libpcap/cmake/have_siocglifconf.c
index 5a67abc192c40..5a67abc192c40 100644
--- a/contrib/libpcap/config/have_siocglifconf.c
+++ b/contrib/libpcap/cmake/have_siocglifconf.c
diff --git a/contrib/libpcap/cmake_uninstall.cmake.in b/contrib/libpcap/cmake_uninstall.cmake.in
new file mode 100644
index 0000000000000..2037e365393a1
--- /dev/null
+++ b/contrib/libpcap/cmake_uninstall.cmake.in
@@ -0,0 +1,21 @@
+if(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
+ message(FATAL_ERROR "Cannot find install manifest: @CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
+endif(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
+
+file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files)
+string(REGEX REPLACE "\n" ";" files "${files}")
+foreach(file ${files})
+ message(STATUS "Uninstalling $ENV{DESTDIR}${file}")
+ if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
+ exec_program(
+ "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
+ OUTPUT_VARIABLE rm_out
+ RETURN_VALUE rm_retval
+ )
+ if(NOT "${rm_retval}" STREQUAL 0)
+ message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}")
+ endif(NOT "${rm_retval}" STREQUAL 0)
+ else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
+ message(STATUS "File $ENV{DESTDIR}${file} does not exist.")
+ endif(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
+endforeach(file)
diff --git a/contrib/libpcap/cmakeconfig.h.in b/contrib/libpcap/cmakeconfig.h.in
new file mode 100644
index 0000000000000..6760cec768343
--- /dev/null
+++ b/contrib/libpcap/cmakeconfig.h.in
@@ -0,0 +1,366 @@
+/* cmakeconfig.h.in */
+
+/* Define to 1 if arpa/inet.h declares `ether_hostton' */
+#cmakedefine ARPA_INET_H_DECLARES_ETHER_HOSTTON 1
+
+/* Enable optimizer debugging */
+#cmakedefine BDEBUG 1
+
+/* Define to 1 if remote packet capture is to be supported */
+#cmakedefine ENABLE_REMOTE 1
+
+/* define if we have the AIX getnetbyname_r() */
+#cmakedefine HAVE_AIX_GETNETBYNAME_R 1
+
+/* define if we have the AIX getprotobyname_r() */
+#cmakedefine HAVE_AIX_GETPROTOBYNAME_R 1
+
+/* define if you have the DAG API */
+#cmakedefine HAVE_DAG_API 1
+
+/* define if you have dag_get_erf_types() */
+#cmakedefine HAVE_DAG_GET_ERF_TYPES 1
+
+/* define if you have dag_get_stream_erf_types() */
+#cmakedefine HAVE_DAG_GET_STREAM_ERF_TYPES 1
+
+/* define if you have large streams capable DAG API */
+#cmakedefine HAVE_DAG_LARGE_STREAMS_API 1
+
+/* define if you have vdag_set_device_info() */
+#cmakedefine HAVE_DAG_VDAG 1
+
+/* Define to 1 if you have the declaration of `ether_hostton' */
+#cmakedefine HAVE_DECL_ETHER_HOSTTON 1
+
+/* Define to 1 if `dl_module_id_1' is a member of `dl_hp_ppa_info_t'. */
+#cmakedefine HAVE_DL_HP_PPA_INFO_T_DL_MODULE_ID_1 1
+
+/* Define to 1 if the system has the type `dl_passive_req_t'. */
+#cmakedefine HAVE_DL_PASSIVE_REQ_T 1
+
+/* Define to 1 if you have the `ether_hostton' function. */
+#cmakedefine HAVE_ETHER_HOSTTON 1
+
+/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */
+#cmakedefine HAVE_FSEEKO 1
+
+/* Define to 1 if you have the `getspnam' function. */
+#cmakedefine HAVE_GETSPNAM 1
+
+/* on HP-UX 10.20 or later */
+#cmakedefine HAVE_HPUX10_20_OR_LATER 1
+
+/* on HP-UX 9.x */
+#cmakedefine HAVE_HPUX9 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#cmakedefine HAVE_INTTYPES_H 1
+
+/* if libdlpi exists */
+#cmakedefine HAVE_LIBDLPI 1
+
+/* if libnl exists */
+#cmakedefine HAVE_LIBNL 1
+
+/* if libnl exists and is version 2.x */
+#cmakedefine HAVE_LIBNL_2_x 1
+
+/* if libnl exists and is version 3.x */
+#cmakedefine HAVE_LIBNL_3_x 1
+
+/* libnl has NLE_FAILURE */
+#cmakedefine HAVE_LIBNL_NLE 1
+
+/* libnl has new-style socket api */
+#cmakedefine HAVE_LIBNL_SOCKETS 1
+
+/* Define to 1 if you have the <limits.h> header file. */
+#cmakedefine HAVE_LIMITS_H 1
+
+/* Define to 1 if you have the <linux/compiler.h> header file. */
+#cmakedefine HAVE_LINUX_COMPILER_H 1
+
+/* Define to 1 if you have the <linux/ethtool.h> header file. */
+#cmakedefine HAVE_LINUX_ETHTOOL_H 1
+
+/* define if we have the Linux getnetbyname_r() */
+#cmakedefine HAVE_LINUX_GETNETBYNAME_R 1
+
+/* define if we have the Linux getprotobyname_r() */
+#cmakedefine HAVE_LINUX_GETPROTOBYNAME_R 1
+
+/* Define to 1 if you have the <linux/if_bonding.h> header file. */
+#cmakedefine HAVE_LINUX_IF_BONDING_H 1
+
+/* Define to 1 if you have the <linux/net_tstamp.h> header file. */
+#cmakedefine HAVE_LINUX_NET_TSTAMP_H 1
+
+/* Define to 1 if you have the <linux/socket.h> header file. */
+#cmakedefine HAVE_LINUX_SOCKET_H 1
+
+/* Define to 1 if you have the <linux/sockios.h> header file. */
+#cmakedefine HAVE_LINUX_SOCKIOS_H 1
+
+/* Define to 1 if you have the <linux/usbdevice_fs.h> header file. */
+#cmakedefine HAVE_LINUX_USBDEVICE_FS_H 1
+
+/* Define to 1 if you have the <linux/wireless.h> header file. */
+#cmakedefine HAVE_LINUX_WIRELESS_H 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#cmakedefine HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the <netpacket/packet.h> header file. */
+#cmakedefine HAVE_NETPACKET_PACKET_H 1
+
+/* Define to 1 if you have the <net/bpf.h> header file. */
+#cmakedefine HAVE_NET_BPF_H 1
+
+/* Define to 1 if you have the <net/enet.h> header file. */
+#cmakedefine HAVE_NET_ENET_H 1
+
+/* Define to 1 if you have the <net/if_media.h> header file. */
+#cmakedefine HAVE_NET_IF_MEDIA_H 1
+
+/* Define to 1 if you have the <net/nit.h> header file. */
+#cmakedefine HAVE_NET_NIT_H 1
+
+/* Define to 1 if you have the <net/pfilt.h> header file. */
+#cmakedefine HAVE_NET_PFILT_H 1
+
+/* Define to 1 if you have the <net/pfvar.h> header file. */
+#cmakedefine HAVE_NET_PFVAR_H 1
+
+/* Define to 1 if you have the <net/raw.h> header file. */
+#cmakedefine HAVE_NET_RAW_H 1
+
+/* 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 */
+#cmakedefine HAVE_PACKET32 1
+
+/* define if net/pfvar.h defines PF_NAT through PF_NORDR */
+#cmakedefine HAVE_PF_NAT_THROUGH_PF_NORDR 1
+
+/* define if you have the Septel API */
+#cmakedefine HAVE_SEPTEL_API 1
+
+/* define if you have the Myricom SNF API */
+#cmakedefine HAVE_SNF_API 1
+
+/* Define to 1 if you have the `snprintf' function. */
+#cmakedefine HAVE_SNPRINTF 1
+
+/* Define to 1 if the system has the type `socklen_t'. */
+#cmakedefine HAVE_SOCKLEN_T 1
+
+/* On solaris */
+#cmakedefine HAVE_SOLARIS 1
+
+/* define if we have the Solaris/IRIX getnetbyname_r() */
+#cmakedefine HAVE_SOLARIS_IRIX_GETNETBYNAME_R 1
+
+/* define if we have the Solaris/IRIX getprotobyname_r() */
+#cmakedefine HAVE_SOLARIS_IRIX_GETPROTOBYNAME_R 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#cmakedefine HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#cmakedefine HAVE_STDLIB_H 1
+
+/* 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
+
+/* Define to 1 if you have the <strings.h> header file. */
+#cmakedefine HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#cmakedefine HAVE_STRING_H 1
+
+/* Define to 1 if you have the `strlcat' function. */
+#cmakedefine HAVE_STRLCAT 1
+
+/* Define to 1 if you have the `strlcpy' function. */
+#cmakedefine HAVE_STRLCPY 1
+
+/* Define to 1 if you have the `strtok_r' function. */
+#cmakedefine HAVE_STRTOK_R 1
+
+/* Define to 1 if the system has the type `struct BPF_TIMEVAL'. */
+#cmakedefine HAVE_STRUCT_BPF_TIMEVAL 1
+
+/* Define to 1 if the system has the type `struct ether_addr'. */
+#cmakedefine HAVE_STRUCT_ETHER_ADDR 1
+
+/* Define to 1 if `msg_control' is a member of `struct msghdr'. */
+#cmakedefine HAVE_STRUCT_MSGHDR_MSG_CONTROL 1
+
+/* Define to 1 if `msg_flags' is a member of `struct msghdr'. */
+#cmakedefine HAVE_STRUCT_MSGHDR_MSG_FLAGS 1
+
+/* Define to 1 if `hci_channel' is a member of `struct sockaddr_hci'. */
+#cmakedefine HAVE_STRUCT_SOCKADDR_HCI_HCI_CHANNEL 1
+
+/* Define to 1 if `sa_len' is a member of `struct sockaddr'. */
+#cmakedefine HAVE_STRUCT_SOCKADDR_SA_LEN 1
+
+/* Define to 1 if the system has the type `struct sockaddr_storage'. */
+#cmakedefine HAVE_STRUCT_SOCKADDR_STORAGE 1
+
+/* Define to 1 if `tp_vlan_tci' is a member of `struct tpacket_auxdata'. */
+#cmakedefine HAVE_STRUCT_TPACKET_AUXDATA_TP_VLAN_TCI 1
+
+/* Define to 1 if the system has the type `struct tpacket_stats'. */
+#cmakedefine HAVE_STRUCT_TPACKET_STATS 1
+
+/* Define to 1 if `bRequestType' is a member of `struct
+ usbdevfs_ctrltransfer'. */
+#cmakedefine HAVE_STRUCT_USBDEVFS_CTRLTRANSFER_BREQUESTTYPE 1
+
+/* Define to 1 if you have the <sys/bufmod.h> header file. */
+#cmakedefine HAVE_SYS_BUFMOD_H 1
+
+/* Define to 1 if you have the <sys/dlpi_ext.h> header file. */
+#cmakedefine HAVE_SYS_DLPI_EXT_H 1
+
+/* Define to 1 if you have the <sys/dlpi.h> header file. */
+#cmakedefine HAVE_SYS_DLPI_H 1
+
+/* Define to 1 if you have the <sys/ioccom.h> header file. */
+#cmakedefine HAVE_SYS_IOCCOM_H 1
+
+/* Define to 1 if you have the <sys/net/nit.h> header file. */
+#cmakedefine HAVE_SYS_NET_NIT_H 1
+
+/* Define to 1 if you have the <sys/sockio.h> header file. */
+#cmakedefine HAVE_SYS_SOCKIO_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#cmakedefine HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#cmakedefine HAVE_SYS_TYPES_H 1
+
+/* define if you have the TurboCap API */
+#cmakedefine HAVE_TC_API 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#cmakedefine HAVE_UNISTD_H 1
+
+/* Define to 1 if you have the `vsnprintf' function. */
+#cmakedefine HAVE_VSNPRINTF 1
+
+/* Define to 1 if you have the `PacketIsLoopbackAdapter' function. */
+#cmakedefine HAVE_PACKET_IS_LOOPBACK_ADAPTER 1
+
+/* IPv6 */
+#cmakedefine INET6 1
+
+/* if unaligned access fails */
+#cmakedefine LBL_ALIGN 1
+
+/* path for device for USB sniffing */
+#cmakedefine LINUX_USB_MON_DEV "@LINUX_USB_MON_DEV@"
+
+/* Define to 1 if netinet/ether.h declares `ether_hostton' */
+#cmakedefine NETINET_ETHER_H_DECLARES_ETHER_HOSTTON 1
+
+/* Define to 1 if netinet/if_ether.h declares `ether_hostton' */
+#cmakedefine NETINET_IF_ETHER_H_DECLARES_ETHER_HOSTTON 1
+
+/* Define to 1 if net/ethernet.h declares `ether_hostton' */
+#cmakedefine NET_ETHERNET_H_DECLARES_ETHER_HOSTTON 1
+
+/* do not use protochain */
+#cmakedefine NO_PROTOCHAIN 1
+
+/* Define to the address where bug reports for this package should be sent. */
+#cmakedefine PACKAGE_BUGREPORT 1
+
+/* Define to the DLL-preferred version string of of this package. */
+#cmakedefine PACKAGE_VERSION_DLL @PACKAGE_VERSION_DLL@
+
+/* Define to the full name of this package. */
+#cmakedefine PACKAGE_NAME "@PACKAGE_NAME@"
+
+/* Define to the full name and version of this package. */
+#cmakedefine PACKAGE_STRING "@PACKAGE_STRING@"
+
+/* Define to the one symbol short name of this package. */
+#cmakedefine PACKAGE_TARNAME 1
+
+/* Define to the home page for this package. */
+#cmakedefine PACKAGE_URL 1
+
+/* Define to the version of this package. */
+#cmakedefine PACKAGE_VERSION "@PACKAGE_VERSION@"
+
+/* target host supports Bluetooth sniffing */
+#cmakedefine PCAP_SUPPORT_BT 1
+
+/* target host supports Bluetooth Monitor */
+#cmakedefine PCAP_SUPPORT_BT_MONITOR 1
+
+/* support D-Bus sniffing */
+#cmakedefine PCAP_SUPPORT_DBUS 1
+
+/* target host supports netfilter sniffing */
+#cmakedefine PCAP_SUPPORT_NETFILTER 1
+
+/* target host supports netmap */
+#cmakedefine PCAP_SUPPORT_NETMAP 1
+
+/* use packet ring capture support on Linux if available */
+#cmakedefine PCAP_SUPPORT_PACKET_RING 1
+
+/* target host supports RDMA sniffing */
+#cmakedefine PCAP_SUPPORT_RDMASNIFF 1
+
+/* target host supports USB sniffing */
+#cmakedefine PCAP_SUPPORT_USB 1
+
+/* include ACN support */
+#cmakedefine SITA 1
+
+/* Define to 1 if you have the ANSI C header files. */
+#cmakedefine STDC_HEADERS 1
+
+/* Define to 1 if strings.h declares `ffs' */
+#cmakedefine STRINGS_H_DECLARES_FFS 1
+
+/* Define to 1 if sys/ethernet.h declares `ether_hostton' */
+#cmakedefine SYS_ETHERNET_H_DECLARES_ETHER_HOSTTON 1
+
+/* Enable parser debugging */
+#cmakedefine YYDEBUG 1
+
+/* Enable large inode numbers on Mac OS X 10.5. */
+#ifndef _DARWIN_USE_64_BIT_INODE
+# define _DARWIN_USE_64_BIT_INODE 1
+#endif
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+#cmakedefine _FILE_OFFSET_BITS 1
+
+/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */
+#cmakedefine _LARGEFILE_SOURCE 1
+
+/* Define for large files, on AIX-style hosts. */
+#cmakedefine _LARGE_FILES 1
+
+/* define on AIX to get certain functions */
+#cmakedefine _SUN 1
+
+#if 0
+/* on sinix */
+#cmakedefine sinix 1
+#endif
diff --git a/contrib/libpcap/config.h.in b/contrib/libpcap/config.h.in
index e85b2a3f56175..b1a20a44131c4 100644
--- a/contrib/libpcap/config.h.in
+++ b/contrib/libpcap/config.h.in
@@ -1,10 +1,22 @@
/* config.h.in. Generated from configure.ac by autoheader. */
+/* Define to 1 if arpa/inet.h declares `ether_hostton' */
+#undef ARPA_INET_H_DECLARES_ETHER_HOSTTON
+
/* Enable optimizer debugging */
#undef BDEBUG
-/* define if you have a cloning BPF device */
-#undef HAVE_CLONING_BPF
+/* Define to 1 if remote packet capture is to be supported */
+#undef ENABLE_REMOTE
+
+/* define if we have the AIX getnetbyname_r() */
+#undef HAVE_AIX_GETNETBYNAME_R
+
+/* define if we have the AIX getprotobyname_r() */
+#undef HAVE_AIX_GETPROTOBYNAME_R
+
+/* Define to 1 if you have the <dagapi.h> header file. */
+#undef HAVE_DAGAPI_H
/* define if you have the DAG API */
#undef HAVE_DAG_API
@@ -15,40 +27,45 @@
/* define if you have dag_get_stream_erf_types() */
#undef HAVE_DAG_GET_STREAM_ERF_TYPES
-/* define if you have streams capable DAG API */
-#undef HAVE_DAG_STREAMS_API
+/* define if you have large streams capable DAG API */
+#undef HAVE_DAG_LARGE_STREAMS_API
/* define if you have vdag_set_device_info() */
#undef HAVE_DAG_VDAG
-/* Define to 1 if you have the declaration of `ether_hostton', and to 0 if you
- don't. */
+/* Define to 1 if you have the declaration of `ether_hostton' */
#undef HAVE_DECL_ETHER_HOSTTON
-/* define if you have a /dev/dlpi */
-#undef HAVE_DEV_DLPI
+/* Define to 1 if `dl_module_id_1' is a member of `dl_hp_ppa_info_t'. */
+#undef HAVE_DL_HP_PPA_INFO_T_DL_MODULE_ID_1
-/* if passive_req_t primitive exists */
-#undef HAVE_DLPI_PASSIVE
+/* Define to 1 if the system has the type `dl_passive_req_t'. */
+#undef HAVE_DL_PASSIVE_REQ_T
/* Define to 1 if you have the `ether_hostton' function. */
#undef HAVE_ETHER_HOSTTON
+/* Define to 1 if you have the `ffs' function. */
+#undef HAVE_FFS
+
/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */
#undef HAVE_FSEEKO
+/* Define to 1 if you have the `getspnam' function. */
+#undef HAVE_GETSPNAM
+
/* on HP-UX 10.20 or later */
#undef HAVE_HPUX10_20_OR_LATER
/* on HP-UX 9.x */
#undef HAVE_HPUX9
-/* if ppa_info_t_dl_module_id exists */
-#undef HAVE_HP_PPA_INFO_T_DL_MODULE_ID_1
-
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
+/* Define to 1 if you have the `dag' library (-ldag). */
+#undef HAVE_LIBDAG
+
/* if libdlpi exists */
#undef HAVE_LIBDLPI
@@ -76,24 +93,24 @@
/* Define to 1 if you have the <linux/ethtool.h> header file. */
#undef HAVE_LINUX_ETHTOOL_H
+/* define if we have the Linux getnetbyname_r() */
+#undef HAVE_LINUX_GETNETBYNAME_R
+
+/* define if we have the Linux getprotobyname_r() */
+#undef HAVE_LINUX_GETPROTOBYNAME_R
+
/* Define to 1 if you have the <linux/if_bonding.h> header file. */
#undef HAVE_LINUX_IF_BONDING_H
-/* Define to 1 if you have the <linux/if_packet.h> header file. */
-#undef HAVE_LINUX_IF_PACKET_H
-
/* Define to 1 if you have the <linux/net_tstamp.h> header file. */
#undef HAVE_LINUX_NET_TSTAMP_H
+/* Define to 1 if you have the <linux/socket.h> header file. */
+#undef HAVE_LINUX_SOCKET_H
+
/* Define to 1 if you have the <linux/sockios.h> header file. */
#undef HAVE_LINUX_SOCKIOS_H
-/* if tp_vlan_tci exists */
-#undef HAVE_LINUX_TPACKET_AUXDATA_TP_VLAN_TCI
-
-/* Define to 1 if you have the <linux/types.h> header file. */
-#undef HAVE_LINUX_TYPES_H
-
/* Define to 1 if you have the <linux/usbdevice_fs.h> header file. */
#undef HAVE_LINUX_USBDEVICE_FS_H
@@ -103,24 +120,30 @@
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
-/* Define to 1 if you have the <netinet/ether.h> header file. */
-#undef HAVE_NETINET_ETHER_H
-
-/* Define to 1 if you have the <netinet/if_ether.h> header file. */
-#undef HAVE_NETINET_IF_ETHER_H
-
-/* Define to 1 if you have the <netpacket/if_packet.h> header file. */
-#undef HAVE_NETPACKET_IF_PACKET_H
-
/* Define to 1 if you have the <netpacket/packet.h> header file. */
#undef HAVE_NETPACKET_PACKET_H
+/* Define to 1 if you have the <net/bpf.h> header file. */
+#undef HAVE_NET_BPF_H
+
+/* Define to 1 if you have the <net/enet.h> header file. */
+#undef HAVE_NET_ENET_H
+
/* Define to 1 if you have the <net/if_media.h> header file. */
#undef HAVE_NET_IF_MEDIA_H
+/* Define to 1 if you have the <net/nit.h> header file. */
+#undef HAVE_NET_NIT_H
+
+/* Define to 1 if you have the <net/pfilt.h> header file. */
+#undef HAVE_NET_PFILT_H
+
/* Define to 1 if you have the <net/pfvar.h> header file. */
#undef HAVE_NET_PFVAR_H
+/* Define to 1 if you have the <net/raw.h> header file. */
+#undef HAVE_NET_RAW_H
+
/* if there's an os_proto.h for this platform, to use additional prototypes */
#undef HAVE_OS_PROTO_H
@@ -136,18 +159,18 @@
/* Define to 1 if you have the `snprintf' function. */
#undef HAVE_SNPRINTF
-/* if struct sockaddr has the sa_len member */
-#undef HAVE_SOCKADDR_SA_LEN
-
-/* if struct sockaddr_storage exists */
-#undef HAVE_SOCKADDR_STORAGE
-
-/* define if socklen_t is defined */
+/* Define to 1 if the system has the type `socklen_t'. */
#undef HAVE_SOCKLEN_T
/* On solaris */
#undef HAVE_SOLARIS
+/* define if we have the Solaris/IRIX getnetbyname_r() */
+#undef HAVE_SOLARIS_IRIX_GETNETBYNAME_R
+
+/* define if we have the Solaris/IRIX getprotobyname_r() */
+#undef HAVE_SOLARIS_IRIX_GETPROTOBYNAME_R
+
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
@@ -157,12 +180,21 @@
/* 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
+
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
+/* Define to 1 if you have the `strlcat' function. */
+#undef HAVE_STRLCAT
+
/* Define to 1 if you have the `strlcpy' function. */
#undef HAVE_STRLCPY
@@ -175,8 +207,30 @@
/* Define to 1 if the system has the type `struct ether_addr'. */
#undef HAVE_STRUCT_ETHER_ADDR
-/* Define to 1 if you have the <sys/bitypes.h> header file. */
-#undef HAVE_SYS_BITYPES_H
+/* Define to 1 if `msg_control' is a member of `struct msghdr'. */
+#undef HAVE_STRUCT_MSGHDR_MSG_CONTROL
+
+/* Define to 1 if `msg_flags' is a member of `struct msghdr'. */
+#undef HAVE_STRUCT_MSGHDR_MSG_FLAGS
+
+/* Define to 1 if `hci_channel' is a member of `struct sockaddr_hci'. */
+#undef HAVE_STRUCT_SOCKADDR_HCI_HCI_CHANNEL
+
+/* Define to 1 if `sa_len' is a member of `struct sockaddr'. */
+#undef HAVE_STRUCT_SOCKADDR_SA_LEN
+
+/* Define to 1 if the system has the type `struct sockaddr_storage'. */
+#undef HAVE_STRUCT_SOCKADDR_STORAGE
+
+/* Define to 1 if `tp_vlan_tci' is a member of `struct tpacket_auxdata'. */
+#undef HAVE_STRUCT_TPACKET_AUXDATA_TP_VLAN_TCI
+
+/* Define to 1 if the system has the type `struct tpacket_stats'. */
+#undef HAVE_STRUCT_TPACKET_STATS
+
+/* Define to 1 if `bRequestType' is a member of `struct
+ usbdevfs_ctrltransfer'. */
+#undef HAVE_STRUCT_USBDEVFS_CTRLTRANSFER_BREQUESTTYPE
/* Define to 1 if you have the <sys/bufmod.h> header file. */
#undef HAVE_SYS_BUFMOD_H
@@ -184,11 +238,14 @@
/* Define to 1 if you have the <sys/dlpi_ext.h> header file. */
#undef HAVE_SYS_DLPI_EXT_H
+/* Define to 1 if you have the <sys/dlpi.h> header file. */
+#undef HAVE_SYS_DLPI_H
+
/* Define to 1 if you have the <sys/ioccom.h> header file. */
#undef HAVE_SYS_IOCCOM_H
-/* Define to 1 if you have the <sys/select.h> header file. */
-#undef HAVE_SYS_SELECT_H
+/* Define to 1 if you have the <sys/net/nit.h> header file. */
+#undef HAVE_SYS_NET_NIT_H
/* Define to 1 if you have the <sys/sockio.h> header file. */
#undef HAVE_SYS_SOCKIO_H
@@ -202,24 +259,12 @@
/* define if you have the TurboCap API */
#undef HAVE_TC_API
-/* if if_packet.h has tpacket_stats defined */
-#undef HAVE_TPACKET_STATS
-
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
-/* if struct usbdevfs_ctrltransfer has bRequestType */
-#undef HAVE_USBDEVFS_CTRLTRANSFER_BREQUESTTYPE
-
/* Define to 1 if you have the `vsnprintf' function. */
#undef HAVE_VSNPRINTF
-/* define if the system supports zerocopy BPF */
-#undef HAVE_ZEROCOPY_BPF
-
-/* define if your compiler has __attribute__ */
-#undef HAVE___ATTRIBUTE__
-
/* IPv6 */
#undef INET6
@@ -235,6 +280,9 @@
/* Define to 1 if netinet/if_ether.h declares `ether_hostton' */
#undef NETINET_IF_ETHER_H_DECLARES_ETHER_HOSTTON
+/* Define to 1 if net/ethernet.h declares `ether_hostton' */
+#undef NET_ETHERNET_H_DECLARES_ETHER_HOSTTON
+
/* do not use protochain */
#undef NO_PROTOCHAIN
@@ -256,9 +304,6 @@
/* Define to the version of this package. */
#undef PACKAGE_VERSION
-/* /dev/dlpi directory */
-#undef PCAP_DEV_PREFIX
-
/* target host supports Bluetooth sniffing */
#undef PCAP_SUPPORT_BT
@@ -271,21 +316,30 @@
/* target host supports netfilter sniffing */
#undef PCAP_SUPPORT_NETFILTER
-/* use Linux packet ring capture if available */
+/* target host supports netmap */
+#undef PCAP_SUPPORT_NETMAP
+
+/* use packet ring capture support on Linux if available */
#undef PCAP_SUPPORT_PACKET_RING
+/* target host supports RDMA sniffing */
+#undef PCAP_SUPPORT_RDMASNIFF
+
/* target host supports USB sniffing */
#undef PCAP_SUPPORT_USB
/* include ACN support */
#undef SITA
-/* if struct sockaddr_hci has hci_channel member */
-#undef SOCKADDR_HCI_HAS_HCI_CHANNEL
-
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
+/* Define to 1 if strings.h declares `ffs' */
+#undef STRINGS_H_DECLARES_FFS
+
+/* Define to 1 if sys/ethernet.h declares `ether_hostton' */
+#undef SYS_ETHERNET_H_DECLARES_ETHER_HOSTTON
+
/* Enable parser debugging */
#undef YYDEBUG
@@ -310,38 +364,11 @@
/* define on AIX to get certain functions */
#undef _SUN
-/* define if your compiler allows __attribute__((format)) without a warning */
-#undef __ATTRIBUTE___FORMAT_OK
-
/* to handle Ultrix compilers that don't support const in prototypes */
#undef const
/* Define as token for inline if inlining supported */
#undef inline
-/* Define to `short' if int16_t not defined. */
-#undef int16_t
-
-/* Define to `int' if int32_t not defined. */
-#undef int32_t
-
-/* Define to `long long' if int64_t not defined. */
-#undef int64_t
-
-/* Define to `signed char' if int8_t not defined. */
-#undef int8_t
-
/* on sinix */
#undef sinix
-
-/* Define to `unsigned short' if u_int16_t not defined. */
-#undef u_int16_t
-
-/* Define to `unsigned int' if u_int32_t not defined. */
-#undef u_int32_t
-
-/* Define to `unsigned long long' if u_int64_t not defined. */
-#undef u_int64_t
-
-/* Define to `unsigned char' if u_int8_t not defined. */
-#undef u_int8_t
diff --git a/contrib/libpcap/configure b/contrib/libpcap/configure
index 4c64875e3e69f..ef4bc9f2cc069 100755
--- a/contrib/libpcap/configure
+++ b/contrib/libpcap/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69.
+# Generated by GNU Autoconf 2.69 for pcap 1.9.0-PRE-GIT.
#
#
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@@ -575,12 +575,12 @@ MFLAGS=
MAKEFLAGS=
# Identity of this package.
-PACKAGE_NAME=
-PACKAGE_TARNAME=
-PACKAGE_VERSION=
-PACKAGE_STRING=
-PACKAGE_BUGREPORT=
-PACKAGE_URL=
+PACKAGE_NAME='pcap'
+PACKAGE_TARNAME='pcap'
+PACKAGE_VERSION='1.9.0-PRE-GIT'
+PACKAGE_STRING='pcap 1.9.0-PRE-GIT'
+PACKAGE_BUGREPORT=''
+PACKAGE_URL=''
ac_unique_file="pcap.c"
# Factoring default headers for most tests.
@@ -623,17 +623,26 @@ ac_subst_vars='LTLIBOBJS
INSTALL_DATA
INSTALL_SCRIPT
INSTALL_PROGRAM
-PCAP_SUPPORT_PACKET_RING
+RDMA_SRC
+PCAP_SUPPORT_RDMASNIFF
DBUS_SRC
PCAP_SUPPORT_DBUS
PKGCONFIG
BT_MONITOR_SRC
BT_SRC
PCAP_SUPPORT_BT
+NETMAP_SRC
+PCAP_SUPPORT_NETMAP
NETFILTER_SRC
PCAP_SUPPORT_NETFILTER
USB_SRC
PCAP_SUPPORT_USB
+EXTRA_NETWORK_LIBS
+RPCAPD_LIBS
+INSTALL_RPCAPD
+BUILD_RPCAPD
+PTHREAD_LIBS
+MAN_ADMIN_COMMANDS
MAN_MISC_INFO
MAN_FILE_FORMATS
DYEXT
@@ -645,6 +654,7 @@ V_RPATH_OPT
V_SONAME_OPT
V_SHLIB_OPT
V_SHLIB_CMD
+V_SHLIB_CCOPT
V_PCAP
V_LEX
V_INCLS
@@ -661,8 +671,8 @@ YACC
LEXLIB
LEX_OUTPUT_ROOT
LEX
-HAVE_LINUX_TPACKET_AUXDATA
-VALGRINDTEST
+PCAP_SUPPORT_PACKET_RING
+VALGRINDTEST_SRC
LIBOBJS
EGREP
GREP
@@ -734,9 +744,8 @@ enable_protochain
with_sita
with_pcap
with_libnl
+enable_packet_ring
enable_ipv6
-enable_optimizer_dbg
-enable_yydebug
with_dag
with_dag_includes
with_dag_libraries
@@ -745,12 +754,16 @@ with_snf
with_snf_includes
with_snf_libraries
with_turbocap
+enable_remote
+enable_optimizer_dbg
+enable_yydebug
enable_universal
enable_shared
enable_usb
+enable_netmap
enable_bluetooth
enable_dbus
-enable_packet_ring
+enable_rdma
'
ac_precious_vars='build_alias
host_alias
@@ -803,7 +816,7 @@ sharedstatedir='${prefix}/com'
localstatedir='${prefix}/var'
includedir='${prefix}/include'
oldincludedir='/usr/include'
-docdir='${datarootdir}/doc/${PACKAGE}'
+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
infodir='${datarootdir}/info'
htmldir='${docdir}'
dvidir='${docdir}'
@@ -1303,7 +1316,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures this package to adapt to many kinds of systems.
+\`configure' configures pcap 1.9.0-PRE-GIT to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1351,7 +1364,7 @@ Fine tuning of the installation directories:
--infodir=DIR info documentation [DATAROOTDIR/info]
--localedir=DIR locale-dependent data [DATAROOTDIR/locale]
--mandir=DIR man documentation [DATAROOTDIR/man]
- --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE]
+ --docdir=DIR documentation root [DATAROOTDIR/doc/pcap]
--htmldir=DIR html documentation [DOCDIR]
--dvidir=DIR dvi documentation [DOCDIR]
--pdfdir=DIR pdf documentation [DOCDIR]
@@ -1368,7 +1381,9 @@ _ACEOF
fi
if test -n "$ac_init_help"; then
-
+ case $ac_init_help in
+ short | recursive ) echo "Configuration of pcap 1.9.0-PRE-GIT:";;
+ esac
cat <<\_ACEOF
Optional Features:
@@ -1377,20 +1392,25 @@ Optional Features:
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
--disable-largefile omit support for large files
--disable-protochain disable \"protochain\" insn
- --enable-ipv6 build IPv6-capable version [default=yes, if
- getaddrinfo available]
+ --enable-packet-ring enable packet ring support on Linux [default=yes]
+ --enable-ipv6 build IPv6-capable version [default=yes]
+ --enable-remote enable remote packet capture [default=no]
+ --disable-remote disable remote packet capture
--enable-optimizer-dbg build optimizer debugging code
--enable-yydebug build parser debugging code
- --disable-universal don't build universal on OS X
+ --disable-universal don't build universal on macOS
--enable-shared build shared libraries [default=yes, if support
available]
- --enable-usb enable nusb support [default=yes, if support
+ --enable-usb enable USB capture support [default=yes, if support
+ available]
+ --enable-netmap enable netmap support [default=yes, if support
available]
--enable-bluetooth enable Bluetooth support [default=yes, if support
available]
--enable-dbus enable D-Bus capture support [default=yes, if
support available]
- --enable-packet-ring enable Linux packet ring support [default=yes]
+ --enable-rdma enable RDMA capture support [default=yes, if support
+ available]
Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
@@ -1500,7 +1520,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-configure
+pcap configure 1.9.0-PRE-GIT
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1552,6 +1572,52 @@ fi
} # ac_fn_c_try_compile
+# ac_fn_c_try_link LINENO
+# -----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_link ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext conftest$ac_exeext
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ test -x conftest$ac_exeext
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+ # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+ # interfere with the next link command; also delete a directory that is
+ # left behind by Apple's compiler. We do this before executing the actions.
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_link
+
# ac_fn_c_try_cpp LINENO
# ----------------------
# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
@@ -1749,106 +1815,6 @@ $as_echo "$ac_res" >&6; }
} # ac_fn_c_check_header_compile
-# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
-# -------------------------------------------
-# Tests whether TYPE exists after having included INCLUDES, setting cache
-# variable VAR accordingly.
-ac_fn_c_check_type ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if eval \${$3+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- eval "$3=no"
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-$4
-int
-main ()
-{
-if (sizeof ($2))
- return 0;
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-$4
-int
-main ()
-{
-if (sizeof (($2)))
- return 0;
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-
-else
- eval "$3=yes"
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-eval ac_res=\$$3
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
- eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-
-} # ac_fn_c_check_type
-
-# ac_fn_c_try_link LINENO
-# -----------------------
-# Try to link conftest.$ac_ext, and return whether this succeeded.
-ac_fn_c_try_link ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- rm -f conftest.$ac_objext conftest$ac_exeext
- if { { ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_link") 2>conftest.err
- ac_status=$?
- if test -s conftest.err; then
- grep -v '^ *+' conftest.err >conftest.er1
- cat conftest.er1 >&5
- mv -f conftest.er1 conftest.err
- fi
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext && {
- test "$cross_compiling" = yes ||
- test -x conftest$ac_exeext
- }; then :
- ac_retval=0
-else
- $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_retval=1
-fi
- # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
- # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
- # interfere with the next link command; also delete a directory that is
- # left behind by Apple's compiler. We do this before executing the actions.
- rm -rf conftest.dSYM conftest_ipa8_conftest.oo
- eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
- as_fn_set_status $ac_retval
-
-} # ac_fn_c_try_link
-
# ac_fn_c_check_func LINENO FUNC VAR
# ----------------------------------
# Tests whether FUNC exists, setting the cache variable VAR accordingly
@@ -1961,11 +1927,122 @@ $as_echo "$ac_res" >&6; }
eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
} # ac_fn_c_check_decl
+
+# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
+# -------------------------------------------
+# Tests whether TYPE exists after having included INCLUDES, setting cache
+# variable VAR accordingly.
+ac_fn_c_check_type ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ eval "$3=no"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+if (sizeof ($2))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+if (sizeof (($2)))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+ eval "$3=yes"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_type
+
+# ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES
+# ----------------------------------------------------
+# Tries to find if the field MEMBER exists in type AGGR, after including
+# INCLUDES, setting cache variable VAR accordingly.
+ac_fn_c_check_member ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5
+$as_echo_n "checking for $2.$3... " >&6; }
+if eval \${$4+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$5
+int
+main ()
+{
+static $2 ac_aggr;
+if (ac_aggr.$3)
+return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$4=yes"
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$5
+int
+main ()
+{
+static $2 ac_aggr;
+if (sizeof ac_aggr.$3)
+return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$4=yes"
+else
+ eval "$4=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$4
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_member
cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by $as_me, which was
+It was created by pcap $as_me 1.9.0-PRE-GIT, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -2314,6 +2391,8 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
ac_aux_dir=
for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
if test -f "$ac_dir/install-sh"; then
@@ -2527,6 +2606,10 @@ fi
export CC
fi
+#
+# Try to enable as many C99 features as we can.
+# At minimum, we want C++/C99-style // comments.
+#
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -3316,6 +3399,183 @@ ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C99" >&5
+$as_echo_n "checking for $CC option to accept ISO C99... " >&6; }
+if ${ac_cv_prog_cc_c99+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_prog_cc_c99=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <wchar.h>
+#include <stdio.h>
+
+// Check varargs macros. These examples are taken from C99 6.10.3.5.
+#define debug(...) fprintf (stderr, __VA_ARGS__)
+#define showlist(...) puts (#__VA_ARGS__)
+#define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__))
+static void
+test_varargs_macros (void)
+{
+ int x = 1234;
+ int y = 5678;
+ debug ("Flag");
+ debug ("X = %d\n", x);
+ showlist (The first, second, and third items.);
+ report (x>y, "x is %d but y is %d", x, y);
+}
+
+// Check long long types.
+#define BIG64 18446744073709551615ull
+#define BIG32 4294967295ul
+#define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0)
+#if !BIG_OK
+ your preprocessor is broken;
+#endif
+#if BIG_OK
+#else
+ your preprocessor is broken;
+#endif
+static long long int bignum = -9223372036854775807LL;
+static unsigned long long int ubignum = BIG64;
+
+struct incomplete_array
+{
+ int datasize;
+ double data[];
+};
+
+struct named_init {
+ int number;
+ const wchar_t *name;
+ double average;
+};
+
+typedef const char *ccp;
+
+static inline int
+test_restrict (ccp restrict text)
+{
+ // See if C++-style comments work.
+ // Iterate through items via the restricted pointer.
+ // Also check for declarations in for loops.
+ for (unsigned int i = 0; *(text+i) != '\0'; ++i)
+ continue;
+ return 0;
+}
+
+// Check varargs and va_copy.
+static void
+test_varargs (const char *format, ...)
+{
+ va_list args;
+ va_start (args, format);
+ va_list args_copy;
+ va_copy (args_copy, args);
+
+ const char *str;
+ int number;
+ float fnumber;
+
+ while (*format)
+ {
+ switch (*format++)
+ {
+ case 's': // string
+ str = va_arg (args_copy, const char *);
+ break;
+ case 'd': // int
+ number = va_arg (args_copy, int);
+ break;
+ case 'f': // float
+ fnumber = va_arg (args_copy, double);
+ break;
+ default:
+ break;
+ }
+ }
+ va_end (args_copy);
+ va_end (args);
+}
+
+int
+main ()
+{
+
+ // Check bool.
+ _Bool success = false;
+
+ // Check restrict.
+ if (test_restrict ("String literal") == 0)
+ success = true;
+ char *restrict newvar = "Another string";
+
+ // Check varargs.
+ test_varargs ("s, d' f .", "string", 65, 34.234);
+ test_varargs_macros ();
+
+ // Check flexible array members.
+ struct incomplete_array *ia =
+ malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10));
+ ia->datasize = 10;
+ for (int i = 0; i < ia->datasize; ++i)
+ ia->data[i] = i * 1.234;
+
+ // Check named initializers.
+ struct named_init ni = {
+ .number = 34,
+ .name = L"Test wide string",
+ .average = 543.34343,
+ };
+
+ ni.number = 58;
+
+ int dynamic_array[ni.number];
+ dynamic_array[ni.number - 1] = 543;
+
+ // work around unused variable warnings
+ return (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == 'x'
+ || dynamic_array[ni.number - 1] != 543);
+
+ ;
+ return 0;
+}
+_ACEOF
+for ac_arg in '' -std=gnu99 -std=c99 -c99 -AC99 -D_STDC_C99= -qlanglvl=extc99
+do
+ CC="$ac_save_CC $ac_arg"
+ if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_c99=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+ test "x$ac_cv_prog_cc_c99" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c99" in
+ x)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+ xno)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+ *)
+ CC="$CC $ac_cv_prog_cc_c99"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5
+$as_echo "$ac_cv_prog_cc_c99" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c99" != xno; then :
+
+fi
+
+
@@ -3605,7 +3865,7 @@ $as_echo "#define const /**/" >>confdefs.h
# On platforms where we build a shared library:
#
# add options to generate position-independent code,
- # if necessary (it's the default in AIX and Darwin/OS X);
+ # if necessary (it's the default in AIX and Darwin/macOS);
#
# define option to set the soname of the shared library,
# if the OS supports that;
@@ -3643,13 +3903,13 @@ $as_echo "#define const /**/" >>confdefs.h
esac
;;
esac
- V_CCOPT="$V_CCOPT $PIC_OPT"
+ V_SHLIB_CCOPT="$V_SHLIB_CCOPT $PIC_OPT"
V_SONAME_OPT="-Wl,-soname,"
V_RPATH_OPT="-Wl,-rpath,"
;;
hpux*)
- V_CCOPT="$V_CCOPT -fpic"
+ V_SHLIB_CCOPT="$V_SHLIB_CCOPT -fpic"
#
# XXX - this assumes GCC is using the HP linker,
# rather than the GNU linker, and that the "+h"
@@ -3665,7 +3925,7 @@ $as_echo "#define const /**/" >>confdefs.h
;;
solaris*)
- V_CCOPT="$V_CCOPT -fpic"
+ V_SHLIB_CCOPT="$V_SHLIB_CCOPT -fpic"
#
# XXX - this assumes GCC is using the Sun linker,
# rather than the GNU linker.
@@ -3680,7 +3940,7 @@ $as_echo "#define const /**/" >>confdefs.h
# where we build a shared library:
#
# add options to generate position-independent code,
- # if necessary (it's the default in Darwin/OS X);
+ # if necessary (it's the default in Darwin/macOS);
#
# if we generate ".so" shared libraries, define the
# appropriate options for building the shared library;
@@ -3706,7 +3966,7 @@ $as_echo "#define const /**/" >>confdefs.h
#
# "cc" is GCC.
#
- V_CCOPT="$V_CCOPT -fpic"
+ V_SHLIB_CCOPT="$V_SHLIB_CCOPT -fpic"
V_SHLIB_CMD="\$(CC)"
V_SHLIB_OPT="-shared"
V_SONAME_OPT="-Wl,-soname,"
@@ -3714,7 +3974,7 @@ $as_echo "#define const /**/" >>confdefs.h
;;
hpux*)
- V_CCOPT="$V_CCOPT +z"
+ V_SHLIB_CCOPT="$V_SHLIB_CCOPT +z"
V_SHLIB_CMD="\$(LD)"
V_SHLIB_OPT="-b"
V_SONAME_OPT="+h "
@@ -3737,7 +3997,7 @@ $as_echo "#define const /**/" >>confdefs.h
;;
solaris*)
- V_CCOPT="$V_CCOPT -Kpic"
+ V_SHLIB_CCOPT="$V_SHLIB_CCOPT -Kpic"
V_SHLIB_CMD="\$(CC)"
V_SHLIB_OPT="-G"
V_SONAME_OPT="-h "
@@ -3809,140 +4069,277 @@ cat >>confdefs.h <<_ACEOF
_ACEOF
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __attribute__" >&5
-$as_echo_n "checking for __attribute__... " >&6; }
-if ${ac_cv___attribute__+:} false; then :
+#
+# Try to arrange for large file support.
+#
+# Check whether --enable-largefile was given.
+if test "${enable_largefile+set}" = set; then :
+ enableval=$enable_largefile;
+fi
+
+if test "$enable_largefile" != no; then
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for special C compiler options needed for large files" >&5
+$as_echo_n "checking for special C compiler options needed for large files... " >&6; }
+if ${ac_cv_sys_largefile_CC+:} false; then :
$as_echo_n "(cached) " >&6
else
-
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ ac_cv_sys_largefile_CC=no
+ if test "$GCC" != yes; then
+ ac_save_CC=$CC
+ while :; do
+ # IRIX 6.2 and later do not support large files by default,
+ # so use the C compiler's -n32 option if that helps.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-
-
-#include <stdlib.h>
-
-static void foo(void) __attribute__ ((noreturn));
-
-static void
-foo(void)
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
+int
+main ()
{
- exit(1);
+
+ ;
+ return 0;
}
+_ACEOF
+ if ac_fn_c_try_compile "$LINENO"; then :
+ break
+fi
+rm -f core conftest.err conftest.$ac_objext
+ CC="$CC -n32"
+ if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_sys_largefile_CC=' -n32'; break
+fi
+rm -f core conftest.err conftest.$ac_objext
+ break
+ done
+ CC=$ac_save_CC
+ rm -f conftest.$ac_ext
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_CC" >&5
+$as_echo "$ac_cv_sys_largefile_CC" >&6; }
+ if test "$ac_cv_sys_largefile_CC" != no; then
+ CC=$CC$ac_cv_sys_largefile_CC
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS value needed for large files" >&5
+$as_echo_n "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; }
+if ${ac_cv_sys_file_offset_bits+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ while :; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
int
-main(int argc, char **argv)
+main ()
{
- foo();
-}
+ ;
+ return 0;
+}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv___attribute__=yes
-else
- ac_cv___attribute__=no
+ ac_cv_sys_file_offset_bits=no; break
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-
-if test "$ac_cv___attribute__" = "yes"; then
-
-$as_echo "#define HAVE___ATTRIBUTE__ 1" >>confdefs.h
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#define _FILE_OFFSET_BITS 64
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
+int
+main ()
+{
-else
- #
- # We can't use __attribute__, so we can't use __attribute__((unused)),
- # so we define _U_ to an empty string.
- #
- V_DEFS="$V_DEFS -D_U_=\"\""
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_sys_file_offset_bits=64; break
fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv___attribute__" >&5
-$as_echo "$ac_cv___attribute__" >&6; }
-
-if test "$ac_cv___attribute__" = "yes"; then
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether __attribute__((unused)) can be used without warnings" >&5
-$as_echo_n "checking whether __attribute__((unused)) can be used without warnings... " >&6; }
-if ${ac_cv___attribute___unused+:} false; then :
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_cv_sys_file_offset_bits=unknown
+ break
+done
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_file_offset_bits" >&5
+$as_echo "$ac_cv_sys_file_offset_bits" >&6; }
+case $ac_cv_sys_file_offset_bits in #(
+ no | unknown) ;;
+ *)
+cat >>confdefs.h <<_ACEOF
+#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits
+_ACEOF
+;;
+esac
+rm -rf conftest*
+ if test $ac_cv_sys_file_offset_bits = unknown; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGE_FILES value needed for large files" >&5
+$as_echo_n "checking for _LARGE_FILES value needed for large files... " >&6; }
+if ${ac_cv_sys_large_files+:} false; then :
$as_echo_n "(cached) " >&6
else
-
-save_CFLAGS="$CFLAGS"
-CFLAGS="$CFLAGS $ac_lbl_cc_force_warning_errors"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ while :; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-
-
-#include <stdlib.h>
-#include <stdio.h>
-
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
int
-main(int argc __attribute((unused)), char **argv __attribute((unused)))
+main ()
{
- printf("Hello, world!\n");
+
+ ;
return 0;
}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_sys_large_files=no; break
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#define _LARGE_FILES 1
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
+int
+main ()
+{
+ ;
+ return 0;
+}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv___attribute___unused=yes
-else
- ac_cv___attribute___unused=no
+ ac_cv_sys_large_files=1; break
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_cv_sys_large_files=unknown
+ break
+done
fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_large_files" >&5
+$as_echo "$ac_cv_sys_large_files" >&6; }
+case $ac_cv_sys_large_files in #(
+ no | unknown) ;;
+ *)
+cat >>confdefs.h <<_ACEOF
+#define _LARGE_FILES $ac_cv_sys_large_files
+_ACEOF
+;;
+esac
+rm -rf conftest*
+ fi
-CFLAGS="$save_CFLAGS"
-if test "$ac_cv___attribute___unused" = "yes"; then
- V_DEFS="$V_DEFS -D_U_=\"__attribute__((unused))\""
-else
- V_DEFS="$V_DEFS -D_U_=\"\""
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv___attribute___unused" >&5
-$as_echo "$ac_cv___attribute___unused" >&6; }
+fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether __attribute__((format)) can be used without warnings" >&5
-$as_echo_n "checking whether __attribute__((format)) can be used without warnings... " >&6; }
-if ${ac_cv___attribute___format+:} false; then :
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGEFILE_SOURCE value needed for large files" >&5
+$as_echo_n "checking for _LARGEFILE_SOURCE value needed for large files... " >&6; }
+if ${ac_cv_sys_largefile_source+:} false; then :
$as_echo_n "(cached) " >&6
else
-
-save_CFLAGS="$CFLAGS"
-CFLAGS="$CFLAGS $ac_lbl_cc_force_warning_errors"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ while :; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-
-
-#include <stdlib.h>
-
-extern int foo(const char *fmt, ...)
- __attribute__ ((format (printf, 1, 2)));
-
+#include <sys/types.h> /* for off_t */
+ #include <stdio.h>
int
-main(int argc, char **argv)
+main ()
{
- foo("%s", "test");
+int (*fp) (FILE *, off_t, int) = fseeko;
+ return fseeko (stdin, 0, 0) && fp (stdin, 0, 0);
+ ;
+ return 0;
}
-
_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv___attribute___format=yes
-else
- ac_cv___attribute___format=no
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_sys_largefile_source=no; break
fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#define _LARGEFILE_SOURCE 1
+#include <sys/types.h> /* for off_t */
+ #include <stdio.h>
+int
+main ()
+{
+int (*fp) (FILE *, off_t, int) = fseeko;
+ return fseeko (stdin, 0, 0) && fp (stdin, 0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_sys_largefile_source=1; break
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ ac_cv_sys_largefile_source=unknown
+ break
+done
fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_source" >&5
+$as_echo "$ac_cv_sys_largefile_source" >&6; }
+case $ac_cv_sys_largefile_source in #(
+ no | unknown) ;;
+ *)
+cat >>confdefs.h <<_ACEOF
+#define _LARGEFILE_SOURCE $ac_cv_sys_largefile_source
+_ACEOF
+;;
+esac
+rm -rf conftest*
-CFLAGS="$save_CFLAGS"
-if test "$ac_cv___attribute___format" = "yes"; then
+# We used to try defining _XOPEN_SOURCE=500 too, to work around a bug
+# in glibc 2.1.3, but that breaks too many other things.
+# If you want fseeko and ftello with glibc, upgrade to a fixed glibc.
+if test $ac_cv_sys_largefile_source != unknown; then
-$as_echo "#define __ATTRIBUTE___FORMAT_OK 1" >>confdefs.h
+$as_echo "#define HAVE_FSEEKO 1" >>confdefs.h
fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv___attribute___format" >&5
-$as_echo "$ac_cv___attribute___format" >&6; }
-fi
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
@@ -4341,397 +4738,7 @@ fi
done
-for ac_header in sys/bitypes.h
-do :
- ac_fn_c_check_header_mongrel "$LINENO" "sys/bitypes.h" "ac_cv_header_sys_bitypes_h" "$ac_includes_default"
-if test "x$ac_cv_header_sys_bitypes_h" = xyes; then :
- cat >>confdefs.h <<_ACEOF
-#define HAVE_SYS_BITYPES_H 1
-_ACEOF
-
-fi
-
-done
-
-
-ac_fn_c_check_type "$LINENO" "int8_t" "ac_cv_type_int8_t" "$ac_includes_default
-#ifdef HAVE_SYS_BITYPES_H
-#include <sys/bitypes.h>
-#endif
-"
-if test "x$ac_cv_type_int8_t" = xyes; then :
-
-else
-
-$as_echo "#define int8_t signed char" >>confdefs.h
-
-fi
-
-ac_fn_c_check_type "$LINENO" "u_int8_t" "ac_cv_type_u_int8_t" "$ac_includes_default
-#ifdef HAVE_SYS_BITYPES_H
-#include <sys/bitypes.h>
-#endif
-"
-if test "x$ac_cv_type_u_int8_t" = xyes; then :
-
-else
-
-$as_echo "#define u_int8_t unsigned char" >>confdefs.h
-
-fi
-
-ac_fn_c_check_type "$LINENO" "int16_t" "ac_cv_type_int16_t" "$ac_includes_default"
-if test "x$ac_cv_type_int16_t" = xyes; then :
-
-else
-
-$as_echo "#define int16_t short" >>confdefs.h
-
- $ac_includes_default
-#ifdef HAVE_SYS_BITYPES_H
-#include <sys/bitypes.h>
-#endif
-fi
-
-ac_fn_c_check_type "$LINENO" "u_int16_t" "ac_cv_type_u_int16_t" "$ac_includes_default
-#ifdef HAVE_SYS_BITYPES_H
-#include <sys/bitypes.h>
-#endif
-"
-if test "x$ac_cv_type_u_int16_t" = xyes; then :
-
-else
-
-$as_echo "#define u_int16_t unsigned short" >>confdefs.h
-
-fi
-
-ac_fn_c_check_type "$LINENO" "int32_t" "ac_cv_type_int32_t" "$ac_includes_default
-#ifdef HAVE_SYS_BITYPES_H
-#include <sys/bitypes.h>
-#endif
-"
-if test "x$ac_cv_type_int32_t" = xyes; then :
-
-else
-
-$as_echo "#define int32_t int" >>confdefs.h
-
-fi
-
-ac_fn_c_check_type "$LINENO" "u_int32_t" "ac_cv_type_u_int32_t" "$ac_includes_default
-#ifdef HAVE_SYS_BITYPES_H
-#include <sys/bitypes.h>
-#endif
-"
-if test "x$ac_cv_type_u_int32_t" = xyes; then :
-
-else
-
-$as_echo "#define u_int32_t unsigned int" >>confdefs.h
-
-fi
-
-ac_fn_c_check_type "$LINENO" "int64_t" "ac_cv_type_int64_t" "$ac_includes_default
-#ifdef HAVE_SYS_BITYPES_H
-#include <sys/bitypes.h>
-#endif
-"
-if test "x$ac_cv_type_int64_t" = xyes; then :
-
-else
-
-$as_echo "#define int64_t long long" >>confdefs.h
-
-fi
-
-ac_fn_c_check_type "$LINENO" "u_int64_t" "ac_cv_type_u_int64_t" "$ac_includes_default
-#ifdef HAVE_SYS_BITYPES_H
-#include <sys/bitypes.h>
-#endif
-"
-if test "x$ac_cv_type_u_int64_t" = xyes; then :
-
-else
-
-$as_echo "#define u_int64_t unsigned long long" >>confdefs.h
-
-fi
-
-
-#
-# Try to arrange for large file support.
-#
-# Check whether --enable-largefile was given.
-if test "${enable_largefile+set}" = set; then :
- enableval=$enable_largefile;
-fi
-
-if test "$enable_largefile" != no; then
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for special C compiler options needed for large files" >&5
-$as_echo_n "checking for special C compiler options needed for large files... " >&6; }
-if ${ac_cv_sys_largefile_CC+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- ac_cv_sys_largefile_CC=no
- if test "$GCC" != yes; then
- ac_save_CC=$CC
- while :; do
- # IRIX 6.2 and later do not support large files by default,
- # so use the C compiler's -n32 option if that helps.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <sys/types.h>
- /* Check that off_t can represent 2**63 - 1 correctly.
- We can't simply define LARGE_OFF_T to be 9223372036854775807,
- since some C++ compilers masquerading as C compilers
- incorrectly reject 9223372036854775807. */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
- int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
- && LARGE_OFF_T % 2147483647 == 1)
- ? 1 : -1];
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
- if ac_fn_c_try_compile "$LINENO"; then :
- break
-fi
-rm -f core conftest.err conftest.$ac_objext
- CC="$CC -n32"
- if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_sys_largefile_CC=' -n32'; break
-fi
-rm -f core conftest.err conftest.$ac_objext
- break
- done
- CC=$ac_save_CC
- rm -f conftest.$ac_ext
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_CC" >&5
-$as_echo "$ac_cv_sys_largefile_CC" >&6; }
- if test "$ac_cv_sys_largefile_CC" != no; then
- CC=$CC$ac_cv_sys_largefile_CC
- fi
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS value needed for large files" >&5
-$as_echo_n "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; }
-if ${ac_cv_sys_file_offset_bits+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- while :; do
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <sys/types.h>
- /* Check that off_t can represent 2**63 - 1 correctly.
- We can't simply define LARGE_OFF_T to be 9223372036854775807,
- since some C++ compilers masquerading as C compilers
- incorrectly reject 9223372036854775807. */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
- int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
- && LARGE_OFF_T % 2147483647 == 1)
- ? 1 : -1];
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_sys_file_offset_bits=no; break
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#define _FILE_OFFSET_BITS 64
-#include <sys/types.h>
- /* Check that off_t can represent 2**63 - 1 correctly.
- We can't simply define LARGE_OFF_T to be 9223372036854775807,
- since some C++ compilers masquerading as C compilers
- incorrectly reject 9223372036854775807. */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
- int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
- && LARGE_OFF_T % 2147483647 == 1)
- ? 1 : -1];
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_sys_file_offset_bits=64; break
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- ac_cv_sys_file_offset_bits=unknown
- break
-done
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_file_offset_bits" >&5
-$as_echo "$ac_cv_sys_file_offset_bits" >&6; }
-case $ac_cv_sys_file_offset_bits in #(
- no | unknown) ;;
- *)
-cat >>confdefs.h <<_ACEOF
-#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits
-_ACEOF
-;;
-esac
-rm -rf conftest*
- if test $ac_cv_sys_file_offset_bits = unknown; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGE_FILES value needed for large files" >&5
-$as_echo_n "checking for _LARGE_FILES value needed for large files... " >&6; }
-if ${ac_cv_sys_large_files+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- while :; do
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <sys/types.h>
- /* Check that off_t can represent 2**63 - 1 correctly.
- We can't simply define LARGE_OFF_T to be 9223372036854775807,
- since some C++ compilers masquerading as C compilers
- incorrectly reject 9223372036854775807. */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
- int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
- && LARGE_OFF_T % 2147483647 == 1)
- ? 1 : -1];
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_sys_large_files=no; break
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#define _LARGE_FILES 1
-#include <sys/types.h>
- /* Check that off_t can represent 2**63 - 1 correctly.
- We can't simply define LARGE_OFF_T to be 9223372036854775807,
- since some C++ compilers masquerading as C compilers
- incorrectly reject 9223372036854775807. */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
- int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
- && LARGE_OFF_T % 2147483647 == 1)
- ? 1 : -1];
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_sys_large_files=1; break
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- ac_cv_sys_large_files=unknown
- break
-done
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_large_files" >&5
-$as_echo "$ac_cv_sys_large_files" >&6; }
-case $ac_cv_sys_large_files in #(
- no | unknown) ;;
- *)
-cat >>confdefs.h <<_ACEOF
-#define _LARGE_FILES $ac_cv_sys_large_files
-_ACEOF
-;;
-esac
-rm -rf conftest*
- fi
-
-
-fi
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGEFILE_SOURCE value needed for large files" >&5
-$as_echo_n "checking for _LARGEFILE_SOURCE value needed for large files... " >&6; }
-if ${ac_cv_sys_largefile_source+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- while :; do
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <sys/types.h> /* for off_t */
- #include <stdio.h>
-int
-main ()
-{
-int (*fp) (FILE *, off_t, int) = fseeko;
- return fseeko (stdin, 0, 0) && fp (stdin, 0, 0);
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_sys_largefile_source=no; break
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#define _LARGEFILE_SOURCE 1
-#include <sys/types.h> /* for off_t */
- #include <stdio.h>
-int
-main ()
-{
-int (*fp) (FILE *, off_t, int) = fseeko;
- return fseeko (stdin, 0, 0) && fp (stdin, 0, 0);
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_sys_largefile_source=1; break
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
- ac_cv_sys_largefile_source=unknown
- break
-done
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_source" >&5
-$as_echo "$ac_cv_sys_largefile_source" >&6; }
-case $ac_cv_sys_largefile_source in #(
- no | unknown) ;;
- *)
-cat >>confdefs.h <<_ACEOF
-#define _LARGEFILE_SOURCE $ac_cv_sys_largefile_source
-_ACEOF
-;;
-esac
-rm -rf conftest*
-
-# We used to try defining _XOPEN_SOURCE=500 too, to work around a bug
-# in glibc 2.1.3, but that breaks too many other things.
-# If you want fseeko and ftello with glibc, upgrade to a fixed glibc.
-if test $ac_cv_sys_largefile_source != unknown; then
-
-$as_echo "#define HAVE_FSEEKO 1" >>confdefs.h
-
-fi
-
-
-for ac_header in sys/ioccom.h sys/select.h sys/sockio.h limits.h
+for ac_header in sys/ioccom.h sys/sockio.h limits.h
do :
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
@@ -4744,25 +4751,12 @@ fi
done
-for ac_header in linux/types.h
-do :
- ac_fn_c_check_header_mongrel "$LINENO" "linux/types.h" "ac_cv_header_linux_types_h" "$ac_includes_default"
-if test "x$ac_cv_header_linux_types_h" = xyes; then :
- cat >>confdefs.h <<_ACEOF
-#define HAVE_LINUX_TYPES_H 1
-_ACEOF
-
-fi
-
-done
-
-for ac_header in linux/if_packet.h netpacket/packet.h netpacket/if_packet.h
+for ac_header in netpacket/packet.h
do :
- as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
-ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
-if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ ac_fn_c_check_header_mongrel "$LINENO" "netpacket/packet.h" "ac_cv_header_netpacket_packet_h" "$ac_includes_default"
+if test "x$ac_cv_header_netpacket_packet_h" = xyes; then :
cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+#define HAVE_NETPACKET_PACKET_H 1
_ACEOF
fi
@@ -4818,50 +4812,6 @@ $as_echo "no" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
-for ac_header in netinet/if_ether.h
-do :
- ac_fn_c_check_header_compile "$LINENO" "netinet/if_ether.h" "ac_cv_header_netinet_if_ether_h" "#include <sys/types.h>
-#include <sys/socket.h>
-"
-if test "x$ac_cv_header_netinet_if_ether_h" = xyes; then :
- cat >>confdefs.h <<_ACEOF
-#define HAVE_NETINET_IF_ETHER_H 1
-_ACEOF
-
-fi
-
-done
-
-if test "$ac_cv_header_netinet_if_ether_h" != yes; then
- #
- # The simple test didn't work.
- # Do we need to include <net/if.h> first?
- # Unset ac_cv_header_netinet_if_ether_h so we don't
- # treat the previous failure as a cached value and
- # suppress the next test.
- #
- { $as_echo "$as_me:${as_lineno-$LINENO}: Rechecking with some additional includes" >&5
-$as_echo "$as_me: Rechecking with some additional includes" >&6;}
- unset ac_cv_header_netinet_if_ether_h
- for ac_header in netinet/if_ether.h
-do :
- ac_fn_c_check_header_compile "$LINENO" "netinet/if_ether.h" "ac_cv_header_netinet_if_ether_h" "#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-struct mbuf;
-struct rtentry;
-#include <net/if.h>
-"
-if test "x$ac_cv_header_netinet_if_ether_h" = xyes; then :
- cat >>confdefs.h <<_ACEOF
-#define HAVE_NETINET_IF_ETHER_H 1
-_ACEOF
-
-fi
-
-done
-
-fi
case "$host_os" in
linux*|uclinux*)
@@ -4931,7 +4881,7 @@ $as_echo "$ac_cv_lbl_gcc_fixincludes" >&6; }
fi
fi
-for ac_func in strerror strlcpy
+for ac_func in strerror strerror_r strerror_s strlcpy strlcat
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
@@ -4992,20 +4942,65 @@ esac
fi
#
+# Do we have ffs(), and is it declared in <strings.h>?
+#
+for ac_func in ffs
+do :
+ ac_fn_c_check_func "$LINENO" "ffs" "ac_cv_func_ffs"
+if test "x$ac_cv_func_ffs" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_FFS 1
+_ACEOF
+
+fi
+done
+
+if test "$ac_cv_func_ffs" = yes; then
+ #
+ # We have ffs(); is it declared in <strings.h>?
+ #
+ # This test fails if we don't have <strings.h> or if we do
+ # but it doesn't declare ffs().
+ #
+ ac_fn_c_check_decl "$LINENO" "ffs" "ac_cv_have_decl_ffs" "
+#include <strings.h>
+
+"
+if test "x$ac_cv_have_decl_ffs" = xyes; then :
+
+
+$as_echo "#define STRINGS_H_DECLARES_FFS /**/" >>confdefs.h
+
+
+fi
+
+fi
+
+#
# Do this before checking for ether_hostton(), as it's a
-# "gethostbyname() -ish function".
+# "getaddrinfo()-ish function".
#
- # Most operating systems have gethostbyname() in the default searched
- # libraries (i.e. libc):
- # Some OSes (eg. Solaris) place it in libnsl
- # Some strange OSes (SINIX) have it in libsocket:
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing gethostbyname" >&5
-$as_echo_n "checking for library containing gethostbyname... " >&6; }
-if ${ac_cv_search_gethostbyname+:} false; then :
+ #
+ # Most operating systems have getaddrinfo() in the default searched
+ # libraries (i.e. libc). Check there first.
+ #
+ ac_fn_c_check_func "$LINENO" "getaddrinfo" "ac_cv_func_getaddrinfo"
+if test "x$ac_cv_func_getaddrinfo" = xyes; then :
+
+else
+
+ #
+ # Not found in the standard system libraries.
+ # Try libsocket, which requires libnsl.
+ #
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getaddrinfo in -lsocket" >&5
+$as_echo_n "checking for getaddrinfo in -lsocket... " >&6; }
+if ${ac_cv_lib_socket_getaddrinfo+:} false; then :
$as_echo_n "(cached) " >&6
else
- ac_func_search_save_LIBS=$LIBS
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsocket -lnsl $LIBS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
@@ -5015,58 +5010,54 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
#ifdef __cplusplus
extern "C"
#endif
-char gethostbyname ();
+char getaddrinfo ();
int
main ()
{
-return gethostbyname ();
+return getaddrinfo ();
;
return 0;
}
_ACEOF
-for ac_lib in '' nsl socket resolv; do
- if test -z "$ac_lib"; then
- ac_res="none required"
- else
- ac_res=-l$ac_lib
- LIBS="-l$ac_lib $ac_func_search_save_LIBS"
- fi
- if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_search_gethostbyname=$ac_res
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_socket_getaddrinfo=yes
+else
+ ac_cv_lib_socket_getaddrinfo=no
fi
rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext
- if ${ac_cv_search_gethostbyname+:} false; then :
- break
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
fi
-done
-if ${ac_cv_search_gethostbyname+:} false; then :
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_getaddrinfo" >&5
+$as_echo "$ac_cv_lib_socket_getaddrinfo" >&6; }
+if test "x$ac_cv_lib_socket_getaddrinfo" = xyes; then :
+
+ #
+ # OK, we found it in libsocket.
+ #
+ LIBS="-lsocket -lnsl $LIBS"
else
- ac_cv_search_gethostbyname=no
-fi
-rm conftest.$ac_ext
-LIBS=$ac_func_search_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_gethostbyname" >&5
-$as_echo "$ac_cv_search_gethostbyname" >&6; }
-ac_res=$ac_cv_search_gethostbyname
-if test "$ac_res" != no; then :
- test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+ #
+ # We didn't find it.
+ #
+ as_fn_error $? "getaddrinfo is required, but wasn't found" "$LINENO" 5
fi
- # Unfortunately libsocket sometimes depends on libnsl and
- # AC_SEARCH_LIBS isn't up to the task of handling dependencies like this.
- if test "$ac_cv_search_gethostbyname" = "no"
- then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lsocket" >&5
-$as_echo_n "checking for gethostbyname in -lsocket... " >&6; }
-if ${ac_cv_lib_socket_gethostbyname+:} false; then :
+
+ #
+ # OK, do we have recvmsg() in libxnet?
+ # We also link with libsocket and libnsl.
+ #
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for recvmsg in -lxnet" >&5
+$as_echo_n "checking for recvmsg in -lxnet... " >&6; }
+if ${ac_cv_lib_xnet_recvmsg+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
-LIBS="-lsocket -lnsl $LIBS"
+LIBS="-lxnet -lsocket -lnsl $LIBS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
@@ -5076,34 +5067,42 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
#ifdef __cplusplus
extern "C"
#endif
-char gethostbyname ();
+char recvmsg ();
int
main ()
{
-return gethostbyname ();
+return recvmsg ();
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_socket_gethostbyname=yes
+ ac_cv_lib_xnet_recvmsg=yes
else
- ac_cv_lib_socket_gethostbyname=no
+ ac_cv_lib_xnet_recvmsg=no
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_gethostbyname" >&5
-$as_echo "$ac_cv_lib_socket_gethostbyname" >&6; }
-if test "x$ac_cv_lib_socket_gethostbyname" = xyes; then :
- LIBS="-lsocket -lnsl $LIBS"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_xnet_recvmsg" >&5
+$as_echo "$ac_cv_lib_xnet_recvmsg" >&6; }
+if test "x$ac_cv_lib_xnet_recvmsg" = xyes; then :
+
+ #
+ # Yes - link with it as well.
+ #
+ LIBS="-lxnet $LIBS"
+
fi
- fi
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing socket" >&5
-$as_echo_n "checking for library containing socket... " >&6; }
-if ${ac_cv_search_socket+:} false; then :
+
+fi
+
+ # DLPI needs putmsg under HPUX so test for -lstr while we're at it
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing putmsg" >&5
+$as_echo_n "checking for library containing putmsg... " >&6; }
+if ${ac_cv_search_putmsg+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_func_search_save_LIBS=$LIBS
@@ -5116,16 +5115,16 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
#ifdef __cplusplus
extern "C"
#endif
-char socket ();
+char putmsg ();
int
main ()
{
-return socket ();
+return putmsg ();
;
return 0;
}
_ACEOF
-for ac_lib in '' socket; do
+for ac_lib in '' str; do
if test -z "$ac_lib"; then
ac_res="none required"
else
@@ -5133,138 +5132,294 @@ for ac_lib in '' socket; do
LIBS="-l$ac_lib $ac_func_search_save_LIBS"
fi
if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_search_socket=$ac_res
+ ac_cv_search_putmsg=$ac_res
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext
- if ${ac_cv_search_socket+:} false; then :
+ if ${ac_cv_search_putmsg+:} false; then :
break
fi
done
-if ${ac_cv_search_socket+:} false; then :
+if ${ac_cv_search_putmsg+:} false; then :
else
- ac_cv_search_socket=no
+ ac_cv_search_putmsg=no
fi
rm conftest.$ac_ext
LIBS=$ac_func_search_save_LIBS
fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_socket" >&5
-$as_echo "$ac_cv_search_socket" >&6; }
-ac_res=$ac_cv_search_socket
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_putmsg" >&5
+$as_echo "$ac_cv_search_putmsg" >&6; }
+ac_res=$ac_cv_search_putmsg
if test "$ac_res" != no; then :
test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+fi
+
+
+
+#
+# Check for reentrant versions of getnetbyname_r(), as provided by
+# Linux (glibc), Solaris/IRIX, and AIX (with three different APIs!).
+# If we don't find one, we just use getnetbyname(), which uses
+# thread-specific data on many platforms, but doesn't use it on
+# NetBSD or OpenBSD, and may not use it on older versions of other
+# platforms.
+#
+# Only do the check if we have a declaration of getnetbyname_r();
+# without it, we can't check which API it has. (We assume that
+# if there's a declaration, it has a prototype, so that the API
+# can be checked.)
+#
+ac_fn_c_check_decl "$LINENO" "getnetbyname_r" "ac_cv_have_decl_getnetbyname_r" "#include <netdb.h>
+"
+if test "x$ac_cv_have_decl_getnetbyname_r" = xyes; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the Linux getnetbyname_r()" >&5
+$as_echo_n "checking for the Linux getnetbyname_r()... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <netdb.h>
+int
+main ()
+{
+
+ struct netent netent_buf;
+ char buf[1024];
+ struct netent *resultp;
+ int h_errnoval;
+
+ return getnetbyname_r((const char *)0, &netent_buf, buf, sizeof buf, &resultp, &h_errnoval);
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_LINUX_GETNETBYNAME_R 1" >>confdefs.h
+
+
else
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for socket in -lsocket" >&5
-$as_echo_n "checking for socket in -lsocket... " >&6; }
-if ${ac_cv_lib_socket_socket+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lsocket -lnsl $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Solaris/IRIX getnetbyname_r()" >&5
+$as_echo_n "checking for Solaris/IRIX getnetbyname_r()... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
+#include <netdb.h>
+int
+main ()
+{
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char socket ();
+ struct netent netent_buf;
+ char buf[1024];
+
+ return getnetbyname_r((const char *)0, &netent_buf, buf, (int)sizeof buf) != NULL;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_SOLARIS_IRIX_GETNETBYNAME_R 1" >>confdefs.h
+
+
+else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for AIX getnetbyname_r()" >&5
+$as_echo_n "checking for AIX getnetbyname_r()... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <netdb.h>
int
main ()
{
-return socket ();
+
+ struct netent netent_buf;
+ struct netent_data net_data;
+
+ return getnetbyname_r((const char *)0, &netent_buf, &net_data);
+
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_socket_socket=yes
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_AIX_GETNETBYNAME_R 1" >>confdefs.h
+
+
else
- ac_cv_lib_socket_socket=no
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
+
fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_socket" >&5
-$as_echo "$ac_cv_lib_socket_socket" >&6; }
-if test "x$ac_cv_lib_socket_socket" = xyes; then :
- LIBS="-lsocket -lnsl $LIBS"
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+
fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
fi
- # DLPI needs putmsg under HPUX so test for -lstr while we're at it
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing putmsg" >&5
-$as_echo_n "checking for library containing putmsg... " >&6; }
-if ${ac_cv_search_putmsg+:} false; then :
- $as_echo_n "(cached) " >&6
+
+#
+# Check for reentrant versions of getprotobyname_r(), as provided by
+# Linux (glibc), Solaris/IRIX, and AIX (with three different APIs!).
+# If we don't find one, we just use getprotobyname(), which uses
+# thread-specific data on many platforms, but doesn't use it on
+# NetBSD or OpenBSD, and may not use it on older versions of other
+# platforms.
+#
+# Only do the check if we have a declaration of getprotobyname_r();
+# without it, we can't check which API it has. (We assume that
+# if there's a declaration, it has a prototype, so that the API
+# can be checked.)
+#
+ac_fn_c_check_decl "$LINENO" "getprotobyname_r" "ac_cv_have_decl_getprotobyname_r" "#include <netdb.h>
+"
+if test "x$ac_cv_have_decl_getprotobyname_r" = xyes; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the Linux getprotobyname_r()" >&5
+$as_echo_n "checking for the Linux getprotobyname_r()... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <netdb.h>
+int
+main ()
+{
+
+ struct protoent protoent_buf;
+ char buf[1024];
+ struct protoent *resultp;
+
+ return getprotobyname_r((const char *)0, &protoent_buf, buf, sizeof buf, &resultp);
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_LINUX_GETPROTOBYNAME_R 1" >>confdefs.h
+
+
else
- ac_func_search_save_LIBS=$LIBS
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Solaris/IRIX getprotobyname_r()" >&5
+$as_echo_n "checking for Solaris/IRIX getprotobyname_r()... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
+#include <netdb.h>
+int
+main ()
+{
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char putmsg ();
+ struct protoent protoent_buf;
+ char buf[1024];
+
+ return getprotobyname_r((const char *)0, &protoent_buf, buf, (int)sizeof buf) != NULL;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_SOLARIS_IRIX_GETPROTOBYNAME_R 1" >>confdefs.h
+
+
+else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for AIX getprotobyname_r()" >&5
+$as_echo_n "checking for AIX getprotobyname_r()... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <netdb.h>
int
main ()
{
-return putmsg ();
+
+ struct protoent protoent_buf;
+ struct protoent_data proto_data;
+
+ return getprotobyname_r((const char *)0, &protoent_buf, &proto_data);
+
;
return 0;
}
_ACEOF
-for ac_lib in '' str; do
- if test -z "$ac_lib"; then
- ac_res="none required"
- else
- ac_res=-l$ac_lib
- LIBS="-l$ac_lib $ac_func_search_save_LIBS"
- fi
- if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_search_putmsg=$ac_res
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext
- if ${ac_cv_search_putmsg+:} false; then :
- break
-fi
-done
-if ${ac_cv_search_putmsg+:} false; then :
+if ac_fn_c_try_link "$LINENO"; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_AIX_GETPROTOBYNAME_R 1" >>confdefs.h
+
else
- ac_cv_search_putmsg=no
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
fi
-rm conftest.$ac_ext
-LIBS=$ac_func_search_save_LIBS
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+
fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_putmsg" >&5
-$as_echo "$ac_cv_search_putmsg" >&6; }
-ac_res=$ac_cv_search_putmsg
-if test "$ac_res" != no; then :
- test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
#
# You are in a twisty little maze of UN*Xes, all different.
# Some might not have ether_hostton().
-# Some might have it, but not declare it in any header file.
-# Some might have it, but declare it in <netinet/if_ether.h>.
-# Some might have it, but declare it in <netinet/ether.h>
-# (And some might have it but document it as something declared in
-# <netinet/ethernet.h>, although <netinet/if_ether.h> appears to work.)
+# Some might have it and declare it in <net/ethernet.h>.
+# Some might have it and declare it in <netinet/ether.h>
+# Some might have it and declare it in <sys/ethernet.h>.
+# Some might have it and declare it in <arpa/inet.h>.
+# Some might have it and declare it in <netinet/if_ether.h>.
+# Some might have it and not declare it in any header file.
#
# Before you is a C compiler.
#
@@ -5281,27 +5436,46 @@ done
if test "$ac_cv_func_ether_hostton" = yes; then
#
- # OK, we have ether_hostton(). Do we have <netinet/if_ether.h>?
+ # OK, we have ether_hostton(). Is it declared in <net/ethernet.h>?
#
- if test "$ac_cv_header_netinet_if_ether_h" = yes; then
+ # This test fails if we don't have <net/ethernet.h> or if we do
+ # but it doesn't declare ether_hostton().
+ #
+ ac_fn_c_check_decl "$LINENO" "ether_hostton" "ac_cv_have_decl_ether_hostton" "
+#include <net/ethernet.h>
+
+"
+if test "x$ac_cv_have_decl_ether_hostton" = xyes; then :
+
+
+$as_echo "#define NET_ETHERNET_H_DECLARES_ETHER_HOSTTON /**/" >>confdefs.h
+
+
+fi
+
+ #
+ # Did that succeed?
+ #
+ if test "$ac_cv_have_decl_ether_hostton" != yes; then
#
- # Yes. Does it declare ether_hostton()?
+ # No, how about <netinet/ether.h>, as on Linux?
#
+ # This test fails if we don't have <netinet/ether.h>
+ # or if we do but it doesn't declare ether_hostton().
+ #
+ # Unset ac_cv_have_decl_ether_hostton so we don't
+ # treat the previous failure as a cached value and
+ # suppress the next test.
+ #
+ unset ac_cv_have_decl_ether_hostton
ac_fn_c_check_decl "$LINENO" "ether_hostton" "ac_cv_have_decl_ether_hostton" "
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-struct mbuf;
-struct rtentry;
-#include <net/if.h>
-#include <netinet/if_ether.h>
+#include <netinet/ether.h>
"
if test "x$ac_cv_have_decl_ether_hostton" = xyes; then :
-$as_echo "#define NETINET_IF_ETHER_H_DECLARES_ETHER_HOSTTON /**/" >>confdefs.h
+$as_echo "#define NETINET_ETHER_H_DECLARES_ETHER_HOSTTON /**/" >>confdefs.h
fi
@@ -5312,61 +5486,121 @@ fi
#
if test "$ac_cv_have_decl_ether_hostton" != yes; then
#
- # No, how about <netinet/ether.h>, as on Linux?
+ # No, how about <sys/ethernet.h>, as on Solaris 10
+ # and later?
#
- for ac_header in netinet/ether.h
-do :
- ac_fn_c_check_header_mongrel "$LINENO" "netinet/ether.h" "ac_cv_header_netinet_ether_h" "$ac_includes_default"
-if test "x$ac_cv_header_netinet_ether_h" = xyes; then :
- cat >>confdefs.h <<_ACEOF
-#define HAVE_NETINET_ETHER_H 1
-_ACEOF
+ # This test fails if we don't have <sys/ethernet.h>
+ # or if we do but it doesn't declare ether_hostton().
+ #
+ # Unset ac_cv_have_decl_ether_hostton so we don't
+ # treat the previous failure as a cached value and
+ # suppress the next test.
+ #
+ unset ac_cv_have_decl_ether_hostton
+ ac_fn_c_check_decl "$LINENO" "ether_hostton" "ac_cv_have_decl_ether_hostton" "
+#include <sys/ethernet.h>
-fi
+"
+if test "x$ac_cv_have_decl_ether_hostton" = xyes; then :
-done
- if test "$ac_cv_header_netinet_ether_h" = yes; then
- #
- # We have it - does it declare ether_hostton()?
- # Unset ac_cv_have_decl_ether_hostton so we don't
- # treat the previous failure as a cached value and
- # suppress the next test.
- #
- unset ac_cv_have_decl_ether_hostton
- ac_fn_c_check_decl "$LINENO" "ether_hostton" "ac_cv_have_decl_ether_hostton" "
-#include <netinet/ether.h>
+$as_echo "#define SYS_ETHERNET_H_DECLARES_ETHER_HOSTTON /**/" >>confdefs.h
+
+
+fi
+
+ fi
+ #
+ # Did that succeed?
+ #
+ if test "$ac_cv_have_decl_ether_hostton" != yes; then
+ #
+ # No, how about <arpa/inet.h>, as in AIX?
+ #
+ # This test fails if we don't have <arpa/inet.h>
+ # (if we have ether_hostton(), we should have
+ # networking, and if we have networking, we should
+ # have <arapa/inet.h>) or if we do but it doesn't
+ # declare ether_hostton().
+ #
+ # Unset ac_cv_have_decl_ether_hostton so we don't
+ # treat the previous failure as a cached value and
+ # suppress the next test.
+ #
+ unset ac_cv_have_decl_ether_hostton
+ ac_fn_c_check_decl "$LINENO" "ether_hostton" "ac_cv_have_decl_ether_hostton" "
+#include <arpa/inet.h>
"
if test "x$ac_cv_have_decl_ether_hostton" = xyes; then :
-$as_echo "#define NETINET_ETHER_H_DECLARES_ETHER_HOSTTON /**/" >>confdefs.h
+$as_echo "#define ARPA_INET_H_DECLARES_ETHER_HOSTTON /**/" >>confdefs.h
fi
- fi
fi
#
- # Is ether_hostton() declared?
+ # Did that succeed?
#
if test "$ac_cv_have_decl_ether_hostton" != yes; then
#
- # No, we'll have to declare it ourselves.
- # Do we have "struct ether_addr"?
+ # No, how about <netinet/if_ether.h>?
+ # On some platforms, it requires <net/if.h> and
+ # <netinet/in.h>, and we always include it with
+ # both of them, so test it with both of them.
#
- ac_fn_c_check_type "$LINENO" "struct ether_addr" "ac_cv_type_struct_ether_addr" "
+ # This test fails if we don't have <netinet/if_ether.h>
+ # and the headers we include before it, or if we do but
+ # <netinet/if_ether.h> doesn't declare ether_hostton().
+ #
+ # Unset ac_cv_have_decl_ether_hostton so we don't
+ # treat the previous failure as a cached value and
+ # suppress the next test.
+ #
+ unset ac_cv_have_decl_ether_hostton
+ ac_fn_c_check_decl "$LINENO" "ether_hostton" "ac_cv_have_decl_ether_hostton" "
#include <sys/types.h>
#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-struct mbuf;
-struct rtentry;
#include <net/if.h>
+#include <netinet/in.h>
#include <netinet/if_ether.h>
"
+if test "x$ac_cv_have_decl_ether_hostton" = xyes; then :
+
+
+$as_echo "#define NETINET_IF_ETHER_H_DECLARES_ETHER_HOSTTON /**/" >>confdefs.h
+
+
+fi
+
+ fi
+ #
+ # After all that, is ether_hostton() declared?
+ #
+ if test "$ac_cv_have_decl_ether_hostton" = yes; then
+ #
+ # Yes.
+ #
+
+$as_echo "#define HAVE_DECL_ETHER_HOSTTON 1" >>confdefs.h
+
+ else
+ #
+ # No, we'll have to declare it ourselves.
+ # Do we have "struct ether_addr" if we include
+ # <netinet/if_ether.h>?
+ #
+ ac_fn_c_check_type "$LINENO" "struct ether_addr" "ac_cv_type_struct_ether_addr" "
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <net/if.h>
+ #include <netinet/in.h>
+ #include <netinet/if_ether.h>
+
+"
if test "x$ac_cv_type_struct_ether_addr" = xyes; then :
cat >>confdefs.h <<_ACEOF
@@ -5376,16 +5610,153 @@ _ACEOF
fi
+ fi
+fi
-$as_echo "#define HAVE_DECL_ETHER_HOSTTON 0" >>confdefs.h
+#
+# For various things that might use pthreads.
+#
+ac_fn_c_check_header_mongrel "$LINENO" "pthread.h" "ac_cv_header_pthread_h" "$ac_includes_default"
+if test "x$ac_cv_header_pthread_h" = xyes; then :
- else
+ #
+ # OK, we have pthread.h. Do we have pthread_create in the
+ # system libraries?
+ #
+ ac_fn_c_check_func "$LINENO" "pthread_create" "ac_cv_func_pthread_create"
+if test "x$ac_cv_func_pthread_create" = xyes; then :
+
+ #
+ # Yes.
+ #
+ ac_lbl_have_pthreads="found"
+
+else
+
+ #
+ # No - do we have it in -lpthreads?
+ #
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_create in -lpthreads" >&5
+$as_echo_n "checking for pthread_create in -lpthreads... " >&6; }
+if ${ac_cv_lib_pthreads_pthread_create+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpthreads $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char pthread_create ();
+int
+main ()
+{
+return pthread_create ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_pthreads_pthread_create=yes
+else
+ ac_cv_lib_pthreads_pthread_create=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthreads_pthread_create" >&5
+$as_echo "$ac_cv_lib_pthreads_pthread_create" >&6; }
+if test "x$ac_cv_lib_pthreads_pthread_create" = xyes; then :
+
+ #
+ # Yes - add -lpthreads.
+ #
+ ac_lbl_have_pthreads="found"
+ PTHREAD_LIBS="$PTHREAD_LIBS -lpthreads"
+
+else
+
+ #
+ # No - do we have it in -lpthread?
+ #
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_create in -lpthread" >&5
+$as_echo_n "checking for pthread_create in -lpthread... " >&6; }
+if ${ac_cv_lib_pthread_pthread_create+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpthread $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char pthread_create ();
+int
+main ()
+{
+return pthread_create ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_pthread_pthread_create=yes
+else
+ ac_cv_lib_pthread_pthread_create=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_pthread_create" >&5
+$as_echo "$ac_cv_lib_pthread_pthread_create" >&6; }
+if test "x$ac_cv_lib_pthread_pthread_create" = xyes; then :
+
+ #
+ # Yes - add -lpthread.
+ #
+ ac_lbl_have_pthreads="found"
+ PTHREAD_LIBS="$PTHREAD_LIBS -lpthread"
+
+else
+
+ #
+ # No.
+ #
+ ac_lbl_have_pthreads="not found"
+
+fi
+
+
+fi
-$as_echo "#define HAVE_DECL_ETHER_HOSTTON 1" >>confdefs.h
- fi
fi
+
+else
+
+ #
+ # We didn't find pthread.h.
+ #
+ ac_lbl_have_pthreads="not found"
+
+
+fi
+
+
+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --disable-protochain option is specified" >&5
$as_echo_n "checking if --disable-protochain option is specified... " >&6; }
# Check whether --enable-protochain was given.
@@ -5412,7 +5783,7 @@ $as_echo "${enable_protochain}" >&6; }
# only tests with BPF and PF_PACKET sockets; only enable it if
# we have BPF or PF_PACKET sockets.
#
-VALGRINDTEST=
+VALGRINDTEST_SRC=
#
# SITA support is mutually exclusive with native capture support;
@@ -5433,80 +5804,209 @@ $as_echo "$as_me: Enabling SITA ACN support" >&6;}
else
-if test -z "$with_pcap" && test "$cross_compiling" = yes; then
- as_fn_error $? "pcap type not determined when cross-compiling; use --with-pcap=..." "$LINENO" 5
-fi
# Check whether --with-pcap was given.
if test "${with_pcap+set}" = set; then :
withval=$with_pcap;
fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking packet capture type" >&5
-$as_echo_n "checking packet capture type... " >&6; }
if test ! -z "$with_pcap" ; then
V_PCAP="$withval"
-elif test -r /dev/bpf -o -h /dev/bpf ; then
+else
#
- # Cloning BPF device.
+ # Check for a bunch of headers for various packet
+ # capture mechanisms.
#
- V_PCAP=bpf
-
-$as_echo "#define HAVE_CLONING_BPF 1" >>confdefs.h
+ for ac_header in net/bpf.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "net/bpf.h" "ac_cv_header_net_bpf_h" "$ac_includes_default"
+if test "x$ac_cv_header_net_bpf_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_NET_BPF_H 1
+_ACEOF
+fi
- #
- # We have BPF, so build valgrindtest with "make test".
- #
- VALGRINDTEST=valgrindtest
-elif test -r /dev/bpf0 ; then
- V_PCAP=bpf
+done
- #
- # We have BPF, so build valgrindtest with "make test".
- #
- VALGRINDTEST=valgrindtest
-elif test -r /usr/include/net/pfilt.h ; then
- V_PCAP=pf
-elif test -r /dev/enet ; then
- V_PCAP=enet
-elif test -r /dev/nit ; then
- V_PCAP=snit
-elif test -r /usr/include/sys/net/nit.h ; then
- V_PCAP=nit
-elif test -r /usr/include/linux/socket.h ; then
- V_PCAP=linux
+ if test "$ac_cv_header_net_bpf_h" = yes; then
+ #
+ # Does it define BIOCSETIF?
+ # I.e., is it a header for an LBL/BSD-style capture
+ # mechanism, or is it just a header for a BPF filter
+ # engine? Some versions of Arch Linux, for example,
+ # have a net/bpf.h that doesn't define BIOCSETIF;
+ # 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/ioctl.h and, if we have it, sys/ioccom.h,
+ # because net/bpf.h defines ioctls;
+ #
+ # net/if.h, because it defines some structures
+ # used in ioctls defined by net/bpf.h;
+ #
+ # sys/socket.h, because OpenBSD 5.9's net/bpf.h
+ # defines some structure fields as being
+ # struct sockaddrs;
+ #
+ # and net/bpf.h doesn't necessarily include all
+ # of those headers itself.
+ #
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if net/bpf.h defines BIOCSETIF" >&5
+$as_echo_n "checking if net/bpf.h defines BIOCSETIF... " >&6; }
+ if ${ac_cv_lbl_bpf_h_defines_biocsetif+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
- #
- # XXX - this won't work with older kernels that have SOCK_PACKET
- # sockets but not PF_PACKET sockets.
- #
- VALGRINDTEST=valgrindtest
-elif test -r /usr/include/net/raw.h ; then
- V_PCAP=snoop
-elif test -r /usr/include/odmi.h ; then
- #
- # On AIX, the BPF devices might not yet be present - they're
- # created the first time libpcap runs after booting.
- # We check for odmi.h instead.
- #
- V_PCAP=bpf
-elif test -c /dev/bpf0 ; then # check again in case not readable
- V_PCAP=bpf
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#ifdef HAVE_SYS_IOCCOM_H
+#include <sys/ioccom.h>
+#endif
+#include <net/bpf.h>
+#include <net/if.h>
- #
- # We have BPF, so build valgrindtest with "make test".
- #
- VALGRINDTEST=valgrindtest
-elif test -r /usr/include/sys/dlpi.h ; then
- V_PCAP=dlpi
-elif test -c /dev/enet ; then # check again in case not readable
- V_PCAP=enet
-elif test -c /dev/nit ; then # check again in case not readable
- V_PCAP=snit
+int
+main ()
+{
+u_int i = BIOCSETIF;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_lbl_bpf_h_defines_biocsetif=yes
else
- V_PCAP=null
+ ac_cv_lbl_bpf_h_defines_biocsetif=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lbl_bpf_h_defines_biocsetif" >&5
+$as_echo "$ac_cv_lbl_bpf_h_defines_biocsetif" >&6; }
+ fi
+ for ac_header in net/pfilt.h net/enet.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+ for ac_header in net/nit.h sys/net/nit.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+ for ac_header in linux/socket.h net/raw.h sys/dlpi.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+ if test "$ac_cv_lbl_bpf_h_defines_biocsetif" = yes; then
+ #
+ # BPF.
+ # Check this before DLPI, so that we pick BPF on
+ # Solaris 11 and later.
+ #
+ V_PCAP=bpf
+
+ #
+ # We have BPF, so build valgrindtest with "make test"
+ # on macOS and FreeBSD (add your OS once there's a
+ # valgrind for it).
+ #
+ case "$host_os" in
+
+ freebsd*|darwin*|linux*)
+ VALGRINDTEST_SRC=valgrindtest.c
+ ;;
+ esac
+ elif test "$ac_cv_header_linux_socket_h" = yes; then
+ #
+ # No prizes for guessing this one.
+ #
+ V_PCAP=linux
+
+ #
+ # XXX - this won't work with older kernels that have
+ # SOCK_PACKET sockets but not PF_PACKET sockets.
+ #
+ VALGRINDTEST_SRC=valgrindtest.c
+ elif test "$ac_cv_header_net_pfilt_h" = yes; then
+ #
+ # DEC OSF/1, Digital UNIX, Tru64 UNIX
+ #
+ V_PCAP=pf
+ elif test "$ac_cv_header_net_enet_h" = yes; then
+ #
+ # Stanford Enetfilter.
+ #
+ V_PCAP=enet
+ elif test "$ac_cv_header_net_nit_h" = yes; then
+ #
+ # SunOS 4.x STREAMS NIT.
+ #
+ V_PCAP=snit
+ elif test "$ac_cv_header_sys_net_nit_h" = yes; then
+ #
+ # Pre-SunOS 4.x non-STREAMS NIT.
+ #
+ V_PCAP=nit
+ elif test "$ac_cv_header_net_raw_h" = yes; then
+ #
+ # IRIX snoop.
+ #
+ V_PCAP=snoop
+ elif test "$ac_cv_header_sys_dlpi_h" = yes; then
+ #
+ # DLPI on pre-Solaris 11 SunOS 5, HP-UX, possibly others.
+ #
+ V_PCAP=dlpi
+ else
+ #
+ # Nothing we support.
+ #
+ V_PCAP=null
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cannot determine packet capture interface" >&5
+$as_echo "$as_me: WARNING: cannot determine packet capture interface" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: (see the INSTALL doc for more info)" >&5
+$as_echo "$as_me: WARNING: (see the INSTALL doc for more info)" >&2;}
+ fi
fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking packet capture type" >&5
+$as_echo_n "checking packet capture type... " >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $V_PCAP" >&5
$as_echo "$V_PCAP" >&6; }
@@ -5640,73 +6140,25 @@ $as_echo "$ac_cv_sys_dlpi_usable" >&6; }
fi
#
- # Check whether we have a /dev/dlpi device or have multiple devices.
+ # Check to see if Solaris has the dl_passive_req_t struct defined
+ # in <sys/dlpi.h>.
+ # This check is for DLPI support for passive modes.
+ # See dlpi(7P) for more details.
#
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for /dev/dlpi device" >&5
-$as_echo_n "checking for /dev/dlpi device... " >&6; }
- if test -c /dev/dlpi ; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
+ ac_fn_c_check_type "$LINENO" "dl_passive_req_t" "ac_cv_type_dl_passive_req_t" "
+ #include <sys/types.h>
+ #include <sys/dlpi.h>
-$as_echo "#define HAVE_DEV_DLPI 1" >>confdefs.h
-
- else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
- dir="/dev/dlpi"
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $dir directory" >&5
-$as_echo_n "checking for $dir directory... " >&6; }
- if test -d $dir ; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
+"
+if test "x$ac_cv_type_dl_passive_req_t" = xyes; then :
cat >>confdefs.h <<_ACEOF
-#define PCAP_DEV_PREFIX "$dir"
+#define HAVE_DL_PASSIVE_REQ_T 1
_ACEOF
- else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
- fi
- fi
-
- #
- # This check is for Solaris with DLPI support for passive modes.
- # See dlpi(7P) for more details.
- #
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if dl_passive_req_t struct exists" >&5
-$as_echo_n "checking if dl_passive_req_t struct exists... " >&6; }
- if ${ac_cv_lbl_has_dl_passive_req_t+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-# include <sys/types.h>
-# include <sys/dlpi.h>
-int
-main ()
-{
-u_int i = sizeof(dl_passive_req_t)
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_lbl_has_dl_passive_req_t=yes
-else
- ac_cv_lbl_has_dl_passive_req_t=no
fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lbl_has_dl_passive_req_t" >&5
-$as_echo "$ac_cv_lbl_has_dl_passive_req_t" >&6; }
- if test $ac_cv_lbl_has_dl_passive_req_t = yes ; then
-$as_echo "#define HAVE_DLPI_PASSIVE 1" >>confdefs.h
-
- fi
;;
linux)
@@ -5738,6 +6190,8 @@ done
# Check whether --with-libnl was given.
if test "${with_libnl+set}" = set; then :
withval=$with_libnl; with_libnl=$withval
+else
+ with_libnl=if_available
fi
@@ -5746,10 +6200,18 @@ fi
incdir=-I/usr/include/libnl3
libnldir=
- if test x$withval != x ; then
- libnldir=-L${withval}/lib/.libs
- incdir=-I${withval}/include
- fi
+ case "$with_libnl" in
+
+ yes|if_available)
+ ;;
+
+ *)
+ if test -d $withval; then
+ libnldir=-L${withval}/lib/.libs
+ incdir=-I${withval}/include
+ fi
+ ;;
+ esac
#
# Try libnl 3.x first.
@@ -5959,73 +6421,50 @@ fi
done
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if if_packet.h has tpacket_stats defined" >&5
-$as_echo_n "checking if if_packet.h has tpacket_stats defined... " >&6; }
- if ${ac_cv_lbl_tpacket_stats+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-# include <linux/if_packet.h>
-int
-main ()
-{
-struct tpacket_stats stats
- ;
- return 0;
-}
+ #
+ # Check to see if struct tpacket_stats is defined in
+ # <linux/if_packet.h>. If so, then pcap-linux.c can use this
+ # to report proper statistics.
+ #
+ # -Scott Barron
+ #
+ ac_fn_c_check_type "$LINENO" "struct tpacket_stats" "ac_cv_type_struct_tpacket_stats" "
+ #include <linux/if_packet.h>
+
+"
+if test "x$ac_cv_type_struct_tpacket_stats" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_TPACKET_STATS 1
_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_lbl_tpacket_stats=yes
-else
- ac_cv_lbl_tpacket_stats=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
fi
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lbl_tpacket_stats" >&5
-$as_echo "$ac_cv_lbl_tpacket_stats" >&6; }
- if test $ac_cv_lbl_tpacket_stats = yes; then
-$as_echo "#define HAVE_TPACKET_STATS 1" >>confdefs.h
+ #
+ # Check to see if the tpacket_auxdata struct has a tp_vlan_tci member.
+ #
+ # NOTE: any failure means we conclude that it doesn't have that
+ # member, so if we don't have tpacket_auxdata, we conclude it
+ # doesn't have that member (which is OK, as either we won't be
+ # using code that would use that member, or we wouldn't compile
+ # in any case).
+ ac_fn_c_check_member "$LINENO" "struct tpacket_auxdata" "tp_vlan_tci" "ac_cv_member_struct_tpacket_auxdata_tp_vlan_tci" "
+ #include <sys/types.h>
+ #include <linux/if_packet.h>
- fi
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if tpacket_auxdata struct has tp_vlan_tci member" >&5
-$as_echo_n "checking if tpacket_auxdata struct has tp_vlan_tci member... " >&6; }
- if ${ac_cv_lbl_linux_tpacket_auxdata_tp_vlan_tci+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
+"
+if test "x$ac_cv_member_struct_tpacket_auxdata_tp_vlan_tci" = xyes; then :
-# include <sys/types.h>
-# include <linux/if_packet.h>
-int
-main ()
-{
-u_int i = sizeof(((struct tpacket_auxdata *)0)->tp_vlan_tci)
- ;
- return 0;
-}
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_TPACKET_AUXDATA_TP_VLAN_TCI 1
_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_lbl_linux_tpacket_auxdata_tp_vlan_tci=yes
-else
- ac_cv_lbl_linux_tpacket_auxdata_tp_vlan_tci=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lbl_linux_tpacket_auxdata_tp_vlan_tci" >&5
-$as_echo "$ac_cv_lbl_linux_tpacket_auxdata_tp_vlan_tci" >&6; }
- if test $ac_cv_lbl_linux_tpacket_auxdata_tp_vlan_tci = yes ; then
- HAVE_LINUX_TPACKET_AUXDATA=tp_vlan_tci
-$as_echo "#define HAVE_LINUX_TPACKET_AUXDATA_TP_VLAN_TCI 1" >>confdefs.h
+fi
- fi
;;
bpf)
@@ -6045,46 +6484,16 @@ fi
done
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the system supports zerocopy BPF" >&5
-$as_echo_n "checking whether the system supports zerocopy BPF... " >&6; }
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <sys/socket.h>
- #include <sys/ioctl.h>
- #include <net/if.h>
- #include <net/bpf.h>
-int
-main ()
-{
-return (BIOCROTZBUF + BPF_BUFMODE_ZBUF);
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-
-$as_echo "#define HAVE_ZEROCOPY_BPF 1" >>confdefs.h
-
-
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-
- #
- # Check whether we have struct BPF_TIMEVAL.
- #
- ac_fn_c_check_type "$LINENO" "struct BPF_TIMEVAL" "ac_cv_type_struct_BPF_TIMEVAL" "
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#ifdef HAVE_SYS_IOCCOM_H
-#include <sys/ioccom.h>
-#endif
-#include <net/bpf.h>
+ #
+ # Check whether we have struct BPF_TIMEVAL.
+ #
+ ac_fn_c_check_type "$LINENO" "struct BPF_TIMEVAL" "ac_cv_type_struct_BPF_TIMEVAL" "
+ #include <sys/types.h>
+ #include <sys/ioctl.h>
+ #ifdef HAVE_SYS_IOCCOM_H
+ #include <sys/ioccom.h>
+ #endif
+ #include <net/bpf.h>
"
if test "x$ac_cv_type_struct_BPF_TIMEVAL" = xyes; then :
@@ -6126,10 +6535,10 @@ snf)
;;
null)
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cannot determine packet capture interface" >&5
-$as_echo "$as_me: WARNING: cannot determine packet capture interface" >&2;}
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: (see the INSTALL doc for more info)" >&5
-$as_echo "$as_me: WARNING: (see the INSTALL doc for more info)" >&2;}
+ ;;
+
+*)
+ as_fn_error $? "$V_PCAP is not a valid pcap type" "$LINENO" 5
;;
esac
@@ -6171,33 +6580,34 @@ fi
else
#
- # Well, we don't have "getifaddrs()", so we have to use
- # some other mechanism; determine what that mechanism is.
+ # Well, we don't have "getifaddrs()", at least not with the
+ # libraries with which we've decided we need to link
+ # libpcap with, so we have to use some other mechanism.
#
- # The first thing we use is the type of capture mechanism,
- # which is somewhat of a proxy for the OS we're using.
+ # Note that this may happen on Solaris, which has
+ # getifaddrs(), but in -lsocket, not in -lxnet, so we
+ # won't find it if we link with -lxnet, which we want
+ # to do for other reasons.
#
- case "$V_PCAP" in
-
- dlpi|libdlpi)
- #
- # This might be Solaris 8 or later, with
- # SIOCGLIFCONF, or it might be some other OS
- # or some older version of Solaris, with
- # just SIOCGIFCONF.
- #
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we have SIOCGLIFCONF" >&5
+ # For now, we use either the SIOCGIFCONF ioctl or the
+ # SIOCGLIFCONF ioctl, preferring the latter if we have
+ # it; the latter is a Solarisism that first appeared
+ # in Solaris 8. (Solaris's getifaddrs() appears to
+ # be built atop SIOCGLIFCONF; using it directly
+ # avoids a not-all-that-useful middleman.)
+ #
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we have SIOCGLIFCONF" >&5
$as_echo_n "checking whether we have SIOCGLIFCONF... " >&6; }
- if ${ac_cv_lbl_have_siocglifconf+:} false; then :
+ if ${ac_cv_lbl_have_siocglifconf+:} false; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <sys/param.h>
- #include <sys/file.h>
- #include <sys/ioctl.h>
- #include <sys/socket.h>
- #include <sys/sockio.h>
+ #include <sys/file.h>
+ #include <sys/ioctl.h>
+ #include <sys/socket.h>
+ #include <sys/sockio.h>
int
main ()
{
@@ -6214,119 +6624,91 @@ fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lbl_have_siocglifconf" >&5
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lbl_have_siocglifconf" >&5
$as_echo "$ac_cv_lbl_have_siocglifconf" >&6; }
- if test $ac_cv_lbl_have_siocglifconf = yes ; then
- V_FINDALLDEVS=fad-glifc.c
- else
- V_FINDALLDEVS=fad-gifc.c
- fi
- ;;
-
- *)
- #
- # Assume we just have SIOCGIFCONF.
- # (XXX - on at least later Linux kernels, there's
- # another mechanism, and we should be using that
- # instead.)
- #
+ if test $ac_cv_lbl_have_siocglifconf = yes ; then
+ V_FINDALLDEVS=fad-glifc.c
+ else
V_FINDALLDEVS=fad-gifc.c
- ;;
- esac
-fi
+ fi
fi
fi
+fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for socklen_t" >&5
-$as_echo_n "checking for socklen_t... " >&6; }
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
- #include <sys/types.h>
- #include <sys/socket.h>
-int
-main ()
-{
- socklen_t x;
- ;
- return 0;
-}
+case "$host_os" in
+linux*)
+ for ac_header in linux/net_tstamp.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "linux/net_tstamp.h" "ac_cv_header_linux_net_tstamp_h" "$ac_includes_default"
+if test "x$ac_cv_header_linux_net_tstamp_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LINUX_NET_TSTAMP_H 1
_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- have_socklen_t=yes
-else
- have_socklen_t=no
+
fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-if test "x$have_socklen_t" = "xyes"; then
-$as_echo "#define HAVE_SOCKLEN_T 1" >>confdefs.h
+done
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_socklen_t" >&5
-$as_echo "$have_socklen_t" >&6; }
+ ;;
+*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: no hardware timestamp support implemented for $host_os" >&5
+$as_echo "$as_me: no hardware timestamp support implemented for $host_os" >&6;}
+ ;;
+esac
-# Check whether --enable-ipv6 was given.
-if test "${enable_ipv6+set}" = set; then :
- enableval=$enable_ipv6;
+# Check whether --enable-packet-ring was given.
+if test "${enable_packet_ring+set}" = set; then :
+ enableval=$enable_packet_ring;
else
- enable_ipv6=ifavailable
+ enable_packet_ring=yes
fi
-if test "$enable_ipv6" != "no"; then
- ac_fn_c_check_func "$LINENO" "getaddrinfo" "ac_cv_func_getaddrinfo"
-if test "x$ac_cv_func_getaddrinfo" = xyes; then :
-
-
-$as_echo "#define INET6 1" >>confdefs.h
+if test "x$enable_packet_ring" != "xno" ; then
-else
+$as_echo "#define PCAP_SUPPORT_PACKET_RING 1" >>confdefs.h
- if test "$enable_ipv6" != "ifavailable"; then
- { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "--enable-ipv6 was given, but getaddrinfo isn't available
-See \`config.log' for more details" "$LINENO" 5; }
- fi
fi
-fi
+#
+# Check for socklen_t.
+#
+ac_fn_c_check_type "$LINENO" "socklen_t" "ac_cv_type_socklen_t" "
+ #include <sys/types.h>
+ #include <sys/socket.h>
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build optimizer debugging code" >&5
-$as_echo_n "checking whether to build optimizer debugging code... " >&6; }
-# Check whether --enable-optimizer-dbg was given.
-if test "${enable_optimizer_dbg+set}" = set; then :
- enableval=$enable_optimizer_dbg;
-fi
+"
+if test "x$ac_cv_type_socklen_t" = xyes; then :
-if test "$enable_optimizer_dbg" = "yes"; then
+cat >>confdefs.h <<_ACEOF
+#define HAVE_SOCKLEN_T 1
+_ACEOF
-$as_echo "#define BDEBUG 1" >>confdefs.h
fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${enable_optimizer_dbg-no}" >&5
-$as_echo "${enable_optimizer_dbg-no}" >&6; }
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build parser debugging code" >&5
-$as_echo_n "checking whether to build parser debugging code... " >&6; }
-# Check whether --enable-yydebug was given.
-if test "${enable_yydebug+set}" = set; then :
- enableval=$enable_yydebug;
+
+# Check whether --enable-ipv6 was given.
+if test "${enable_ipv6+set}" = set; then :
+ enableval=$enable_ipv6;
+else
+ enable_ipv6=yes
fi
-if test "$enable_yydebug" = "yes"; then
+if test "$enable_ipv6" != "no"; then
+ #
+ # We've already made sure we have getaddrinfo above in
+ # AC_LBL_LIBRARY_NET.
+ #
-$as_echo "#define YYDEBUG 1" >>confdefs.h
+$as_echo "#define INET6 1" >>confdefs.h
fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${enable_yydebug-no}" >&5
-$as_echo "${enable_yydebug-no}" >&6; }
# Check for Endace DAG card support.
@@ -6389,12 +6771,8 @@ if test "${with_dag_libraries+set}" = set; then :
fi
-ac_cv_lbl_dag_api=no
if test "$want_dag" != no; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we have DAG API headers" >&5
-$as_echo_n "checking whether we have DAG API headers... " >&6; }
-
# If necessary, set default paths for DAG API headers and libraries.
if test -z "$dag_root"; then
dag_root=/usr/local
@@ -6408,25 +6786,28 @@ $as_echo_n "checking whether we have DAG API headers... " >&6; }
dag_lib_dir="$dag_root/lib"
fi
- if test -z "$dag_tools_dir"; then
- dag_tools_dir="$dag_root/tools"
- fi
+ V_INCLS="$V_INCLS -I$dag_include_dir"
- if test -r $dag_include_dir/dagapi.h; then
- ac_cv_lbl_dag_api=yes
- fi
+ for ac_header in dagapi.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "dagapi.h" "ac_cv_header_dagapi_h" "$ac_includes_default"
+if test "x$ac_cv_header_dagapi_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_DAGAPI_H 1
+_ACEOF
- if test "$ac_cv_lbl_dag_api" = yes; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes ($dag_include_dir)" >&5
-$as_echo "yes ($dag_include_dir)" >&6; }
+fi
+
+done
- V_INCLS="$V_INCLS -I$dag_include_dir"
+
+ if test "$ac_cv_header_dagapi_h" = yes; then
if test $V_PCAP != dag ; then
SSRC="$SSRC pcap-dag.c"
fi
- # See if we can find a general version string.
+ # Check for various DAG API functions.
# Don't need to save and restore LIBS to prevent -ldag being
# included if there's a found-action (arg 3).
saved_ldflags=$LDFLAGS
@@ -6468,9 +6849,56 @@ fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dag_dag_attach_stream" >&5
$as_echo "$ac_cv_lib_dag_dag_attach_stream" >&6; }
if test "x$ac_cv_lib_dag_dag_attach_stream" = xyes; then :
- dag_streams="1"
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBDAG 1
+_ACEOF
+
+ LIBS="-ldag $LIBS"
+
else
- dag_streams="0"
+ as_fn_error $? "DAG library lacks streams support" "$LINENO" 5
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dag_attach_stream64 in -ldag" >&5
+$as_echo_n "checking for dag_attach_stream64 in -ldag... " >&6; }
+if ${ac_cv_lib_dag_dag_attach_stream64+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldag $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dag_attach_stream64 ();
+int
+main ()
+{
+return dag_attach_stream64 ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dag_dag_attach_stream64=yes
+else
+ ac_cv_lib_dag_dag_attach_stream64=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dag_dag_attach_stream64" >&5
+$as_echo "$ac_cv_lib_dag_dag_attach_stream64" >&6; }
+if test "x$ac_cv_lib_dag_dag_attach_stream64" = xyes; then :
+ dag_large_streams="1"
+else
+ dag_large_streams="0"
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for dag_get_erf_types in -ldag" >&5
@@ -6562,12 +6990,17 @@ fi
LDFLAGS=$saved_ldflags
- if test "$dag_streams" = 1; then
+ #
+ # We assume that if we have libdag we have libdagconf,
+ # as they're installed at the same time from the same
+ # package.
+ #
+ LIBS="$LIBS -ldag -ldagconf"
+ LDFLAGS="$LDFLAGS -L$dag_lib_dir"
-$as_echo "#define HAVE_DAG_STREAMS_API 1" >>confdefs.h
+ if test "$dag_large_streams" = 1; then
- LIBS="$LIBS -ldag"
- LDFLAGS="$LDFLAGS -L$dag_lib_dir"
+$as_echo "#define HAVE_DAG_LARGE_STREAMS_API 1" >>confdefs.h
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for vdag_set_device_info in -lvdag" >&5
$as_echo_n "checking for vdag_set_device_info in -lvdag... " >&6; }
@@ -6615,7 +7048,10 @@ fi
$as_echo "#define HAVE_DAG_VDAG 1" >>confdefs.h
- LIBS="$LIBS -lpthread"
+ if test "$ac_lbl_have_pthreads" != "found"; then
+ as_fn_error $? "DAG requires pthreads, but we didn't find them" "$LINENO" 5
+ fi
+ LIBS="$LIBS $PTHREAD_LIBS"
fi
fi
@@ -6623,8 +7059,6 @@ $as_echo "#define HAVE_DAG_VDAG 1" >>confdefs.h
$as_echo "#define HAVE_DAG_API 1" >>confdefs.h
else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
if test "$V_PCAP" = dag; then
# User requested "dag" capture type but we couldn't
@@ -6980,6 +7414,182 @@ $as_echo "no" >&6; }
fi
fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable remote packet capture" >&5
+$as_echo_n "checking whether to enable remote packet capture... " >&6; }
+# Check whether --enable-remote was given.
+if test "${enable_remote+set}" = set; then :
+ enableval=$enable_remote;
+else
+ enableval=no
+fi
+
+case "$enableval" in
+yes) { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Remote packet capture may expose libpcap-based applications" >&5
+$as_echo "$as_me: WARNING: Remote packet capture may expose libpcap-based applications" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: to attacks by malicious remote capture servers!" >&5
+$as_echo "$as_me: WARNING: to attacks by malicious remote capture servers!" >&2;}
+ #
+ # rpcapd requires pthreads on UN*X.
+ #
+ if test "$ac_lbl_have_pthreads" != "found"; then
+ as_fn_error $? "rpcapd requires pthreads, but we didn't find them" "$LINENO" 5
+ fi
+ #
+ # It also requires crypt().
+ # Do we have it in the system libraries?
+ #
+ ac_fn_c_check_func "$LINENO" "crypt" "ac_cv_func_crypt"
+if test "x$ac_cv_func_crypt" = xyes; then :
+
+else
+
+ #
+ # No. Do we have it in -lcrypt?
+ #
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for crypt in -lcrypt" >&5
+$as_echo_n "checking for crypt in -lcrypt... " >&6; }
+if ${ac_cv_lib_crypt_crypt+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcrypt $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char crypt ();
+int
+main ()
+{
+return crypt ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_crypt_crypt=yes
+else
+ ac_cv_lib_crypt_crypt=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypt_crypt" >&5
+$as_echo "$ac_cv_lib_crypt_crypt" >&6; }
+if test "x$ac_cv_lib_crypt_crypt" = xyes; then :
+
+ #
+ # Yes; add -lcrypt to the libraries for rpcapd.
+ #
+ RPCAPD_LIBS="$RPCAPD_LIBS -lcrypt"
+
+else
+
+ as_fn_error $? "rpcapd requires crypt(), but we didn't find it" "$LINENO" 5
+
+fi
+
+
+fi
+
+
+ #
+ # OK, we have crypt(). Do we have getspnam()?
+ #
+ for ac_func in getspnam
+do :
+ ac_fn_c_check_func "$LINENO" "getspnam" "ac_cv_func_getspnam"
+if test "x$ac_cv_func_getspnam" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_GETSPNAM 1
+_ACEOF
+
+fi
+done
+
+
+ #
+ # Check for various members of struct msghdr.
+ #
+ ac_fn_c_check_member "$LINENO" "struct msghdr" "msg_control" "ac_cv_member_struct_msghdr_msg_control" "
+ #include \"ftmacros.h\"
+ #include <sys/socket.h>
+
+"
+if test "x$ac_cv_member_struct_msghdr_msg_control" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_MSGHDR_MSG_CONTROL 1
+_ACEOF
+
+
+fi
+
+ ac_fn_c_check_member "$LINENO" "struct msghdr" "msg_flags" "ac_cv_member_struct_msghdr_msg_flags" "
+ #include \"ftmacros.h\"
+ #include <sys/socket.h>
+
+"
+if test "x$ac_cv_member_struct_msghdr_msg_flags" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_MSGHDR_MSG_FLAGS 1
+_ACEOF
+
+
+fi
+
+
+
+$as_echo "#define ENABLE_REMOTE /**/" >>confdefs.h
+
+ SSRC="$SSRC pcap-new.c pcap-rpcap.c rpcap-protocol.c sockutils.c"
+ BUILD_RPCAPD=build-rpcapd
+ INSTALL_RPCAPD=install-rpcapd
+ ;;
+*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ ;;
+esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build optimizer debugging code" >&5
+$as_echo_n "checking whether to build optimizer debugging code... " >&6; }
+# Check whether --enable-optimizer-dbg was given.
+if test "${enable_optimizer_dbg+set}" = set; then :
+ enableval=$enable_optimizer_dbg;
+fi
+
+if test "$enable_optimizer_dbg" = "yes"; then
+
+$as_echo "#define BDEBUG 1" >>confdefs.h
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${enable_optimizer_dbg-no}" >&5
+$as_echo "${enable_optimizer_dbg-no}" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build parser debugging code" >&5
+$as_echo_n "checking whether to build parser debugging code... " >&6; }
+# Check whether --enable-yydebug was given.
+if test "${enable_yydebug+set}" = set; then :
+ enableval=$enable_yydebug;
+fi
+
+if test "$enable_yydebug" = "yes"; then
+
+$as_echo "#define YYDEBUG 1" >>confdefs.h
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${enable_yydebug-no}" >&5
+$as_echo "${enable_yydebug-no}" >&6; }
+
#
# Look for {f}lex.
#
@@ -7238,13 +7848,17 @@ if test $tcpdump_cv_capable_yacc = insufficient ; then
fi
#
-# 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).
+# 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.
#
DYEXT="none"
MAN_FILE_FORMATS=5
MAN_MISC_INFO=7
+MAN_ADMIN_COMMANDS=8
case "$host_os" in
aix*)
@@ -7389,6 +8003,7 @@ $as_echo "#define HAVE_HPUX9 1" >>confdefs.h
#
# Use System V conventions for man pages.
#
+ MAN_ADMIN_COMMANDS=1m
MAN_FILE_FORMATS=4
MAN_MISC_INFO=5
;;
@@ -7398,6 +8013,7 @@ hpux10.0*)
#
# Use System V conventions for man pages.
#
+ MAN_ADMIN_COMMANDS=1m
MAN_FILE_FORMATS=4
MAN_MISC_INFO=5
;;
@@ -7407,6 +8023,7 @@ hpux10.1*)
#
# Use System V conventions for man pages.
#
+ MAN_ADMIN_COMMANDS=1m
MAN_FILE_FORMATS=4
MAN_MISC_INFO=5
;;
@@ -7436,7 +8053,9 @@ $as_echo "#define HAVE_HPUX10_20_OR_LATER 1" >>confdefs.h
irix*)
#
- # Use System V conventions for man pages.
+ # Use IRIX conventions for man pages; they're the same as the
+ # System V conventions, except that they use section 8 for
+ # administrative commands and daemons.
#
MAN_FILE_FORMATS=4
MAN_MISC_INFO=5
@@ -7458,7 +8077,10 @@ osf*)
DYEXT="so"
#
- # Use System V conventions for man pages.
+ # DEC OSF/1, a/k/a Digial UNIX, a/k/a Tru64 UNIX.
+ # Use Tru64 UNIX conventions for man pages; they're the same as
+ # the System V conventions except that they use section 8 for
+ # administrative commands and daemons.
#
MAN_FILE_FORMATS=4
MAN_MISC_INFO=5
@@ -7504,11 +8126,30 @@ $as_echo "#define HAVE_SOLARIS 1" >>confdefs.h
DYEXT="so"
+
#
- # Use System V conventions for man pages.
+ # Make sure errno is thread-safe, in case we're called in
+ # a multithreaded program. We don't guarantee that two
+ # threads can use the *same* pcap_t safely, but the
+ # current version does guarantee that you can use different
+ # pcap_t's in different threads, and even that pcap_compile()
+ # is thread-safe (it wasn't thread-safe in some older versions).
#
- MAN_FILE_FORMATS=4
- MAN_MISC_INFO=5
+ V_CCOPT="$V_CCOPT -D_TS_ERRNO"
+
+ case "`uname -r`" in
+
+ 5.12)
+ ;;
+
+ *)
+ #
+ # Use System V conventions for man pages.
+ #
+ MAN_ADMIN_COMMANDS=1m
+ MAN_FILE_FORMATS=4
+ MAN_MISC_INFO=5
+ esac
;;
esac
@@ -8063,6 +8704,310 @@ $as_echo "no" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports the -Wdocumentation option" >&5
+$as_echo_n "checking whether the compiler supports the -Wdocumentation option... " >&6; }
+ save_CFLAGS="$CFLAGS"
+ if expr "x-Wdocumentation" : "x-W.*" >/dev/null
+ then
+ CFLAGS="$CFLAGS $ac_lbl_unknown_warning_option_error -Wdocumentation"
+ elif expr "x-Wdocumentation" : "x-f.*" >/dev/null
+ then
+ CFLAGS="$CFLAGS -Werror -Wdocumentation"
+ elif expr "x-Wdocumentation" : "x-m.*" >/dev/null
+ then
+ CFLAGS="$CFLAGS -Werror -Wdocumentation"
+ else
+ CFLAGS="$CFLAGS -Wdocumentation"
+ fi
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+return 0
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ CFLAGS="$save_CFLAGS"
+ V_CCOPT="$V_CCOPT -Wdocumentation"
+
+else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ CFLAGS="$save_CFLAGS"
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports the -Wcomma option" >&5
+$as_echo_n "checking whether the compiler supports the -Wcomma option... " >&6; }
+ save_CFLAGS="$CFLAGS"
+ if expr "x-Wcomma" : "x-W.*" >/dev/null
+ then
+ CFLAGS="$CFLAGS $ac_lbl_unknown_warning_option_error -Wcomma"
+ elif expr "x-Wcomma" : "x-f.*" >/dev/null
+ then
+ CFLAGS="$CFLAGS -Werror -Wcomma"
+ elif expr "x-Wcomma" : "x-m.*" >/dev/null
+ then
+ CFLAGS="$CFLAGS -Werror -Wcomma"
+ else
+ CFLAGS="$CFLAGS -Wcomma"
+ fi
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+return 0
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ CFLAGS="$save_CFLAGS"
+ V_CCOPT="$V_CCOPT -Wcomma"
+
+else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ CFLAGS="$save_CFLAGS"
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports the -Wmissing-noreturn option" >&5
+$as_echo_n "checking whether the compiler supports the -Wmissing-noreturn option... " >&6; }
+ save_CFLAGS="$CFLAGS"
+ if expr "x-Wmissing-noreturn" : "x-W.*" >/dev/null
+ then
+ CFLAGS="$CFLAGS $ac_lbl_unknown_warning_option_error -Wmissing-noreturn"
+ elif expr "x-Wmissing-noreturn" : "x-f.*" >/dev/null
+ then
+ CFLAGS="$CFLAGS -Werror -Wmissing-noreturn"
+ elif expr "x-Wmissing-noreturn" : "x-m.*" >/dev/null
+ then
+ CFLAGS="$CFLAGS -Werror -Wmissing-noreturn"
+ else
+ CFLAGS="$CFLAGS -Wmissing-noreturn"
+ fi
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+return 0
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ CFLAGS="$save_CFLAGS"
+ V_CCOPT="$V_CCOPT -Wmissing-noreturn"
+
+else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ CFLAGS="$save_CFLAGS"
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+ # Warns about safeguards added in case the enums are
+ # extended
+ # AC_LBL_CHECK_COMPILER_OPT(V_CCOPT, -Wcovered-switch-default)
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports the -Wmissing-variable-declarations option" >&5
+$as_echo_n "checking whether the compiler supports the -Wmissing-variable-declarations option... " >&6; }
+ save_CFLAGS="$CFLAGS"
+ if expr "x-Wmissing-variable-declarations" : "x-W.*" >/dev/null
+ then
+ CFLAGS="$CFLAGS $ac_lbl_unknown_warning_option_error -Wmissing-variable-declarations"
+ elif expr "x-Wmissing-variable-declarations" : "x-f.*" >/dev/null
+ then
+ CFLAGS="$CFLAGS -Werror -Wmissing-variable-declarations"
+ elif expr "x-Wmissing-variable-declarations" : "x-m.*" >/dev/null
+ then
+ CFLAGS="$CFLAGS -Werror -Wmissing-variable-declarations"
+ else
+ CFLAGS="$CFLAGS -Wmissing-variable-declarations"
+ fi
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+return 0
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ CFLAGS="$save_CFLAGS"
+ V_CCOPT="$V_CCOPT -Wmissing-variable-declarations"
+
+else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ CFLAGS="$save_CFLAGS"
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports the -Wunused-parameter option" >&5
+$as_echo_n "checking whether the compiler supports the -Wunused-parameter option... " >&6; }
+ save_CFLAGS="$CFLAGS"
+ if expr "x-Wunused-parameter" : "x-W.*" >/dev/null
+ then
+ CFLAGS="$CFLAGS $ac_lbl_unknown_warning_option_error -Wunused-parameter"
+ elif expr "x-Wunused-parameter" : "x-f.*" >/dev/null
+ then
+ CFLAGS="$CFLAGS -Werror -Wunused-parameter"
+ elif expr "x-Wunused-parameter" : "x-m.*" >/dev/null
+ then
+ CFLAGS="$CFLAGS -Werror -Wunused-parameter"
+ else
+ CFLAGS="$CFLAGS -Wunused-parameter"
+ fi
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+return 0
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ CFLAGS="$save_CFLAGS"
+ V_CCOPT="$V_CCOPT -Wunused-parameter"
+
+else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ CFLAGS="$save_CFLAGS"
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports the -Wformat-nonliteral option" >&5
+$as_echo_n "checking whether the compiler supports the -Wformat-nonliteral option... " >&6; }
+ save_CFLAGS="$CFLAGS"
+ if expr "x-Wformat-nonliteral" : "x-W.*" >/dev/null
+ then
+ CFLAGS="$CFLAGS $ac_lbl_unknown_warning_option_error -Wformat-nonliteral"
+ elif expr "x-Wformat-nonliteral" : "x-f.*" >/dev/null
+ then
+ CFLAGS="$CFLAGS -Werror -Wformat-nonliteral"
+ elif expr "x-Wformat-nonliteral" : "x-m.*" >/dev/null
+ then
+ CFLAGS="$CFLAGS -Werror -Wformat-nonliteral"
+ else
+ CFLAGS="$CFLAGS -Wformat-nonliteral"
+ fi
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+return 0
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ CFLAGS="$save_CFLAGS"
+ V_CCOPT="$V_CCOPT -Wformat-nonliteral"
+
+else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ CFLAGS="$save_CFLAGS"
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports the -Wunreachable-code option" >&5
+$as_echo_n "checking whether the compiler supports the -Wunreachable-code option... " >&6; }
+ save_CFLAGS="$CFLAGS"
+ if expr "x-Wunreachable-code" : "x-W.*" >/dev/null
+ then
+ CFLAGS="$CFLAGS $ac_lbl_unknown_warning_option_error -Wunreachable-code"
+ elif expr "x-Wunreachable-code" : "x-f.*" >/dev/null
+ then
+ CFLAGS="$CFLAGS -Werror -Wunreachable-code"
+ elif expr "x-Wunreachable-code" : "x-m.*" >/dev/null
+ then
+ CFLAGS="$CFLAGS -Werror -Wunreachable-code"
+ else
+ CFLAGS="$CFLAGS -Wunreachable-code"
+ fi
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+return 0
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ CFLAGS="$save_CFLAGS"
+ V_CCOPT="$V_CCOPT -Wunreachable-code"
+
+else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ CFLAGS="$save_CFLAGS"
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports generating dependencies" >&5
@@ -8135,8 +9080,11 @@ $as_echo_n "checking whether the compiler supports generating dependencies... "
/* end confdefs.h. */
int main(void) { return 0; }
_ACEOF
- echo "$CC" $ac_lbl_dependency_flag conftest.c >&5
- if "$CC" $ac_lbl_dependency_flag conftest.c >/dev/null 2>&1; then
+ if { { $as_echo "$as_me:${as_lineno-$LINENO}: eval \"\$CC \$ac_lbl_dependency_flag conftest.c >/dev/null 2>&1\""; } >&5
+ (eval "$CC $ac_lbl_dependency_flag conftest.c >/dev/null 2>&1") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes, with $ac_lbl_dependency_flag" >&5
$as_echo "yes, with $ac_lbl_dependency_flag" >&6; }
DEPENDENCY_CFLAG="$ac_lbl_dependency_flag"
@@ -8148,7 +9096,7 @@ $as_echo "no" >&6; }
# We can't run mkdep, so have "make depend" do
# nothing.
#
- MKDEP=:
+ MKDEP='${srcdir}/nomkdep'
fi
rm -rf conftest*
else
@@ -8158,7 +9106,7 @@ $as_echo "no" >&6; }
# We can't run mkdep, so have "make depend" do
# nothing.
#
- MKDEP=:
+ MKDEP='${srcdir}/nomkdep'
fi
@@ -8184,108 +9132,68 @@ $as_echo "$as_me: WARNING: can't find $name" >&2;}
fi
fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if sockaddr struct has the sa_len member" >&5
-$as_echo_n "checking if sockaddr struct has the sa_len member... " >&6; }
- if ${ac_cv_lbl_sockaddr_has_sa_len+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
+#
+# Check to see if the sockaddr struct has the 4.4 BSD sa_len member.
+#
+ac_fn_c_check_member "$LINENO" "struct sockaddr" "sa_len" "ac_cv_member_struct_sockaddr_sa_len" "
+ #include <sys/types.h>
+ #include <sys/socket.h>
-# include <sys/types.h>
-# include <sys/socket.h>
-int
-main ()
-{
-u_int i = sizeof(((struct sockaddr *)0)->sa_len)
- ;
- return 0;
-}
+"
+if test "x$ac_cv_member_struct_sockaddr_sa_len" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_SOCKADDR_SA_LEN 1
_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_lbl_sockaddr_has_sa_len=yes
-else
- ac_cv_lbl_sockaddr_has_sa_len=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lbl_sockaddr_has_sa_len" >&5
-$as_echo "$ac_cv_lbl_sockaddr_has_sa_len" >&6; }
- if test $ac_cv_lbl_sockaddr_has_sa_len = yes ; then
-$as_echo "#define HAVE_SOCKADDR_SA_LEN 1" >>confdefs.h
+fi
- fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if sockaddr_storage struct exists" >&5
-$as_echo_n "checking if sockaddr_storage struct exists... " >&6; }
- if ${ac_cv_lbl_has_sockaddr_storage+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
+#
+# Check to see if there's a sockaddr_storage structure.
+#
+ac_fn_c_check_type "$LINENO" "struct sockaddr_storage" "ac_cv_type_struct_sockaddr_storage" "
+ #include <sys/types.h>
+ #include <sys/socket.h>
-# include <sys/types.h>
-# include <sys/socket.h>
-int
-main ()
-{
-u_int i = sizeof (struct sockaddr_storage)
- ;
- return 0;
-}
+"
+if test "x$ac_cv_type_struct_sockaddr_storage" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_SOCKADDR_STORAGE 1
_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_lbl_has_sockaddr_storage=yes
-else
- ac_cv_lbl_has_sockaddr_storage=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lbl_has_sockaddr_storage" >&5
-$as_echo "$ac_cv_lbl_has_sockaddr_storage" >&6; }
- if test $ac_cv_lbl_has_sockaddr_storage = yes ; then
-$as_echo "#define HAVE_SOCKADDR_STORAGE 1" >>confdefs.h
+fi
- fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if dl_hp_ppa_info_t struct has dl_module_id_1 member" >&5
-$as_echo_n "checking if dl_hp_ppa_info_t struct has dl_module_id_1 member... " >&6; }
- if ${ac_cv_lbl_dl_hp_ppa_info_t_has_dl_module_id_1+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
+#
+# Check to see if the dl_hp_ppa_info_t struct has the HP-UX 11.00
+# dl_module_id_1 member.
+#
+# NOTE: any failure means we conclude that it doesn't have that member,
+# so if we don't have DLPI, don't have a <sys/dlpi_ext.h> header, or
+# have one that doesn't declare a dl_hp_ppa_info_t type, we conclude
+# it doesn't have that member (which is OK, as either we won't be
+# using code that would use that member, or we wouldn't compile in
+# any case).
+#
+ac_fn_c_check_member "$LINENO" "dl_hp_ppa_info_t" "dl_module_id_1" "ac_cv_member_dl_hp_ppa_info_t_dl_module_id_1" "
+ #include <sys/types.h>
+ #include <sys/dlpi.h>
+ #include <sys/dlpi_ext.h>
-# include <sys/types.h>
-# include <sys/dlpi.h>
-# include <sys/dlpi_ext.h>
-int
-main ()
-{
-u_int i = sizeof(((dl_hp_ppa_info_t *)0)->dl_module_id_1)
- ;
- return 0;
-}
+"
+if test "x$ac_cv_member_dl_hp_ppa_info_t_dl_module_id_1" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DL_HP_PPA_INFO_T_DL_MODULE_ID_1 1
_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_lbl_dl_hp_ppa_info_t_has_dl_module_id_1=yes
-else
- ac_cv_lbl_dl_hp_ppa_info_t_has_dl_module_id_1=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lbl_dl_hp_ppa_info_t_has_dl_module_id_1" >&5
-$as_echo "$ac_cv_lbl_dl_hp_ppa_info_t_has_dl_module_id_1" >&6; }
- if test $ac_cv_lbl_dl_hp_ppa_info_t_has_dl_module_id_1 = yes ; then
-$as_echo "#define HAVE_HP_PPA_INFO_T_DL_MODULE_ID_1 1" >>confdefs.h
+fi
- fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if unaligned accesses fail" >&5
$as_echo_n "checking if unaligned accesses fail... " >&6; }
@@ -8382,8 +9290,12 @@ $as_echo "#define LBL_ALIGN 1" >>confdefs.h
fi
-rm -f net
-ln -s ${srcdir}/bpf/net net
+
+
+
+
+
+
@@ -8493,45 +9405,23 @@ done
# "value", rather than "bRequestType", "bRequest", and
# "wValue".
#
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if usbdevfs_ctrltransfer struct has bRequestType member" >&5
-$as_echo_n "checking if usbdevfs_ctrltransfer struct has bRequestType member... " >&6; }
- if ${ac_cv_usbdevfs_ctrltransfer_has_bRequestType+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
+ ac_fn_c_check_member "$LINENO" "struct usbdevfs_ctrltransfer" "bRequestType" "ac_cv_member_struct_usbdevfs_ctrltransfer_bRequestType" "
+ $ac_includes_default
+ #ifdef HAVE_LINUX_COMPILER_H
+ #include <linux/compiler.h>
+ #endif
+ #include <linux/usbdevice_fs.h>
-$ac_includes_default
-#ifdef HAVE_SYS_BITYPES_H
-#include <sys/bitypes.h>
-#endif
-#ifdef HAVE_LINUX_COMPILER_H
-#include <linux/compiler.h>
-#endif
-#include <linux/usbdevice_fs.h>
-int
-main ()
-{
-u_int i = sizeof(((struct usbdevfs_ctrltransfer *)0)->bRequestType)
- ;
- return 0;
-}
+"
+if test "x$ac_cv_member_struct_usbdevfs_ctrltransfer_bRequestType" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_USBDEVFS_CTRLTRANSFER_BREQUESTTYPE 1
_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_usbdevfs_ctrltransfer_has_bRequestType=yes
-else
- ac_cv_usbdevfs_ctrltransfer_has_bRequestType=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_usbdevfs_ctrltransfer_has_bRequestType" >&5
-$as_echo "$ac_cv_usbdevfs_ctrltransfer_has_bRequestType" >&6; }
- if test $ac_cv_usbdevfs_ctrltransfer_has_bRequestType = yes ; then
-$as_echo "#define HAVE_USBDEVFS_CTRLTRANSFER_BREQUESTTYPE 1" >>confdefs.h
+fi
- fi
fi
;;
freebsd*)
@@ -8619,6 +9509,61 @@ fi
+# Check whether --enable-netmap was given.
+if test "${enable_netmap+set}" = set; then :
+ enableval=$enable_netmap;
+else
+ enable_netmap=yes
+fi
+
+
+if test "x$enable_netmap" != "xno" ; then
+ #
+ # Check whether net/netmap_user.h is usable if NETMAP_WITH_LIBS is
+ # defined; it's not usable on DragonFly BSD 4.6 if NETMAP_WITH_LIBS
+ # is defined, for example, as it includes a non-existent malloc.h
+ # header.
+ #
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we can compile the netmap support" >&5
+$as_echo_n "checking whether we can compile the netmap support... " >&6; }
+ if ${ac_cv_net_netmap_user_can_compile+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+$ac_includes_default
+#define NETMAP_WITH_LIBS
+#include <net/netmap_user.h>
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_net_netmap_user_can_compile=yes
+else
+ ac_cv_net_netmap_user_can_compile=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_net_netmap_user_can_compile" >&5
+$as_echo "$ac_cv_net_netmap_user_can_compile" >&6; }
+ if test $ac_cv_net_netmap_user_can_compile = yes ; then
+
+$as_echo "#define PCAP_SUPPORT_NETMAP 1" >>confdefs.h
+
+ NETMAP_SRC=pcap-netmap.c
+ fi
+
+
+fi
+
+
# Check whether --enable-bluetooth was given.
if test "${enable_bluetooth+set}" = set; then :
enableval=$enable_bluetooth;
@@ -8639,112 +9584,102 @@ if test "x$enable_bluetooth" != "xno" ; then
ac_fn_c_check_header_mongrel "$LINENO" "bluetooth/bluetooth.h" "ac_cv_header_bluetooth_bluetooth_h" "$ac_includes_default"
if test "x$ac_cv_header_bluetooth_bluetooth_h" = xyes; then :
+ #
+ # We have bluetooth.h, so we support Bluetooth
+ # sniffing.
+ #
$as_echo "#define PCAP_SUPPORT_BT 1" >>confdefs.h
- BT_SRC=pcap-bt-linux.c
- { $as_echo "$as_me:${as_lineno-$LINENO}: Bluetooth sniffing is supported" >&5
+ BT_SRC=pcap-bt-linux.c
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Bluetooth sniffing is supported" >&5
$as_echo "$as_me: Bluetooth sniffing is supported" >&6;}
+ ac_lbl_bluetooth_available=yes
- #
- # OK, does struct sockaddr_hci have an hci_channel
- # member?
- #
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if struct sockaddr_hci has hci_channel member" >&5
-$as_echo_n "checking if struct sockaddr_hci has hci_channel member... " >&6; }
- if ${ac_cv_lbl_sockaddr_hci_has_hci_channel+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
+ #
+ # OK, does struct sockaddr_hci have an hci_channel
+ # member?
+ #
+ ac_fn_c_check_member "$LINENO" "struct sockaddr_hci" "hci_channel" "ac_cv_member_struct_sockaddr_hci_hci_channel" "
+ #include <bluetooth/bluetooth.h>
+ #include <bluetooth/hci.h>
-#include <bluetooth/bluetooth.h>
-#include <bluetooth/hci.h>
+"
+if test "x$ac_cv_member_struct_sockaddr_hci_hci_channel" = xyes; then :
-int
-main ()
-{
-u_int i = sizeof(((struct sockaddr_hci *)0)->hci_channel)
- ;
- return 0;
-}
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_SOCKADDR_HCI_HCI_CHANNEL 1
_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_lbl_sockaddr_hci_has_hci_channel=yes
-else
- ac_cv_lbl_sockaddr_hci_has_hci_channel=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lbl_sockaddr_hci_has_hci_channel" >&5
-$as_echo "$ac_cv_lbl_sockaddr_hci_has_hci_channel" >&6; }
- if test $ac_cv_lbl_sockaddr_hci_has_hci_channel = yes ; then
-$as_echo "#define SOCKADDR_HCI_HAS_HCI_CHANNEL /**/" >>confdefs.h
-
- #
- # OK, is HCI_CHANNEL_MONITOR defined?
- #
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if HCI_CHANNEL_MONITOR is defined" >&5
+ #
+ # Yes; is HCI_CHANNEL_MONITOR defined?
+ #
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if HCI_CHANNEL_MONITOR is defined" >&5
$as_echo_n "checking if HCI_CHANNEL_MONITOR is defined... " >&6; }
- if ${ac_cv_lbl_hci_channel_monitor_is_defined+:} false; then :
+ if ${ac_cv_lbl_hci_channel_monitor_is_defined+:} false; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-#include <bluetooth/bluetooth.h>
-#include <bluetooth/hci.h>
+ #include <bluetooth/bluetooth.h>
+ #include <bluetooth/hci.h>
int
main ()
{
-u_int i = HCI_CHANNEL_MONITOR
+
+ u_int i = HCI_CHANNEL_MONITOR;
+
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_lbl_hci_channel_monitor_is_defined=yes
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define PCAP_SUPPORT_BT_MONITOR /**/" >>confdefs.h
+
+ BT_MONITOR_SRC=pcap-bt-monitor-linux.c
+
else
- ac_cv_lbl_hci_channel_monitor_is_defined=no
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lbl_hci_channel_monitor_is_defined" >&5
-$as_echo "$ac_cv_lbl_hci_channel_monitor_is_defined" >&6; }
- if test $ac_cv_lbl_hci_channel_monitor_is_defined = yes ; then
-$as_echo "#define PCAP_SUPPORT_BT_MONITOR /**/" >>confdefs.h
+fi
- BT_MONITOR_SRC=pcap-bt-monitor-linux.c
- fi
- fi
- ac_lbl_bluetooth_available=yes
else
- ac_lbl_bluetooth_available=no
+
+ #
+ # We don't have bluetooth.h, so we don't support
+ # Bluetooth sniffing.
+ #
+ if test "x$enable_bluetooth" = "xyes" ; then
+ as_fn_error $? "Bluetooth sniffing is not supported; install bluez-lib devel to enable it" "$LINENO" 5
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Bluetooth sniffing is not supported; install bluez-lib devel to enable it" >&5
+$as_echo "$as_me: Bluetooth sniffing is not supported; install bluez-lib devel to enable it" >&6;}
+ fi
fi
- if test "x$ac_lbl_bluetooth_available" == "xno" ; then
- if test "x$enable_bluetooth" = "xyes" ; then
- as_fn_error $? "Bluetooth sniffing is not supported; install bluez-lib devel to enable it" "$LINENO" 5
- else
- { $as_echo "$as_me:${as_lineno-$LINENO}: Bluetooth sniffing is not supported; install bluez-lib devel to enable it" >&5
-$as_echo "$as_me: Bluetooth sniffing is not supported; install bluez-lib devel to enable it" >&6;}
- fi
- fi
;;
*)
if test "x$enable_bluetooth" = "xyes" ; then
- as_fn_error $? "no Bluetooth sniffing support implemented for $host_os" "$LINENO" 5
+ as_fn_error $? "no Bluetooth sniffing support implemented for $host_os" "$LINENO" 5
else
- { $as_echo "$as_me:${as_lineno-$LINENO}: no Bluetooth sniffing support implemented for $host_os" >&5
+ { $as_echo "$as_me:${as_lineno-$LINENO}: no Bluetooth sniffing support implemented for $host_os" >&5
$as_echo "$as_me: no Bluetooth sniffing support implemented for $host_os" >&6;}
fi
;;
@@ -8774,20 +9709,20 @@ if test "x$enable_dbus" != "xno"; then
darwin*)
#
- # We don't support D-Bus sniffing on OS X; see
+ # We don't support D-Bus sniffing on macOS; see
#
# https://bugs.freedesktop.org/show_bug.cgi?id=74029
#
# The user requested it, so fail.
#
- as_fn_error $? "Due to freedesktop.org bug 74029, D-Bus capture support is not available on OS X" "$LINENO" 5
+ as_fn_error $? "Due to freedesktop.org bug 74029, D-Bus capture support is not available on macOS" "$LINENO" 5
esac
else
case "$host_os" in
darwin*)
#
- # We don't support D-Bus sniffing on OS X; see
+ # We don't support D-Bus sniffing on macOS; see
#
# https://bugs.freedesktop.org/show_bug.cgi?id=74029
#
@@ -8904,38 +9839,117 @@ $as_echo "no" >&6; }
fi
-case "$host_os" in
-linux*)
- for ac_header in linux/net_tstamp.h
-do :
- ac_fn_c_check_header_mongrel "$LINENO" "linux/net_tstamp.h" "ac_cv_header_linux_net_tstamp_h" "$ac_includes_default"
-if test "x$ac_cv_header_linux_net_tstamp_h" = xyes; then :
- cat >>confdefs.h <<_ACEOF
-#define HAVE_LINUX_NET_TSTAMP_H 1
-_ACEOF
+# Check whether --enable-rdma was given.
+if test "${enable_rdma+set}" = set; then :
+ enableval=$enable_rdma;
+else
+ enable_rdmasniff=ifavailable
+fi
+
+if test "xxx_only" = yes; then
+ # User requested something-else-only pcap, so they don't
+ # want RDMA support.
+ enable_rdmasniff=no
fi
-done
+if test "x$enable_rdmasniff" != "xno"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ibv_get_device_list in -libverbs" >&5
+$as_echo_n "checking for ibv_get_device_list in -libverbs... " >&6; }
+if ${ac_cv_lib_ibverbs_ibv_get_device_list+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-libverbs $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
- ;;
-*)
- { $as_echo "$as_me:${as_lineno-$LINENO}: no hardware timestamp support implemented for $host_os" >&5
-$as_echo "$as_me: no hardware timestamp support implemented for $host_os" >&6;}
- ;;
-esac
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char ibv_get_device_list ();
+int
+main ()
+{
+return ibv_get_device_list ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_ibverbs_ibv_get_device_list=yes
+else
+ ac_cv_lib_ibverbs_ibv_get_device_list=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ibverbs_ibv_get_device_list" >&5
+$as_echo "$ac_cv_lib_ibverbs_ibv_get_device_list" >&6; }
+if test "x$ac_cv_lib_ibverbs_ibv_get_device_list" = xyes; then :
+
+ ac_fn_c_check_header_mongrel "$LINENO" "infiniband/verbs.h" "ac_cv_header_infiniband_verbs_h" "$ac_includes_default"
+if test "x$ac_cv_header_infiniband_verbs_h" = xyes; then :
+
+ #
+ # ibv_create_flow may be defined as a static inline
+ # function in infiniband/verbs.h, so we can't
+ # use AC_CHECK_LIB.
+ #
+ # Too bad autoconf has no AC_SYMBOL_EXISTS()
+ # macro that works like CMake's check_symbol_exists()
+ # function, to check do a compile check like
+ # this (they do a clever trick to avoid having
+ # to know the function's signature).
+ #
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether libibverbs defines ibv_create_flow" >&5
+$as_echo_n "checking whether libibverbs defines ibv_create_flow... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <infiniband/verbs.h>
+
+int
+main ()
+{
+
+ (void) ibv_create_flow((struct ibv_qp *) NULL,
+ (struct ibv_flow_attr *) NULL);
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define PCAP_SUPPORT_RDMASNIFF /**/" >>confdefs.h
+
+ RDMA_SRC=pcap-rdmasniff.c
+ LIBS="-libverbs $LIBS"
-# Check whether --enable-packet-ring was given.
-if test "${enable_packet_ring+set}" = set; then :
- enableval=$enable_packet_ring;
else
- enable_packet_ring=yes
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+
fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
-if test "x$enable_packet_ring" != "xno" ; then
-$as_echo "#define PCAP_SUPPORT_PACKET_RING 1" >>confdefs.h
+
+fi
+
fi
@@ -9039,7 +10053,7 @@ ac_config_headers="$ac_config_headers config.h"
ac_config_commands="$ac_config_commands default-1"
-ac_config_files="$ac_config_files Makefile pcap-filter.manmisc pcap-linktype.manmisc pcap-tstamp.manmisc pcap-savefile.manfile pcap.3pcap pcap_compile.3pcap pcap_datalink.3pcap pcap_dump_open.3pcap pcap_get_tstamp_precision.3pcap pcap_list_datalinks.3pcap pcap_list_tstamp_types.3pcap pcap_open_dead.3pcap pcap_open_offline.3pcap pcap_set_tstamp_precision.3pcap pcap_set_tstamp_type.3pcap"
+ac_config_files="$ac_config_files Makefile pcap-filter.manmisc pcap-linktype.manmisc pcap-tstamp.manmisc pcap-savefile.manfile pcap.3pcap pcap_compile.3pcap pcap_datalink.3pcap pcap_dump_open.3pcap pcap_get_tstamp_precision.3pcap pcap_list_datalinks.3pcap pcap_list_tstamp_types.3pcap pcap_open_dead.3pcap pcap_open_offline.3pcap pcap_set_tstamp_precision.3pcap pcap_set_tstamp_type.3pcap rpcapd/Makefile rpcapd/rpcapd.manadmin testprogs/Makefile"
cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
@@ -9547,7 +10561,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by $as_me, which was
+This file was extended by pcap $as_me 1.9.0-PRE-GIT, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -9613,7 +10627,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-config.status
+pcap config.status 1.9.0-PRE-GIT
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
@@ -9758,6 +10772,9 @@ do
"pcap_open_offline.3pcap") CONFIG_FILES="$CONFIG_FILES pcap_open_offline.3pcap" ;;
"pcap_set_tstamp_precision.3pcap") CONFIG_FILES="$CONFIG_FILES pcap_set_tstamp_precision.3pcap" ;;
"pcap_set_tstamp_type.3pcap") CONFIG_FILES="$CONFIG_FILES pcap_set_tstamp_type.3pcap" ;;
+ "rpcapd/Makefile") CONFIG_FILES="$CONFIG_FILES rpcapd/Makefile" ;;
+ "rpcapd/rpcapd.manadmin") CONFIG_FILES="$CONFIG_FILES rpcapd/rpcapd.manadmin" ;;
+ "testprogs/Makefile") CONFIG_FILES="$CONFIG_FILES testprogs/Makefile" ;;
*) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
esac
@@ -10315,7 +11332,7 @@ $as_echo "$as_me: executing $ac_file commands" >&6;}
case $ac_file$ac_mode in
"default-1":C) if test -f .devel; then
echo timestamp > stamp-h
- cat Makefile-devel-adds >> Makefile
+ cat $srcdir/Makefile-devel-adds >> Makefile
make depend
fi ;;
diff --git a/contrib/libpcap/configure.ac b/contrib/libpcap/configure.ac
index da2f940da963f..2a9c8e95e19ee 100644
--- a/contrib/libpcap/configure.ac
+++ b/contrib/libpcap/configure.ac
@@ -14,80 +14,23 @@ dnl
# config.sub.
#
-AC_PREREQ(2.61)
-AC_INIT(pcap.c)
+AC_PREREQ(2.64)
+
+AC_INIT(pcap, m4_esyscmd_s([cat VERSION]))
+AC_CONFIG_SRCDIR(pcap.c)
+AC_SUBST(PACKAGE_NAME)
AC_CANONICAL_SYSTEM
AC_LBL_C_INIT_BEFORE_CC(V_CCOPT, V_INCLS)
-AC_PROG_CC
+#
+# Try to enable as many C99 features as we can.
+# At minimum, we want C++/C99-style // comments.
+#
+AC_PROG_CC_C99
AC_LBL_C_INIT(V_CCOPT, V_INCLS)
AC_LBL_SHLIBS_INIT
AC_LBL_C_INLINE
-AC_C___ATTRIBUTE__
-if test "$ac_cv___attribute__" = "yes"; then
- AC_C___ATTRIBUTE___UNUSED
- AC_C___ATTRIBUTE___FORMAT
-fi
-
-AC_CHECK_HEADERS(sys/bitypes.h)
-
-AC_CHECK_TYPE([int8_t], ,
- [AC_DEFINE([int8_t], [signed char],
- [Define to `signed char' if int8_t not defined.])],
- [AC_INCLUDES_DEFAULT
-#ifdef HAVE_SYS_BITYPES_H
-#include <sys/bitypes.h>
-#endif])
-AC_CHECK_TYPE([u_int8_t], ,
- [AC_DEFINE([u_int8_t], [unsigned char],
- [Define to `unsigned char' if u_int8_t not defined.])],
- [AC_INCLUDES_DEFAULT
-#ifdef HAVE_SYS_BITYPES_H
-#include <sys/bitypes.h>
-#endif])
-AC_CHECK_TYPE([int16_t], ,
- [AC_DEFINE([int16_t], [short],
- [Define to `short' if int16_t not defined.])]
- [AC_INCLUDES_DEFAULT
-#ifdef HAVE_SYS_BITYPES_H
-#include <sys/bitypes.h>
-#endif])
-AC_CHECK_TYPE([u_int16_t], ,
- [AC_DEFINE([u_int16_t], [unsigned short],
- [Define to `unsigned short' if u_int16_t not defined.])],
- [AC_INCLUDES_DEFAULT
-#ifdef HAVE_SYS_BITYPES_H
-#include <sys/bitypes.h>
-#endif])
-AC_CHECK_TYPE([int32_t], ,
- [AC_DEFINE([int32_t], [int],
- [Define to `int' if int32_t not defined.])],
- [AC_INCLUDES_DEFAULT
-#ifdef HAVE_SYS_BITYPES_H
-#include <sys/bitypes.h>
-#endif])
-AC_CHECK_TYPE([u_int32_t], ,
- [AC_DEFINE([u_int32_t], [unsigned int],
- [Define to `unsigned int' if u_int32_t not defined.])],
- [AC_INCLUDES_DEFAULT
-#ifdef HAVE_SYS_BITYPES_H
-#include <sys/bitypes.h>
-#endif])
-AC_CHECK_TYPE([int64_t], ,
- [AC_DEFINE([int64_t], [long long],
- [Define to `long long' if int64_t not defined.])],
- [AC_INCLUDES_DEFAULT
-#ifdef HAVE_SYS_BITYPES_H
-#include <sys/bitypes.h>
-#endif])
-AC_CHECK_TYPE([u_int64_t], ,
- [AC_DEFINE([u_int64_t], [unsigned long long],
- [Define to `unsigned long long' if u_int64_t not defined.])],
- [AC_INCLUDES_DEFAULT
-#ifdef HAVE_SYS_BITYPES_H
-#include <sys/bitypes.h>
-#endif])
#
# Try to arrange for large file support.
@@ -104,9 +47,8 @@ dnl in "aclocal.m4" uses it, so we would still have to test for it
dnl and set "HAVE_SYS_IOCCOM_H" if we have it, otherwise
dnl "AC_LBL_FIXINCLUDES" wouldn't work on some platforms such as Solaris.
dnl
-AC_CHECK_HEADERS(sys/ioccom.h sys/select.h sys/sockio.h limits.h)
-AC_CHECK_HEADERS(linux/types.h)
-AC_CHECK_HEADERS(linux/if_packet.h netpacket/packet.h netpacket/if_packet.h)
+AC_CHECK_HEADERS(sys/ioccom.h sys/sockio.h limits.h)
+AC_CHECK_HEADERS(netpacket/packet.h)
AC_CHECK_HEADERS(net/pfvar.h, , , [#include <sys/types.h>
#include <sys/socket.h>
#include <net/if.h>])
@@ -128,25 +70,6 @@ if test "$ac_cv_header_net_pfvar_h" = yes; then
],
AC_MSG_RESULT(no))
fi
-AC_CHECK_HEADERS(netinet/if_ether.h, , , [#include <sys/types.h>
-#include <sys/socket.h>])
-if test "$ac_cv_header_netinet_if_ether_h" != yes; then
- #
- # The simple test didn't work.
- # Do we need to include <net/if.h> first?
- # Unset ac_cv_header_netinet_if_ether_h so we don't
- # treat the previous failure as a cached value and
- # suppress the next test.
- #
- AC_MSG_NOTICE([Rechecking with some additional includes])
- unset ac_cv_header_netinet_if_ether_h
- AC_CHECK_HEADERS(netinet/if_ether.h, , , [#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-struct mbuf;
-struct rtentry;
-#include <net/if.h>])
-fi
case "$host_os" in
linux*|uclinux*)
@@ -160,7 +83,7 @@ esac
AC_LBL_FIXINCLUDES
-AC_CHECK_FUNCS(strerror strlcpy)
+AC_CHECK_FUNCS(strerror strerror_r strerror_s strlcpy strlcat)
needsnprintf=no
AC_CHECK_FUNCS(vsnprintf snprintf,,
@@ -177,45 +100,225 @@ if test $needstrtok_r = yes; then
fi
#
+# Do we have ffs(), and is it declared in <strings.h>?
+#
+AC_CHECK_FUNCS(ffs)
+if test "$ac_cv_func_ffs" = yes; then
+ #
+ # We have ffs(); is it declared in <strings.h>?
+ #
+ # This test fails if we don't have <strings.h> or if we do
+ # but it doesn't declare ffs().
+ #
+ AC_CHECK_DECL(ffs,
+ [
+ AC_DEFINE(STRINGS_H_DECLARES_FFS,,
+ [Define to 1 if strings.h declares `ffs'])
+ ],,
+ [
+#include <strings.h>
+ ])
+fi
+
+#
# Do this before checking for ether_hostton(), as it's a
-# "gethostbyname() -ish function".
+# "getaddrinfo()-ish function".
#
AC_LBL_LIBRARY_NET
#
+# Check for reentrant versions of getnetbyname_r(), as provided by
+# Linux (glibc), Solaris/IRIX, and AIX (with three different APIs!).
+# If we don't find one, we just use getnetbyname(), which uses
+# thread-specific data on many platforms, but doesn't use it on
+# NetBSD or OpenBSD, and may not use it on older versions of other
+# platforms.
+#
+# Only do the check if we have a declaration of getnetbyname_r();
+# without it, we can't check which API it has. (We assume that
+# if there's a declaration, it has a prototype, so that the API
+# can be checked.)
+#
+AC_CHECK_DECL(getnetbyname_r,
+ [
+ AC_MSG_CHECKING([for the Linux getnetbyname_r()])
+ AC_TRY_LINK(
+ [#include <netdb.h>],
+ [
+ struct netent netent_buf;
+ char buf[1024];
+ struct netent *resultp;
+ int h_errnoval;
+
+ return getnetbyname_r((const char *)0, &netent_buf, buf, sizeof buf, &resultp, &h_errnoval);
+ ],
+ [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_LINUX_GETNETBYNAME_R, 1,
+ [define if we have the Linux getnetbyname_r()])
+ ],
+ [
+ AC_MSG_RESULT(no)
+
+ AC_MSG_CHECKING([for Solaris/IRIX getnetbyname_r()])
+ AC_TRY_LINK(
+ [#include <netdb.h>],
+ [
+ struct netent netent_buf;
+ char buf[1024];
+
+ return getnetbyname_r((const char *)0, &netent_buf, buf, (int)sizeof buf) != NULL;
+ ],
+ [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_SOLARIS_IRIX_GETNETBYNAME_R, 1,
+ [define if we have the Solaris/IRIX getnetbyname_r()])
+ ],
+ [
+ AC_MSG_RESULT(no)
+
+ AC_MSG_CHECKING([for AIX getnetbyname_r()])
+ AC_TRY_LINK(
+ [#include <netdb.h>],
+ [
+ struct netent netent_buf;
+ struct netent_data net_data;
+
+ return getnetbyname_r((const char *)0, &netent_buf, &net_data);
+ ],
+ [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_AIX_GETNETBYNAME_R, 1,
+ [define if we have the AIX getnetbyname_r()])
+ ],
+ [
+ AC_MSG_RESULT(no)
+ ])
+ ])
+ ])
+ ],,[#include <netdb.h>])
+
+#
+# Check for reentrant versions of getprotobyname_r(), as provided by
+# Linux (glibc), Solaris/IRIX, and AIX (with three different APIs!).
+# If we don't find one, we just use getprotobyname(), which uses
+# thread-specific data on many platforms, but doesn't use it on
+# NetBSD or OpenBSD, and may not use it on older versions of other
+# platforms.
+#
+# Only do the check if we have a declaration of getprotobyname_r();
+# without it, we can't check which API it has. (We assume that
+# if there's a declaration, it has a prototype, so that the API
+# can be checked.)
+#
+AC_CHECK_DECL(getprotobyname_r,
+ [
+ AC_MSG_CHECKING([for the Linux getprotobyname_r()])
+ AC_TRY_LINK(
+ [#include <netdb.h>],
+ [
+ struct protoent protoent_buf;
+ char buf[1024];
+ struct protoent *resultp;
+
+ return getprotobyname_r((const char *)0, &protoent_buf, buf, sizeof buf, &resultp);
+ ],
+ [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_LINUX_GETPROTOBYNAME_R, 1,
+ [define if we have the Linux getprotobyname_r()])
+ ],
+ [
+ AC_MSG_RESULT(no)
+
+ AC_MSG_CHECKING([for Solaris/IRIX getprotobyname_r()])
+ AC_TRY_LINK(
+ [#include <netdb.h>],
+ [
+ struct protoent protoent_buf;
+ char buf[1024];
+
+ return getprotobyname_r((const char *)0, &protoent_buf, buf, (int)sizeof buf) != NULL;
+ ],
+ [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_SOLARIS_IRIX_GETPROTOBYNAME_R, 1,
+ [define if we have the Solaris/IRIX getprotobyname_r()])
+ ],
+ [
+ AC_MSG_RESULT(no)
+
+ AC_MSG_CHECKING([for AIX getprotobyname_r()])
+ AC_TRY_LINK(
+ [#include <netdb.h>],
+ [
+ struct protoent protoent_buf;
+ struct protoent_data proto_data;
+
+ return getprotobyname_r((const char *)0, &protoent_buf, &proto_data);
+ ],
+ [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_AIX_GETPROTOBYNAME_R, 1,
+ [define if we have the AIX getprotobyname_r()])
+ ],
+ [
+ AC_MSG_RESULT(no)
+ ])
+ ])
+ ])
+ ],,[#include <netdb.h>])
+
+#
# You are in a twisty little maze of UN*Xes, all different.
# Some might not have ether_hostton().
-# Some might have it, but not declare it in any header file.
-# Some might have it, but declare it in <netinet/if_ether.h>.
-# Some might have it, but declare it in <netinet/ether.h>
-# (And some might have it but document it as something declared in
-# <netinet/ethernet.h>, although <netinet/if_ether.h> appears to work.)
+# Some might have it and declare it in <net/ethernet.h>.
+# Some might have it and declare it in <netinet/ether.h>
+# Some might have it and declare it in <sys/ethernet.h>.
+# Some might have it and declare it in <arpa/inet.h>.
+# Some might have it and declare it in <netinet/if_ether.h>.
+# Some might have it and not declare it in any header file.
#
# Before you is a C compiler.
#
AC_CHECK_FUNCS(ether_hostton)
if test "$ac_cv_func_ether_hostton" = yes; then
#
- # OK, we have ether_hostton(). Do we have <netinet/if_ether.h>?
+ # OK, we have ether_hostton(). Is it declared in <net/ethernet.h>?
+ #
+ # This test fails if we don't have <net/ethernet.h> or if we do
+ # but it doesn't declare ether_hostton().
+ #
+ AC_CHECK_DECL(ether_hostton,
+ [
+ AC_DEFINE(NET_ETHERNET_H_DECLARES_ETHER_HOSTTON,,
+ [Define to 1 if net/ethernet.h declares `ether_hostton'])
+ ],,
+ [
+#include <net/ethernet.h>
+ ])
+ #
+ # Did that succeed?
#
- if test "$ac_cv_header_netinet_if_ether_h" = yes; then
+ if test "$ac_cv_have_decl_ether_hostton" != yes; then
+ #
+ # No, how about <netinet/ether.h>, as on Linux?
+ #
+ # This test fails if we don't have <netinet/ether.h>
+ # or if we do but it doesn't declare ether_hostton().
#
- # Yes. Does it declare ether_hostton()?
+ # Unset ac_cv_have_decl_ether_hostton so we don't
+ # treat the previous failure as a cached value and
+ # suppress the next test.
#
+ unset ac_cv_have_decl_ether_hostton
AC_CHECK_DECL(ether_hostton,
[
- AC_DEFINE(NETINET_IF_ETHER_H_DECLARES_ETHER_HOSTTON,,
- [Define to 1 if netinet/if_ether.h declares `ether_hostton'])
+ AC_DEFINE(NETINET_ETHER_H_DECLARES_ETHER_HOSTTON,,
+ [Define to 1 if netinet/ether.h declares `ether_hostton'])
],,
[
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-struct mbuf;
-struct rtentry;
-#include <net/if.h>
-#include <netinet/if_ether.h>
+#include <netinet/ether.h>
])
fi
#
@@ -223,56 +326,168 @@ struct rtentry;
#
if test "$ac_cv_have_decl_ether_hostton" != yes; then
#
- # No, how about <netinet/ether.h>, as on Linux?
+ # No, how about <sys/ethernet.h>, as on Solaris 10
+ # and later?
#
- AC_CHECK_HEADERS(netinet/ether.h)
- if test "$ac_cv_header_netinet_ether_h" = yes; then
- #
- # We have it - does it declare ether_hostton()?
- # Unset ac_cv_have_decl_ether_hostton so we don't
- # treat the previous failure as a cached value and
- # suppress the next test.
- #
- unset ac_cv_have_decl_ether_hostton
- AC_CHECK_DECL(ether_hostton,
- [
- AC_DEFINE(NETINET_ETHER_H_DECLARES_ETHER_HOSTTON,,
- [Define to 1 if netinet/ether.h declares `ether_hostton'])
- ],,
- [
-#include <netinet/ether.h>
- ])
- fi
+ # This test fails if we don't have <sys/ethernet.h>
+ # or if we do but it doesn't declare ether_hostton().
+ #
+ # Unset ac_cv_have_decl_ether_hostton so we don't
+ # treat the previous failure as a cached value and
+ # suppress the next test.
+ #
+ unset ac_cv_have_decl_ether_hostton
+ AC_CHECK_DECL(ether_hostton,
+ [
+ AC_DEFINE(SYS_ETHERNET_H_DECLARES_ETHER_HOSTTON,,
+ [Define to 1 if sys/ethernet.h declares `ether_hostton'])
+ ],,
+ [
+#include <sys/ethernet.h>
+ ])
fi
#
- # Is ether_hostton() declared?
+ # Did that succeed?
#
if test "$ac_cv_have_decl_ether_hostton" != yes; then
#
- # No, we'll have to declare it ourselves.
- # Do we have "struct ether_addr"?
+ # No, how about <arpa/inet.h>, as in AIX?
#
- AC_CHECK_TYPES(struct ether_addr,,,
+ # This test fails if we don't have <arpa/inet.h>
+ # (if we have ether_hostton(), we should have
+ # networking, and if we have networking, we should
+ # have <arapa/inet.h>) or if we do but it doesn't
+ # declare ether_hostton().
+ #
+ # Unset ac_cv_have_decl_ether_hostton so we don't
+ # treat the previous failure as a cached value and
+ # suppress the next test.
+ #
+ unset ac_cv_have_decl_ether_hostton
+ AC_CHECK_DECL(ether_hostton,
+ [
+ AC_DEFINE(ARPA_INET_H_DECLARES_ETHER_HOSTTON,,
+ [Define to 1 if arpa/inet.h declares `ether_hostton'])
+ ],,
+ [
+#include <arpa/inet.h>
+ ])
+ fi
+ #
+ # Did that succeed?
+ #
+ if test "$ac_cv_have_decl_ether_hostton" != yes; then
+ #
+ # No, how about <netinet/if_ether.h>?
+ # On some platforms, it requires <net/if.h> and
+ # <netinet/in.h>, and we always include it with
+ # both of them, so test it with both of them.
+ #
+ # This test fails if we don't have <netinet/if_ether.h>
+ # and the headers we include before it, or if we do but
+ # <netinet/if_ether.h> doesn't declare ether_hostton().
+ #
+ # Unset ac_cv_have_decl_ether_hostton so we don't
+ # treat the previous failure as a cached value and
+ # suppress the next test.
+ #
+ unset ac_cv_have_decl_ether_hostton
+ AC_CHECK_DECL(ether_hostton,
+ [
+ AC_DEFINE(NETINET_IF_ETHER_H_DECLARES_ETHER_HOSTTON,,
+ [Define to 1 if netinet/if_ether.h declares `ether_hostton'])
+ ],,
[
#include <sys/types.h>
#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-struct mbuf;
-struct rtentry;
#include <net/if.h>
+#include <netinet/in.h>
#include <netinet/if_ether.h>
])
- AC_DEFINE(HAVE_DECL_ETHER_HOSTTON, 0,
- [Define to 1 if you have the declaration of `ether_hostton', and to 0 if you
-don't.])
- else
+ fi
+ #
+ # After all that, is ether_hostton() declared?
+ #
+ if test "$ac_cv_have_decl_ether_hostton" = yes; then
+ #
+ # Yes.
+ #
AC_DEFINE(HAVE_DECL_ETHER_HOSTTON, 1,
- [Define to 1 if you have the declaration of `ether_hostton', and to 0 if you
-don't.])
+ [Define to 1 if you have the declaration of `ether_hostton'])
+ else
+ #
+ # No, we'll have to declare it ourselves.
+ # Do we have "struct ether_addr" if we include
+ # <netinet/if_ether.h>?
+ #
+ AC_CHECK_TYPES(struct ether_addr,,,
+ [
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <net/if.h>
+ #include <netinet/in.h>
+ #include <netinet/if_ether.h>
+ ])
fi
fi
+#
+# For various things that might use pthreads.
+#
+AC_CHECK_HEADER(pthread.h,
+ [
+ #
+ # OK, we have pthread.h. Do we have pthread_create in the
+ # system libraries?
+ #
+ AC_CHECK_FUNC(pthread_create,
+ [
+ #
+ # Yes.
+ #
+ ac_lbl_have_pthreads="found"
+ ],
+ [
+ #
+ # No - do we have it in -lpthreads?
+ #
+ AC_CHECK_LIB(pthreads, pthread_create,
+ [
+ #
+ # Yes - add -lpthreads.
+ #
+ ac_lbl_have_pthreads="found"
+ PTHREAD_LIBS="$PTHREAD_LIBS -lpthreads"
+ ],
+ [
+ #
+ # No - do we have it in -lpthread?
+ #
+ AC_CHECK_LIB(pthread, pthread_create,
+ [
+ #
+ # Yes - add -lpthread.
+ #
+ ac_lbl_have_pthreads="found"
+ PTHREAD_LIBS="$PTHREAD_LIBS -lpthread"
+ ],
+ [
+ #
+ # No.
+ #
+ ac_lbl_have_pthreads="not found"
+ ])
+ ])
+ ])
+ ],
+ [
+ #
+ # We didn't find pthread.h.
+ #
+ ac_lbl_have_pthreads="not found"
+ ]
+)
+
dnl to pacify those who hate protochain insn
AC_MSG_CHECKING(if --disable-protochain option is specified)
AC_ARG_ENABLE(protochain,
@@ -293,7 +508,7 @@ AC_MSG_RESULT(${enable_protochain})
# only tests with BPF and PF_PACKET sockets; only enable it if
# we have BPF or PF_PACKET sockets.
#
-VALGRINDTEST=
+VALGRINDTEST_SRC=
#
# SITA support is mutually exclusive with native capture support;
@@ -309,83 +524,139 @@ AC_HELP_STRING([--with-sita],[include SITA support]),
fi
],
[
-dnl
-dnl Not all versions of test support -c (character special) but it's a
-dnl better way of testing since the device might be protected. So we
-dnl check in our normal order using -r and then check the for the /dev
-dnl guys again using -c.
-dnl
-dnl XXX This could be done for cross-compiling, but for now it's not.
-dnl
-if test -z "$with_pcap" && test "$cross_compiling" = yes; then
- AC_MSG_ERROR(pcap type not determined when cross-compiling; use --with-pcap=...)
-fi
AC_ARG_WITH(pcap,
AC_HELP_STRING([--with-pcap=TYPE],[use packet capture TYPE]))
-AC_MSG_CHECKING(packet capture type)
if test ! -z "$with_pcap" ; then
V_PCAP="$withval"
-elif test -r /dev/bpf -o -h /dev/bpf ; then
+else
#
- # Cloning BPF device.
+ # Check for a bunch of headers for various packet
+ # capture mechanisms.
#
- V_PCAP=bpf
- AC_DEFINE(HAVE_CLONING_BPF,1,[define if you have a cloning BPF device])
+ AC_CHECK_HEADERS(net/bpf.h)
+ if test "$ac_cv_header_net_bpf_h" = yes; then
+ #
+ # Does it define BIOCSETIF?
+ # I.e., is it a header for an LBL/BSD-style capture
+ # mechanism, or is it just a header for a BPF filter
+ # engine? Some versions of Arch Linux, for example,
+ # have a net/bpf.h that doesn't define BIOCSETIF;
+ # 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/ioctl.h and, if we have it, sys/ioccom.h,
+ # because net/bpf.h defines ioctls;
+ #
+ # net/if.h, because it defines some structures
+ # used in ioctls defined by net/bpf.h;
+ #
+ # sys/socket.h, because OpenBSD 5.9's net/bpf.h
+ # defines some structure fields as being
+ # struct sockaddrs;
+ #
+ # and net/bpf.h doesn't necessarily include all
+ # of those headers itself.
+ #
+ AC_MSG_CHECKING(if net/bpf.h defines BIOCSETIF)
+ AC_CACHE_VAL(ac_cv_lbl_bpf_h_defines_biocsetif,
+ AC_TRY_COMPILE(
+[
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#ifdef HAVE_SYS_IOCCOM_H
+#include <sys/ioccom.h>
+#endif
+#include <net/bpf.h>
+#include <net/if.h>
+],
+ [u_int i = BIOCSETIF;],
+ ac_cv_lbl_bpf_h_defines_biocsetif=yes,
+ ac_cv_lbl_bpf_h_defines_biocsetif=no))
+ AC_MSG_RESULT($ac_cv_lbl_bpf_h_defines_biocsetif)
+ fi
+ AC_CHECK_HEADERS(net/pfilt.h net/enet.h)
+ AC_CHECK_HEADERS(net/nit.h sys/net/nit.h)
+ AC_CHECK_HEADERS(linux/socket.h net/raw.h sys/dlpi.h)
- #
- # We have BPF, so build valgrindtest with "make test".
- #
- VALGRINDTEST=valgrindtest
-elif test -r /dev/bpf0 ; then
- V_PCAP=bpf
+ if test "$ac_cv_lbl_bpf_h_defines_biocsetif" = yes; then
+ #
+ # BPF.
+ # Check this before DLPI, so that we pick BPF on
+ # Solaris 11 and later.
+ #
+ V_PCAP=bpf
- #
- # We have BPF, so build valgrindtest with "make test".
- #
- VALGRINDTEST=valgrindtest
-elif test -r /usr/include/net/pfilt.h ; then
- V_PCAP=pf
-elif test -r /dev/enet ; then
- V_PCAP=enet
-elif test -r /dev/nit ; then
- V_PCAP=snit
-elif test -r /usr/include/sys/net/nit.h ; then
- V_PCAP=nit
-elif test -r /usr/include/linux/socket.h ; then
- V_PCAP=linux
+ #
+ # We have BPF, so build valgrindtest with "make test"
+ # on macOS and FreeBSD (add your OS once there's a
+ # valgrind for it).
+ #
+ case "$host_os" in
- #
- # XXX - this won't work with older kernels that have SOCK_PACKET
- # sockets but not PF_PACKET sockets.
- #
- VALGRINDTEST=valgrindtest
-elif test -r /usr/include/net/raw.h ; then
- V_PCAP=snoop
-elif test -r /usr/include/odmi.h ; then
- #
- # On AIX, the BPF devices might not yet be present - they're
- # created the first time libpcap runs after booting.
- # We check for odmi.h instead.
- #
- V_PCAP=bpf
-elif test -c /dev/bpf0 ; then # check again in case not readable
- V_PCAP=bpf
+ freebsd*|darwin*|linux*)
+ VALGRINDTEST_SRC=valgrindtest.c
+ ;;
+ esac
+ elif test "$ac_cv_header_linux_socket_h" = yes; then
+ #
+ # No prizes for guessing this one.
+ #
+ V_PCAP=linux
- #
- # We have BPF, so build valgrindtest with "make test".
- #
- VALGRINDTEST=valgrindtest
-elif test -r /usr/include/sys/dlpi.h ; then
- V_PCAP=dlpi
-elif test -c /dev/enet ; then # check again in case not readable
- V_PCAP=enet
-elif test -c /dev/nit ; then # check again in case not readable
- V_PCAP=snit
-else
- V_PCAP=null
+ #
+ # XXX - this won't work with older kernels that have
+ # SOCK_PACKET sockets but not PF_PACKET sockets.
+ #
+ VALGRINDTEST_SRC=valgrindtest.c
+ elif test "$ac_cv_header_net_pfilt_h" = yes; then
+ #
+ # DEC OSF/1, Digital UNIX, Tru64 UNIX
+ #
+ V_PCAP=pf
+ elif test "$ac_cv_header_net_enet_h" = yes; then
+ #
+ # Stanford Enetfilter.
+ #
+ V_PCAP=enet
+ elif test "$ac_cv_header_net_nit_h" = yes; then
+ #
+ # SunOS 4.x STREAMS NIT.
+ #
+ V_PCAP=snit
+ elif test "$ac_cv_header_sys_net_nit_h" = yes; then
+ #
+ # Pre-SunOS 4.x non-STREAMS NIT.
+ #
+ V_PCAP=nit
+ elif test "$ac_cv_header_net_raw_h" = yes; then
+ #
+ # IRIX snoop.
+ #
+ V_PCAP=snoop
+ elif test "$ac_cv_header_sys_dlpi_h" = yes; then
+ #
+ # DLPI on pre-Solaris 11 SunOS 5, HP-UX, possibly others.
+ #
+ V_PCAP=dlpi
+ else
+ #
+ # Nothing we support.
+ #
+ V_PCAP=null
+ AC_MSG_WARN(cannot determine packet capture interface)
+ AC_MSG_WARN((see the INSTALL doc for more info))
+ fi
fi
+AC_MSG_CHECKING(packet capture type)
AC_MSG_RESULT($V_PCAP)
-AC_SUBST(VALGRINDTEST)
+AC_SUBST(VALGRINDTEST_SRC)
#
# Do capture-mechanism-dependent tests.
@@ -445,29 +716,16 @@ dlpi)
fi
#
- # Check whether we have a /dev/dlpi device or have multiple devices.
- #
- AC_MSG_CHECKING(for /dev/dlpi device)
- if test -c /dev/dlpi ; then
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_DEV_DLPI, 1, [define if you have a /dev/dlpi])
- else
- AC_MSG_RESULT(no)
- dir="/dev/dlpi"
- AC_MSG_CHECKING(for $dir directory)
- if test -d $dir ; then
- AC_MSG_RESULT(yes)
- AC_DEFINE_UNQUOTED(PCAP_DEV_PREFIX, "$dir", [/dev/dlpi directory])
- else
- AC_MSG_RESULT(no)
- fi
- fi
-
- #
- # This check is for Solaris with DLPI support for passive modes.
+ # Check to see if Solaris has the dl_passive_req_t struct defined
+ # in <sys/dlpi.h>.
+ # This check is for DLPI support for passive modes.
# See dlpi(7P) for more details.
#
- AC_LBL_DL_PASSIVE_REQ_T
+ AC_CHECK_TYPES(dl_passive_req_t,,,
+ [
+ #include <sys/types.h>
+ #include <sys/dlpi.h>
+ ])
;;
linux)
@@ -486,17 +744,25 @@ linux)
#
AC_ARG_WITH(libnl,
AC_HELP_STRING([--without-libnl],[disable libnl support @<:@default=yes, on Linux, if present@:>@]),
- with_libnl=$withval,,)
+ with_libnl=$withval,with_libnl=if_available)
if test x$with_libnl != xno ; then
have_any_nl="no"
incdir=-I/usr/include/libnl3
libnldir=
- if test x$withval != x ; then
- libnldir=-L${withval}/lib/.libs
- incdir=-I${withval}/include
- fi
+ case "$with_libnl" in
+
+ yes|if_available)
+ ;;
+
+ *)
+ if test -d $withval; then
+ libnldir=-L${withval}/lib/.libs
+ incdir=-I${withval}/include
+ fi
+ ;;
+ esac
#
# Try libnl 3.x first.
@@ -563,8 +829,32 @@ linux)
AC_INCLUDES_DEFAULT
#include <linux/types.h>
])
- AC_LBL_TPACKET_STATS
- AC_LBL_LINUX_TPACKET_AUXDATA_TP_VLAN_TCI
+
+ #
+ # Check to see if struct tpacket_stats is defined in
+ # <linux/if_packet.h>. If so, then pcap-linux.c can use this
+ # to report proper statistics.
+ #
+ # -Scott Barron
+ #
+ AC_CHECK_TYPES(struct tpacket_stats,,,
+ [
+ #include <linux/if_packet.h>
+ ])
+
+ #
+ # Check to see if the tpacket_auxdata struct has a tp_vlan_tci member.
+ #
+ # NOTE: any failure means we conclude that it doesn't have that
+ # member, so if we don't have tpacket_auxdata, we conclude it
+ # doesn't have that member (which is OK, as either we won't be
+ # using code that would use that member, or we wouldn't compile
+ # in any case).
+ AC_CHECK_MEMBERS([struct tpacket_auxdata.tp_vlan_tci],,,
+ [
+ #include <sys/types.h>
+ #include <linux/if_packet.h>
+ ])
;;
bpf)
@@ -573,32 +863,18 @@ bpf)
#
AC_CHECK_HEADERS(net/if_media.h)
- AC_MSG_CHECKING(whether the system supports zerocopy BPF)
- AC_TRY_COMPILE(
- [#include <sys/socket.h>
- #include <sys/ioctl.h>
- #include <net/if.h>
- #include <net/bpf.h>],
- [return (BIOCROTZBUF + BPF_BUFMODE_ZBUF);],
+ #
+ # Check whether we have struct BPF_TIMEVAL.
+ #
+ AC_CHECK_TYPES(struct BPF_TIMEVAL,,,
[
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_ZEROCOPY_BPF, 1,
- [define if the system supports zerocopy BPF])
- ],
- AC_MSG_RESULT(no))
-
- #
- # Check whether we have struct BPF_TIMEVAL.
- #
- AC_CHECK_TYPES(struct BPF_TIMEVAL,,,
- [
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#ifdef HAVE_SYS_IOCCOM_H
-#include <sys/ioccom.h>
-#endif
-#include <net/bpf.h>
- ])
+ #include <sys/types.h>
+ #include <sys/ioctl.h>
+ #ifdef HAVE_SYS_IOCCOM_H
+ #include <sys/ioccom.h>
+ #endif
+ #include <net/bpf.h>
+ ])
;;
dag)
@@ -629,8 +905,10 @@ snf)
;;
null)
- AC_MSG_WARN(cannot determine packet capture interface)
- AC_MSG_WARN((see the INSTALL doc for more info))
+ ;;
+
+*)
+ AC_MSG_ERROR($V_PCAP is not a valid pcap type)
;;
esac
@@ -666,97 +944,82 @@ then
])
],[
#
- # Well, we don't have "getifaddrs()", so we have to use
- # some other mechanism; determine what that mechanism is.
+ # Well, we don't have "getifaddrs()", at least not with the
+ # libraries with which we've decided we need to link
+ # libpcap with, so we have to use some other mechanism.
#
- # The first thing we use is the type of capture mechanism,
- # which is somewhat of a proxy for the OS we're using.
+ # Note that this may happen on Solaris, which has
+ # getifaddrs(), but in -lsocket, not in -lxnet, so we
+ # won't find it if we link with -lxnet, which we want
+ # to do for other reasons.
#
- case "$V_PCAP" in
-
- dlpi|libdlpi)
- #
- # This might be Solaris 8 or later, with
- # SIOCGLIFCONF, or it might be some other OS
- # or some older version of Solaris, with
- # just SIOCGIFCONF.
- #
- AC_MSG_CHECKING(whether we have SIOCGLIFCONF)
- AC_CACHE_VAL(ac_cv_lbl_have_siocglifconf,
- AC_TRY_COMPILE(
- [#include <sys/param.h>
- #include <sys/file.h>
- #include <sys/ioctl.h>
- #include <sys/socket.h>
- #include <sys/sockio.h>],
- [ioctl(0, SIOCGLIFCONF, (char *)0);],
- ac_cv_lbl_have_siocglifconf=yes,
- ac_cv_lbl_have_siocglifconf=no))
- AC_MSG_RESULT($ac_cv_lbl_have_siocglifconf)
- if test $ac_cv_lbl_have_siocglifconf = yes ; then
- V_FINDALLDEVS=fad-glifc.c
- else
- V_FINDALLDEVS=fad-gifc.c
- fi
- ;;
-
- *)
- #
- # Assume we just have SIOCGIFCONF.
- # (XXX - on at least later Linux kernels, there's
- # another mechanism, and we should be using that
- # instead.)
- #
+ # For now, we use either the SIOCGIFCONF ioctl or the
+ # SIOCGLIFCONF ioctl, preferring the latter if we have
+ # it; the latter is a Solarisism that first appeared
+ # in Solaris 8. (Solaris's getifaddrs() appears to
+ # be built atop SIOCGLIFCONF; using it directly
+ # avoids a not-all-that-useful middleman.)
+ #
+ AC_MSG_CHECKING(whether we have SIOCGLIFCONF)
+ AC_CACHE_VAL(ac_cv_lbl_have_siocglifconf,
+ AC_TRY_COMPILE(
+ [#include <sys/param.h>
+ #include <sys/file.h>
+ #include <sys/ioctl.h>
+ #include <sys/socket.h>
+ #include <sys/sockio.h>],
+ [ioctl(0, SIOCGLIFCONF, (char *)0);],
+ ac_cv_lbl_have_siocglifconf=yes,
+ ac_cv_lbl_have_siocglifconf=no))
+ AC_MSG_RESULT($ac_cv_lbl_have_siocglifconf)
+ if test $ac_cv_lbl_have_siocglifconf = yes ; then
+ V_FINDALLDEVS=fad-glifc.c
+ else
V_FINDALLDEVS=fad-gifc.c
- ;;
- esac])
+ fi
+ ])
fi
])
-AC_MSG_CHECKING(for socklen_t)
-AC_TRY_COMPILE([
+dnl check for hardware timestamp support
+case "$host_os" in
+linux*)
+ AC_CHECK_HEADERS([linux/net_tstamp.h])
+ ;;
+*)
+ AC_MSG_NOTICE(no hardware timestamp support implemented for $host_os)
+ ;;
+esac
+
+AC_ARG_ENABLE([packet-ring],
+[AC_HELP_STRING([--enable-packet-ring],[enable packet ring support on Linux @<:@default=yes@:>@])],
+,enable_packet_ring=yes)
+
+if test "x$enable_packet_ring" != "xno" ; then
+ AC_DEFINE(PCAP_SUPPORT_PACKET_RING, 1, [use packet ring capture support on Linux if available])
+ AC_SUBST(PCAP_SUPPORT_PACKET_RING)
+fi
+
+#
+# Check for socklen_t.
+#
+AC_CHECK_TYPES(socklen_t,,,
+ [
#include <sys/types.h>
#include <sys/socket.h>
- ],
- [ socklen_t x; ],
- have_socklen_t=yes,
- have_socklen_t=no)
-if test "x$have_socklen_t" = "xyes"; then
- AC_DEFINE(HAVE_SOCKLEN_T, 1, [define if socklen_t is defined])
-fi
-AC_MSG_RESULT($have_socklen_t)
+ ])
AC_ARG_ENABLE(ipv6,
-AC_HELP_STRING([--enable-ipv6],[build IPv6-capable version @<:@default=yes, if getaddrinfo available@:>@]),
+AC_HELP_STRING([--enable-ipv6],[build IPv6-capable version @<:@default=yes@:>@]),
[],
- [enable_ipv6=ifavailable])
+ [enable_ipv6=yes])
if test "$enable_ipv6" != "no"; then
- AC_CHECK_FUNC(getaddrinfo,
- [
- AC_DEFINE(INET6,1,[IPv6])
- ],
- [
- if test "$enable_ipv6" != "ifavailable"; then
- AC_MSG_FAILURE([--enable-ipv6 was given, but getaddrinfo isn't available])
- fi
- ])
-fi
-
-AC_MSG_CHECKING(whether to build optimizer debugging code)
-AC_ARG_ENABLE(optimizer-dbg,
-AC_HELP_STRING([--enable-optimizer-dbg],[build optimizer debugging code]))
-if test "$enable_optimizer_dbg" = "yes"; then
- AC_DEFINE(BDEBUG,1,[Enable optimizer debugging])
-fi
-AC_MSG_RESULT(${enable_optimizer_dbg-no})
-
-AC_MSG_CHECKING(whether to build parser debugging code)
-AC_ARG_ENABLE(yydebug,
-AC_HELP_STRING([--enable-yydebug],[build parser debugging code]))
-if test "$enable_yydebug" = "yes"; then
- AC_DEFINE(YYDEBUG,1,[Enable parser debugging])
+ #
+ # We've already made sure we have getaddrinfo above in
+ # AC_LBL_LIBRARY_NET.
+ #
+ AC_DEFINE(INET6,1,[IPv6])
fi
-AC_MSG_RESULT(${enable_yydebug-no})
# Check for Endace DAG card support.
AC_ARG_WITH([dag],
@@ -808,11 +1071,8 @@ AC_HELP_STRING([--with-dag-libraries=LDIR],[Endace DAG library directory, if not
dag_lib_dir=$withval
],[])
-ac_cv_lbl_dag_api=no
if test "$want_dag" != no; then
- AC_MSG_CHECKING([whether we have DAG API headers])
-
# If necessary, set default paths for DAG API headers and libraries.
if test -z "$dag_root"; then
dag_root=/usr/local
@@ -826,29 +1086,25 @@ if test "$want_dag" != no; then
dag_lib_dir="$dag_root/lib"
fi
- if test -z "$dag_tools_dir"; then
- dag_tools_dir="$dag_root/tools"
- fi
-
- if test -r $dag_include_dir/dagapi.h; then
- ac_cv_lbl_dag_api=yes
- fi
+ V_INCLS="$V_INCLS -I$dag_include_dir"
- if test "$ac_cv_lbl_dag_api" = yes; then
- AC_MSG_RESULT([yes ($dag_include_dir)])
+ AC_CHECK_HEADERS([dagapi.h])
- V_INCLS="$V_INCLS -I$dag_include_dir"
+ if test "$ac_cv_header_dagapi_h" = yes; then
if test $V_PCAP != dag ; then
SSRC="$SSRC pcap-dag.c"
fi
- # See if we can find a general version string.
+ # Check for various DAG API functions.
# Don't need to save and restore LIBS to prevent -ldag being
# included if there's a found-action (arg 3).
saved_ldflags=$LDFLAGS
LDFLAGS="-L$dag_lib_dir"
- AC_CHECK_LIB([dag], [dag_attach_stream], [dag_streams="1"], [dag_streams="0"])
+ AC_CHECK_LIB([dag], [dag_attach_stream],
+ [],
+ [AC_MSG_ERROR(DAG library lacks streams support)])
+ AC_CHECK_LIB([dag], [dag_attach_stream64], [dag_large_streams="1"], [dag_large_streams="0"])
AC_CHECK_LIB([dag],[dag_get_erf_types], [
AC_DEFINE(HAVE_DAG_GET_ERF_TYPES, 1, [define if you have dag_get_erf_types()])])
AC_CHECK_LIB([dag],[dag_get_stream_erf_types], [
@@ -856,21 +1112,28 @@ if test "$want_dag" != no; then
LDFLAGS=$saved_ldflags
- if test "$dag_streams" = 1; then
- AC_DEFINE(HAVE_DAG_STREAMS_API, 1, [define if you have streams capable DAG API])
- LIBS="$LIBS -ldag"
- LDFLAGS="$LDFLAGS -L$dag_lib_dir"
+ #
+ # We assume that if we have libdag we have libdagconf,
+ # as they're installed at the same time from the same
+ # package.
+ #
+ LIBS="$LIBS -ldag -ldagconf"
+ LDFLAGS="$LDFLAGS -L$dag_lib_dir"
+ if test "$dag_large_streams" = 1; then
+ AC_DEFINE(HAVE_DAG_LARGE_STREAMS_API, 1, [define if you have large streams capable DAG API])
AC_CHECK_LIB([vdag],[vdag_set_device_info], [ac_dag_have_vdag="1"], [ac_dag_have_vdag="0"])
if test "$ac_dag_have_vdag" = 1; then
AC_DEFINE(HAVE_DAG_VDAG, 1, [define if you have vdag_set_device_info()])
- LIBS="$LIBS -lpthread"
+ if test "$ac_lbl_have_pthreads" != "found"; then
+ AC_MSG_ERROR([DAG requires pthreads, but we didn't find them])
+ fi
+ LIBS="$LIBS $PTHREAD_LIBS"
fi
fi
AC_DEFINE(HAVE_DAG_API, 1, [define if you have the DAG API])
else
- AC_MSG_RESULT(no)
if test "$V_PCAP" = dag; then
# User requested "dag" capture type but we couldn't
@@ -1140,6 +1403,92 @@ if test "$want_turbocap" != no; then
fi
fi
+dnl
+dnl Allow the user to enable remote capture.
+dnl It's off by default, as that increases the attack surface of
+dnl libpcap, exposing it to malicious servers.
+dnl
+AC_MSG_CHECKING([whether to enable remote packet capture])
+AC_ARG_ENABLE(remote,
+[ --enable-remote enable remote packet capture @<:@default=no@:>@
+ --disable-remote disable remote packet capture],,
+ enableval=no)
+case "$enableval" in
+yes) AC_MSG_RESULT(yes)
+ AC_WARN([Remote packet capture may expose libpcap-based applications])
+ AC_WARN([to attacks by malicious remote capture servers!])
+ #
+ # rpcapd requires pthreads on UN*X.
+ #
+ if test "$ac_lbl_have_pthreads" != "found"; then
+ AC_MSG_ERROR([rpcapd requires pthreads, but we didn't find them])
+ fi
+ #
+ # It also requires crypt().
+ # Do we have it in the system libraries?
+ #
+ AC_CHECK_FUNC(crypt,,
+ [
+ #
+ # No. Do we have it in -lcrypt?
+ #
+ AC_CHECK_LIB(crypt, crypt,
+ [
+ #
+ # Yes; add -lcrypt to the libraries for rpcapd.
+ #
+ RPCAPD_LIBS="$RPCAPD_LIBS -lcrypt"
+ ],
+ [
+ AC_MSG_ERROR([rpcapd requires crypt(), but we didn't find it])
+ ])
+ ])
+
+ #
+ # OK, we have crypt(). Do we have getspnam()?
+ #
+ AC_CHECK_FUNCS(getspnam)
+
+ #
+ # Check for various members of struct msghdr.
+ #
+ AC_CHECK_MEMBERS([struct msghdr.msg_control],,,
+ [
+ #include "ftmacros.h"
+ #include <sys/socket.h>
+ ])
+ AC_CHECK_MEMBERS([struct msghdr.msg_flags],,,
+ [
+ #include "ftmacros.h"
+ #include <sys/socket.h>
+ ])
+
+ 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"
+ BUILD_RPCAPD=build-rpcapd
+ INSTALL_RPCAPD=install-rpcapd
+ ;;
+*) AC_MSG_RESULT(no)
+ ;;
+esac
+
+AC_MSG_CHECKING(whether to build optimizer debugging code)
+AC_ARG_ENABLE(optimizer-dbg,
+AC_HELP_STRING([--enable-optimizer-dbg],[build optimizer debugging code]))
+if test "$enable_optimizer_dbg" = "yes"; then
+ AC_DEFINE(BDEBUG,1,[Enable optimizer debugging])
+fi
+AC_MSG_RESULT(${enable_optimizer_dbg-no})
+
+AC_MSG_CHECKING(whether to build parser debugging code)
+AC_ARG_ENABLE(yydebug,
+AC_HELP_STRING([--enable-yydebug],[build parser debugging code]))
+if test "$enable_yydebug" = "yes"; then
+ AC_DEFINE(YYDEBUG,1,[Enable parser debugging])
+fi
+AC_MSG_RESULT(${enable_yydebug-no})
+
#
# Look for {f}lex.
#
@@ -1184,13 +1533,17 @@ if test $tcpdump_cv_capable_yacc = insufficient ; then
fi
#
-# 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).
+# 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.
#
DYEXT="none"
MAN_FILE_FORMATS=5
MAN_MISC_INFO=7
+MAN_ADMIN_COMMANDS=8
case "$host_os" in
aix*)
@@ -1239,7 +1592,7 @@ darwin*)
DYEXT="dylib"
V_CCOPT="$V_CCOPT -fno-common"
AC_ARG_ENABLE(universal,
- AC_HELP_STRING([--disable-universal],[don't build universal on OS X]))
+ AC_HELP_STRING([--disable-universal],[don't build universal on macOS]))
if test "$enable_universal" != "no"; then
case "$host_os" in
@@ -1327,6 +1680,7 @@ hpux9*)
#
# Use System V conventions for man pages.
#
+ MAN_ADMIN_COMMANDS=1m
MAN_FILE_FORMATS=4
MAN_MISC_INFO=5
;;
@@ -1336,6 +1690,7 @@ hpux10.0*)
#
# Use System V conventions for man pages.
#
+ MAN_ADMIN_COMMANDS=1m
MAN_FILE_FORMATS=4
MAN_MISC_INFO=5
;;
@@ -1345,6 +1700,7 @@ hpux10.1*)
#
# Use System V conventions for man pages.
#
+ MAN_ADMIN_COMMANDS=1m
MAN_FILE_FORMATS=4
MAN_MISC_INFO=5
;;
@@ -1378,7 +1734,9 @@ hpux*)
irix*)
#
- # Use System V conventions for man pages.
+ # Use IRIX conventions for man pages; they're the same as the
+ # System V conventions, except that they use section 8 for
+ # administrative commands and daemons.
#
MAN_FILE_FORMATS=4
MAN_MISC_INFO=5
@@ -1400,7 +1758,10 @@ osf*)
DYEXT="so"
#
- # Use System V conventions for man pages.
+ # DEC OSF/1, a/k/a Digial UNIX, a/k/a Tru64 UNIX.
+ # Use Tru64 UNIX conventions for man pages; they're the same as
+ # the System V conventions except that they use section 8 for
+ # administrative commands and daemons.
#
MAN_FILE_FORMATS=4
MAN_MISC_INFO=5
@@ -1424,11 +1785,30 @@ solaris*)
AC_DEFINE(HAVE_SOLARIS,1,[On solaris])
DYEXT="so"
+
#
- # Use System V conventions for man pages.
+ # Make sure errno is thread-safe, in case we're called in
+ # a multithreaded program. We don't guarantee that two
+ # threads can use the *same* pcap_t safely, but the
+ # current version does guarantee that you can use different
+ # pcap_t's in different threads, and even that pcap_compile()
+ # is thread-safe (it wasn't thread-safe in some older versions).
#
- MAN_FILE_FORMATS=4
- MAN_MISC_INFO=5
+ V_CCOPT="$V_CCOPT -D_TS_ERRNO"
+
+ case "`uname -r`" in
+
+ 5.12)
+ ;;
+
+ *)
+ #
+ # Use System V conventions for man pages.
+ #
+ MAN_ADMIN_COMMANDS=1m
+ MAN_FILE_FORMATS=4
+ MAN_MISC_INFO=5
+ esac
;;
esac
@@ -1444,23 +1824,51 @@ AC_SUBST(LN_S)
AC_LBL_DEVEL(V_CCOPT)
-AC_LBL_SOCKADDR_SA_LEN
+#
+# Check to see if the sockaddr struct has the 4.4 BSD sa_len member.
+#
+AC_CHECK_MEMBERS([struct sockaddr.sa_len],,,
+ [
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ ])
-AC_LBL_SOCKADDR_STORAGE
+#
+# Check to see if there's a sockaddr_storage structure.
+#
+AC_CHECK_TYPES(struct sockaddr_storage,,,
+ [
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ ])
-AC_LBL_HP_PPA_INFO_T_DL_MODULE_ID_1
+#
+# Check to see if the dl_hp_ppa_info_t struct has the HP-UX 11.00
+# dl_module_id_1 member.
+#
+# NOTE: any failure means we conclude that it doesn't have that member,
+# so if we don't have DLPI, don't have a <sys/dlpi_ext.h> header, or
+# have one that doesn't declare a dl_hp_ppa_info_t type, we conclude
+# it doesn't have that member (which is OK, as either we won't be
+# using code that would use that member, or we wouldn't compile in
+# any case).
+#
+AC_CHECK_MEMBERS([dl_hp_ppa_info_t.dl_module_id_1],,,
+ [
+ #include <sys/types.h>
+ #include <sys/dlpi.h>
+ #include <sys/dlpi_ext.h>
+ ])
AC_LBL_UNALIGNED_ACCESS
-rm -f net
-ln -s ${srcdir}/bpf/net net
-
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)
@@ -1472,9 +1880,15 @@ AC_SUBST(SSRC)
AC_SUBST(DYEXT)
AC_SUBST(MAN_FILE_FORMATS)
AC_SUBST(MAN_MISC_INFO)
+AC_SUBST(MAN_ADMIN_COMMANDS)
+AC_SUBST(PTHREAD_LIBS)
+AC_SUBST(BUILD_RPCAPD)
+AC_SUBST(INSTALL_RPCAPD)
+AC_SUBST(RPCAPD_LIBS)
+AC_SUBST(EXTRA_NETWORK_LIBS)
AC_ARG_ENABLE([usb],
-[AC_HELP_STRING([--enable-usb],[enable nusb support @<:@default=yes, if support available@:>@])],
+[AC_HELP_STRING([--enable-usb],[enable USB capture support @<:@default=yes, if support available@:>@])],
[],
[enable_usb=yes])
@@ -1518,25 +1932,14 @@ if test "x$enable_usb" != "xno" ; then
# "value", rather than "bRequestType", "bRequest", and
# "wValue".
#
- AC_MSG_CHECKING(if usbdevfs_ctrltransfer struct has bRequestType member)
- AC_CACHE_VAL(ac_cv_usbdevfs_ctrltransfer_has_bRequestType,
- AC_TRY_COMPILE([
-AC_INCLUDES_DEFAULT
-#ifdef HAVE_SYS_BITYPES_H
-#include <sys/bitypes.h>
-#endif
-#ifdef HAVE_LINUX_COMPILER_H
-#include <linux/compiler.h>
-#endif
-#include <linux/usbdevice_fs.h>],
- [u_int i = sizeof(((struct usbdevfs_ctrltransfer *)0)->bRequestType)],
- ac_cv_usbdevfs_ctrltransfer_has_bRequestType=yes,
- ac_cv_usbdevfs_ctrltransfer_has_bRequestType=no))
- AC_MSG_RESULT($ac_cv_usbdevfs_ctrltransfer_has_bRequestType)
- if test $ac_cv_usbdevfs_ctrltransfer_has_bRequestType = yes ; then
- AC_DEFINE(HAVE_USBDEVFS_CTRLTRANSFER_BREQUESTTYPE,1,
- [if struct usbdevfs_ctrltransfer has bRequestType])
- fi
+ AC_CHECK_MEMBERS([struct usbdevfs_ctrltransfer.bRequestType],,,
+ [
+ AC_INCLUDES_DEFAULT
+ #ifdef HAVE_LINUX_COMPILER_H
+ #include <linux/compiler.h>
+ #endif
+ #include <linux/usbdevice_fs.h>
+ ])
fi
;;
freebsd*)
@@ -1582,9 +1985,9 @@ AC_INCLUDES_DEFAULT
#include <linux/netfilter/nfnetlink.h>
#include <linux/netfilter/nfnetlink_log.h>
#include <linux/netfilter/nfnetlink_queue.h>],
- [],
- ac_cv_netfilter_can_compile=yes,
- ac_cv_netfilter_can_compile=no))
+ [],
+ ac_cv_netfilter_can_compile=yes,
+ ac_cv_netfilter_can_compile=no))
AC_MSG_RESULT($ac_cv_netfilter_can_compile)
if test $ac_cv_netfilter_can_compile = yes ; then
AC_DEFINE(PCAP_SUPPORT_NETFILTER, 1,
@@ -1600,6 +2003,38 @@ fi
AC_SUBST(PCAP_SUPPORT_NETFILTER)
AC_SUBST(NETFILTER_SRC)
+AC_ARG_ENABLE([netmap],
+[AC_HELP_STRING([--enable-netmap],[enable netmap support @<:@default=yes, if support available@:>@])],
+ [],
+ [enable_netmap=yes])
+
+if test "x$enable_netmap" != "xno" ; then
+ #
+ # Check whether net/netmap_user.h is usable if NETMAP_WITH_LIBS is
+ # defined; it's not usable on DragonFly BSD 4.6 if NETMAP_WITH_LIBS
+ # is defined, for example, as it includes a non-existent malloc.h
+ # header.
+ #
+ AC_MSG_CHECKING(whether we can compile the netmap support)
+ AC_CACHE_VAL(ac_cv_net_netmap_user_can_compile,
+ AC_TRY_COMPILE([
+AC_INCLUDES_DEFAULT
+#define NETMAP_WITH_LIBS
+#include <net/netmap_user.h>],
+ [],
+ ac_cv_net_netmap_user_can_compile=yes,
+ ac_cv_net_netmap_user_can_compile=no))
+ AC_MSG_RESULT($ac_cv_net_netmap_user_can_compile)
+ if test $ac_cv_net_netmap_user_can_compile = yes ; then
+ AC_DEFINE(PCAP_SUPPORT_NETMAP, 1,
+ [target host supports netmap])
+ NETMAP_SRC=pcap-netmap.c
+ fi
+ AC_SUBST(PCAP_SUPPORT_NETMAP)
+ AC_SUBST(NETMAP_SRC)
+fi
+
+
AC_ARG_ENABLE([bluetooth],
[AC_HELP_STRING([--enable-bluetooth],[enable Bluetooth support @<:@default=yes, if support available@:>@])],
[],
@@ -1616,67 +2051,67 @@ if test "x$enable_bluetooth" != "xno" ; then
case "$host_os" in
linux*)
AC_CHECK_HEADER(bluetooth/bluetooth.h,
- [
- AC_DEFINE(PCAP_SUPPORT_BT, 1, [target host supports Bluetooth sniffing])
- BT_SRC=pcap-bt-linux.c
- AC_MSG_NOTICE(Bluetooth sniffing is supported)
-
- #
- # OK, does struct sockaddr_hci have an hci_channel
- # member?
- #
- AC_MSG_CHECKING(if struct sockaddr_hci has hci_channel member)
- AC_CACHE_VAL(ac_cv_lbl_sockaddr_hci_has_hci_channel,
- AC_TRY_COMPILE(
-[
-#include <bluetooth/bluetooth.h>
-#include <bluetooth/hci.h>
-],
- [u_int i = sizeof(((struct sockaddr_hci *)0)->hci_channel)],
- ac_cv_lbl_sockaddr_hci_has_hci_channel=yes,
- ac_cv_lbl_sockaddr_hci_has_hci_channel=no))
- AC_MSG_RESULT($ac_cv_lbl_sockaddr_hci_has_hci_channel)
- if test $ac_cv_lbl_sockaddr_hci_has_hci_channel = yes ; then
- AC_DEFINE(SOCKADDR_HCI_HAS_HCI_CHANNEL,,
- [if struct sockaddr_hci has hci_channel member])
-
- #
- # OK, is HCI_CHANNEL_MONITOR defined?
- #
- AC_MSG_CHECKING(if HCI_CHANNEL_MONITOR is defined)
- AC_CACHE_VAL(ac_cv_lbl_hci_channel_monitor_is_defined,
- AC_TRY_COMPILE(
-[
-#include <bluetooth/bluetooth.h>
-#include <bluetooth/hci.h>
-],
- [u_int i = HCI_CHANNEL_MONITOR],
- ac_cv_lbl_hci_channel_monitor_is_defined=yes,
- ac_cv_lbl_hci_channel_monitor_is_defined=no))
- AC_MSG_RESULT($ac_cv_lbl_hci_channel_monitor_is_defined)
- if test $ac_cv_lbl_hci_channel_monitor_is_defined = yes ; then
- AC_DEFINE(PCAP_SUPPORT_BT_MONITOR,,
- [target host supports Bluetooth Monitor])
- BT_MONITOR_SRC=pcap-bt-monitor-linux.c
- fi
- fi
- ac_lbl_bluetooth_available=yes
- ],
- ac_lbl_bluetooth_available=no
- )
- if test "x$ac_lbl_bluetooth_available" == "xno" ; then
- if test "x$enable_bluetooth" = "xyes" ; then
- AC_MSG_ERROR(Bluetooth sniffing is not supported; install bluez-lib devel to enable it)
- else
- AC_MSG_NOTICE(Bluetooth sniffing is not supported; install bluez-lib devel to enable it)
- fi
- fi
+ [
+ #
+ # We have bluetooth.h, so we support Bluetooth
+ # sniffing.
+ #
+ AC_DEFINE(PCAP_SUPPORT_BT, 1, [target host supports Bluetooth sniffing])
+ BT_SRC=pcap-bt-linux.c
+ AC_MSG_NOTICE(Bluetooth sniffing is supported)
+ ac_lbl_bluetooth_available=yes
+
+ #
+ # OK, does struct sockaddr_hci have an hci_channel
+ # member?
+ #
+ AC_CHECK_MEMBERS([struct sockaddr_hci.hci_channel],
+ [
+ #
+ # Yes; is HCI_CHANNEL_MONITOR defined?
+ #
+ AC_MSG_CHECKING(if HCI_CHANNEL_MONITOR is defined)
+ AC_CACHE_VAL(ac_cv_lbl_hci_channel_monitor_is_defined,
+ AC_TRY_COMPILE(
+ [
+ #include <bluetooth/bluetooth.h>
+ #include <bluetooth/hci.h>
+ ],
+ [
+ u_int i = HCI_CHANNEL_MONITOR;
+ ],
+ [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(PCAP_SUPPORT_BT_MONITOR,,
+ [target host supports Bluetooth Monitor])
+ BT_MONITOR_SRC=pcap-bt-monitor-linux.c
+ ],
+ [
+ AC_MSG_RESULT(no)
+ ]))
+ ],,
+ [
+ #include <bluetooth/bluetooth.h>
+ #include <bluetooth/hci.h>
+ ])
+ ],
+ [
+ #
+ # We don't have bluetooth.h, so we don't support
+ # Bluetooth sniffing.
+ #
+ if test "x$enable_bluetooth" = "xyes" ; then
+ AC_MSG_ERROR(Bluetooth sniffing is not supported; install bluez-lib devel to enable it)
+ else
+ AC_MSG_NOTICE(Bluetooth sniffing is not supported; install bluez-lib devel to enable it)
+ fi
+ ])
;;
*)
if test "x$enable_bluetooth" = "xyes" ; then
- AC_MSG_ERROR(no Bluetooth sniffing support implemented for $host_os)
+ AC_MSG_ERROR(no Bluetooth sniffing support implemented for $host_os)
else
- AC_MSG_NOTICE(no Bluetooth sniffing support implemented for $host_os)
+ AC_MSG_NOTICE(no Bluetooth sniffing support implemented for $host_os)
fi
;;
esac
@@ -1702,20 +2137,20 @@ if test "x$enable_dbus" != "xno"; then
darwin*)
#
- # We don't support D-Bus sniffing on OS X; see
+ # We don't support D-Bus sniffing on macOS; see
#
# https://bugs.freedesktop.org/show_bug.cgi?id=74029
#
# The user requested it, so fail.
#
- AC_MSG_ERROR([Due to freedesktop.org bug 74029, D-Bus capture support is not available on OS X])
+ AC_MSG_ERROR([Due to freedesktop.org bug 74029, D-Bus capture support is not available on macOS])
esac
else
case "$host_os" in
darwin*)
#
- # We don't support D-Bus sniffing on OS X; see
+ # We don't support D-Bus sniffing on macOS; see
#
# https://bugs.freedesktop.org/show_bug.cgi?id=74029
#
@@ -1774,32 +2209,54 @@ if test "x$enable_dbus" != "xno"; then
AC_SUBST(DBUS_SRC)
fi
-dnl check for hardware timestamp support
-case "$host_os" in
-linux*)
- AC_CHECK_HEADERS([linux/net_tstamp.h])
- ;;
-*)
- AC_MSG_NOTICE(no hardware timestamp support implemented for $host_os)
- ;;
-esac
+AC_ARG_ENABLE([rdma],
+[AC_HELP_STRING([--enable-rdma],[enable RDMA capture support @<:@default=yes, if support available@:>@])],
+ [],
+ [enable_rdmasniff=ifavailable])
-dnl The packet ring capture facility of Linux, described in
-dnl Documentation/networking/packet_mmap.txt, is not 32/64-bit compatible before
-dnl version 2.6.27. A 32-bit kernel requires a 32-bit userland, and likewise for
-dnl 64-bit. The effect of this is that a 32-bit libpcap binary will not run
-dnl correctly on a 64-bit kernel (the binary will use the wrong offsets into a
-dnl kernel struct). This problem was solved in Linux 2.6.27. Use
-dnl --disable-packet-ring whenever a 32-bit application must run on a 64-bit
-dnl target host, and either the build host or the target host run Linux 2.6.26
-dnl or earlier.
-AC_ARG_ENABLE([packet-ring],
-[AC_HELP_STRING([--enable-packet-ring],[enable Linux packet ring support @<:@default=yes@:>@])],
-,enable_packet_ring=yes)
+if test "xxx_only" = yes; then
+ # User requested something-else-only pcap, so they don't
+ # want RDMA support.
+ enable_rdmasniff=no
+fi
-if test "x$enable_packet_ring" != "xno" ; then
- AC_DEFINE(PCAP_SUPPORT_PACKET_RING, 1, [use Linux packet ring capture if available])
- AC_SUBST(PCAP_SUPPORT_PACKET_RING)
+if test "x$enable_rdmasniff" != "xno"; then
+ AC_CHECK_LIB(ibverbs, ibv_get_device_list, [
+ AC_CHECK_HEADER(infiniband/verbs.h, [
+ #
+ # ibv_create_flow may be defined as a static inline
+ # function in infiniband/verbs.h, so we can't
+ # use AC_CHECK_LIB.
+ #
+ # Too bad autoconf has no AC_SYMBOL_EXISTS()
+ # macro that works like CMake's check_symbol_exists()
+ # function, to check do a compile check like
+ # this (they do a clever trick to avoid having
+ # to know the function's signature).
+ #
+ AC_MSG_CHECKING(whether libibverbs defines ibv_create_flow)
+ AC_TRY_LINK(
+ [
+ #include <infiniband/verbs.h>
+ ],
+ [
+ (void) ibv_create_flow((struct ibv_qp *) NULL,
+ (struct ibv_flow_attr *) NULL);
+ ],
+ [
+ AC_MSG_RESULT([yes])
+ AC_DEFINE(PCAP_SUPPORT_RDMASNIFF, , [target host supports RDMA sniffing])
+ RDMA_SRC=pcap-rdmasniff.c
+ LIBS="-libverbs $LIBS"
+ ],
+ [
+ AC_MSG_RESULT([no])
+ ]
+ )
+ ])
+ ])
+ AC_SUBST(PCAP_SUPPORT_RDMASNIFF)
+ AC_SUBST(RDMA_SRC)
fi
AC_PROG_INSTALL
@@ -1808,7 +2265,7 @@ AC_CONFIG_HEADER(config.h)
AC_OUTPUT_COMMANDS([if test -f .devel; then
echo timestamp > stamp-h
- cat Makefile-devel-adds >> Makefile
+ cat $srcdir/Makefile-devel-adds >> Makefile
make depend
fi])
AC_OUTPUT(Makefile pcap-filter.manmisc pcap-linktype.manmisc
@@ -1817,5 +2274,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)
+ pcap_set_tstamp_type.3pcap rpcapd/Makefile rpcapd/rpcapd.manadmin
+ testprogs/Makefile)
exit 0
diff --git a/contrib/libpcap/diag-control.h b/contrib/libpcap/diag-control.h
new file mode 100644
index 0000000000000..1277036186331
--- /dev/null
+++ b/contrib/libpcap/diag-control.h
@@ -0,0 +1,215 @@
+/* -*- 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 _diag_control_h
+#define _diag_control_h
+
+#include "pcap/compiler-tests.h"
+
+#ifndef _MSC_VER
+ /*
+ * Clang and GCC both support this way of putting pragmas into #defines.
+ * We don't use it unless we have a compiler that supports it; the
+ * warning-suppressing pragmas differ between Clang and GCC, so we test
+ * for both of those separately.
+ */
+ #define PCAP_DO_PRAGMA(x) _Pragma (#x)
+#endif
+
+/*
+ * Suppress Flex warnings.
+ */
+#if defined(_MSC_VER)
+ /*
+ * This is Microsoft Visual Studio; we can use __pragma(warning(disable:XXXX))
+ * and __pragma(warning(push/pop)).
+ *
+ * Suppress signed-vs-unsigned comparison, narrowing, and unreachable
+ * code warnings.
+ */
+ #define DIAG_OFF_FLEX \
+ __pragma(warning(push)) \
+ __pragma(warning(disable:4127)) \
+ __pragma(warning(disable:4242)) \
+ __pragma(warning(disable:4244)) \
+ __pragma(warning(disable:4702))
+ #define DIAG_ON_FLEX __pragma(warning(pop))
+#elif PCAP_IS_AT_LEAST_CLANG_VERSION(2,8)
+ /*
+ * This is Clang 2.8 or later; we can use "clang diagnostic
+ * ignored -Wxxx" and "clang diagnostic push/pop".
+ *
+ * Suppress -Wdocumentation warnings; GCC doesn't support -Wdocumentation,
+ * at least according to the GCC 7.3 documentation. Apparently, Flex
+ * generates code that upsets at least some versions of Clang's
+ * -Wdocumentation.
+ */
+ #define DIAG_OFF_FLEX \
+ PCAP_DO_PRAGMA(clang diagnostic push) \
+ PCAP_DO_PRAGMA(clang diagnostic ignored "-Wsign-compare") \
+ PCAP_DO_PRAGMA(clang diagnostic ignored "-Wdocumentation") \
+ PCAP_DO_PRAGMA(clang diagnostic ignored "-Wmissing-noreturn") \
+ PCAP_DO_PRAGMA(clang diagnostic ignored "-Wunused-parameter") \
+ PCAP_DO_PRAGMA(clang diagnostic ignored "-Wunreachable-code")
+ #define DIAG_ON_FLEX \
+ PCAP_DO_PRAGMA(clang diagnostic pop)
+#elif PCAP_IS_AT_LEAST_GNUC_VERSION(4,6)
+ /*
+ * This is GCC 4.6 or later, or a compiler claiming to be that.
+ * We can use "GCC diagnostic ignored -Wxxx" (introduced in 4.2)
+ * and "GCC diagnostic push/pop" (introduced in 4.6).
+ */
+ #define DIAG_OFF_FLEX \
+ PCAP_DO_PRAGMA(GCC diagnostic push) \
+ PCAP_DO_PRAGMA(GCC diagnostic ignored "-Wsign-compare") \
+ PCAP_DO_PRAGMA(GCC diagnostic ignored "-Wunused-parameter") \
+ PCAP_DO_PRAGMA(GCC diagnostic ignored "-Wunreachable-code")
+ #define DIAG_ON_FLEX \
+ PCAP_DO_PRAGMA(GCC diagnostic pop)
+#else
+ /*
+ * Neither Visual Studio, nor Clang 2.8 or later, nor GCC 4.6 or later
+ * or a compiler claiming to be that; there's nothing we know of that
+ * we can do.
+ */
+ #define DIAG_OFF_FLEX
+ #define DIAG_ON_FLEX
+#endif
+
+#ifdef YYBYACC
+ /*
+ * Berkeley YACC.
+ *
+ * It generates a global declaration of yylval, or the appropriately
+ * prefixed version of yylval, in grammar.h, *even though it's been
+ * told to generate a pure parser, meaning it doesn't have any global
+ * variables*. Bison doesn't do this.
+ *
+ * That causes a warning due to the local declaration in the parser
+ * shadowing the global declaration.
+ *
+ * So, if the compiler warns about that, we turn off -Wshadow warnings.
+ */
+ #if defined(_MSC_VER)
+ /*
+ * This is Microsoft Visual Studio; we can use
+ * __pragma(warning(disable:XXXX)) and __pragma(warning(push/pop)).
+ *
+ * Suppress unreachable code warnings.
+ */
+ #define DIAG_OFF_BISON_BYACC \
+ __pragma(warning(push)) \
+ __pragma(warning(disable:4702))
+ #define DIAG_ON_BISON_BYACC __pragma(warning(pop))
+ #elif PCAP_IS_AT_LEAST_CLANG_VERSION(2,8)
+ /*
+ * This is Clang 2.8 or later; we can use "clang diagnostic
+ * ignored -Wxxx" and "clang diagnostic push/pop".
+ */
+ #define DIAG_OFF_BISON_BYACC \
+ PCAP_DO_PRAGMA(clang diagnostic push) \
+ PCAP_DO_PRAGMA(clang diagnostic ignored "-Wshadow") \
+ PCAP_DO_PRAGMA(clang diagnostic ignored "-Wunreachable-code")
+ #define DIAG_ON_BISON_BYACC \
+ PCAP_DO_PRAGMA(clang diagnostic pop)
+ #elif PCAP_IS_AT_LEAST_GNUC_VERSION(4,6)
+ /*
+ * This is GCC 4.6 or later, or a compiler claiming to be that.
+ * We can use "GCC diagnostic ignored -Wxxx" (introduced in 4.2)
+ * and "GCC diagnostic push/pop" (introduced in 4.6).
+ */
+ #define DIAG_OFF_BISON_BYACC \
+ PCAP_DO_PRAGMA(GCC diagnostic push) \
+ PCAP_DO_PRAGMA(GCC diagnostic ignored "-Wshadow") \
+ PCAP_DO_PRAGMA(GCC diagnostic ignored "-Wunreachable-code")
+ #define DIAG_ON_BISON_BYACC \
+ PCAP_DO_PRAGMA(GCC diagnostic pop)
+ #else
+ /*
+ * Neither Clang 2.8 or later nor GCC 4.6 or later or a compiler
+ * claiming to be that; there's nothing we know of that we can do.
+ */
+ #define DIAG_OFF_BISON_BYACC
+ #define DIAG_ON_BISON_BYACC
+ #endif
+#else
+ /*
+ * Bison.
+ */
+ #if defined(_MSC_VER)
+ /*
+ * This is Microsoft Visual Studio; we can use
+ * __pragma(warning(disable:XXXX)) and __pragma(warning(push/pop)).
+ *
+ * Suppress some /Wall warnings.
+ */
+ #define DIAG_OFF_BISON_BYACC \
+ __pragma(warning(push)) \
+ __pragma(warning(disable:4127)) \
+ __pragma(warning(disable:4242)) \
+ __pragma(warning(disable:4244)) \
+ __pragma(warning(disable:4702))
+ #define DIAG_ON_BISON_BYACC __pragma(warning(pop))
+ #elif PCAP_IS_AT_LEAST_CLANG_VERSION(2,8)
+ /*
+ * This is Clang 2.8 or later; we can use "clang diagnostic
+ * ignored -Wxxx" and "clang diagnostic push/pop".
+ */
+ #define DIAG_OFF_BISON_BYACC \
+ PCAP_DO_PRAGMA(clang diagnostic push) \
+ PCAP_DO_PRAGMA(clang diagnostic ignored "-Wunreachable-code")
+ #define DIAG_ON_BISON_BYACC \
+ PCAP_DO_PRAGMA(clang diagnostic pop)
+ #elif PCAP_IS_AT_LEAST_GNUC_VERSION(4,6)
+ /*
+ * This is GCC 4.6 or later, or a compiler claiming to be that.
+ * We can use "GCC diagnostic ignored -Wxxx" (introduced in 4.2)
+ * and "GCC diagnostic push/pop" (introduced in 4.6).
+ */
+ #define DIAG_OFF_BISON_BYACC \
+ PCAP_DO_PRAGMA(GCC diagnostic push) \
+ PCAP_DO_PRAGMA(GCC diagnostic ignored "-Wunreachable-code")
+ #define DIAG_ON_BISON_BYACC \
+ PCAP_DO_PRAGMA(GCC diagnostic pop)
+ #else
+ /*
+ * Neither Clang 2.8 or later nor GCC 4.6 or later or a compiler
+ * claiming to be that; there's nothing we know of that we can do.
+ */
+ #define DIAG_OFF_BISON_BYACC
+ #define DIAG_ON_BISON_BYACC
+ #endif
+#endif
+
+#endif /* _diag_control_h */
diff --git a/contrib/libpcap/dlpisubs.c b/contrib/libpcap/dlpisubs.c
index fb94a6057675c..5f6e41af80b5d 100644
--- a/contrib/libpcap/dlpisubs.c
+++ b/contrib/libpcap/dlpisubs.c
@@ -12,7 +12,7 @@
*/
#ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
#endif
#ifndef DL_IPATM
@@ -271,7 +271,16 @@ pcap_process_mactype(pcap_t *p, u_int mactype)
#ifdef DL_IPNET
case DL_IPNET:
- p->linktype = DLT_IPNET;
+ /*
+ * XXX - DL_IPNET devices default to "raw IP" rather than
+ * "IPNET header"; see
+ *
+ * http://seclists.org/tcpdump/2009/q1/202
+ *
+ * We'd have to do DL_IOC_IPNET_INFO to enable getting
+ * the IPNET header.
+ */
+ p->linktype = DLT_RAW;
p->offset = 0;
break;
#endif
@@ -349,7 +358,8 @@ pcap_alloc_databuf(pcap_t *p)
p->bufsize = PKTBUFSIZE;
p->buffer = malloc(p->bufsize + p->offset);
if (p->buffer == NULL) {
- strlcpy(p->errbuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "malloc");
return (-1);
}
@@ -383,6 +393,6 @@ strioctl(int fd, int cmd, int len, char *dp)
static void
pcap_stream_err(const char *func, int err, char *errbuf)
{
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", func, pcap_strerror(err));
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, err, "%s", func);
}
#endif
diff --git a/contrib/libpcap/etherent.c b/contrib/libpcap/etherent.c
index 5cfd1b4c3bbb6..5f499613e088e 100644
--- a/contrib/libpcap/etherent.c
+++ b/contrib/libpcap/etherent.c
@@ -20,22 +20,10 @@
*/
#ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
#endif
-#ifdef _WIN32
-#include <pcap-stdinc.h>
-#else /* _WIN32 */
-#if HAVE_INTTYPES_H
-#include <inttypes.h>
-#elif HAVE_STDINT_H
-#include <stdint.h>
-#endif
-#ifdef HAVE_SYS_BITYPES_H
-#include <sys/bitypes.h>
-#endif
-#include <sys/types.h>
-#endif /* _WIN32 */
+#include <pcap-types.h>
#include <ctype.h>
#include <memory.h>
@@ -50,26 +38,23 @@
#include "os-proto.h"
#endif
-static inline int xdtoi(int);
static inline int skip_space(FILE *);
static inline int skip_line(FILE *);
/* Hex digit to integer. */
-static inline int
-xdtoi(c)
- register int c;
+static inline u_char
+xdtoi(u_char c)
{
if (isdigit(c))
- return c - '0';
+ return (u_char)(c - '0');
else if (islower(c))
- return c - 'a' + 10;
+ return (u_char)(c - 'a' + 10);
else
- return c - 'A' + 10;
+ return (u_char)(c - 'A' + 10);
}
static inline int
-skip_space(f)
- FILE *f;
+skip_space(FILE *f)
{
int c;
@@ -81,8 +66,7 @@ skip_space(f)
}
static inline int
-skip_line(f)
- FILE *f;
+skip_line(FILE *f)
{
int c;
@@ -96,47 +80,61 @@ skip_line(f)
struct pcap_etherent *
pcap_next_etherent(FILE *fp)
{
- register int c, d, i;
+ register int c, i;
+ u_char d;
char *bp;
+ size_t namesize;
static struct pcap_etherent e;
memset((char *)&e, 0, sizeof(e));
- do {
+ for (;;) {
/* Find addr */
c = skip_space(fp);
+ if (c == EOF)
+ return (NULL);
if (c == '\n')
continue;
/* If this is a comment, or first thing on line
- cannot be etehrnet address, skip the line. */
+ cannot be Ethernet address, skip the line. */
if (!isxdigit(c)) {
c = skip_line(fp);
+ if (c == EOF)
+ return (NULL);
continue;
}
/* must be the start of an address */
for (i = 0; i < 6; i += 1) {
- d = xdtoi(c);
+ d = xdtoi((u_char)c);
c = getc(fp);
+ if (c == EOF)
+ return (NULL);
if (isxdigit(c)) {
d <<= 4;
- d |= xdtoi(c);
+ d |= xdtoi((u_char)c);
c = getc(fp);
+ if (c == EOF)
+ return (NULL);
}
e.addr[i] = d;
if (c != ':')
break;
c = getc(fp);
+ if (c == EOF)
+ return (NULL);
}
- if (c == EOF)
- break;
/* Must be whitespace */
if (!isspace(c)) {
c = skip_line(fp);
+ if (c == EOF)
+ return (NULL);
continue;
}
c = skip_space(fp);
+ if (c == EOF)
+ return (NULL);
/* hit end of line... */
if (c == '\n')
@@ -144,17 +142,21 @@ pcap_next_etherent(FILE *fp)
if (c == '#') {
c = skip_line(fp);
+ if (c == EOF)
+ return (NULL);
continue;
}
/* pick up name */
bp = e.name;
- /* Use 'd' to prevent buffer overflow. */
- d = sizeof(e.name) - 1;
+ /* Use 'namesize' to prevent buffer overflow. */
+ namesize = sizeof(e.name) - 1;
do {
- *bp++ = c;
+ *bp++ = (u_char)c;
c = getc(fp);
- } while (!isspace(c) && c != EOF && --d > 0);
+ if (c == EOF)
+ return (NULL);
+ } while (!isspace(c) && --namesize != 0);
*bp = '\0';
/* Eat trailing junk */
@@ -162,8 +164,5 @@ pcap_next_etherent(FILE *fp)
(void)skip_line(fp);
return &e;
-
- } while (c != EOF);
-
- return (NULL);
+ }
}
diff --git a/contrib/libpcap/extract.h b/contrib/libpcap/extract.h
index face5b7e94cd8..aa3ff99196e3a 100644
--- a/contrib/libpcap/extract.h
+++ b/contrib/libpcap/extract.h
@@ -23,6 +23,9 @@
#include <arpa/inet.h>
#endif
+#include <pcap/pcap-inttypes.h>
+#include <pcap/compiler-tests.h>
+
/*
* Macros to extract possibly-unaligned big-endian integral values.
*/
@@ -30,15 +33,16 @@
/*
* The processor doesn't natively handle unaligned loads.
*/
-#if defined(__GNUC__) && defined(HAVE___ATTRIBUTE__) && \
+#if PCAP_IS_AT_LEAST_GNUC_VERSION(2,0) && \
(defined(__alpha) || defined(__alpha__) || \
defined(__mips) || defined(__mips__))
-
/*
- * This is a GCC-compatible compiler and we have __attribute__, which
- * we assume that mean we have __attribute__((packed)), and this is
- * MIPS or Alpha, which has instructions that can help when doing
- * unaligned loads.
+ * This is MIPS or Alpha, which don't natively handle unaligned loads,
+ * but which have instructions that can help when doing unaligned
+ * loads, and this is GCC 2.0 or later or a compiler that claims to
+ * be GCC 2.0 or later, which we assume that mean we have
+ * __attribute__((packed)), which we can use to convince the compiler
+ * to generate those instructions.
*
* Declare packed structures containing a uint16_t and a uint32_t,
* cast the pointer to point to one of those, and fetch through it;
diff --git a/contrib/libpcap/fad-getad.c b/contrib/libpcap/fad-getad.c
index b67b5cdcd46aa..5236fbb94cda9 100644
--- a/contrib/libpcap/fad-getad.c
+++ b/contrib/libpcap/fad-getad.c
@@ -33,7 +33,7 @@
*/
#ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
#endif
#include <sys/types.h>
@@ -102,10 +102,10 @@
* all those systems we have "struct sockaddr_storage".
*/
#ifndef SA_LEN
-#ifdef HAVE_SOCKADDR_SA_LEN
+#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
#define SA_LEN(addr) ((addr)->sa_len)
-#else /* HAVE_SOCKADDR_SA_LEN */
-#ifdef HAVE_SOCKADDR_STORAGE
+#else /* HAVE_STRUCT_SOCKADDR_SA_LEN */
+#ifdef HAVE_STRUCT_SOCKADDR_STORAGE
static size_t
get_sa_len(struct sockaddr *addr)
{
@@ -131,10 +131,10 @@ get_sa_len(struct sockaddr *addr)
}
}
#define SA_LEN(addr) (get_sa_len(addr))
-#else /* HAVE_SOCKADDR_STORAGE */
+#else /* HAVE_STRUCT_SOCKADDR_STORAGE */
#define SA_LEN(addr) (sizeof (struct sockaddr))
-#endif /* HAVE_SOCKADDR_STORAGE */
-#endif /* HAVE_SOCKADDR_SA_LEN */
+#endif /* HAVE_STRUCT_SOCKADDR_STORAGE */
+#endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
#endif /* SA_LEN */
/*
@@ -144,10 +144,9 @@ get_sa_len(struct sockaddr *addr)
* could be opened.
*/
int
-pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf,
- int (*check_usable)(const char *))
+pcap_findalldevs_interfaces(pcap_if_list_t *devlistp, char *errbuf,
+ int (*check_usable)(const char *), get_if_flags_func get_flags_func)
{
- pcap_if_t *devlist = NULL;
struct ifaddrs *ifap, *ifa;
struct sockaddr *addr, *netmask, *broadaddr, *dstaddr;
size_t addr_size, broadaddr_size, dstaddr_size;
@@ -169,8 +168,8 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf,
* those.
*/
if (getifaddrs(&ifap) != 0) {
- (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "getifaddrs: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ errno, "getifaddrs");
return (-1);
}
for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
@@ -233,7 +232,7 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf,
/*
* Note that, on some platforms, ifa_broadaddr and
* ifa_dstaddr could be the same field (true on at
- * least some versions of *BSD and OS X), so we
+ * least some versions of *BSD and macOS), so we
* can't just check whether the broadcast address
* is null and add it if so and check whether the
* destination address is null and add it if so.
@@ -265,8 +264,8 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf,
/*
* Add information for this address to the list.
*/
- if (add_addr_to_iflist(&devlist, ifa->ifa_name,
- if_flags_to_pcap_flags(ifa->ifa_name, ifa->ifa_flags),
+ if (add_addr_to_if(devlistp, ifa->ifa_name, ifa->ifa_flags,
+ get_flags_func,
addr, addr_size, netmask, addr_size,
broadaddr, broadaddr_size, dstaddr, dstaddr_size,
errbuf) < 0) {
@@ -277,16 +276,5 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf,
freeifaddrs(ifap);
- if (ret == -1) {
- /*
- * We had an error; free the list we've been constructing.
- */
- if (devlist != NULL) {
- pcap_freealldevs(devlist);
- devlist = NULL;
- }
- }
-
- *alldevsp = devlist;
return (ret);
}
diff --git a/contrib/libpcap/fad-gifc.c b/contrib/libpcap/fad-gifc.c
index 1b24af2929853..6b1612747582e 100644
--- a/contrib/libpcap/fad-gifc.c
+++ b/contrib/libpcap/fad-gifc.c
@@ -33,7 +33,7 @@
*/
#ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
#endif
#include <sys/param.h>
@@ -57,6 +57,12 @@ struct rtentry; /* declarations in <net/if.h> */
#include <string.h>
#include <unistd.h>
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#else
+#define INT_MAX 2147483647
+#endif
+
#include "pcap-int.h"
#ifdef HAVE_OS_PROTO_H
@@ -89,11 +95,11 @@ struct rtentry; /* declarations in <net/if.h> */
* address in an entry returned by SIOCGIFCONF.
*/
#ifndef SA_LEN
-#ifdef HAVE_SOCKADDR_SA_LEN
+#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
#define SA_LEN(addr) ((addr)->sa_len)
-#else /* HAVE_SOCKADDR_SA_LEN */
+#else /* HAVE_STRUCT_SOCKADDR_SA_LEN */
#define SA_LEN(addr) (sizeof (struct sockaddr))
-#endif /* HAVE_SOCKADDR_SA_LEN */
+#endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
#endif /* SA_LEN */
/*
@@ -132,10 +138,9 @@ struct rtentry; /* declarations in <net/if.h> */
* we already have that.
*/
int
-pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf,
- int (*check_usable)(const char *))
+pcap_findalldevs_interfaces(pcap_if_list_t *devlistp, char *errbuf,
+ int (*check_usable)(const char *), get_if_flags_func get_flags_func)
{
- pcap_if_t *devlist = NULL;
register int fd;
register struct ifreq *ifrp, *ifend, *ifnext;
size_t n;
@@ -155,8 +160,8 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf,
*/
fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd < 0) {
- (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "socket: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ errno, "socket");
return (-1);
}
@@ -169,10 +174,20 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf,
*/
buf_size = 8192;
for (;;) {
+ /*
+ * Don't let the buffer size get bigger than INT_MAX.
+ */
+ if (buf_size > INT_MAX) {
+ (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "interface information requires more than %u bytes",
+ INT_MAX);
+ (void)close(fd);
+ return (-1);
+ }
buf = malloc(buf_size);
if (buf == NULL) {
- (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "malloc: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ errno, "malloc");
(void)close(fd);
return (-1);
}
@@ -182,13 +197,13 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf,
memset(buf, 0, buf_size);
if (ioctl(fd, SIOCGIFCONF, (char *)&ifc) < 0
&& errno != EINVAL) {
- (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "SIOCGIFCONF: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ errno, "SIOCGIFCONF");
(void)close(fd);
free(buf);
return (-1);
}
- if (ifc.ifc_len < buf_size &&
+ if (ifc.ifc_len < (int)buf_size &&
(buf_size - ifc.ifc_len) > sizeof(ifrp->ifr_name) + MAX_SA_LEN)
break;
free(buf);
@@ -255,11 +270,10 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf,
if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifrflags) < 0) {
if (errno == ENXIO)
continue;
- (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "SIOCGIFFLAGS: %.*s: %s",
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ errno, "SIOCGIFFLAGS: %.*s",
(int)sizeof(ifrflags.ifr_name),
- ifrflags.ifr_name,
- pcap_strerror(errno));
+ ifrflags.ifr_name);
ret = -1;
break;
}
@@ -279,11 +293,11 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf,
netmask = NULL;
netmask_size = 0;
} else {
- (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "SIOCGIFNETMASK: %.*s: %s",
+ pcap_fmt_errmsg_for_errno(errbuf,
+ PCAP_ERRBUF_SIZE, errno,
+ "SIOCGIFNETMASK: %.*s",
(int)sizeof(ifrnetmask.ifr_name),
- ifrnetmask.ifr_name,
- pcap_strerror(errno));
+ ifrnetmask.ifr_name);
ret = -1;
break;
}
@@ -310,11 +324,11 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf,
broadaddr = NULL;
broadaddr_size = 0;
} else {
- (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "SIOCGIFBRDADDR: %.*s: %s",
+ pcap_fmt_errmsg_for_errno(errbuf,
+ PCAP_ERRBUF_SIZE, errno,
+ "SIOCGIFBRDADDR: %.*s",
(int)sizeof(ifrbroadaddr.ifr_name),
- ifrbroadaddr.ifr_name,
- pcap_strerror(errno));
+ ifrbroadaddr.ifr_name);
ret = -1;
break;
}
@@ -349,11 +363,11 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf,
dstaddr = NULL;
dstaddr_size = 0;
} else {
- (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "SIOCGIFDSTADDR: %.*s: %s",
+ pcap_fmt_errmsg_for_errno(errbuf,
+ PCAP_ERRBUF_SIZE, errno,
+ "SIOCGIFDSTADDR: %.*s",
(int)sizeof(ifrdstaddr.ifr_name),
- ifrdstaddr.ifr_name,
- pcap_strerror(errno));
+ ifrdstaddr.ifr_name);
ret = -1;
break;
}
@@ -401,8 +415,8 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf,
/*
* Add information for this address to the list.
*/
- if (add_addr_to_iflist(&devlist, ifrp->ifr_name,
- if_flags_to_pcap_flags(ifrp->ifr_name, ifrflags.ifr_flags),
+ if (add_addr_to_if(devlistp, ifrp->ifr_name,
+ ifrflags.ifr_flags, get_flags_func,
&ifrp->ifr_addr, SA_LEN(&ifrp->ifr_addr),
netmask, netmask_size, broadaddr, broadaddr_size,
dstaddr, dstaddr_size, errbuf) < 0) {
@@ -413,16 +427,5 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf,
free(buf);
(void)close(fd);
- if (ret == -1) {
- /*
- * We had an error; free the list we've been constructing.
- */
- if (devlist != NULL) {
- pcap_freealldevs(devlist);
- devlist = NULL;
- }
- }
-
- *alldevsp = devlist;
return (ret);
}
diff --git a/contrib/libpcap/fad-glifc.c b/contrib/libpcap/fad-glifc.c
index 511481cf96368..f22f56d73eb7c 100644
--- a/contrib/libpcap/fad-glifc.c
+++ b/contrib/libpcap/fad-glifc.c
@@ -33,7 +33,7 @@
*/
#ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
#endif
#include <sys/param.h>
@@ -75,10 +75,9 @@ struct rtentry; /* declarations in <net/if.h> */
* SIOCGLIFCONF rather than SIOCGIFCONF in order to get IPv6 addresses.)
*/
int
-pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf,
- int (*check_usable)(const char *))
+pcap_findalldevs_interfaces(pcap_if_list_t *devlistp, char *errbuf,
+ int (*check_usable)(const char *), get_if_flags_func get_flags_func)
{
- pcap_if_t *devlist = NULL;
register int fd4, fd6, fd;
register struct lifreq *ifrp, *ifend;
struct lifnum ifn;
@@ -98,8 +97,8 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf,
*/
fd4 = socket(AF_INET, SOCK_DGRAM, 0);
if (fd4 < 0) {
- (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "socket: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ errno, "socket: AF_INET");
return (-1);
}
@@ -108,8 +107,8 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf,
*/
fd6 = socket(AF_INET6, SOCK_DGRAM, 0);
if (fd6 < 0) {
- (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "socket: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ errno, "socket: AF_INET6");
(void)close(fd4);
return (-1);
}
@@ -121,8 +120,8 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf,
ifn.lifn_flags = 0;
ifn.lifn_count = 0;
if (ioctl(fd4, SIOCGLIFNUM, (char *)&ifn) < 0) {
- (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "SIOCGLIFNUM: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ errno, "SIOCGLIFNUM");
(void)close(fd6);
(void)close(fd4);
return (-1);
@@ -134,8 +133,8 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf,
buf_size = ifn.lifn_count * sizeof (struct lifreq);
buf = malloc(buf_size);
if (buf == NULL) {
- (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "malloc: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ errno, "malloc");
(void)close(fd6);
(void)close(fd4);
return (-1);
@@ -150,8 +149,8 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf,
ifc.lifc_flags = 0;
memset(buf, 0, buf_size);
if (ioctl(fd4, SIOCGLIFCONF, (char *)&ifc) < 0) {
- (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "SIOCGLIFCONF: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ errno, "SIOCGLIFCONF");
(void)close(fd6);
(void)close(fd4);
free(buf);
@@ -199,11 +198,10 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf,
if (ioctl(fd, SIOCGLIFFLAGS, (char *)&ifrflags) < 0) {
if (errno == ENXIO)
continue;
- (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "SIOCGLIFFLAGS: %.*s: %s",
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ errno, "SIOCGLIFFLAGS: %.*s",
(int)sizeof(ifrflags.lifr_name),
- ifrflags.lifr_name,
- pcap_strerror(errno));
+ ifrflags.lifr_name);
ret = -1;
break;
}
@@ -222,11 +220,11 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf,
*/
netmask = NULL;
} else {
- (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "SIOCGLIFNETMASK: %.*s: %s",
+ pcap_fmt_errmsg_for_errno(errbuf,
+ PCAP_ERRBUF_SIZE, errno,
+ "SIOCGLIFNETMASK: %.*s",
(int)sizeof(ifrnetmask.lifr_name),
- ifrnetmask.lifr_name,
- pcap_strerror(errno));
+ ifrnetmask.lifr_name);
ret = -1;
break;
}
@@ -250,11 +248,11 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf,
*/
broadaddr = NULL;
} else {
- (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "SIOCGLIFBRDADDR: %.*s: %s",
+ pcap_fmt_errmsg_for_errno(errbuf,
+ PCAP_ERRBUF_SIZE, errno,
+ "SIOCGLIFBRDADDR: %.*s",
(int)sizeof(ifrbroadaddr.lifr_name),
- ifrbroadaddr.lifr_name,
- pcap_strerror(errno));
+ ifrbroadaddr.lifr_name);
ret = -1;
break;
}
@@ -285,11 +283,11 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf,
*/
dstaddr = NULL;
} else {
- (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "SIOCGLIFDSTADDR: %.*s: %s",
+ pcap_fmt_errmsg_for_errno(errbuf,
+ PCAP_ERRBUF_SIZE, errno,
+ "SIOCGLIFDSTADDR: %.*s",
(int)sizeof(ifrdstaddr.lifr_name),
- ifrdstaddr.lifr_name,
- pcap_strerror(errno));
+ ifrdstaddr.lifr_name);
ret = -1;
break;
}
@@ -329,8 +327,8 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf,
/*
* Add information for this address to the list.
*/
- if (add_addr_to_iflist(&devlist, ifrp->lifr_name,
- if_flags_to_pcap_flags(ifrp->lifr_name, ifrflags.lifr_flags),
+ if (add_addr_to_if(devlistp, ifrp->lifr_name,
+ ifrflags.lifr_flags, get_flags_func,
(struct sockaddr *)&ifrp->lifr_addr,
sizeof (struct sockaddr_storage),
netmask, sizeof (struct sockaddr_storage),
@@ -344,16 +342,5 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf,
(void)close(fd6);
(void)close(fd4);
- if (ret == -1) {
- /*
- * We had an error; free the list we've been constructing.
- */
- if (devlist != NULL) {
- pcap_freealldevs(devlist);
- devlist = NULL;
- }
- }
-
- *alldevsp = devlist;
return (ret);
}
diff --git a/contrib/libpcap/fad-helpers.c b/contrib/libpcap/fad-helpers.c
deleted file mode 100644
index 4860bc55ca802..0000000000000
--- a/contrib/libpcap/fad-helpers.c
+++ /dev/null
@@ -1,884 +0,0 @@
-/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */
-/*
- * Copyright (c) 1994, 1995, 1996, 1997, 1998
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the Computer Systems
- * Engineering Group at Lawrence Berkeley Laboratory.
- * 4. Neither the name of the University nor of the Laboratory may be used
- * to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#ifdef _WIN32
-#include <pcap-stdinc.h>
-#else /* _WIN32 */
-
-#include <sys/param.h>
-#ifndef MSDOS
-#include <sys/file.h>
-#endif
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-#ifdef HAVE_SYS_SOCKIO_H
-#include <sys/sockio.h>
-#endif
-
-struct mbuf; /* Squelch compiler warnings on some platforms for */
-struct rtentry; /* declarations in <net/if.h> */
-#include <net/if.h>
-#include <netinet/in.h>
-#endif /* _WIN32 */
-
-#include <ctype.h>
-#include <errno.h>
-#include <memory.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#if !defined(_WIN32) && !defined(__BORLANDC__)
-#include <unistd.h>
-#endif /* !_WIN32 && !__BORLANDC__ */
-#ifdef HAVE_LIMITS_H
-#include <limits.h>
-#else
-#define INT_MAX 2147483647
-#endif
-
-#include "pcap-int.h"
-
-#ifdef HAVE_OS_PROTO_H
-#include "os-proto.h"
-#endif
-
-#ifndef _WIN32
-/* Not all systems have IFF_LOOPBACK */
-#ifdef IFF_LOOPBACK
-#define ISLOOPBACK(name, flags) ((flags) & IFF_LOOPBACK)
-#else
-#define ISLOOPBACK(name, flags) ((name)[0] == 'l' && (name)[1] == 'o' && \
- (isdigit((unsigned char)((name)[2])) || (name)[2] == '\0'))
-#endif
-
-#ifdef IFF_UP
-#define ISUP(flags) ((flags) & IFF_UP)
-#else
-#define ISUP(flags) 0
-#endif
-
-#ifdef IFF_RUNNING
-#define ISRUNNING(flags) ((flags) & IFF_RUNNING)
-#else
-#define ISRUNNING(flags) 0
-#endif
-
-/*
- * Map UN*X-style interface flags to libpcap flags.
- */
-bpf_u_int32
-if_flags_to_pcap_flags(const char *name _U_, u_int if_flags)
-{
- bpf_u_int32 pcap_flags;
-
- pcap_flags = 0;
- if (ISLOOPBACK(name, if_flags))
- pcap_flags |= PCAP_IF_LOOPBACK;
- if (ISUP(if_flags))
- pcap_flags |= PCAP_IF_UP;
- if (ISRUNNING(if_flags))
- pcap_flags |= PCAP_IF_RUNNING;
- return (pcap_flags);
-}
-#endif
-
-static struct sockaddr *
-dup_sockaddr(struct sockaddr *sa, size_t sa_length)
-{
- struct sockaddr *newsa;
-
- if ((newsa = malloc(sa_length)) == NULL)
- return (NULL);
- return (memcpy(newsa, sa, sa_length));
-}
-
-/*
- * Construct a "figure of merit" for an interface, for use when sorting
- * the list of interfaces, in which interfaces that are up are superior
- * to interfaces that aren't up, interfaces that are up and running are
- * superior to interfaces that are up but not running, and non-loopback
- * interfaces that are up and running are superior to loopback interfaces,
- * and interfaces with the same flags have a figure of merit that's higher
- * the lower the instance number.
- *
- * The goal is to try to put the interfaces most likely to be useful for
- * capture at the beginning of the list.
- *
- * The figure of merit, which is lower the "better" the interface is,
- * has the uppermost bit set if the interface isn't running, the bit
- * below that set if the interface isn't up, the bit below that set
- * if the interface is a loopback interface, and the interface index
- * in the 29 bits below that. (Yes, we assume u_int is 32 bits.)
- */
-static u_int
-get_figure_of_merit(pcap_if_t *dev)
-{
- const char *cp;
- u_int n;
-
- if (strcmp(dev->name, "any") == 0) {
- /*
- * Give the "any" device an artificially high instance
- * number, so it shows up after all other non-loopback
- * interfaces.
- */
- n = 0x1FFFFFFF; /* 29 all-1 bits */
- } else {
- /*
- * A number at the end of the device name string is
- * assumed to be a unit number.
- */
- cp = dev->name + strlen(dev->name) - 1;
- while (cp-1 >= dev->name && *(cp-1) >= '0' && *(cp-1) <= '9')
- cp--;
- if (*cp >= '0' && *cp <= '9')
- n = atoi(cp);
- else
- n = 0;
- }
- if (!(dev->flags & PCAP_IF_RUNNING))
- n |= 0x80000000;
- if (!(dev->flags & PCAP_IF_UP))
- n |= 0x40000000;
- if (dev->flags & PCAP_IF_LOOPBACK)
- n |= 0x20000000;
- return (n);
-}
-
-/*
- * Try to get a description for a given device.
- * Returns a mallocated description if it could and NULL if it couldn't.
- *
- * XXX - on FreeBSDs that support it, should it get the sysctl named
- * "dev.{adapter family name}.{adapter unit}.%desc" to get a description
- * of the adapter? Note that "dev.an.0.%desc" is "Aironet PC4500/PC4800"
- * with my Cisco 350 card, so the name isn't entirely descriptive. The
- * "dev.an.0.%pnpinfo" has a better description, although one might argue
- * that the problem is really a driver bug - if it can find out that it's
- * a Cisco 340 or 350, rather than an old Aironet card, it should use
- * that in the description.
- *
- * Do NetBSD, DragonflyBSD, or OpenBSD support this as well? FreeBSD
- * and OpenBSD let you get a description, but it's not generated by the OS,
- * it's set with another ioctl that ifconfig supports; we use that to get
- * a description in FreeBSD and OpenBSD, but if there is no such
- * description available, it still might be nice to get some description
- * string based on the device type or something such as that.
- *
- * In OS X, the System Configuration framework can apparently return
- * names in 10.4 and later.
- *
- * It also appears that freedesktop.org's HAL offers an "info.product"
- * string, but the HAL specification says it "should not be used in any
- * UI" and "subsystem/capability specific properties" should be used
- * instead and, in any case, I think HAL is being deprecated in
- * favor of other stuff such as DeviceKit. DeviceKit doesn't appear
- * to have any obvious product information for devices, but maybe
- * I haven't looked hard enough.
- *
- * Using the System Configuration framework, or HAL, or DeviceKit, or
- * whatever, would require that libpcap applications be linked with
- * the frameworks/libraries in question. That shouldn't be a problem
- * for programs linking with the shared version of libpcap (unless
- * you're running on AIX - which I think is the only UN*X that doesn't
- * support linking a shared library with other libraries on which it
- * depends, and having an executable linked only with the first shared
- * library automatically pick up the other libraries when started -
- * and using HAL or whatever). Programs linked with the static
- * version of libpcap would have to use pcap-config with the --static
- * flag in order to get the right linker flags in order to pick up
- * the additional libraries/frameworks; those programs need that anyway
- * for libpcap 1.1 and beyond on Linux, as, by default, it requires
- * -lnl.
- *
- * Do any other UN*Xes, or desktop environments support getting a
- * description?
- */
-static char *
-get_if_description(const char *name)
-{
-#ifdef SIOCGIFDESCR
- char *description = NULL;
- int s;
- struct ifreq ifrdesc;
-#ifndef IFDESCRSIZE
- size_t descrlen = 64;
-#else
- size_t descrlen = IFDESCRSIZE;
-#endif /* IFDESCRSIZE */
-
- /*
- * Get the description for the interface.
- */
- memset(&ifrdesc, 0, sizeof ifrdesc);
- strlcpy(ifrdesc.ifr_name, name, sizeof ifrdesc.ifr_name);
- s = socket(AF_INET, SOCK_DGRAM, 0);
- if (s >= 0) {
-#ifdef __FreeBSD__
- /*
- * On FreeBSD, if the buffer isn't big enough for the
- * description, the ioctl succeeds, but the description
- * isn't copied, ifr_buffer.length is set to the description
- * length, and ifr_buffer.buffer is set to NULL.
- */
- for (;;) {
- free(description);
- if ((description = malloc(descrlen)) != NULL) {
- ifrdesc.ifr_buffer.buffer = description;
- ifrdesc.ifr_buffer.length = descrlen;
- if (ioctl(s, SIOCGIFDESCR, &ifrdesc) == 0) {
- if (ifrdesc.ifr_buffer.buffer ==
- description)
- break;
- else
- descrlen = ifrdesc.ifr_buffer.length;
- } else {
- /*
- * Failed to get interface description.
- */
- free(description);
- description = NULL;
- break;
- }
- } else
- break;
- }
-#else /* __FreeBSD__ */
- /*
- * The only other OS that currently supports
- * SIOCGIFDESCR is OpenBSD, and it has no way
- * to get the description length - it's clamped
- * to a maximum of IFDESCRSIZE.
- */
- if ((description = malloc(descrlen)) != NULL) {
- ifrdesc.ifr_data = (caddr_t)description;
- if (ioctl(s, SIOCGIFDESCR, &ifrdesc) != 0) {
- /*
- * Failed to get interface description.
- */
- free(description);
- description = NULL;
- }
- }
-#endif /* __FreeBSD__ */
- close(s);
- if (description != NULL && strlen(description) == 0) {
- /*
- * Description is empty, so discard it.
- */
- free(description);
- description = NULL;
- }
- }
-
-#ifdef __FreeBSD__
- /*
- * For FreeBSD, if we didn't get a description, and this is
- * a device with a name of the form usbusN, label it as a USB
- * bus.
- */
- if (description == NULL) {
- if (strncmp(name, "usbus", 5) == 0) {
- /*
- * OK, it begins with "usbus".
- */
- long busnum;
- char *p;
-
- errno = 0;
- busnum = strtol(name + 5, &p, 10);
- if (errno == 0 && p != name + 5 && *p == '\0' &&
- busnum >= 0 && busnum <= INT_MAX) {
- /*
- * OK, it's a valid number that's not
- * bigger than INT_MAX. Construct
- * a description from it.
- */
- 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);
- }
- }
- }
- }
-#endif
- return (description);
-#else /* SIOCGIFDESCR */
- return (NULL);
-#endif /* SIOCGIFDESCR */
-}
-
-/*
- * Look for a given device in the specified list of devices.
- *
- * If we find it, return 0 and set *curdev_ret to point to it.
- *
- * If we don't find it, check whether we can open it:
- *
- * If that fails with PCAP_ERROR_NO_SUCH_DEVICE or
- * PCAP_ERROR_IFACE_NOT_UP, don't attempt to add an entry for
- * it, as that probably means it exists but doesn't support
- * packet capture.
- *
- * Otherwise, attempt to add an entry for it, with the specified
- * ifnet flags and description, and, if that succeeds, return 0
- * and set *curdev_ret to point to the new entry, otherwise
- * return PCAP_ERROR and set errbuf to an error message. If we
- * weren't given a description, try to get one.
- */
-int
-add_or_find_if(pcap_if_t **curdev_ret, pcap_if_t **alldevs, const char *name,
- bpf_u_int32 flags, const char *description, char *errbuf)
-{
- pcap_t *p;
- pcap_if_t *curdev, *prevdev, *nextdev;
- u_int this_figure_of_merit, nextdev_figure_of_merit;
- char open_errbuf[PCAP_ERRBUF_SIZE];
- int ret;
-
- /*
- * Is there already an entry in the list for this interface?
- */
- for (curdev = *alldevs; curdev != NULL; curdev = curdev->next) {
- if (strcmp(name, curdev->name) == 0)
- break; /* yes, we found it */
- }
-
- if (curdev == NULL) {
- /*
- * No, we didn't find it.
- *
- * Can we open this interface for live capture?
- *
- * We do this check so that interfaces that are
- * supplied by the interface enumeration mechanism
- * we're using but that don't support packet capture
- * aren't included in the list. Loopback interfaces
- * on Solaris are an example of this; we don't just
- * omit loopback interfaces on all platforms because
- * you *can* capture on loopback interfaces on some
- * OSes.
- *
- * On OS X, we don't do this check if the device
- * name begins with "wlt"; at least some versions
- * of OS X offer monitor mode capturing by having
- * a separate "monitor mode" device for each wireless
- * adapter, rather than by implementing the ioctls
- * that {Free,Net,Open,DragonFly}BSD provide.
- * Opening that device puts the adapter into monitor
- * mode, which, at least for some adapters, causes
- * them to deassociate from the network with which
- * they're associated.
- *
- * Instead, we try to open the corresponding "en"
- * device (so that we don't end up with, for users
- * without sufficient privilege to open capture
- * devices, a list of adapters that only includes
- * the wlt devices).
- */
-#ifdef __APPLE__
- if (strncmp(name, "wlt", 3) == 0) {
- char *en_name;
- size_t en_name_len;
-
- /*
- * Try to allocate a buffer for the "en"
- * device's name.
- */
- en_name_len = strlen(name) - 1;
- en_name = malloc(en_name_len + 1);
- if (en_name == NULL) {
- (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "malloc: %s", pcap_strerror(errno));
- return (-1);
- }
- strcpy(en_name, "en");
- strcat(en_name, name + 3);
- p = pcap_create(en_name, open_errbuf);
- free(en_name);
- } else
-#endif /* __APPLE */
- p = pcap_create(name, open_errbuf);
- if (p == NULL) {
- /*
- * The attempt to create the pcap_t failed;
- * that's probably an indication that we're
- * out of memory.
- *
- * Don't bother including this interface,
- * but don't treat it as an error.
- */
- *curdev_ret = NULL;
- return (0);
- }
- /* Small snaplen, so we don't try to allocate much memory. */
- pcap_set_snaplen(p, 68);
- ret = pcap_activate(p);
- pcap_close(p);
- switch (ret) {
-
- case PCAP_ERROR_NO_SUCH_DEVICE:
- case PCAP_ERROR_IFACE_NOT_UP:
- /*
- * We expect these two errors - they're the
- * reason we try to open the device.
- *
- * PCAP_ERROR_NO_SUCH_DEVICE typically means
- * "there's no such device *known to the
- * OS's capture mechanism*", so, even though
- * it might be a valid network interface, you
- * can't capture on it (e.g., the loopback
- * device in Solaris up to Solaris 10, or
- * the vmnet devices in OS X with VMware
- * Fusion). We don't include those devices
- * in our list of devices, as there's no
- * point in doing so - they're not available
- * for capture.
- *
- * PCAP_ERROR_IFACE_NOT_UP means that the
- * OS's capture mechanism doesn't work on
- * interfaces not marked as up; some capture
- * mechanisms *do* support that, so we no
- * longer reject those interfaces out of hand,
- * but we *do* want to reject them if they
- * can't be opened for capture.
- */
- *curdev_ret = NULL;
- return (0);
- }
-
- /*
- * Yes, we can open it, or we can't, for some other
- * reason.
- *
- * If we can open it, we want to offer it for
- * capture, as you can capture on it. If we can't,
- * we want to offer it for capture, so that, if
- * the user tries to capture on it, they'll get
- * an error and they'll know why they can't
- * capture on it (e.g., insufficient permissions)
- * or they'll report it as a problem (and then
- * have the error message to provide as information).
- *
- * Allocate a new entry.
- */
- curdev = malloc(sizeof(pcap_if_t));
- if (curdev == NULL) {
- (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "malloc: %s", pcap_strerror(errno));
- return (-1);
- }
-
- /*
- * Fill in the entry.
- */
- curdev->next = NULL;
- curdev->name = strdup(name);
- if (curdev->name == NULL) {
- (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "malloc: %s", pcap_strerror(errno));
- free(curdev);
- return (-1);
- }
- if (description == NULL) {
- /*
- * We weren't handed a description for the
- * interface, so see if we can generate one
- * ourselves.
- */
- curdev->description = get_if_description(name);
- } else {
- /*
- * We were handed a description; make a copy.
- */
- curdev->description = strdup(description);
- if (curdev->description == NULL) {
- (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "malloc: %s", pcap_strerror(errno));
- free(curdev->name);
- free(curdev);
- return (-1);
- }
- }
- curdev->addresses = NULL; /* list starts out as empty */
- curdev->flags = flags;
-
- /*
- * Add it to the list, in the appropriate location.
- * First, get the "figure of merit" for this
- * interface.
- */
- this_figure_of_merit = get_figure_of_merit(curdev);
-
- /*
- * Now look for the last interface with an figure of merit
- * less than or equal to the new interface's figure of
- * merit.
- *
- * We start with "prevdev" being NULL, meaning we're before
- * the first element in the list.
- */
- prevdev = NULL;
- for (;;) {
- /*
- * Get the interface after this one.
- */
- if (prevdev == NULL) {
- /*
- * The next element is the first element.
- */
- nextdev = *alldevs;
- } else
- nextdev = prevdev->next;
-
- /*
- * Are we at the end of the list?
- */
- if (nextdev == NULL) {
- /*
- * Yes - we have to put the new entry
- * after "prevdev".
- */
- break;
- }
-
- /*
- * Is the new interface's figure of merit less
- * than the next interface's figure of merit,
- * meaning that the new interface is better
- * than the next interface?
- */
- nextdev_figure_of_merit = get_figure_of_merit(nextdev);
- if (this_figure_of_merit < nextdev_figure_of_merit) {
- /*
- * Yes - we should put the new entry
- * before "nextdev", i.e. after "prevdev".
- */
- break;
- }
-
- prevdev = nextdev;
- }
-
- /*
- * Insert before "nextdev".
- */
- curdev->next = nextdev;
-
- /*
- * Insert after "prevdev" - unless "prevdev" is null,
- * in which case this is the first interface.
- */
- if (prevdev == NULL) {
- /*
- * This is the first interface. Pass back a
- * pointer to it, and put "curdev" before
- * "nextdev".
- */
- *alldevs = curdev;
- } else
- prevdev->next = curdev;
- }
-
- *curdev_ret = curdev;
- return (0);
-}
-
-/*
- * Try to get a description for a given device, and then look for that
- * device in the specified list of devices.
- *
- * If we find it, then, if the specified address isn't null, add it to
- * the list of addresses for the device and return 0.
- *
- * If we don't find it, check whether we can open it:
- *
- * If that fails with PCAP_ERROR_NO_SUCH_DEVICE or
- * PCAP_ERROR_IFACE_NOT_UP, don't attempt to add an entry for
- * it, as that probably means it exists but doesn't support
- * packet capture.
- *
- * Otherwise, attempt to add an entry for it, with the specified
- * ifnet flags, and, if that succeeds, add the specified address
- * to its list of addresses if that address is non-null, set
- * *curdev_ret to point to the new entry, and return 0, otherwise
- * return PCAP_ERROR and set errbuf to an error message.
- *
- * (We can get called with a null address because we might get a list
- * of interface name/address combinations from the underlying OS, with
- * the address being absent in some cases, rather than a list of
- * interfaces with each interface having a list of addresses, so this
- * call may be the only call made to add to the list, and we want to
- * add interfaces even if they have no addresses.)
- */
-int
-add_addr_to_iflist(pcap_if_t **alldevs, const char *name, bpf_u_int32 flags,
- struct sockaddr *addr, size_t addr_size,
- struct sockaddr *netmask, size_t netmask_size,
- struct sockaddr *broadaddr, size_t broadaddr_size,
- struct sockaddr *dstaddr, size_t dstaddr_size,
- char *errbuf)
-{
- pcap_if_t *curdev;
-
- if (add_or_find_if(&curdev, alldevs, name, flags, NULL, errbuf) == -1) {
- /*
- * Error - give up.
- */
- return (-1);
- }
- if (curdev == NULL) {
- /*
- * Device wasn't added because it can't be opened.
- * Not a fatal error.
- */
- return (0);
- }
-
- if (addr == NULL) {
- /*
- * There's no address to add; this entry just meant
- * "here's a new interface".
- */
- return (0);
- }
-
- /*
- * "curdev" is an entry for this interface, and we have an
- * address for it; add an entry for that address to the
- * interface's list of addresses.
- *
- * Allocate the new entry and fill it in.
- */
- return (add_addr_to_dev(curdev, addr, addr_size, netmask,
- netmask_size, broadaddr, broadaddr_size, dstaddr,
- dstaddr_size, errbuf));
-}
-
-/*
- * Add an entry to the list of addresses for an interface.
- * "curdev" is the entry for that interface.
- * If this is the first IP address added to the interface, move it
- * in the list as appropriate.
- */
-int
-add_addr_to_dev(pcap_if_t *curdev,
- struct sockaddr *addr, size_t addr_size,
- struct sockaddr *netmask, size_t netmask_size,
- struct sockaddr *broadaddr, size_t broadaddr_size,
- struct sockaddr *dstaddr, size_t dstaddr_size,
- char *errbuf)
-{
- pcap_addr_t *curaddr, *prevaddr, *nextaddr;
-
- curaddr = malloc(sizeof(pcap_addr_t));
- if (curaddr == NULL) {
- (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "malloc: %s", pcap_strerror(errno));
- return (-1);
- }
-
- curaddr->next = NULL;
- if (addr != NULL) {
- curaddr->addr = dup_sockaddr(addr, addr_size);
- if (curaddr->addr == NULL) {
- (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "malloc: %s", pcap_strerror(errno));
- free(curaddr);
- return (-1);
- }
- } else
- curaddr->addr = NULL;
-
- if (netmask != NULL) {
- curaddr->netmask = dup_sockaddr(netmask, netmask_size);
- if (curaddr->netmask == NULL) {
- (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "malloc: %s", pcap_strerror(errno));
- if (curaddr->addr != NULL)
- free(curaddr->addr);
- free(curaddr);
- return (-1);
- }
- } else
- curaddr->netmask = NULL;
-
- if (broadaddr != NULL) {
- curaddr->broadaddr = dup_sockaddr(broadaddr, broadaddr_size);
- if (curaddr->broadaddr == NULL) {
- (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "malloc: %s", pcap_strerror(errno));
- if (curaddr->netmask != NULL)
- free(curaddr->netmask);
- if (curaddr->addr != NULL)
- free(curaddr->addr);
- free(curaddr);
- return (-1);
- }
- } else
- curaddr->broadaddr = NULL;
-
- if (dstaddr != NULL) {
- curaddr->dstaddr = dup_sockaddr(dstaddr, dstaddr_size);
- if (curaddr->dstaddr == NULL) {
- (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "malloc: %s", pcap_strerror(errno));
- if (curaddr->broadaddr != NULL)
- free(curaddr->broadaddr);
- if (curaddr->netmask != NULL)
- free(curaddr->netmask);
- if (curaddr->addr != NULL)
- free(curaddr->addr);
- free(curaddr);
- return (-1);
- }
- } else
- curaddr->dstaddr = NULL;
-
- /*
- * Find the end of the list of addresses.
- */
- for (prevaddr = curdev->addresses; prevaddr != NULL; prevaddr = nextaddr) {
- nextaddr = prevaddr->next;
- if (nextaddr == NULL) {
- /*
- * This is the end of the list.
- */
- break;
- }
- }
-
- if (prevaddr == NULL) {
- /*
- * The list was empty; this is the first member.
- */
- curdev->addresses = curaddr;
- } else {
- /*
- * "prevaddr" is the last member of the list; append
- * this member to it.
- */
- prevaddr->next = curaddr;
- }
-
- return (0);
-}
-
-/*
- * Look for a given device in the specified list of devices.
- *
- * If we find it, return 0.
- *
- * If we don't find it, check whether we can open it:
- *
- * If that fails with PCAP_ERROR_NO_SUCH_DEVICE or
- * PCAP_ERROR_IFACE_NOT_UP, don't attempt to add an entry for
- * it, as that probably means it exists but doesn't support
- * packet capture.
- *
- * Otherwise, attempt to add an entry for it, with the specified
- * ifnet flags and description, and, if that succeeds, return 0
- * and set *curdev_ret to point to the new entry, otherwise
- * return PCAP_ERROR and set errbuf to an error message.
- */
-int
-pcap_add_if(pcap_if_t **devlist, const char *name, u_int flags,
- const char *description, char *errbuf)
-{
- pcap_if_t *curdev;
-
- return (add_or_find_if(&curdev, devlist, name, flags, description,
- errbuf));
-}
-
-
-/*
- * Free a list of interfaces.
- */
-void
-pcap_freealldevs(pcap_if_t *alldevs)
-{
- pcap_if_t *curdev, *nextdev;
- pcap_addr_t *curaddr, *nextaddr;
-
- for (curdev = alldevs; curdev != NULL; curdev = nextdev) {
- nextdev = curdev->next;
-
- /*
- * Free all addresses.
- */
- for (curaddr = curdev->addresses; curaddr != NULL; curaddr = nextaddr) {
- nextaddr = curaddr->next;
- if (curaddr->addr)
- free(curaddr->addr);
- if (curaddr->netmask)
- free(curaddr->netmask);
- if (curaddr->broadaddr)
- free(curaddr->broadaddr);
- if (curaddr->dstaddr)
- free(curaddr->dstaddr);
- free(curaddr);
- }
-
- /*
- * Free the name string.
- */
- free(curdev->name);
-
- /*
- * Free the description string, if any.
- */
- if (curdev->description != NULL)
- free(curdev->description);
-
- /*
- * Free the interface.
- */
- free(curdev);
- }
-}
diff --git a/contrib/libpcap/fad-win32.c b/contrib/libpcap/fad-win32.c
deleted file mode 100644
index 0de893ef54877..0000000000000
--- a/contrib/libpcap/fad-win32.c
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * Copyright (c) 2002 - 2005 NetGroup, Politecnico di Torino (Italy)
- * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the Politecnico di Torino, CACE Technologies
- * nor the names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <pcap.h>
-#include <pcap-int.h>
-#include <Packet32.h>
-
-#include <errno.h>
-
-static int
-pcap_add_if_win32(pcap_if_t **devlist, char *name, const char *desc,
- char *errbuf)
-{
- pcap_if_t *curdev;
- npf_if_addr if_addrs[MAX_NETWORK_ADDRESSES];
- LONG if_addr_size;
- int res = 0;
-
- if_addr_size = MAX_NETWORK_ADDRESSES;
-
- /*
- * Add an entry for this interface, with no addresses.
- */
- if (add_or_find_if(&curdev, devlist, name, 0, desc, errbuf) == -1) {
- /*
- * Failure.
- */
- return (-1);
- }
-
- /*
- * Get the list of addresses for the interface.
- */
- if (!PacketGetNetInfoEx((void *)name, if_addrs, &if_addr_size)) {
- /*
- * Failure.
- *
- * We don't return an error, because this can happen with
- * NdisWan interfaces, and we want to supply them even
- * if we can't supply their addresses.
- *
- * We return an entry with an empty address list.
- */
- return (0);
- }
-
- /*
- * Now add the addresses.
- */
- while (if_addr_size-- > 0) {
- /*
- * "curdev" is an entry for this interface; add an entry for
- * this address to its list of addresses.
- */
- if(curdev == NULL)
- break;
- res = add_addr_to_dev(curdev,
- (struct sockaddr *)&if_addrs[if_addr_size].IPAddress,
- sizeof (struct sockaddr_storage),
- (struct sockaddr *)&if_addrs[if_addr_size].SubnetMask,
- sizeof (struct sockaddr_storage),
- (struct sockaddr *)&if_addrs[if_addr_size].Broadcast,
- sizeof (struct sockaddr_storage),
- NULL,
- 0,
- errbuf);
- if (res == -1) {
- /*
- * Failure.
- */
- break;
- }
- }
-
- return (res);
-}
-
-
-/*
- * Get a list of all interfaces that are up and that we can open.
- * Returns -1 on error, 0 otherwise.
- * The list, as returned through "alldevsp", may be null if no interfaces
- * were up and could be opened.
- *
- * Win32 implementation, based on WinPcap
- */
-int
-pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
-{
- pcap_if_t *devlist = NULL;
- int ret = 0;
- const char *desc;
- char *AdaptersName;
- ULONG NameLength;
- char *name;
-
- /*
- * Find out how big a buffer we need.
- *
- * This call should always return FALSE; if the error is
- * ERROR_INSUFFICIENT_BUFFER, NameLength will be set to
- * the size of the buffer we need, otherwise there's a
- * problem, and NameLength should be set to 0.
- *
- * It shouldn't require NameLength to be set, but,
- * at least as of WinPcap 4.1.3, it checks whether
- * NameLength is big enough before it checks for a
- * NULL buffer argument, so, while it'll still do
- * the right thing if NameLength is uninitialized and
- * whatever junk happens to be there is big enough
- * (because the pointer argument will be null), it's
- * still reading an uninitialized variable.
- */
- NameLength = 0;
- if (!PacketGetAdapterNames(NULL, &NameLength))
- {
- DWORD last_error = GetLastError();
-
- if (last_error != ERROR_INSUFFICIENT_BUFFER)
- {
- snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "PacketGetAdapterNames: %s",
- pcap_win32strerror());
- return (-1);
- }
- }
-
- if (NameLength > 0)
- AdaptersName = (char*) malloc(NameLength);
- else
- {
- *alldevsp = NULL;
- return 0;
- }
- if (AdaptersName == NULL)
- {
- snprintf(errbuf, PCAP_ERRBUF_SIZE, "Cannot allocate enough memory to list the adapters.");
- return (-1);
- }
-
- if (!PacketGetAdapterNames(AdaptersName, &NameLength)) {
- snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "PacketGetAdapterNames: %s",
- pcap_win32strerror());
- free(AdaptersName);
- return (-1);
- }
-
- /*
- * "PacketGetAdapterNames()" returned a list of
- * null-terminated ASCII interface name strings,
- * terminated by a null string, followed by a list
- * of null-terminated ASCII interface description
- * strings, terminated by a null string.
- * This means there are two ASCII nulls at the end
- * of the first list.
- *
- * Find the end of the first list; that's the
- * beginning of the second list.
- */
- desc = &AdaptersName[0];
- while (*desc != '\0' || *(desc + 1) != '\0')
- desc++;
-
- /*
- * Found it - "desc" points to the first of the two
- * nulls at the end of the list of names, so the
- * first byte of the list of descriptions is two bytes
- * after it.
- */
- desc += 2;
-
- /*
- * Loop over the elements in the first list.
- */
- name = &AdaptersName[0];
- while (*name != '\0') {
- /*
- * Add an entry for this interface.
- */
- if (pcap_add_if_win32(&devlist, name, desc, errbuf) == -1) {
- /*
- * Failure.
- */
- ret = -1;
- break;
- }
- name += strlen(name) + 1;
- desc += strlen(desc) + 1;
- }
-
- if (ret != -1) {
- /*
- * We haven't had any errors yet; do any platform-specific
- * operations to add devices.
- */
- if (pcap_platform_finddevs(&devlist, errbuf) < 0)
- ret = -1;
- }
-
- if (ret == -1) {
- /*
- * We had an error; free the list we've been constructing.
- */
- if (devlist != NULL) {
- pcap_freealldevs(devlist);
- devlist = NULL;
- }
- }
-
- *alldevsp = devlist;
- free(AdaptersName);
- return (ret);
-}
diff --git a/contrib/libpcap/fmtutils.c b/contrib/libpcap/fmtutils.c
new file mode 100644
index 0000000000000..f1a8907327deb
--- /dev/null
+++ b/contrib/libpcap/fmtutils.c
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 1993, 1994, 1995, 1996, 1997, 1998
+ * 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.
+ */
+
+/*
+ * Utilities for message formatting used both by libpcap and rpcapd.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "ftmacros.h"
+
+#include <stddef.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include <pcap/pcap.h>
+
+#include "portability.h"
+
+#include "fmtutils.h"
+
+/*
+ * Generate an error message based on a format, arguments, and an
+ * errno, with a message for the errno after the formatted output.
+ */
+void
+pcap_fmt_errmsg_for_errno(char *errbuf, size_t errbuflen, int errnum,
+ const char *fmt, ...)
+{
+ va_list ap;
+ 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);
+ 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.
+ */
+#if defined(HAVE_STRERROR_S)
+ err = strerror_s(p, errbuflen_remaining, errnum);
+ if (err != 0) {
+ /*
+ * It doesn't appear to be documented anywhere obvious
+ * what the error returns from strerror_s().
+ */
+ pcap_snprintf(p, errbuflen_remaining, "Error %d", errnum);
+ }
+#elif defined(HAVE_STRERROR_R)
+ err = strerror_r(errnum, p, errbuflen_remaining);
+ if (err == EINVAL) {
+ /*
+ * UNIX 03 says this isn't guaranteed to produce a
+ * fallback error message.
+ */
+ pcap_snprintf(p, errbuflen_remaining, "Unknown error: %d",
+ errnum);
+ } else if (err == ERANGE) {
+ /*
+ * UNIX 03 says this isn't guaranteed to produce a
+ * fallback error message.
+ */
+ pcap_snprintf(p, errbuflen_remaining,
+ "Message for error %d is too long", errnum);
+ }
+#else
+ /*
+ * We have neither strerror_s() nor strerror_r(), so we're
+ * stuck with using pcap_strerror().
+ */
+ pcap_snprintf(p, errbuflen_remaining, "%s", pcap_strerror(errnum));
+#endif
+}
diff --git a/contrib/libpcap/fmtutils.h b/contrib/libpcap/fmtutils.h
new file mode 100644
index 0000000000000..62c78fdba1b25
--- /dev/null
+++ b/contrib/libpcap/fmtutils.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 1994, 1995, 1996
+ * 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 fmtutils_h
+#define fmtutils_h
+
+#include "pcap/funcattrs.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void pcap_fmt_errmsg_for_errno(char *, size_t, int,
+ PCAP_FORMAT_STRING(const char *), ...) PCAP_PRINTFLIKE(4, 5);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/contrib/libpcap/ftmacros.h b/contrib/libpcap/ftmacros.h
new file mode 100644
index 0000000000000..de8da98e38b6d
--- /dev/null
+++ b/contrib/libpcap/ftmacros.h
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 1994, 1995, 1996
+ * 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 ftmacros_h
+#define ftmacros_h
+
+/*
+ * Define some feature test macros to make sure that everything we want
+ * to be declared gets declared.
+ *
+ * On some UN*Xes we need to force strtok_r() to be declared.
+ * We do *NOT* want to define _POSIX_C_SOURCE, as that tends
+ * to make non-POSIX APIs that we use unavailable.
+ * XXX - is there no portable way to say "please pollute the
+ * namespace to the maximum extent possible"?
+ */
+#if defined(sun) || defined(__sun)
+ #define __EXTENSIONS__
+
+ /*
+ * We also need to define _XPG4_2 in order to get
+ * the Single UNIX Specification version of
+ * recvmsg().
+ */
+ #define _XPG4_2
+#elif defined(_hpux) || defined(hpux) || defined(__hpux)
+ #define _REENTRANT
+
+ /*
+ * We need this to get the versions of socket functions that
+ * use socklen_t. Define it only if it's not already defined,
+ * so we don't get redefiniton warnings.
+ */
+ #ifndef _XOPEN_SOURCE_EXTENDED
+ #define _XOPEN_SOURCE_EXTENDED
+ #endif
+
+ /*
+ * XXX - the list of PA-RISC options for GCC makes it sound as if
+ * building code that uses a particular vintage of UNIX API/ABI
+ * is complicated:
+ *
+ * https://gcc.gnu.org/onlinedocs/gcc/HPPA-Options.html
+ *
+ * See the description of the -munix flag.
+ *
+ * We probably want libpcap to work with programs built for any
+ * UN*X standard. I'm not sure whether that's possible and, if
+ * it is, what sort of stuff it'd have to do.
+ *
+ * It might also be a requirement that we build with a special
+ * flag to allow the library to be used with threaded code, at
+ * least with HP's C compiler; hopefully doing so won't make it
+ * *not* work with *un*-threaded code.
+ */
+#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.
+ *
+ * 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.
+ */
+ #define _POSIX_C_SOURCE 200809L
+ #define _XOPEN_SOURCE 600
+
+ /*
+ * We turn on both _DEFAULT_SOURCE and _BSD_SOURCE to try to get
+ * the BSD u_XXX types, such as u_int and u_short, defined. We
+ * define _DEFAULT_SOURCE first, so that newer versions of GNU libc
+ * don't whine about _BSD_SOURCE being deprecated; we still have
+ * to define _BSD_SOURCE to handle older versions of GNU libc that
+ * don't support _DEFAULT_SOURCE.
+ */
+ #define _DEFAULT_SOURCE
+ #define _BSD_SOURCE
+#endif
+
+#endif
diff --git a/contrib/libpcap/gen_version_c.sh b/contrib/libpcap/gen_version_c.sh
deleted file mode 100755
index d5a5e75bfec8e..0000000000000
--- a/contrib/libpcap/gen_version_c.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-#! /bin/sh
-echo '#include <pcap/export-defs.h>' > "$2"
-echo 'PCAP_API_DEF' >> "$2"
-if grep GIT "$1" >/dev/null; then
- read ver <"$1"
- echo $ver | tr -d '\012'
- date +_%Y_%m_%d
-else
- cat "$1"
-fi | sed -e 's/.*/char pcap_version[] = "&";/' >> "$2"
-
diff --git a/contrib/libpcap/gen_version_header.sh b/contrib/libpcap/gen_version_header.sh
deleted file mode 100755
index 6b4b82da1af7e..0000000000000
--- a/contrib/libpcap/gen_version_header.sh
+++ /dev/null
@@ -1,19 +0,0 @@
-#! /bin/sh
-print_version_string()
-{
- if grep GIT "$1" >/dev/null
- then
- read ver <"$1"
- echo $ver | tr -d '\012'
- date +_%Y_%m_%d
- else
- cat "$1"
- fi
-}
-if test $# != 3
-then
- echo "Usage: gen_version_header.sh <version file> <template> <output file>" 1>&2
- exit 1
-fi
-version_string=`print_version_string "$1"`
-sed "s/%%LIBPCAP_VERSION%%/$version_string/" "$2" >"$3"
diff --git a/contrib/libpcap/gencode.c b/contrib/libpcap/gencode.c
index 406c08358ba20..959a56e6e5e6c 100644
--- a/contrib/libpcap/gencode.c
+++ b/contrib/libpcap/gencode.c
@@ -18,38 +18,24 @@
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * $FreeBSD$
*/
#ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
#endif
+#include <pcap-types.h>
#ifdef _WIN32
-#include <pcap-stdinc.h>
-#else /* _WIN32 */
-#if HAVE_INTTYPES_H
-#include <inttypes.h>
-#elif HAVE_STDINT_H
-#include <stdint.h>
-#endif
-#ifdef HAVE_SYS_BITYPES_H
-#include <sys/bitypes.h>
-#endif
-#include <sys/types.h>
-#include <sys/socket.h>
-#endif /* _WIN32 */
-
-#ifndef _WIN32
-
-#ifdef __NetBSD__
-#include <sys/param.h>
-#endif
+ #include <ws2tcpip.h>
+#else
+ #include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
+ #ifdef __NetBSD__
+ #include <sys/param.h>
+ #endif
+ #include <netinet/in.h>
+ #include <arpa/inet.h>
#endif /* _WIN32 */
#include <stdlib.h>
@@ -96,17 +82,17 @@
#define offsetof(s, e) ((size_t)&((s *)0)->e)
#endif
-#ifdef INET6
#ifdef _WIN32
-#if defined(__MINGW32__) && defined(DEFINE_ADDITIONAL_IPV6_STUFF)
+ #ifdef INET6
+ #if defined(__MINGW32__) && defined(DEFINE_ADDITIONAL_IPV6_STUFF)
/* IPv6 address */
struct in6_addr
{
union
{
- u_int8_t u6_addr8[16];
- u_int16_t u6_addr16[8];
- u_int32_t u6_addr32[4];
+ uint8_t u6_addr8[16];
+ uint16_t u6_addr16[8];
+ uint32_t u6_addr32[4];
} in6_u;
#define s6_addr in6_u.u6_addr8
#define s6_addr16 in6_u.u6_addr16
@@ -123,12 +109,12 @@ typedef unsigned short sa_family_t;
struct sockaddr_in6
{
__SOCKADDR_COMMON (sin6_);
- u_int16_t sin6_port; /* Transport layer port # */
- u_int32_t sin6_flowinfo; /* IPv6 flow information */
+ uint16_t sin6_port; /* Transport layer port # */
+ uint32_t sin6_flowinfo; /* IPv6 flow information */
struct in6_addr sin6_addr; /* IPv6 address */
};
-#ifndef EAI_ADDRFAMILY
+ #ifndef EAI_ADDRFAMILY
struct addrinfo {
int ai_flags; /* AI_PASSIVE, AI_CANONNAME */
int ai_family; /* PF_xxx */
@@ -139,12 +125,12 @@ struct addrinfo {
struct sockaddr *ai_addr; /* binary address */
struct addrinfo *ai_next; /* next structure in linked list */
};
-#endif /* EAI_ADDRFAMILY */
-#endif /* defined(__MINGW32__) && defined(DEFINE_ADDITIONAL_IPV6_STUFF) */
+ #endif /* EAI_ADDRFAMILY */
+ #endif /* defined(__MINGW32__) && defined(DEFINE_ADDITIONAL_IPV6_STUFF) */
+ #endif /* INET6 */
#else /* _WIN32 */
-#include <netdb.h> /* for "struct addrinfo" */
+ #include <netdb.h> /* for "struct addrinfo" */
#endif /* _WIN32 */
-#endif /* INET6 */
#include <pcap/namedb.h>
#include "nametoaddr.h"
@@ -279,7 +265,6 @@ struct _compiler_state {
/* XXX */
u_int pcap_fddipad;
-#ifdef INET6
/*
* As errors are handled by a longjmp, anything allocated must
* be freed in the longjmp handler, so it must be reachable
@@ -290,7 +275,6 @@ struct _compiler_state {
* any addrinfo structure that would need to be freed.
*/
struct addrinfo *ai;
-#endif
/*
* Various code constructs need to know the layout of the packet.
@@ -360,6 +344,11 @@ struct _compiler_state {
int is_geneve;
/*
+ * TRUE if we need variable length part of VLAN offset
+ */
+ int is_vlan_vloffset;
+
+ /*
* These are offsets for the ATM pseudo-header.
*/
u_int off_vpi;
@@ -428,7 +417,7 @@ struct _compiler_state {
int cur_chunk;
};
-void
+void PCAP_NORETURN
bpf_syntax_error(compiler_state_t *cstate, const char *msg)
{
bpf_error(cstate, "syntax error in filter expression: %s", msg);
@@ -436,7 +425,7 @@ bpf_syntax_error(compiler_state_t *cstate, const char *msg)
}
/* VARARGS */
-void
+void PCAP_NORETURN
bpf_error(compiler_state_t *cstate, const char *fmt, ...)
{
va_list ap;
@@ -526,7 +515,7 @@ static struct block *gen_host6(compiler_state_t *, struct in6_addr *,
#endif
#ifndef INET6
static struct block *gen_gateway(compiler_state_t *, const u_char *,
- bpf_u_int32 **, int, int);
+ struct addrinfo *, int, int);
#endif
static struct block *gen_ipfrag(compiler_state_t *);
static struct block *gen_portatom(compiler_state_t *, int, bpf_int32);
@@ -585,7 +574,8 @@ newchunk(compiler_state_t *cstate, size_t n)
cp = &cstate->chunks[cstate->cur_chunk];
if (n > cp->n_left) {
- ++cp, k = ++cstate->cur_chunk;
+ ++cp;
+ k = ++cstate->cur_chunk;
if (k >= NCHUNKS)
bpf_error(cstate, "out of memory");
size = CHUNK0SIZE << k;
@@ -656,7 +646,7 @@ gen_retblk(compiler_state_t *cstate, int v)
return b;
}
-static inline void
+static inline PCAP_NORETURN_DEF void
syntax(compiler_state_t *cstate)
{
bpf_error(cstate, "syntax error in filter expression");
@@ -666,6 +656,9 @@ int
pcap_compile(pcap_t *p, struct bpf_program *program,
const char *buf, int optimize, bpf_u_int32 mask)
{
+#ifdef _WIN32
+ static int done = 0;
+#endif
compiler_state_t cstate;
const char * volatile xbuf = buf;
yyscan_t scanner = NULL;
@@ -673,14 +666,6 @@ pcap_compile(pcap_t *p, struct bpf_program *program,
u_int len;
int rc;
-#ifdef _WIN32
- static int done = 0;
-
- if (!done)
- pcap_wsockinit();
- done = 1;
-#endif
-
/*
* If this pcap_t hasn't been activated, it doesn't have a
* link-layer type, so we can't use it.
@@ -688,9 +673,36 @@ pcap_compile(pcap_t *p, struct bpf_program *program,
if (!p->activated) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"not-yet-activated pcap_t passed to pcap_compile");
- rc = -1;
- goto quit;
+ return (-1);
}
+
+#ifdef _WIN32
+ if (!done)
+ pcap_wsockinit();
+ done = 1;
+#endif
+
+#ifdef ENABLE_REMOTE
+ /*
+ * If the device on which we're capturing need to be notified
+ * that a new filter is being compiled, do so.
+ *
+ * This allows them to save a copy of it, in case, for example,
+ * they're implementing a form of remote packet capture, and
+ * want the remote machine to filter out the packets in which
+ * it's sending the packets it's captured.
+ *
+ * XXX - the fact that we happen to be compiling a filter
+ * doesn't necessarily mean we'll be installing it as the
+ * filter for this pcap_t; we might be running it from userland
+ * on captured packets to do packet classification. We really
+ * need a better way of handling this, but this is all that
+ * the WinPcap code did.
+ */
+ if (p->save_current_filter_op != NULL)
+ (p->save_current_filter_op)(p, buf);
+#endif
+
initchunks(&cstate);
cstate.no_optimize = 0;
#ifdef INET6
@@ -721,7 +733,8 @@ pcap_compile(pcap_t *p, struct bpf_program *program,
}
if (pcap_lex_init(&scanner) != 0)
- bpf_error(&cstate, "can't initialize scanner: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "can't initialize scanner");
in_buffer = pcap__scan_string(xbuf ? xbuf : "", scanner);
/*
@@ -805,8 +818,7 @@ pcap_freecode(struct bpf_program *program)
* in each block is already resolved.
*/
static void
-backpatch(list, target)
- struct block *list, *target;
+backpatch(struct block *list, struct block *target)
{
struct block *next;
@@ -827,8 +839,7 @@ backpatch(list, target)
* which of jt and jf is the link.
*/
static void
-merge(b0, b1)
- struct block *b0, *b1;
+merge(struct block *b0, struct block *b1)
{
register struct block **p = &b0;
@@ -890,8 +901,7 @@ finish_parse(compiler_state_t *cstate, struct block *p)
}
void
-gen_and(b0, b1)
- struct block *b0, *b1;
+gen_and(struct block *b0, struct block *b1)
{
backpatch(b0, b1->head);
b0->sense = !b0->sense;
@@ -902,8 +912,7 @@ gen_and(b0, b1)
}
void
-gen_or(b0, b1)
- struct block *b0, *b1;
+gen_or(struct block *b0, struct block *b1)
{
b0->sense = !b0->sense;
backpatch(b0, b1->head);
@@ -913,8 +922,7 @@ gen_or(b0, b1)
}
void
-gen_not(b)
- struct block *b;
+gen_not(struct block *b)
{
b->sense = !b->sense;
}
@@ -1066,10 +1074,10 @@ init_linktype(compiler_state_t *cstate, pcap_t *p)
* Assume it's not raw ATM with a pseudo-header, for now.
*/
cstate->is_atm = 0;
- cstate->off_vpi = -1;
- cstate->off_vci = -1;
- cstate->off_proto = -1;
- cstate->off_payload = -1;
+ cstate->off_vpi = OFFSET_NOT_SET;
+ cstate->off_vci = OFFSET_NOT_SET;
+ cstate->off_proto = OFFSET_NOT_SET;
+ cstate->off_payload = OFFSET_NOT_SET;
/*
* And not Geneve.
@@ -1077,14 +1085,19 @@ init_linktype(compiler_state_t *cstate, pcap_t *p)
cstate->is_geneve = 0;
/*
+ * No variable length VLAN offset by default
+ */
+ cstate->is_vlan_vloffset = 0;
+
+ /*
* And assume we're not doing SS7.
*/
- cstate->off_li = -1;
- cstate->off_li_hsl = -1;
- cstate->off_sio = -1;
- cstate->off_opc = -1;
- cstate->off_dpc = -1;
- cstate->off_sls = -1;
+ cstate->off_li = OFFSET_NOT_SET;
+ cstate->off_li_hsl = OFFSET_NOT_SET;
+ cstate->off_sio = OFFSET_NOT_SET;
+ cstate->off_opc = OFFSET_NOT_SET;
+ cstate->off_dpc = OFFSET_NOT_SET;
+ cstate->off_sls = OFFSET_NOT_SET;
cstate->label_stack_depth = 0;
cstate->vlan_stack_depth = 0;
@@ -1094,7 +1107,7 @@ init_linktype(compiler_state_t *cstate, pcap_t *p)
case DLT_ARCNET:
cstate->off_linktype.constant_part = 2;
cstate->off_linkpl.constant_part = 6;
- cstate->off_nl = 0; /* XXX in reality, variable! */
+ cstate->off_nl = 0; /* XXX in reality, variable! */
cstate->off_nl_nosnap = 0; /* no 802.2 LLC */
break;
@@ -1408,7 +1421,7 @@ init_linktype(compiler_state_t *cstate, pcap_t *p)
cstate->off_linktype.constant_part = 4;
cstate->off_linkpl.constant_part = 4;
cstate->off_nl = 0;
- cstate->off_nl_nosnap = -1; /* no 802.2 LLC */
+ cstate->off_nl_nosnap = OFFSET_NOT_SET; /* no 802.2 LLC */
break;
case DLT_JUNIPER_ATM1:
@@ -1439,63 +1452,63 @@ init_linktype(compiler_state_t *cstate, pcap_t *p)
cstate->off_linktype.constant_part = 4;
cstate->off_linkpl.constant_part = 6;
cstate->off_nl = 0;
- cstate->off_nl_nosnap = -1; /* no 802.2 LLC */
+ cstate->off_nl_nosnap = OFFSET_NOT_SET; /* no 802.2 LLC */
break;
case DLT_JUNIPER_GGSN:
cstate->off_linktype.constant_part = 6;
cstate->off_linkpl.constant_part = 12;
cstate->off_nl = 0;
- cstate->off_nl_nosnap = -1; /* no 802.2 LLC */
+ cstate->off_nl_nosnap = OFFSET_NOT_SET; /* no 802.2 LLC */
break;
case DLT_JUNIPER_ES:
cstate->off_linktype.constant_part = 6;
cstate->off_linkpl.constant_part = OFFSET_NOT_SET; /* not really a network layer but raw IP addresses */
- cstate->off_nl = -1; /* not really a network layer but raw IP addresses */
- cstate->off_nl_nosnap = -1; /* no 802.2 LLC */
+ cstate->off_nl = OFFSET_NOT_SET; /* not really a network layer but raw IP addresses */
+ cstate->off_nl_nosnap = OFFSET_NOT_SET; /* no 802.2 LLC */
break;
case DLT_JUNIPER_MONITOR:
cstate->off_linktype.constant_part = 12;
cstate->off_linkpl.constant_part = 12;
- cstate->off_nl = 0; /* raw IP/IP6 header */
- cstate->off_nl_nosnap = -1; /* no 802.2 LLC */
+ cstate->off_nl = 0; /* raw IP/IP6 header */
+ cstate->off_nl_nosnap = OFFSET_NOT_SET; /* no 802.2 LLC */
break;
case DLT_BACNET_MS_TP:
cstate->off_linktype.constant_part = OFFSET_NOT_SET;
cstate->off_linkpl.constant_part = OFFSET_NOT_SET;
- cstate->off_nl = -1;
- cstate->off_nl_nosnap = -1;
+ cstate->off_nl = OFFSET_NOT_SET;
+ cstate->off_nl_nosnap = OFFSET_NOT_SET;
break;
case DLT_JUNIPER_SERVICES:
cstate->off_linktype.constant_part = 12;
cstate->off_linkpl.constant_part = OFFSET_NOT_SET; /* L3 proto location dep. on cookie type */
- cstate->off_nl = -1; /* L3 proto location dep. on cookie type */
- cstate->off_nl_nosnap = -1; /* no 802.2 LLC */
+ cstate->off_nl = OFFSET_NOT_SET; /* L3 proto location dep. on cookie type */
+ cstate->off_nl_nosnap = OFFSET_NOT_SET; /* no 802.2 LLC */
break;
case DLT_JUNIPER_VP:
cstate->off_linktype.constant_part = 18;
cstate->off_linkpl.constant_part = OFFSET_NOT_SET;
- cstate->off_nl = -1;
- cstate->off_nl_nosnap = -1;
+ cstate->off_nl = OFFSET_NOT_SET;
+ cstate->off_nl_nosnap = OFFSET_NOT_SET;
break;
case DLT_JUNIPER_ST:
cstate->off_linktype.constant_part = 18;
cstate->off_linkpl.constant_part = OFFSET_NOT_SET;
- cstate->off_nl = -1;
- cstate->off_nl_nosnap = -1;
+ cstate->off_nl = OFFSET_NOT_SET;
+ cstate->off_nl_nosnap = OFFSET_NOT_SET;
break;
case DLT_JUNIPER_ISM:
cstate->off_linktype.constant_part = 8;
cstate->off_linkpl.constant_part = OFFSET_NOT_SET;
- cstate->off_nl = -1;
- cstate->off_nl_nosnap = -1;
+ cstate->off_nl = OFFSET_NOT_SET;
+ cstate->off_nl_nosnap = OFFSET_NOT_SET;
break;
case DLT_JUNIPER_VS:
@@ -1504,8 +1517,8 @@ init_linktype(compiler_state_t *cstate, pcap_t *p)
case DLT_JUNIPER_ATM_CEMIC:
cstate->off_linktype.constant_part = 8;
cstate->off_linkpl.constant_part = OFFSET_NOT_SET;
- cstate->off_nl = -1;
- cstate->off_nl_nosnap = -1;
+ cstate->off_nl = OFFSET_NOT_SET;
+ cstate->off_nl_nosnap = OFFSET_NOT_SET;
break;
case DLT_MTP2:
@@ -1517,8 +1530,8 @@ init_linktype(compiler_state_t *cstate, pcap_t *p)
cstate->off_sls = 7;
cstate->off_linktype.constant_part = OFFSET_NOT_SET;
cstate->off_linkpl.constant_part = OFFSET_NOT_SET;
- cstate->off_nl = -1;
- cstate->off_nl_nosnap = -1;
+ cstate->off_nl = OFFSET_NOT_SET;
+ cstate->off_nl_nosnap = OFFSET_NOT_SET;
break;
case DLT_MTP2_WITH_PHDR:
@@ -1530,8 +1543,8 @@ init_linktype(compiler_state_t *cstate, pcap_t *p)
cstate->off_sls = 11;
cstate->off_linktype.constant_part = OFFSET_NOT_SET;
cstate->off_linkpl.constant_part = OFFSET_NOT_SET;
- cstate->off_nl = -1;
- cstate->off_nl_nosnap = -1;
+ cstate->off_nl = OFFSET_NOT_SET;
+ cstate->off_nl_nosnap = OFFSET_NOT_SET;
break;
case DLT_ERF:
@@ -1543,8 +1556,8 @@ init_linktype(compiler_state_t *cstate, pcap_t *p)
cstate->off_sls = 27;
cstate->off_linktype.constant_part = OFFSET_NOT_SET;
cstate->off_linkpl.constant_part = OFFSET_NOT_SET;
- cstate->off_nl = -1;
- cstate->off_nl_nosnap = -1;
+ cstate->off_nl = OFFSET_NOT_SET;
+ cstate->off_nl_nosnap = OFFSET_NOT_SET;
break;
case DLT_PFSYNC:
@@ -1560,15 +1573,15 @@ init_linktype(compiler_state_t *cstate, pcap_t *p)
*/
cstate->off_linktype.constant_part = OFFSET_NOT_SET; /* variable, min 15, max 71 steps of 7 */
cstate->off_linkpl.constant_part = OFFSET_NOT_SET;
- cstate->off_nl = -1; /* variable, min 16, max 71 steps of 7 */
- cstate->off_nl_nosnap = -1; /* no 802.2 LLC */
+ cstate->off_nl = OFFSET_NOT_SET; /* variable, min 16, max 71 steps of 7 */
+ cstate->off_nl_nosnap = OFFSET_NOT_SET; /* no 802.2 LLC */
break;
case DLT_IPNET:
cstate->off_linktype.constant_part = 1;
cstate->off_linkpl.constant_part = 24; /* ipnet header length */
cstate->off_nl = 0;
- cstate->off_nl_nosnap = -1;
+ cstate->off_nl_nosnap = OFFSET_NOT_SET;
break;
case DLT_NETANALYZER:
@@ -1596,8 +1609,8 @@ init_linktype(compiler_state_t *cstate, pcap_t *p)
cstate->linktype <= DLT_MATCHING_MAX) {
cstate->off_linktype.constant_part = OFFSET_NOT_SET;
cstate->off_linkpl.constant_part = OFFSET_NOT_SET;
- cstate->off_nl = -1;
- cstate->off_nl_nosnap = -1;
+ cstate->off_nl = OFFSET_NOT_SET;
+ cstate->off_nl_nosnap = OFFSET_NOT_SET;
} else {
bpf_error(cstate, "unknown data link type %d", cstate->linktype);
}
@@ -1722,7 +1735,7 @@ gen_load_a(compiler_state_t *cstate, enum e_offrel offrel, u_int offset,
default:
abort();
- return NULL;
+ /* NOTREACHED */
}
return s;
}
@@ -1786,6 +1799,7 @@ gen_loadx_iphdrlen(compiler_state_t *cstate)
return s;
}
+
static struct block *
gen_uncond(compiler_state_t *cstate, int rsense)
{
@@ -2803,6 +2817,28 @@ insert_compute_vloffsets(compiler_state_t *cstate, struct block *b)
}
/*
+ * If there there is no initialization yet and we need variable
+ * length offsets for VLAN, initialize them to zero
+ */
+ if (s == NULL && cstate->is_vlan_vloffset) {
+ struct slist *s2;
+
+ if (cstate->off_linkpl.reg == -1)
+ cstate->off_linkpl.reg = alloc_reg(cstate);
+ if (cstate->off_linktype.reg == -1)
+ cstate->off_linktype.reg = alloc_reg(cstate);
+
+ s = new_stmt(cstate, BPF_LD|BPF_W|BPF_IMM);
+ s->s.k = 0;
+ s2 = new_stmt(cstate, BPF_ST);
+ s2->s.k = cstate->off_linkpl.reg;
+ sappend(s, s2);
+ s2 = new_stmt(cstate, BPF_ST);
+ s2->s.k = cstate->off_linktype.reg;
+ sappend(s, s2);
+ }
+
+ /*
* If we have any offset-loading code, append all the
* existing statements in the block to those statements,
* and make the resulting list the list of statements
@@ -2888,8 +2924,7 @@ gen_abs_offset_varpart(compiler_state_t *cstate, bpf_abs_offset *off)
* Map an Ethernet type to the equivalent PPP type.
*/
static int
-ethertype_to_ppptype(proto)
- int proto;
+ethertype_to_ppptype(int proto)
{
switch (proto) {
@@ -2976,7 +3011,7 @@ gen_prevlinkhdr_check(compiler_state_t *cstate)
*/
#define BSD_AFNUM_INET6_BSD 24 /* NetBSD, OpenBSD, BSD/OS, Npcap */
#define BSD_AFNUM_INET6_FREEBSD 28 /* FreeBSD */
-#define BSD_AFNUM_INET6_DARWIN 30 /* OS X, iOS, other Darwin-based OSes */
+#define BSD_AFNUM_INET6_DARWIN 30 /* macOS, iOS, other Darwin-based OSes */
/*
* Generate code to match a particular packet type by matching the
@@ -3532,14 +3567,14 @@ gen_snap(compiler_state_t *cstate, bpf_u_int32 orgcode, bpf_u_int32 ptype)
{
u_char snapblock[8];
- snapblock[0] = LLCSAP_SNAP; /* DSAP = SNAP */
- snapblock[1] = LLCSAP_SNAP; /* SSAP = SNAP */
- snapblock[2] = 0x03; /* control = UI */
- snapblock[3] = (orgcode >> 16); /* upper 8 bits of organization code */
- snapblock[4] = (orgcode >> 8); /* middle 8 bits of organization code */
- snapblock[5] = (orgcode >> 0); /* lower 8 bits of organization code */
- snapblock[6] = (ptype >> 8); /* upper 8 bits of protocol type */
- snapblock[7] = (ptype >> 0); /* lower 8 bits of protocol type */
+ snapblock[0] = LLCSAP_SNAP; /* DSAP = SNAP */
+ snapblock[1] = LLCSAP_SNAP; /* SSAP = SNAP */
+ snapblock[2] = 0x03; /* control = UI */
+ snapblock[3] = (u_char)(orgcode >> 16); /* upper 8 bits of organization code */
+ snapblock[4] = (u_char)(orgcode >> 8); /* middle 8 bits of organization code */
+ snapblock[5] = (u_char)(orgcode >> 0); /* lower 8 bits of organization code */
+ snapblock[6] = (u_char)(ptype >> 8); /* upper 8 bits of protocol type */
+ snapblock[7] = (u_char)(ptype >> 0); /* lower 8 bits of protocol type */
return gen_bcmp(cstate, OR_LLC, 0, 8, snapblock);
}
@@ -3832,6 +3867,30 @@ gen_hostop(compiler_state_t *cstate, bpf_u_int32 addr, bpf_u_int32 mask,
gen_or(b0, b1);
return b1;
+ case Q_ADDR1:
+ bpf_error(cstate, "'addr1' and 'address1' are not valid qualifiers for addresses other than 802.11 MAC addresses");
+ break;
+
+ case Q_ADDR2:
+ bpf_error(cstate, "'addr2' and 'address2' are not valid qualifiers for addresses other than 802.11 MAC addresses");
+ break;
+
+ case Q_ADDR3:
+ bpf_error(cstate, "'addr3' and 'address3' are not valid qualifiers for addresses other than 802.11 MAC addresses");
+ break;
+
+ case Q_ADDR4:
+ bpf_error(cstate, "'addr4' and 'address4' are not valid qualifiers for addresses other than 802.11 MAC addresses");
+ break;
+
+ case Q_RA:
+ bpf_error(cstate, "'ra' is not a valid qualifier for addresses other than 802.11 MAC addresses");
+ break;
+
+ case Q_TA:
+ bpf_error(cstate, "'ta' is not a valid qualifier for addresses other than 802.11 MAC addresses");
+ break;
+
default:
abort();
}
@@ -3848,7 +3907,7 @@ gen_hostop6(compiler_state_t *cstate, struct in6_addr *addr,
{
struct block *b0, *b1;
u_int offset;
- u_int32_t *a, *m;
+ uint32_t *a, *m;
switch (dir) {
@@ -3873,12 +3932,36 @@ gen_hostop6(compiler_state_t *cstate, struct in6_addr *addr,
gen_or(b0, b1);
return b1;
+ case Q_ADDR1:
+ bpf_error(cstate, "'addr1' and 'address1' are not valid qualifiers for addresses other than 802.11 MAC addresses");
+ break;
+
+ case Q_ADDR2:
+ bpf_error(cstate, "'addr2' and 'address2' are not valid qualifiers for addresses other than 802.11 MAC addresses");
+ break;
+
+ case Q_ADDR3:
+ bpf_error(cstate, "'addr3' and 'address3' are not valid qualifiers for addresses other than 802.11 MAC addresses");
+ break;
+
+ case Q_ADDR4:
+ bpf_error(cstate, "'addr4' and 'address4' are not valid qualifiers for addresses other than 802.11 MAC addresses");
+ break;
+
+ case Q_RA:
+ bpf_error(cstate, "'ra' is not a valid qualifier for addresses other than 802.11 MAC addresses");
+ break;
+
+ case Q_TA:
+ bpf_error(cstate, "'ta' is not a valid qualifier for addresses other than 802.11 MAC addresses");
+ break;
+
default:
abort();
}
/* this order is important */
- a = (u_int32_t *)addr;
- m = (u_int32_t *)mask;
+ a = (uint32_t *)addr;
+ m = (uint32_t *)mask;
b1 = gen_mcmp(cstate, OR_LINKPL, offset + 12, BPF_W, ntohl(a[3]), ntohl(m[3]));
b0 = gen_mcmp(cstate, OR_LINKPL, offset + 8, BPF_W, ntohl(a[2]), ntohl(m[2]));
gen_and(b0, b1);
@@ -3918,19 +4001,19 @@ gen_ehostop(compiler_state_t *cstate, const u_char *eaddr, int dir)
return b1;
case Q_ADDR1:
- bpf_error(cstate, "'addr1' is only supported on 802.11 with 802.11 headers");
+ bpf_error(cstate, "'addr1' and 'address1' are only supported on 802.11 with 802.11 headers");
break;
case Q_ADDR2:
- bpf_error(cstate, "'addr2' is only supported on 802.11 with 802.11 headers");
+ bpf_error(cstate, "'addr2' and 'address2' are only supported on 802.11 with 802.11 headers");
break;
case Q_ADDR3:
- bpf_error(cstate, "'addr3' is only supported on 802.11 with 802.11 headers");
+ bpf_error(cstate, "'addr3' and 'address3' are only supported on 802.11 with 802.11 headers");
break;
case Q_ADDR4:
- bpf_error(cstate, "'addr4' is only supported on 802.11 with 802.11 headers");
+ bpf_error(cstate, "'addr4' and 'address4' are only supported on 802.11 with 802.11 headers");
break;
case Q_RA:
@@ -3974,19 +4057,19 @@ gen_fhostop(compiler_state_t *cstate, const u_char *eaddr, int dir)
return b1;
case Q_ADDR1:
- bpf_error(cstate, "'addr1' is only supported on 802.11");
+ bpf_error(cstate, "'addr1' and 'address1' are only supported on 802.11");
break;
case Q_ADDR2:
- bpf_error(cstate, "'addr2' is only supported on 802.11");
+ bpf_error(cstate, "'addr2' and 'address2' are only supported on 802.11");
break;
case Q_ADDR3:
- bpf_error(cstate, "'addr3' is only supported on 802.11");
+ bpf_error(cstate, "'addr3' and 'address3' are only supported on 802.11");
break;
case Q_ADDR4:
- bpf_error(cstate, "'addr4' is only supported on 802.11");
+ bpf_error(cstate, "'addr4' and 'address4' are only supported on 802.11");
break;
case Q_RA:
@@ -4030,19 +4113,19 @@ gen_thostop(compiler_state_t *cstate, const u_char *eaddr, int dir)
return b1;
case Q_ADDR1:
- bpf_error(cstate, "'addr1' is only supported on 802.11");
+ bpf_error(cstate, "'addr1' and 'address1' are only supported on 802.11");
break;
case Q_ADDR2:
- bpf_error(cstate, "'addr2' is only supported on 802.11");
+ bpf_error(cstate, "'addr2' and 'address2' are only supported on 802.11");
break;
case Q_ADDR3:
- bpf_error(cstate, "'addr3' is only supported on 802.11");
+ bpf_error(cstate, "'addr3' and 'address3' are only supported on 802.11");
break;
case Q_ADDR4:
- bpf_error(cstate, "'addr4' is only supported on 802.11");
+ bpf_error(cstate, "'addr4' and 'address4' are only supported on 802.11");
break;
case Q_RA:
@@ -4511,19 +4594,19 @@ gen_ipfchostop(compiler_state_t *cstate, const u_char *eaddr, int dir)
return b1;
case Q_ADDR1:
- bpf_error(cstate, "'addr1' is only supported on 802.11");
+ bpf_error(cstate, "'addr1' and 'address1' are only supported on 802.11");
break;
case Q_ADDR2:
- bpf_error(cstate, "'addr2' is only supported on 802.11");
+ bpf_error(cstate, "'addr2' and 'address2' are only supported on 802.11");
break;
case Q_ADDR3:
- bpf_error(cstate, "'addr3' is only supported on 802.11");
+ bpf_error(cstate, "'addr3' and 'address3' are only supported on 802.11");
break;
case Q_ADDR4:
- bpf_error(cstate, "'addr4' is only supported on 802.11");
+ bpf_error(cstate, "'addr4' and 'address4' are only supported on 802.11");
break;
case Q_RA:
@@ -4639,7 +4722,7 @@ gen_mpls_linktype(compiler_state_t *cstate, int proto)
case Q_IP:
/* match the bottom-of-stack bit */
- b0 = gen_mcmp(cstate, OR_LINKPL, -2, BPF_B, 0x01, 0x01);
+ b0 = gen_mcmp(cstate, OR_LINKPL, (u_int)-2, BPF_B, 0x01, 0x01);
/* match the IPv4 version number */
b1 = gen_mcmp(cstate, OR_LINKPL, 0, BPF_B, 0x40, 0xf0);
gen_and(b0, b1);
@@ -4647,7 +4730,7 @@ gen_mpls_linktype(compiler_state_t *cstate, int proto)
case Q_IPV6:
/* match the bottom-of-stack bit */
- b0 = gen_mcmp(cstate, OR_LINKPL, -2, BPF_B, 0x01, 0x01);
+ b0 = gen_mcmp(cstate, OR_LINKPL, (u_int)-2, BPF_B, 0x01, 0x01);
/* match the IPv4 version number */
b1 = gen_mcmp(cstate, OR_LINKPL, 0, BPF_B, 0x60, 0xf0);
gen_and(b0, b1);
@@ -4907,10 +4990,12 @@ gen_host6(compiler_state_t *cstate, struct in6_addr *addr,
#ifndef INET6
static struct block *
-gen_gateway(compiler_state_t *cstate, const u_char *eaddr, bpf_u_int32 **alist,
- int proto, int dir)
+gen_gateway(compiler_state_t *cstate, const u_char *eaddr,
+ struct addrinfo *alist, int proto, int dir)
{
struct block *b0, *b1, *tmp;
+ struct addrinfo *ai;
+ struct sockaddr_in *sin;
if (dir != 0)
bpf_error(cstate, "direction applied to 'gateway'");
@@ -4958,12 +5043,48 @@ gen_gateway(compiler_state_t *cstate, const u_char *eaddr, bpf_u_int32 **alist,
bpf_error(cstate,
"'gateway' supported only on ethernet/FDDI/token ring/802.11/ATM LANE/Fibre Channel");
}
- b1 = gen_host(cstate, **alist++, 0xffffffff, proto, Q_OR, Q_HOST);
- while (*alist) {
- tmp = gen_host(cstate, **alist++, 0xffffffff, proto, Q_OR,
- Q_HOST);
- gen_or(b1, tmp);
- b1 = tmp;
+ b1 = NULL;
+ for (ai = alist; ai != NULL; ai = ai->ai_next) {
+ /*
+ * Does it have an address?
+ */
+ if (ai->ai_addr != NULL) {
+ /*
+ * Yes. Is it an IPv4 address?
+ */
+ if (ai->ai_addr->sa_family == AF_INET) {
+ /*
+ * Generate an entry for it.
+ */
+ sin = (struct sockaddr_in *)ai->ai_addr;
+ tmp = gen_host(cstate,
+ ntohl(sin->sin_addr.s_addr),
+ 0xffffffff, proto, Q_OR, Q_HOST);
+ /*
+ * Is it the *first* IPv4 address?
+ */
+ if (b1 == NULL) {
+ /*
+ * Yes, so start with it.
+ */
+ b1 = tmp;
+ } else {
+ /*
+ * No, so OR it into the
+ * existing set of
+ * addresses.
+ */
+ gen_or(b1, tmp);
+ b1 = tmp;
+ }
+ }
+ }
+ }
+ if (b1 == NULL) {
+ /*
+ * No IPv4 addresses found.
+ */
+ return (NULL);
}
gen_not(b1);
gen_and(b0, b1);
@@ -5645,9 +5766,7 @@ lookup_proto(compiler_state_t *cstate, const char *name, int proto)
#if 0
struct stmt *
-gen_joinsp(s, n)
- struct stmt **s;
- int n;
+gen_joinsp(struct stmt **s, int n)
{
return NULL;
}
@@ -5697,7 +5816,7 @@ gen_protochain(compiler_state_t *cstate, int v, int proto, int dir)
if (cstate->off_linkpl.is_variable)
bpf_error(cstate, "'protochain' not supported with variable length headers");
- cstate->no_optimize = 1; /*this code is not compatible with optimzer yet */
+ cstate->no_optimize = 1; /* this code is not compatible with optimizer yet */
/*
* s[0] is a dummy entry to protect other BPF insn from damage
@@ -6201,13 +6320,11 @@ gen_scode(compiler_state_t *cstate, const char *name, struct qual q)
int tproto;
u_char *eaddr;
bpf_u_int32 mask, addr;
-#ifndef INET6
- bpf_u_int32 **alist;
-#else
- int tproto6;
+ struct addrinfo *res, *res0;
struct sockaddr_in *sin4;
+#ifdef INET6
+ int tproto6;
struct sockaddr_in6 *sin6;
- struct addrinfo *res, *res0;
struct in6_addr mask128;
#endif /*INET6*/
struct block *b, *tmp;
@@ -6306,46 +6423,39 @@ gen_scode(compiler_state_t *cstate, const char *name, struct qual q)
*/
return (gen_host(cstate, dn_addr, 0, proto, dir, q.addr));
} else {
-#ifndef INET6
- alist = pcap_nametoaddr(name);
- if (alist == NULL || *alist == NULL)
- bpf_error(cstate, "unknown host '%s'", name);
- tproto = proto;
- if (cstate->off_linktype.constant_part == OFFSET_NOT_SET &&
- tproto == Q_DEFAULT)
- tproto = Q_IP;
- b = gen_host(cstate, **alist++, 0xffffffff, tproto, dir, q.addr);
- while (*alist) {
- tmp = gen_host(cstate, **alist++, 0xffffffff,
- tproto, dir, q.addr);
- gen_or(b, tmp);
- b = tmp;
- }
- return b;
-#else
+#ifdef INET6
memset(&mask128, 0xff, sizeof(mask128));
+#endif
res0 = res = pcap_nametoaddrinfo(name);
if (res == NULL)
bpf_error(cstate, "unknown host '%s'", name);
cstate->ai = res;
b = tmp = NULL;
- tproto = tproto6 = proto;
+ tproto = proto;
+#ifdef INET6
+ tproto6 = proto;
+#endif
if (cstate->off_linktype.constant_part == OFFSET_NOT_SET &&
tproto == Q_DEFAULT) {
tproto = Q_IP;
+#ifdef INET6
tproto6 = Q_IPV6;
+#endif
}
for (res = res0; res; res = res->ai_next) {
switch (res->ai_family) {
case AF_INET:
+#ifdef INET6
if (tproto == Q_IPV6)
continue;
+#endif
sin4 = (struct sockaddr_in *)
res->ai_addr;
tmp = gen_host(cstate, ntohl(sin4->sin_addr.s_addr),
0xffffffff, tproto, dir, q.addr);
break;
+#ifdef INET6
case AF_INET6:
if (tproto6 == Q_IP)
continue;
@@ -6355,6 +6465,7 @@ gen_scode(compiler_state_t *cstate, const char *name, struct qual q)
tmp = gen_host6(cstate, &sin6->sin6_addr,
&mask128, tproto6, dir, q.addr);
break;
+#endif
default:
continue;
}
@@ -6371,7 +6482,6 @@ gen_scode(compiler_state_t *cstate, const char *name, struct qual q)
: " for specified address family");
}
return b;
-#endif /*INET6*/
}
case Q_PORT:
@@ -6469,11 +6579,15 @@ gen_scode(compiler_state_t *cstate, const char *name, struct qual q)
if (eaddr == NULL)
bpf_error(cstate, "unknown ether host: %s", name);
- alist = pcap_nametoaddr(name);
- if (alist == NULL || *alist == NULL)
+ res = pcap_nametoaddrinfo(name);
+ cstate->ai = res;
+ if (res == NULL)
+ bpf_error(cstate, "unknown host '%s'", name);
+ b = gen_gateway(cstate, eaddr, res, proto, dir);
+ cstate->ai = NULL;
+ freeaddrinfo(res);
+ if (b == NULL)
bpf_error(cstate, "unknown host '%s'", name);
- b = gen_gateway(cstate, eaddr, alist, proto, dir);
- free(eaddr);
return b;
#else
bpf_error(cstate, "'gateway' not supported in this configuration");
@@ -6546,7 +6660,6 @@ gen_mcode(compiler_state_t *cstate, const char *s1, const char *s2,
/* NOTREACHED */
}
/* NOTREACHED */
- return NULL;
}
struct block *
@@ -6665,7 +6778,7 @@ gen_mcode6(compiler_state_t *cstate, const char *s1, const char *s2,
struct in6_addr *addr;
struct in6_addr mask;
struct block *b;
- u_int32_t *a, *m;
+ uint32_t *a, *m;
if (s2)
bpf_error(cstate, "no mask %s supported", s2);
@@ -6687,8 +6800,8 @@ gen_mcode6(compiler_state_t *cstate, const char *s1, const char *s2,
(0xff << (8 - masklen % 8)) & 0xff;
}
- a = (u_int32_t *)addr;
- m = (u_int32_t *)&mask;
+ a = (uint32_t *)addr;
+ m = (uint32_t *)&mask;
if ((a[0] & ~m[0]) || (a[1] & ~m[1])
|| (a[2] & ~m[2]) || (a[3] & ~m[3])) {
bpf_error(cstate, "non-network bits set in \"%s/%d\"", s1, masklen);
@@ -6712,7 +6825,6 @@ gen_mcode6(compiler_state_t *cstate, const char *s1, const char *s2,
bpf_error(cstate, "invalid qualifier against IPv6 address");
/* NOTREACHED */
}
- return NULL;
}
#endif /*INET6*/
@@ -6750,12 +6862,10 @@ gen_ecode(compiler_state_t *cstate, const u_char *eaddr, struct qual q)
}
bpf_error(cstate, "ethernet address used in non-ether expression");
/* NOTREACHED */
- return NULL;
}
void
-sappend(s0, s1)
- struct slist *s0, *s1;
+sappend(struct slist *s0, struct slist *s1)
{
/*
* This is definitely not the best way to do this, but the
@@ -7005,8 +7115,58 @@ gen_load(compiler_state_t *cstate, int proto, struct arth *inst, int size)
inst->b = b;
break;
case Q_ICMPV6:
- bpf_error(cstate, "IPv6 upper-layer protocol is not supported by proto[x]");
- /*NOTREACHED*/
+ /*
+ * Do the computation only if the packet contains
+ * the protocol in question.
+ */
+ b = gen_proto_abbrev(cstate, Q_IPV6);
+ if (inst->b) {
+ gen_and(inst->b, b);
+ }
+ inst->b = b;
+
+ /*
+ * Check if we have an icmp6 next header
+ */
+ b = gen_cmp(cstate, OR_LINKPL, 6, BPF_B, 58);
+ if (inst->b) {
+ gen_and(inst->b, b);
+ }
+ inst->b = b;
+
+
+ s = gen_abs_offset_varpart(cstate, &cstate->off_linkpl);
+ /*
+ * If "s" is non-null, it has code to arrange that the
+ * X register contains the variable part of the offset
+ * of the link-layer payload. Add to it the offset
+ * computed into the register specified by "index",
+ * and move that into the X register. Otherwise, just
+ * load into the X register the offset computed into
+ * the register specified by "index".
+ */
+ if (s != NULL) {
+ sappend(s, xfer_to_a(cstate, inst));
+ sappend(s, new_stmt(cstate, BPF_ALU|BPF_ADD|BPF_X));
+ sappend(s, new_stmt(cstate, BPF_MISC|BPF_TAX));
+ } else {
+ s = xfer_to_x(cstate, inst);
+ }
+
+ /*
+ * Load the item at the sum of the offset we've put in the
+ * X register, the offset of the start of the network
+ * layer header from the beginning of the link-layer
+ * payload, and the constant part of the offset of the
+ * start of the link-layer payload.
+ */
+ tmp = new_stmt(cstate, BPF_LD|BPF_IND|size);
+ tmp->s.k = cstate->off_linkpl.constant_part + cstate->off_nl + 40;
+
+ sappend(s, tmp);
+ sappend(inst->s, s);
+
+ break;
}
inst->regno = regno;
s = new_stmt(cstate, BPF_ST);
@@ -7178,7 +7338,6 @@ alloc_reg(compiler_state_t *cstate)
}
bpf_error(cstate, "too many registers needed to evaluate expression");
/* NOTREACHED */
- return 0;
}
/*
@@ -7333,7 +7492,6 @@ gen_broadcast(compiler_state_t *cstate, int proto)
}
bpf_error(cstate, "only link-layer/IP broadcast filters supported");
/* NOTREACHED */
- return NULL;
}
/*
@@ -7529,7 +7687,6 @@ gen_multicast(compiler_state_t *cstate, int proto)
}
bpf_error(cstate, "link-layer multicast filters supported only on ethernet/FDDI/token ring/ARCNET/802.11/ATM LANE/Fibre Channel");
/* NOTREACHED */
- return NULL;
}
/*
@@ -7630,8 +7787,18 @@ gen_inbound(compiler_state_t *cstate, int dir)
default:
/*
* If we have packet meta-data indicating a direction,
- * check it, otherwise give up as this link-layer type
- * has nothing in the packet data.
+ * and that metadata can be checked by BPF code, check
+ * it. Otherwise, give up, as this link-layer type has
+ * nothing in the packet data.
+ *
+ * Currently, the only platform where a BPF filter can
+ * check that metadata is Linux with the in-kernel
+ * BPF interpreter. If other packet capture mechanisms
+ * and BPF filters also supported this, it would be
+ * nice. It would be even better if they made that
+ * metadata available so that we could provide it
+ * with newer capture APIs, allowing it to be saved
+ * in pcapng files.
*/
#if defined(linux) && defined(PF_PACKET) && defined(SO_ATTACH_FILTER)
/*
@@ -7657,7 +7824,6 @@ gen_inbound(compiler_state_t *cstate, int dir)
#else /* defined(linux) && defined(PF_PACKET) && defined(SO_ATTACH_FILTER) */
bpf_error(cstate, "inbound/outbound not supported on linktype %d",
cstate->linktype);
- b0 = NULL;
/* NOTREACHED */
#endif /* defined(linux) && defined(PF_PACKET) && defined(SO_ATTACH_FILTER) */
}
@@ -7774,51 +7940,45 @@ gen_pf_action(compiler_state_t *cstate, int action)
}
#else /* !HAVE_NET_PFVAR_H */
struct block *
-gen_pf_ifname(compiler_state_t *cstate, const char *ifname)
+gen_pf_ifname(compiler_state_t *cstate, const char *ifname _U_)
{
bpf_error(cstate, "libpcap was compiled without pf support");
/* NOTREACHED */
- return (NULL);
}
struct block *
-gen_pf_ruleset(compiler_state_t *cstate, char *ruleset)
+gen_pf_ruleset(compiler_state_t *cstate, char *ruleset _U_)
{
bpf_error(cstate, "libpcap was compiled on a machine without pf support");
/* NOTREACHED */
- return (NULL);
}
struct block *
-gen_pf_rnr(compiler_state_t *cstate, int rnr)
+gen_pf_rnr(compiler_state_t *cstate, int rnr _U_)
{
bpf_error(cstate, "libpcap was compiled on a machine without pf support");
/* NOTREACHED */
- return (NULL);
}
struct block *
-gen_pf_srnr(compiler_state_t *cstate, int srnr)
+gen_pf_srnr(compiler_state_t *cstate, int srnr _U_)
{
bpf_error(cstate, "libpcap was compiled on a machine without pf support");
/* NOTREACHED */
- return (NULL);
}
struct block *
-gen_pf_reason(compiler_state_t *cstate, int reason)
+gen_pf_reason(compiler_state_t *cstate, int reason _U_)
{
bpf_error(cstate, "libpcap was compiled on a machine without pf support");
/* NOTREACHED */
- return (NULL);
}
struct block *
-gen_pf_action(compiler_state_t *cstate, int action)
+gen_pf_action(compiler_state_t *cstate, int action _U_)
{
bpf_error(cstate, "libpcap was compiled on a machine without pf support");
/* NOTREACHED */
- return (NULL);
}
#endif /* HAVE_NET_PFVAR_H */
@@ -7890,9 +8050,6 @@ gen_acode(compiler_state_t *cstate, const u_char *eaddr, struct qual q)
bpf_error(cstate, "aid supported only on ARCnet");
/* NOTREACHED */
}
- bpf_error(cstate, "ARCnet address used in non-arc expression");
- /* NOTREACHED */
- return NULL;
}
static struct block *
@@ -7922,19 +8079,19 @@ gen_ahostop(compiler_state_t *cstate, const u_char *eaddr, int dir)
return b1;
case Q_ADDR1:
- bpf_error(cstate, "'addr1' is only supported on 802.11");
+ bpf_error(cstate, "'addr1' and 'address1' are only supported on 802.11");
break;
case Q_ADDR2:
- bpf_error(cstate, "'addr2' is only supported on 802.11");
+ bpf_error(cstate, "'addr2' and 'address2' are only supported on 802.11");
break;
case Q_ADDR3:
- bpf_error(cstate, "'addr3' is only supported on 802.11");
+ bpf_error(cstate, "'addr3' and 'address3' are only supported on 802.11");
break;
case Q_ADDR4:
- bpf_error(cstate, "'addr4' is only supported on 802.11");
+ bpf_error(cstate, "'addr4' and 'address4' are only supported on 802.11");
break;
case Q_RA:
@@ -7949,74 +8106,181 @@ gen_ahostop(compiler_state_t *cstate, const u_char *eaddr, int dir)
/* NOTREACHED */
}
-#if defined(SKF_AD_VLAN_TAG) && defined(SKF_AD_VLAN_TAG_PRESENT)
static struct block *
-gen_vlan_bpf_extensions(compiler_state_t *cstate, int vlan_num)
+gen_vlan_tpid_test(compiler_state_t *cstate)
{
- struct block *b0, *b1;
- struct slist *s;
-
- /* generate new filter code based on extracting packet
- * metadata */
- s = new_stmt(cstate, BPF_LD|BPF_B|BPF_ABS);
- s->s.k = SKF_AD_OFF + SKF_AD_VLAN_TAG_PRESENT;
-
- b0 = new_block(cstate, JMP(BPF_JEQ));
- b0->stmts = s;
- b0->s.k = 1;
-
- if (vlan_num >= 0) {
- s = new_stmt(cstate, BPF_LD|BPF_B|BPF_ABS);
- s->s.k = SKF_AD_OFF + SKF_AD_VLAN_TAG;
+ struct block *b0, *b1;
- b1 = new_block(cstate, JMP(BPF_JEQ));
- b1->stmts = s;
- b1->s.k = (bpf_int32) vlan_num;
+ /* check for VLAN, including QinQ */
+ b0 = gen_linktype(cstate, ETHERTYPE_8021Q);
+ b1 = gen_linktype(cstate, ETHERTYPE_8021AD);
+ gen_or(b0,b1);
+ b0 = b1;
+ b1 = gen_linktype(cstate, ETHERTYPE_8021QINQ);
+ gen_or(b0,b1);
- gen_and(b0,b1);
- b0 = b1;
- }
+ return b1;
+}
- return b0;
+static struct block *
+gen_vlan_vid_test(compiler_state_t *cstate, int vlan_num)
+{
+ return gen_mcmp(cstate, OR_LINKPL, 0, BPF_H, (bpf_int32)vlan_num, 0x0fff);
}
-#endif
static struct block *
gen_vlan_no_bpf_extensions(compiler_state_t *cstate, int vlan_num)
{
- struct block *b0, *b1;
-
- /* check for VLAN, including QinQ */
- b0 = gen_linktype(cstate, ETHERTYPE_8021Q);
- b1 = gen_linktype(cstate, ETHERTYPE_8021AD);
- gen_or(b0,b1);
- b0 = b1;
- b1 = gen_linktype(cstate, ETHERTYPE_8021QINQ);
- gen_or(b0,b1);
- b0 = b1;
-
- /* If a specific VLAN is requested, check VLAN id */
- if (vlan_num >= 0) {
- b1 = gen_mcmp(cstate, OR_LINKPL, 0, BPF_H,
- (bpf_int32)vlan_num, 0x0fff);
- gen_and(b0, b1);
- b0 = b1;
- }
+ struct block *b0, *b1;
+
+ b0 = gen_vlan_tpid_test(cstate);
+
+ if (vlan_num >= 0) {
+ b1 = gen_vlan_vid_test(cstate, vlan_num);
+ gen_and(b0, b1);
+ b0 = b1;
+ }
/*
- * The payload follows the full header, including the
- * VLAN tags, so skip past this VLAN tag.
+ * Both payload and link header type follow the VLAN tags so that
+ * both need to be updated.
*/
- cstate->off_linkpl.constant_part += 4;
+ cstate->off_linkpl.constant_part += 4;
+ cstate->off_linktype.constant_part += 4;
+
+ return b0;
+}
+
+#if defined(SKF_AD_VLAN_TAG_PRESENT)
+/* add v to variable part of off */
+static void
+gen_vlan_vloffset_add(compiler_state_t *cstate, bpf_abs_offset *off, int v, struct slist *s)
+{
+ struct slist *s2;
+
+ if (!off->is_variable)
+ off->is_variable = 1;
+ if (off->reg == -1)
+ off->reg = alloc_reg(cstate);
+
+ s2 = new_stmt(cstate, BPF_LD|BPF_MEM);
+ s2->s.k = off->reg;
+ sappend(s, s2);
+ s2 = new_stmt(cstate, BPF_ALU|BPF_ADD|BPF_IMM);
+ s2->s.k = v;
+ sappend(s, s2);
+ s2 = new_stmt(cstate, BPF_ST);
+ s2->s.k = off->reg;
+ sappend(s, s2);
+}
+
+/*
+ * patch block b_tpid (VLAN TPID test) to update variable parts of link payload
+ * and link type offsets first
+ */
+static void
+gen_vlan_patch_tpid_test(compiler_state_t *cstate, struct block *b_tpid)
+{
+ struct slist s;
+
+ /* offset determined at run time, shift variable part */
+ s.next = NULL;
+ cstate->is_vlan_vloffset = 1;
+ gen_vlan_vloffset_add(cstate, &cstate->off_linkpl, 4, &s);
+ gen_vlan_vloffset_add(cstate, &cstate->off_linktype, 4, &s);
+
+ /* we get a pointer to a chain of or-ed blocks, patch first of them */
+ sappend(s.next, b_tpid->head->stmts);
+ b_tpid->head->stmts = s.next;
+}
+
+/*
+ * patch block b_vid (VLAN id test) to load VID value either from packet
+ * metadata (using BPF extensions) if SKF_AD_VLAN_TAG_PRESENT is true
+ */
+static void
+gen_vlan_patch_vid_test(compiler_state_t *cstate, struct block *b_vid)
+{
+ struct slist *s, *s2, *sjeq;
+ unsigned cnt;
+
+ s = new_stmt(cstate, BPF_LD|BPF_B|BPF_ABS);
+ s->s.k = SKF_AD_OFF + SKF_AD_VLAN_TAG_PRESENT;
+
+ /* true -> next instructions, false -> beginning of b_vid */
+ sjeq = new_stmt(cstate, JMP(BPF_JEQ));
+ sjeq->s.k = 1;
+ sjeq->s.jf = b_vid->stmts;
+ sappend(s, sjeq);
+
+ s2 = new_stmt(cstate, BPF_LD|BPF_B|BPF_ABS);
+ s2->s.k = SKF_AD_OFF + SKF_AD_VLAN_TAG;
+ sappend(s, s2);
+ sjeq->s.jt = s2;
+
+ /* jump to the test in b_vid (bypass loading VID from packet data) */
+ cnt = 0;
+ for (s2 = b_vid->stmts; s2; s2 = s2->next)
+ cnt++;
+ s2 = new_stmt(cstate, JMP(BPF_JA));
+ s2->s.k = cnt;
+ sappend(s, s2);
+
+ /* insert our statements at the beginning of b_vid */
+ sappend(s, b_vid->stmts);
+ b_vid->stmts = s;
+}
+
+/*
+ * Generate check for "vlan" or "vlan <id>" on systems with support for BPF
+ * extensions. Even if kernel supports VLAN BPF extensions, (outermost) VLAN
+ * tag can be either in metadata or in packet data; therefore if the
+ * SKF_AD_VLAN_TAG_PRESENT test is negative, we need to check link
+ * header for VLAN tag. As the decision is done at run time, we need
+ * update variable part of the offsets
+ */
+static struct block *
+gen_vlan_bpf_extensions(compiler_state_t *cstate, int vlan_num)
+{
+ struct block *b0, *b_tpid, *b_vid = NULL;
+ struct slist *s;
+
+ /* generate new filter code based on extracting packet
+ * metadata */
+ s = new_stmt(cstate, BPF_LD|BPF_B|BPF_ABS);
+ s->s.k = SKF_AD_OFF + SKF_AD_VLAN_TAG_PRESENT;
+
+ b0 = new_block(cstate, JMP(BPF_JEQ));
+ b0->stmts = s;
+ b0->s.k = 1;
/*
- * The link-layer type information follows the VLAN tags, so
- * skip past this VLAN tag.
+ * This is tricky. We need to insert the statements updating variable
+ * parts of offsets before the the traditional TPID and VID tests so
+ * that they are called whenever SKF_AD_VLAN_TAG_PRESENT fails but
+ * we do not want this update to affect those checks. That's why we
+ * generate both test blocks first and insert the statements updating
+ * variable parts of both offsets after that. This wouldn't work if
+ * there already were variable length link header when entering this
+ * function but gen_vlan_bpf_extensions() isn't called in that case.
*/
- cstate->off_linktype.constant_part += 4;
+ b_tpid = gen_vlan_tpid_test(cstate);
+ if (vlan_num >= 0)
+ b_vid = gen_vlan_vid_test(cstate, vlan_num);
+
+ gen_vlan_patch_tpid_test(cstate, b_tpid);
+ gen_or(b0, b_tpid);
+ b0 = b_tpid;
+
+ if (vlan_num >= 0) {
+ gen_vlan_patch_vid_test(cstate, b_vid);
+ gen_and(b0, b_vid);
+ b0 = b_vid;
+ }
return b0;
}
+#endif
/*
* support IEEE 802.1Q VLAN trunk over ethernet
@@ -8066,7 +8330,7 @@ gen_vlan(compiler_state_t *cstate, int vlan_num)
case DLT_EN10MB:
case DLT_NETANALYZER:
case DLT_NETANALYZER_TRANSPARENT:
-#if defined(SKF_AD_VLAN_TAG) && defined(SKF_AD_VLAN_TAG_PRESENT)
+#if defined(SKF_AD_VLAN_TAG_PRESENT)
/* Verify that this is the outer part of the packet and
* not encapsulated somehow. */
if (cstate->vlan_stack_depth == 0 && !cstate->off_linkhdr.is_variable &&
@@ -8138,7 +8402,6 @@ gen_mpls(compiler_state_t *cstate, int label_num)
default:
bpf_error(cstate, "no MPLS support for data link type %d",
cstate->linktype);
- b0 = NULL;
/*NOTREACHED*/
break;
}
@@ -8559,7 +8822,7 @@ gen_atmfield_code(compiler_state_t *cstate, int atmfield, bpf_int32 jvalue,
case A_VPI:
if (!cstate->is_atm)
bpf_error(cstate, "'vpi' supported only on raw ATM");
- if (cstate->off_vpi == (u_int)-1)
+ if (cstate->off_vpi == OFFSET_NOT_SET)
abort();
b0 = gen_ncmp(cstate, OR_LINKHDR, cstate->off_vpi, BPF_B, 0xffffffff, jtype,
reverse, jvalue);
@@ -8568,21 +8831,21 @@ gen_atmfield_code(compiler_state_t *cstate, int atmfield, bpf_int32 jvalue,
case A_VCI:
if (!cstate->is_atm)
bpf_error(cstate, "'vci' supported only on raw ATM");
- if (cstate->off_vci == (u_int)-1)
+ if (cstate->off_vci == OFFSET_NOT_SET)
abort();
b0 = gen_ncmp(cstate, OR_LINKHDR, cstate->off_vci, BPF_H, 0xffffffff, jtype,
reverse, jvalue);
break;
case A_PROTOTYPE:
- if (cstate->off_proto == (u_int)-1)
+ if (cstate->off_proto == OFFSET_NOT_SET)
abort(); /* XXX - this isn't on FreeBSD */
b0 = gen_ncmp(cstate, OR_LINKHDR, cstate->off_proto, BPF_B, 0x0f, jtype,
reverse, jvalue);
break;
case A_MSGTYPE:
- if (cstate->off_payload == (u_int)-1)
+ if (cstate->off_payload == OFFSET_NOT_SET)
abort();
b0 = gen_ncmp(cstate, OR_LINKHDR, cstate->off_payload + MSG_TYPE_POS, BPF_B,
0xffffffff, jtype, reverse, jvalue);
@@ -8591,7 +8854,7 @@ gen_atmfield_code(compiler_state_t *cstate, int atmfield, bpf_int32 jvalue,
case A_CALLREFTYPE:
if (!cstate->is_atm)
bpf_error(cstate, "'callref' supported only on raw ATM");
- if (cstate->off_proto == (u_int)-1)
+ if (cstate->off_proto == OFFSET_NOT_SET)
abort();
b0 = gen_ncmp(cstate, OR_LINKHDR, cstate->off_proto, BPF_B, 0xffffffff,
jtype, reverse, jvalue);
@@ -8793,7 +9056,7 @@ gen_mtp3field_code(compiler_state_t *cstate, int mtp3field, bpf_u_int32 jvalue,
/* FALLTHROUGH */
case M_SIO:
- if (cstate->off_sio == (u_int)-1)
+ if (cstate->off_sio == OFFSET_NOT_SET)
bpf_error(cstate, "'sio' supported only on SS7");
/* sio coded on 1 byte so max value 255 */
if(jvalue > 255)
@@ -8806,7 +9069,7 @@ gen_mtp3field_code(compiler_state_t *cstate, int mtp3field, bpf_u_int32 jvalue,
case MH_OPC:
newoff_opc+=3;
case M_OPC:
- if (cstate->off_opc == (u_int)-1)
+ if (cstate->off_opc == OFFSET_NOT_SET)
bpf_error(cstate, "'opc' supported only on SS7");
/* opc coded on 14 bits so max value 16383 */
if (jvalue > 16383)
@@ -8830,7 +9093,7 @@ gen_mtp3field_code(compiler_state_t *cstate, int mtp3field, bpf_u_int32 jvalue,
/* FALLTHROUGH */
case M_DPC:
- if (cstate->off_dpc == (u_int)-1)
+ if (cstate->off_dpc == OFFSET_NOT_SET)
bpf_error(cstate, "'dpc' supported only on SS7");
/* dpc coded on 14 bits so max value 16383 */
if (jvalue > 16383)
@@ -8850,7 +9113,7 @@ gen_mtp3field_code(compiler_state_t *cstate, int mtp3field, bpf_u_int32 jvalue,
case MH_SLS:
newoff_sls+=3;
case M_SLS:
- if (cstate->off_sls == (u_int)-1)
+ if (cstate->off_sls == OFFSET_NOT_SET)
bpf_error(cstate, "'sls' supported only on SS7");
/* sls coded on 4 bits so max value 15 */
if (jvalue > 15)
diff --git a/contrib/libpcap/gencode.h b/contrib/libpcap/gencode.h
index 2b089d21d5616..88def5a8ad280 100644
--- a/contrib/libpcap/gencode.h
+++ b/contrib/libpcap/gencode.h
@@ -19,6 +19,8 @@
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
+#include "pcap/funcattrs.h"
+
/*
* ATM support:
*
@@ -53,10 +55,6 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef HAVE___ATTRIBUTE__
-#define __attribute__(x)
-#endif /* HAVE___ATTRIBUTE__ */
-
/* Address qualifiers. */
#define Q_HOST 1
@@ -268,6 +266,11 @@ struct block {
int val[N_ATOMS];
};
+/*
+ * A value of 0 for val[i] means the value is unknown.
+ */
+#define VAL_UNKNOWN 0
+
struct arth {
struct block *b; /* protocol checks */
struct slist *s; /* stmt list */
@@ -340,11 +343,29 @@ 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);
@@ -366,20 +387,13 @@ struct icode {
};
void bpf_optimize(compiler_state_t *, struct icode *ic);
-void bpf_syntax_error(compiler_state_t *, const char *);
-void bpf_error(compiler_state_t *, const char *, ...)
- __attribute__((noreturn))
-#ifdef __ATTRIBUTE___FORMAT_OK
- __attribute__((format (printf, 2, 3)))
-#endif /* __ATTRIBUTE___FORMAT_OK */
- ;
+void PCAP_NORETURN bpf_syntax_error(compiler_state_t *, const char *);
+void PCAP_NORETURN bpf_error(compiler_state_t *, const char *, ...)
+ PCAP_PRINTFLIKE(2, 3);
void finish_parse(compiler_state_t *, struct block *);
char *sdup(compiler_state_t *, const char *);
-struct _opt_state;
-typedef struct _opt_state opt_state_t;
-
struct bpf_insn *icode_to_fcode(compiler_state_t *, struct icode *,
struct block *, u_int *);
void sappend(struct slist *, struct slist *);
diff --git a/contrib/libpcap/grammar.y b/contrib/libpcap/grammar.y
index ef6a7abbb0b96..be80e2bfcfdef 100644
--- a/contrib/libpcap/grammar.y
+++ b/contrib/libpcap/grammar.y
@@ -21,7 +21,7 @@
/*
* And we need to pass the compiler state to the scanner.
*/
-%parse-param {compiler_state_t *cstate}
+%parse-param { compiler_state_t *cstate }
%{
/*
@@ -44,23 +44,18 @@
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * $FreeBSD$
*/
#ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
#endif
-#ifdef _WIN32
-#include <pcap-stdinc.h>
-#else /* _WIN32 */
-#include <sys/types.h>
-#include <sys/socket.h>
-#endif /* _WIN32 */
-
#include <stdlib.h>
#ifndef _WIN32
+#include <sys/types.h>
+#include <sys/socket.h>
+
#if __STDC__
struct mbuf;
struct rtentry;
@@ -72,6 +67,8 @@ struct rtentry;
#include <stdio.h>
+#include "diag-control.h"
+
#include "pcap-int.h"
#include "gencode.h"
@@ -80,7 +77,7 @@ struct rtentry;
#ifdef HAVE_NET_PFVAR_H
#include <net/if.h>
-#include <netpfil/pf/pf.h>
+#include <net/pfvar.h>
#include <net/if_pflog.h>
#endif
#include "llc.h"
@@ -91,9 +88,30 @@ struct rtentry;
#include "os-proto.h"
#endif
-#define QSET(q, p, d, a) (q).proto = (p),\
- (q).dir = (d),\
- (q).addr = (a)
+#ifdef YYBYACC
+/*
+ * Both Berkeley YACC and Bison define yydebug (under whatever name
+ * it has) as a global, but Bison does so only if YYDEBUG is defined.
+ * Berkeley YACC define it even if YYDEBUG isn't defined; declare it
+ * here to suppress a warning.
+ */
+#if !defined(YYDEBUG)
+extern int yydebug;
+#endif
+
+/*
+ * In Berkeley YACC, yynerrs (under whatever name it has) is global,
+ * even if it's building a reentrant parser. In Bison, it's local
+ * in reentrant parsers.
+ *
+ * Declare it to squelch a warning.
+ */
+extern int yynerrs;
+#endif
+
+#define QSET(q, p, d, a) (q).proto = (unsigned char)(p),\
+ (q).dir = (unsigned char)(d),\
+ (q).addr = (unsigned char)(a)
struct tok {
int v; /* value */
@@ -200,8 +218,8 @@ str2tok(const char *str, const struct tok *toks)
static struct qual qerr = { Q_UNDEF, Q_UNDEF, Q_UNDEF, Q_UNDEF };
-static void
-yyerror(void *yyscanner, compiler_state_t *cstate, const char *msg)
+static PCAP_NORETURN_DEF void
+yyerror(void *yyscanner _U_, compiler_state_t *cstate, const char *msg)
{
bpf_syntax_error(cstate, msg);
/* NOTREACHED */
@@ -247,26 +265,22 @@ pfaction_to_num(compiler_state_t *cstate, const char *action)
}
}
#else /* !HAVE_NET_PFVAR_H */
-static int
-pfreason_to_num(compiler_state_t *cstate, const char *reason)
+static PCAP_NORETURN_DEF 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*/
-
- /* this is to make the VC compiler happy */
- return -1;
}
-static int
-pfaction_to_num(compiler_state_t *cstate, const char *action)
+static PCAP_NORETURN_DEF 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*/
-
- /* this is to make the VC compiler happy */
- return -1;
}
#endif /* HAVE_NET_PFVAR_H */
+
+DIAG_OFF_BISON_BYACC
%}
%union {
diff --git a/contrib/libpcap/ieee80211.h b/contrib/libpcap/ieee80211.h
index 894a9e761a962..d79f0f8e36569 100644
--- a/contrib/libpcap/ieee80211.h
+++ b/contrib/libpcap/ieee80211.h
@@ -90,7 +90,7 @@
#define IEEE80211_FC1_RETRY 0x08
#define IEEE80211_FC1_PWR_MGT 0x10
#define IEEE80211_FC1_MORE_DATA 0x20
-#define IEEE80211_FC1_PROTECTED 0x40
+#define IEEE80211_FC1_WEP 0x40
#define IEEE80211_FC1_ORDER 0x80
#define IEEE80211_SEQ_FRAG_MASK 0x000f
diff --git a/contrib/libpcap/inet.c b/contrib/libpcap/inet.c
deleted file mode 100644
index a5d0f87bf879e..0000000000000
--- a/contrib/libpcap/inet.c
+++ /dev/null
@@ -1,407 +0,0 @@
-/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */
-/*
- * Copyright (c) 1994, 1995, 1996, 1997, 1998
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the Computer Systems
- * Engineering Group at Lawrence Berkeley Laboratory.
- * 4. Neither the name of the University nor of the Laboratory may be used
- * to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#ifdef _WIN32
-#include <pcap-stdinc.h>
-#else /* _WIN32 */
-
-#include <sys/param.h>
-#ifndef MSDOS
-#include <sys/file.h>
-#endif
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-#ifdef HAVE_SYS_SOCKIO_H
-#include <sys/sockio.h>
-#endif
-
-struct mbuf; /* Squelch compiler warnings on some platforms for */
-struct rtentry; /* declarations in <net/if.h> */
-#include <net/if.h>
-#include <netinet/in.h>
-#endif /* _WIN32 */
-
-#include <errno.h>
-#include <memory.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#if !defined(_WIN32) && !defined(__BORLANDC__)
-#include <unistd.h>
-#endif /* !_WIN32 && !__BORLANDC__ */
-
-#include "pcap-int.h"
-
-#ifdef HAVE_OS_PROTO_H
-#include "os-proto.h"
-#endif
-
-#if !defined(_WIN32) && !defined(MSDOS)
-
-/*
- * Return the name of a network interface attached to the system, or NULL
- * if none can be found. The interface must be configured up; the
- * lowest unit number is preferred; loopback is ignored.
- */
-char *
-pcap_lookupdev(errbuf)
- register char *errbuf;
-{
- pcap_if_t *alldevs;
-/* for old BSD systems, including bsdi3 */
-#ifndef IF_NAMESIZE
-#define IF_NAMESIZE IFNAMSIZ
-#endif
- static char device[IF_NAMESIZE + 1];
- char *ret;
-
- if (pcap_findalldevs(&alldevs, errbuf) == -1)
- return (NULL);
-
- if (alldevs == NULL || (alldevs->flags & PCAP_IF_LOOPBACK)) {
- /*
- * There are no devices on the list, or the first device
- * on the list is a loopback device, which means there
- * are no non-loopback devices on the list. This means
- * we can't return any device.
- *
- * XXX - why not return a loopback device? If we can't
- * capture on it, it won't be on the list, and if it's
- * 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",
- PCAP_ERRBUF_SIZE);
- ret = NULL;
- } else {
- /*
- * Return the name of the first device on the list.
- */
- (void)strlcpy(device, alldevs->name, sizeof(device));
- ret = device;
- }
-
- pcap_freealldevs(alldevs);
- return (ret);
-}
-
-int
-pcap_lookupnet(device, netp, maskp, errbuf)
- register const char *device;
- register bpf_u_int32 *netp, *maskp;
- register char *errbuf;
-{
- register int fd;
- register struct sockaddr_in *sin4;
- struct ifreq ifr;
-
- /*
- * The pseudo-device "any" listens on all interfaces and therefore
- * has the network address and -mask "0.0.0.0" therefore catching
- * all traffic. Using NULL for the interface is the same as "any".
- */
- if (!device || strcmp(device, "any") == 0
-#ifdef HAVE_DAG_API
- || strstr(device, "dag") != NULL
-#endif
-#ifdef HAVE_SEPTEL_API
- || strstr(device, "septel") != NULL
-#endif
-#ifdef PCAP_SUPPORT_BT
- || strstr(device, "bluetooth") != NULL
-#endif
-#ifdef PCAP_SUPPORT_USB
- || strstr(device, "usbmon") != NULL
-#endif
-#ifdef PCAP_SUPPORT_NETMAP
- || !strncmp(device, "netmap:", 7)
- || !strncmp(device, "vale", 4)
-#endif
-#ifdef HAVE_SNF_API
- || strstr(device, "snf") != NULL
-#endif
- ) {
- *netp = *maskp = 0;
- return 0;
- }
-
- fd = socket(AF_INET, SOCK_DGRAM, 0);
- if (fd < 0) {
- (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "socket: %s",
- pcap_strerror(errno));
- return (-1);
- }
- memset(&ifr, 0, sizeof(ifr));
-#ifdef linux
- /* XXX Work around Linux kernel bug */
- ifr.ifr_addr.sa_family = AF_INET;
-#endif
- (void)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,
- "%s: no IPv4 address assigned", device);
- } else {
- (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "SIOCGIFADDR: %s: %s",
- device, pcap_strerror(errno));
- }
- (void)close(fd);
- return (-1);
- }
- sin4 = (struct sockaddr_in *)&ifr.ifr_addr;
- *netp = sin4->sin_addr.s_addr;
- memset(&ifr, 0, sizeof(ifr));
-#ifdef linux
- /* XXX Work around Linux kernel bug */
- ifr.ifr_addr.sa_family = AF_INET;
-#endif
- (void)strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
- if (ioctl(fd, SIOCGIFNETMASK, (char *)&ifr) < 0) {
- (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "SIOCGIFNETMASK: %s: %s", device, pcap_strerror(errno));
- (void)close(fd);
- return (-1);
- }
- (void)close(fd);
- *maskp = sin4->sin_addr.s_addr;
- if (*maskp == 0) {
- if (IN_CLASSA(*netp))
- *maskp = IN_CLASSA_NET;
- else if (IN_CLASSB(*netp))
- *maskp = IN_CLASSB_NET;
- else if (IN_CLASSC(*netp))
- *maskp = IN_CLASSC_NET;
- else {
- (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "inet class for 0x%x unknown", *netp);
- return (-1);
- }
- }
- *netp &= *maskp;
- return (0);
-}
-
-#elif defined(_WIN32)
-
-/*
- * Return the name of a network interface attached to the system, or NULL
- * if none can be found. The interface must be configured up; the
- * lowest unit number is preferred; loopback is ignored.
- *
- * In the best of all possible worlds, this would be the same as on
- * UN*X, but there may be software that expects this to return a
- * full list of devices after the first device.
- */
-#define ADAPTERSNAME_LEN 8192
-char *
-pcap_lookupdev(errbuf)
- register 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 */
- dwVersion = GetVersion(); /* get the OS version */
-#pragma warning (pop)
- dwWindowsMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
-
- if (dwVersion >= 0x80000000 && dwWindowsMajorVersion >= 4) {
- /*
- * Windows 95, 98, ME.
- */
- ULONG NameLength = ADAPTERSNAME_LEN;
- static char AdaptersName[ADAPTERSNAME_LEN];
-
- if (PacketGetAdapterNames(AdaptersName,&NameLength) )
- return (AdaptersName);
- else
- return NULL;
- } else {
- /*
- * Windows NT (NT 4.0 and later).
- * Convert the names to Unicode for backward compatibility.
- */
- ULONG NameLength = ADAPTERSNAME_LEN;
- static WCHAR AdaptersName[ADAPTERSNAME_LEN];
- size_t BufferSpaceLeft;
- char *tAstr;
- WCHAR *Unameptr;
- char *Adescptr;
- size_t namelen, i;
- WCHAR *TAdaptersName = (WCHAR*)malloc(ADAPTERSNAME_LEN * sizeof(WCHAR));
- int NAdapts = 0;
-
- if(TAdaptersName == NULL)
- {
- (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "memory allocation failure");
- return NULL;
- }
-
- if ( !PacketGetAdapterNames((PTSTR)TAdaptersName,&NameLength) )
- {
- pcap_win32_err_to_str(GetLastError(), our_errbuf);
- (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "PacketGetAdapterNames: %s", our_errbuf);
- free(TAdaptersName);
- return NULL;
- }
-
-
- BufferSpaceLeft = ADAPTERSNAME_LEN * sizeof(WCHAR);
- tAstr = (char*)TAdaptersName;
- Unameptr = AdaptersName;
-
- /*
- * Convert the device names to Unicode into AdapterName.
- */
- do {
- /*
- * Length of the name, including the terminating
- * NUL.
- */
- namelen = strlen(tAstr) + 1;
-
- /*
- * Do we have room for the name in the Unicode
- * buffer?
- */
- if (BufferSpaceLeft < namelen * sizeof(WCHAR)) {
- /*
- * No.
- */
- goto quit;
- }
- BufferSpaceLeft -= namelen * sizeof(WCHAR);
-
- /*
- * Copy the name, converting ASCII to Unicode.
- * namelen includes the NUL, so we copy it as
- * well.
- */
- for (i = 0; i < namelen; i++)
- *Unameptr++ = *tAstr++;
-
- /*
- * Count this adapter.
- */
- NAdapts++;
- } while (namelen != 1);
-
- /*
- * Copy the descriptions, but don't convert them from
- * ASCII to Unicode.
- */
- Adescptr = (char *)Unameptr;
- while(NAdapts--)
- {
- size_t desclen;
-
- desclen = strlen(tAstr) + 1;
-
- /*
- * Do we have room for the name in the Unicode
- * buffer?
- */
- if (BufferSpaceLeft < desclen) {
- /*
- * No.
- */
- goto quit;
- }
-
- /*
- * Just copy the ASCII string.
- * namelen includes the NUL, so we copy it as
- * well.
- */
- memcpy(Adescptr, tAstr, desclen);
- Adescptr += desclen;
- tAstr += desclen;
- BufferSpaceLeft -= desclen;
- }
-
- quit:
- free(TAdaptersName);
- return (char *)(AdaptersName);
- }
-}
-
-
-int
-pcap_lookupnet(device, netp, maskp, errbuf)
- register const char *device;
- register bpf_u_int32 *netp, *maskp;
- register char *errbuf;
-{
- /*
- * We need only the first IPv4 address, so we must scan the array returned by PacketGetNetInfo()
- * in order to skip non IPv4 (i.e. IPv6 addresses)
- */
- npf_if_addr if_addrs[MAX_NETWORK_ADDRESSES];
- LONG if_addr_size = 1;
- struct sockaddr_in *t_addr;
- unsigned int i;
-
- if (!PacketGetNetInfoEx((void *)device, if_addrs, &if_addr_size)) {
- *netp = *maskp = 0;
- return (0);
- }
-
- for(i=0; i<MAX_NETWORK_ADDRESSES; i++)
- {
- if(if_addrs[i].IPAddress.ss_family == AF_INET)
- {
- t_addr = (struct sockaddr_in *) &(if_addrs[i].IPAddress);
- *netp = t_addr->sin_addr.S_un.S_addr;
- t_addr = (struct sockaddr_in *) &(if_addrs[i].SubnetMask);
- *maskp = t_addr->sin_addr.S_un.S_addr;
-
- *netp &= *maskp;
- return (0);
- }
-
- }
-
- *netp = *maskp = 0;
- return (0);
-}
-
-#endif /* !_WIN32 && !MSDOS */
diff --git a/contrib/libpcap/libpcap.pc.in b/contrib/libpcap/libpcap.pc.in
new file mode 100644
index 0000000000000..d74cbc55dddde
--- /dev/null
+++ b/contrib/libpcap/libpcap.pc.in
@@ -0,0 +1,18 @@
+#
+# pkg-config file for libpcap.
+#
+# These variables come from the configure script, so includedir and
+# libdir may be defined in terms of prefix and exec_prefix, so the
+# latter must be defined as well.
+#
+prefix="@prefix@"
+exec_prefix="@exec_prefix@"
+includedir="@includedir@"
+libdir="@libdir@"
+
+Name: libpcap
+Description: Platform-independent network traffic capture library
+Version: @PACKAGE_VERSION@
+Libs: -L${libdir} -l@PACKAGE_NAME@
+Libs.private: @LIBS@
+Cflags: -I${includedir}
diff --git a/contrib/libpcap/missing/getopt.c b/contrib/libpcap/missing/getopt.c
index cc798e1de84d3..7c897c6f59363 100644
--- a/contrib/libpcap/missing/getopt.c
+++ b/contrib/libpcap/missing/getopt.c
@@ -56,10 +56,7 @@ char *optarg; /* argument associated with option */
* Parse argc/argv argument vector.
*/
int
-getopt(nargc, nargv, ostr)
- int nargc;
- char * const *nargv;
- const char *ostr;
+getopt(int nargc, char * const *nargv, const char *ostr)
{
char *cp;
static char *__progname;
diff --git a/contrib/libpcap/missing/getopt.h b/contrib/libpcap/missing/getopt.h
index d176345ae20ba..fc83c944d7def 100644
--- a/contrib/libpcap/missing/getopt.h
+++ b/contrib/libpcap/missing/getopt.h
@@ -2,6 +2,6 @@
* Header for the getopt() we supply if the platform doesn't supply it.
*/
extern char *optarg; /* getopt(3) external variables */
-extern int optind, opterr, optopt;
+extern int optind, opterr, optreset, optopt;
extern int getopt(int nargc, char * const *nargv, const char *ostr);
diff --git a/contrib/libpcap/missing/strtok_r.c b/contrib/libpcap/missing/strtok_r.c
index c9c94b95d832c..5fca2f3d36979 100644
--- a/contrib/libpcap/missing/strtok_r.c
+++ b/contrib/libpcap/missing/strtok_r.c
@@ -35,7 +35,7 @@
*/
#ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
#endif
#include "portability.h"
diff --git a/contrib/libpcap/msdos/bin2c.c b/contrib/libpcap/msdos/bin2c.c
new file mode 100644
index 0000000000000..26d90083fbfb4
--- /dev/null
+++ b/contrib/libpcap/msdos/bin2c.c
@@ -0,0 +1,43 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <time.h>
+
+static void Abort (const char *fmt,...)
+{
+ va_list args;
+ va_start (args, fmt);
+ vfprintf (stderr, fmt, args);
+ va_end (args);
+ exit (1);
+}
+
+int main (int argc, char **argv)
+{
+ FILE *inFile;
+ FILE *outFile = stdout;
+ time_t now = time (NULL);
+ int ch, i;
+
+ if (argc != 2)
+ Abort ("Usage: %s bin-file [> result]", argv[0]);
+
+ if ((inFile = fopen(argv[1],"rb")) == NULL)
+ Abort ("Cannot open %s\n", argv[1]);
+
+ fprintf (outFile,
+ "/* data statements for file %s at %.24s */\n"
+ "/* Generated by BIN2C, G. Vanem 1995 */\n",
+ argv[1], ctime(&now));
+
+ i = 0;
+ while ((ch = fgetc(inFile)) != EOF)
+ {
+ if (i++ % 12 == 0)
+ fputs ("\n ", outFile);
+ fprintf (outFile, "0x%02X,", ch);
+ }
+ fputc ('\n', outFile);
+ fclose (inFile);
+ return (0);
+}
diff --git a/contrib/libpcap/msdos/makefile b/contrib/libpcap/msdos/makefile
new file mode 100644
index 0000000000000..599a619f402ef
--- /dev/null
+++ b/contrib/libpcap/msdos/makefile
@@ -0,0 +1,180 @@
+#
+# Makefile for dos-libpcap. NB. This makefile requires a Borland
+# compatible make tool.
+#
+# Targets:
+# Borland C 4.0+ (DOS large model)
+# Metaware HighC 3.3+ (PharLap 386|DosX)
+#
+
+.AUTODEPEND
+.SWAP
+
+!if "$(WATT_ROOT)" == ""
+!error Environment variable "WATT_ROOT" not set.
+!endif
+
+WATT_INC = $(WATT_ROOT)\inc
+
+DEFS = -DMSDOS -DDEBUG -DNDIS_DEBUG -D_U_= -Dinline= \
+ -DHAVE_STRERROR -DHAVE_LIMITS_H
+
+ASM = tasm.exe -t -l -mx -m2 -DDEBUG
+
+SOURCE = grammar.c scanner.c bpf_filt.c bpf_imag.c bpf_dump.c \
+ etherent.c gencode.c nametoad.c pcap-dos.c optimize.c \
+ savefile.c pcap.c msdos\ndis2.c msdos\pktdrvr.c \
+ missing\snprintf.c
+
+BORLAND_OBJ = $(SOURCE:.c=.obj) msdos\pkt_rx0.obj msdos\ndis_0.obj
+
+HIGHC_OBJ = $(SOURCE:.c=.o32) msdos\pkt_rx0.o32
+
+all:
+ @echo Usage: make pcap_bc.lib or pcap_hc.lib
+
+
+pcap_bc.lib: bcc.arg $(BORLAND_OBJ) pcap_bc
+
+
+pcap_hc.lib: hc386.arg $(HIGHC_OBJ)
+ 386lib $< @&&|
+ -nowarn -nobackup -twocase -replace $(HIGHC_OBJ)
+|
+
+pcap_bc: $(BORLAND_OBJ)
+ @tlib pcap_bc.lib /C @&&|
+ -+$(**:.obj=-+)
+|
+
+.c.obj:
+ bcc.exe @bcc.arg -o$*.obj $*.c
+
+.c.o32:
+ hc386.exe @hc386.arg -o $*.o32 $*.c
+
+.asm.obj:
+ $(ASM) $*.asm, $*.obj
+
+.asm.o32:
+ $(ASM) -DDOSX=1 $*.asm, $*.o32
+
+scanner.c: scanner.l
+ flex -Ppcap_ -7 -oscanner.c scanner.l
+
+grammar.c tokdefs.h: grammar.y
+ bison --name-prefix=pcap_ --yacc --defines grammar.y
+ - @del grammar.c
+ - @del tokdefs.h
+ ren y_tab.c grammar.c
+ ren y_tab.h tokdefs.h
+
+bcc.arg: msdos\Makefile
+ @copy &&|
+ $(DEFS) -ml -c -v -3 -O2 -po -RT- -w-
+ -I$(WATT_INC) -I. -I.\msdos\pm_drvr -H=$(TEMP)\bcc.sym
+| $<
+
+hc386.arg: msdos\Makefile
+ @copy &&|
+ # -DUSE_32BIT_DRIVERS
+ $(DEFS) -DDOSX=1 -w3 -c -g -O5
+ -I$(WATT_INC) -I. -I.\msdos\pm_drvr
+ -Hsuffix=.o32
+ -Hnocopyr
+ -Hpragma=Offwarn(491,553,572)
+ -Hon=Recognize_library # make memcpy/strlen etc. inline
+ -Hoff=Behaved # turn off some optimiser warnings
+| $<
+
+clean:
+ @del *.obj
+ @del *.o32
+ @del *.lst
+ @del *.map
+ @del bcc.arg
+ @del hc386.arg
+ @del grammar.c
+ @del tokdefs.h
+ @del scanner.c
+ @echo Cleaned
+
+#
+# dependencies
+#
+pkt_rx0.obj: msdos\pkt_rx0.asm
+
+bpf_filt.obj: bpf_filt.c pcap-int.h pcap.h pcap-bpf.h gnuc.h
+
+bpf_imag.obj: bpf_imag.c pcap-int.h pcap.h pcap-bpf.h
+
+bpf_dump.obj: bpf_dump.c pcap.h pcap-bpf.h
+
+etherent.obj: etherent.c pcap-int.h pcap.h pcap-bpf.h pcap-namedb.h
+
+optimize.obj: optimize.c pcap-int.h pcap.h pcap-bpf.h gencode.h
+
+savefile.obj: savefile.c pcap-int.h pcap.h pcap-bpf.h
+
+pcap.obj: pcap.c pcap-dos.h pcap-int.h pcap.h pcap-bpf.h
+
+grammar.obj: grammar.c pcap-int.h pcap.h pcap-bpf.h gencode.h \
+ pf.h pcap-namedb.h
+
+scanner.obj: scanner.c pcap-int.h pcap.h pcap-bpf.h gencode.h \
+ pcap-namedb.h tokdefs.h
+
+gencode.obj: gencode.c pcap-dos.h pcap-int.h pcap.h pcap-bpf.h \
+ ethertype.h nlpid.h llc.h gencode.h atmuni31.h sunatmpos.h ppp.h sll.h \
+ arcnet.h pf.h pcap-namedb.h
+
+nametoad.obj: nametoad.c pcap-int.h pcap.h pcap-bpf.h gencode.h \
+ pcap-namedb.h ethertype.h
+
+pcap-dos.obj: pcap-dos.c pcap.h pcap-bpf.h pcap-dos.h pcap-int.h \
+ msdos\pktdrvr.h
+
+pktdrvr.obj: msdos\pktdrvr.c gnuc.h pcap-dos.h pcap-int.h \
+ pcap.h pcap-bpf.h msdos\pktdrvr.h msdos\pkt_stub.inc
+
+ndis2.obj: msdos\ndis2.c pcap-dos.h pcap-int.h pcap.h pcap-bpf.h \
+ msdos\ndis2.h
+
+pkt_rx0.o32: msdos\pkt_rx0.asm
+
+bpf_filt.o32: bpf_filt.c pcap-int.h pcap.h pcap-bpf.h gnuc.h
+
+bpf_imag.o32: bpf_imag.c pcap-int.h pcap.h pcap-bpf.h
+
+bpf_dump.o32: bpf_dump.c pcap.h pcap-bpf.h
+
+etherent.o32: etherent.c pcap-int.h pcap.h pcap-bpf.h pcap-namedb.h
+
+optimize.o32: optimize.c pcap-int.h pcap.h pcap-bpf.h gencode.h
+
+savefile.o32: savefile.c pcap-int.h pcap.h pcap-bpf.h
+
+pcap.o32: pcap.c pcap-dos.h pcap-int.h pcap.h pcap-bpf.h
+
+grammar.o32: grammar.c pcap-int.h pcap.h pcap-bpf.h gencode.h \
+ pf.h pcap-namedb.h
+
+scanner.o32: scanner.c pcap-int.h pcap.h pcap-bpf.h gencode.h \
+ pcap-namedb.h tokdefs.h
+
+gencode.o32: gencode.c pcap-dos.h pcap-int.h pcap.h pcap-bpf.h \
+ ethertype.h nlpid.h llc.h gencode.h atmuni31.h sunatmpos.h ppp.h sll.h \
+ arcnet.h pf.h pcap-namedb.h
+
+nametoad.o32: nametoad.c pcap-int.h pcap.h pcap-bpf.h gencode.h \
+ pcap-namedb.h ethertype.h
+
+pcap-dos.o32: pcap-dos.c pcap.h pcap-bpf.h pcap-dos.h pcap-int.h \
+ msdos\pktdrvr.h
+
+pktdrvr.o32: msdos\pktdrvr.c gnuc.h pcap-dos.h pcap-int.h \
+ pcap.h pcap-bpf.h msdos\pktdrvr.h msdos\pkt_stub.inc
+
+ndis2.o32: msdos\ndis2.c pcap-dos.h pcap-int.h pcap.h pcap-bpf.h \
+ msdos\ndis2.h
+
diff --git a/contrib/libpcap/msdos/makefile.dj b/contrib/libpcap/msdos/makefile.dj
new file mode 100644
index 0000000000000..190db0071e45a
--- /dev/null
+++ b/contrib/libpcap/msdos/makefile.dj
@@ -0,0 +1,127 @@
+#
+# GNU Makefile for DOS-libpcap. djgpp version.
+#
+# Use this makefile from the libpcap root directory.
+# E.g. like this:
+#
+# c:\net\pcap> make -f msdos/makefile.dj
+#
+# Note: you should do a "set LFN=y" before running this makefile.
+#
+
+VPATH = missing msdos bpf/net
+
+PREREQUISITES = scanner.c grammar.c tokdefs.h version.h msdos/pkt_stub.inc
+
+include ./msdos/common.dj
+
+DRIVER_DIR = ./msdos/pm_drvr
+
+CFLAGS += -DDEBUG -DNDIS_DEBUG -DHAVE_LIMITS_H -DHAVE_STRERROR -DHAVE_SNPRINTF -DHAVE_VSNPRINTF\
+ -D_U_='__attribute__((unused))'
+
+CFLAGS += -Dyylval=pcap_lval # -DBDEBUG -DNDEBUG
+
+SOURCES = grammar.c scanner.c bpf/net/bpf_filter.c bpf_image.c bpf_dump.c \
+ etherent.c gencode.c nametoaddr.c pcap-common.c pcap-dos.c optimize.c \
+ savefile.c pcap.c sf-pcap.c sf-pcapng.c \
+ msdos/pktdrvr.c msdos/ndis2.c # missing/snprintf.c
+
+OBJECTS = $(addprefix $(OBJ_DIR)/, $(notdir $(SOURCES:.c=.o)))
+TEMPBIN = tmp.bin
+
+ifeq ($(USE_32BIT_DRIVERS),1)
+ PM_OBJECTS = $(addprefix $(OBJ_DIR)/, \
+ printk.o pci.o pci-scan.o bios32.o dma.o irq.o intwrap.o \
+ lock.o kmalloc.o quirks.o timer.o net_init.o)
+ #
+ # Static link of drivers
+ #
+ ifeq ($(USE_32BIT_MODULES),0)
+ PM_OBJECTS += $(addprefix $(OBJ_DIR)/, \
+ accton.o 8390.o 3c503.o 3c509.o 3c59x.o 3c515.o \
+ 3c575_cb.o 3c90x.o ne.o wd.o cs89x0.o rtl8139.o)
+ endif
+endif
+
+TARGETS = msdos/bin2c.exe libpcap.a filtertest.exe findalldevstest.exe \
+ nonblocktest.exe opentest.exe
+
+all: $(TARGETS)
+ @echo 'Welcome to libpcap/djgpp with samples.'
+
+ifeq ($(USE_32BIT_DRIVERS),1)
+$(PM_OBJECTS):
+ $(MAKE) -f Makefile.dj -C $(DRIVER_DIR) $(notdir $@)
+endif
+
+libpcap.a: version.h $(OBJECTS) $(PM_OBJECTS)
+ rm -f $@
+ ar rs $@ $^
+
+filtertest.exe: tests/filtertest.c libpcap.a
+ $(CC) $(CFLAGS) -Din_addr_t=u_long -o $@ $^ $(WATT32_ROOT)/lib/libwatt.a
+ @echo
+
+findalldevstest.exe: tests/findalldevstest.c libpcap.a
+ $(CC) $(CFLAGS) -o $@ $^ $(WATT32_ROOT)/lib/libwatt.a
+ @echo
+
+nonblocktest.exe: tests/nonblocktest.c libpcap.a
+ $(CC) $(CFLAGS) -o $@ $^ $(WATT32_ROOT)/lib/libwatt.a
+ @echo
+
+opentest.exe: tests/opentest.c libpcap.a
+ $(CC) $(CFLAGS) -o $@ $^ $(WATT32_ROOT)/lib/libwatt.a
+ @echo
+
+msdos/pkt_stub.inc: msdos/bin2c.exe msdos/pkt_rx1.S
+ $(ASM) -o $(TEMPBIN) -lmsdos/pkt_rx1.lst msdos/pkt_rx1.S
+ ./msdos/bin2c $(TEMPBIN) > $@
+ rm -f $(TEMPBIN)
+
+grammar.c tokdefs.h: grammar.y
+ rm -f grammar.c tokdefs.h
+ $(YACC) --name-prefix=pcap_ --yacc --defines grammar.y
+ mv -f y.tab.c grammar.c
+ mv -f y.tab.h tokdefs.h
+
+version.h: ./VERSION
+ @echo '/* Generated from VERSION. Do not edit */' > $@
+ sed -e 's/.*/static char pcap_version_string[] = "libpcap (&)";/' ./VERSION >> $@
+
+scanner.c: scanner.l
+ $(LEX) -Ppcap_ -7 -t $^ > $@
+ @echo
+
+msdos/bin2c.exe: msdos/bin2c.c
+ $(CC) $*.c -o $*.exe
+
+clean:
+ rm -f $(OBJECTS) msdos/pkt_rx1.lst Makefile.bak .depend.dj $(PREREQUISITES)
+# $(MAKE) -f Makefile.dj -C $(DRIVER_DIR) clean
+
+vclean: clean
+ rm -f $(TARGETS)
+ -rmdir $(OBJ_DIR)
+
+#
+# Manually generated dependencies
+#
+msdos/pktdrvr.c: msdos/pkt_stub.inc
+scanner.c: scanner.l
+grammar.c tokdefs.h: grammar.y
+grammar.h: grammar.y
+scanner.l: pcap-int.h pcap-namedb.h gencode.h grammar.h
+grammar.y: pcap-int.h gencode.h pcap-namedb.h
+
+#
+# Generate dependencies.
+#
+REPLACE = sed -e 's/\(.*\)\.o: /\n$$(OBJ_DIR)\/\1.o: /'
+
+depend: $(PREREQUISITES)
+ $(CC) -MM $(CFLAGS) $(SOURCES) | $(REPLACE) > .depend.dj
+
+-include .depend.dj
+
diff --git a/contrib/libpcap/msdos/makefile.wc b/contrib/libpcap/msdos/makefile.wc
new file mode 100644
index 0000000000000..0246012050336
--- /dev/null
+++ b/contrib/libpcap/msdos/makefile.wc
@@ -0,0 +1,132 @@
+#
+# Watcom Makefile for dos-libpcap.
+#
+# Specify MODEL = `3r' or `3s'
+# Specify TARGET = `pharlap' or `dos4g'
+#
+# Use this makefile from the libpcap root directory.
+# E.g. like this:
+#
+# c:\net\pcap> wmake -f msdos\makefile.wc
+#
+
+MODEL = 3s
+TARGET = dos4g
+
+OBJDIR = msdos\$(TARGET).w$(MODEL)
+LIB = $(OBJDIR)\pcap.lib
+
+.EXTENSIONS: .l .y
+
+DEFS = -dDEBUG -dNDIS_DEBUG -d_U_= -dHAVE_LIMITS_H -dHAVE_STRERROR &
+ -dHAVE_SNPRINTF -dHAVE_VSNPRINTF
+
+CC = wcc386.exe
+ASM = wasm.exe -$(MODEL) $(DEFS) -dDOSX -dDOS4GW -zq -bt=dos -fr=nul -d3 -s
+
+OBJS = $(OBJDIR)\grammar.obj $(OBJDIR)\scanner.obj $(OBJDIR)\pcap.obj &
+ $(OBJDIR)\bpf_filter.obj $(OBJDIR)\bpf_imag.obj $(OBJDIR)\bpf_dump.obj &
+ $(OBJDIR)\etherent.obj $(OBJDIR)\gencode.obj $(OBJDIR)\nametoad.obj &
+ $(OBJDIR)\pcap-dos.obj $(OBJDIR)\pktdrvr.obj $(OBJDIR)\optimize.obj &
+ $(OBJDIR)\savefile.obj $(OBJDIR)\ndis2.obj
+
+CFLAGS = $(DEFS) $(YYDEFS) -I. -I$(%watt_root)\inc -I.\msdos\pm_drvr &
+ -$(MODEL) -mf -zff -zgf -zq -bt=dos -fr=nul -w6 -fpi &
+ -oilrtf -zm
+
+TEMPBIN = tmp.bin
+
+all: $(OBJDIR) $(OBJDIR)\pcap.lib
+
+$(OBJDIR):
+ - mkdir $(OBJDIR)
+
+$(OBJDIR)\pcap.lib: $(OBJS) wlib.arg
+ wlib -q -b -c $(OBJDIR)\pcap.lib @wlib.arg
+
+wlib.arg: msdos\makefile.wc
+ %create $^@
+ for %f in ($(OBJS)) do %append $^@ +- %f
+
+$(OBJDIR)\pktdrvr.obj: msdos\pkt_stub.inc msdos\pktdrvr.c &
+ pcap-dos.h pcap-int.h pcap.h msdos\pktdrvr.h
+ *$(CC) $(CFLAGS) msdos\pktdrvr.c -fo=$@
+
+$(OBJDIR)\bpf_filter.obj: bpf\net\bpf_filter.c
+ *$(CC) $(CFLAGS) bpf\net\bpf_filter.c -fo=$@
+
+$(OBJDIR)\ndis2.obj: msdos\ndis2.c
+ *$(CC) $(CFLAGS) msdos\ndis2.c -fo=$@
+
+.ERASE
+.c{$(OBJDIR)}.obj:
+ *$(CC) $(CFLAGS) $[@ -fo=$@
+
+grammar.c tokdefs.h: grammar.y
+ bison --name-prefix=pcap_ --yacc --defines $[@
+ - @del grammar.c
+ - @del tokdefs.h
+ ren y_tab.c grammar.c
+ ren y_tab.h tokdefs.h
+
+scanner.c: scanner.l
+ flex -Ppcap_ -7 -o$@ $[@
+
+msdos\pkt_stub.inc: bin2c.exe msdos\pkt_rx1.S
+ nasm -fbin -dDEBUG -o $(TEMPBIN) -lmsdos\pkt_rx1.lst msdos\pkt_rx1.S
+ bin2c.exe $(TEMPBIN) > $@
+ @del $(TEMPBIN)
+
+bin2c.exe: msdos\bin2c.c
+ wcl $[@
+
+clean realclean vclean: .SYMBOLIC
+ for %f in (dos4g.w3r dos4g.w3s pharlap.w3r pharlap.w3s) do &
+ @del %f\*.obj
+ @del grammar.c
+ @del tokdefs.h
+ @del scanner.c
+ @del bin2c.exe
+ @del bin2c.obj
+ @del msdos\pkt_stub.inc
+ @echo Cleaned
+
+#
+# dependencies
+#
+$(OBJDIR)\bpf_filter.obj: bpf\net\bpf_filter.c pcap-int.h pcap.h pcap-bpf.h
+
+$(OBJDIR)\bpf_imag.obj: bpf_imag.c pcap-int.h pcap.h pcap-bpf.h
+
+$(OBJDIR)\bpf_dump.obj: bpf_dump.c pcap.h pcap-bpf.h
+
+$(OBJDIR)\etherent.obj: etherent.c pcap-int.h pcap.h pcap-bpf.h pcap-namedb.h
+
+$(OBJDIR)\optimize.obj: optimize.c pcap-int.h pcap.h pcap-bpf.h gencode.h
+
+$(OBJDIR)\savefile.obj: savefile.c pcap-int.h pcap.h pcap-bpf.h
+
+$(OBJDIR)\pcap.obj: pcap.c pcap-dos.h pcap-int.h pcap.h pcap-bpf.h
+
+$(OBJDIR)\grammar.obj: grammar.c pcap-int.h pcap.h pcap-bpf.h gencode.h &
+ pcap-namedb.h
+
+$(OBJDIR)\scanner.obj: scanner.c pcap-int.h pcap.h pcap-bpf.h gencode.h &
+ pcap-namedb.h tokdefs.h
+
+$(OBJDIR)\gencode.obj: gencode.c pcap-dos.h pcap-int.h pcap.h pcap-bpf.h &
+ ethertyp.h nlpid.h llc.h gencode.h atmuni31.h sunatmpo.h ppp.h sll.h &
+ arcnet.h pcap-namedb.h
+
+$(OBJDIR)\nametoad.obj: nametoad.c pcap-int.h pcap.h pcap-bpf.h gencode.h &
+ pcap-namedb.h ethertyp.h
+
+$(OBJDIR)\pcap-dos.obj: pcap-dos.c pcap.h pcap-bpf.h pcap-dos.h pcap-int.h &
+ msdos\pktdrvr.h
+
+$(OBJDIR)\pktdrvr.obj: msdos\pktdrvr.c pcap-dos.h pcap-int.h &
+ pcap.h pcap-bpf.h msdos\pktdrvr.h msdos\pkt_stub.inc
+
+$(OBJDIR)\ndis2.obj: msdos\ndis2.c pcap-dos.h pcap-int.h pcap.h pcap-bpf.h &
+ msdos\ndis2.h
+
diff --git a/contrib/libpcap/msdos/pkt_rx0.asm b/contrib/libpcap/msdos/pkt_rx0.asm
new file mode 100644
index 0000000000000..d604fa14be67f
--- /dev/null
+++ b/contrib/libpcap/msdos/pkt_rx0.asm
@@ -0,0 +1,197 @@
+PAGE 60,132
+NAME PKT_RX
+
+ifdef ??version ; using TASM
+ masm
+ jumps
+endif
+
+PUBLIC _pktDrop, _pktRxBuf, _pktTxBuf, _pktTemp
+PUBLIC _rxOutOfs, _rxInOfs, _PktReceiver, _pktRxEnd
+
+;
+; these sizes MUST be equal to the sizes in PKTDRVR.H
+;
+
+RX_BUF_SIZE = 1500 ; max message size on Ethernet
+TX_BUF_SIZE = 1500
+
+ifdef DOSX
+ .386
+ NUM_RX_BUF = 32 ; # of RX element buffers
+ _TEXT SEGMENT PUBLIC DWORD USE16 'CODE'
+ _TEXT ENDS
+ _DATA SEGMENT PUBLIC DWORD USE16 'CODE'
+ _DATA ENDS
+ D_SEG EQU <_TEXT SEGMENT>
+ D_END EQU <_TEXT ENDS>
+ ASSUME CS:_TEXT,DS:_TEXT
+else
+ .286
+ NUM_RX_BUF = 10
+ _TEXT SEGMENT PUBLIC DWORD 'CODE'
+ _TEXT ENDS
+ _DATA SEGMENT PUBLIC DWORD 'DATA'
+ _DATA ENDS
+ D_SEG EQU <_DATA SEGMENT>
+ D_END EQU <_DATA ENDS>
+ ASSUME CS:_TEXT,DS:_DATA
+endif
+
+;-------------------------------------------
+
+D_SEG
+
+RX_ELEMENT STRUC
+ firstCount dw 0 ; # of bytes on 1st call
+ secondCount dw 0 ; # of bytes on 2nd call
+ handle dw 0 ; handle for upcall
+ destinAdr db 6 dup (0) ; packet destination address
+ sourceAdr db 6 dup (0) ; packet source address
+ protocol dw 0 ; packet protocol number
+ rxBuffer db RX_BUF_SIZE dup (0) ; RX buffer
+ENDS
+ align 4
+_rxOutOfs dw offset _pktRxBuf ; ring buffer offsets
+_rxInOfs dw offset _pktRxBuf ; into _pktRxBuf
+_pktDrop dw 0,0 ; packet drop counter
+_pktTemp db 20 dup (0) ; temp work area
+_pktTxBuf db (TX_BUF_SIZE+14) dup (0) ; TX buffer
+_pktRxBuf RX_ELEMENT NUM_RX_BUF dup (<>) ; RX structures
+ LAST_OFS = offset $
+
+ screenSeg dw 0B800h
+ newInOffset dw 0
+
+ fanChars db '-\|/'
+ fanIndex dw 0
+
+D_END
+
+_TEXT SEGMENT
+
+
+SHOW_RX MACRO
+ push es
+ push bx
+ mov bx, screenSeg
+ mov es, bx ;; r-mode segment of colour screen
+ mov di, 158 ;; upper right corner - 1
+ mov bx, fanIndex
+ mov al, fanChars[bx] ;; get write char
+ mov ah, 15 ;; and white colour
+ stosw ;; write to screen at ES:EDI
+ inc fanIndex ;; update next index
+ and fanIndex, 3
+ pop bx
+ pop es
+ENDM
+
+;------------------------------------------------------------------------
+;
+; This macro return ES:DI to tail of Rx queue
+
+ENQUEUE MACRO
+ LOCAL @noWrap
+ mov ax, _rxInOfs ;; DI = current in-offset
+ add ax, SIZE RX_ELEMENT ;; point to next _pktRxBuf buffer
+ cmp ax, LAST_OFS ;; pointing past last ?
+ jb @noWrap ;; no - jump
+ lea ax, _pktRxBuf ;; yes, point to 1st buffer
+ align 4
+@noWrap: cmp ax, _rxOutOfs ;; in-ofs = out-ofs ?
+ je @dump ;; yes, queue is full
+ mov di, _rxInOfs ;; ES:DI -> buffer at queue input
+ mov newInOffset, ax ;; remember new input offset
+
+ ;; NOTE. rxInOfs is updated after the packet has been copied
+ ;; to ES:DI (= DS:SI on 2nd call) by the packet driver
+
+ENDM
+
+;------------------------------------------------------------------------
+;
+; This routine gets called by the packet driver twice:
+; 1st time (AX=0) it requests an address where to put the packet
+;
+; 2nd time (AX=1) the packet has been copied to this location (DS:SI)
+; BX has client handle (stored in RX_ELEMENT.handle).
+; CX has # of bytes in packet on both call. They should be equal.
+;
+; A test for equality is done by putting CX in _pktRxBuf [n].firstCount
+; and _pktRxBuf[n].secondCount, and CL on first call in
+; _pktRxBuf[n].rxBuffer[CX]. These values are checked in "PktReceive"
+; (PKTDRVR.C)
+;
+;---------------------------------------------------------------------
+
+_PktReceiver:
+ pushf
+ cli ; no distraction wanted !
+ push ds
+ push bx
+ifdef DOSX
+ mov bx, cs
+else
+ mov bx, SEG _DATA
+endif
+ mov ds, bx
+ mov es, bx ; ES = DS = CS or seg _DATA
+ pop bx ; restore handle
+
+ cmp ax, 0 ; first call? (AX=0)
+ jne @post ; AX=1: second call, do post process
+
+ifdef DEBUG
+ SHOW_RX ; show that a packet is received
+endif
+ cmp cx, RX_BUF_SIZE+14 ; size OK ?
+ ja @skip ; no, packet to large for us
+
+ ENQUEUE ; ES:DI -> _pktRxBuf[n]
+
+ mov [di].firstCount, cx ; remember the first count.
+ mov [di].handle, bx ; remember the handle.
+ add di, 6 ; ES:DI -> _pktRxBuf[n].destinAdr
+ pop ds
+ popf
+ retf ; far return to driver with ES:DI
+
+ align 4
+@dump: inc _pktDrop[0] ; discard the packet on 1st call
+ adc _pktDrop[2], 0 ; increment packets lost
+
+@skip: xor di, di ; return ES:DI = NIL pointer
+ xor ax, ax
+ mov es, ax
+ pop ds
+ popf
+ retf
+
+ align 4
+@post: or si, si ; DS:SI->_pktRxBuf[n][n].destinAdr
+ jz @discard ; make sure we don't use NULL-pointer
+
+ sub si, 6 ; DS:SI -> _pktRxBuf[n].destinAdr
+ ;
+ ; push si
+ ; push [si].firstCount
+ ; call bpf_filter_match ; run the filter here some day?
+ ; add sp, 4
+ ; cmp ax, 0
+ ; je @discard
+
+ mov [si].secondCount, cx
+ mov ax, newInOffset
+ mov _rxInOfs, ax ; update _pktRxBuf input offset
+
+ align 4
+@discard:pop ds
+ popf
+ retf
+
+_pktRxEnd db 0 ; marker for end of r-mode code/data
+
+_TEXT ENDS
+
+END
diff --git a/contrib/libpcap/msdos/pkt_rx1.s b/contrib/libpcap/msdos/pkt_rx1.s
new file mode 100644
index 0000000000000..654e6577790af
--- /dev/null
+++ b/contrib/libpcap/msdos/pkt_rx1.s
@@ -0,0 +1,155 @@
+;
+; This file requires NASM 0.97+ to assemble
+;
+; Currently used only for djgpp + DOS4GW targets
+;
+; these sizes MUST be equal to the sizes in PKTDRVR.H
+;
+%define ETH_MTU 1500 ; max data size on Ethernet
+%define ETH_MIN 60 ; min/max total frame size
+%define ETH_MAX (ETH_MTU+2*6+2) ; =1514
+%define NUM_RX_BUF 32 ; # of RX element buffers
+%define RX_SIZE (ETH_MAX+6) ; sizeof(RX_ELEMENT) = 1514+6
+%idefine offset
+
+struc RX_ELEMENT
+ .firstCount resw 1 ; # of bytes on 1st call
+ .secondCount resw 1 ; # of bytes on 2nd call
+ .handle resw 1 ; handle for upcall
+ ; .timeStamp resw 4 ; 64-bit RDTSC value
+ .destinAdr resb 6 ; packet destination address
+ .sourceAdr resb 6 ; packet source address
+ .protocol resw 1 ; packet protocol number
+ .rxBuffer resb ETH_MTU ; RX buffer
+endstruc
+
+;-------------------------------------------
+
+[org 0] ; assemble to .bin file
+
+_rxOutOfs dw offset _pktRxBuf ; ring buffer offsets
+_rxInOfs dw offset _pktRxBuf ; into _pktRxBuf
+_pktDrop dw 0,0 ; packet drop counter
+_pktTemp resb 20 ; temp work area
+_pktTxBuf resb (ETH_MAX) ; TX buffer
+_pktRxBuf resb (RX_SIZE*NUM_RX_BUF) ; RX structures
+ LAST_OFS equ $
+
+screenSeg dw 0B800h
+newInOffset dw 0
+
+fanChars db '-\|/'
+fanIndex dw 0
+
+%macro SHOW_RX 0
+ push es
+ push bx
+ mov bx, [screenSeg]
+ mov es, bx ;; r-mode segment of colour screen
+ mov di, 158 ;; upper right corner - 1
+ mov bx, [fanIndex]
+ mov al, [fanChars+bx] ;; get write char
+ mov ah, 15 ;; and white colour
+ cld ;; Needed?
+ stosw ;; write to screen at ES:EDI
+ inc word [fanIndex] ;; update next index
+ and word [fanIndex], 3
+ pop bx
+ pop es
+%endmacro
+
+;PutTimeStamp
+; rdtsc
+; mov [si].timeStamp, eax
+; mov [si+4].timeStamp, edx
+; ret
+
+
+;------------------------------------------------------------------------
+;
+; This routine gets called by the packet driver twice:
+; 1st time (AX=0) it requests an address where to put the packet
+;
+; 2nd time (AX=1) the packet has been copied to this location (DS:SI)
+; BX has client handle (stored in RX_ELEMENT.handle).
+; CX has # of bytes in packet on both call. They should be equal.
+; A test for equality is done by putting CX in _pktRxBuf [n].firstCount
+; and _pktRxBuf[n].secondCount, and CL on first call in
+; _pktRxBuf[n].rxBuffer[CX]. These values are checked in "PktReceive"
+; (PKTDRVR.C)
+;
+;---------------------------------------------------------------------
+
+_PktReceiver:
+ pushf
+ cli ; no distraction wanted !
+ push ds
+ push bx
+ mov bx, cs
+ mov ds, bx
+ mov es, bx ; ES = DS = CS or seg _DATA
+ pop bx ; restore handle
+
+ cmp ax, 0 ; first call? (AX=0)
+ jne @post ; AX=1: second call, do post process
+
+%ifdef DEBUG
+ SHOW_RX ; show that a packet is received
+%endif
+
+ cmp cx, ETH_MAX ; size OK ?
+ ja @skip ; no, too big
+
+ mov ax, [_rxInOfs]
+ add ax, RX_SIZE
+ cmp ax, LAST_OFS
+ jb @noWrap
+ mov ax, offset _pktRxBuf
+@noWrap:
+ cmp ax, [_rxOutOfs]
+ je @dump
+ mov di, [_rxInOfs] ; ES:DI -> _pktRxBuf[n]
+ mov [newInOffset], ax
+
+ mov [di], cx ; remember firstCount.
+ mov [di+4], bx ; remember handle.
+ add di, 6 ; ES:DI -> _pktRxBuf[n].destinAdr
+ pop ds
+ popf
+ retf ; far return to driver with ES:DI
+
+@dump: add word [_pktDrop+0], 1 ; discard the packet on 1st call
+ adc word [_pktDrop+2], 0 ; increment packets lost
+
+@skip: xor di, di ; return ES:DI = NIL pointer
+ xor ax, ax
+ mov es, ax
+ pop ds
+ popf
+ retf
+
+@post: or si, si ; DS:SI->_pktRxBuf[n][n].destinAdr
+ jz @discard ; make sure we don't use NULL-pointer
+
+ ;
+ ; push si
+ ; call bpf_filter_match ; run the filter here some day
+ ; pop si
+ ; cmp ax, 0
+ ; je @discard
+
+ mov [si-6+2], cx ; store _pktRxBuf[n].secondCount
+ mov ax, [newInOffset]
+ mov [_rxInOfs], ax ; update _pktRxBuf input offset
+
+ ; call PutTimeStamp
+
+@discard:
+ pop ds
+ popf
+ retf
+
+_pktRxEnd db 0 ; marker for end of r-mode code/data
+
+END
+
diff --git a/contrib/libpcap/msdos/pktdrvr.c b/contrib/libpcap/msdos/pktdrvr.c
new file mode 100644
index 0000000000000..37fc8a41e7760
--- /dev/null
+++ b/contrib/libpcap/msdos/pktdrvr.c
@@ -0,0 +1,1436 @@
+/*
+ * File.........: pktdrvr.c
+ *
+ * Responsible..: Gisle Vanem, giva@bgnett.no
+ *
+ * Created......: 26.Sept 1995
+ *
+ * Description..: Packet-driver interface for 16/32-bit C :
+ * Borland C/C++ 3.0+ small/large model
+ * Watcom C/C++ 11+, DOS4GW flat model
+ * Metaware HighC 3.1+ and PharLap 386|DosX
+ * GNU C/C++ 2.7+ and djgpp 2.x extender
+ *
+ * References...: PC/TCP Packet driver Specification. rev 1.09
+ * FTP Software Inc.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dos.h>
+
+#include "pcap-dos.h"
+#include "pcap-int.h"
+#include "msdos/pktdrvr.h"
+
+#if (DOSX)
+#define NUM_RX_BUF 32 /* # of buffers in Rx FIFO queue */
+#else
+#define NUM_RX_BUF 10
+#endif
+
+#define DIM(x) (sizeof((x)) / sizeof(x[0]))
+#define PUTS(s) do { \
+ if (!pktInfo.quiet) \
+ pktInfo.error ? \
+ printf ("%s: %s\n", s, pktInfo.error) : \
+ printf ("%s\n", pktInfo.error = s); \
+ } while (0)
+
+#if defined(__HIGHC__)
+ extern UINT _mwenv;
+
+#elif defined(__DJGPP__)
+ #include <stddef.h>
+ #include <dpmi.h>
+ #include <go32.h>
+ #include <pc.h>
+ #include <sys/farptr.h>
+
+#elif defined(__WATCOMC__)
+ #include <i86.h>
+ #include <stddef.h>
+ extern char _Extender;
+
+#else
+ extern void far PktReceiver (void);
+#endif
+
+
+#if (DOSX & (DJGPP|DOS4GW))
+ #include <sys/pack_on.h>
+
+ struct DPMI_regs {
+ DWORD r_di;
+ DWORD r_si;
+ DWORD r_bp;
+ DWORD reserved;
+ DWORD r_bx;
+ DWORD r_dx;
+ DWORD r_cx;
+ DWORD r_ax;
+ WORD r_flags;
+ WORD r_es, r_ds, r_fs, r_gs;
+ WORD r_ip, r_cs, r_sp, r_ss;
+ };
+
+ /* Data located in a real-mode segment. This becomes far at runtime
+ */
+ typedef struct { /* must match data/code in pkt_rx1.s */
+ WORD _rxOutOfs;
+ WORD _rxInOfs;
+ DWORD _pktDrop;
+ BYTE _pktTemp [20];
+ TX_ELEMENT _pktTxBuf[1];
+ RX_ELEMENT _pktRxBuf[NUM_RX_BUF];
+ WORD _dummy[2]; /* screenSeg,newInOffset */
+ BYTE _fanChars[4];
+ WORD _fanIndex;
+ BYTE _PktReceiver[15]; /* starts on a paragraph (16byte) */
+ } PktRealStub;
+ #include <sys/pack_off.h>
+
+ static BYTE real_stub_array [] = {
+ #include "pkt_stub.inc" /* generated opcode array */
+ };
+
+ #define rxOutOfs offsetof (PktRealStub,_rxOutOfs)
+ #define rxInOfs offsetof (PktRealStub,_rxInOfs)
+ #define PktReceiver offsetof (PktRealStub,_PktReceiver [para_skip])
+ #define pktDrop offsetof (PktRealStub,_pktDrop)
+ #define pktTemp offsetof (PktRealStub,_pktTemp)
+ #define pktTxBuf offsetof (PktRealStub,_pktTxBuf)
+ #define FIRST_RX_BUF offsetof (PktRealStub,_pktRxBuf [0])
+ #define LAST_RX_BUF offsetof (PktRealStub,_pktRxBuf [NUM_RX_BUF-1])
+
+#else
+ extern WORD rxOutOfs; /* offsets into pktRxBuf FIFO queue */
+ extern WORD rxInOfs;
+ extern DWORD pktDrop; /* # packets dropped in PktReceiver() */
+ extern BYTE pktRxEnd; /* marks the end of r-mode code/data */
+
+ extern RX_ELEMENT pktRxBuf [NUM_RX_BUF]; /* PktDrvr Rx buffers */
+ extern TX_ELEMENT pktTxBuf; /* PktDrvr Tx buffer */
+ extern char pktTemp[20]; /* PktDrvr temp area */
+
+ #define FIRST_RX_BUF (WORD) &pktRxBuf [0]
+ #define LAST_RX_BUF (WORD) &pktRxBuf [NUM_RX_BUF-1]
+#endif
+
+
+#ifdef __BORLANDC__ /* Use Borland's inline functions */
+ #define memcpy __memcpy__
+ #define memcmp __memcmp__
+ #define memset __memset__
+#endif
+
+
+#if (DOSX & PHARLAP)
+ extern void PktReceiver (void); /* in pkt_rx0.asm */
+ static int RealCopy (ULONG, ULONG, REALPTR*, FARPTR*, USHORT*);
+
+ #undef FP_SEG
+ #undef FP_OFF
+ #define FP_OFF(x) ((WORD)(x))
+ #define FP_SEG(x) ((WORD)(realBase >> 16))
+ #define DOS_ADDR(s,o) (((DWORD)(s) << 16) + (WORD)(o))
+ #define r_ax eax
+ #define r_bx ebx
+ #define r_dx edx
+ #define r_cx ecx
+ #define r_si esi
+ #define r_di edi
+ #define r_ds ds
+ #define r_es es
+ LOCAL FARPTR protBase;
+ LOCAL REALPTR realBase;
+ LOCAL WORD realSeg; /* DOS para-address of allocated area */
+ LOCAL SWI_REGS reg;
+
+ static WORD _far *rxOutOfsFp, *rxInOfsFp;
+
+#elif (DOSX & DJGPP)
+ static _go32_dpmi_seginfo rm_mem;
+ static __dpmi_regs reg;
+ static DWORD realBase;
+ static int para_skip = 0;
+
+ #define DOS_ADDR(s,o) (((WORD)(s) << 4) + (o))
+ #define r_ax x.ax
+ #define r_bx x.bx
+ #define r_dx x.dx
+ #define r_cx x.cx
+ #define r_si x.si
+ #define r_di x.di
+ #define r_ds x.ds
+ #define r_es x.es
+
+#elif (DOSX & DOS4GW)
+ LOCAL struct DPMI_regs reg;
+ LOCAL WORD rm_base_seg, rm_base_sel;
+ LOCAL DWORD realBase;
+ LOCAL int para_skip = 0;
+
+ LOCAL DWORD dpmi_get_real_vector (int intr);
+ LOCAL WORD dpmi_real_malloc (int size, WORD *selector);
+ LOCAL void dpmi_real_free (WORD selector);
+ #define DOS_ADDR(s,o) (((DWORD)(s) << 4) + (WORD)(o))
+
+#else /* real-mode Borland etc. */
+ static struct {
+ WORD r_ax, r_bx, r_cx, r_dx, r_bp;
+ WORD r_si, r_di, r_ds, r_es, r_flags;
+ } reg;
+#endif
+
+#ifdef __HIGHC__
+ #pragma Alias (pktDrop, "_pktDrop")
+ #pragma Alias (pktRxBuf, "_pktRxBuf")
+ #pragma Alias (pktTxBuf, "_pktTxBuf")
+ #pragma Alias (pktTemp, "_pktTemp")
+ #pragma Alias (rxOutOfs, "_rxOutOfs")
+ #pragma Alias (rxInOfs, "_rxInOfs")
+ #pragma Alias (pktRxEnd, "_pktRxEnd")
+ #pragma Alias (PktReceiver,"_PktReceiver")
+#endif
+
+
+PUBLIC PKT_STAT pktStat; /* statistics for packets */
+PUBLIC PKT_INFO pktInfo; /* packet-driver information */
+
+PUBLIC PKT_RX_MODE receiveMode = PDRX_DIRECT;
+PUBLIC ETHER myAddress = { 0, 0, 0, 0, 0, 0 };
+PUBLIC ETHER ethBroadcast = { 255,255,255,255,255,255 };
+
+LOCAL struct { /* internal statistics */
+ DWORD tooSmall; /* size < ETH_MIN */
+ DWORD tooLarge; /* size > ETH_MAX */
+ DWORD badSync; /* count_1 != count_2 */
+ DWORD wrongHandle; /* upcall to wrong handle */
+ } intStat;
+
+/***************************************************************************/
+
+PUBLIC const char *PktGetErrorStr (int errNum)
+{
+ static const char *errStr[] = {
+ "",
+ "Invalid handle number",
+ "No interfaces of specified class found",
+ "No interfaces of specified type found",
+ "No interfaces of specified number found",
+ "Bad packet type specified",
+ "Interface does not support multicast",
+ "Packet driver cannot terminate",
+ "Invalid receiver mode specified",
+ "Insufficient memory space",
+ "Type previously accessed, and not released",
+ "Command out of range, or not implemented",
+ "Cannot send packet (usually hardware error)",
+ "Cannot change hardware address ( > 1 handle open)",
+ "Hardware address has bad length or format",
+ "Cannot reset interface (more than 1 handle open)",
+ "Bad Check-sum",
+ "Bad size",
+ "Bad sync" ,
+ "Source hit"
+ };
+
+ if (errNum < 0 || errNum >= DIM(errStr))
+ return ("Unknown driver error.");
+ return (errStr [errNum]);
+}
+
+/**************************************************************************/
+
+PUBLIC const char *PktGetClassName (WORD class)
+{
+ switch (class)
+ {
+ case PD_ETHER:
+ return ("DIX-Ether");
+ case PD_PRONET10:
+ return ("ProNET-10");
+ case PD_IEEE8025:
+ return ("IEEE 802.5");
+ case PD_OMNINET:
+ return ("OmniNet");
+ case PD_APPLETALK:
+ return ("AppleTalk");
+ case PD_SLIP:
+ return ("SLIP");
+ case PD_STARTLAN:
+ return ("StartLAN");
+ case PD_ARCNET:
+ return ("ArcNet");
+ case PD_AX25:
+ return ("AX.25");
+ case PD_KISS:
+ return ("KISS");
+ case PD_IEEE8023_2:
+ return ("IEEE 802.3 w/802.2 hdr");
+ case PD_FDDI8022:
+ return ("FDDI w/802.2 hdr");
+ case PD_X25:
+ return ("X.25");
+ case PD_LANstar:
+ return ("LANstar");
+ case PD_PPP:
+ return ("PPP");
+ default:
+ return ("unknown");
+ }
+}
+
+/**************************************************************************/
+
+PUBLIC char const *PktRXmodeStr (PKT_RX_MODE mode)
+{
+ static const char *modeStr [] = {
+ "Receiver turned off",
+ "Receive only directly addressed packets",
+ "Receive direct & broadcast packets",
+ "Receive direct,broadcast and limited multicast packets",
+ "Receive direct,broadcast and all multicast packets",
+ "Receive all packets (promiscuouos mode)"
+ };
+
+ if (mode > DIM(modeStr))
+ return ("??");
+ return (modeStr [mode-1]);
+}
+
+/**************************************************************************/
+
+LOCAL __inline BOOL PktInterrupt (void)
+{
+ BOOL okay;
+
+#if (DOSX & PHARLAP)
+ _dx_real_int ((UINT)pktInfo.intr, &reg);
+ okay = ((reg.flags & 1) == 0); /* OK if carry clear */
+
+#elif (DOSX & DJGPP)
+ __dpmi_int ((int)pktInfo.intr, &reg);
+ okay = ((reg.x.flags & 1) == 0);
+
+#elif (DOSX & DOS4GW)
+ union REGS r;
+ struct SREGS s;
+
+ memset (&r, 0, sizeof(r));
+ segread (&s);
+ r.w.ax = 0x300;
+ r.x.ebx = pktInfo.intr;
+ r.w.cx = 0;
+ s.es = FP_SEG (&reg);
+ r.x.edi = FP_OFF (&reg);
+ reg.r_flags = 0;
+ reg.r_ss = reg.r_sp = 0; /* DPMI host provides stack */
+
+ int386x (0x31, &r, &r, &s);
+ okay = (!r.w.cflag);
+
+#else
+ reg.r_flags = 0;
+ intr (pktInfo.intr, (struct REGPACK*)&reg);
+ okay = ((reg.r_flags & 1) == 0);
+#endif
+
+ if (okay)
+ pktInfo.error = NULL;
+ else pktInfo.error = PktGetErrorStr (reg.r_dx >> 8);
+ return (okay);
+}
+
+/**************************************************************************/
+
+/*
+ * Search for packet driver at interrupt 60h through 80h. If ASCIIZ
+ * string "PKT DRVR" found at offset 3 in the interrupt handler, return
+ * interrupt number, else return zero in pktInfo.intr
+ */
+PUBLIC BOOL PktSearchDriver (void)
+{
+ BYTE intr = 0x20;
+ BOOL found = FALSE;
+
+ while (!found && intr < 0xFF)
+ {
+ static char str[12]; /* 3 + strlen("PKT DRVR") */
+ static char pktStr[9] = "PKT DRVR"; /* ASCIIZ string at ofs 3 */
+ DWORD rp; /* in interrupt routine */
+
+#if (DOSX & PHARLAP)
+ _dx_rmiv_get (intr, &rp);
+ ReadRealMem (&str, (REALPTR)rp, sizeof(str));
+
+#elif (DOSX & DJGPP)
+ __dpmi_raddr realAdr;
+ __dpmi_get_real_mode_interrupt_vector (intr, &realAdr);
+ rp = (realAdr.segment << 4) + realAdr.offset16;
+ dosmemget (rp, sizeof(str), &str);
+
+#elif (DOSX & DOS4GW)
+ rp = dpmi_get_real_vector (intr);
+ memcpy (&str, (void*)rp, sizeof(str));
+
+#else
+ _fmemcpy (&str, getvect(intr), sizeof(str));
+#endif
+
+ found = memcmp (&str[3],&pktStr,sizeof(pktStr)) == 0;
+ intr++;
+ }
+ pktInfo.intr = (found ? intr-1 : 0);
+ return (found);
+}
+
+
+/**************************************************************************/
+
+static BOOL PktSetAccess (void)
+{
+ reg.r_ax = 0x0200 + pktInfo.class;
+ reg.r_bx = 0xFFFF;
+ reg.r_dx = 0;
+ reg.r_cx = 0;
+
+#if (DOSX & PHARLAP)
+ reg.ds = 0;
+ reg.esi = 0;
+ reg.es = RP_SEG (realBase);
+ reg.edi = (WORD) &PktReceiver;
+
+#elif (DOSX & DJGPP)
+ reg.x.ds = 0;
+ reg.x.si = 0;
+ reg.x.es = rm_mem.rm_segment;
+ reg.x.di = PktReceiver;
+
+#elif (DOSX & DOS4GW)
+ reg.r_ds = 0;
+ reg.r_si = 0;
+ reg.r_es = rm_base_seg;
+ reg.r_di = PktReceiver;
+
+#else
+ reg.r_ds = 0;
+ reg.r_si = 0;
+ reg.r_es = FP_SEG (&PktReceiver);
+ reg.r_di = FP_OFF (&PktReceiver);
+#endif
+
+ if (!PktInterrupt())
+ return (FALSE);
+
+ pktInfo.handle = reg.r_ax;
+ return (TRUE);
+}
+
+/**************************************************************************/
+
+PUBLIC BOOL PktReleaseHandle (WORD handle)
+{
+ reg.r_ax = 0x0300;
+ reg.r_bx = handle;
+ return PktInterrupt();
+}
+
+/**************************************************************************/
+
+PUBLIC BOOL PktTransmit (const void *eth, int len)
+{
+ if (len > ETH_MTU)
+ return (FALSE);
+
+ reg.r_ax = 0x0400; /* Function 4, send pkt */
+ reg.r_cx = len; /* total size of frame */
+
+#if (DOSX & DJGPP)
+ dosmemput (eth, len, realBase+pktTxBuf);
+ reg.x.ds = rm_mem.rm_segment; /* DOS data segment and */
+ reg.x.si = pktTxBuf; /* DOS offset to buffer */
+
+#elif (DOSX & DOS4GW)
+ memcpy ((void*)(realBase+pktTxBuf), eth, len);
+ reg.r_ds = rm_base_seg;
+ reg.r_si = pktTxBuf;
+
+#elif (DOSX & PHARLAP)
+ memcpy (&pktTxBuf, eth, len);
+ reg.r_ds = FP_SEG (&pktTxBuf);
+ reg.r_si = FP_OFF (&pktTxBuf);
+
+#else
+ reg.r_ds = FP_SEG (eth);
+ reg.r_si = FP_OFF (eth);
+#endif
+
+ return PktInterrupt();
+}
+
+/**************************************************************************/
+
+#if (DOSX & (DJGPP|DOS4GW))
+LOCAL __inline BOOL CheckElement (RX_ELEMENT *rx)
+#else
+LOCAL __inline BOOL CheckElement (RX_ELEMENT _far *rx)
+#endif
+{
+ WORD count_1, count_2;
+
+ /*
+ * We got an upcall to the same RMCB with wrong handle.
+ * This can happen if we failed to release handle at program exit
+ */
+ if (rx->handle != pktInfo.handle)
+ {
+ pktInfo.error = "Wrong handle";
+ intStat.wrongHandle++;
+ PktReleaseHandle (rx->handle);
+ return (FALSE);
+ }
+ count_1 = rx->firstCount;
+ count_2 = rx->secondCount;
+
+ if (count_1 != count_2)
+ {
+ pktInfo.error = "Bad sync";
+ intStat.badSync++;
+ return (FALSE);
+ }
+ if (count_1 > ETH_MAX)
+ {
+ pktInfo.error = "Large esize";
+ intStat.tooLarge++;
+ return (FALSE);
+ }
+#if 0
+ if (count_1 < ETH_MIN)
+ {
+ pktInfo.error = "Small esize";
+ intStat.tooSmall++;
+ return (FALSE);
+ }
+#endif
+ return (TRUE);
+}
+
+/**************************************************************************/
+
+PUBLIC BOOL PktTerminHandle (WORD handle)
+{
+ reg.r_ax = 0x0500;
+ reg.r_bx = handle;
+ return PktInterrupt();
+}
+
+/**************************************************************************/
+
+PUBLIC BOOL PktResetInterface (WORD handle)
+{
+ reg.r_ax = 0x0700;
+ reg.r_bx = handle;
+ return PktInterrupt();
+}
+
+/**************************************************************************/
+
+PUBLIC BOOL PktSetReceiverMode (PKT_RX_MODE mode)
+{
+ if (pktInfo.class == PD_SLIP || pktInfo.class == PD_PPP)
+ return (TRUE);
+
+ reg.r_ax = 0x1400;
+ reg.r_bx = pktInfo.handle;
+ reg.r_cx = (WORD)mode;
+
+ if (!PktInterrupt())
+ return (FALSE);
+
+ receiveMode = mode;
+ return (TRUE);
+}
+
+/**************************************************************************/
+
+PUBLIC BOOL PktGetReceiverMode (PKT_RX_MODE *mode)
+{
+ reg.r_ax = 0x1500;
+ reg.r_bx = pktInfo.handle;
+
+ if (!PktInterrupt())
+ return (FALSE);
+
+ *mode = reg.r_ax;
+ return (TRUE);
+}
+
+/**************************************************************************/
+
+static PKT_STAT initialStat; /* statistics at startup */
+static BOOL resetStat = FALSE; /* statistics reset ? */
+
+PUBLIC BOOL PktGetStatistics (WORD handle)
+{
+ reg.r_ax = 0x1800;
+ reg.r_bx = handle;
+
+ if (!PktInterrupt())
+ return (FALSE);
+
+#if (DOSX & PHARLAP)
+ ReadRealMem (&pktStat, DOS_ADDR(reg.ds,reg.esi), sizeof(pktStat));
+
+#elif (DOSX & DJGPP)
+ dosmemget (DOS_ADDR(reg.x.ds,reg.x.si), sizeof(pktStat), &pktStat);
+
+#elif (DOSX & DOS4GW)
+ memcpy (&pktStat, (void*)DOS_ADDR(reg.r_ds,reg.r_si), sizeof(pktStat));
+
+#else
+ _fmemcpy (&pktStat, MK_FP(reg.r_ds,reg.r_si), sizeof(pktStat));
+#endif
+
+ return (TRUE);
+}
+
+/**************************************************************************/
+
+PUBLIC BOOL PktSessStatistics (WORD handle)
+{
+ if (!PktGetStatistics(pktInfo.handle))
+ return (FALSE);
+
+ if (resetStat)
+ {
+ pktStat.inPackets -= initialStat.inPackets;
+ pktStat.outPackets -= initialStat.outPackets;
+ pktStat.inBytes -= initialStat.inBytes;
+ pktStat.outBytes -= initialStat.outBytes;
+ pktStat.inErrors -= initialStat.inErrors;
+ pktStat.outErrors -= initialStat.outErrors;
+ pktStat.outErrors -= initialStat.outErrors;
+ pktStat.lost -= initialStat.lost;
+ }
+ return (TRUE);
+}
+
+/**************************************************************************/
+
+PUBLIC BOOL PktResetStatistics (WORD handle)
+{
+ if (!PktGetStatistics(pktInfo.handle))
+ return (FALSE);
+
+ memcpy (&initialStat, &pktStat, sizeof(initialStat));
+ resetStat = TRUE;
+ return (TRUE);
+}
+
+/**************************************************************************/
+
+PUBLIC BOOL PktGetAddress (ETHER *addr)
+{
+ reg.r_ax = 0x0600;
+ reg.r_bx = pktInfo.handle;
+ reg.r_cx = sizeof (*addr);
+
+#if (DOSX & DJGPP)
+ reg.x.es = rm_mem.rm_segment;
+ reg.x.di = pktTemp;
+#elif (DOSX & DOS4GW)
+ reg.r_es = rm_base_seg;
+ reg.r_di = pktTemp;
+#else
+ reg.r_es = FP_SEG (&pktTemp);
+ reg.r_di = FP_OFF (&pktTemp); /* ES:DI = address for result */
+#endif
+
+ if (!PktInterrupt())
+ return (FALSE);
+
+#if (DOSX & PHARLAP)
+ ReadRealMem (addr, realBase + (WORD)&pktTemp, sizeof(*addr));
+
+#elif (DOSX & DJGPP)
+ dosmemget (realBase+pktTemp, sizeof(*addr), addr);
+
+#elif (DOSX & DOS4GW)
+ memcpy (addr, (void*)(realBase+pktTemp), sizeof(*addr));
+
+#else
+ memcpy ((void*)addr, &pktTemp, sizeof(*addr));
+#endif
+
+ return (TRUE);
+}
+
+/**************************************************************************/
+
+PUBLIC BOOL PktSetAddress (const ETHER *addr)
+{
+ /* copy addr to real-mode scrath area */
+
+#if (DOSX & PHARLAP)
+ WriteRealMem (realBase + (WORD)&pktTemp, (void*)addr, sizeof(*addr));
+
+#elif (DOSX & DJGPP)
+ dosmemput (addr, sizeof(*addr), realBase+pktTemp);
+
+#elif (DOSX & DOS4GW)
+ memcpy ((void*)(realBase+pktTemp), addr, sizeof(*addr));
+
+#else
+ memcpy (&pktTemp, (void*)addr, sizeof(*addr));
+#endif
+
+ reg.r_ax = 0x1900;
+ reg.r_cx = sizeof (*addr); /* address length */
+
+#if (DOSX & DJGPP)
+ reg.x.es = rm_mem.rm_segment; /* DOS offset to param */
+ reg.x.di = pktTemp; /* DOS segment to param */
+#elif (DOSX & DOS4GW)
+ reg.r_es = rm_base_seg;
+ reg.r_di = pktTemp;
+#else
+ reg.r_es = FP_SEG (&pktTemp);
+ reg.r_di = FP_OFF (&pktTemp);
+#endif
+
+ return PktInterrupt();
+}
+
+/**************************************************************************/
+
+PUBLIC BOOL PktGetDriverInfo (void)
+{
+ pktInfo.majVer = 0;
+ pktInfo.minVer = 0;
+ memset (&pktInfo.name, 0, sizeof(pktInfo.name));
+ reg.r_ax = 0x01FF;
+ reg.r_bx = 0;
+
+ if (!PktInterrupt())
+ return (FALSE);
+
+ pktInfo.number = reg.r_cx & 0xFF;
+ pktInfo.class = reg.r_cx >> 8;
+#if 0
+ pktInfo.minVer = reg.r_bx % 10;
+ pktInfo.majVer = reg.r_bx / 10;
+#else
+ pktInfo.majVer = reg.r_bx; // !!
+#endif
+ pktInfo.funcs = reg.r_ax & 0xFF;
+ pktInfo.type = reg.r_dx & 0xFF;
+
+#if (DOSX & PHARLAP)
+ ReadRealMem (&pktInfo.name, DOS_ADDR(reg.ds,reg.esi), sizeof(pktInfo.name));
+
+#elif (DOSX & DJGPP)
+ dosmemget (DOS_ADDR(reg.x.ds,reg.x.si), sizeof(pktInfo.name), &pktInfo.name);
+
+#elif (DOSX & DOS4GW)
+ memcpy (&pktInfo.name, (void*)DOS_ADDR(reg.r_ds,reg.r_si), sizeof(pktInfo.name));
+
+#else
+ _fmemcpy (&pktInfo.name, MK_FP(reg.r_ds,reg.r_si), sizeof(pktInfo.name));
+#endif
+ return (TRUE);
+}
+
+/**************************************************************************/
+
+PUBLIC BOOL PktGetDriverParam (void)
+{
+ reg.r_ax = 0x0A00;
+
+ if (!PktInterrupt())
+ return (FALSE);
+
+#if (DOSX & PHARLAP)
+ ReadRealMem (&pktInfo.majVer, DOS_ADDR(reg.es,reg.edi), PKT_PARAM_SIZE);
+
+#elif (DOSX & DJGPP)
+ dosmemget (DOS_ADDR(reg.x.es,reg.x.di), PKT_PARAM_SIZE, &pktInfo.majVer);
+
+#elif (DOSX & DOS4GW)
+ memcpy (&pktInfo.majVer, (void*)DOS_ADDR(reg.r_es,reg.r_di), PKT_PARAM_SIZE);
+
+#else
+ _fmemcpy (&pktInfo.majVer, MK_FP(reg.r_es,reg.r_di), PKT_PARAM_SIZE);
+#endif
+ return (TRUE);
+}
+
+/**************************************************************************/
+
+#if (DOSX & PHARLAP)
+ PUBLIC int PktReceive (BYTE *buf, int max)
+ {
+ WORD inOfs = *rxInOfsFp;
+ WORD outOfs = *rxOutOfsFp;
+
+ if (outOfs != inOfs)
+ {
+ RX_ELEMENT _far *head = (RX_ELEMENT _far*)(protBase+outOfs);
+ int size, len = max;
+
+ if (CheckElement(head))
+ {
+ size = min (head->firstCount, sizeof(RX_ELEMENT));
+ len = min (size, max);
+ _fmemcpy (buf, &head->destin, len);
+ }
+ else
+ size = -1;
+
+ outOfs += sizeof (RX_ELEMENT);
+ if (outOfs > LAST_RX_BUF)
+ outOfs = FIRST_RX_BUF;
+ *rxOutOfsFp = outOfs;
+ return (size);
+ }
+ return (0);
+ }
+
+ PUBLIC void PktQueueBusy (BOOL busy)
+ {
+ *rxOutOfsFp = busy ? (*rxInOfsFp + sizeof(RX_ELEMENT)) : *rxInOfsFp;
+ if (*rxOutOfsFp > LAST_RX_BUF)
+ *rxOutOfsFp = FIRST_RX_BUF;
+ *(DWORD _far*)(protBase + (WORD)&pktDrop) = 0;
+ }
+
+ PUBLIC WORD PktBuffersUsed (void)
+ {
+ WORD inOfs = *rxInOfsFp;
+ WORD outOfs = *rxOutOfsFp;
+
+ if (inOfs >= outOfs)
+ return (inOfs - outOfs) / sizeof(RX_ELEMENT);
+ return (NUM_RX_BUF - (outOfs - inOfs) / sizeof(RX_ELEMENT));
+ }
+
+ PUBLIC DWORD PktRxDropped (void)
+ {
+ return (*(DWORD _far*)(protBase + (WORD)&pktDrop));
+ }
+
+#elif (DOSX & DJGPP)
+ PUBLIC int PktReceive (BYTE *buf, int max)
+ {
+ WORD ofs = _farpeekw (_dos_ds, realBase+rxOutOfs);
+
+ if (ofs != _farpeekw (_dos_ds, realBase+rxInOfs))
+ {
+ RX_ELEMENT head;
+ int size, len = max;
+
+ head.firstCount = _farpeekw (_dos_ds, realBase+ofs);
+ head.secondCount = _farpeekw (_dos_ds, realBase+ofs+2);
+ head.handle = _farpeekw (_dos_ds, realBase+ofs+4);
+
+ if (CheckElement(&head))
+ {
+ size = min (head.firstCount, sizeof(RX_ELEMENT));
+ len = min (size, max);
+ dosmemget (realBase+ofs+6, len, buf);
+ }
+ else
+ size = -1;
+
+ ofs += sizeof (RX_ELEMENT);
+ if (ofs > LAST_RX_BUF)
+ _farpokew (_dos_ds, realBase+rxOutOfs, FIRST_RX_BUF);
+ else _farpokew (_dos_ds, realBase+rxOutOfs, ofs);
+ return (size);
+ }
+ return (0);
+ }
+
+ PUBLIC void PktQueueBusy (BOOL busy)
+ {
+ WORD ofs;
+
+ disable();
+ ofs = _farpeekw (_dos_ds, realBase+rxInOfs);
+ if (busy)
+ ofs += sizeof (RX_ELEMENT);
+
+ if (ofs > LAST_RX_BUF)
+ _farpokew (_dos_ds, realBase+rxOutOfs, FIRST_RX_BUF);
+ else _farpokew (_dos_ds, realBase+rxOutOfs, ofs);
+ _farpokel (_dos_ds, realBase+pktDrop, 0UL);
+ enable();
+ }
+
+ PUBLIC WORD PktBuffersUsed (void)
+ {
+ WORD inOfs, outOfs;
+
+ disable();
+ inOfs = _farpeekw (_dos_ds, realBase+rxInOfs);
+ outOfs = _farpeekw (_dos_ds, realBase+rxOutOfs);
+ enable();
+ if (inOfs >= outOfs)
+ return (inOfs - outOfs) / sizeof(RX_ELEMENT);
+ return (NUM_RX_BUF - (outOfs - inOfs) / sizeof(RX_ELEMENT));
+ }
+
+ PUBLIC DWORD PktRxDropped (void)
+ {
+ return _farpeekl (_dos_ds, realBase+pktDrop);
+ }
+
+#elif (DOSX & DOS4GW)
+ PUBLIC int PktReceive (BYTE *buf, int max)
+ {
+ WORD ofs = *(WORD*) (realBase+rxOutOfs);
+
+ if (ofs != *(WORD*) (realBase+rxInOfs))
+ {
+ RX_ELEMENT head;
+ int size, len = max;
+
+ head.firstCount = *(WORD*) (realBase+ofs);
+ head.secondCount = *(WORD*) (realBase+ofs+2);
+ head.handle = *(WORD*) (realBase+ofs+4);
+
+ if (CheckElement(&head))
+ {
+ size = min (head.firstCount, sizeof(RX_ELEMENT));
+ len = min (size, max);
+ memcpy (buf, (const void*)(realBase+ofs+6), len);
+ }
+ else
+ size = -1;
+
+ ofs += sizeof (RX_ELEMENT);
+ if (ofs > LAST_RX_BUF)
+ *(WORD*) (realBase+rxOutOfs) = FIRST_RX_BUF;
+ else *(WORD*) (realBase+rxOutOfs) = ofs;
+ return (size);
+ }
+ return (0);
+ }
+
+ PUBLIC void PktQueueBusy (BOOL busy)
+ {
+ WORD ofs;
+
+ _disable();
+ ofs = *(WORD*) (realBase+rxInOfs);
+ if (busy)
+ ofs += sizeof (RX_ELEMENT);
+
+ if (ofs > LAST_RX_BUF)
+ *(WORD*) (realBase+rxOutOfs) = FIRST_RX_BUF;
+ else *(WORD*) (realBase+rxOutOfs) = ofs;
+ *(DWORD*) (realBase+pktDrop) = 0UL;
+ _enable();
+ }
+
+ PUBLIC WORD PktBuffersUsed (void)
+ {
+ WORD inOfs, outOfs;
+
+ _disable();
+ inOfs = *(WORD*) (realBase+rxInOfs);
+ outOfs = *(WORD*) (realBase+rxOutOfs);
+ _enable();
+ if (inOfs >= outOfs)
+ return (inOfs - outOfs) / sizeof(RX_ELEMENT);
+ return (NUM_RX_BUF - (outOfs - inOfs) / sizeof(RX_ELEMENT));
+ }
+
+ PUBLIC DWORD PktRxDropped (void)
+ {
+ return *(DWORD*) (realBase+pktDrop);
+ }
+
+#else /* real-mode small/large model */
+
+ PUBLIC int PktReceive (BYTE *buf, int max)
+ {
+ if (rxOutOfs != rxInOfs)
+ {
+ RX_ELEMENT far *head = (RX_ELEMENT far*) MK_FP (_DS,rxOutOfs);
+ int size, len = max;
+
+ if (CheckElement(head))
+ {
+ size = min (head->firstCount, sizeof(RX_ELEMENT));
+ len = min (size, max);
+ _fmemcpy (buf, &head->destin, len);
+ }
+ else
+ size = -1;
+
+ rxOutOfs += sizeof (RX_ELEMENT);
+ if (rxOutOfs > LAST_RX_BUF)
+ rxOutOfs = FIRST_RX_BUF;
+ return (size);
+ }
+ return (0);
+ }
+
+ PUBLIC void PktQueueBusy (BOOL busy)
+ {
+ rxOutOfs = busy ? (rxInOfs + sizeof(RX_ELEMENT)) : rxInOfs;
+ if (rxOutOfs > LAST_RX_BUF)
+ rxOutOfs = FIRST_RX_BUF;
+ pktDrop = 0L;
+ }
+
+ PUBLIC WORD PktBuffersUsed (void)
+ {
+ WORD inOfs = rxInOfs;
+ WORD outOfs = rxOutOfs;
+
+ if (inOfs >= outOfs)
+ return ((inOfs - outOfs) / sizeof(RX_ELEMENT));
+ return (NUM_RX_BUF - (outOfs - inOfs) / sizeof(RX_ELEMENT));
+ }
+
+ PUBLIC DWORD PktRxDropped (void)
+ {
+ return (pktDrop);
+ }
+#endif
+
+/**************************************************************************/
+
+LOCAL __inline void PktFreeMem (void)
+{
+#if (DOSX & PHARLAP)
+ if (realSeg)
+ {
+ _dx_real_free (realSeg);
+ realSeg = 0;
+ }
+#elif (DOSX & DJGPP)
+ if (rm_mem.rm_segment)
+ {
+ unsigned ofs; /* clear the DOS-mem to prevent further upcalls */
+
+ for (ofs = 0; ofs < 16 * rm_mem.size / 4; ofs += 4)
+ _farpokel (_dos_ds, realBase + ofs, 0);
+ _go32_dpmi_free_dos_memory (&rm_mem);
+ rm_mem.rm_segment = 0;
+ }
+#elif (DOSX & DOS4GW)
+ if (rm_base_sel)
+ {
+ dpmi_real_free (rm_base_sel);
+ rm_base_sel = 0;
+ }
+#endif
+}
+
+/**************************************************************************/
+
+PUBLIC BOOL PktExitDriver (void)
+{
+ if (pktInfo.handle)
+ {
+ if (!PktSetReceiverMode(PDRX_BROADCAST))
+ PUTS ("Error restoring receiver mode.");
+
+ if (!PktReleaseHandle(pktInfo.handle))
+ PUTS ("Error releasing PKT-DRVR handle.");
+
+ PktFreeMem();
+ pktInfo.handle = 0;
+ }
+
+ if (pcap_pkt_debug >= 1)
+ printf ("Internal stats: too-small %lu, too-large %lu, bad-sync %lu, "
+ "wrong-handle %lu\n",
+ intStat.tooSmall, intStat.tooLarge,
+ intStat.badSync, intStat.wrongHandle);
+ return (TRUE);
+}
+
+#if (DOSX & (DJGPP|DOS4GW))
+static void dump_pkt_stub (void)
+{
+ int i;
+
+ fprintf (stderr, "PktReceiver %lu, pkt_stub[PktReceiver] =\n",
+ PktReceiver);
+ for (i = 0; i < 15; i++)
+ fprintf (stderr, "%02X, ", real_stub_array[i+PktReceiver]);
+ fputs ("\n", stderr);
+}
+#endif
+
+/*
+ * Front end initialization routine
+ */
+PUBLIC BOOL PktInitDriver (PKT_RX_MODE mode)
+{
+ PKT_RX_MODE rxMode;
+ BOOL writeInfo = (pcap_pkt_debug >= 3);
+
+ pktInfo.quiet = (pcap_pkt_debug < 3);
+
+#if (DOSX & PHARLAP) && defined(__HIGHC__)
+ if (_mwenv != 2)
+ {
+ fprintf (stderr, "Only Pharlap DOS extender supported.\n");
+ return (FALSE);
+ }
+#endif
+
+#if (DOSX & PHARLAP) && defined(__WATCOMC__)
+ if (_Extender != 1)
+ {
+ fprintf (stderr, "Only DOS4GW style extenders supported.\n");
+ return (FALSE);
+ }
+#endif
+
+ if (!PktSearchDriver())
+ {
+ PUTS ("Packet driver not found.");
+ PktFreeMem();
+ return (FALSE);
+ }
+
+ if (!PktGetDriverInfo())
+ {
+ PUTS ("Error getting pkt-drvr information.");
+ PktFreeMem();
+ return (FALSE);
+ }
+
+#if (DOSX & PHARLAP)
+ if (RealCopy((ULONG)&rxOutOfs, (ULONG)&pktRxEnd,
+ &realBase, &protBase, (USHORT*)&realSeg))
+ {
+ rxOutOfsFp = (WORD _far *) (protBase + (WORD) &rxOutOfs);
+ rxInOfsFp = (WORD _far *) (protBase + (WORD) &rxInOfs);
+ *rxOutOfsFp = FIRST_RX_BUF;
+ *rxInOfsFp = FIRST_RX_BUF;
+ }
+ else
+ {
+ PUTS ("Cannot allocate real-mode stub.");
+ return (FALSE);
+ }
+
+#elif (DOSX & (DJGPP|DOS4GW))
+ if (sizeof(real_stub_array) > 0xFFFF)
+ {
+ fprintf (stderr, "`real_stub_array[]' too big.\n");
+ return (FALSE);
+ }
+#if (DOSX & DJGPP)
+ rm_mem.size = (sizeof(real_stub_array) + 15) / 16;
+
+ if (_go32_dpmi_allocate_dos_memory(&rm_mem) || rm_mem.rm_offset != 0)
+ {
+ PUTS ("real-mode init failed.");
+ return (FALSE);
+ }
+ realBase = (rm_mem.rm_segment << 4);
+ dosmemput (&real_stub_array, sizeof(real_stub_array), realBase);
+ _farpokel (_dos_ds, realBase+rxOutOfs, FIRST_RX_BUF);
+ _farpokel (_dos_ds, realBase+rxInOfs, FIRST_RX_BUF);
+
+#elif (DOSX & DOS4GW)
+ rm_base_seg = dpmi_real_malloc (sizeof(real_stub_array), &rm_base_sel);
+ if (!rm_base_seg)
+ {
+ PUTS ("real-mode init failed.");
+ return (FALSE);
+ }
+ realBase = (rm_base_seg << 4);
+ memcpy ((void*)realBase, &real_stub_array, sizeof(real_stub_array));
+ *(WORD*) (realBase+rxOutOfs) = FIRST_RX_BUF;
+ *(WORD*) (realBase+rxInOfs) = FIRST_RX_BUF;
+
+#endif
+ {
+ int pushf = PktReceiver;
+
+ while (real_stub_array[pushf++] != 0x9C && /* pushf */
+ real_stub_array[pushf] != 0xFA) /* cli */
+ {
+ if (++para_skip > 16)
+ {
+ fprintf (stderr, "Something wrong with `pkt_stub.inc'.\n");
+ para_skip = 0;
+ dump_pkt_stub();
+ return (FALSE);
+ }
+ }
+ if (*(WORD*)(real_stub_array + offsetof(PktRealStub,_dummy)) != 0xB800)
+ {
+ fprintf (stderr, "`real_stub_array[]' is misaligned.\n");
+ return (FALSE);
+ }
+ }
+
+ if (pcap_pkt_debug > 2)
+ dump_pkt_stub();
+
+#else
+ rxOutOfs = FIRST_RX_BUF;
+ rxInOfs = FIRST_RX_BUF;
+#endif
+
+ if (!PktSetAccess())
+ {
+ PUTS ("Error setting pkt-drvr access.");
+ PktFreeMem();
+ return (FALSE);
+ }
+
+ if (!PktGetAddress(&myAddress))
+ {
+ PUTS ("Error fetching adapter address.");
+ PktFreeMem();
+ return (FALSE);
+ }
+
+ if (!PktSetReceiverMode(mode))
+ {
+ PUTS ("Error setting receiver mode.");
+ PktFreeMem();
+ return (FALSE);
+ }
+
+ if (!PktGetReceiverMode(&rxMode))
+ {
+ PUTS ("Error getting receiver mode.");
+ PktFreeMem();
+ return (FALSE);
+ }
+
+ if (writeInfo)
+ printf ("Pkt-driver information:\n"
+ " Version : %d.%d\n"
+ " Name : %.15s\n"
+ " Class : %u (%s)\n"
+ " Type : %u\n"
+ " Number : %u\n"
+ " Funcs : %u\n"
+ " Intr : %Xh\n"
+ " Handle : %u\n"
+ " Extended : %s\n"
+ " Hi-perf : %s\n"
+ " RX mode : %s\n"
+ " Eth-addr : %02X:%02X:%02X:%02X:%02X:%02X\n",
+
+ pktInfo.majVer, pktInfo.minVer, pktInfo.name,
+ pktInfo.class, PktGetClassName(pktInfo.class),
+ pktInfo.type, pktInfo.number,
+ pktInfo.funcs, pktInfo.intr, pktInfo.handle,
+ pktInfo.funcs == 2 || pktInfo.funcs == 6 ? "Yes" : "No",
+ pktInfo.funcs == 5 || pktInfo.funcs == 6 ? "Yes" : "No",
+ PktRXmodeStr(rxMode),
+ myAddress[0], myAddress[1], myAddress[2],
+ myAddress[3], myAddress[4], myAddress[5]);
+
+#if defined(DEBUG) && (DOSX & PHARLAP)
+ if (writeInfo)
+ {
+ DWORD rAdr = realBase + (WORD)&PktReceiver;
+ unsigned sel, ofs;
+
+ printf ("\nReceiver at %04X:%04X\n", RP_SEG(rAdr), RP_OFF(rAdr));
+ printf ("Realbase = %04X:%04X\n", RP_SEG(realBase),RP_OFF(realBase));
+
+ sel = _FP_SEG (protBase);
+ ofs = _FP_OFF (protBase);
+ printf ("Protbase = %04X:%08X\n", sel,ofs);
+ printf ("RealSeg = %04X\n", realSeg);
+
+ sel = _FP_SEG (rxOutOfsFp);
+ ofs = _FP_OFF (rxOutOfsFp);
+ printf ("rxOutOfsFp = %04X:%08X\n", sel,ofs);
+
+ sel = _FP_SEG (rxInOfsFp);
+ ofs = _FP_OFF (rxInOfsFp);
+ printf ("rxInOfsFp = %04X:%08X\n", sel,ofs);
+
+ printf ("Ready: *rxOutOfsFp = %04X *rxInOfsFp = %04X\n",
+ *rxOutOfsFp, *rxInOfsFp);
+
+ PktQueueBusy (TRUE);
+ printf ("Busy: *rxOutOfsFp = %04X *rxInOfsFp = %04X\n",
+ *rxOutOfsFp, *rxInOfsFp);
+ }
+#endif
+
+ memset (&pktStat, 0, sizeof(pktStat)); /* clear statistics */
+ PktQueueBusy (TRUE);
+ return (TRUE);
+}
+
+
+/*
+ * DPMI functions only for Watcom + DOS4GW extenders
+ */
+#if (DOSX & DOS4GW)
+LOCAL DWORD dpmi_get_real_vector (int intr)
+{
+ union REGS r;
+
+ r.x.eax = 0x200;
+ r.x.ebx = (DWORD) intr;
+ int386 (0x31, &r, &r);
+ return ((r.w.cx << 4) + r.w.dx);
+}
+
+LOCAL WORD dpmi_real_malloc (int size, WORD *selector)
+{
+ union REGS r;
+
+ r.x.eax = 0x0100; /* DPMI allocate DOS memory */
+ r.x.ebx = (size + 15) / 16; /* Number of paragraphs requested */
+ int386 (0x31, &r, &r);
+ if (r.w.cflag & 1)
+ return (0);
+
+ *selector = r.w.dx;
+ return (r.w.ax); /* Return segment address */
+}
+
+LOCAL void dpmi_real_free (WORD selector)
+{
+ union REGS r;
+
+ r.x.eax = 0x101; /* DPMI free DOS memory */
+ r.x.ebx = selector; /* Selector to free */
+ int386 (0x31, &r, &r);
+}
+#endif
+
+
+#if defined(DOSX) && (DOSX & PHARLAP)
+/*
+ * Description:
+ * This routine allocates conventional memory for the specified block
+ * of code (which must be within the first 64K of the protected mode
+ * program segment) and copies the code to it.
+ *
+ * The caller should free up the conventional memory block when it
+ * is done with the conventional memory.
+ *
+ * NOTE THIS ROUTINE REQUIRES 386|DOS-EXTENDER 3.0 OR LATER.
+ *
+ * Calling arguments:
+ * start_offs start of real mode code in program segment
+ * end_offs 1 byte past end of real mode code in program segment
+ * real_basep returned; real mode ptr to use as a base for the
+ * real mode code (eg, to get the real mode FAR
+ * addr of a function foo(), take
+ * real_basep + (ULONG) foo).
+ * This pointer is constructed such that
+ * offsets within the real mode segment are
+ * the same as the link-time offsets in the
+ * protected mode program segment
+ * prot_basep returned; prot mode ptr to use as a base for getting
+ * to the conventional memory, also constructed
+ * so that adding the prot mode offset of a
+ * function or variable to the base gets you a
+ * ptr to the function or variable in the
+ * conventional memory block.
+ * rmem_adrp returned; real mode para addr of allocated
+ * conventional memory block, to be used to free
+ * up the conventional memory when done. DO NOT
+ * USE THIS TO CONSTRUCT A REAL MODE PTR, USE
+ * REAL_BASEP INSTEAD SO THAT OFFSETS WORK OUT
+ * CORRECTLY.
+ *
+ * Returned values:
+ * 0 if error
+ * 1 if success
+ */
+int RealCopy (ULONG start_offs,
+ ULONG end_offs,
+ REALPTR *real_basep,
+ FARPTR *prot_basep,
+ USHORT *rmem_adrp)
+{
+ ULONG rm_base; /* base real mode para addr for accessing */
+ /* allocated conventional memory */
+ UCHAR *source; /* source pointer for copy */
+ FARPTR destin; /* destination pointer for copy */
+ ULONG len; /* number of bytes to copy */
+ ULONG temp;
+ USHORT stemp;
+
+ /* First check for valid inputs
+ */
+ if (start_offs >= end_offs || end_offs > 0x10000)
+ return (FALSE);
+
+ /* Round start_offs down to a paragraph (16-byte) boundary so we can set up
+ * the real mode pointer easily. Round up end_offs to make sure we allocate
+ * enough paragraphs
+ */
+ start_offs &= ~15;
+ end_offs = (15 + (end_offs << 4)) >> 4;
+
+ /* Allocate the conventional memory for our real mode code. Remember to
+ * round byte count UP to 16-byte paragraph size. We alloc it
+ * above the DOS data buffer so both the DOS data buffer and the appl
+ * conventional mem block can still be resized.
+ *
+ * First just try to alloc it; if we can't get it, shrink the appl mem
+ * block down to the minimum, try to alloc the memory again, then grow the
+ * appl mem block back to the maximum. (Don't try to shrink the DOS data
+ * buffer to free conventional memory; it wouldn't be good for this routine
+ * to have the possible side effect of making file I/O run slower.)
+ */
+ len = ((end_offs - start_offs) + 15) >> 4;
+ if (_dx_real_above(len, rmem_adrp, &stemp) != _DOSE_NONE)
+ {
+ if (_dx_cmem_usage(0, 0, &temp, &temp) != _DOSE_NONE)
+ return (FALSE);
+
+ if (_dx_real_above(len, rmem_adrp, &stemp) != _DOSE_NONE)
+ *rmem_adrp = 0;
+
+ if (_dx_cmem_usage(0, 1, &temp, &temp) != _DOSE_NONE)
+ {
+ if (*rmem_adrp != 0)
+ _dx_real_free (*rmem_adrp);
+ return (FALSE);
+ }
+
+ if (*rmem_adrp == 0)
+ return (FALSE);
+ }
+
+ /* Construct real mode & protected mode pointers to access the allocated
+ * memory. Note we know start_offs is aligned on a paragraph (16-byte)
+ * boundary, because we rounded it down.
+ *
+ * We make the offsets come out rights by backing off the real mode selector
+ * by start_offs.
+ */
+ rm_base = ((ULONG) *rmem_adrp) - (start_offs >> 4);
+ RP_SET (*real_basep, 0, rm_base);
+ FP_SET (*prot_basep, rm_base << 4, SS_DOSMEM);
+
+ /* Copy the real mode code/data to the allocated memory
+ */
+ source = (UCHAR *) start_offs;
+ destin = *prot_basep;
+ FP_SET (destin, FP_OFF(*prot_basep) + start_offs, FP_SEL(*prot_basep));
+ len = end_offs - start_offs;
+ WriteFarMem (destin, source, len);
+
+ return (TRUE);
+}
+#endif /* DOSX && (DOSX & PHARLAP) */
diff --git a/contrib/libpcap/msdos/pktdrvr.h b/contrib/libpcap/msdos/pktdrvr.h
new file mode 100644
index 0000000000000..3e0cfe017b4f6
--- /dev/null
+++ b/contrib/libpcap/msdos/pktdrvr.h
@@ -0,0 +1,153 @@
+#ifndef __PKTDRVR_H
+#define __PKTDRVR_H
+
+#define PUBLIC
+#define LOCAL static
+
+#define RX_BUF_SIZE ETH_MTU /* buffer size variables. NB !! */
+#define TX_BUF_SIZE ETH_MTU /* must be same as in pkt_rx*.* */
+
+#ifdef __HIGHC__
+#pragma Off(Align_members)
+#else
+#pragma pack(1)
+#endif
+
+typedef enum { /* Packet-driver classes */
+ PD_ETHER = 1,
+ PD_PRONET10 = 2,
+ PD_IEEE8025 = 3,
+ PD_OMNINET = 4,
+ PD_APPLETALK = 5,
+ PD_SLIP = 6,
+ PD_STARTLAN = 7,
+ PD_ARCNET = 8,
+ PD_AX25 = 9,
+ PD_KISS = 10,
+ PD_IEEE8023_2 = 11,
+ PD_FDDI8022 = 12,
+ PD_X25 = 13,
+ PD_LANstar = 14,
+ PD_PPP = 18
+ } PKT_CLASS;
+
+typedef enum { /* Packet-driver receive modes */
+ PDRX_OFF = 1, /* turn off receiver */
+ PDRX_DIRECT, /* receive only to this interface */
+ PDRX_BROADCAST, /* DIRECT + broadcast packets */
+ PDRX_MULTICAST1, /* BROADCAST + limited multicast */
+ PDRX_MULTICAST2, /* BROADCAST + all multicast */
+ PDRX_ALL_PACKETS, /* receive all packets on network */
+ } PKT_RX_MODE;
+
+typedef struct {
+ char type[8];
+ char len;
+ } PKT_FRAME;
+
+
+typedef struct {
+ BYTE class; /* = 1 for DEC/Interl/Xerox Ethernet */
+ BYTE number; /* = 0 for single LAN adapter */
+ WORD type; /* = 13 for 3C523 */
+ BYTE funcs; /* Basic/Extended/HiPerf functions */
+ WORD intr; /* user interrupt vector number */
+ WORD handle; /* Handle associated with session */
+ BYTE name [15]; /* Name of adapter interface,ie.3C523*/
+ BOOL quiet; /* (don't) print errors to stdout */
+ const char *error; /* address of error string */
+ BYTE majVer; /* Major driver implementation ver. */
+ BYTE minVer; /* Minor driver implementation ver. */
+ BYTE dummyLen; /* length of following data */
+ WORD MAClength; /* HiPerformance data, N/A */
+ WORD MTU; /* HiPerformance data, N/A */
+ WORD multicast; /* HiPerformance data, N/A */
+ WORD rcvrBuffers; /* valid for */
+ WORD UMTbufs; /* High Performance drivers only */
+ WORD postEOIintr; /* Usage ?? */
+ } PKT_INFO;
+
+#define PKT_PARAM_SIZE 14 /* members majVer - postEOIintr */
+
+
+typedef struct {
+ DWORD inPackets; /* # of packets received */
+ DWORD outPackets; /* # of packets transmitted */
+ DWORD inBytes; /* # of bytes received */
+ DWORD outBytes; /* # of bytes transmitted */
+ DWORD inErrors; /* # of reception errors */
+ DWORD outErrors; /* # of transmission errors */
+ DWORD lost; /* # of packets lost (RX) */
+ } PKT_STAT;
+
+
+typedef struct {
+ ETHER destin;
+ ETHER source;
+ WORD proto;
+ BYTE data [TX_BUF_SIZE];
+ } TX_ELEMENT;
+
+typedef struct {
+ WORD firstCount; /* # of bytes on 1st */
+ WORD secondCount; /* and 2nd upcall */
+ WORD handle; /* instance that upcalled */
+ ETHER destin; /* E-net destination address */
+ ETHER source; /* E-net source address */
+ WORD proto; /* protocol number */
+ BYTE data [RX_BUF_SIZE];
+ } RX_ELEMENT;
+
+
+#ifdef __HIGHC__
+#pragma pop(Align_members)
+#else
+#pragma pack()
+#endif
+
+
+/*
+ * Prototypes for publics
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern PKT_STAT pktStat; /* statistics for packets */
+extern PKT_INFO pktInfo; /* packet-driver information */
+
+extern PKT_RX_MODE receiveMode;
+extern ETHER myAddress, ethBroadcast;
+
+extern BOOL PktInitDriver (PKT_RX_MODE mode);
+extern BOOL PktExitDriver (void);
+
+extern const char *PktGetErrorStr (int errNum);
+extern const char *PktGetClassName (WORD class);
+extern const char *PktRXmodeStr (PKT_RX_MODE mode);
+extern BOOL PktSearchDriver (void);
+extern int PktReceive (BYTE *buf, int max);
+extern BOOL PktTransmit (const void *eth, int len);
+extern DWORD PktRxDropped (void);
+extern BOOL PktReleaseHandle (WORD handle);
+extern BOOL PktTerminHandle (WORD handle);
+extern BOOL PktResetInterface (WORD handle);
+extern BOOL PktSetReceiverMode(PKT_RX_MODE mode);
+extern BOOL PktGetReceiverMode(PKT_RX_MODE *mode);
+extern BOOL PktGetStatistics (WORD handle);
+extern BOOL PktSessStatistics (WORD handle);
+extern BOOL PktResetStatistics(WORD handle);
+extern BOOL PktGetAddress (ETHER *addr);
+extern BOOL PktSetAddress (const ETHER *addr);
+extern BOOL PktGetDriverInfo (void);
+extern BOOL PktGetDriverParam (void);
+extern void PktQueueBusy (BOOL busy);
+extern WORD PktBuffersUsed (void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __PKTDRVR_H */
+
diff --git a/contrib/libpcap/msdos/readme.dos b/contrib/libpcap/msdos/readme.dos
new file mode 100644
index 0000000000000..990a2e8a63d10
--- /dev/null
+++ b/contrib/libpcap/msdos/readme.dos
@@ -0,0 +1,166 @@
+libpcap for DOS
+---------------
+
+This file contains some notes on building and using libpcap for MS-DOS.
+Look in `README' and `pcap.man' for usage and details. These targets are
+supported:
+
+ - Borland C 4.0+ small or large model.
+ - Metaware HighC 3.1+ with PharLap DOS-extender
+ - GNU C 2.7+ with djgpp 2.01+ DOS extender
+ - Watcom C 11.x with DOS4GW extender
+
+Note: the files in the libpcap.zip contains short truncated filenames.
+ So for djgpp to work with these, disable the use of long file names by
+ setting "LFN=n" in the environment. On the other hand, if you get libpcap
+ from Github or the official libpcap.tar.gz, some filenames are beyond 8+3.
+ In this case set "LFN=y".
+
+Files specific to DOS are pcap-dos.[ch] and the assembly and C files in
+the MSDOS sub-directory. Remember to built the libpcap library from the top
+install directory. And not from the MSDOS sub-directory.
+
+Note for djgpp users:
+ If you got the libpcap from the official site www.tcpdump, then that
+ distribution does NOT contain any sources for building 32-bit drivers.
+ Instead get the full version at
+ http://www.watt-32.net/pcap/libpcap.zip
+
+ and set "USE_32BIT_DRIVERS = 1" in msdos\common.dj.
+
+
+
+Requirements
+------------
+
+DOS-libpcap currently only works reliably with a real-mode Ethernet packet-
+driver. This driver must be installed prior to using any program (e.g.
+tcpdump) compiled with libpcap. Work is underway to implement protected-
+mode drivers for 32-bit targets (djgpp only). The 3Com 3c509 driver is
+working almost perfectly. Due to lack of LAN-cards, I've not had the
+opportunity to test other drivers. These 32-bit drivers are modified
+Linux drivers.
+
+
+Required packages
+-----------------
+
+The following packages and tools must be present for all targets.
+
+1. Watt-32 tcp/ip library. This library is *not* used to send or
+ receive network data. It's mostly used to access the 'hosts'
+ file and other <netdb.h> features. Get 'watt32s*.zip' at:
+
+ http://www.watt-32.net
+
+2. Exception handler and disassember library (libexc.a) is needed if
+ "USE_EXCEPT = 1" in common.dj. Available at:
+
+ http://www.watt-32.net/misc/exc_dx07.zip
+
+3. Flex & Bison is used to generate parser for the filter handler
+ pcap_compile:
+ ftp://ftp.delorie.com/pub/djgpp/current/v2gnu/flx254b.zip
+ ftp://ftp.delorie.com/pub/djgpp/current/v2gnu/bsn241b.zip
+
+4. NASM assembler v 0.98 or later is required when building djgpp and
+ Watcom targets:
+ http://www.nasm.us/
+
+5. sed (Stream Editor) is required for doing `make depend'.
+ It's available at:
+ ftp://ftp.delorie.com/pub/djgpp/current/v2gnu/sed422b.zip
+
+ A touch tool to update the time-stamp of a file. E.g.:
+ ftp://ftp.delorie.com/pub/djgpp/current/v2gnu/grep29b.zip
+
+6. For djgpp rm.exe and cp.exe are required. These should already be
+ part of your djgpp installation. Also required (experimental at the
+ time) for djgpp is DLX 2.91 or later. This tool is for the generation
+ of dynamically loadable modules.
+
+
+Compiling libpcap
+-----------------
+
+Follow these steps in building libpcap:
+
+1. Make sure you've installed Watt-32 properly (see it's `INSTALL' file).
+ During that installation a environment variable `WATT_ROOT' is set.
+ This variable is used for building libpcap also (`WATT_INC' is
+ deducted from `WATT_ROOT'). djgpp users should also define environment
+ variables `C_INCLUDE_PATH' and `LIBRARY_PATH' to point to the include
+ directory and library directory respectively. E.g. put this in your
+ AUTOEXEC.BAT:
+ set C_INCLUDE_PATH=c:/net/watt/inc
+ set LIBRARY_PATH=c:/net/watt/lib
+
+2. Revise the msdos/common.dj file for your djgpp/gcc installation;
+ - change the value of `GCCLIB' to match location of libgcc.a.
+ - set `USE_32BIT_DRIVERS = 1' to build 32-bit driver objects.
+
+
+3. Build pcap by using appropriate makefile. For djgpp, use:
+ `make -f msdos/makefile.dj' (i.e. GNU `make')
+
+ For a Watcom target say:
+ `wmake -f msdos\makefile.wc'
+
+ For a Borland target say:
+ `maker -f msdos\Makefile pcap_bc.lib' (Borland's `maker.exe')
+
+ And for a HighC/Pharlap target say:
+ `maker -f msdos\Makefile pcap_hc.lib' (Borland's `maker.exe')
+
+ You might like to change some `CFLAGS' -- only `DEBUG' define currently
+ have any effect. It shows a rotating "fan" in upper right corner of
+ screen. Remove `DEBUG' if you don't like it. You could add
+ `-fomit-frame-pointer' to `CFLAGS' to speed up the generated code.
+ But note, this makes debugging and crash-traceback difficult. Only
+ add it if you're fully confident your application is 100% stable.
+
+ Note: Code in `USE_NDIS2' does not work at the moment.
+
+4. The resulting library is put in current directory. There's some
+ test-program for `libpcap': `filtertest.exe', `findalldevstest.exe',
+ `nonblocktest.exe' and `opentest.exe'.
+
+ But linking the library with `tcpdump' is the ultimate test. DOS/djgpp
+ should now hopefully be a supported target. Get the sources at:
+ http://www.tcpdump.org/
+ or
+ https://github.com/the-tcpdump-group/tcpdump/
+
+ (click on the 'Download ZIP' on the right side of that page.)
+
+
+Extensions to libpcap
+---------------------
+
+I've included some extra functions to DOS-libpcap:
+
+ `pcap_config_hook (const char *keyword, const char *value)' :
+
+ Allows an application to set values of internal libpcap variables.
+ `keyword' and an associated `value' should be present in the `debug_tab[]'
+ array in pcap-dos.c (currently only used to set debug-levels and parameters
+ for the 32-bit network drivers.) Thus an application using DOS-libpcap can
+ override the default value during it's configure process (see tcpdump's
+ msdos/config.c file for an extended example).
+
+ `pcap_set_wait (pcap_t *, void (*)(void), int)' :
+
+ Only effective when reading offline traffic from dump-files.
+ Function `pcap_offline_read()' will wait (and optionally yield)
+ before printing next packet. This will simulate the pace the packets
+ where actually recorded.
+
+
+
+Happy sniffing !
+
+
+Gisle Vanem <gvanem@yahoo.no>
+
+October 1999, 2004, 2006, 2013
+
diff --git a/contrib/libpcap/nametoaddr.c b/contrib/libpcap/nametoaddr.c
index 49d23d85521ee..087d14be750d6 100644
--- a/contrib/libpcap/nametoaddr.c
+++ b/contrib/libpcap/nametoaddr.c
@@ -20,12 +20,10 @@
*
* Name to id translation routines used by the scanner.
* These functions are not time critical.
- *
- * $FreeBSD$
*/
#ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
#endif
#ifdef DECNETLIB
@@ -34,62 +32,99 @@
#endif
#ifdef _WIN32
-#include <pcap-stdinc.h>
-
-#ifdef INET6
-/*
- * To quote the MSDN page for getaddrinfo() at
- *
- * https://msdn.microsoft.com/en-us/library/windows/desktop/ms738520(v=vs.85).aspx
- *
- * "Support for getaddrinfo on Windows 2000 and older versions
- * The getaddrinfo function was added to the Ws2_32.dll on Windows XP and
- * later. To execute an application that uses this function on earlier
- * versions of Windows, then you need to include the Ws2tcpip.h and
- * Wspiapi.h files. When the Wspiapi.h include file is added, the
- * getaddrinfo function is defined to the WspiapiGetAddrInfo inline
- * function in the Wspiapi.h file. At runtime, the WspiapiGetAddrInfo
- * function is implemented in such a way that if the Ws2_32.dll or the
- * Wship6.dll (the file containing getaddrinfo in the IPv6 Technology
- * Preview for Windows 2000) does not include getaddrinfo, then a
- * version of getaddrinfo is implemented inline based on code in the
- * Wspiapi.h header file. This inline code will be used on older Windows
- * platforms that do not natively support the getaddrinfo function."
- *
- * We use getaddrinfo(), so we include Wspiapi.h here. pcap-stdinc.h
- * includes Ws2tcpip.h, so we don't need to include it ourselves.
- */
-#include <Wspiapi.h>
-#endif
-
+ #include <winsock2.h>
+ #include <ws2tcpip.h>
+
+ #ifdef INET6
+ /*
+ * To quote the MSDN page for getaddrinfo() at
+ *
+ * https://msdn.microsoft.com/en-us/library/windows/desktop/ms738520(v=vs.85).aspx
+ *
+ * "Support for getaddrinfo on Windows 2000 and older versions
+ * The getaddrinfo function was added to the Ws2_32.dll on Windows XP and
+ * later. To execute an application that uses this function on earlier
+ * versions of Windows, then you need to include the Ws2tcpip.h and
+ * Wspiapi.h files. When the Wspiapi.h include file is added, the
+ * getaddrinfo function is defined to the WspiapiGetAddrInfo inline
+ * function in the Wspiapi.h file. At runtime, the WspiapiGetAddrInfo
+ * function is implemented in such a way that if the Ws2_32.dll or the
+ * Wship6.dll (the file containing getaddrinfo in the IPv6 Technology
+ * Preview for Windows 2000) does not include getaddrinfo, then a
+ * version of getaddrinfo is implemented inline based on code in the
+ * Wspiapi.h header file. This inline code will be used on older Windows
+ * platforms that do not natively support the getaddrinfo function."
+ *
+ * We use getaddrinfo(), so we include Wspiapi.h here.
+ */
+ #include <wspiapi.h>
+ #endif /* INET6 */
#else /* _WIN32 */
-
-#include <sys/param.h>
-#include <sys/types.h> /* concession to AIX */
-#include <sys/socket.h>
-#include <sys/time.h>
-
-#include <netinet/in.h>
-#endif /* _WIN32 */
-
-#ifndef _WIN32
-#ifdef HAVE_ETHER_HOSTTON
-/*
- * XXX - do we need any of this if <netinet/if_ether.h> doesn't declare
- * ether_hostton()?
- */
-#ifdef HAVE_NETINET_IF_ETHER_H
-struct mbuf; /* Squelch compiler warnings on some platforms for */
-struct rtentry; /* declarations in <net/if.h> */
-#include <net/if.h> /* for "struct ifnet" in "struct arpcom" on Solaris */
-#include <netinet/if_ether.h>
-#endif /* HAVE_NETINET_IF_ETHER_H */
-#ifdef NETINET_ETHER_H_DECLARES_ETHER_HOSTTON
-#include <netinet/ether.h>
-#endif /* NETINET_ETHER_H_DECLARES_ETHER_HOSTTON */
-#endif /* HAVE_ETHER_HOSTTON */
-#include <arpa/inet.h>
-#include <netdb.h>
+ #include <sys/param.h>
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <sys/time.h>
+
+ #include <netinet/in.h>
+
+ #ifdef HAVE_ETHER_HOSTTON
+ #if defined(NET_ETHERNET_H_DECLARES_ETHER_HOSTTON)
+ /*
+ * OK, just include <net/ethernet.h>.
+ */
+ #include <net/ethernet.h>
+ #elif defined(NETINET_ETHER_H_DECLARES_ETHER_HOSTTON)
+ /*
+ * OK, just include <netinet/ether.h>
+ */
+ #include <netinet/ether.h>
+ #elif defined(SYS_ETHERNET_H_DECLARES_ETHER_HOSTTON)
+ /*
+ * OK, just include <sys/ethernet.h>
+ */
+ #include <sys/ethernet.h>
+ #elif defined(ARPA_INET_H_DECLARES_ETHER_HOSTTON)
+ /*
+ * OK, just include <arpa/inet.h>
+ */
+ #include <arpa/inet.h>
+ #elif defined(NETINET_IF_ETHER_H_DECLARES_ETHER_HOSTTON)
+ /*
+ * OK, include <netinet/if_ether.h>, after all the other stuff we
+ * need to include or define for its benefit.
+ */
+ #define NEED_NETINET_IF_ETHER_H
+ #else
+ /*
+ * We'll have to declare it ourselves.
+ * If <netinet/if_ether.h> defines struct ether_addr, include
+ * it. Otherwise, define it ourselves.
+ */
+ #ifdef HAVE_STRUCT_ETHER_ADDR
+ #define NEED_NETINET_IF_ETHER_H
+ #else /* HAVE_STRUCT_ETHER_ADDR */
+ struct ether_addr {
+ unsigned char ether_addr_octet[6];
+ };
+ #endif /* HAVE_STRUCT_ETHER_ADDR */
+ #endif /* what declares ether_hostton() */
+
+ #ifdef NEED_NETINET_IF_ETHER_H
+ #include <net/if.h> /* Needed on some platforms */
+ #include <netinet/in.h> /* Needed on some platforms */
+ #include <netinet/if_ether.h>
+ #endif /* NEED_NETINET_IF_ETHER_H */
+
+ #ifndef HAVE_DECL_ETHER_HOSTTON
+ /*
+ * No header declares it, so declare it ourselves.
+ */
+ extern int ether_hostton(const char *, struct ether_addr *);
+ #endif /* !defined(HAVE_DECL_ETHER_HOSTTON) */
+ #endif /* HAVE_ETHER_HOSTTON */
+
+ #include <arpa/inet.h>
+ #include <netdb.h>
#endif /* _WIN32 */
#include <ctype.h>
@@ -113,11 +148,10 @@ struct rtentry; /* declarations in <net/if.h> */
#define NTOHS(x) (x) = ntohs(x)
#endif
-static inline int xdtoi(int);
-
/*
* Convert host name to internet address.
* Return 0 upon failure.
+ * XXX - not thread-safe; don't use it inside libpcap.
*/
bpf_u_int32 **
pcap_nametoaddr(const char *name)
@@ -143,7 +177,6 @@ pcap_nametoaddr(const char *name)
return 0;
}
-#ifdef INET6
struct addrinfo *
pcap_nametoaddrinfo(const char *name)
{
@@ -160,23 +193,17 @@ pcap_nametoaddrinfo(const char *name)
else
return res;
}
-#endif /*INET6*/
/*
* Convert net name to internet address.
* Return 0 upon failure.
+ * XXX - not guaranteed to be thread-safe! See below for platforms
+ * on which it is thread-safe and on which it isn't.
*/
bpf_u_int32
pcap_nametonetaddr(const char *name)
{
-#ifndef _WIN32
- struct netent *np;
-
- if ((np = getnetbyname(name)) != NULL)
- return np->n_net;
- else
- return 0;
-#else
+#ifdef _WIN32
/*
* There's no "getnetbyname()" on Windows.
*
@@ -190,7 +217,66 @@ pcap_nametonetaddr(const char *name)
* of *UN*X* machines.)
*/
return 0;
-#endif
+#else
+ /*
+ * UN*X.
+ */
+ struct netent *np;
+ #if defined(HAVE_LINUX_GETNETBYNAME_R)
+ /*
+ * We have Linux's reentrant getnetbyname_r().
+ */
+ struct netent result_buf;
+ char buf[1024]; /* arbitrary size */
+ int h_errnoval;
+ int err;
+
+ err = getnetbyname_r(name, &result_buf, buf, sizeof buf, &np,
+ &h_errnoval);
+ if (err != 0) {
+ /*
+ * XXX - dynamically allocate the buffer, and make it
+ * bigger if we get ERANGE back?
+ */
+ return 0;
+ }
+ #elif defined(HAVE_SOLARIS_IRIX_GETNETBYNAME_R)
+ /*
+ * We have Solaris's and IRIX's reentrant getnetbyname_r().
+ */
+ struct netent result_buf;
+ char buf[1024]; /* arbitrary size */
+
+ np = getnetbyname_r(name, &result_buf, buf, (int)sizeof buf);
+ #elif defined(HAVE_AIX_GETNETBYNAME_R)
+ /*
+ * We have AIX's reentrant getnetbyname_r().
+ */
+ struct netent result_buf;
+ struct netent_data net_data;
+
+ if (getnetbyname_r(name, &result_buf, &net_data) == -1)
+ np = NULL;
+ else
+ np = &result_buf;
+ #else
+ /*
+ * We don't have any getnetbyname_r(); either we have a
+ * getnetbyname() that uses thread-specific data, in which
+ * case we're thread-safe (sufficiently recent FreeBSD,
+ * sufficiently recent Darwin-based OS, sufficiently recent
+ * HP-UX, sufficiently recent Tru64 UNIX), or we have the
+ * traditional getnetbyname() (everything else, including
+ * current NetBSD and OpenBSD), in which case we're not
+ * thread-safe.
+ */
+ np = getnetbyname(name);
+ #endif
+ if (np != NULL)
+ return np->n_net;
+ else
+ return 0;
+#endif /* _WIN32 */
}
/*
@@ -201,20 +287,111 @@ pcap_nametonetaddr(const char *name)
int
pcap_nametoport(const char *name, int *port, int *proto)
{
- struct servent *sp;
+ struct addrinfo hints, *res, *ai;
+ int error;
+ struct sockaddr_in *in4;
+#ifdef INET6
+ struct sockaddr_in6 *in6;
+#endif
int tcp_port = -1;
int udp_port = -1;
/*
+ * We check for both TCP and UDP in case there are
+ * ambiguous entries.
+ */
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = PF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_protocol = IPPROTO_TCP;
+ error = getaddrinfo(NULL, name, &hints, &res);
+ if (error != 0) {
+ if (error != EAI_NONAME) {
+ /*
+ * This is a real error, not just "there's
+ * no such service name".
+ * XXX - this doesn't return an error string.
+ */
+ return 0;
+ }
+ } else {
+ /*
+ * OK, we found it. Did it find anything?
+ */
+ for (ai = res; ai != NULL; ai = ai->ai_next) {
+ /*
+ * Does it have an address?
+ */
+ if (ai->ai_addr != NULL) {
+ /*
+ * Yes. Get a port number; we're done.
+ */
+ if (ai->ai_addr->sa_family == AF_INET) {
+ in4 = (struct sockaddr_in *)ai->ai_addr;
+ tcp_port = ntohs(in4->sin_port);
+ break;
+ }
+#ifdef INET6
+ if (ai->ai_addr->sa_family == AF_INET6) {
+ in6 = (struct sockaddr_in6 *)ai->ai_addr;
+ tcp_port = ntohs(in6->sin6_port);
+ break;
+ }
+#endif
+ }
+ }
+ freeaddrinfo(res);
+ }
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = PF_UNSPEC;
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_protocol = IPPROTO_UDP;
+ error = getaddrinfo(NULL, name, &hints, &res);
+ if (error != 0) {
+ if (error != EAI_NONAME) {
+ /*
+ * This is a real error, not just "there's
+ * no such service name".
+ * XXX - this doesn't return an error string.
+ */
+ return 0;
+ }
+ } else {
+ /*
+ * OK, we found it. Did it find anything?
+ */
+ for (ai = res; ai != NULL; ai = ai->ai_next) {
+ /*
+ * Does it have an address?
+ */
+ if (ai->ai_addr != NULL) {
+ /*
+ * Yes. Get a port number; we're done.
+ */
+ if (ai->ai_addr->sa_family == AF_INET) {
+ in4 = (struct sockaddr_in *)ai->ai_addr;
+ udp_port = ntohs(in4->sin_port);
+ break;
+ }
+#ifdef INET6
+ if (ai->ai_addr->sa_family == AF_INET6) {
+ in6 = (struct sockaddr_in6 *)ai->ai_addr;
+ udp_port = ntohs(in6->sin6_port);
+ break;
+ }
+#endif
+ }
+ }
+ freeaddrinfo(res);
+ }
+
+ /*
* We need to check /etc/services for ambiguous entries.
- * If we find the ambiguous entry, and it has the
+ * If we find an ambiguous entry, and it has the
* same port number, change the proto to PROTO_UNDEF
* so both TCP and UDP will be checked.
*/
- sp = getservbyname(name, "tcp");
- if (sp != NULL) tcp_port = ntohs(sp->s_port);
- sp = getservbyname(name, "udp");
- if (sp != NULL) udp_port = ntohs(sp->s_port);
if (tcp_port >= 0) {
*port = tcp_port;
*proto = IPPROTO_TCP;
@@ -293,12 +470,62 @@ pcap_nametoportrange(const char *name, int *port1, int *port2, int *proto)
return 1;
}
+/*
+ * XXX - not guaranteed to be thread-safe! See below for platforms
+ * on which it is thread-safe and on which it isn't.
+ */
int
pcap_nametoproto(const char *str)
{
struct protoent *p;
+ #if defined(HAVE_LINUX_GETNETBYNAME_R)
+ /*
+ * We have Linux's reentrant getprotobyname_r().
+ */
+ struct protoent result_buf;
+ char buf[1024]; /* arbitrary size */
+ int err;
+
+ err = getprotobyname_r(str, &result_buf, buf, sizeof buf, &p);
+ if (err != 0) {
+ /*
+ * XXX - dynamically allocate the buffer, and make it
+ * bigger if we get ERANGE back?
+ */
+ return 0;
+ }
+ #elif defined(HAVE_SOLARIS_IRIX_GETNETBYNAME_R)
+ /*
+ * We have Solaris's and IRIX's reentrant getprotobyname_r().
+ */
+ struct protoent result_buf;
+ char buf[1024]; /* arbitrary size */
+
+ p = getprotobyname_r(str, &result_buf, buf, (int)sizeof buf);
+ #elif defined(HAVE_AIX_GETNETBYNAME_R)
+ /*
+ * We have AIX's reentrant getprotobyname_r().
+ */
+ struct protoent result_buf;
+ struct protoent_data proto_data;
+ if (getprotobyname_r(str, &result_buf, &proto_data) == -1)
+ p = NULL;
+ else
+ p = &result_buf;
+ #else
+ /*
+ * We don't have any getprotobyname_r(); either we have a
+ * getprotobyname() that uses thread-specific data, in which
+ * case we're thread-safe (sufficiently recent FreeBSD,
+ * sufficiently recent Darwin-based OS, sufficiently recent
+ * HP-UX, sufficiently recent Tru64 UNIX, Windows), or we have
+ * the traditional getprotobyname() (everything else, including
+ * current NetBSD and OpenBSD), in which case we're not
+ * thread-safe.
+ */
p = getprotobyname(str);
+ #endif
if (p != 0)
return p->p_proto;
else
@@ -318,18 +545,14 @@ struct eproto {
* Debian, at least, so make it a public symbol, even though we
* don't officially export it by declaring it in a header file.
* (Programs *should* do this themselves, as tcpdump now does.)
+ *
+ * We declare it here, right before defining it, to squelch any
+ * warnings we might get from compilers about the lack of a
+ * declaration.
*/
+PCAP_API struct eproto eproto_db[];
PCAP_API_DEF struct eproto eproto_db[] = {
-#if 0
- /* The FreeBSD elf linker generates a request to copy this array
- * (including its size) when you link with -lpcap. In order to
- * not bump the major version number of this libpcap.so, we need
- * to ensure that the array stays the same size. Since PUP is
- * likely never seen in real life any more, it's the first to
- * be sacrificed (in favor of ip6).
- */
{ "pup", ETHERTYPE_PUP },
-#endif
{ "xns", ETHERTYPE_NS },
{ "ip", ETHERTYPE_IP },
#ifdef INET6
@@ -391,17 +614,16 @@ pcap_nametollc(const char *s)
return PROTO_UNDEF;
}
-/* Hex digit to integer. */
-static inline int
-xdtoi(c)
- register int c;
+/* Hex digit to 8-bit unsigned integer. */
+static inline u_char
+xdtoi(u_char c)
{
if (isdigit(c))
- return c - '0';
+ return (u_char)(c - '0');
else if (islower(c))
- return c - 'a' + 10;
+ return (u_char)(c - 'a' + 10);
else
- return c - 'A' + 10;
+ return (u_char)(c - 'A' + 10);
}
int
@@ -412,7 +634,7 @@ __pcap_atoin(const char *s, bpf_u_int32 *addr)
*addr = 0;
len = 0;
- while (1) {
+ for (;;) {
n = 0;
while (*s && *s != '.')
n = n * 10 + *s++ - '0';
@@ -460,7 +682,7 @@ u_char *
pcap_ether_aton(const char *s)
{
register u_char *ep, *e;
- register u_int d;
+ register u_char d;
e = ep = (u_char *)malloc(6);
if (e == NULL)
@@ -481,7 +703,11 @@ pcap_ether_aton(const char *s)
}
#ifndef HAVE_ETHER_HOSTTON
-/* Roll our own */
+/*
+ * Roll our own.
+ * XXX - not thread-safe, because pcap_next_etherent() isn't thread-
+ * safe! Needs a mutex or a thread-safe pcap_next_etherent().
+ */
u_char *
pcap_ether_hostton(const char *name)
{
@@ -513,17 +739,10 @@ pcap_ether_hostton(const char *name)
return (NULL);
}
#else
-
-#if !defined(HAVE_DECL_ETHER_HOSTTON) || !HAVE_DECL_ETHER_HOSTTON
-#ifndef HAVE_STRUCT_ETHER_ADDR
-struct ether_addr {
- unsigned char ether_addr_octet[6];
-};
-#endif
-extern int ether_hostton(const char *, struct ether_addr *);
-#endif
-
-/* Use the os supplied routines */
+/*
+ * Use the OS-supplied routine.
+ * This *should* be thread-safe; the API doesn't have a static buffer.
+ */
u_char *
pcap_ether_hostton(const char *name)
{
@@ -540,10 +759,13 @@ pcap_ether_hostton(const char *name)
}
#endif
+/*
+ * XXX - not guaranteed to be thread-safe!
+ */
int
+#ifdef DECNETLIB
__pcap_nametodnaddr(const char *name, u_short *res)
{
-#ifdef DECNETLIB
struct nodeent *getnodebyname();
struct nodeent *nep;
@@ -554,6 +776,8 @@ __pcap_nametodnaddr(const char *name, u_short *res)
memcpy((char *)res, (char *)nep->n_addr, sizeof(unsigned short));
return(1);
#else
+__pcap_nametodnaddr(const char *name _U_, u_short *res _U_)
+{
return(0);
#endif
}
diff --git a/contrib/libpcap/nomkdep b/contrib/libpcap/nomkdep
new file mode 100644
index 0000000000000..bed736687e873
--- /dev/null
+++ b/contrib/libpcap/nomkdep
@@ -0,0 +1,6 @@
+#!/bin/sh -
+#
+# Does nothing; used if we don't have a command-line flag to the compiler
+# to get it to generate dependencies.
+#
+exit 0
diff --git a/contrib/libpcap/optimize.c b/contrib/libpcap/optimize.c
index 19980dc81d9f8..86dcbeef5fe83 100644
--- a/contrib/libpcap/optimize.c
+++ b/contrib/libpcap/optimize.c
@@ -18,26 +18,14 @@
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * Optimization module for tcpdump intermediate representation.
+ * Optimization module for BPF code intermediate representation.
*/
#ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
#endif
-#ifdef _WIN32
-#include <pcap-stdinc.h>
-#else /* _WIN32 */
-#if HAVE_INTTYPES_H
-#include <inttypes.h>
-#elif HAVE_STDINT_H
-#include <stdint.h>
-#endif
-#ifdef HAVE_SYS_BITYPES_H
-#include <sys/bitypes.h>
-#endif
-#include <sys/types.h>
-#endif /* _WIN32 */
+#include <pcap-types.h>
#include <stdio.h>
#include <stdlib.h>
@@ -49,39 +37,149 @@
#include "pcap-int.h"
#include "gencode.h"
+#include "optimize.h"
#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
#ifdef BDEBUG
-int pcap_optimizer_debug;
-#endif
+/*
+ * The internal "debug printout" flag for the filter expression optimizer.
+ * The code to print that stuff is present only if BDEBUG is defined, so
+ * the flag, and the routine to set it, are defined only if BDEBUG is
+ * defined.
+ */
+static int pcap_optimizer_debug;
-#if defined(MSDOS) && !defined(__DJGPP__)
-extern int _w32_ffs (int mask);
-#define ffs _w32_ffs
-#endif
+/*
+ * Routine to set that flag.
+ *
+ * This is intended for libpcap developers, not for general use.
+ * If you want to set these in a program, you'll have to declare this
+ * routine yourself, with the appropriate DLL import attribute on Windows;
+ * it's not declared in any header file, and won't be declared in any
+ * header file provided by libpcap.
+ */
+PCAP_API void pcap_set_optimizer_debug(int value);
+
+PCAP_API_DEF void
+pcap_set_optimizer_debug(int value)
+{
+ pcap_optimizer_debug = value;
+}
+
+/*
+ * The internal "print dot graph" flag for the filter expression optimizer.
+ * The code to print that stuff is present only if BDEBUG is defined, so
+ * the flag, and the routine to set it, are defined only if BDEBUG is
+ * defined.
+ */
+static int pcap_print_dot_graph;
/*
- * So is the check for _MSC_VER done because MinGW has this?
+ * Routine to set that flag.
+ *
+ * This is intended for libpcap developers, not for general use.
+ * If you want to set these in a program, you'll have to declare this
+ * routine yourself, with the appropriate DLL import attribute on Windows;
+ * it's not declared in any header file, and won't be declared in any
+ * header file provided by libpcap.
*/
-#if defined(_WIN32) && defined (_MSC_VER)
+PCAP_API void pcap_set_print_dot_graph(int value);
+
+PCAP_API_DEF void
+pcap_set_print_dot_graph(int value)
+{
+ pcap_print_dot_graph = value;
+}
+
+#endif
+
/*
- * ffs -- vax ffs instruction
+ * lowest_set_bit().
+ *
+ * Takes a 32-bit integer as an argument.
*
- * XXX - with versions of VS that have it, use _BitScanForward()?
+ * If handed a non-zero value, returns the index of the lowest set bit,
+ * counting upwards fro zero.
+ *
+ * If handed zero, the results are platform- and compiler-dependent.
+ * Keep it out of the light, don't give it any water, don't feed it
+ * after midnight, and don't pass zero to it.
+ *
+ * This is the same as the count of trailing zeroes in the word.
+ */
+#if PCAP_IS_AT_LEAST_GNUC_VERSION(3,4)
+ /*
+ * GCC 3.4 and later; we have __builtin_ctz().
+ */
+ #define lowest_set_bit(mask) __builtin_ctz(mask)
+#elif defined(_MSC_VER)
+ /*
+ * Visual Studio; we support only 2005 and later, so use
+ * _BitScanForward().
+ */
+#include <intrin.h>
+
+#ifndef __clang__
+#pragma intrinsic(_BitScanForward)
+#endif
+
+static __forceinline int
+lowest_set_bit(int mask)
+{
+ unsigned long bit;
+
+ /*
+ * Don't sign-extend mask if long is longer than int.
+ * (It's currently not, in MSVC, even on 64-bit platforms, but....)
+ */
+ if (_BitScanForward(&bit, (unsigned int)mask) == 0)
+ return -1; /* mask is zero */
+ return (int)bit;
+}
+#elif defined(MSDOS) && defined(__DJGPP__)
+ /*
+ * MS-DOS with DJGPP, which declares ffs() in <string.h>, which
+ * we've already included.
+ */
+ #define lowest_set_bit(mask) (ffs((mask)) - 1)
+#elif (defined(MSDOS) && defined(__WATCOMC__)) || defined(STRINGS_H_DECLARES_FFS)
+ /*
+ * MS-DOS with Watcom C, which has <strings.h> and declares ffs() there,
+ * or some other platform (UN*X conforming to a sufficient recent version
+ * of the Single UNIX Specification).
+ */
+ #include <strings.h>
+ #define lowest_set_bit(mask) (ffs((mask)) - 1)
+#else
+/*
+ * None of the above.
+ * Use a perfect-hash-function-based function.
*/
static int
-ffs(int mask)
+lowest_set_bit(int mask)
{
- int bit;
+ unsigned int v = (unsigned int)mask;
+
+ static const int MultiplyDeBruijnBitPosition[32] = {
+ 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
+ 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
+ };
- if (mask == 0)
- return(0);
- for (bit = 1; !(mask & 1); bit++)
- mask >>= 1;
- return(bit);
+ /*
+ * We strip off all but the lowermost set bit (v & ~v),
+ * and perform a minimal perfect hash on it to look up the
+ * number of low-order zero bits in a table.
+ *
+ * See:
+ *
+ * http://7ooo.mooo.com/text/ComputingTrailingZerosHOWTO.pdf
+ *
+ * http://supertech.csail.mit.edu/papers/debruijn.pdf
+ */
+ return (MultiplyDeBruijnBitPosition[((v & -v) * 0x077CB531U) >> 27]);
}
#endif
@@ -127,7 +225,7 @@ struct vmapinfo {
bpf_int32 const_val;
};
-struct _opt_state {
+typedef struct {
/*
* A flag to indicate that further optimization is needed.
* Iterative passes are continued until a given pass yields no
@@ -210,7 +308,7 @@ struct _opt_state {
struct vmapinfo *vmap;
struct valnode *vnode_base;
struct valnode *next_vnode;
-};
+} opt_state_t;
typedef struct {
/*
@@ -290,7 +388,7 @@ find_dom(opt_state_t *opt_state, struct block *root)
x = opt_state->all_dom_sets;
i = opt_state->n_blocks * opt_state->nodewords;
while (--i >= 0)
- *x++ = ~0;
+ *x++ = 0xFFFFFFFFU;
/* Root starts off empty. */
for (i = opt_state->nodewords; --i >= 0;)
root->dom[i] = 0;
@@ -330,7 +428,7 @@ find_edom(opt_state_t *opt_state, struct block *root)
x = opt_state->all_edge_sets;
for (i = opt_state->n_edges * opt_state->edgewords; --i >= 0; )
- x[i] = ~0;
+ x[i] = 0xFFFFFFFFU;
/* root->level is the highest level no found. */
memset(root->et.edom, 0, opt_state->edgewords * sizeof(*(uset)0));
@@ -590,7 +688,7 @@ F(opt_state_t *opt_state, int code, int v0, int v1)
static inline void
vstore(struct stmt *s, int *valp, int newval, int alter)
{
- if (alter && *valp == newval)
+ if (alter && newval != VAL_UNKNOWN && *valp == newval)
s->code = NOP;
else
*valp = newval;
@@ -601,7 +699,7 @@ vstore(struct stmt *s, int *valp, int newval, int alter)
* (Unary operators are handled elsewhere.)
*/
static void
-fold_op(compiler_state_t *cstate, struct icode *ic, opt_state_t *opt_state,
+fold_op(compiler_state_t *cstate, opt_state_t *opt_state,
struct stmt *s, int v0, int v1)
{
bpf_u_int32 a, b;
@@ -943,7 +1041,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, struct icode *ic, opt_state_t *opt_state,
+opt_stmt(compiler_state_t *cstate, opt_state_t *opt_state,
struct stmt *s, int val[], int alter)
{
int op;
@@ -1032,7 +1130,7 @@ opt_stmt(compiler_state_t *cstate, struct icode *ic, opt_state_t *opt_state,
}
}
if (opt_state->vmap[val[A_ATOM]].is_const) {
- fold_op(cstate, ic, opt_state, s, val[A_ATOM], K(s->k));
+ fold_op(cstate, opt_state, s, val[A_ATOM], K(s->k));
val[A_ATOM] = K(s->k);
break;
}
@@ -1053,7 +1151,7 @@ opt_stmt(compiler_state_t *cstate, struct icode *ic, 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, ic, opt_state, s, val[A_ATOM], val[X_ATOM]);
+ fold_op(cstate, opt_state, s, val[A_ATOM], val[X_ATOM]);
val[A_ATOM] = K(s->k);
}
else {
@@ -1177,7 +1275,7 @@ opt_deadstores(opt_state_t *opt_state, register struct block *b)
}
static void
-opt_blk(compiler_state_t *cstate, struct icode *ic, opt_state_t *opt_state,
+opt_blk(compiler_state_t *cstate, opt_state_t *opt_state,
struct block *b, int do_stmts)
{
struct slist *s;
@@ -1228,7 +1326,7 @@ opt_blk(compiler_state_t *cstate, struct icode *ic, 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, ic, opt_state, &s->s, b->val, do_stmts);
+ opt_stmt(cstate, opt_state, &s->s, b->val, do_stmts);
/*
* This is a special case: if we don't use anything from this
@@ -1254,8 +1352,9 @@ opt_blk(compiler_state_t *cstate, struct icode *ic, opt_state_t *opt_state,
* block, can we eliminate it?
*/
if (do_stmts &&
- ((b->out_use == 0 && aval != 0 && b->val[A_ATOM] == aval &&
- xval != 0 && b->val[X_ATOM] == xval) ||
+ ((b->out_use == 0 &&
+ aval != VAL_UNKNOWN && b->val[A_ATOM] == aval &&
+ xval != VAL_UNKNOWN && b->val[X_ATOM] == xval) ||
BPF_CLASS(b->s.code) == BPF_RET)) {
if (b->stmts != 0) {
b->stmts = 0;
@@ -1380,7 +1479,7 @@ opt_j(opt_state_t *opt_state, struct edge *ep)
register bpf_u_int32 x = ep->edom[i];
while (x != 0) {
- k = ffs(x) - 1;
+ k = lowest_set_bit(x);
x &=~ (1 << k);
k += i * BITS_PER_WORD;
@@ -1431,7 +1530,7 @@ or_pullup(opt_state_t *opt_state, struct block *b)
diffp = &JF(b->in_edges->pred);
at_top = 1;
- while (1) {
+ for (;;) {
if (*diffp == 0)
return;
@@ -1448,7 +1547,7 @@ or_pullup(opt_state_t *opt_state, struct block *b)
at_top = 0;
}
samep = &JF(*diffp);
- while (1) {
+ for (;;) {
if (*samep == 0)
return;
@@ -1522,7 +1621,7 @@ and_pullup(opt_state_t *opt_state, struct block *b)
diffp = &JF(b->in_edges->pred);
at_top = 1;
- while (1) {
+ for (;;) {
if (*diffp == 0)
return;
@@ -1539,7 +1638,7 @@ and_pullup(opt_state_t *opt_state, struct block *b)
at_top = 0;
}
samep = &JT(*diffp);
- while (1) {
+ for (;;) {
if (*samep == 0)
return;
@@ -1600,7 +1699,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, ic, opt_state, p, do_stmts);
+ opt_blk(cstate, opt_state, p, do_stmts);
if (do_stmts)
/*
@@ -1683,7 +1782,7 @@ opt_loop(compiler_state_t *cstate, opt_state_t *opt_state, struct icode *ic,
{
#ifdef BDEBUG
- if (pcap_optimizer_debug > 1) {
+ if (pcap_optimizer_debug > 1 || pcap_print_dot_graph) {
printf("opt_loop(root, %d) begin\n", do_stmts);
opt_dump(cstate, ic);
}
@@ -1697,7 +1796,7 @@ opt_loop(compiler_state_t *cstate, opt_state_t *opt_state, struct icode *ic,
find_edom(opt_state, ic->root);
opt_blks(cstate, opt_state, ic, do_stmts);
#ifdef BDEBUG
- if (pcap_optimizer_debug > 1) {
+ 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);
}
@@ -1718,14 +1817,14 @@ bpf_optimize(compiler_state_t *cstate, struct icode *ic)
opt_loop(cstate, &opt_state, ic, 1);
intern_blocks(&opt_state, ic);
#ifdef BDEBUG
- if (pcap_optimizer_debug > 1) {
+ if (pcap_optimizer_debug > 1 || pcap_print_dot_graph) {
printf("after intern_blocks()\n");
opt_dump(cstate, ic);
}
#endif
opt_root(&ic->root);
#ifdef BDEBUG
- if (pcap_optimizer_debug > 1) {
+ if (pcap_optimizer_debug > 1 || pcap_print_dot_graph) {
printf("after opt_root()\n");
opt_dump(cstate, ic);
}
@@ -1763,7 +1862,7 @@ mark_code(struct icode *ic)
static int
eq_slist(struct slist *x, struct slist *y)
{
- while (1) {
+ for (;;) {
while (x && x->s.code == NOP)
x = x->next;
while (y && y->s.code == NOP)
@@ -2013,7 +2112,7 @@ opt_init(compiler_state_t *cstate, opt_state_t *opt_state, struct icode *ic)
* and expect it to provide meaningful information.
*/
#ifdef BDEBUG
-int bids[1000];
+int bids[NBIDS];
#endif
/*
@@ -2030,7 +2129,7 @@ convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state,
struct slist *src;
u_int slen;
u_int off;
- int extrajmps; /* number of extra jumps inserted */
+ u_int extrajmps; /* number of extra jumps inserted */
struct slist **offset = NULL;
if (p == 0 || isMarked(ic, p))
@@ -2088,7 +2187,7 @@ convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state,
{
u_int i;
int jt, jf;
- const char *ljerr = "%s for block-local relative jump: off=%d";
+ const char ljerr[] = "%s for block-local relative jump: off=%d";
#if 0
printf("code=%x off=%d %x %x\n", src->s.code,
@@ -2108,7 +2207,11 @@ convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state,
/*NOTREACHED*/
}
- dst->jt = i - off - 1;
+ if (i - off - 1 >= 256) {
+ bpf_error(cstate, ljerr, "out-of-range jump", off);
+ /*NOTREACHED*/
+ }
+ dst->jt = (u_char)(i - off - 1);
jt++;
}
if (offset[i] == src->s.jf) {
@@ -2116,7 +2219,11 @@ convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state,
bpf_error(cstate, ljerr, "multiple matches", off);
/*NOTREACHED*/
}
- dst->jf = i - off - 1;
+ if (i - off - 1 >= 256) {
+ bpf_error(cstate, ljerr, "out-of-range jump", off);
+ /*NOTREACHED*/
+ }
+ dst->jf = (u_char)(i - off - 1);
jf++;
}
}
@@ -2133,7 +2240,8 @@ filled:
free(offset);
#ifdef BDEBUG
- bids[dst - conv_state->fstart] = p->id + 1;
+ if (dst - conv_state->fstart < NBIDS)
+ bids[dst - conv_state->fstart] = p->id + 1;
#endif
dst->code = (u_short)p->s.code;
dst->k = p->s.k;
@@ -2148,13 +2256,17 @@ filled:
return(0);
}
/* branch if T to following jump */
- dst->jt = extrajmps;
+ if (extrajmps >= 256) {
+ bpf_error(cstate, "too many extra jumps");
+ /*NOTREACHED*/
+ }
+ dst->jt = (u_char)extrajmps;
extrajmps++;
dst[extrajmps].code = BPF_JMP|BPF_JA;
dst[extrajmps].k = off - extrajmps;
}
else
- dst->jt = off;
+ dst->jt = (u_char)off;
off = JF(p)->offset - (p->offset + slen) - 1;
if (off >= 256) {
/* offset too large for branch, must add a jump */
@@ -2165,13 +2277,17 @@ filled:
}
/* branch if F to following jump */
/* if two jumps are inserted, F goes to second one */
- dst->jf = extrajmps;
+ if (extrajmps >= 256) {
+ bpf_error(cstate, "too many extra jumps");
+ /*NOTREACHED*/
+ }
+ dst->jf = (u_char)extrajmps;
extrajmps++;
dst[extrajmps].code = BPF_JMP|BPF_JA;
dst[extrajmps].k = off - extrajmps;
}
else
- dst->jf = off;
+ dst->jf = (u_char)off;
}
return (1);
}
@@ -2207,7 +2323,7 @@ icode_to_fcode(compiler_state_t *cstate, struct icode *ic,
* Loop doing convert_code_r() until no branches remain
* with too-large offsets.
*/
- while (1) {
+ for (;;) {
unMarkAll(ic);
n = *lenp = count_stmts(ic, root);
@@ -2258,8 +2374,8 @@ install_bpf_program(pcap_t *p, struct bpf_program *fp)
p->fcode.bf_len = fp->bf_len;
p->fcode.bf_insns = (struct bpf_insn *)malloc(prog_size);
if (p->fcode.bf_insns == NULL) {
- pcap_snprintf(p->errbuf, sizeof(p->errbuf),
- "malloc: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, sizeof(p->errbuf),
+ errno, "malloc");
return (-1);
}
memcpy(p->fcode.bf_insns, fp->bf_insns, prog_size);
@@ -2287,7 +2403,7 @@ dot_dump_node(struct icode *ic, struct block *block, struct bpf_program *prog,
}
fprintf(out, "\" tooltip=\"");
for (i = 0; i < BPF_MEMWORDS; i++)
- if (block->val[i] != 0)
+ if (block->val[i] != VAL_UNKNOWN)
fprintf(out, "val[%d]=%d ", i, block->val[i]);
fprintf(out, "val[A]=%d ", block->val[A_ATOM]);
fprintf(out, "val[X]=%d", block->val[X_ATOM]);
@@ -2346,10 +2462,8 @@ dot_dump(compiler_state_t *cstate, struct icode *ic)
f.bf_insns = icode_to_fcode(cstate, ic, ic->root, &f.bf_len);
fprintf(out, "digraph BPF {\n");
- ic->cur_mark = 0;
unMarkAll(ic);
dot_dump_node(ic, ic->root, &f, out);
- ic->cur_mark = 0;
unMarkAll(ic);
dot_dump_edge(ic, ic->root, out);
fprintf(out, "}\n");
@@ -2372,11 +2486,11 @@ plain_dump(compiler_state_t *cstate, struct icode *ic)
static void
opt_dump(compiler_state_t *cstate, struct icode *ic)
{
- /* if optimizer debugging is enabled, output DOT graph
- * `pcap_optimizer_debug=4' is equivalent to -dddd to follow -d/-dd/-ddd
- * convention in tcpdump command line
+ /*
+ * If the CFG, in DOT format, is requested, output it rather than
+ * the code that would be generated from that graph.
*/
- if (pcap_optimizer_debug > 3)
+ if (pcap_print_dot_graph)
dot_dump(cstate, ic);
else
plain_dump(cstate, ic);
diff --git a/contrib/libpcap/optimize.h b/contrib/libpcap/optimize.h
new file mode 100644
index 0000000000000..56b31f40c8990
--- /dev/null
+++ b/contrib/libpcap/optimize.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/*
+ * Some stuff for use when debugging the optimizer.
+ */
+#ifdef BDEBUG
+#define NBIDS 1000
+extern int bids[NBIDS];
+#endif
diff --git a/contrib/libpcap/org.tcpdump.chmod_bpf.plist b/contrib/libpcap/org.tcpdump.chmod_bpf.plist
new file mode 100644
index 0000000000000..8ad685261a3f6
--- /dev/null
+++ b/contrib/libpcap/org.tcpdump.chmod_bpf.plist
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>Label</key>
+ <string>org.tcpdump.chmod_bpf</string>
+ <key>RunAtLoad</key>
+ <true/>
+ <key>Program</key>
+ <string>/usr/local/bin/chmod_bpf</string>
+ <key>ProgramArguments</key>
+ <array>
+ <string>/usr/local/bin/chmod_bpf</string>
+ </array>
+</dict>
+</plist>
diff --git a/contrib/libpcap/packaging/pcap.spec.in b/contrib/libpcap/packaging/pcap.spec.in
deleted file mode 100644
index ff7b996eca64e..0000000000000
--- a/contrib/libpcap/packaging/pcap.spec.in
+++ /dev/null
@@ -1,77 +0,0 @@
-%define prefix /usr
-%define version @VERSION@
-
-Summary: A system-independent interface for user-level packet capture
-Name: libpcap
-Version: %version
-Release: 1
-Group: Development/Libraries
-License: BSD with advertising
-Source: @NAME@.tar.gz
-BuildRoot: /tmp/%{name}-buildroot
-URL: http://www.tcpdump.org
-
-Source: http://www.tcpdump.org/release/%{name}-%{version}.tar.gz
-
-%description
-Libpcap provides a portable framework for low-level network
-monitoring. Libpcap can provide network statistics collection,
-security monitoring and network debugging. Since almost every system
-vendor provides a different interface for packet capture, the libpcap
-authors created this system-independent API to ease in porting and to
-alleviate the need for several system-dependent packet capture modules
-in each application.
-
-Install libpcap if you need to do low-level network traffic monitoring
-on your network.
-
-%package devel
-Summary: Libraries and header files for the libpcap library
-Group: Development/Libraries
-
-%description devel
-Libpcap provides a portable framework for low-level network
-monitoring. Libpcap can provide network statistics collection,
-security monitoring and network debugging. Since almost every system
-vendor provides a different interface for packet capture, the libpcap
-authors created this system-independent API to ease in porting and to
-alleviate the need for several system-dependent packet capture modules
-in each application.
-
-This package provides the libraries, include files, and other
-resources needed for developing libpcap applications.
-
-%prep
-%setup -q
-
-%build
-export CFLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing"
-%configure
-make %{?_smp_mflags}
-
-%install
-rm -rf $RPM_BUILD_ROOT
-
-make DESTDIR=$RPM_BUILD_ROOT install
-
-%clean
-rm -rf $RPM_BUILD_ROOT
-
-%files
-%defattr(-,root,root)
-%doc LICENSE README CHANGES INSTALL.txt README.linux TODO VERSION CREDITS packaging/pcap.spec
-%{_libdir}/libpcap.so.*
-%{_mandir}/man7/pcap*.7*
-
-%files devel
-%defattr(-,root,root)
-%{_bindir}/pcap-config
-%{_includedir}/pcap/*.h
-%{_includedir}/pcap.h
-%{_includedir}/pcap-bpf.h
-%{_includedir}/pcap-namedb.h
-%{_libdir}/libpcap.so
-%{_libdir}/libpcap.a
-%{_mandir}/man1/pcap-config.1*
-%{_mandir}/man3/pcap*.3*
-%{_mandir}/man5/pcap*.5*
diff --git a/contrib/libpcap/pcap-bpf.c b/contrib/libpcap/pcap-bpf.c
index eb9d100d117fc..6ce383b0f605b 100644
--- a/contrib/libpcap/pcap-bpf.c
+++ b/contrib/libpcap/pcap-bpf.c
@@ -17,25 +17,20 @@
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * $FreeBSD$
*/
#ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
#endif
#include <sys/param.h> /* optionally get BSD define */
-#ifdef HAVE_ZEROCOPY_BPF
-#include <sys/mman.h>
-#endif
#include <sys/socket.h>
#include <time.h>
/*
* <net/bpf.h> defines ioctls, but doesn't include <sys/ioccom.h>.
*
* We include <sys/ioctl.h> as it might be necessary to declare ioctl();
- * at least on *BSD and Mac OS X, it also defines various SIOC ioctls -
+ * at least on *BSD and macOS, it also defines various SIOC ioctls -
* we could include <sys/sockio.h>, but if we're already including
* <sys/ioctl.h>, which includes <sys/sockio.h> on those platforms,
* there's not much point in doing so.
@@ -59,10 +54,6 @@ static const char usbus_prefix[] = "usbus";
#include <dirent.h>
#endif
-#ifdef HAVE_ZEROCOPY_BPF
-#include <machine/atomic.h>
-#endif
-
#include <net/if.h>
#ifdef _AIX
@@ -84,6 +75,16 @@ static const char usbus_prefix[] = "usbus";
#include <net/bpf.h>
#define _AIX
+/*
+ * If both BIOCROTZBUF and BPF_BUFMODE_ZBUF are defined, we have
+ * zero-copy BPF.
+ */
+#if defined(BIOCROTZBUF) && defined(BPF_BUFMODE_ZBUF)
+ #define HAVE_ZEROCOPY_BPF
+ #include <sys/mman.h>
+ #include <machine/atomic.h>
+#endif
+
#include <net/if_types.h> /* for IFT_ values */
#include <sys/sysconfig.h>
#include <sys/device.h>
@@ -123,7 +124,7 @@ static int bpf_load(char *errbuf);
#include <string.h>
#include <unistd.h>
-#ifdef HAVE_NET_IF_MEDIA_H
+#ifdef SIOCGIFMEDIA
# include <net/if_media.h>
#endif
@@ -226,8 +227,9 @@ static void remove_802_11(pcap_t *);
#endif
/*
- * On OS X, we don't even get any of the 802.11-plus-radio-header DLT_'s
- * defined, even though some of them are used by various Airport drivers.
+ * In some versions of macOS, we might not even get any of the
+ * 802.11-plus-radio-header DLT_'s defined, even though some
+ * of them are used by various Airport drivers in those versions.
*/
#ifndef DLT_PRISM_HEADER
#define DLT_PRISM_HEADER 119
@@ -254,7 +256,7 @@ static int pcap_set_datalink_bpf(pcap_t *p, int dlt);
* blocking mode.
*/
static int
-pcap_getnonblock_bpf(pcap_t *p, char *errbuf)
+pcap_getnonblock_bpf(pcap_t *p)
{
#ifdef HAVE_ZEROCOPY_BPF
struct pcap_bpf *pb = p->priv;
@@ -262,11 +264,11 @@ pcap_getnonblock_bpf(pcap_t *p, char *errbuf)
if (pb->zerocopy)
return (pb->nonblock);
#endif
- return (pcap_getnonblock_fd(p, errbuf));
+ return (pcap_getnonblock_fd(p));
}
static int
-pcap_setnonblock_bpf(pcap_t *p, int nonblock, char *errbuf)
+pcap_setnonblock_bpf(pcap_t *p, int nonblock)
{
#ifdef HAVE_ZEROCOPY_BPF
struct pcap_bpf *pb = p->priv;
@@ -276,7 +278,7 @@ pcap_setnonblock_bpf(pcap_t *p, int nonblock, char *errbuf)
return (0);
}
#endif
- return (pcap_setnonblock_fd(p, nonblock, errbuf));
+ return (pcap_setnonblock_fd(p, nonblock));
}
#ifdef HAVE_ZEROCOPY_BPF
@@ -367,8 +369,8 @@ pcap_next_zbuf(pcap_t *p, int *cc)
if (data)
return (data);
if (ioctl(p->fd, BIOCROTZBUF, &bz) < 0) {
- (void) pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "BIOCROTZBUF: %s", strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf,
+ PCAP_ERRBUF_SIZE, errno, "BIOCROTZBUF");
return (PCAP_ERROR);
}
return (pcap_next_zbuf_shm(p, cc));
@@ -395,8 +397,8 @@ pcap_next_zbuf(pcap_t *p, int *cc)
}
return (0);
} else if (r < 0) {
- (void) pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "select: %s", strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "select");
return (PCAP_ERROR);
}
}
@@ -414,8 +416,8 @@ pcap_next_zbuf(pcap_t *p, int *cc)
* data.
*/
if (ioctl(p->fd, BIOCROTZBUF, &bz) < 0) {
- (void) pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "BIOCROTZBUF: %s", strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "BIOCROTZBUF");
return (PCAP_ERROR);
}
return (pcap_next_zbuf_shm(p, cc));
@@ -457,8 +459,8 @@ pcap_create_interface(const char *device _U_, char *ebuf)
p->tstamp_precision_count = 2;
p->tstamp_precision_list = malloc(2 * sizeof(u_int));
if (p->tstamp_precision_list == NULL) {
- snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE, errno,
+ "malloc");
free(p);
return (NULL);
}
@@ -475,13 +477,11 @@ pcap_create_interface(const char *device _U_, char *ebuf)
static int
bpf_open(char *errbuf)
{
- int fd;
-#ifdef HAVE_CLONING_BPF
- static const char device[] = "/dev/bpf";
-#else
+ int fd = -1;
+ static const char cloning_device[] = "/dev/bpf";
int n = 0;
char device[sizeof "/dev/bpf0000000000"];
-#endif
+ static int no_cloning_bpf = 0;
#ifdef _AIX
/*
@@ -493,40 +493,55 @@ bpf_open(char *errbuf)
return (PCAP_ERROR);
#endif
-#ifdef HAVE_CLONING_BPF
- if ((fd = open(device, O_RDWR)) == -1 &&
- (errno != EACCES || (fd = open(device, O_RDONLY)) == -1)) {
- if (errno == EACCES)
- fd = PCAP_ERROR_PERM_DENIED;
- else
- fd = PCAP_ERROR;
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "(cannot open device) %s: %s", device, pcap_strerror(errno));
- }
-#else
/*
- * Go through all the minors and find one that isn't in use.
+ * First, unless we've already tried opening /dev/bpf and
+ * gotten ENOENT, try opening /dev/bpf.
+ * If it fails with ENOENT, remember that, so we don't try
+ * again, and try /dev/bpfN.
*/
- do {
- (void)pcap_snprintf(device, sizeof(device), "/dev/bpf%d", n++);
+ if (!no_cloning_bpf &&
+ (fd = open(cloning_device, O_RDWR)) == -1 &&
+ ((errno != EACCES && errno != ENOENT) ||
+ (fd = open(cloning_device, O_RDONLY)) == -1)) {
+ if (errno != ENOENT) {
+ if (errno == EACCES)
+ fd = PCAP_ERROR_PERM_DENIED;
+ else
+ fd = PCAP_ERROR;
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ errno, "(cannot open device) %s", cloning_device);
+ return (fd);
+ }
+ no_cloning_bpf = 1;
+ }
+
+ if (no_cloning_bpf) {
/*
- * Initially try a read/write open (to allow the inject
- * method to work). If that fails due to permission
- * issues, fall back to read-only. This allows a
- * non-root user to be granted specific access to pcap
- * capabilities via file permissions.
- *
- * XXX - we should have an API that has a flag that
- * controls whether to open read-only or read-write,
- * so that denial of permission to send (or inability
- * to send, if sending packets isn't supported on
- * the device in question) can be indicated at open
- * time.
+ * We don't have /dev/bpf.
+ * Go through all the /dev/bpfN minors and find one
+ * that isn't in use.
*/
- fd = open(device, O_RDWR);
- if (fd == -1 && errno == EACCES)
- fd = open(device, O_RDONLY);
- } while (fd < 0 && errno == EBUSY);
+ do {
+ (void)pcap_snprintf(device, sizeof(device), "/dev/bpf%d", n++);
+ /*
+ * Initially try a read/write open (to allow the inject
+ * method to work). If that fails due to permission
+ * issues, fall back to read-only. This allows a
+ * non-root user to be granted specific access to pcap
+ * capabilities via file permissions.
+ *
+ * XXX - we should have an API that has a flag that
+ * controls whether to open read-only or read-write,
+ * so that denial of permission to send (or inability
+ * to send, if sending packets isn't supported on
+ * the device in question) can be indicated at open
+ * time.
+ */
+ fd = open(device, O_RDWR);
+ if (fd == -1 && errno == EACCES)
+ fd = open(device, O_RDONLY);
+ } while (fd < 0 && errno == EBUSY);
+ }
/*
* XXX better message for all minors used
@@ -563,9 +578,8 @@ bpf_open(char *errbuf)
* if any.
*/
fd = PCAP_ERROR_PERM_DENIED;
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "(cannot open BPF device) %s: %s", device,
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ errno, "(cannot open BPF device) %s", device);
break;
default:
@@ -573,13 +587,11 @@ bpf_open(char *errbuf)
* Some other problem.
*/
fd = PCAP_ERROR;
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "(cannot open BPF device) %s: %s", device,
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ errno, "(cannot open BPF device) %s", device);
break;
}
}
-#endif
return (fd);
}
@@ -631,8 +643,8 @@ bpf_open_and_bind(const char *name, char *errbuf)
return (PCAP_ERROR_IFACE_NOT_UP);
default:
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "BIOCSETIF: %s: %s", name, pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ errno, "BIOCSETIF: %s", name);
close(fd);
return (PCAP_ERROR);
}
@@ -655,14 +667,14 @@ get_dlt_list(int fd, int v, struct bpf_dltlist *bdlp, char *ebuf)
bdlp->bfl_list = (u_int *) malloc(sizeof(u_int) * (bdlp->bfl_len + 1));
if (bdlp->bfl_list == NULL) {
- (void)pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
+ errno, "malloc");
return (PCAP_ERROR);
}
if (ioctl(fd, BIOCGDLTLIST, (caddr_t)bdlp) < 0) {
- (void)pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
- "BIOCGDLTLIST: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
+ errno, "BIOCGDLTLIST");
free(bdlp->bfl_list);
return (PCAP_ERROR);
}
@@ -716,8 +728,8 @@ get_dlt_list(int fd, int v, struct bpf_dltlist *bdlp, char *ebuf)
* this device"; don't treat it as an error.
*/
if (errno != EINVAL) {
- (void)pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
- "BIOCGDLTLIST: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
+ errno, "BIOCGDLTLIST");
return (PCAP_ERROR);
}
}
@@ -737,7 +749,7 @@ pcap_can_set_rfmon_bpf(pcap_t *p)
#endif
/*
- * The joys of monitor mode on OS X.
+ * The joys of monitor mode on Mac OS X/OS X/macOS.
*
* Prior to 10.4, it's not supported at all.
*
@@ -783,8 +795,8 @@ pcap_can_set_rfmon_bpf(pcap_t *p)
}
fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd == -1) {
- (void)pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "socket: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "socket");
return (PCAP_ERROR);
}
strlcpy(ifr.ifr_name, "wlt", sizeof(ifr.ifr_name));
@@ -838,9 +850,8 @@ pcap_can_set_rfmon_bpf(pcap_t *p)
return (PCAP_ERROR_IFACE_NOT_UP);
default:
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "BIOCSETIF: %s: %s",
- p->opt.device, pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "BIOCSETIF: %s", p->opt.device);
close(fd);
return (PCAP_ERROR);
}
@@ -902,8 +913,8 @@ pcap_stats_bpf(pcap_t *p, struct pcap_stat *ps)
* by libpcap, and thus not yet seen by the application.
*/
if (ioctl(p->fd, BIOCGSTATS, (caddr_t)&s) < 0) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCGSTATS: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "BIOCGSTATS");
return (PCAP_ERROR);
}
@@ -1030,8 +1041,8 @@ pcap_read_bpf(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
/* fall through */
#endif
}
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "read");
return (PCAP_ERROR);
}
bp = (u_char *)p->buffer;
@@ -1184,13 +1195,13 @@ pcap_inject_bpf(pcap_t *p, const void *buf, size_t size)
#ifdef __APPLE__
if (ret == -1 && errno == EAFNOSUPPORT) {
/*
- * In Mac OS X, there's a bug wherein setting the
- * BIOCSHDRCMPLT flag causes writes to fail; see,
- * for example:
+ * In some versions of macOS, there's a bug wherein setting
+ * the BIOCSHDRCMPLT flag causes writes to fail; see, for
+ * example:
*
* http://cerberus.sourcefire.com/~jeff/archives/patches/macosx/BIOCSHDRCMPLT-10.3.3.patch
*
- * So, if, on OS X, we get EAFNOSUPPORT from the write, we
+ * So, if, on macOS, we get EAFNOSUPPORT from the write, we
* assume it's due to that bug, and turn off that flag
* and try again. If we succeed, it either means that
* somebody applied the fix from that URL, or other patches
@@ -1199,14 +1210,13 @@ pcap_inject_bpf(pcap_t *p, const void *buf, size_t size)
* http://cerberus.sourcefire.com/~jeff/archives/patches/macosx/
*
* and are running a Darwin kernel with those fixes, or
- * that Apple fixed the problem in some OS X release.
+ * that Apple fixed the problem in some macOS release.
*/
u_int spoof_eth_src = 0;
if (ioctl(p->fd, BIOCSHDRCMPLT, &spoof_eth_src) == -1) {
- (void)pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "send: can't turn off BIOCSHDRCMPLT: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "send: can't turn off BIOCSHDRCMPLT");
return (PCAP_ERROR);
}
@@ -1217,8 +1227,8 @@ pcap_inject_bpf(pcap_t *p, const void *buf, size_t size)
}
#endif /* __APPLE__ */
if (ret == -1) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "send");
return (PCAP_ERROR);
}
return (ret);
@@ -1306,8 +1316,8 @@ bpf_load(char *errbuf)
major = genmajor(BPF_NAME);
if (major == -1) {
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "bpf_load: genmajor failed: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ errno, "bpf_load: genmajor failed");
(void)bpf_odmcleanup(NULL);
return (PCAP_ERROR);
}
@@ -1316,9 +1326,8 @@ bpf_load(char *errbuf)
if (!minors) {
minors = genminor("bpf", major, 0, BPF_MINORS, 1, 1);
if (!minors) {
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "bpf_load: genminor failed: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ errno, "bpf_load: genminor failed");
(void)bpf_odmcleanup(NULL);
return (PCAP_ERROR);
}
@@ -1329,20 +1338,19 @@ bpf_load(char *errbuf)
rc = stat(BPF_NODE "0", &sbuf);
if (rc == -1 && errno != ENOENT) {
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "bpf_load: can't stat %s: %s",
- BPF_NODE "0", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ errno, "bpf_load: can't stat %s", BPF_NODE "0");
return (PCAP_ERROR);
}
if (rc == -1 || getmajor(sbuf.st_rdev) != major) {
for (i = 0; i < BPF_MINORS; i++) {
- sprintf(buf, "%s%d", BPF_NODE, i);
+ pcap_snprintf(buf, sizeof(buf), "%s%d", BPF_NODE, i);
unlink(buf);
if (mknod(buf, S_IRUSR | S_IFCHR, domakedev(major, i)) == -1) {
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "bpf_load: can't mknod %s: %s",
- buf, pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(errbuf,
+ PCAP_ERRBUF_SIZE, errno,
+ "bpf_load: can't mknod %s", buf);
return (PCAP_ERROR);
}
}
@@ -1351,14 +1359,13 @@ bpf_load(char *errbuf)
/* Check if the driver is loaded */
memset(&cfg_ld, 0x0, sizeof(cfg_ld));
cfg_ld.path = buf;
- sprintf(cfg_ld.path, "%s/%s", DRIVER_PATH, BPF_NAME);
+ 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 */
if (sysconfig(SYS_SINGLELOAD, (void *)&cfg_ld, sizeof(cfg_ld)) == -1) {
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "bpf_load: could not load driver: %s",
- strerror(errno));
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ errno, "bpf_load: could not load driver");
return (PCAP_ERROR);
}
}
@@ -1371,9 +1378,8 @@ bpf_load(char *errbuf)
for (i = 0; i < BPF_MINORS; i++) {
cfg_bpf.devno = domakedev(major, i);
if (sysconfig(SYS_CFGKMOD, (void *)&cfg_km, sizeof(cfg_km)) == -1) {
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "bpf_load: could not configure driver: %s",
- strerror(errno));
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ errno, "bpf_load: could not configure driver");
return (PCAP_ERROR);
}
}
@@ -1493,7 +1499,6 @@ pcap_cleanup_bpf(pcap_t *p)
if (pb->zbuf2 != MAP_FAILED && pb->zbuf2 != NULL)
(void) munmap(pb->zbuf2, pb->zbufsize);
p->buffer = NULL;
- p->buffer = NULL;
}
#endif
if (pb->device != NULL) {
@@ -1538,9 +1543,10 @@ check_setif_failure(pcap_t *p, int error)
* exist.
*/
err = PCAP_ERROR_NO_SUCH_DEVICE;
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "SIOCGIFFLAGS on %s failed: %s",
- ifr.ifr_name, pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf,
+ PCAP_ERRBUF_SIZE, errno,
+ "SIOCGIFFLAGS on %s failed",
+ ifr.ifr_name);
} else {
/*
* The underlying "enN" device
@@ -1562,9 +1568,9 @@ check_setif_failure(pcap_t *p, int error)
* just report "no such device".
*/
err = PCAP_ERROR_NO_SUCH_DEVICE;
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "socket() failed: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf,
+ errno, PCAP_ERRBUF_SIZE,
+ "socket() failed");
}
return (err);
}
@@ -1572,8 +1578,8 @@ check_setif_failure(pcap_t *p, int error)
/*
* No such device.
*/
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCSETIF failed: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "BIOCSETIF failed");
return (PCAP_ERROR_NO_SUCH_DEVICE);
} else if (errno == ENETDOWN) {
/*
@@ -1589,8 +1595,8 @@ check_setif_failure(pcap_t *p, int error)
* Some other error; fill in the error string, and
* return PCAP_ERROR.
*/
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCSETIF: %s: %s",
- p->opt.device, pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "BIOCSETIF: %s", p->opt.device);
return (PCAP_ERROR);
}
}
@@ -1647,15 +1653,6 @@ pcap_activate_bpf(pcap_t *p)
struct bpf_insn total_insn;
struct bpf_program total_prog;
struct utsname osinfo;
-
-#ifdef HAVE_DAG_API
- if (strstr(device, "dag")) {
- return dag_open_live(device, snaplen, promisc, to_ms, ebuf);
- }
-#endif /* HAVE_DAG_API */
-
-#ifdef BIOCGDLTLIST
- memset(&bdl, 0, sizeof(bdl));
int have_osinfo = 0;
#ifdef HAVE_ZEROCOPY_BPF
struct bpf_zbuf bz;
@@ -1671,8 +1668,8 @@ pcap_activate_bpf(pcap_t *p)
p->fd = fd;
if (ioctl(fd, BIOCVERSION, (caddr_t)&bv) < 0) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCVERSION: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "BIOCVERSION");
status = PCAP_ERROR;
goto bad;
}
@@ -1684,13 +1681,24 @@ pcap_activate_bpf(pcap_t *p)
goto bad;
}
+ /*
+ * Turn a negative snapshot value (invalid), a snapshot value of
+ * 0 (unspecified), or a value bigger than the normal maximum
+ * value, into the maximum allowed value.
+ *
+ * If some application really *needs* a bigger snapshot
+ * length, we should just increase MAXIMUM_SNAPLEN.
+ */
+ if (p->snapshot <= 0 || p->snapshot > MAXIMUM_SNAPLEN)
+ p->snapshot = MAXIMUM_SNAPLEN;
+
#if defined(LIFNAMSIZ) && defined(ZONENAME_MAX) && defined(lifr_zoneid)
/*
* Retrieve the zoneid of the zone we are currently executing in.
*/
if ((ifr.lifr_zoneid = getzoneid()) == -1) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "getzoneid(): %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "getzoneid()");
status = PCAP_ERROR;
goto bad;
}
@@ -1716,16 +1724,15 @@ pcap_activate_bpf(pcap_t *p)
(void) strlcpy(path_zname, p->opt.device, znamelen + 1);
ifr.lifr_zoneid = getzoneidbyname(path_zname);
if (ifr.lifr_zoneid == -1) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "getzoneidbyname(%s): %s", path_zname,
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "getzoneidbyname(%s)", path_zname);
status = PCAP_ERROR;
goto bad;
}
lnamep = strdup(zonesep + 1);
if (lnamep == NULL) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "strdup: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "strdup");
status = PCAP_ERROR;
goto bad;
}
@@ -1736,20 +1743,13 @@ pcap_activate_bpf(pcap_t *p)
pb->device = strdup(p->opt.device);
if (pb->device == NULL) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "strdup: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "strdup");
status = PCAP_ERROR;
goto bad;
}
/*
- * Try finding a good size for the buffer; 32768 may be too
- * big, so keep cutting it in half until we find a size
- * that works, or run out of sizes to try. If the default
- * is larger, don't make it smaller.
- *
- * XXX - there should be a user-accessible hook to set the
- * initial buffer size.
* Attempt to find out the version of the OS on which we're running.
*/
if (uname(&osinfo) == 0)
@@ -1798,10 +1798,10 @@ pcap_activate_bpf(pcap_t *p)
* exist.
*/
status = PCAP_ERROR_NO_SUCH_DEVICE;
- pcap_snprintf(p->errbuf,
+ pcap_fmt_errmsg_for_errno(p->errbuf,
PCAP_ERRBUF_SIZE,
- "SIOCGIFFLAGS failed: %s",
- pcap_strerror(errno));
+ errno,
+ "SIOCGIFFLAGS failed");
} else
status = PCAP_ERROR_RFMON_NOTSUP;
close(sockfd);
@@ -1812,18 +1812,17 @@ pcap_activate_bpf(pcap_t *p)
* report "no such device".
*/
status = PCAP_ERROR_NO_SUCH_DEVICE;
- pcap_snprintf(p->errbuf,
- PCAP_ERRBUF_SIZE,
- "socket() failed: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf,
+ PCAP_ERRBUF_SIZE, errno,
+ "socket() failed");
}
goto bad;
}
wltdev = malloc(strlen(p->opt.device) + 2);
if (wltdev == NULL) {
- (void)pcap_snprintf(p->errbuf,
- PCAP_ERRBUF_SIZE, "malloc: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf,
+ PCAP_ERRBUF_SIZE, errno,
+ "malloc");
status = PCAP_ERROR;
goto bad;
}
@@ -1863,9 +1862,9 @@ pcap_activate_bpf(pcap_t *p)
*/
s = socket(AF_LOCAL, SOCK_DGRAM, 0);
if (s < 0) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "Can't open socket: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf,
+ PCAP_ERRBUF_SIZE, errno,
+ "Can't open socket");
status = PCAP_ERROR;
goto bad;
}
@@ -1896,9 +1895,10 @@ pcap_activate_bpf(pcap_t *p)
"Invalid USB bus interface %s",
p->opt.device);
} else {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "Can't create interface for %s: %s",
- p->opt.device, pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf,
+ PCAP_ERRBUF_SIZE, errno,
+ "Can't create interface for %s",
+ p->opt.device);
}
close(s);
status = PCAP_ERROR;
@@ -1941,8 +1941,8 @@ pcap_activate_bpf(pcap_t *p)
* size.
*/
if (ioctl(fd, BIOCGETZMAX, (caddr_t)&zbufmax) < 0) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCGETZMAX: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "BIOCGETZMAX");
status = PCAP_ERROR;
goto bad;
}
@@ -1968,8 +1968,8 @@ pcap_activate_bpf(pcap_t *p)
pb->zbuf2 = mmap(NULL, pb->zbufsize, PROT_READ | PROT_WRITE,
MAP_ANON, -1, 0);
if (pb->zbuf1 == MAP_FAILED || pb->zbuf2 == MAP_FAILED) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "mmap: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "mmap");
status = PCAP_ERROR;
goto bad;
}
@@ -1978,15 +1978,15 @@ pcap_activate_bpf(pcap_t *p)
bz.bz_bufb = pb->zbuf2;
bz.bz_buflen = pb->zbufsize;
if (ioctl(fd, BIOCSETZBUF, (caddr_t)&bz) < 0) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCSETZBUF: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "BIOCSETZBUF");
status = PCAP_ERROR;
goto bad;
}
(void)strncpy(ifrname, p->opt.device, ifnamsiz);
if (ioctl(fd, BIOCSETIF, (caddr_t)&ifr) < 0) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCSETIF: %s: %s",
- p->opt.device, pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "BIOCSETIF: %s", p->opt.device);
status = PCAP_ERROR;
goto bad;
}
@@ -2004,9 +2004,9 @@ pcap_activate_bpf(pcap_t *p)
*/
if (ioctl(fd, BIOCSBLEN,
(caddr_t)&p->opt.buffer_size) < 0) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "BIOCSBLEN: %s: %s", p->opt.device,
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf,
+ PCAP_ERRBUF_SIZE, errno,
+ "BIOCSBLEN: %s", p->opt.device);
status = PCAP_ERROR;
goto bad;
}
@@ -2070,12 +2070,11 @@ pcap_activate_bpf(pcap_t *p)
}
}
}
-#endif
/* Get the data link layer type. */
if (ioctl(fd, BIOCGDLT, (caddr_t)&v) < 0) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCGDLT: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "BIOCGDLT");
status = PCAP_ERROR;
goto bad;
}
@@ -2319,8 +2318,8 @@ pcap_activate_bpf(pcap_t *p)
* BSDs - check CVS log for "bpf.c"?
*/
if (ioctl(fd, BIOCSHDRCMPLT, &spoof_eth_src) == -1) {
- (void)pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "BIOCSHDRCMPLT: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "BIOCSHDRCMPLT");
status = PCAP_ERROR;
goto bad;
}
@@ -2361,8 +2360,8 @@ pcap_activate_bpf(pcap_t *p)
bpf_to.tv_sec = p->opt.timeout / 1000;
bpf_to.tv_usec = (p->opt.timeout * 1000) % 1000000;
if (ioctl(p->fd, BIOCSRTIMEOUT, (caddr_t)&bpf_to) < 0) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "BIOCSRTIMEOUT: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf,
+ errno, PCAP_ERRBUF_SIZE, "BIOCSRTIMEOUT");
status = PCAP_ERROR;
goto bad;
}
@@ -2371,8 +2370,8 @@ pcap_activate_bpf(pcap_t *p)
to.tv_sec = p->opt.timeout / 1000;
to.tv_usec = (p->opt.timeout * 1000) % 1000000;
if (ioctl(p->fd, BIOCSRTIMEOUT, (caddr_t)&to) < 0) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "BIOCSRTIMEOUT: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf,
+ errno, PCAP_ERRBUF_SIZE, "BIOCSRTIMEOUT");
status = PCAP_ERROR;
goto bad;
}
@@ -2406,8 +2405,8 @@ pcap_activate_bpf(pcap_t *p)
#endif /* _AIX */
v = 1;
if (ioctl(p->fd, BIOCIMMEDIATE, &v) < 0) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "BIOCIMMEDIATE: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "BIOCIMMEDIATE");
status = PCAP_ERROR;
goto bad;
}
@@ -2428,8 +2427,8 @@ pcap_activate_bpf(pcap_t *p)
if (p->opt.promisc) {
/* set promiscuous mode, just warn if it fails */
if (ioctl(p->fd, BIOCPROMISC, NULL) < 0) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCPROMISC: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "BIOCPROMISC");
status = PCAP_WARNING_PROMISC_NOTSUP;
}
}
@@ -2437,16 +2436,16 @@ pcap_activate_bpf(pcap_t *p)
#ifdef BIOCSTSTAMP
v = BPF_T_BINTIME;
if (ioctl(p->fd, BIOCSTSTAMP, &v) < 0) {
- snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCSTSTAMP: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "BIOCSTSTAMP");
status = PCAP_ERROR;
goto bad;
}
#endif /* BIOCSTSTAMP */
if (ioctl(fd, BIOCGBLEN, (caddr_t)&v) < 0) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCGBLEN: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "BIOCGBLEN");
status = PCAP_ERROR;
goto bad;
}
@@ -2456,8 +2455,8 @@ pcap_activate_bpf(pcap_t *p)
#endif
p->buffer = malloc(p->bufsize);
if (p->buffer == NULL) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "malloc: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "malloc");
status = PCAP_ERROR;
goto bad;
}
@@ -2487,8 +2486,8 @@ pcap_activate_bpf(pcap_t *p)
total_prog.bf_len = 1;
total_prog.bf_insns = &total_insn;
if (ioctl(p->fd, BIOCSETF, (caddr_t)&total_prog) < 0) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCSETF: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "BIOCSETF");
status = PCAP_ERROR;
goto bad;
}
@@ -2570,6 +2569,44 @@ check_bpf_bindable(const char *name)
int fd;
char errbuf[PCAP_ERRBUF_SIZE];
+ /*
+ * On macOS, we don't do this check if the device name begins
+ * with "wlt"; at least some versions of macOS (actually, it
+ * was called "Mac OS X" then...) offer monitor mode capturing
+ * by having a separate "monitor mode" device for each wireless
+ * adapter, rather than by implementing the ioctls that
+ * {Free,Net,Open,DragonFly}BSD provide. Opening that device
+ * puts the adapter into monitor mode, which, at least for
+ * some adapters, causes them to deassociate from the network
+ * with which they're associated.
+ *
+ * Instead, we try to open the corresponding "en" device (so
+ * that we don't end up with, for users without sufficient
+ * privilege to open capture devices, a list of adapters that
+ * only includes the wlt devices).
+ */
+#ifdef __APPLE__
+ if (strncmp(name, "wlt", 3) == 0) {
+ char *en_name;
+ size_t en_name_len;
+
+ /*
+ * Try to allocate a buffer for the "en"
+ * device's name.
+ */
+ en_name_len = strlen(name) - 1;
+ en_name = malloc(en_name_len + 1);
+ if (en_name == NULL) {
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ errno, "malloc");
+ return (-1);
+ }
+ strcpy(en_name, "en");
+ strcat(en_name, name + 3);
+ fd = bpf_open_and_bind(en_name, errbuf);
+ free(en_name);
+ } else
+#endif /* __APPLE */
fd = bpf_open_and_bind(name, errbuf);
if (fd < 0) {
/*
@@ -2604,7 +2641,18 @@ check_bpf_bindable(const char *name)
#if defined(__FreeBSD__) && defined(SIOCIFCREATE2)
static int
-finddevs_usb(pcap_if_t **alldevsp, char *errbuf)
+get_usb_if_flags(const char *name _U_, bpf_u_int32 *flags _U_, char *errbuf _U_)
+{
+ /*
+ * XXX - if there's a way to determine whether there's something
+ * plugged into a given USB bus, use that to determine whether
+ * this device is "connected" or not.
+ */
+ return (0);
+}
+
+static int
+finddevs_usb(pcap_if_list_t *devlistp, char *errbuf)
{
DIR *usbdir;
struct dirent *usbitem;
@@ -2644,7 +2692,6 @@ finddevs_usb(pcap_if_t **alldevsp, char *errbuf)
while ((usbitem = readdir(usbdir)) != NULL) {
char *p;
size_t busnumlen;
- int err;
if (strcmp(usbitem->d_name, ".") == 0 ||
strcmp(usbitem->d_name, "..") == 0) {
@@ -2660,11 +2707,18 @@ finddevs_usb(pcap_if_t **alldevsp, char *errbuf)
memcpy(name, usbus_prefix, USBUS_PREFIX_LEN);
memcpy(name + USBUS_PREFIX_LEN, usbitem->d_name, busnumlen);
*(name + USBUS_PREFIX_LEN + busnumlen) = '\0';
- err = pcap_add_if(alldevsp, name, PCAP_IF_UP, NULL, errbuf);
- if (err != 0) {
+ /*
+ * There's an entry in this directory for every USB device,
+ * not for every bus; if there's more than one device on
+ * the bus, there'll be more than one entry for that bus,
+ * so we need to avoid adding multiple capture devices
+ * for each bus.
+ */
+ if (find_or_add_dev(devlistp, name, PCAP_IF_UP,
+ get_usb_if_flags, NULL, errbuf) == NULL) {
free(name);
closedir(usbdir);
- return (err);
+ return (PCAP_ERROR);
}
}
free(name);
@@ -2673,17 +2727,116 @@ finddevs_usb(pcap_if_t **alldevsp, char *errbuf)
}
#endif
+/*
+ * Get additional flags for a device, using SIOCGIFMEDIA.
+ */
+#ifdef SIOCGIFMEDIA
+static int
+get_if_flags(const char *name, bpf_u_int32 *flags, char *errbuf)
+{
+ int sock;
+ struct ifmediareq req;
+
+ sock = socket(AF_INET, SOCK_DGRAM, 0);
+ if (sock == -1) {
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, errno,
+ "Can't create socket to get media information for %s",
+ name);
+ return (-1);
+ }
+ memset(&req, 0, sizeof(req));
+ strncpy(req.ifm_name, name, sizeof(req.ifm_name));
+ if (ioctl(sock, SIOCGIFMEDIA, &req) < 0) {
+ if (errno == EOPNOTSUPP || errno == EINVAL || errno == ENOTTY ||
+ errno == ENODEV) {
+ /*
+ * Not supported, so we can't provide any
+ * additional information. Assume that
+ * this means that "connected" vs.
+ * "disconnected" doesn't apply.
+ */
+ *flags |= PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE;
+ close(sock);
+ return (0);
+ }
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, errno,
+ "SIOCGIFMEDIA on %s failed", name);
+ close(sock);
+ return (-1);
+ }
+ close(sock);
+
+ /*
+ * OK, what type of network is this?
+ */
+ switch (IFM_TYPE(req.ifm_active)) {
+
+ case IFM_IEEE80211:
+ /*
+ * Wireless.
+ */
+ *flags |= PCAP_IF_WIRELESS;
+ break;
+ }
+
+ /*
+ * Do we know whether it's connected?
+ */
+ if (req.ifm_status & IFM_AVALID) {
+ /*
+ * Yes.
+ */
+ if (req.ifm_status & IFM_ACTIVE) {
+ /*
+ * It's connected.
+ */
+ *flags |= PCAP_IF_CONNECTION_STATUS_CONNECTED;
+ } else {
+ /*
+ * It's disconnected.
+ */
+ *flags |= PCAP_IF_CONNECTION_STATUS_DISCONNECTED;
+ }
+ }
+ return (0);
+}
+#else
+static int
+get_if_flags(const char *name _U_, bpf_u_int32 *flags _U_, char *errbuf _U_)
+{
+ /*
+ * Nothing we can do other than mark loopback devices as "the
+ * connected/disconnected status doesn't apply".
+ *
+ * XXX - on Solaris, can we do what the dladm command does,
+ * i.e. get a connected/disconnected indication from a kstat?
+ * (Note that you can also get the link speed, and possibly
+ * other information, from a kstat as well.)
+ */
+ if (*flags & PCAP_IF_LOOPBACK) {
+ /*
+ * Loopback devices aren't wireless, and "connected"/
+ * "disconnected" doesn't apply to them.
+ */
+ *flags |= PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE;
+ return (0);
+ }
+ return (0);
+}
+#endif
+
int
-pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
+pcap_platform_finddevs(pcap_if_list_t *devlistp, char *errbuf)
{
/*
* Get the list of regular interfaces first.
*/
- if (pcap_findalldevs_interfaces(alldevsp, errbuf, check_bpf_bindable) == -1)
+ if (pcap_findalldevs_interfaces(devlistp, errbuf, check_bpf_bindable,
+ get_if_flags) == -1)
return (-1); /* failure */
#if defined(__FreeBSD__) && defined(SIOCIFCREATE2)
- if (finddevs_usb(alldevsp, errbuf) == -1)
+ if (finddevs_usb(devlistp, errbuf) == -1)
return (-1);
#endif
@@ -2704,8 +2857,8 @@ monitor_mode(pcap_t *p, int set)
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock == -1) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "can't open socket: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "can't open socket");
return (PCAP_ERROR);
}
@@ -2736,8 +2889,8 @@ monitor_mode(pcap_t *p, int set)
return (PCAP_ERROR_RFMON_NOTSUP);
default:
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "SIOCGIFMEDIA 1: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "SIOCGIFMEDIA 1");
close(sock);
return (PCAP_ERROR);
}
@@ -2756,15 +2909,15 @@ monitor_mode(pcap_t *p, int set)
*/
media_list = malloc(req.ifm_count * sizeof(*media_list));
if (media_list == NULL) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "malloc: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "malloc");
close(sock);
return (PCAP_ERROR);
}
req.ifm_ulist = media_list;
if (ioctl(sock, SIOCGIFMEDIA, &req) < 0) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "SIOCGIFMEDIA: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "SIOCGIFMEDIA");
free(media_list);
close(sock);
return (PCAP_ERROR);
@@ -2824,8 +2977,8 @@ monitor_mode(pcap_t *p, int set)
sizeof(ifr.ifr_name));
ifr.ifr_media = req.ifm_current | IFM_IEEE80211_MONITOR;
if (ioctl(sock, SIOCSIFMEDIA, &ifr) == -1) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "SIOCSIFMEDIA: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf,
+ PCAP_ERRBUF_SIZE, errno, "SIOCSIFMEDIA");
close(sock);
return (PCAP_ERROR);
}
@@ -3049,8 +3202,8 @@ pcap_setfilter_bpf(pcap_t *p, struct bpf_program *fp)
* some kernels.
*/
if (errno != EINVAL) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCSETF: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "BIOCSETF");
return (-1);
}
@@ -3078,11 +3231,10 @@ pcap_setdirection_bpf(pcap_t *p, pcap_direction_t d)
direction = (d == PCAP_D_IN) ? BPF_D_IN :
((d == PCAP_D_OUT) ? BPF_D_OUT : BPF_D_INOUT);
if (ioctl(p->fd, BIOCSDIRECTION, &direction) == -1) {
- (void) pcap_snprintf(p->errbuf, sizeof(p->errbuf),
- "Cannot set direction to %s: %s",
+ pcap_fmt_errmsg_for_errno(p->errbuf, sizeof(p->errbuf),
+ errno, "Cannot set direction to %s",
(d == PCAP_D_IN) ? "PCAP_D_IN" :
- ((d == PCAP_D_OUT) ? "PCAP_D_OUT" : "PCAP_D_INOUT"),
- strerror(errno));
+ ((d == PCAP_D_OUT) ? "PCAP_D_OUT" : "PCAP_D_INOUT"));
return (-1);
}
return (0);
@@ -3100,10 +3252,9 @@ pcap_setdirection_bpf(pcap_t *p, pcap_direction_t d)
seesent = (d == PCAP_D_INOUT);
if (ioctl(p->fd, BIOCSSEESENT, &seesent) == -1) {
- (void) pcap_snprintf(p->errbuf, sizeof(p->errbuf),
- "Cannot set direction to %s: %s",
- (d == PCAP_D_INOUT) ? "PCAP_D_INOUT" : "PCAP_D_IN",
- strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, sizeof(p->errbuf),
+ errno, "Cannot set direction to %s",
+ (d == PCAP_D_INOUT) ? "PCAP_D_INOUT" : "PCAP_D_IN");
return (-1);
}
return (0);
@@ -3119,10 +3270,23 @@ pcap_set_datalink_bpf(pcap_t *p, int dlt)
{
#ifdef BIOCSDLT
if (ioctl(p->fd, BIOCSDLT, &dlt) == -1) {
- (void) pcap_snprintf(p->errbuf, sizeof(p->errbuf),
- "Cannot set DLT %d: %s", dlt, strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, sizeof(p->errbuf),
+ errno, "Cannot set DLT %d", dlt);
return (-1);
}
#endif
return (0);
}
+
+/*
+ * Platform-specific information.
+ */
+const char *
+pcap_lib_version(void)
+{
+#ifdef HAVE_ZEROCOPY_BPF
+ return (PCAP_VERSION_STRING " (with zerocopy support)");
+#else
+ return (PCAP_VERSION_STRING);
+#endif
+}
diff --git a/contrib/libpcap/pcap-bt-linux.c b/contrib/libpcap/pcap-bt-linux.c
index 4452fe44e3796..07ed1c73de5a4 100644
--- a/contrib/libpcap/pcap-bt-linux.c
+++ b/contrib/libpcap/pcap-bt-linux.c
@@ -33,17 +33,13 @@
*/
#ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
#endif
#include "pcap-int.h"
#include "pcap-bt-linux.h"
#include "pcap/bluetooth.h"
-#ifdef NEED_STRERROR_H
-#include "strerror.h"
-#endif
-
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
@@ -74,7 +70,7 @@ struct pcap_bt {
};
int
-bt_findalldevs(pcap_if_t **alldevsp, char *err_str)
+bt_findalldevs(pcap_if_list_t *devlistp, char *err_str)
{
struct hci_dev_list_req *dev_list;
struct hci_dev_req *dev_req;
@@ -87,8 +83,8 @@ bt_findalldevs(pcap_if_t **alldevsp, char *err_str)
/* if bluetooth is not supported this this is not fatal*/
if (errno == EAFNOSUPPORT)
return 0;
- pcap_snprintf(err_str, PCAP_ERRBUF_SIZE,
- "Can't open raw Bluetooth socket: %s", strerror(errno));
+ pcap_fmt_errmsg_for_errno(err_str, PCAP_ERRBUF_SIZE,
+ errno, "Can't open raw Bluetooth socket");
return -1;
}
@@ -105,9 +101,8 @@ bt_findalldevs(pcap_if_t **alldevsp, char *err_str)
if (ioctl(sock, HCIGETDEVLIST, (void *) dev_list) < 0)
{
- pcap_snprintf(err_str, PCAP_ERRBUF_SIZE,
- "Can't get Bluetooth device list via ioctl: %s",
- strerror(errno));
+ pcap_fmt_errmsg_for_errno(err_str, PCAP_ERRBUF_SIZE,
+ errno, "Can't get Bluetooth device list via ioctl");
ret = -1;
goto free;
}
@@ -119,13 +114,19 @@ bt_findalldevs(pcap_if_t **alldevsp, char *err_str)
pcap_snprintf(dev_name, 20, BT_IFACE"%d", dev_req->dev_id);
pcap_snprintf(dev_descr, 30, "Bluetooth adapter number %d", i);
- if (pcap_add_if(alldevsp, dev_name, 0,
- dev_descr, err_str) < 0)
+ /*
+ * Bluetooth is a wireless technology.
+ * XXX - if there's the notion of associating with a
+ * network, and we can determine whether the interface
+ * is associated with a network, check that and set
+ * the status to PCAP_IF_CONNECTION_STATUS_CONNECTED
+ * or PCAP_IF_CONNECTION_STATUS_DISCONNECTED.
+ */
+ if (add_dev(devlistp, dev_name, PCAP_IF_WIRELESS, dev_descr, err_str) == NULL)
{
ret = -1;
break;
}
-
}
free:
@@ -198,6 +199,17 @@ bt_activate(pcap_t* handle)
return PCAP_ERROR;
}
+ /*
+ * Turn a negative snapshot value (invalid), a snapshot value of
+ * 0 (unspecified), or a value bigger than the normal maximum
+ * value, into the maximum allowed value.
+ *
+ * If some application really *needs* a bigger snapshot
+ * length, we should just increase MAXIMUM_SNAPLEN.
+ */
+ if (handle->snapshot <= 0 || handle->snapshot > MAXIMUM_SNAPLEN)
+ handle->snapshot = MAXIMUM_SNAPLEN;
+
/* Initialize some components of the pcap structure. */
handle->bufsize = BT_CTRL_SIZE+sizeof(pcap_bluetooth_h4_header)+handle->snapshot;
handle->linktype = DLT_BLUETOOTH_HCI_H4_WITH_PHDR;
@@ -215,29 +227,29 @@ bt_activate(pcap_t* handle)
/* Create HCI socket */
handle->fd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
if (handle->fd < 0) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "Can't create raw socket: %s", strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "Can't create raw socket");
return PCAP_ERROR;
}
handle->buffer = malloc(handle->bufsize);
if (!handle->buffer) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't allocate dump buffer: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "Can't allocate dump buffer");
goto close_fail;
}
opt = 1;
if (setsockopt(handle->fd, SOL_HCI, HCI_DATA_DIR, &opt, sizeof(opt)) < 0) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "Can't enable data direction info: %s", strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "Can't enable data direction info");
goto close_fail;
}
opt = 1;
if (setsockopt(handle->fd, SOL_HCI, HCI_TIME_STAMP, &opt, sizeof(opt)) < 0) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "Can't enable time stamp: %s", strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "Can't enable time stamp");
goto close_fail;
}
@@ -247,8 +259,8 @@ bt_activate(pcap_t* handle)
memset((void *) &flt.type_mask, 0xff, sizeof(flt.type_mask));
memset((void *) &flt.event_mask, 0xff, sizeof(flt.event_mask));
if (setsockopt(handle->fd, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "Can't set filter: %s", strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "Can't set filter");
goto close_fail;
}
@@ -256,13 +268,12 @@ bt_activate(pcap_t* handle)
/* Bind socket to the HCI device */
addr.hci_family = AF_BLUETOOTH;
addr.hci_dev = handlep->dev_id;
-#ifdef SOCKADDR_HCI_HAS_HCI_CHANNEL
+#ifdef HAVE_STRUCT_SOCKADDR_HCI_HCI_CHANNEL
addr.hci_channel = HCI_CHANNEL_RAW;
#endif
if (bind(handle->fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "Can't attach to device %d: %s", handlep->dev_id,
- strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "Can't attach to device %d", handlep->dev_id);
goto close_fail;
}
@@ -281,8 +292,8 @@ bt_activate(pcap_t* handle)
if (setsockopt(handle->fd, SOL_SOCKET, SO_RCVBUF,
&handle->opt.buffer_size,
sizeof(handle->opt.buffer_size)) == -1) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "SO_RCVBUF: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf,
+ errno, PCAP_ERRBUF_SIZE, "SO_RCVBUF");
goto close_fail;
}
}
@@ -296,7 +307,7 @@ close_fail:
}
static int
-bt_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user)
+bt_read_linux(pcap_t *handle, int max_packets _U_, pcap_handler callback, u_char *user)
{
struct cmsghdr *cmsg;
struct msghdr msg;
@@ -329,8 +340,8 @@ bt_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *us
} while ((ret == -1) && (errno == EINTR));
if (ret < 0) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "Can't receive packet: %s", strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "Can't receive packet");
return -1;
}
@@ -366,7 +377,7 @@ bt_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *us
}
static int
-bt_inject_linux(pcap_t *handle, const void *buf, size_t size)
+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");
@@ -389,8 +400,8 @@ bt_stats_linux(pcap_t *handle, struct pcap_stat *stats)
} while ((ret == -1) && (errno == EINTR));
if (ret < 0) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "Can't get stats via ioctl: %s", strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "Can't get stats via ioctl");
return (-1);
}
diff --git a/contrib/libpcap/pcap-bt-linux.h b/contrib/libpcap/pcap-bt-linux.h
index e098654dcbc8e..163bd341fc782 100644
--- a/contrib/libpcap/pcap-bt-linux.h
+++ b/contrib/libpcap/pcap-bt-linux.h
@@ -34,5 +34,5 @@
/*
* Prototypes for Bluetooth-related functions
*/
-int bt_findalldevs(pcap_if_t **alldevsp, char *err_str);
+int bt_findalldevs(pcap_if_list_t *devlistp, char *err_str);
pcap_t *bt_create(const char *device, char *ebuf, int *is_ours);
diff --git a/contrib/libpcap/pcap-bt-monitor-linux.c b/contrib/libpcap/pcap-bt-monitor-linux.c
index 521d6d500d056..c222c100edb23 100644
--- a/contrib/libpcap/pcap-bt-monitor-linux.c
+++ b/contrib/libpcap/pcap-bt-monitor-linux.c
@@ -30,7 +30,7 @@
*/
#ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
#endif
#include <errno.h>
@@ -60,12 +60,21 @@ struct hci_mon_hdr {
} __attribute__((packed));
int
-bt_monitor_findalldevs(pcap_if_t **alldevsp, char *err_str)
+bt_monitor_findalldevs(pcap_if_list_t *devlistp, char *err_str)
{
int ret = 0;
- if (pcap_add_if(alldevsp, INTERFACE_NAME, 0,
- "Bluetooth Linux Monitor", err_str) < 0)
+ /*
+ * Bluetooth is a wireless technology.
+ *
+ * This is a device to monitor all Bluetooth interfaces, so
+ * there's no notion of "connected" or "disconnected", any
+ * more than there's a notion of "connected" or "disconnected"
+ * for the "any" device.
+ */
+ if (add_dev(devlistp, INTERFACE_NAME,
+ PCAP_IF_WIRELESS|PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE,
+ "Bluetooth Linux Monitor", err_str) == NULL)
{
ret = -1;
}
@@ -110,8 +119,8 @@ bt_monitor_read(pcap_t *handle, int max_packets _U_, pcap_handler callback, u_ch
} while ((ret == -1) && (errno == EINTR));
if (ret < 0) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "Can't receive packet: %s", strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "Can't receive packet");
return -1;
}
@@ -173,6 +182,17 @@ bt_monitor_activate(pcap_t* handle)
return PCAP_ERROR_RFMON_NOTSUP;
}
+ /*
+ * Turn a negative snapshot value (invalid), a snapshot value of
+ * 0 (unspecified), or a value bigger than the normal maximum
+ * value, into the maximum allowed value.
+ *
+ * If some application really *needs* a bigger snapshot
+ * length, we should just increase MAXIMUM_SNAPLEN.
+ */
+ if (handle->snapshot <= 0 || handle->snapshot > MAXIMUM_SNAPLEN)
+ handle->snapshot = MAXIMUM_SNAPLEN;
+
handle->bufsize = BT_CONTROL_SIZE + sizeof(pcap_bluetooth_linux_monitor_header) + handle->snapshot;
handle->linktype = DLT_BLUETOOTH_LINUX_MONITOR;
@@ -187,15 +207,15 @@ bt_monitor_activate(pcap_t* handle)
handle->fd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
if (handle->fd < 0) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "Can't create raw socket: %s", strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "Can't create raw socket");
return PCAP_ERROR;
}
handle->buffer = malloc(handle->bufsize);
if (!handle->buffer) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't allocate dump buffer: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "Can't allocate dump buffer");
goto close_fail;
}
@@ -205,15 +225,15 @@ bt_monitor_activate(pcap_t* handle)
addr.hci_channel = HCI_CHANNEL_MONITOR;
if (bind(handle->fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "Can't attach to interface: %s", strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "Can't attach to interface");
goto close_fail;
}
opt = 1;
if (setsockopt(handle->fd, SOL_SOCKET, SO_TIMESTAMP, &opt, sizeof(opt)) < 0) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "Can't enable time stamp: %s", strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "Can't enable time stamp");
goto close_fail;
}
diff --git a/contrib/libpcap/pcap-bt-monitor-linux.h b/contrib/libpcap/pcap-bt-monitor-linux.h
index aada2bc77bfbe..8133710a2617a 100644
--- a/contrib/libpcap/pcap-bt-monitor-linux.h
+++ b/contrib/libpcap/pcap-bt-monitor-linux.h
@@ -28,5 +28,5 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-int bt_monitor_findalldevs(pcap_if_t **alldevsp, char *err_str);
+int bt_monitor_findalldevs(pcap_if_list_t *devlistp, char *err_str);
pcap_t *bt_monitor_create(const char *device, char *ebuf, int *is_ours);
diff --git a/contrib/libpcap/pcap-common.c b/contrib/libpcap/pcap-common.c
index 84368f6cefa68..7f2b81a3a3376 100644
--- a/contrib/libpcap/pcap-common.c
+++ b/contrib/libpcap/pcap-common.c
@@ -18,26 +18,14 @@
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * pcap-common.c - common code for pcap and pcap-ng files
+ * pcap-common.c - common code for pcap and pcapng files
*/
#ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
#endif
-#ifdef _WIN32
-#include <pcap-stdinc.h>
-#else /* _WIN32 */
-#if HAVE_INTTYPES_H
-#include <inttypes.h>
-#elif HAVE_STDINT_H
-#include <stdint.h>
-#endif
-#ifdef HAVE_SYS_BITYPES_H
-#include <sys/bitypes.h>
-#endif
-#include <sys/types.h>
-#endif /* _WIN32 */
+#include <pcap-types.h>
#include "pcap-int.h"
#include "extract.h"
@@ -496,9 +484,14 @@
/*
* IEEE 802.15.4, exactly as it appears in the spec (no padding, no
- * nothing); requested by Mikko Saarnivala <mikko.saarnivala@sensinode.com>.
+ * nothing), and with the FCS at the end of the frame; requested by
+ * Mikko Saarnivala <mikko.saarnivala@sensinode.com>.
+ *
+ * This should only be used if the FCS is present at the end of the
+ * frame; if the frame has no FCS, DLT_IEEE802_15_4_NOFCS should be
+ * used.
*/
-#define LINKTYPE_IEEE802_15_4 195
+#define LINKTYPE_IEEE802_15_4_WITHFCS 195
/*
* Various link-layer types, with a pseudo-header, for SITA
@@ -703,14 +696,14 @@
* the pseudo-header is:
*
* struct dl_ipnetinfo {
- * u_int8_t dli_version;
- * u_int8_t dli_family;
- * u_int16_t dli_htype;
- * u_int32_t dli_pktlen;
- * u_int32_t dli_ifindex;
- * u_int32_t dli_grifindex;
- * u_int32_t dli_zsrc;
- * u_int32_t dli_zdst;
+ * uint8_t dli_version;
+ * uint8_t dli_family;
+ * uint16_t dli_htype;
+ * uint32_t dli_pktlen;
+ * uint32_t dli_ifindex;
+ * uint32_t dli_grifindex;
+ * uint32_t dli_zsrc;
+ * uint32_t dli_zdst;
* };
*
* dli_version is 2 for the current version of the pseudo-header.
@@ -887,7 +880,7 @@
/*
* pfsync output; DLT_PFSYNC is 18, which collides with DLT_CIP in
- * SuSE 6.3, on OpenBSD, NetBSD, DragonFly BSD, and Mac OS X, and
+ * SuSE 6.3, on OpenBSD, NetBSD, DragonFly BSD, and macOS, and
* is 121, which collides with DLT_HHDLC, in FreeBSD. We pick a
* shiny new link-layer header type value that doesn't collide with
* anything, in the hopes that future pfsync savefiles, if any,
@@ -984,7 +977,7 @@
* So I'll just give them one; hopefully this will show up in a
* libpcap release in time for them to get this into 10.10 Big Sur
* or whatever Mavericks' successor is called. LINKTYPE_PKTAP
- * will be 258 *even on OS X*; that is *intentional*, so that
+ * will be 258 *even on macOS*; that is *intentional*, so that
* PKTAP files look the same on *all* OSes (different OSes can have
* different numerical values for a given DLT_, but *MUST NOT* have
* different values for what goes in a file, as files can be moved
@@ -1028,7 +1021,67 @@
*/
#define LINKTYPE_RDS 265
-#define LINKTYPE_MATCHING_MAX 265 /* highest value in the "matching" range */
+/*
+ * USB packets, beginning with a Darwin (macOS, etc.) header.
+ */
+#define LINKTYPE_USB_DARWIN 266
+
+/*
+ * OpenBSD DLT_OPENFLOW.
+ */
+#define LINKTYPE_OPENFLOW 267
+
+/*
+ * SDLC frames containing SNA PDUs.
+ */
+#define LINKTYPE_SDLC 268
+
+/*
+ * per "Selvig, Bjorn" <b.selvig@ti.com> used for
+ * TI protocol sniffer.
+ */
+#define LINKTYPE_TI_LLN_SNIFFER 269
+
+/*
+ * per: Erik de Jong <erikdejong at gmail.com> for
+ * https://github.com/eriknl/LoRaTap/releases/tag/v0.1
+ */
+#define LINKTYPE_LORATAP 270
+
+/*
+ * per: Stefanha at gmail.com for
+ * http://lists.sandelman.ca/pipermail/tcpdump-workers/2017-May/000772.html
+ * and: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/vsockmon.h
+ * for: http://qemu-project.org/Features/VirtioVsock
+ */
+#define LINKTYPE_VSOCK 271
+
+/*
+ * Nordic Semiconductor Bluetooth LE sniffer.
+ */
+#define LINKTYPE_NORDIC_BLE 272
+
+/*
+ * Excentis DOCSIS 3.1 RF sniffer (XRA-31)
+ * per: bruno.verstuyft at excentis.com
+ * http://www.xra31.com/xra-header
+ */
+#define LINKTYPE_DOCSIS31_XRA31 273
+
+/*
+ * mPackets, as specified by IEEE 802.3br Figure 99-4, starting
+ * with the preamble and always ending with a CRC field.
+ */
+#define LINKTYPE_ETHERNET_MPACKET 274
+
+/*
+ * DisplayPort AUX channel monitoring data as specified by VESA
+ * DisplayPort(DP) Standard preceeded by a pseudo-header.
+ * per dirk.eibach at gdsys.cc
+ */
+#define LINKTYPE_DISPLAYPORT_AUX 275
+
+#define LINKTYPE_MATCHING_MAX 275 /* highest value in the "matching" range */
static struct linktype_map {
int dlt;
@@ -1175,7 +1228,22 @@ linktype_to_dlt(int linktype)
return linktype;
}
-#define EXTRACT_
+/*
+ * 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
+ *
+ * https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-messages
+ */
+u_int
+max_snaplen_for_dlt(int dlt)
+{
+ if (dlt == DLT_DBUS)
+ return 134217728;
+ else
+ return MAXIMUM_SNAPLEN;
+}
/*
* DLT_LINUX_SLL packets with a protocol type of LINUX_SLL_P_CAN or
@@ -1192,7 +1260,7 @@ swap_linux_sll_header(const struct pcap_pkthdr *hdr, u_char *buf)
u_int caplen = hdr->caplen;
u_int length = hdr->len;
struct sll_header *shdr = (struct sll_header *)buf;
- u_int16_t protocol;
+ uint16_t protocol;
pcap_can_socketcan_hdr *chdr;
if (caplen < (u_int) sizeof(struct sll_header) ||
@@ -1338,7 +1406,7 @@ swap_linux_usb_header(const struct pcap_pkthdr *hdr, u_char *buf,
if (uhdr->transfer_type == URB_ISOCHRONOUS) {
/* swap the values in struct linux_usb_isodesc */
usb_isodesc *pisodesc;
- u_int32_t i;
+ uint32_t i;
pisodesc = (usb_isodesc *)(void *)(buf+offset);
for (i = 0; i < uhdr->ndesc; i++) {
@@ -1384,7 +1452,7 @@ swap_nflog_header(const struct pcap_pkthdr *hdr, u_char *buf)
nflog_tlv_t *tlv;
u_int caplen = hdr->caplen;
u_int length = hdr->len;
- u_int16_t size;
+ uint16_t size;
if (caplen < (u_int) sizeof(nflog_hdr_t) ||
length < (u_int) sizeof(nflog_hdr_t)) {
diff --git a/contrib/libpcap/pcap-common.h b/contrib/libpcap/pcap-common.h
index 6ac5bcd264f9c..88c057cb49870 100644
--- a/contrib/libpcap/pcap-common.h
+++ b/contrib/libpcap/pcap-common.h
@@ -1,3 +1,25 @@
+/*
+ * 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: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * pcap-common.h - common code for pcap and pcapng files
+ */
/*
* We use the "receiver-makes-right" approach to byte order,
@@ -23,3 +45,5 @@ extern int linktype_to_dlt(int linktype);
extern void swap_pseudo_headers(int linktype, struct pcap_pkthdr *hdr,
u_char *data);
+
+extern u_int max_snaplen_for_dlt(int dlt);
diff --git a/contrib/libpcap/pcap-config.in b/contrib/libpcap/pcap-config.in
index 206be3b4a6443..54ca42f07bc5f 100644
--- a/contrib/libpcap/pcap-config.in
+++ b/contrib/libpcap/pcap-config.in
@@ -4,12 +4,17 @@
# Script to give the appropriate compiler flags and linker flags
# to use when building code that uses libpcap.
#
+# These variables come from the configure script, so includedir and
+# libdir may be defined in terms of prefix and exec_prefix, so the
+# latter must be defined as well.
+#
prefix="@prefix@"
exec_prefix="@exec_prefix@"
includedir="@includedir@"
libdir="@libdir@"
V_RPATH_OPT="@V_RPATH_OPT@"
LIBS="@LIBS@"
+PACKAGE_NAME="@PACKAGE_NAME@"
static=0
show_cflags=0
@@ -75,7 +80,7 @@ else
#
if [ "$show_cflags" = 1 -a "$show_libs" = 1 ]
then
- echo "-I$includedir -L$libdir $RPATH -lpcap"
+ echo "-I$includedir -L$libdir $RPATH -l$PACKAGE_NAME"
elif [ "$show_cflags" = 1 -a "$show_additional_libs" = 1 ]
then
echo "-I$includedir"
@@ -84,6 +89,6 @@ else
echo "-I$includedir"
elif [ "$show_libs" = 1 ]
then
- echo "-L$libdir $RPATH -lpcap"
+ echo "-L$libdir $RPATH -l$PACKAGE_NAME"
fi
fi
diff --git a/contrib/libpcap/pcap-dag.c b/contrib/libpcap/pcap-dag.c
index 201696cca296c..5d5b6c10318b4 100644
--- a/contrib/libpcap/pcap-dag.c
+++ b/contrib/libpcap/pcap-dag.c
@@ -16,7 +16,7 @@
*/
#ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
#endif
#include <sys/param.h> /* optionally get BSD define */
@@ -41,6 +41,7 @@ struct rtentry; /* declarations in <net/if.h> */
#include "dagnew.h"
#include "dagapi.h"
#include "dagpci.h"
+#include "dag_config_api.h"
#include "pcap-dag.h"
@@ -54,96 +55,100 @@ struct rtentry; /* declarations in <net/if.h> */
#endif
-#ifndef TYPE_AAL5
-#define TYPE_AAL5 4
+#ifndef ERF_TYPE_AAL5
+#define ERF_TYPE_AAL5 4
#endif
-#ifndef TYPE_MC_HDLC
-#define TYPE_MC_HDLC 5
+#ifndef ERF_TYPE_MC_HDLC
+#define ERF_TYPE_MC_HDLC 5
#endif
-#ifndef TYPE_MC_RAW
-#define TYPE_MC_RAW 6
+#ifndef ERF_TYPE_MC_RAW
+#define ERF_TYPE_MC_RAW 6
#endif
-#ifndef TYPE_MC_ATM
-#define TYPE_MC_ATM 7
+#ifndef ERF_TYPE_MC_ATM
+#define ERF_TYPE_MC_ATM 7
#endif
-#ifndef TYPE_MC_RAW_CHANNEL
-#define TYPE_MC_RAW_CHANNEL 8
+#ifndef ERF_TYPE_MC_RAW_CHANNEL
+#define ERF_TYPE_MC_RAW_CHANNEL 8
#endif
-#ifndef TYPE_MC_AAL5
-#define TYPE_MC_AAL5 9
+#ifndef ERF_TYPE_MC_AAL5
+#define ERF_TYPE_MC_AAL5 9
#endif
-#ifndef TYPE_COLOR_HDLC_POS
-#define TYPE_COLOR_HDLC_POS 10
+#ifndef ERF_TYPE_COLOR_HDLC_POS
+#define ERF_TYPE_COLOR_HDLC_POS 10
#endif
-#ifndef TYPE_COLOR_ETH
-#define TYPE_COLOR_ETH 11
+#ifndef ERF_TYPE_COLOR_ETH
+#define ERF_TYPE_COLOR_ETH 11
#endif
-#ifndef TYPE_MC_AAL2
-#define TYPE_MC_AAL2 12
+#ifndef ERF_TYPE_MC_AAL2
+#define ERF_TYPE_MC_AAL2 12
#endif
-#ifndef TYPE_IP_COUNTER
-#define TYPE_IP_COUNTER 13
+#ifndef ERF_TYPE_IP_COUNTER
+#define ERF_TYPE_IP_COUNTER 13
#endif
-#ifndef TYPE_TCP_FLOW_COUNTER
-#define TYPE_TCP_FLOW_COUNTER 14
+#ifndef ERF_TYPE_TCP_FLOW_COUNTER
+#define ERF_TYPE_TCP_FLOW_COUNTER 14
#endif
-#ifndef TYPE_DSM_COLOR_HDLC_POS
-#define TYPE_DSM_COLOR_HDLC_POS 15
+#ifndef ERF_TYPE_DSM_COLOR_HDLC_POS
+#define ERF_TYPE_DSM_COLOR_HDLC_POS 15
#endif
-#ifndef TYPE_DSM_COLOR_ETH
-#define TYPE_DSM_COLOR_ETH 16
+#ifndef ERF_TYPE_DSM_COLOR_ETH
+#define ERF_TYPE_DSM_COLOR_ETH 16
#endif
-#ifndef TYPE_COLOR_MC_HDLC_POS
-#define TYPE_COLOR_MC_HDLC_POS 17
+#ifndef ERF_TYPE_COLOR_MC_HDLC_POS
+#define ERF_TYPE_COLOR_MC_HDLC_POS 17
#endif
-#ifndef TYPE_AAL2
-#define TYPE_AAL2 18
+#ifndef ERF_TYPE_AAL2
+#define ERF_TYPE_AAL2 18
#endif
-#ifndef TYPE_COLOR_HASH_POS
-#define TYPE_COLOR_HASH_POS 19
+#ifndef ERF_TYPE_COLOR_HASH_POS
+#define ERF_TYPE_COLOR_HASH_POS 19
#endif
-#ifndef TYPE_COLOR_HASH_ETH
-#define TYPE_COLOR_HASH_ETH 20
+#ifndef ERF_TYPE_COLOR_HASH_ETH
+#define ERF_TYPE_COLOR_HASH_ETH 20
#endif
-#ifndef TYPE_INFINIBAND
-#define TYPE_INFINIBAND 21
+#ifndef ERF_TYPE_INFINIBAND
+#define ERF_TYPE_INFINIBAND 21
#endif
-#ifndef TYPE_IPV4
-#define TYPE_IPV4 22
+#ifndef ERF_TYPE_IPV4
+#define ERF_TYPE_IPV4 22
#endif
-#ifndef TYPE_IPV6
-#define TYPE_IPV6 23
+#ifndef ERF_TYPE_IPV6
+#define ERF_TYPE_IPV6 23
#endif
-#ifndef TYPE_RAW_LINK
-#define TYPE_RAW_LINK 24
+#ifndef ERF_TYPE_RAW_LINK
+#define ERF_TYPE_RAW_LINK 24
#endif
-#ifndef TYPE_INFINIBAND_LINK
-#define TYPE_INFINIBAND_LINK 25
+#ifndef ERF_TYPE_INFINIBAND_LINK
+#define ERF_TYPE_INFINIBAND_LINK 25
#endif
-#ifndef TYPE_PAD
-#define TYPE_PAD 48
+#ifndef ERF_TYPE_META
+#define ERF_TYPE_META 27
+#endif
+
+#ifndef ERF_TYPE_PAD
+#define ERF_TYPE_PAD 48
#endif
#define ATM_CELL_SIZE 52
@@ -173,20 +178,19 @@ struct sunatm_hdr {
*/
struct pcap_dag {
struct pcap_stat stat;
-#ifdef HAVE_DAG_STREAMS_API
u_char *dag_mem_bottom; /* DAG card current memory bottom pointer */
u_char *dag_mem_top; /* DAG card current memory top pointer */
-#else /* HAVE_DAG_STREAMS_API */
- void *dag_mem_base; /* DAG card memory base address */
- u_int dag_mem_bottom; /* DAG card current memory bottom offset */
- u_int dag_mem_top; /* DAG card current memory top offset */
-#endif /* HAVE_DAG_STREAMS_API */
int dag_fcs_bits; /* Number of checksum bits from link layer */
- int dag_offset_flags; /* Flags to pass to dag_offset(). */
+ int dag_flags; /* Flags */
int dag_stream; /* DAG stream number */
int dag_timeout; /* timeout specified to pcap_open_live.
* Same as in linux above, introduce
* generally? */
+ dag_card_ref_t dag_ref; /* DAG Configuration/Status API card reference */
+ dag_component_t dag_root; /* DAG CSAPI Root component */
+ attr_uuid_t drop_attr; /* DAG Stream Drop Attribute handle, if available */
+ struct timeval required_select_timeout;
+ /* Timeout caller must use in event loops */
};
typedef struct pcap_dag_node {
@@ -205,11 +209,18 @@ static const unsigned short endian_test_word = 0x0100;
static unsigned char TempPkt[MAX_DAG_PACKET];
+#ifndef HAVE_DAG_LARGE_STREAMS_API
+#define dag_attach_stream64(a, b, c, d) dag_attach_stream(a, b, c, d)
+#define dag_get_stream_poll64(a, b, c, d, e) dag_get_stream_poll(a, b, c, d, e)
+#define dag_set_stream_poll64(a, b, c, d, e) dag_set_stream_poll(a, b, c, d, e)
+#define dag_size_t uint32_t
+#endif
+
static int dag_setfilter(pcap_t *p, struct bpf_program *fp);
static int dag_stats(pcap_t *p, struct pcap_stat *ps);
static int dag_set_datalink(pcap_t *p, int dlt);
static int dag_get_datalink(pcap_t *p);
-static int dag_setnonblock(pcap_t *p, int nonblock, char *errbuf);
+static int dag_setnonblock(pcap_t *p, int nonblock);
static void
delete_pcap_dag(pcap_t *p)
@@ -237,26 +248,22 @@ delete_pcap_dag(pcap_t *p)
static void
dag_platform_cleanup(pcap_t *p)
{
- struct pcap_dag *pd = p->pr;
+ struct pcap_dag *pd = p->priv;
-#ifdef HAVE_DAG_STREAMS_API
if(dag_stop_stream(p->fd, pd->dag_stream) < 0)
fprintf(stderr,"dag_stop_stream: %s\n", strerror(errno));
if(dag_detach_stream(p->fd, pd->dag_stream) < 0)
fprintf(stderr,"dag_detach_stream: %s\n", strerror(errno));
-#else
- if(dag_stop(p->fd) < 0)
- fprintf(stderr,"dag_stop: %s\n", strerror(errno));
-#endif /* HAVE_DAG_STREAMS_API */
- if(p->fd != -1) {
- if(dag_close(p->fd) < 0)
- fprintf(stderr,"dag_close: %s\n", strerror(errno));
+
+ if(pd->dag_ref != NULL) {
+ dag_config_dispose(pd->dag_ref);
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) here as dag_close(p->fd) does this. */
+ /* 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
@@ -337,8 +344,7 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
{
struct pcap_dag *pd = p->priv;
unsigned int processed = 0;
- int flags = pd->dag_offset_flags;
- unsigned int nonblocking = flags & DAGF_NONBLOCK;
+ unsigned int nonblocking = pd->dag_flags & DAGF_NONBLOCK;
unsigned int num_ext_hdr = 0;
unsigned int ticks_per_second;
@@ -358,7 +364,6 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
return -2;
}
-#ifdef HAVE_DAG_STREAMS_API
/* dag_advance_stream() will block (unless nonblock is called)
* until 64kB of data has accumulated.
* If to_ms is set, it will timeout before 64kB has accumulated.
@@ -373,10 +378,6 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
if ( NULL == (pd->dag_mem_top = dag_advance_stream(p->fd, pd->dag_stream, &(pd->dag_mem_bottom))) ) {
return -1;
}
-#else
- /* dag_offset does not support timeouts */
- pd->dag_mem_top = dag_offset(p->fd, &(pd->dag_mem_bottom), flags);
-#endif /* HAVE_DAG_STREAMS_API */
if (nonblocking && (pd->dag_mem_top - pd->dag_mem_bottom < dag_record_size))
{
@@ -401,11 +402,7 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
int caplen = 0;
struct pcap_pkthdr pcap_header;
-#ifdef HAVE_DAG_STREAMS_API
dag_record_t *header = (dag_record_t *)(pd->dag_mem_bottom);
-#else
- dag_record_t *header = (dag_record_t *)(pd->dag_mem_base + pd->dag_mem_bottom);
-#endif /* HAVE_DAG_STREAMS_API */
u_char *dp = ((u_char *)header); /* + dag_record_size; */
unsigned short rlen;
@@ -434,26 +431,22 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
/* Count lost packets. */
switch((header->type & 0x7f)) {
/* in these types the color value overwrites the lctr */
- case TYPE_COLOR_HDLC_POS:
- case TYPE_COLOR_ETH:
- case TYPE_DSM_COLOR_HDLC_POS:
- case TYPE_DSM_COLOR_ETH:
- case TYPE_COLOR_MC_HDLC_POS:
- case TYPE_COLOR_HASH_ETH:
- case TYPE_COLOR_HASH_POS:
+ case ERF_TYPE_COLOR_HDLC_POS:
+ case ERF_TYPE_COLOR_ETH:
+ case ERF_TYPE_DSM_COLOR_HDLC_POS:
+ case ERF_TYPE_DSM_COLOR_ETH:
+ case ERF_TYPE_COLOR_MC_HDLC_POS:
+ case ERF_TYPE_COLOR_HASH_ETH:
+ case ERF_TYPE_COLOR_HASH_POS:
break;
default:
- if (header->lctr) {
- if (pd->stat.ps_drop > (UINT_MAX - ntohs(header->lctr))) {
- pd->stat.ps_drop = UINT_MAX;
- } else {
- pd->stat.ps_drop += ntohs(header->lctr);
- }
+ if ( (pd->drop_attr == kNullAttributeUuid) && (header->lctr) ) {
+ pd->stat.ps_drop += ntohs(header->lctr);
}
}
- if ((header->type & 0x7f) == TYPE_PAD) {
+ if ((header->type & 0x7f) == ERF_TYPE_PAD) {
continue;
}
@@ -477,20 +470,20 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
packet_len = ntohs(header->wlen) + dag_record_size;
caplen = rlen;
switch ((header->type & 0x7f)) {
- case TYPE_MC_AAL5:
- case TYPE_MC_ATM:
- case TYPE_MC_HDLC:
- case TYPE_MC_RAW_CHANNEL:
- case TYPE_MC_RAW:
- case TYPE_MC_AAL2:
- case TYPE_COLOR_MC_HDLC_POS:
+ case ERF_TYPE_MC_AAL5:
+ case ERF_TYPE_MC_ATM:
+ case ERF_TYPE_MC_HDLC:
+ case ERF_TYPE_MC_RAW_CHANNEL:
+ case ERF_TYPE_MC_RAW:
+ case ERF_TYPE_MC_AAL2:
+ case ERF_TYPE_COLOR_MC_HDLC_POS:
packet_len += 4; /* MC header */
break;
- case TYPE_COLOR_HASH_ETH:
- case TYPE_DSM_COLOR_ETH:
- case TYPE_COLOR_ETH:
- case TYPE_ETH:
+ case ERF_TYPE_COLOR_HASH_ETH:
+ case ERF_TYPE_DSM_COLOR_ETH:
+ case ERF_TYPE_COLOR_ETH:
+ case ERF_TYPE_ETH:
packet_len += 2; /* ETH header */
break;
} /* switch type */
@@ -510,19 +503,19 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
dp += 8 * num_ext_hdr;
switch((header->type & 0x7f)) {
- case TYPE_ATM:
- case TYPE_AAL5:
- if (header->type == TYPE_AAL5) {
+ case ERF_TYPE_ATM:
+ case ERF_TYPE_AAL5:
+ if ((header->type & 0x7f) == ERF_TYPE_AAL5) {
packet_len = ntohs(header->wlen);
caplen = rlen - dag_record_size;
}
- case TYPE_MC_ATM:
- if (header->type == TYPE_MC_ATM) {
+ case ERF_TYPE_MC_ATM:
+ if ((header->type & 0x7f) == ERF_TYPE_MC_ATM) {
caplen = packet_len = ATM_CELL_SIZE;
dp+=4;
}
- case TYPE_MC_AAL5:
- if (header->type == TYPE_MC_AAL5) {
+ case ERF_TYPE_MC_AAL5:
+ if ((header->type & 0x7f) == ERF_TYPE_MC_AAL5) {
packet_len = ntohs(header->wlen);
caplen = rlen - dag_record_size - 4;
dp+=4;
@@ -530,7 +523,7 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
/* Skip over extension headers */
caplen -= (8 * num_ext_hdr);
- if (header->type == TYPE_ATM) {
+ if ((header->type & 0x7f) == ERF_TYPE_ATM) {
caplen = packet_len = ATM_CELL_SIZE;
}
if (p->linktype == DLT_SUNATM) {
@@ -547,17 +540,21 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
dp[ATM_HDR_SIZE+1] == 0xaa &&
dp[ATM_HDR_SIZE+2] == 0x03) ? 2 : 1)));
- } else {
+ } else if (p->linktype == DLT_ATM_RFC1483) {
packet_len -= ATM_HDR_SIZE;
caplen -= ATM_HDR_SIZE;
dp += ATM_HDR_SIZE;
- }
+ } else
+ continue;
break;
- case TYPE_COLOR_HASH_ETH:
- case TYPE_DSM_COLOR_ETH:
- case TYPE_COLOR_ETH:
- case TYPE_ETH:
+ case ERF_TYPE_COLOR_HASH_ETH:
+ case ERF_TYPE_DSM_COLOR_ETH:
+ case ERF_TYPE_COLOR_ETH:
+ case ERF_TYPE_ETH:
+ if ((p->linktype != DLT_EN10MB) &&
+ (p->linktype != DLT_DOCSIS))
+ continue;
packet_len = ntohs(header->wlen);
packet_len -= (pd->dag_fcs_bits >> 3);
caplen = rlen - dag_record_size - 2;
@@ -569,10 +566,14 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
dp += 2;
break;
- case TYPE_COLOR_HASH_POS:
- case TYPE_DSM_COLOR_HDLC_POS:
- case TYPE_COLOR_HDLC_POS:
- case TYPE_HDLC_POS:
+ case ERF_TYPE_COLOR_HASH_POS:
+ case ERF_TYPE_DSM_COLOR_HDLC_POS:
+ case ERF_TYPE_COLOR_HDLC_POS:
+ case ERF_TYPE_HDLC_POS:
+ if ((p->linktype != DLT_CHDLC) &&
+ (p->linktype != DLT_PPP_SERIAL) &&
+ (p->linktype != DLT_FRELAY))
+ continue;
packet_len = ntohs(header->wlen);
packet_len -= (pd->dag_fcs_bits >> 3);
caplen = rlen - dag_record_size;
@@ -583,8 +584,15 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
}
break;
- case TYPE_COLOR_MC_HDLC_POS:
- case TYPE_MC_HDLC:
+ case ERF_TYPE_COLOR_MC_HDLC_POS:
+ case ERF_TYPE_MC_HDLC:
+ if ((p->linktype != DLT_CHDLC) &&
+ (p->linktype != DLT_PPP_SERIAL) &&
+ (p->linktype != DLT_FRELAY) &&
+ (p->linktype != DLT_MTP2) &&
+ (p->linktype != DLT_MTP2_WITH_PHDR) &&
+ (p->linktype != DLT_LAPD))
+ continue;
packet_len = ntohs(header->wlen);
packet_len -= (pd->dag_fcs_bits >> 3);
caplen = rlen - dag_record_size - 4;
@@ -611,8 +619,23 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
#endif
break;
- case TYPE_IPV4:
- case TYPE_IPV6:
+ case ERF_TYPE_IPV4:
+ if ((p->linktype != DLT_RAW) &&
+ (p->linktype != DLT_IPV4))
+ continue;
+ packet_len = ntohs(header->wlen);
+ caplen = rlen - dag_record_size;
+ /* Skip over extension headers */
+ caplen -= (8 * num_ext_hdr);
+ if (caplen > packet_len) {
+ caplen = packet_len;
+ }
+ break;
+
+ case ERF_TYPE_IPV6:
+ if ((p->linktype != DLT_RAW) &&
+ (p->linktype != DLT_IPV6))
+ continue;
packet_len = ntohs(header->wlen);
caplen = rlen - dag_record_size;
/* Skip over extension headers */
@@ -623,13 +646,13 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
break;
/* These types have no matching 'native' DLT, but can be used with DLT_ERF above */
- case TYPE_MC_RAW:
- case TYPE_MC_RAW_CHANNEL:
- case TYPE_IP_COUNTER:
- case TYPE_TCP_FLOW_COUNTER:
- case TYPE_INFINIBAND:
- case TYPE_RAW_LINK:
- case TYPE_INFINIBAND_LINK:
+ case ERF_TYPE_MC_RAW:
+ case ERF_TYPE_MC_RAW_CHANNEL:
+ case ERF_TYPE_IP_COUNTER:
+ case ERF_TYPE_TCP_FLOW_COUNTER:
+ case ERF_TYPE_INFINIBAND:
+ case ERF_TYPE_RAW_LINK:
+ case ERF_TYPE_INFINIBAND_LINK:
default:
/* Unhandled ERF type.
* Ignore rather than generating error
@@ -715,86 +738,103 @@ dag_inject(pcap_t *p, const void *buf _U_, size_t size _U_)
*
* See also pcap(3).
*/
-static int dag_activate(pcap_t* handle)
+static int dag_activate(pcap_t* p)
{
- struct pcap_dag *handlep = handle->priv;
-#if 0
- char conf[30]; /* dag configure string */
-#endif
+ struct pcap_dag *pd = p->priv;
char *s;
int n;
daginf_t* daginf;
char * newDev = NULL;
- char * device = handle->opt.device;
-#ifdef HAVE_DAG_STREAMS_API
- uint32_t mindata;
+ char * device = p->opt.device;
+ dag_size_t mindata;
struct timeval maxwait;
struct timeval poll;
-#endif
if (device == NULL) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "device is NULL: %s", pcap_strerror(errno));
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "device is NULL");
return -1;
}
/* Initialize some components of the pcap structure. */
-
-#ifdef HAVE_DAG_STREAMS_API
newDev = (char *)malloc(strlen(device) + 16);
if (newDev == NULL) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't allocate string for device name: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "Can't allocate string for device name");
goto fail;
}
/* Parse input name to get dag device and stream number if provided */
- if (dag_parse_name(device, newDev, strlen(device) + 16, &handlep->dag_stream) < 0) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_parse_name: %s", pcap_strerror(errno));
+ if (dag_parse_name(device, newDev, strlen(device) + 16, &pd->dag_stream) < 0) {
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "dag_parse_name");
goto fail;
}
device = newDev;
- if (handlep->dag_stream%2) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_parse_name: tx (even numbered) streams not supported for capture");
+ if (pd->dag_stream%2) {
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "dag_parse_name: tx (even numbered) streams not supported for capture");
goto fail;
}
-#else
- if (strncmp(device, "/dev/", 5) != 0) {
- newDev = (char *)malloc(strlen(device) + 5);
- if (newDev == NULL) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't allocate string for device name: %s", pcap_strerror(errno));
- goto fail;
- }
- strcpy(newDev, "/dev/");
- strcat(newDev, device);
- device = newDev;
- }
-#endif /* HAVE_DAG_STREAMS_API */
/* setup device parameters */
- if((handle->fd = dag_open((char *)device)) < 0) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_open %s: %s", device, pcap_strerror(errno));
+ if((pd->dag_ref = dag_config_init((char *)device)) == NULL) {
+ 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) {
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "dag_config_get_card_fd %s", device);
goto fail;
}
-#ifdef HAVE_DAG_STREAMS_API
/* Open requested stream. Can fail if already locked or on error */
- if (dag_attach_stream(handle->fd, handlep->dag_stream, 0, 0) < 0) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_attach_stream: %s", pcap_strerror(errno));
+ if (dag_attach_stream64(p->fd, pd->dag_stream, 0, 0) < 0) {
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "dag_attach_stream");
goto failclose;
}
+ /* Try to find Stream Drop attribute */
+ pd->drop_attr = kNullAttributeUuid;
+ pd->dag_root = dag_config_get_root_component(pd->dag_ref);
+ if ( dag_component_get_subcomponent(pd->dag_root, kComponentStreamFeatures, 0) )
+ {
+ pd->drop_attr = dag_config_get_indexed_attribute_uuid(pd->dag_ref, kUint32AttributeStreamDropCount, pd->dag_stream/2);
+ }
+
/* Set up default poll parameters for stream
* Can be overridden by pcap_set_nonblock()
*/
- if (dag_get_stream_poll(handle->fd, handlep->dag_stream,
+ if (dag_get_stream_poll64(p->fd, pd->dag_stream,
&mindata, &maxwait, &poll) < 0) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_get_stream_poll: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "dag_get_stream_poll");
goto faildetach;
}
- if (handle->opt.immediate) {
+ /* Use the poll time as the required select timeout for callers
+ * who are using select()/etc. in an event loop waiting for
+ * packets to arrive.
+ */
+ pd->required_select_timeout = poll;
+ p->required_select_timeout = &pd->required_select_timeout;
+
+ /*
+ * Turn a negative snapshot value (invalid), a snapshot value of
+ * 0 (unspecified), or a value bigger than the normal maximum
+ * value, into the maximum allowed value.
+ *
+ * If some application really *needs* a bigger snapshot
+ * length, we should just increase MAXIMUM_SNAPLEN.
+ */
+ if (p->snapshot <= 0 || p->snapshot > MAXIMUM_SNAPLEN)
+ p->snapshot = MAXIMUM_SNAPLEN;
+
+ if (p->opt.immediate) {
/* Call callback immediately.
- * XXX - is this the right way to handle this?
+ * XXX - is this the right way to p this?
*/
mindata = 0;
} else {
@@ -808,23 +848,16 @@ static int dag_activate(pcap_t* handle)
/* Obey opt.timeout (was to_ms) if supplied. This is a good idea!
* Recommend 10-100ms. Calls will time out even if no data arrived.
*/
- maxwait.tv_sec = handle->opt.timeout/1000;
- maxwait.tv_usec = (handle->opt.timeout%1000) * 1000;
+ maxwait.tv_sec = p->opt.timeout/1000;
+ maxwait.tv_usec = (p->opt.timeout%1000) * 1000;
- if (dag_set_stream_poll(handle->fd, handlep->dag_stream,
+ if (dag_set_stream_poll64(p->fd, pd->dag_stream,
mindata, &maxwait, &poll) < 0) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_set_stream_poll: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "dag_set_stream_poll");
goto faildetach;
}
-#else
- if((handlep->dag_mem_base = dag_mmap(handle->fd)) == MAP_FAILED) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,"dag_mmap %s: %s", device, pcap_strerror(errno));
- goto failclose;
- }
-
-#endif /* HAVE_DAG_STREAMS_API */
-
/* XXX Not calling dag_configure() to set slen; this is unsafe in
* multi-stream environments as the gpp config is global.
* Once the firmware provides 'per-stream slen' this can be supported
@@ -833,63 +866,51 @@ static int dag_activate(pcap_t* handle)
/* set the card snap length to the specified snaplen parameter */
/* This is a really bad idea, as different cards have different
* valid slen ranges. Should fix in Config API. */
- if (handle->snapshot == 0 || handle->snapshot > MAX_DAG_SNAPLEN) {
- handle->snapshot = MAX_DAG_SNAPLEN;
+ if (p->snapshot == 0 || p->snapshot > MAX_DAG_SNAPLEN) {
+ p->snapshot = MAX_DAG_SNAPLEN;
} else if (snaplen < MIN_DAG_SNAPLEN) {
- handle->snapshot = MIN_DAG_SNAPLEN;
+ p->snapshot = MIN_DAG_SNAPLEN;
}
/* snap len has to be a multiple of 4 */
- pcap_snprintf(conf, 30, "varlen slen=%d", (snaplen + 3) & ~3);
-
- if(dag_configure(handle->fd, conf) < 0) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,"dag_configure %s: %s", device, pcap_strerror(errno));
- goto faildetach;
- }
#endif
-#ifdef HAVE_DAG_STREAMS_API
- if(dag_start_stream(handle->fd, handlep->dag_stream) < 0) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_start_stream %s: %s", device, pcap_strerror(errno));
+ if(dag_start_stream(p->fd, pd->dag_stream) < 0) {
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "dag_start_stream %s", device);
goto faildetach;
}
-#else
- if(dag_start(handle->fd) < 0) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_start %s: %s", device, pcap_strerror(errno));
- goto failclose;
- }
-#endif /* HAVE_DAG_STREAMS_API */
/*
* Important! You have to ensure bottom is properly
* initialized to zero on startup, it won't give you
* a compiler warning if you make this mistake!
*/
- handlep->dag_mem_bottom = 0;
- handlep->dag_mem_top = 0;
+ pd->dag_mem_bottom = 0;
+ pd->dag_mem_top = 0;
/*
* Find out how many FCS bits we should strip.
* First, query the card to see if it strips the FCS.
*/
- daginf = dag_info(handle->fd);
+ daginf = dag_info(p->fd);
if ((0x4200 == daginf->device_code) || (0x4230 == daginf->device_code)) {
/* DAG 4.2S and 4.23S already strip the FCS. Stripping the final word again truncates the packet. */
- handlep->dag_fcs_bits = 0;
+ pd->dag_fcs_bits = 0;
/* Note that no FCS will be supplied. */
- handle->linktype_ext = LT_FCS_DATALINK_EXT(0);
+ p->linktype_ext = LT_FCS_DATALINK_EXT(0);
} else {
/*
* Start out assuming it's 32 bits.
*/
- handlep->dag_fcs_bits = 32;
+ pd->dag_fcs_bits = 32;
/* Allow an environment variable to override. */
if ((s = getenv("ERF_FCS_BITS")) != NULL) {
if ((n = atoi(s)) == 0 || n == 16 || n == 32) {
- handlep->dag_fcs_bits = n;
+ pd->dag_fcs_bits = n;
} else {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"pcap_activate %s: bad ERF_FCS_BITS value (%d) in environment", device, n);
goto failstop;
}
@@ -901,71 +922,65 @@ static int dag_activate(pcap_t* handle)
if ((s = getenv("ERF_DONT_STRIP_FCS")) != NULL) {
/* Yes. Note the number of bytes that will be
supplied. */
- handle->linktype_ext = LT_FCS_DATALINK_EXT(handlep->dag_fcs_bits/16);
+ p->linktype_ext = LT_FCS_DATALINK_EXT(pd->dag_fcs_bits/16);
/* And don't strip them. */
- handlep->dag_fcs_bits = 0;
+ pd->dag_fcs_bits = 0;
}
}
- handlep->dag_timeout = handle->opt.timeout;
+ pd->dag_timeout = p->opt.timeout;
- handle->linktype = -1;
- if (dag_get_datalink(handle) < 0)
+ p->linktype = -1;
+ if (dag_get_datalink(p) < 0)
goto failstop;
- handle->bufsize = 0;
+ p->bufsize = 0;
- if (new_pcap_dag(handle) < 0) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "new_pcap_dag %s: %s", device, pcap_strerror(errno));
+ if (new_pcap_dag(p) < 0) {
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "new_pcap_dag %s", device);
goto failstop;
}
/*
* "select()" and "poll()" don't work on DAG device descriptors.
*/
- handle->selectable_fd = -1;
+ p->selectable_fd = -1;
if (newDev != NULL) {
free((char *)newDev);
}
- handle->read_op = dag_read;
- handle->inject_op = dag_inject;
- handle->setfilter_op = dag_setfilter;
- handle->setdirection_op = NULL; /* Not implemented.*/
- handle->set_datalink_op = dag_set_datalink;
- handle->getnonblock_op = pcap_getnonblock_fd;
- handle->setnonblock_op = dag_setnonblock;
- handle->stats_op = dag_stats;
- handle->cleanup_op = dag_platform_cleanup;
- handlep->stat.ps_drop = 0;
- handlep->stat.ps_recv = 0;
- handlep->stat.ps_ifdrop = 0;
+ p->read_op = dag_read;
+ p->inject_op = dag_inject;
+ p->setfilter_op = dag_setfilter;
+ p->setdirection_op = NULL; /* Not implemented.*/
+ p->set_datalink_op = dag_set_datalink;
+ p->getnonblock_op = pcap_getnonblock_fd;
+ p->setnonblock_op = dag_setnonblock;
+ p->stats_op = dag_stats;
+ p->cleanup_op = dag_platform_cleanup;
+ pd->stat.ps_drop = 0;
+ pd->stat.ps_recv = 0;
+ pd->stat.ps_ifdrop = 0;
return 0;
-#ifdef HAVE_DAG_STREAMS_API
failstop:
- if (dag_stop_stream(handle->fd, handlep->dag_stream) < 0) {
+ if (dag_stop_stream(p->fd, pd->dag_stream) < 0) {
fprintf(stderr,"dag_stop_stream: %s\n", strerror(errno));
}
faildetach:
- if (dag_detach_stream(handle->fd, handlep->dag_stream) < 0)
+ if (dag_detach_stream(p->fd, pd->dag_stream) < 0)
fprintf(stderr,"dag_detach_stream: %s\n", strerror(errno));
-#else
-failstop:
- if (dag_stop(handle->fd) < 0)
- fprintf(stderr,"dag_stop: %s\n", strerror(errno));
-#endif /* HAVE_DAG_STREAMS_API */
failclose:
- if (dag_close(handle->fd) < 0)
- fprintf(stderr,"dag_close: %s\n", strerror(errno));
- delete_pcap_dag(handle);
+ dag_config_dispose(pd->dag_ref);
+ delete_pcap_dag(p);
fail:
- pcap_cleanup_live_common(handle);
+ pcap_cleanup_live_common(p);
if (newDev != NULL) {
free((char *)newDev);
}
@@ -979,9 +994,7 @@ pcap_t *dag_create(const char *device, char *ebuf, int *is_ours)
char *cpend;
long devnum;
pcap_t *p;
-#ifdef HAVE_DAG_STREAMS_API
long stream = 0;
-#endif
/* Does this look like a DAG device? */
cp = strrchr(device, '/');
@@ -996,29 +1009,28 @@ pcap_t *dag_create(const char *device, char *ebuf, int *is_ours)
/* Yes - is "dag" followed by a number from 0 to DAG_MAX_BOARDS-1 */
cp += 3;
devnum = strtol(cp, &cpend, 10);
-#ifdef HAVE_DAG_STREAMS_API
if (*cpend == ':') {
/* Followed by a stream number. */
stream = strtol(++cpend, &cpend, 10);
}
-#endif
+
if (cpend == cp || *cpend != '\0') {
/* Not followed by a number. */
*is_ours = 0;
return NULL;
}
+
if (devnum < 0 || devnum >= DAG_MAX_BOARDS) {
/* Followed by a non-valid number. */
*is_ours = 0;
return NULL;
}
-#ifdef HAVE_DAG_STREAMS_API
+
if (stream <0 || stream >= DAG_STREAM_MAX) {
/* Followed by a non-valid stream number. */
*is_ours = 0;
return NULL;
}
-#endif
/* OK, it's probably ours. */
*is_ours = 1;
@@ -1039,8 +1051,8 @@ pcap_t *dag_create(const char *device, char *ebuf, int *is_ours)
p->tstamp_precision_count = 2;
p->tstamp_precision_list = malloc(2 * sizeof(u_int));
if (p->tstamp_precision_list == NULL) {
- pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
+ errno, "malloc");
pcap_close(p);
return NULL;
}
@@ -1052,12 +1064,28 @@ pcap_t *dag_create(const char *device, char *ebuf, int *is_ours)
static int
dag_stats(pcap_t *p, struct pcap_stat *ps) {
struct pcap_dag *pd = p->priv;
+ uint32_t stream_drop;
+ dag_err_t dag_error;
+
+ /*
+ * Packet records received (ps_recv) are counted in dag_read().
+ * Packet records dropped (ps_drop) are read from Stream Drop attribute if present,
+ * otherwise integrate the ERF Header lctr counts (if available) in dag_read().
+ * We are reporting that no records are dropped by the card/driver (ps_ifdrop).
+ */
- /* This needs to be filled out correctly. Hopefully a dagapi call will
- provide all necessary information.
- */
- /*pd->stat.ps_recv = 0;*/
- /*pd->stat.ps_drop = 0;*/
+ if(pd->drop_attr != kNullAttributeUuid) {
+ /* Note this counter is cleared at start of capture and will wrap at UINT_MAX.
+ * The application is responsible for polling ps_drop frequently enough
+ * to detect each wrap and integrate total drop with a wider counter */
+ if ((dag_error = dag_config_get_uint32_attribute_ex(pd->dag_ref, pd->drop_attr, &stream_drop) == kDagErrNone)) {
+ pd->stat.ps_drop = stream_drop;
+ } else {
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "reading stream drop attribute: %s",
+ dag_config_strerror(dag_error));
+ return -1;
+ }
+ }
*ps = pd->stat;
@@ -1065,72 +1093,72 @@ dag_stats(pcap_t *p, struct pcap_stat *ps) {
}
/*
- * Previously we just generated a list of all possible names and let
- * pcap_add_if() attempt to open each one, but with streams this adds up
- * to 81 possibilities which is inefficient.
- *
- * Since we know more about the devices we can prune the tree here.
- * pcap_add_if() will still retest each device but the total number of
- * open attempts will still be much less than the naive approach.
+ * Add all DAG devices.
*/
int
-dag_findalldevs(pcap_if_t **devlistp, char *errbuf)
+dag_findalldevs(pcap_if_list_t *devlistp, char *errbuf)
{
char name[12]; /* XXX - pick a size */
- int ret = 0;
int c;
char dagname[DAGNAME_BUFSIZE];
int dagstream;
int dagfd;
dag_card_inf_t *inf;
char *description;
+ int stream, rxstreams;
/* Try all the DAGs 0-DAG_MAX_BOARDS */
for (c = 0; c < DAG_MAX_BOARDS; c++) {
pcap_snprintf(name, 12, "dag%d", c);
if (-1 == dag_parse_name(name, dagname, DAGNAME_BUFSIZE, &dagstream))
{
- return -1;
+ (void) pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "dag: device name %s can't be parsed", name);
+ return (-1);
}
- description = NULL;
if ( (dagfd = dag_open(dagname)) >= 0 ) {
+ description = NULL;
if ((inf = dag_pciinfo(dagfd)))
description = dag_device_name(inf->device_code, 1);
- if (pcap_add_if(devlistp, name, 0, description, errbuf) == -1) {
+ /*
+ * XXX - is there a way to determine whether
+ * the card is plugged into a network or not?
+ * If so, we should check that and set
+ * PCAP_IF_CONNECTION_STATUS_CONNECTED or
+ * PCAP_IF_CONNECTION_STATUS_DISCONNECTED.
+ *
+ * Also, are there notions of "up" and "running"?
+ */
+ if (add_dev(devlistp, name, 0, description, errbuf) == NULL) {
/*
* Failure.
*/
- ret = -1;
+ return (-1);
}
-#ifdef HAVE_DAG_STREAMS_API
- {
- int stream, rxstreams;
- 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)) {
- dag_detach_stream(dagfd, stream);
-
- pcap_snprintf(name, 10, "dag%d:%d", c, stream);
- if (pcap_add_if(devlistp, name, 0, description, errbuf) == -1) {
- /*
- * Failure.
- */
- ret = -1;
- }
-
- rxstreams--;
- if(rxstreams <= 0) {
- break;
- }
+ 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)) {
+ dag_detach_stream(dagfd, stream);
+
+ pcap_snprintf(name, 10, "dag%d:%d", c, stream);
+ if (add_dev(devlistp, name, 0, description, errbuf) == NULL) {
+ /*
+ * Failure.
+ */
+ return (-1);
+ }
+
+ rxstreams--;
+ if(rxstreams <= 0) {
+ break;
}
}
}
-#endif /* HAVE_DAG_STREAMS_API */
dag_close(dagfd);
}
}
- return (ret);
+ return (0);
}
/*
@@ -1166,50 +1194,49 @@ dag_set_datalink(pcap_t *p, int dlt)
}
static int
-dag_setnonblock(pcap_t *p, int nonblock, char *errbuf)
+dag_setnonblock(pcap_t *p, int nonblock)
{
struct pcap_dag *pd = p->priv;
+ dag_size_t mindata;
+ struct timeval maxwait;
+ struct timeval poll;
/*
* Set non-blocking mode on the FD.
* XXX - is that necessary? If not, don't bother calling it,
* and have a "dag_getnonblock()" function that looks at
- * "pd->dag_offset_flags".
+ * "pd->dag_flags".
*/
- if (pcap_setnonblock_fd(p, nonblock, errbuf) < 0)
+ if (pcap_setnonblock_fd(p, nonblock) < 0)
return (-1);
-#ifdef HAVE_DAG_STREAMS_API
- {
- uint32_t mindata;
- struct timeval maxwait;
- struct timeval poll;
- if (dag_get_stream_poll(p->fd, pd->dag_stream,
- &mindata, &maxwait, &poll) < 0) {
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "dag_get_stream_poll: %s", pcap_strerror(errno));
- return -1;
- }
+ if (dag_get_stream_poll64(p->fd, pd->dag_stream,
+ &mindata, &maxwait, &poll) < 0) {
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "dag_get_stream_poll");
+ return -1;
+ }
- /* Amount of data to collect in Bytes before calling callbacks.
- * Important for efficiency, but can introduce latency
- * at low packet rates if to_ms not set!
- */
- if(nonblock)
- mindata = 0;
- else
- mindata = 65536;
-
- if (dag_set_stream_poll(p->fd, pd->dag_stream,
- mindata, &maxwait, &poll) < 0) {
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "dag_set_stream_poll: %s", pcap_strerror(errno));
- return -1;
- }
+ /* Amount of data to collect in Bytes before calling callbacks.
+ * Important for efficiency, but can introduce latency
+ * at low packet rates if to_ms not set!
+ */
+ if(nonblock)
+ mindata = 0;
+ else
+ mindata = 65536;
+
+ if (dag_set_stream_poll64(p->fd, pd->dag_stream,
+ mindata, &maxwait, &poll) < 0) {
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "dag_set_stream_poll");
+ return -1;
}
-#endif /* HAVE_DAG_STREAMS_API */
+
if (nonblock) {
- pd->dag_offset_flags |= DAGF_NONBLOCK;
+ pd->dag_flags |= DAGF_NONBLOCK;
} else {
- pd->dag_offset_flags &= ~DAGF_NONBLOCK;
+ pd->dag_flags &= ~DAGF_NONBLOCK;
}
return (0);
}
@@ -1224,7 +1251,8 @@ dag_get_datalink(pcap_t *p)
memset(types, 0, 255);
if (p->dlt_list == NULL && (p->dlt_list = malloc(255*sizeof(*(p->dlt_list)))) == NULL) {
- (void)pcap_snprintf(p->errbuf, sizeof(p->errbuf), "malloc: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, sizeof(p->errbuf),
+ errno, "malloc");
return (-1);
}
@@ -1233,7 +1261,8 @@ dag_get_datalink(pcap_t *p)
#ifdef HAVE_DAG_GET_STREAM_ERF_TYPES
/* Get list of possible ERF types for this card */
if (dag_get_stream_erf_types(p->fd, pd->dag_stream, types, 255) < 0) {
- pcap_snprintf(p->errbuf, sizeof(p->errbuf), "dag_get_stream_erf_types: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, sizeof(p->errbuf),
+ errno, "dag_get_stream_erf_types");
return (-1);
}
@@ -1242,7 +1271,8 @@ dag_get_datalink(pcap_t *p)
#elif defined HAVE_DAG_GET_ERF_TYPES
/* Get list of possible ERF types for this card */
if (dag_get_erf_types(p->fd, types, 255) < 0) {
- pcap_snprintf(p->errbuf, sizeof(p->errbuf), "dag_get_erf_types: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, sizeof(p->errbuf),
+ errno, "dag_get_erf_types");
return (-1);
}
@@ -1255,10 +1285,10 @@ dag_get_datalink(pcap_t *p)
#endif
switch((types[index] & 0x7f)) {
- case TYPE_HDLC_POS:
- case TYPE_COLOR_HDLC_POS:
- case TYPE_DSM_COLOR_HDLC_POS:
- case TYPE_COLOR_HASH_POS:
+ case ERF_TYPE_HDLC_POS:
+ case ERF_TYPE_COLOR_HDLC_POS:
+ case ERF_TYPE_DSM_COLOR_HDLC_POS:
+ case ERF_TYPE_COLOR_HASH_POS:
if (p->dlt_list != NULL) {
p->dlt_list[dlt_index++] = DLT_CHDLC;
@@ -1269,10 +1299,10 @@ dag_get_datalink(pcap_t *p)
p->linktype = DLT_CHDLC;
break;
- case TYPE_ETH:
- case TYPE_COLOR_ETH:
- case TYPE_DSM_COLOR_ETH:
- case TYPE_COLOR_HASH_ETH:
+ case ERF_TYPE_ETH:
+ case ERF_TYPE_COLOR_ETH:
+ case ERF_TYPE_DSM_COLOR_ETH:
+ case ERF_TYPE_COLOR_HASH_ETH:
/*
* This is (presumably) a real Ethernet capture; give it a
* link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so
@@ -1291,10 +1321,10 @@ dag_get_datalink(pcap_t *p)
p->linktype = DLT_EN10MB;
break;
- case TYPE_ATM:
- case TYPE_AAL5:
- case TYPE_MC_ATM:
- case TYPE_MC_AAL5:
+ case ERF_TYPE_ATM:
+ case ERF_TYPE_AAL5:
+ case ERF_TYPE_MC_ATM:
+ case ERF_TYPE_MC_AAL5:
if (p->dlt_list != NULL) {
p->dlt_list[dlt_index++] = DLT_ATM_RFC1483;
p->dlt_list[dlt_index++] = DLT_SUNATM;
@@ -1303,8 +1333,8 @@ dag_get_datalink(pcap_t *p)
p->linktype = DLT_ATM_RFC1483;
break;
- case TYPE_COLOR_MC_HDLC_POS:
- case TYPE_MC_HDLC:
+ case ERF_TYPE_COLOR_MC_HDLC_POS:
+ case ERF_TYPE_MC_HDLC:
if (p->dlt_list != NULL) {
p->dlt_list[dlt_index++] = DLT_CHDLC;
p->dlt_list[dlt_index++] = DLT_PPP_SERIAL;
@@ -1317,20 +1347,33 @@ dag_get_datalink(pcap_t *p)
p->linktype = DLT_CHDLC;
break;
- case TYPE_IPV4:
- case TYPE_IPV6:
+ case ERF_TYPE_IPV4:
+ if (p->dlt_list != NULL) {
+ p->dlt_list[dlt_index++] = DLT_RAW;
+ p->dlt_list[dlt_index++] = DLT_IPV4;
+ }
if(!p->linktype)
p->linktype = DLT_RAW;
break;
- case TYPE_LEGACY:
- case TYPE_MC_RAW:
- case TYPE_MC_RAW_CHANNEL:
- case TYPE_IP_COUNTER:
- case TYPE_TCP_FLOW_COUNTER:
- case TYPE_INFINIBAND:
- case TYPE_RAW_LINK:
- case TYPE_INFINIBAND_LINK:
+ case ERF_TYPE_IPV6:
+ if (p->dlt_list != NULL) {
+ p->dlt_list[dlt_index++] = DLT_RAW;
+ p->dlt_list[dlt_index++] = DLT_IPV6;
+ }
+ if(!p->linktype)
+ p->linktype = DLT_RAW;
+ break;
+
+ case ERF_TYPE_LEGACY:
+ case ERF_TYPE_MC_RAW:
+ case ERF_TYPE_MC_RAW_CHANNEL:
+ case ERF_TYPE_IP_COUNTER:
+ case ERF_TYPE_TCP_FLOW_COUNTER:
+ case ERF_TYPE_INFINIBAND:
+ case ERF_TYPE_RAW_LINK:
+ case ERF_TYPE_INFINIBAND_LINK:
+ case ERF_TYPE_META:
default:
/* Libpcap cannot deal with these types yet */
/* Add no 'native' DLTs, but still covered by DLT_ERF */
@@ -1360,9 +1403,8 @@ dag_get_datalink(pcap_t *p)
* There are no regular interfaces, just DAG interfaces.
*/
int
-pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
+pcap_platform_finddevs(pcap_if_list_t *devlistp _U_, char *errbuf)
{
- *alldevsp = NULL;
return (0);
}
@@ -1376,4 +1418,13 @@ pcap_create_interface(const char *device, char *errbuf)
"This version of libpcap only supports DAG cards");
return NULL;
}
+
+/*
+ * Libpcap version string.
+ */
+const char *
+pcap_lib_version(void)
+{
+ return (PCAP_VERSION_STRING " (DAG-only)");
+}
#endif
diff --git a/contrib/libpcap/pcap-dag.h b/contrib/libpcap/pcap-dag.h
index dfeccd8b71169..67361af9adef9 100644
--- a/contrib/libpcap/pcap-dag.h
+++ b/contrib/libpcap/pcap-dag.h
@@ -9,4 +9,4 @@
*/
pcap_t *dag_create(const char *, char *, int *);
-int dag_findalldevs(pcap_if_t **devlistp, char *errbuf);
+int dag_findalldevs(pcap_if_list_t *devlistp, char *errbuf);
diff --git a/contrib/libpcap/pcap-dbus.c b/contrib/libpcap/pcap-dbus.c
index 8e92093da1107..1252975e9ac7b 100644
--- a/contrib/libpcap/pcap-dbus.c
+++ b/contrib/libpcap/pcap-dbus.c
@@ -29,7 +29,7 @@
*/
#ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
#endif
#include <string.h>
@@ -51,7 +51,7 @@ struct pcap_dbus {
};
static int
-dbus_read(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user)
+dbus_read(pcap_t *handle, int max_packets _U_, pcap_handler callback, u_char *user)
{
struct pcap_dbus *handlep = handle->priv;
@@ -145,6 +145,28 @@ dbus_cleanup(pcap_t *handle)
pcap_cleanup_live_common(handle);
}
+/*
+ * We don't support non-blocking mode. I'm not sure what we'd
+ * do to support it and, given that we don't support select()/
+ * poll()/epoll_wait()/kevent() etc., it probably doesn't
+ * matter.
+ */
+static int
+dbus_getnonblock(pcap_t *p)
+{
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "Non-blocking mode isn't supported for capturing on D-Bus");
+ return (-1);
+}
+
+static int
+dbus_setnonblock(pcap_t *p, int nonblock _U_)
+{
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "Non-blocking mode isn't supported for capturing on D-Bus");
+ return (-1);
+}
+
static int
dbus_activate(pcap_t *handle)
{
@@ -208,11 +230,36 @@ dbus_activate(pcap_t *handle)
handle->setfilter_op = install_bpf_program; /* XXX, later add support for dbus_bus_add_match() */
handle->setdirection_op = NULL;
handle->set_datalink_op = NULL; /* can't change data link type */
- handle->getnonblock_op = pcap_getnonblock_fd;
- handle->setnonblock_op = pcap_setnonblock_fd;
+ handle->getnonblock_op = dbus_getnonblock;
+ handle->setnonblock_op = dbus_setnonblock;
handle->stats_op = dbus_stats;
-
+ handle->cleanup_op = dbus_cleanup;
+
+#ifndef _WIN32
+ /*
+ * Unfortunately, trying to do a select()/poll()/epoll_wait()/
+ * kevent()/etc. on a D-Bus connection isn't a simple
+ * case of "give me an FD on which to wait".
+ *
+ * Apparently, you have to register "add watch", "remove watch",
+ * and "toggle watch" functions with
+ * dbus_connection_set_watch_functions(),
+ * keep a *set* of FDs, add to that set in the "add watch"
+ * function, subtract from it in the "remove watch" function,
+ * and either add to or subtract from that set in the "toggle
+ * watch" function, and do the wait on *all* of the FDs in the
+ * set. (Yes, you need the "toggle watch" function, so that
+ * the main loop doesn't itself need to check for whether
+ * a given watch is enabled or disabled - most libpcap programs
+ * know nothing about D-Bus and shouldn't *have* to know anything
+ * about D-Bus other than how to decode D-Bus messages.)
+ *
+ * Implementing that would require considerable changes in
+ * the way libpcap exports "selectable FDs" to its client.
+ * Until that's done, we just say "you can't do that".
+ */
handle->selectable_fd = handle->fd = -1;
+#endif
if (handle->opt.rfmon) {
/*
@@ -222,6 +269,14 @@ dbus_activate(pcap_t *handle)
return PCAP_ERROR_RFMON_NOTSUP;
}
+ /*
+ * Turn a negative snapshot value (invalid), a snapshot value of
+ * 0 (unspecified), or a value bigger than the normal maximum
+ * value, into the maximum message length for D-Bus (128MB).
+ */
+ if (handle->snapshot <= 0 || handle->snapshot > 134217728)
+ handle->snapshot = 134217728;
+
/* dbus_connection_set_max_message_size(handlep->conn, handle->snapshot); */
if (handle->opt.buffer_size != 0)
dbus_connection_set_max_received_size(handlep->conn, handle->opt.buffer_size);
@@ -264,15 +319,32 @@ dbus_create(const char *device, char *ebuf, int *is_ours)
return (NULL);
p->activate_op = dbus_activate;
+ /*
+ * Set these up front, so that, even if our client tries
+ * to set non-blocking mode before we're activated, or
+ * query the state of non-blocking mode, they get an error,
+ * rather than having the non-blocking mode option set
+ * for use later.
+ */
+ p->getnonblock_op = dbus_getnonblock;
+ p->setnonblock_op = dbus_setnonblock;
return (p);
}
int
-dbus_findalldevs(pcap_if_t **alldevsp, char *err_str)
+dbus_findalldevs(pcap_if_list_t *devlistp, char *err_str)
{
- if (pcap_add_if(alldevsp, "dbus-system", 0, "D-Bus system bus", err_str) < 0)
+ /*
+ * The notion of "connected" vs. "disconnected" doesn't apply.
+ * XXX - what about the notions of "up" and "running"?
+ */
+ if (add_dev(devlistp, "dbus-system",
+ PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE, "D-Bus system bus",
+ err_str) == NULL)
return -1;
- if (pcap_add_if(alldevsp, "dbus-session", 0, "D-Bus session bus", err_str) < 0)
+ if (add_dev(devlistp, "dbus-session",
+ PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE, "D-Bus session bus",
+ err_str) == NULL)
return -1;
return 0;
}
diff --git a/contrib/libpcap/pcap-dbus.h b/contrib/libpcap/pcap-dbus.h
index 67493cce93cfa..c97f2e121e6ee 100644
--- a/contrib/libpcap/pcap-dbus.h
+++ b/contrib/libpcap/pcap-dbus.h
@@ -1,2 +1,2 @@
pcap_t *dbus_create(const char *, char *, int *);
-int dbus_findalldevs(pcap_if_t **devlistp, char *errbuf);
+int dbus_findalldevs(pcap_if_list_t *devlistp, char *errbuf);
diff --git a/contrib/libpcap/pcap-dll.rc b/contrib/libpcap/pcap-dll.rc
new file mode 100644
index 0000000000000..fc4f42b26ef03
--- /dev/null
+++ b/contrib/libpcap/pcap-dll.rc
@@ -0,0 +1,36 @@
+#include "config.h"
+#include <winver.h>
+
+ VS_VERSION_INFO VERSIONINFO
+ FILEVERSION PACKAGE_VERSION_DLL
+ PRODUCTVERSION PACKAGE_VERSION_DLL
+ FILEFLAGSMASK 0x3fL
+ FILEOS VOS__WINDOWS32
+ FILETYPE VFT_DLL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "https://github.com/the-tcpdump-group/libpcap/"
+ VALUE "CompanyName", "The TCPdump Group"
+ VALUE "FileDescription", "System-Independent Interface for User-Level Packet Capture"
+ VALUE "FileVersion", "PACKAGE_VERSION_DLL"
+ VALUE "InternalName", PACKAGE_NAME
+ VALUE "LegalCopyright", "Copyright (c) The TCPdump Group"
+ VALUE "LegalTrademarks", ""
+ VALUE "OriginalFilename", "wpcap.dll"
+ VALUE "ProductName", PACKAGE_NAME
+ VALUE "ProductVersion", PACKAGE_VERSION
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x0, 1200
+ END
+ END
diff --git a/contrib/libpcap/pcap-dlpi.c b/contrib/libpcap/pcap-dlpi.c
index a431e7c1a3fa3..430051e8d5ee1 100644
--- a/contrib/libpcap/pcap-dlpi.c
+++ b/contrib/libpcap/pcap-dlpi.c
@@ -69,7 +69,7 @@
*/
#ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
#endif
#include <sys/types.h>
@@ -122,18 +122,29 @@
#include "os-proto.h"
#endif
-#ifndef PCAP_DEV_PREFIX
-#ifdef _AIX
-#define PCAP_DEV_PREFIX "/dev/dlpi"
-#else
-#define PCAP_DEV_PREFIX "/dev"
-#endif
+#if defined(__hpux)
+ /*
+ * HP-UX has a /dev/dlpi device; you open it and set the PPA of the actual
+ * network device you want.
+ */
+ #define HAVE_DEV_DLPI
+#elif defined(_AIX)
+ /*
+ * AIX has a /dev/dlpi directory, with devices named after the interfaces
+ * underneath it.
+ */
+ #define PCAP_DEV_PREFIX "/dev/dlpi"
+#elif defined(HAVE_SOLARIS)
+ /*
+ * Solaris has devices named after the interfaces underneath /dev.
+ */
+ #define PCAP_DEV_PREFIX "/dev"
#endif
#define MAXDLBUF 8192
/* Forwards */
-static char *split_dname(char *, int *, char *);
+static char *split_dname(char *, u_int *, char *);
static int dl_doattach(int, int, char *);
#ifdef DL_HP_RAWDLS
static int dl_dohpuxbind(int, char *);
@@ -145,7 +156,7 @@ static int dlokack(int, const char *, char *, char *);
static int dlinforeq(int, char *);
static int dlinfoack(int, char *, char *);
-#ifdef HAVE_DLPI_PASSIVE
+#ifdef HAVE_DL_PASSIVE_REQ_T
static void dlpassive(int, char *);
#endif
@@ -165,7 +176,7 @@ static int send_request(int, char *, int, char *, char *);
static int dlpi_kread(int, off_t, void *, u_int, char *);
#endif
#ifdef HAVE_DEV_DLPI
-static int get_dlpi_ppa(int, const char *, int, char *);
+static int get_dlpi_ppa(int, const char *, u_int, u_int *, char *);
#endif
/*
@@ -227,8 +238,8 @@ pcap_read_dlpi(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
case EAGAIN:
return (0);
}
- strlcpy(p->errbuf, pcap_strerror(errno),
- sizeof(p->errbuf));
+ pcap_fmt_errmsg_for_errno(p->errbuf,
+ sizeof(p->errbuf), errno, "getmsg");
return (-1);
}
cc = data.len;
@@ -251,8 +262,8 @@ pcap_inject_dlpi(pcap_t *p, const void *buf, size_t size)
#if defined(DLIOCRAW)
ret = write(p->fd, buf, size);
if (ret == -1) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "send");
return (-1);
}
#elif defined(DL_HP_RAWDLS)
@@ -263,8 +274,8 @@ pcap_inject_dlpi(pcap_t *p, const void *buf, size_t size)
}
ret = dlrawdatareq(pd->send_fd, buf, size);
if (ret == -1) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "send");
return (-1);
}
/*
@@ -334,13 +345,15 @@ pcap_cleanup_dlpi(pcap_t *p)
}
static int
-open_dlpi_device(const char *name, int *ppa, char *errbuf)
+open_dlpi_device(const char *name, u_int *ppa, char *errbuf)
{
int status;
char dname[100];
char *cp;
int fd;
-#ifndef HAVE_DEV_DLPI
+#ifdef HAVE_DEV_DLPI
+ u_int unit;
+#else
char dname2[100];
#endif
@@ -358,7 +371,7 @@ open_dlpi_device(const char *name, int *ppa, char *errbuf)
* Split the device name into a device type name and a unit number;
* chop off the unit number, so "dname" is just a device type name.
*/
- cp = split_dname(dname, ppa, errbuf);
+ cp = split_dname(dname, &unit, errbuf);
if (cp == NULL)
return (PCAP_ERROR_NO_SUCH_DEVICE);
*cp = '\0';
@@ -380,8 +393,8 @@ open_dlpi_device(const char *name, int *ppa, char *errbuf)
status = PCAP_ERROR_PERM_DENIED;
else
status = PCAP_ERROR;
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "%s: %s", cp, pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ errno, "%s", cp);
return (status);
}
@@ -389,10 +402,10 @@ open_dlpi_device(const char *name, int *ppa, char *errbuf)
* Get a table of all PPAs for that device, and search that
* table for the specified device type name and unit number.
*/
- *ppa = get_dlpi_ppa(fd, dname, *ppa, errbuf);
- if (*ppa < 0) {
+ status = get_dlpi_ppa(fd, dname, unit, ppa, errbuf);
+ if (status < 0) {
close(fd);
- return (*ppa);
+ return (status);
}
#else
/*
@@ -429,8 +442,8 @@ open_dlpi_device(const char *name, int *ppa, char *errbuf)
status = PCAP_ERROR_PERM_DENIED;
else
status = PCAP_ERROR;
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", dname,
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ errno, "%s", dname);
return (status);
}
@@ -469,8 +482,8 @@ open_dlpi_device(const char *name, int *ppa, char *errbuf)
status = PCAP_ERROR_PERM_DENIED;
else
status = PCAP_ERROR;
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s",
- dname2, pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(errbuf,
+ PCAP_ERRBUF_SIZE, errno, "%s", dname2);
}
return (status);
}
@@ -489,7 +502,7 @@ pcap_activate_dlpi(pcap_t *p)
#endif
int status = 0;
int retv;
- int ppa;
+ u_int ppa;
#ifdef HAVE_SOLARIS
int isatm = 0;
#endif
@@ -563,7 +576,7 @@ pcap_activate_dlpi(pcap_t *p)
goto bad;
}
-#ifdef HAVE_DLPI_PASSIVE
+#ifdef HAVE_DL_PASSIVE_REQ_T
/*
* Enable Passive mode to be able to capture on aggregated link.
* Not supported in all Solaris versions.
@@ -632,6 +645,17 @@ pcap_activate_dlpi(pcap_t *p)
#endif /* AIX vs. HP-UX vs. other */
#endif /* !HP-UX 9 and !HP-UX 10.20 or later and !SINIX */
+ /*
+ * Turn a negative snapshot value (invalid), a snapshot value of
+ * 0 (unspecified), or a value bigger than the normal maximum
+ * value, into the maximum allowed value.
+ *
+ * If some application really *needs* a bigger snapshot
+ * length, we should just increase MAXIMUM_SNAPLEN.
+ */
+ if (p->snapshot <= 0 || p->snapshot > MAXIMUM_SNAPLEN)
+ p->snapshot = MAXIMUM_SNAPLEN;
+
#ifdef HAVE_SOLARIS
if (isatm) {
/*
@@ -642,8 +666,8 @@ pcap_activate_dlpi(pcap_t *p)
*/
if (strioctl(p->fd, A_PROMISCON_REQ, 0, NULL) < 0) {
status = PCAP_ERROR;
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "A_PROMISCON_REQ: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "A_PROMISCON_REQ");
goto bad;
}
} else
@@ -760,8 +784,8 @@ pcap_activate_dlpi(pcap_t *p)
*/
if (strioctl(p->fd, DLIOCRAW, 0, NULL) < 0) {
status = PCAP_ERROR;
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "DLIOCRAW: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "DLIOCRAW");
goto bad;
}
#endif
@@ -801,8 +825,8 @@ pcap_activate_dlpi(pcap_t *p)
*/
if (ioctl(p->fd, I_FLUSH, FLUSHR) != 0) {
status = PCAP_ERROR;
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "FLUSHR: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "FLUSHR");
goto bad;
}
@@ -845,7 +869,7 @@ bad:
* Returns NULL on error, and fills "ebuf" with an error message.
*/
static char *
-split_dname(char *device, int *unitp, char *ebuf)
+split_dname(char *device, u_int *unitp, char *ebuf)
{
char *cp;
char *eos;
@@ -881,7 +905,7 @@ split_dname(char *device, int *unitp, char *ebuf)
device);
return (NULL);
}
- *unitp = (int)unit;
+ *unitp = (u_int)unit;
return (cp);
}
@@ -986,7 +1010,7 @@ static int
is_dlpi_interface(const char *name)
{
int fd;
- int ppa;
+ u_int ppa;
char errbuf[PCAP_ERRBUF_SIZE];
fd = open_dlpi_device(name, &ppa, errbuf);
@@ -1025,8 +1049,31 @@ is_dlpi_interface(const char *name)
return (1);
}
+static int
+get_if_flags(const char *name _U_, bpf_u_int32 *flags _U_, char *errbuf _U_)
+{
+ /*
+ * Nothing we can do other than mark loopback devices as "the
+ * connected/disconnected status doesn't apply".
+ *
+ * XXX - on Solaris, can we do what the dladm command does,
+ * i.e. get a connected/disconnected indication from a kstat?
+ * (Note that you can also get the link speed, and possibly
+ * other information, from a kstat as well.)
+ */
+ if (*flags & PCAP_IF_LOOPBACK) {
+ /*
+ * Loopback devices aren't wireless, and "connected"/
+ * "disconnected" doesn't apply to them.
+ */
+ *flags |= PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE;
+ return (0);
+ }
+ return (0);
+}
+
int
-pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
+pcap_platform_finddevs(pcap_if_list_t *devlistp, char *errbuf)
{
#ifdef HAVE_SOLARIS
int fd;
@@ -1042,7 +1089,8 @@ pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
/*
* Get the list of regular interfaces first.
*/
- if (pcap_findalldevs_interfaces(alldevsp, errbuf, is_dlpi_interface) == -1)
+ if (pcap_findalldevs_interfaces(devlistp, errbuf, is_dlpi_interface,
+ get_if_flags) == -1)
return (-1); /* failure */
#ifdef HAVE_SOLARIS
@@ -1062,13 +1110,18 @@ pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
}
if (strioctl(fd, A_GET_UNITS, sizeof(buf), (char *)&buf) < 0) {
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "A_GET_UNITS: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ errno, "A_GET_UNITS");
return (-1);
}
for (i = 0; i < buf.nunits; i++) {
pcap_snprintf(baname, sizeof baname, "ba%u", i);
- if (pcap_add_if(alldevsp, baname, 0, NULL, errbuf) < 0)
+ /*
+ * XXX - is there a notion of "up" and "running"?
+ * And is there a way to determine whether the
+ * interface is plugged into a network?
+ */
+ if (add_dev(devlistp, baname, 0, NULL, errbuf) == NULL)
return (-1);
}
#endif
@@ -1088,9 +1141,8 @@ send_request(int fd, char *ptr, int len, char *what, char *ebuf)
flags = 0;
if (putmsg(fd, &ctl, (struct strbuf *) NULL, flags) < 0) {
- pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
- "send_request: putmsg \"%s\": %s",
- what, pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
+ errno, "send_request: putmsg \"%s\"", what);
return (-1);
}
return (0);
@@ -1118,8 +1170,8 @@ recv_ack(int fd, int size, const char *what, char *bufp, char *ebuf, int *uerror
flags = 0;
if (getmsg(fd, &ctl, (struct strbuf*)NULL, &flags) < 0) {
- pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "recv_ack: %s getmsg: %s",
- what, pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
+ errno, "recv_ack: %s getmsg", what);
return (PCAP_ERROR);
}
@@ -1141,9 +1193,9 @@ recv_ack(int fd, int size, const char *what, char *bufp, char *ebuf, int *uerror
case DL_SYSERR:
if (uerror != NULL)
*uerror = dlp->error_ack.dl_unix_errno;
- pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
- "recv_ack: %s: UNIX error - %s",
- what, pcap_strerror(dlp->error_ack.dl_unix_errno));
+ pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
+ dlp->error_ack.dl_unix_errno,
+ "recv_ack: %s: UNIX error", what);
if (dlp->error_ack.dl_unix_errno == EPERM ||
dlp->error_ack.dl_unix_errno == EACCES)
return (PCAP_ERROR_PERM_DENIED);
@@ -1430,7 +1482,7 @@ dlinfoack(int fd, char *bufp, char *ebuf)
return (recv_ack(fd, DL_INFO_ACK_SIZE, "info", bufp, ebuf, NULL));
}
-#ifdef HAVE_DLPI_PASSIVE
+#ifdef HAVE_DL_PASSIVE_REQ_T
/*
* Enable DLPI passive mode. We do not care if this request fails, as this
* indicates the underlying DLPI device does not support link aggregation.
@@ -1552,12 +1604,12 @@ echo 'lanc_outbound_promisc_flag/W1' | /usr/bin/adb -w /stand/vmunix /dev/kmem
* Setting the variable is not necessary on HP-UX 11.x.
*/
static int
-get_dlpi_ppa(register int fd, register const char *device, register int unit,
- register char *ebuf)
+get_dlpi_ppa(register int fd, register const char *device, register u_int unit,
+ u_int *ppa, register char *ebuf)
{
register dl_hp_ppa_ack_t *ap;
register dl_hp_ppa_info_t *ipstart, *ip;
- register int i;
+ register u_int i;
char dname[100];
register u_long majdev;
struct stat statbuf;
@@ -1567,7 +1619,6 @@ get_dlpi_ppa(register int fd, register const char *device, register int unit,
dl_hp_ppa_ack_t *dlp;
struct strbuf ctl;
int flags;
- int ppa;
memset((char *)&req, 0, sizeof(req));
req.dl_primitive = DL_HP_PPA_REQ;
@@ -1595,8 +1646,13 @@ get_dlpi_ppa(register int fd, register const char *device, register int unit,
*/
/* get the head first */
if (getmsg(fd, &ctl, (struct strbuf *)NULL, &flags) < 0) {
+ pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
+ errno, "get_dlpi_ppa: hpppa getmsg");
+ return (PCAP_ERROR);
+ }
+ if (ctl.len == -1) {
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
- "get_dlpi_ppa: hpppa getmsg: %s", pcap_strerror(errno));
+ "get_dlpi_ppa: hpppa getmsg: control buffer has no data");
return (PCAP_ERROR);
}
@@ -1608,7 +1664,7 @@ get_dlpi_ppa(register int fd, register const char *device, register int unit,
return (PCAP_ERROR);
}
- if (ctl.len < DL_HP_PPA_ACK_SIZE) {
+ if ((size_t)ctl.len < DL_HP_PPA_ACK_SIZE) {
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
"get_dlpi_ppa: hpppa ack too small (%d < %lu)",
ctl.len, (unsigned long)DL_HP_PPA_ACK_SIZE);
@@ -1617,8 +1673,8 @@ get_dlpi_ppa(register int fd, register const char *device, register int unit,
/* allocate buffer */
if ((ppa_data_buf = (char *)malloc(dlp->dl_length)) == NULL) {
- pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
- "get_dlpi_ppa: hpppa malloc: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
+ errno, "get_dlpi_ppa: hpppa malloc");
return (PCAP_ERROR);
}
ctl.maxlen = dlp->dl_length;
@@ -1626,12 +1682,17 @@ get_dlpi_ppa(register int fd, register const char *device, register int unit,
ctl.buf = (char *)ppa_data_buf;
/* get the data */
if (getmsg(fd, &ctl, (struct strbuf *)NULL, &flags) < 0) {
- pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
- "get_dlpi_ppa: hpppa getmsg: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
+ errno, "get_dlpi_ppa: hpppa getmsg");
free(ppa_data_buf);
return (PCAP_ERROR);
}
- if (ctl.len < dlp->dl_length) {
+ if (ctl.len == -1) {
+ pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
+ "get_dlpi_ppa: hpppa getmsg: control buffer has no data");
+ return (PCAP_ERROR);
+ }
+ if ((u_int)ctl.len < dlp->dl_length) {
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
"get_dlpi_ppa: hpppa ack too small (%d < %lu)",
ctl.len, (unsigned long)dlp->dl_length);
@@ -1643,7 +1704,7 @@ get_dlpi_ppa(register int fd, register const char *device, register int unit,
ipstart = (dl_hp_ppa_info_t *)ppa_data_buf;
ip = ipstart;
-#ifdef HAVE_HP_PPA_INFO_T_DL_MODULE_ID_1
+#ifdef HAVE_DL_HP_PPA_INFO_T_DL_MODULE_ID_1
/*
* The "dl_hp_ppa_info_t" structure has a "dl_module_id_1"
* member that should, in theory, contain the part of the
@@ -1689,10 +1750,10 @@ get_dlpi_ppa(register int fd, register const char *device, register int unit,
* device number of a device with the name "/dev/<dev><unit>",
* if such a device exists, as the old code did.
*/
- pcap_snprintf(dname, sizeof(dname), "/dev/%s%d", device, unit);
+ pcap_snprintf(dname, sizeof(dname), "/dev/%s%u", device, unit);
if (stat(dname, &statbuf) < 0) {
- pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "stat: %s: %s",
- dname, pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
+ errno, "stat: %s", dname);
return (PCAP_ERROR);
}
majdev = major(statbuf.st_rdev);
@@ -1709,7 +1770,7 @@ get_dlpi_ppa(register int fd, register const char *device, register int unit,
}
if (i == ap->dl_count) {
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
- "can't find /dev/dlpi PPA for %s%d", device, unit);
+ "can't find /dev/dlpi PPA for %s%u", device, unit);
return (PCAP_ERROR_NO_SUCH_DEVICE);
}
if (ip->dl_hdw_state == HDW_DEAD) {
@@ -1718,9 +1779,9 @@ get_dlpi_ppa(register int fd, register const char *device, register int unit,
free(ppa_data_buf);
return (PCAP_ERROR);
}
- ppa = ip->dl_ppa;
+ *ppa = ip->dl_ppa;
free(ppa_data_buf);
- return (ppa);
+ return (0);
}
#endif
@@ -1739,8 +1800,8 @@ static char path_vmunix[] = "/hp-ux";
/* Determine ppa number that specifies ifname */
static int
-get_dlpi_ppa(register int fd, register const char *ifname, register int unit,
- register char *ebuf)
+get_dlpi_ppa(register int fd, register const char *ifname, register u_int unit,
+ u_int *ppa, register char *ebuf)
{
register const char *cp;
register int kd;
@@ -1754,24 +1815,24 @@ get_dlpi_ppa(register int fd, register const char *ifname, register int unit,
if (nlist(path_vmunix, &nl) < 0) {
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "nlist %s failed",
path_vmunix);
- return (-1);
+ return (PCAP_ERROR);
}
if (nl[NL_IFNET].n_value == 0) {
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
"could't find %s kernel symbol",
nl[NL_IFNET].n_name);
- return (-1);
+ return (PCAP_ERROR);
}
kd = open("/dev/kmem", O_RDONLY);
if (kd < 0) {
- pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "kmem open: %s",
- pcap_strerror(errno));
- return (-1);
+ pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
+ errno, "kmem open");
+ return (PCAP_ERROR);
}
if (dlpi_kread(kd, nl[NL_IFNET].n_value,
&addr, sizeof(addr), ebuf) < 0) {
close(kd);
- return (-1);
+ return (PCAP_ERROR);
}
for (; addr != NULL; addr = ifnet.if_next) {
if (dlpi_kread(kd, (off_t)addr,
@@ -1779,15 +1840,17 @@ get_dlpi_ppa(register int fd, register const char *ifname, register int unit,
dlpi_kread(kd, (off_t)ifnet.if_name,
if_name, sizeof(ifnet.if_name), ebuf) < 0) {
(void)close(kd);
- return (-1);
+ return (PCAP_ERROR);
}
if_name[sizeof(ifnet.if_name)] = '\0';
- if (strcmp(if_name, ifname) == 0 && ifnet.if_unit == unit)
- return (ifnet.if_index);
+ if (strcmp(if_name, ifname) == 0 && ifnet.if_unit == unit) {
+ *ppa = ifnet.if_index;
+ return (0);
+ }
}
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "Can't find %s", ifname);
- return (-1);
+ return (PCAP_ERROR_NO_SUCH_DEVICE);
}
static int
@@ -1797,14 +1860,14 @@ dlpi_kread(register int fd, register off_t addr,
register int cc;
if (lseek(fd, addr, SEEK_SET) < 0) {
- pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "lseek: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
+ errno, "lseek");
return (-1);
}
cc = read(fd, buf, len);
if (cc < 0) {
- pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "read: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
+ errno, "read");
return (-1);
} else if (cc != len) {
pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "short read (%d != %d)", cc,
@@ -1835,3 +1898,12 @@ pcap_create_interface(const char *device _U_, char *ebuf)
p->activate_op = pcap_activate_dlpi;
return (p);
}
+
+/*
+ * Libpcap version string.
+ */
+const char *
+pcap_lib_version(void)
+{
+ return (PCAP_VERSION_STRING);
+}
diff --git a/contrib/libpcap/pcap-dos.c b/contrib/libpcap/pcap-dos.c
index ea6b225a23efa..b1b9ecd72b16e 100644
--- a/contrib/libpcap/pcap-dos.c
+++ b/contrib/libpcap/pcap-dos.c
@@ -174,6 +174,17 @@ static int pcap_activate_dos (pcap_t *pcap)
return (PCAP_ERROR_RFMON_NOTSUP);
}
+ /*
+ * Turn a negative snapshot value (invalid), a snapshot value of
+ * 0 (unspecified), or a value bigger than the normal maximum
+ * value, into the maximum allowed value.
+ *
+ * If some application really *needs* a bigger snapshot
+ * length, we should just increase MAXIMUM_SNAPLEN.
+ */
+ if (pcap->snapshot <= 0 || pcap->snapshot > MAXIMUM_SNAPLEN)
+ pcap->snapshot = MAXIMUM_SNAPLEN;
+
if (pcap->snapshot < ETH_MIN+8)
pcap->snapshot = ETH_MIN+8;
@@ -197,6 +208,7 @@ static int pcap_activate_dos (pcap_t *pcap)
if (!init_watt32(pcap, pcap->opt.device, pcap->errbuf) ||
!first_init(pcap->opt.device, pcap->errbuf, pcap->opt.promisc))
{
+ /* XXX - free pcap->buffer? */
return (PCAP_ERROR);
}
atexit (close_driver);
@@ -206,6 +218,7 @@ static int pcap_activate_dos (pcap_t *pcap)
pcap_snprintf (pcap->errbuf, PCAP_ERRBUF_SIZE,
"Cannot use different devices simultaneously "
"(`%s' vs. `%s')", active_dev->name, pcap->opt.device);
+ /* XXX - free pcap->buffer? */
return (PCAP_ERROR);
}
handle_to_device [pcap->fd-1] = active_dev;
@@ -467,6 +480,7 @@ static void pcap_cleanup_dos (pcap_t *p)
return;
}
close_driver();
+ /* XXX - call pcap_cleanup_live_common? */
}
/*
@@ -539,17 +553,18 @@ int pcap_lookupnet (const char *device, bpf_u_int32 *localnet,
/*
* Get a list of all interfaces that are present and that we probe okay.
* Returns -1 on error, 0 otherwise.
- * The list, as returned through "alldevsp", may be NULL if no interfaces
- * were up and could be opened.
+ * The list may be NULL epty if no interfaces were up and could be opened.
*/
-int pcap_platform_finddevs (pcap_if_t **alldevsp, char *errbuf)
+int pcap_platform_finddevs (pcap_if_list_t *devlistp, char *errbuf)
{
struct device *dev;
+ pcap_if_t *curdev;
+#if 0 /* Pkt drivers should have no addresses */
struct sockaddr_in sa_ll_1, sa_ll_2;
struct sockaddr *addr, *netmask, *broadaddr, *dstaddr;
- pcap_if_t *devlist = NULL;
+#endif
int ret = 0;
- size_t addr_size = sizeof(*addr);
+ int found = 0;
for (dev = (struct device*)dev_base; dev; dev = dev->next)
{
@@ -562,6 +577,20 @@ int pcap_platform_finddevs (pcap_if_t **alldevsp, char *errbuf)
FLUSHK();
(*dev->close) (dev);
+ /*
+ * XXX - find out whether it's up or running? Does that apply here?
+ * Can we find out if anything's plugged into the adapter, if it's
+ * a wired device, and set PCAP_IF_CONNECTION_STATUS_CONNECTED
+ * or PCAP_IF_CONNECTION_STATUS_DISCONNECTED?
+ */
+ if ((curdev = add_dev(devlistp, dev->name, 0,
+ dev->long_name, errbuf)) == NULL)
+ {
+ ret = -1;
+ break;
+ }
+ found = 1;
+#if 0 /* Pkt drivers should have no addresses */
memset (&sa_ll_1, 0, sizeof(sa_ll_1));
memset (&sa_ll_2, 0, sizeof(sa_ll_2));
sa_ll_1.sin_family = AF_INET;
@@ -573,16 +602,10 @@ int pcap_platform_finddevs (pcap_if_t **alldevsp, char *errbuf)
broadaddr = (struct sockaddr*) &sa_ll_2;
memset (&sa_ll_2.sin_addr, 0xFF, sizeof(sa_ll_2.sin_addr));
- if (pcap_add_if(&devlist, dev->name, dev->flags,
- dev->long_name, errbuf) < 0)
- {
- ret = -1;
- break;
- }
-#if 0 /* Pkt drivers should have no addresses */
- if (add_addr_to_iflist(&devlist, dev->name, dev->flags, addr, addr_size,
- netmask, addr_size, broadaddr, addr_size,
- dstaddr, addr_size, errbuf) < 0)
+ if (add_addr_to_dev(curdev, addr, sizeof(*addr),
+ netmask, sizeof(*netmask),
+ broadaddr, sizeof(*broadaddr),
+ dstaddr, sizeof(*dstaddr), errbuf) < 0)
{
ret = -1;
break;
@@ -590,16 +613,9 @@ int pcap_platform_finddevs (pcap_if_t **alldevsp, char *errbuf)
#endif
}
- if (devlist && ret < 0)
- {
- pcap_freealldevs (devlist);
- devlist = NULL;
- }
- else
- if (!devlist)
+ if (ret == 0 && !found)
strcpy (errbuf, "No drivers found");
- *alldevsp = devlist;
return (ret);
}
@@ -1510,3 +1526,11 @@ static void pktq_clear (struct rx_ringbuf *q)
#endif /* USE_32BIT_DRIVERS */
+/*
+ * Libpcap version string.
+ */
+const char *
+pcap_lib_version(void)
+{
+ return ("DOS-" PCAP_VERSION_STRING);
+}
diff --git a/contrib/libpcap/pcap-enet.c b/contrib/libpcap/pcap-enet.c
index 777d3e3a81349..cd8cdbbb78b45 100644
--- a/contrib/libpcap/pcap-enet.c
+++ b/contrib/libpcap/pcap-enet.c
@@ -8,7 +8,7 @@
*/
#ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
#endif
#include <sys/types.h>
diff --git a/contrib/libpcap/pcap-filter.manmisc b/contrib/libpcap/pcap-filter.manmisc
deleted file mode 100644
index 3e310209c7c0d..0000000000000
--- a/contrib/libpcap/pcap-filter.manmisc
+++ /dev/null
@@ -1,1017 +0,0 @@
-.\" Copyright (c) 1987, 1988, 1989, 1990, 1991, 1992, 1994, 1995, 1996, 1997
-.\" The Regents of the University of California. All rights reserved.
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that: (1) source code distributions
-.\" retain the above copyright notice and this paragraph in its entirety, (2)
-.\" distributions including binary code include the above copyright notice and
-.\" this paragraph in its entirety in the documentation or other materials
-.\" provided with the distribution, and (3) all advertising materials mentioning
-.\" features or use of this software display the following acknowledgement:
-.\" ``This product includes software developed by the University of California,
-.\" Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
-.\" the University nor the names of its contributors may be used to endorse
-.\" or promote products derived from this software without specific prior
-.\" written permission.
-.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
-.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
-.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
-.\"
-.TH PCAP-FILTER 7 "17 May 2013"
-.SH NAME
-pcap-filter \- packet filter syntax
-.br
-.ad
-.SH DESCRIPTION
-.LP
-.B pcap_compile()
-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() ,
-or
-.BR pcap_next_ex() .
-.LP
-The \fIfilter expression\fP consists of one or more
-.IR primitives .
-Primitives usually consist of an
-.I id
-(name or number) preceded by one or more qualifiers.
-There are three
-different kinds of qualifier:
-.IP \fItype\fP
-.I type
-qualifiers say what kind of thing the id name or number refers to.
-Possible types are
-.BR host ,
-.B net ,
-.B port
-and
-.BR portrange .
-E.g., `host foo', `net 128.3', `port 20', `portrange 6000-6008'.
-If there is no type
-qualifier,
-.B host
-is assumed.
-.IP \fIdir\fP
-.I dir
-qualifiers specify a particular transfer direction to and/or from
-.IR id .
-Possible directions are
-.BR src ,
-.BR dst ,
-.BR "src or dst" ,
-.BR "src and dst" ,
-.BR ra ,
-.BR ta ,
-.BR addr1 ,
-.BR addr2 ,
-.BR addr3 ,
-and
-.BR addr4 .
-E.g., `src foo', `dst net 128.3', `src or dst port ftp-data'.
-If
-there is no dir qualifier,
-.B "src or dst"
-is assumed.
-The
-.BR ra ,
-.BR ta ,
-.BR addr1 ,
-.BR addr2 ,
-.BR addr3 ,
-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.
-Possible
-protos are:
-.BR ether ,
-.BR fddi ,
-.BR tr ,
-.BR wlan ,
-.BR ip ,
-.BR ip6 ,
-.BR arp ,
-.BR rarp ,
-.BR decnet ,
-.B tcp
-and
-.BR udp .
-E.g., `ether src foo', `arp net 128.3', `tcp port 21', `udp portrange
-7000-7009', `wlan addr2 0:2:3:4:5:6'.
-If there is
-no proto qualifier, all protocols consistent with the type are
-assumed.
-E.g., `src foo' means `(ip or arp or rarp) src foo'
-(except the latter is not legal syntax), `net bar' means `(ip or
-arp or rarp) net bar' and `port 53' means `(tcp or udp) port 53'.
-.LP
-[`fddi' is actually an alias for `ether'; the parser treats them
-identically as meaning ``the data link level used on the specified
-network interface.'' FDDI headers contain Ethernet-like source
-and destination addresses, and often contain Ethernet-like packet
-types, so you can filter on these FDDI fields just as with the
-analogous Ethernet fields.
-FDDI headers also contain other fields,
-but you cannot name them explicitly in a filter expression.
-.LP
-Similarly, `tr' and `wlan' are aliases for `ether'; the previous
-paragraph's statements about FDDI headers also apply to Token Ring
-and 802.11 wireless LAN headers. For 802.11 headers, the destination
-address is the DA field and the source address is the SA field; the
-BSSID, RA, and TA fields aren't tested.]
-.LP
-In addition to the above, there are some special `primitive' keywords
-that don't follow the pattern:
-.BR gateway ,
-.BR broadcast ,
-.BR less ,
-.B greater
-and arithmetic expressions.
-All of these are described below.
-.LP
-More complex filter expressions are built up by using the words
-.BR and ,
-.B or
-and
-.B not
-to combine primitives.
-E.g., `host foo and not port ftp and not port ftp-data'.
-To save typing, identical qualifier lists can be omitted.
-E.g.,
-`tcp dst port ftp or ftp-data or domain' is exactly the same as
-`tcp dst port ftp or tcp dst port ftp-data or tcp dst port domain'.
-.LP
-Allowable primitives are:
-.IP "\fBdst host \fIhost\fR"
-True if the IPv4/v6 destination field of the packet is \fIhost\fP,
-which may be either an address or a name.
-.IP "\fBsrc host \fIhost\fR"
-True if the IPv4/v6 source field of the packet is \fIhost\fP.
-.IP "\fBhost \fIhost\fP"
-True if either the IPv4/v6 source or destination of the packet is \fIhost\fP.
-.IP
-Any of the above host expressions can be prepended with the keywords,
-\fBip\fP, \fBarp\fP, \fBrarp\fP, or \fBip6\fP as in:
-.in +.5i
-.nf
-\fBip host \fIhost\fR
-.fi
-.in -.5i
-which is equivalent to:
-.in +.5i
-.nf
-\fBether proto \fI\\ip\fB and host \fIhost\fR
-.fi
-.in -.5i
-If \fIhost\fR is a name with multiple IP addresses, each address will
-be checked for a match.
-.IP "\fBether dst \fIehost\fP"
-True if the Ethernet destination address is \fIehost\fP.
-\fIEhost\fP
-may be either a name from /etc/ethers or a number (see
-.IR ethers (3N)
-for numeric format).
-.IP "\fBether src \fIehost\fP"
-True if the Ethernet source address is \fIehost\fP.
-.IP "\fBether host \fIehost\fP"
-True if either the Ethernet source or destination address is \fIehost\fP.
-.IP "\fBgateway\fP \fIhost\fP"
-True if the packet used \fIhost\fP as a gateway.
-I.e., the Ethernet
-source or destination address was \fIhost\fP but neither the IP source
-nor the IP destination was \fIhost\fP.
-\fIHost\fP must be a name and
-must be found both by the machine's host-name-to-IP-address resolution
-mechanisms (host name file, DNS, NIS, etc.) and by the machine's
-host-name-to-Ethernet-address resolution mechanism (/etc/ethers, etc.).
-(An equivalent expression is
-.in +.5i
-.nf
-\fBether host \fIehost \fBand not host \fIhost\fR
-.fi
-.in -.5i
-which can be used with either names or numbers for \fIhost / ehost\fP.)
-This syntax does not work in IPv6-enabled configuration at this moment.
-.IP "\fBdst net \fInet\fR"
-True if the IPv4/v6 destination address of the packet has a network
-number of \fInet\fP.
-\fINet\fP may be either a name from the networks database
-(/etc/networks, etc.) or a network number.
-An IPv4 network number can be written as a dotted quad (e.g., 192.168.1.0),
-dotted triple (e.g., 192.168.1), dotted pair (e.g, 172.16), or single
-number (e.g., 10); the netmask is 255.255.255.255 for a dotted quad
-(which means that it's really a host match), 255.255.255.0 for a dotted
-triple, 255.255.0.0 for a dotted pair, or 255.0.0.0 for a single number.
-An IPv6 network number must be written out fully; the netmask is
-ff:ff:ff:ff:ff:ff:ff:ff, so IPv6 "network" matches are really always
-host matches, and a network match requires a netmask length.
-.IP "\fBsrc net \fInet\fR"
-True if the IPv4/v6 source address of the packet has a network
-number of \fInet\fP.
-.IP "\fBnet \fInet\fR"
-True if either the IPv4/v6 source or destination address of the packet has a network
-number of \fInet\fP.
-.IP "\fBnet \fInet\fR \fBmask \fInetmask\fR"
-True if the IPv4 address matches \fInet\fR with the specific \fInetmask\fR.
-May be qualified with \fBsrc\fR or \fBdst\fR.
-Note that this syntax is not valid for IPv6 \fInet\fR.
-.IP "\fBnet \fInet\fR/\fIlen\fR"
-True if the IPv4/v6 address matches \fInet\fR with a netmask \fIlen\fR
-bits wide.
-May be qualified with \fBsrc\fR or \fBdst\fR.
-.IP "\fBdst port \fIport\fR"
-True if the packet is ip/tcp, ip/udp, ip6/tcp or ip6/udp and has a
-destination port value of \fIport\fP.
-The \fIport\fP can be a number or a name used in /etc/services (see
-.IR tcp (4P)
-and
-.IR udp (4P)).
-If a name is used, both the port
-number and protocol are checked.
-If a number or ambiguous name is used,
-only the port number is checked (e.g., \fBdst port 513\fR will print both
-tcp/login traffic and udp/who traffic, and \fBport domain\fR will print
-both tcp/domain and udp/domain traffic).
-.IP "\fBsrc port \fIport\fR"
-True if the packet has a source port value of \fIport\fP.
-.IP "\fBport \fIport\fR"
-True if either the source or destination port of the packet is \fIport\fP.
-.IP "\fBdst portrange \fIport1\fB-\fIport2\fR"
-True if the packet is ip/tcp, ip/udp, ip6/tcp or ip6/udp and has a
-destination port value between \fIport1\fP and \fIport2\fP.
-.I port1
-and
-.I port2
-are interpreted in the same fashion as the
-.I port
-parameter for
-.BR port .
-.IP "\fBsrc portrange \fIport1\fB-\fIport2\fR"
-True if the packet has a source port value between \fIport1\fP and
-\fIport2\fP.
-.IP "\fBportrange \fIport1\fB-\fIport2\fR"
-True if either the source or destination port of the packet is between
-\fIport1\fP and \fIport2\fP.
-.IP
-Any of the above port or port range expressions can be prepended with
-the keywords, \fBtcp\fP or \fBudp\fP, as in:
-.in +.5i
-.nf
-\fBtcp src port \fIport\fR
-.fi
-.in -.5i
-which matches only tcp packets whose source port is \fIport\fP.
-.IP "\fBless \fIlength\fR"
-True if the packet has a length less than or equal to \fIlength\fP.
-This is equivalent to:
-.in +.5i
-.nf
-\fBlen <= \fIlength\fP.
-.fi
-.in -.5i
-.IP "\fBgreater \fIlength\fR"
-True if the packet has a length greater than or equal to \fIlength\fP.
-This is equivalent to:
-.in +.5i
-.nf
-\fBlen >= \fIlength\fP.
-.fi
-.in -.5i
-.IP "\fBip proto \fIprotocol\fR"
-True if the packet is an IPv4 packet (see
-.IR ip (4P))
-of protocol type \fIprotocol\fP.
-\fIProtocol\fP can be a number or one of the names
-\fBicmp\fP, \fBicmp6\fP, \fBigmp\fP, \fBigrp\fP, \fBpim\fP, \fBah\fP,
-\fBesp\fP, \fBvrrp\fP, \fBudp\fP, or \fBtcp\fP.
-Note that the identifiers \fBtcp\fP, \fBudp\fP, and \fBicmp\fP are also
-keywords and must be escaped via backslash (\\), which is \\\\ in the C-shell.
-Note that this primitive does not chase the protocol header chain.
-.IP "\fBip6 proto \fIprotocol\fR"
-True if the packet is an IPv6 packet of protocol type \fIprotocol\fP.
-Note that this primitive does not chase the protocol header chain.
-.IP "\fBproto \fIprotocol\fR"
-True if the packet is an IPv4 or IPv6 packet of protocol type
-\fIprotocol\fP. Note that this primitive does not chase the protocol
-header chain.
-.IP "\fBtcp\fR, \fBudp\fR, \fBicmp\fR"
-Abbreviations for:
-.in +.5i
-.nf
-\fBproto \fIp\fR\fB
-.fi
-.in -.5i
-where \fIp\fR is one of the above protocols.
-.IP "\fBip6 protochain \fIprotocol\fR"
-True if the packet is IPv6 packet,
-and contains protocol header with type \fIprotocol\fR
-in its protocol header chain.
-For example,
-.in +.5i
-.nf
-\fBip6 protochain 6\fR
-.fi
-.in -.5i
-matches any IPv6 packet with TCP protocol header in the protocol header chain.
-The packet may contain, for example,
-authentication header, routing header, or hop-by-hop option header,
-between IPv6 header and TCP header.
-The BPF code emitted by this primitive is complex and
-cannot be optimized by the BPF optimizer code, and is not supported by
-filter engines in the kernel, so this can be somewhat slow, and may
-cause more packets to be dropped.
-.IP "\fBip protochain \fIprotocol\fR"
-Equivalent to \fBip6 protochain \fIprotocol\fR, but this is for IPv4.
-.IP "\fBprotochain \fIprotocol\fR"
-True if the packet is an IPv4 or IPv6 packet of protocol type
-\fIprotocol\fP. Note that this primitive chases the protocol
-header chain.
-.IP "\fBether broadcast\fR"
-True if the packet is an Ethernet broadcast packet.
-The \fIether\fP
-keyword is optional.
-.IP "\fBip broadcast\fR"
-True if the packet is an IPv4 broadcast packet.
-It checks for both the all-zeroes and all-ones broadcast conventions,
-and looks up the subnet mask on the interface on which the capture is
-being done.
-.IP
-If the subnet mask of the interface on which the capture is being done
-is not available, either because the interface on which capture is being
-done has no netmask or because the capture is being done on the Linux
-"any" interface, which can capture on more than one interface, this
-check will not work correctly.
-.IP "\fBether multicast\fR"
-True if the packet is an Ethernet multicast packet.
-The \fBether\fP
-keyword is optional.
-This is shorthand for `\fBether[0] & 1 != 0\fP'.
-.IP "\fBip multicast\fR"
-True if the packet is an IPv4 multicast packet.
-.IP "\fBip6 multicast\fR"
-True if the packet is an IPv6 multicast packet.
-.IP "\fBether proto \fIprotocol\fR"
-True if the packet is of ether type \fIprotocol\fR.
-\fIProtocol\fP can be a number or one of the names
-\fBip\fP, \fBip6\fP, \fBarp\fP, \fBrarp\fP, \fBatalk\fP, \fBaarp\fP,
-\fBdecnet\fP, \fBsca\fP, \fBlat\fP, \fBmopdl\fP, \fBmoprc\fP,
-\fBiso\fP, \fBstp\fP, \fBipx\fP, or \fBnetbeui\fP.
-Note these identifiers are also keywords
-and must be escaped via backslash (\\).
-.IP
-[In the case of FDDI (e.g., `\fBfddi protocol arp\fR'), Token Ring
-(e.g., `\fBtr protocol arp\fR'), and IEEE 802.11 wireless LANS (e.g.,
-`\fBwlan protocol arp\fR'), for most of those protocols, the
-protocol identification comes from the 802.2 Logical Link Control (LLC)
-header, which is usually layered on top of the FDDI, Token Ring, or
-802.11 header.
-.IP
-When filtering for most protocol identifiers on FDDI, Token Ring, or
-802.11, the filter checks only the protocol ID field of an LLC header
-in so-called SNAP format with an Organizational Unit Identifier (OUI) of
-0x000000, for encapsulated Ethernet; it doesn't check whether the packet
-is in SNAP format with an OUI of 0x000000.
-The exceptions are:
-.RS
-.TP
-\fBiso\fP
-the filter checks the DSAP (Destination Service Access Point) and
-SSAP (Source Service Access Point) fields of the LLC header;
-.TP
-\fBstp\fP and \fBnetbeui\fP
-the filter checks the DSAP of the LLC header;
-.TP
-\fBatalk\fP
-the filter checks for a SNAP-format packet with an OUI of 0x080007
-and the AppleTalk etype.
-.RE
-.IP
-In the case of Ethernet, the filter checks the Ethernet type field
-for most of those protocols. The exceptions are:
-.RS
-.TP
-\fBiso\fP, \fBstp\fP, and \fBnetbeui\fP
-the filter checks for an 802.3 frame and then checks the LLC header as
-it does for FDDI, Token Ring, and 802.11;
-.TP
-\fBatalk\fP
-the filter checks both for the AppleTalk etype in an Ethernet frame and
-for a SNAP-format packet as it does for FDDI, Token Ring, and 802.11;
-.TP
-\fBaarp\fP
-the filter checks for the AppleTalk ARP etype in either an Ethernet
-frame or an 802.2 SNAP frame with an OUI of 0x000000;
-.TP
-\fBipx\fP
-the filter checks for the IPX etype in an Ethernet frame, the IPX
-DSAP in the LLC header, the 802.3-with-no-LLC-header encapsulation of
-IPX, and the IPX etype in a SNAP frame.
-.RE
-.IP "\fBip\fR, \fBip6\fR, \fBarp\fR, \fBrarp\fR, \fBatalk\fR, \fBaarp\fR, \fBdecnet\fR, \fBiso\fR, \fBstp\fR, \fBipx\fR, \fBnetbeui\fP"
-Abbreviations for:
-.in +.5i
-.nf
-\fBether proto \fIp\fR
-.fi
-.in -.5i
-where \fIp\fR is one of the above protocols.
-.IP "\fBlat\fR, \fBmoprc\fR, \fBmopdl\fR"
-Abbreviations for:
-.in +.5i
-.nf
-\fBether proto \fIp\fR
-.fi
-.in -.5i
-where \fIp\fR is one of the above protocols.
-Note that not all applications using
-.BR pcap (3PCAP)
-currently know how to parse these protocols.
-.IP "\fBdecnet src \fIhost\fR"
-True if the DECNET source address is
-.IR host ,
-which may be an address of the form ``10.123'', or a DECNET host
-name.
-[DECNET host name support is only available on ULTRIX systems
-that are configured to run DECNET.]
-.IP "\fBdecnet dst \fIhost\fR"
-True if the DECNET destination address is
-.IR host .
-.IP "\fBdecnet host \fIhost\fR"
-True if either the DECNET source or destination address is
-.IR host .
-.IP \fBllc\fP
-True if the packet has an 802.2 LLC header. This includes:
-.IP
-Ethernet packets with a length field rather than a type field that
-aren't raw NetWare-over-802.3 packets;
-.IP
-IEEE 802.11 data packets;
-.IP
-Token Ring packets (no check is done for LLC frames);
-.IP
-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 .
-.I type
-can be one of:
-.RS
-.TP
-\fBi\fR
-Information (I) PDUs
-.TP
-\fBs\fR
-Supervisory (S) PDUs
-.TP
-\fBu\fR
-Unnumbered (U) PDUs
-.TP
-\fBrr\fR
-Receiver Ready (RR) S PDUs
-.TP
-\fBrnr\fR
-Receiver Not Ready (RNR) S PDUs
-.TP
-\fBrej\fR
-Reject (REJ) S PDUs
-.TP
-\fBui\fR
-Unnumbered Information (UI) U PDUs
-.TP
-\fBua\fR
-Unnumbered Acknowledgment (UA) U PDUs
-.TP
-\fBdisc\fR
-Disconnect (DISC) U PDUs
-.TP
-\fBsabme\fR
-Set Asynchronous Balanced Mode Extended (SABME) U PDUs
-.TP
-\fBtest\fR
-Test (TEST) U PDUs
-.TP
-\fBxid\fR
-Exchange Identification (XID) U PDUs
-.TP
-\fBfrmr\fR
-Frame Reject (FRMR) U PDUs
-.RE
-.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
-.BR pf (4)).
-.IP "\fBon \fIinterface\fR"
-Synonymous with the
-.B ifname
-modifier.
-.IP "\fBrnr \fInum\fR"
-True if the packet was logged as matching the specified PF rule number
-(applies only to packets logged by OpenBSD's or FreeBSD's
-.BR pf (4)).
-.IP "\fBrulenum \fInum\fR"
-Synonymous with the
-.B rnr
-modifier.
-.IP "\fBreason \fIcode\fR"
-True if the packet was logged with the specified PF reason code. The known
-codes are:
-.BR match ,
-.BR bad-offset ,
-.BR fragment ,
-.BR short ,
-.BR normalize ,
-and
-.B memory
-(applies only to packets logged by OpenBSD's or FreeBSD's
-.BR pf (4)).
-.IP "\fBrset \fIname\fR"
-True if the packet was logged as matching the specified PF ruleset
-name of an anchored ruleset (applies only to packets logged by OpenBSD's
-or FreeBSD's
-.BR pf (4)).
-.IP "\fBruleset \fIname\fR"
-Synonymous with the
-.B rset
-modifier.
-.IP "\fBsrnr \fInum\fR"
-True if the packet was logged as matching the specified PF rule number
-of an anchored ruleset (applies only to packets logged by OpenBSD's or
-FreeBSD's
-.BR pf (4)).
-.IP "\fBsubrulenum \fInum\fR"
-Synonymous with the
-.B srnr
-modifier.
-.IP "\fBaction \fIact\fR"
-True if PF took the specified action when the packet was logged. Known actions
-are:
-.B pass
-and
-.B block
-and, with later versions of
-.BR pf (4)),
-.BR nat ,
-.BR rdr ,
-.B binat
-and
-.B scrub
-(applies only to packets logged by OpenBSD's or FreeBSD's
-.BR pf (4)).
-.IP "\fBwlan ra \fIehost\fR"
-True if the IEEE 802.11 RA is
-.IR ehost .
-The RA field is used in all frames except for management frames.
-.IP "\fBwlan ta \fIehost\fR"
-True if the IEEE 802.11 TA is
-.IR ehost .
-The TA field is used in all frames except for management frames and
-CTS (Clear To Send) and ACK (Acknowledgment) control frames.
-.IP "\fBwlan addr1 \fIehost\fR"
-True if the first IEEE 802.11 address is
-.IR ehost .
-.IP "\fBwlan addr2 \fIehost\fR"
-True if the second IEEE 802.11 address, if present, is
-.IR ehost .
-The second address field is used in all frames except for CTS (Clear To
-Send) and ACK (Acknowledgment) control frames.
-.IP "\fBwlan addr3 \fIehost\fR"
-True if the third IEEE 802.11 address, if present, is
-.IR ehost .
-The third address field is used in management and data frames, but not
-in control frames.
-.IP "\fBwlan addr4 \fIehost\fR"
-True if the fourth IEEE 802.11 address, if present, is
-.IR ehost .
-The fourth address field is only used for
-WDS (Wireless Distribution System) frames.
-.IP "\fBtype \fIwlan_type\fR"
-True if the IEEE 802.11 frame type matches the specified \fIwlan_type\fR.
-Valid \fIwlan_type\fRs are:
-\fBmgt\fP,
-\fBctl\fP
-and \fBdata\fP.
-.IP "\fBtype \fIwlan_type \fBsubtype \fIwlan_subtype\fR"
-True if the IEEE 802.11 frame type matches the specified \fIwlan_type\fR
-and frame subtype matches the specified \fIwlan_subtype\fR.
-.IP
-If the specified \fIwlan_type\fR is \fBmgt\fP,
-then valid \fIwlan_subtype\fRs are:
-\fBassoc-req\fP,
-\fBassoc-resp\fP,
-\fBreassoc-req\fP,
-\fBreassoc-resp\fP,
-\fBprobe-req\fP,
-\fBprobe-resp\fP,
-\fBbeacon\fP,
-\fBatim\fP,
-\fBdisassoc\fP,
-\fBauth\fP and
-\fBdeauth\fP.
-.IP
-If the specified \fIwlan_type\fR is \fBctl\fP,
-then valid \fIwlan_subtype\fRs are:
-\fBps-poll\fP,
-\fBrts\fP,
-\fBcts\fP,
-\fBack\fP,
-\fBcf-end\fP and
-\fBcf-end-ack\fP.
-.IP
-If the specified \fIwlan_type\fR is \fBdata\fP,
-then valid \fIwlan_subtype\fRs are:
-\fBdata\fP,
-\fBdata-cf-ack\fP,
-\fBdata-cf-poll\fP,
-\fBdata-cf-ack-poll\fP,
-\fBnull\fP,
-\fBcf-ack\fP,
-\fBcf-poll\fP,
-\fBcf-ack-poll\fP,
-\fBqos-data\fP,
-\fBqos-data-cf-ack\fP,
-\fBqos-data-cf-poll\fP,
-\fBqos-data-cf-ack-poll\fP,
-\fBqos\fP,
-\fBqos-cf-poll\fP and
-\fBqos-cf-ack-poll\fP.
-.IP "\fBsubtype \fIwlan_subtype\fR"
-True if the IEEE 802.11 frame subtype matches the specified \fIwlan_subtype\fR
-and frame has the type to which the specified \fIwlan_subtype\fR belongs.
-.IP "\fBdir \fIdir\fR"
-True if the IEEE 802.11 frame direction matches the specified
-.IR dir .
-Valid directions are:
-.BR nods ,
-.BR tods ,
-.BR fromds ,
-.BR dstods ,
-or a numeric value.
-.IP "\fBvlan \fI[vlan_id]\fR"
-True if the packet is an IEEE 802.1Q VLAN packet.
-If \fI[vlan_id]\fR is specified, only true if the packet has the specified
-\fIvlan_id\fR.
-Note that the first \fBvlan\fR keyword encountered in \fIexpression\fR
-changes the decoding offsets for the remainder of \fIexpression\fR on
-the assumption that the packet is a VLAN packet. The \fBvlan
-\fI[vlan_id]\fR expression may be used more than once, to filter on VLAN
-hierarchies. Each use of that expression increments the filter offsets
-by 4.
-.IP
-For example:
-.in +.5i
-.nf
-\fBvlan 100 && vlan 200\fR
-.fi
-.in -.5i
-filters on VLAN 200 encapsulated within VLAN 100, and
-.in +.5i
-.nf
-\fBvlan && vlan 300 && ip\fR
-.fi
-.in -.5i
-filters IPv4 protocols encapsulated in VLAN 300 encapsulated within any
-higher order VLAN.
-.IP "\fBmpls \fI[label_num]\fR"
-True if the packet is an MPLS packet.
-If \fI[label_num]\fR is specified, only true is the packet has the specified
-\fIlabel_num\fR.
-Note that the first \fBmpls\fR keyword encountered in \fIexpression\fR
-changes the decoding offsets for the remainder of \fIexpression\fR on
-the assumption that the packet is a MPLS-encapsulated IP packet. The
-\fBmpls \fI[label_num]\fR expression may be used more than once, to
-filter on MPLS hierarchies. Each use of that expression increments the
-filter offsets by 4.
-.IP
-For example:
-.in +.5i
-.nf
-\fBmpls 100000 && mpls 1024\fR
-.fi
-.in -.5i
-filters packets with an outer label of 100000 and an inner label of
-1024, and
-.in +.5i
-.nf
-\fBmpls && mpls 1024 && host 192.9.200.1\fR
-.fi
-.in -.5i
-filters packets to or from 192.9.200.1 with an inner label of 1024 and
-any outer label.
-.IP \fBpppoed\fP
-True if the packet is a PPP-over-Ethernet Discovery packet (Ethernet
-type 0x8863).
-.IP "\fBpppoes \fI[session_id]\fR"
-True if the packet is a PPP-over-Ethernet Session packet (Ethernet
-type 0x8864).
-If \fI[session_id]\fR is specified, only true if the packet has the specified
-\fIsession_id\fR.
-Note that the first \fBpppoes\fR keyword encountered in \fIexpression\fR
-changes the decoding offsets for the remainder of \fIexpression\fR on
-the assumption that the packet is a PPPoE session packet.
-.IP
-For example:
-.in +.5i
-.nf
-\fBpppoes 0x27 && ip\fR
-.fi
-.in -.5i
-filters IPv4 protocols encapsulated in PPPoE session id 0x27.
-.IP "\fBiso proto \fIprotocol\fR"
-True if the packet is an OSI packet of protocol type \fIprotocol\fP.
-\fIProtocol\fP can be a number or one of the names
-\fBclnp\fP, \fBesis\fP, or \fBisis\fP.
-.IP "\fBclnp\fR, \fBesis\fR, \fBisis\fR"
-Abbreviations for:
-.in +.5i
-.nf
-\fBiso proto \fIp\fR
-.fi
-.in -.5i
-where \fIp\fR is one of the above protocols.
-.IP "\fBl1\fR, \fBl2\fR, \fBiih\fR, \fBlsp\fR, \fBsnp\fR, \fBcsnp\fR, \fBpsnp\fR"
-Abbreviations for IS-IS PDU types.
-.IP "\fBvpi\fP \fIn\fR"
-True if the packet is an ATM packet, for SunATM on Solaris, with a
-virtual path identifier of
-.IR n .
-.IP "\fBvci\fP \fIn\fR"
-True if the packet is an ATM packet, for SunATM on Solaris, with a
-virtual channel identifier of
-.IR n .
-.IP \fBlane\fP
-True if the packet is an ATM packet, for SunATM on Solaris, and is
-an ATM LANE packet.
-Note that the first \fBlane\fR keyword encountered in \fIexpression\fR
-changes the tests done in the remainder of \fIexpression\fR
-on the assumption that the packet is either a LANE emulated Ethernet
-packet or a LANE LE Control packet. If \fBlane\fR isn't specified, the
-tests are done under the assumption that the packet is an
-LLC-encapsulated packet.
-.IP \fBoamf4s\fP
-True if the packet is an ATM packet, for SunATM on Solaris, and is
-a segment OAM F4 flow cell (VPI=0 & VCI=3).
-.IP \fBoamf4e\fP
-True if the packet is an ATM packet, for SunATM on Solaris, and is
-an end-to-end OAM F4 flow cell (VPI=0 & VCI=4).
-.IP \fBoamf4\fP
-True if the packet is an ATM packet, for SunATM on Solaris, and is
-a segment or end-to-end OAM F4 flow cell (VPI=0 & (VCI=3 | VCI=4)).
-.IP \fBoam\fP
-True if the packet is an ATM packet, for SunATM on Solaris, and is
-a segment or end-to-end OAM F4 flow cell (VPI=0 & (VCI=3 | VCI=4)).
-.IP \fBmetac\fP
-True if the packet is an ATM packet, for SunATM on Solaris, and is
-on a meta signaling circuit (VPI=0 & VCI=1).
-.IP \fBbcc\fP
-True if the packet is an ATM packet, for SunATM on Solaris, and is
-on a broadcast signaling circuit (VPI=0 & VCI=2).
-.IP \fBsc\fP
-True if the packet is an ATM packet, for SunATM on Solaris, and is
-on a signaling circuit (VPI=0 & VCI=5).
-.IP \fBilmic\fP
-True if the packet is an ATM packet, for SunATM on Solaris, and is
-on an ILMI circuit (VPI=0 & VCI=16).
-.IP \fBconnectmsg\fP
-True if the packet is an ATM packet, for SunATM on Solaris, and is
-on a signaling circuit and is a Q.2931 Setup, Call Proceeding, Connect,
-Connect Ack, Release, or Release Done message.
-.IP \fBmetaconnect\fP
-True if the packet is an ATM packet, for SunATM on Solaris, and is
-on a meta signaling circuit and is a Q.2931 Setup, Call Proceeding, Connect,
-Release, or Release Done message.
-.IP "\fIexpr relop expr\fR"
-True if the relation holds, where \fIrelop\fR is one of >, <, >=, <=, =,
-!=, and \fIexpr\fR is an arithmetic expression composed of integer
-constants (expressed in standard C syntax), the normal binary operators
-[+, -, *, /, %, &, |, ^, <<, >>], a length operator, and special packet data
-accessors. Note that all comparisons are unsigned, so that, for example,
-0x80000000 and 0xffffffff are > 0.
-.IP
-The % and ^ operators are currently only supported for filtering in the
-kernel on Linux with 3.7 and later kernels; on all other systems, if
-those operators are used, filtering will be done in user mode, which
-will increase the overhead of capturing packets and may cause more
-packets to be dropped.
-.IP
-To access data inside the packet, use the following syntax:
-.in +.5i
-.nf
-\fIproto\fB [ \fIexpr\fB : \fIsize\fB ]\fR
-.fi
-.in -.5i
-\fIProto\fR is one of \fBether, fddi, tr, wlan, ppp, slip, link,
-ip, arp, rarp, tcp, udp, icmp, ip6\fR or \fBradio\fR, and
-indicates the protocol layer for the index operation.
-(\fBether, fddi, wlan, tr, ppp, slip\fR and \fBlink\fR all refer to the
-link layer. \fBradio\fR refers to the "radio header" added to some
-802.11 captures.)
-Note that \fItcp, udp\fR and other upper-layer protocol types only
-apply to IPv4, not IPv6 (this will be fixed in the future).
-The byte offset, relative to the indicated protocol layer, is
-given by \fIexpr\fR.
-\fISize\fR is optional and indicates the number of bytes in the
-field of interest; it can be either one, two, or four, and defaults to one.
-The length operator, indicated by the keyword \fBlen\fP, gives the
-length of the packet.
-
-For example, `\fBether[0] & 1 != 0\fP' catches all multicast traffic.
-The expression `\fBip[0] & 0xf != 5\fP'
-catches all IPv4 packets with options.
-The expression
-`\fBip[6:2] & 0x1fff = 0\fP'
-catches only unfragmented IPv4 datagrams and frag zero of fragmented
-IPv4 datagrams.
-This check is implicitly applied to the \fBtcp\fP and \fBudp\fP
-index operations.
-For instance, \fBtcp[0]\fP always means the first
-byte of the TCP \fIheader\fP, and never means the first byte of an
-intervening fragment.
-
-Some offsets and field values may be expressed as names rather than
-as numeric values.
-The following protocol header field offsets are
-available: \fBicmptype\fP (ICMP type field), \fBicmpcode\fP (ICMP
-code field), and \fBtcpflags\fP (TCP flags field).
-
-The following ICMP type field values are available: \fBicmp-echoreply\fP,
-\fBicmp-unreach\fP, \fBicmp-sourcequench\fP, \fBicmp-redirect\fP,
-\fBicmp-echo\fP, \fBicmp-routeradvert\fP, \fBicmp-routersolicit\fP,
-\fBicmp-timxceed\fP, \fBicmp-paramprob\fP, \fBicmp-tstamp\fP,
-\fBicmp-tstampreply\fP, \fBicmp-ireq\fP, \fBicmp-ireqreply\fP,
-\fBicmp-maskreq\fP, \fBicmp-maskreply\fP.
-
-The following TCP flags field values are available: \fBtcp-fin\fP,
-\fBtcp-syn\fP, \fBtcp-rst\fP, \fBtcp-push\fP,
-\fBtcp-ack\fP, \fBtcp-urg\fP.
-.LP
-Primitives may be combined using:
-.IP
-A parenthesized group of primitives and operators
-(parentheses are special to the Shell and must be escaped).
-.IP
-Negation (`\fB!\fP' or `\fBnot\fP').
-.IP
-Concatenation (`\fB&&\fP' or `\fBand\fP').
-.IP
-Alternation (`\fB||\fP' or `\fBor\fP').
-.LP
-Negation has highest precedence.
-Alternation and concatenation have equal precedence and associate
-left to right.
-Note that explicit \fBand\fR tokens, not juxtaposition,
-are now required for concatenation.
-.LP
-If an identifier is given without a keyword, the most recent keyword
-is assumed.
-For example,
-.in +.5i
-.nf
-\fBnot host vs and ace\fR
-.fi
-.in -.5i
-is short for
-.in +.5i
-.nf
-\fBnot host vs and host ace\fR
-.fi
-.in -.5i
-which should not be confused with
-.in +.5i
-.nf
-\fBnot ( host vs or ace )\fR
-.fi
-.in -.5i
-.SH EXAMPLES
-.LP
-To select all packets arriving at or departing from \fIsundown\fP:
-.RS
-.nf
-\fBhost sundown\fP
-.fi
-.RE
-.LP
-To select traffic between \fIhelios\fR and either \fIhot\fR or \fIace\fR:
-.RS
-.nf
-\fBhost helios and \\( hot or ace \\)\fP
-.fi
-.RE
-.LP
-To select all IP packets between \fIace\fR and any host except \fIhelios\fR:
-.RS
-.nf
-\fBip host ace and not helios\fP
-.fi
-.RE
-.LP
-To select all traffic between local hosts and hosts at Berkeley:
-.RS
-.nf
-.B
-net ucb-ether
-.fi
-.RE
-.LP
-To select all ftp traffic through internet gateway \fIsnup\fP:
-.RS
-.nf
-.B
-gateway snup and (port ftp or ftp-data)
-.fi
-.RE
-.LP
-To select traffic neither sourced from nor destined for local hosts
-(if you gateway to one other net, this stuff should never make it
-onto your local net).
-.RS
-.nf
-.B
-ip and not net \fIlocalnet\fP
-.fi
-.RE
-.LP
-To select the start and end packets (the SYN and FIN packets) of each
-TCP conversation that involves a non-local host.
-.RS
-.nf
-.B
-tcp[tcpflags] & (tcp-syn|tcp-fin) != 0 and not src and dst net \fIlocalnet\fP
-.fi
-.RE
-.LP
-To select all IPv4 HTTP packets to and from port 80, i.e. print only
-packets that contain data, not, for example, SYN and FIN packets and
-ACK-only packets. (IPv6 is left as an exercise for the reader.)
-.RS
-.nf
-.B
-tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)
-.fi
-.RE
-.LP
-To select IP packets longer than 576 bytes sent through gateway \fIsnup\fP:
-.RS
-.nf
-.B
-gateway snup and ip[2:2] > 576
-.fi
-.RE
-.LP
-To select IP broadcast or multicast packets that were
-.I not
-sent via Ethernet broadcast or multicast:
-.RS
-.nf
-.B
-ether[0] & 1 = 0 and ip[16] >= 224
-.fi
-.RE
-.LP
-To select all ICMP packets that are not echo requests/replies (i.e., not
-ping packets):
-.RS
-.nf
-.B
-icmp[icmptype] != icmp-echo and icmp[icmptype] != icmp-echoreply
-.fi
-.RE
-.SH "SEE ALSO"
-pcap(3PCAP)
-.SH BUGS
-Please send problems, bugs, questions, desirable enhancements, etc. to:
-.LP
-.RS
-tcpdump-workers@lists.tcpdump.org
-.RE
-.LP
-Filter expressions on fields other than those in Token Ring headers will
-not correctly handle source-routed Token Ring packets.
-.LP
-Filter expressions on fields other than those in 802.11 headers will not
-correctly handle 802.11 data packets with both To DS and From DS set.
-.LP
-.BR "ip6 proto"
-should chase header chain, but at this moment it does not.
-.BR "ip6 protochain"
-is supplied for this behavior.
-.LP
-Arithmetic expression against transport layer headers, like \fBtcp[0]\fP,
-does not work against IPv6 packets.
-It only looks at IPv4 packets.
diff --git a/contrib/libpcap/pcap-filter.manmisc.in b/contrib/libpcap/pcap-filter.manmisc.in
index a23bba1babe76..7e4438d778a8f 100644
--- a/contrib/libpcap/pcap-filter.manmisc.in
+++ b/contrib/libpcap/pcap-filter.manmisc.in
@@ -181,9 +181,10 @@ be checked for a match.
.IP "\fBether dst \fIehost\fP"
True if the Ethernet destination address is \fIehost\fP.
\fIEhost\fP
-may be either a name from /etc/ethers or a number (see
-.IR ethers (3N)
-for numeric format).
+may be either a name from /etc/ethers or a numerical MAC address of the
+form "xx:xx:xx:xx:xx:xx", "xx.xx.xx.xx.xx.xx", "xx-xx-xx-xx-xx-xx",
+"xxxx.xxxx.xxxx", "xxxxxxxxxxxx", or various mixes of ':', '.', and '-',
+where each "x" is a hex digit (0-9, a-f, or A-F).
.IP "\fBether src \fIehost\fP"
True if the Ethernet source address is \fIehost\fP.
.IP "\fBether host \fIehost\fP"
@@ -863,8 +864,9 @@ intervening fragment.
Some offsets and field values may be expressed as names rather than
as numeric values.
The following protocol header field offsets are
-available: \fBicmptype\fP (ICMP type field), \fBicmpcode\fP (ICMP
-code field), and \fBtcpflags\fP (TCP flags field).
+available: \fBicmptype\fP (ICMP type field), \fBicmp6type (ICMP v6 type field)
+\fBicmpcode\fP (ICMP code field), \fBicmp6code\fP (ICMP v6 code field), and
+\fBtcpflags\fP (TCP flags field).
The following ICMP type field values are available: \fBicmp-echoreply\fP,
\fBicmp-unreach\fP, \fBicmp-sourcequench\fP, \fBicmp-redirect\fP,
@@ -873,6 +875,20 @@ The following ICMP type field values are available: \fBicmp-echoreply\fP,
\fBicmp-tstampreply\fP, \fBicmp-ireq\fP, \fBicmp-ireqreply\fP,
\fBicmp-maskreq\fP, \fBicmp-maskreply\fP.
+The following ICMPv6 type fields are available: \fBicmp6-echo\fP,
+\fBicmp6-echoreply\fP, \fBicmp6-multicastlistenerquery\fP,
+\fBicmp6-multicastlistenerreportv1\fP, \fBicmp6-multicastlistenerdone\fP,
+\fBicmp6-routersolicit\fP, \fBicmp6-routeradvert\fP,
+\fBicmp6-neighborsolicit\fP, \fBicmp6-neighboradvert\fP, \fBicmp6-redirect\fP,
+\fBicmp6-routerrenum\fP, \fBicmp6-nodeinformationquery\fP,
+\fBicmp6-nodeinformationresponse\fP, \fBicmp6-ineighbordiscoverysolicit\fP,
+\fBicmp6-ineighbordiscoveryadvert\fP, \fBicmp6-multicastlistenerreportv2\fP,
+\fBicmp6-homeagentdiscoveryrequest\fP, \fBicmp6-homeagentdiscoveryreply\fP,
+\fBicmp6-mobileprefixsolicit\fP, \fBicmp6-mobileprefixadvert\fP,
+\fBicmp6-certpathsolicit\fP, \fBicmp6-certpathadvert\fP,
+\fBicmp6-multicastrouteradvert\fP, \fBicmp6-multicastroutersolicit\fP,
+\fBicmp6-multicastrouterterm\fP.
+
The following TCP flags field values are available: \fBtcp-fin\fP,
\fBtcp-syn\fP, \fBtcp-rst\fP, \fBtcp-push\fP,
\fBtcp-ack\fP, \fBtcp-urg\fP, \fBtcp-ece\fP,
@@ -1011,11 +1027,12 @@ icmp[icmptype] != icmp-echo and icmp[icmptype] != icmp-echoreply
.SH "SEE ALSO"
pcap(3PCAP)
.SH BUGS
-Please send problems, bugs, questions, desirable enhancements, etc. to:
+To report a security issue please send an e-mail to security@tcpdump.org.
.LP
-.RS
-tcpdump-workers@lists.tcpdump.org
-.RE
+To report bugs and other problems, contribute patches, request a
+feature, provide generic feedback etc please see the file
+.I CONTRIBUTING
+in the libpcap source tree root.
.LP
Filter expressions on fields other than those in Token Ring headers will
not correctly handle source-routed Token Ring packets.
diff --git a/contrib/libpcap/pcap-int.h b/contrib/libpcap/pcap-int.h
index 7db7ff5e688d9..5888df7241b65 100644
--- a/contrib/libpcap/pcap-int.h
+++ b/contrib/libpcap/pcap-int.h
@@ -34,55 +34,40 @@
#ifndef pcap_int_h
#define pcap_int_h
+#include <signal.h>
+
#include <pcap/pcap.h>
+#include "varattrs.h"
+#include "fmtutils.h"
+
+/*
+ * Version string.
+ * Uses PACKAGE_VERSION from config.h.
+ */
+#define PCAP_VERSION_STRING "libpcap version " PACKAGE_VERSION
+
#ifdef __cplusplus
extern "C" {
#endif
-#if defined(_WIN32)
- /*
- * Make sure Packet32.h doesn't define BPF structures that we've
- * probably already defined as a result of including <pcap/pcap.h>.
- */
- #define BPF_MAJOR_VERSION
- #include <Packet32.h>
-#elif defined(MSDOS)
+#ifdef MSDOS
#include <fcntl.h>
#include <io.h>
#endif
-#if (defined(_MSC_VER) && (_MSC_VER <= 1200)) /* we are compiling with Visual Studio 6, that doesn't support the LL suffix*/
-
-/*
- * Swap byte ordering of unsigned long long timestamp on a big endian
- * machine.
- */
-#define SWAPLL(ull) ((ull & 0xff00000000000000) >> 56) | \
- ((ull & 0x00ff000000000000) >> 40) | \
- ((ull & 0x0000ff0000000000) >> 24) | \
- ((ull & 0x000000ff00000000) >> 8) | \
- ((ull & 0x00000000ff000000) << 8) | \
- ((ull & 0x0000000000ff0000) << 24) | \
- ((ull & 0x000000000000ff00) << 40) | \
- ((ull & 0x00000000000000ff) << 56)
-
-#else /* A recent Visual studio compiler or not VC */
-
/*
* Swap byte ordering of unsigned long long timestamp on a big endian
* machine.
*/
-#define SWAPLL(ull) ((ull & 0xff00000000000000LL) >> 56) | \
- ((ull & 0x00ff000000000000LL) >> 40) | \
- ((ull & 0x0000ff0000000000LL) >> 24) | \
- ((ull & 0x000000ff00000000LL) >> 8) | \
- ((ull & 0x00000000ff000000LL) << 8) | \
- ((ull & 0x0000000000ff0000LL) << 24) | \
- ((ull & 0x000000000000ff00LL) << 40) | \
- ((ull & 0x00000000000000ffLL) << 56)
-
-#endif /* _MSC_VER */
+#define SWAPLL(ull) ((ull & 0xff00000000000000ULL) >> 56) | \
+ ((ull & 0x00ff000000000000ULL) >> 40) | \
+ ((ull & 0x0000ff0000000000ULL) >> 24) | \
+ ((ull & 0x000000ff00000000ULL) >> 8) | \
+ ((ull & 0x00000000ff000000ULL) << 8) | \
+ ((ull & 0x0000000000ff0000ULL) << 24) | \
+ ((ull & 0x000000000000ff00ULL) << 40) | \
+ ((ull & 0x00000000000000ffULL) << 56)
/*
* Maximum snapshot length.
@@ -114,19 +99,32 @@ struct pcap_opt {
int promisc;
int rfmon; /* monitor mode */
int immediate; /* immediate mode - deliver packets as soon as they arrive */
+ int nonblock; /* non-blocking mode - don't wait for packets to be delivered, return "no packets available" */
int tstamp_type;
int tstamp_precision;
+
+ /*
+ * Platform-dependent options.
+ */
+#ifdef __linux__
+ int protocol; /* protocol to use when creating PF_PACKET socket */
+#endif
+#ifdef _WIN32
+ int nocapture_local;/* disable NPF loopback */
+#endif
};
typedef int (*activate_op_t)(pcap_t *);
typedef int (*can_set_rfmon_op_t)(pcap_t *);
typedef int (*read_op_t)(pcap_t *, int cnt, pcap_handler, u_char *);
+typedef int (*next_packet_op_t)(pcap_t *, struct pcap_pkthdr *, u_char **);
typedef int (*inject_op_t)(pcap_t *, const void *, size_t);
+typedef void (*save_current_filter_op_t)(pcap_t *, const char *);
typedef int (*setfilter_op_t)(pcap_t *, struct bpf_program *);
typedef int (*setdirection_op_t)(pcap_t *, pcap_direction_t);
typedef int (*set_datalink_op_t)(pcap_t *, int);
-typedef int (*getnonblock_op_t)(pcap_t *, char *);
-typedef int (*setnonblock_op_t)(pcap_t *, int, char *);
+typedef int (*getnonblock_op_t)(pcap_t *);
+typedef int (*setnonblock_op_t)(pcap_t *, int);
typedef int (*stats_op_t)(pcap_t *, struct pcap_stat *);
#ifdef _WIN32
typedef struct pcap_stat *(*stats_ex_op_t)(pcap_t *, int *);
@@ -155,15 +153,14 @@ struct pcap {
read_op_t read_op;
/*
- * Method to call to read packets from a savefile.
+ * Method to call to read the next packet from a savefile.
*/
- int (*next_packet_op)(pcap_t *, struct pcap_pkthdr *, u_char **);
+ next_packet_op_t next_packet_op;
#ifdef _WIN32
- ADAPTER *adapter;
+ HANDLE handle;
#else
int fd;
- int selectable_fd;
#endif /* _WIN32 */
/*
@@ -174,10 +171,14 @@ struct pcap {
u_char *bp;
int cc;
- int break_loop; /* flag set to force break from packet-reading loop */
+ sig_atomic_t break_loop; /* flag set to force break from packet-reading loop */
void *priv; /* private data for methods */
+#ifdef ENABLE_REMOTE
+ struct pcap_samp rmt_samp; /* parameters related to the sampling process. */
+#endif
+
int swapped;
FILE *rfile; /* null if live capture, non-null if savefile */
u_int fddipad;
@@ -208,7 +209,7 @@ struct pcap {
u_char *pkt;
#ifdef _WIN32
- struct pcap_stat stat; /* used for pcap_stats_ex() */
+ struct pcap_stat stat; /* used for pcap_stats_ex() */
#endif
/* We're accepting only packets in this direction/these directions. */
@@ -219,6 +220,23 @@ struct pcap {
*/
int bpf_codegen_flags;
+#if !defined(_WIN32) && !defined(MSDOS)
+ int selectable_fd; /* FD on which select()/poll()/epoll_wait()/kevent()/etc. can be done */
+
+ /*
+ * In case there either is no selectable FD, or there is but
+ * it doesn't necessarily work (e.g., if it doesn't get notified
+ * if the packet capture timeout expires before the buffer
+ * fills up), this points to a timeout that should be used
+ * in select()/poll()/epoll_wait()/kevent() call. The pcap_t should
+ * be put into non-blocking mode, and, if the timeout expires on
+ * the call, an attempt should be made to read packets from all
+ * pcap_t's with a required timeout, and the code must be
+ * prepared not to see any packets from the attempt.
+ */
+ struct timeval *required_select_timeout;
+#endif
+
/*
* Placeholder for filter code if bpf not in kernel.
*/
@@ -240,6 +258,7 @@ struct pcap {
activate_op_t activate_op;
can_set_rfmon_op_t can_set_rfmon_op;
inject_op_t inject_op;
+ save_current_filter_op_t save_current_filter_op;
setfilter_op_t setfilter_op;
setdirection_op_t setdirection_op;
set_datalink_op_t set_datalink_op;
@@ -378,8 +397,8 @@ int pcap_offline_read(pcap_t *, int, pcap_handler, u_char *);
* Routines that most pcap implementations can use for non-blocking mode.
*/
#if !defined(_WIN32) && !defined(MSDOS)
-int pcap_getnonblock_fd(pcap_t *, char *);
-int pcap_setnonblock_fd(pcap_t *p, int, char *);
+int pcap_getnonblock_fd(pcap_t *);
+int pcap_setnonblock_fd(pcap_t *p, int);
#endif
/*
@@ -404,32 +423,47 @@ int pcap_check_activated(pcap_t *);
/*
* Internal interfaces for "pcap_findalldevs()".
*
- * "pcap_platform_finddevs()" is a platform-dependent routine to
+ * A pcap_if_list_t * is a reference to a list of devices.
+ *
+ * A get_if_flags_func is a platform-dependent function called to get
+ * additional interface flags.
+ *
+ * "pcap_platform_finddevs()" is the platform-dependent routine to
* find local network interfaces.
*
* "pcap_findalldevs_interfaces()" is a helper to find those interfaces
* using the "standard" mechanisms (SIOCGIFCONF, "getifaddrs()", etc.).
*
- * "pcap_add_if()" adds an interface to the list of interfaces, for
- * use by various "find interfaces" routines.
+ * "add_dev()" adds an entry to a pcap_if_list_t.
+ *
+ * "find_dev()" tries to find a device, by name, in a pcap_if_list_t.
+ *
+ * "find_or_add_dev()" checks whether a device is already in a pcap_if_list_t
+ * and, if not, adds an entry for it.
*/
-int pcap_platform_finddevs(pcap_if_t **, char *);
+struct pcap_if_list;
+typedef struct pcap_if_list pcap_if_list_t;
+typedef int (*get_if_flags_func)(const char *, bpf_u_int32 *, char *);
+int pcap_platform_finddevs(pcap_if_list_t *, char *);
#if !defined(_WIN32) && !defined(MSDOS)
-int pcap_findalldevs_interfaces(pcap_if_t **, char *,
- int (*)(const char *));
+int pcap_findalldevs_interfaces(pcap_if_list_t *, char *,
+ int (*)(const char *), get_if_flags_func);
#endif
-int add_addr_to_iflist(pcap_if_t **, const char *, bpf_u_int32,
- struct sockaddr *, size_t, struct sockaddr *, size_t,
- struct sockaddr *, size_t, struct sockaddr *, size_t, char *);
+pcap_if_t *find_or_add_dev(pcap_if_list_t *, const char *, bpf_u_int32,
+ get_if_flags_func, const char *, char *);
+pcap_if_t *find_dev(pcap_if_list_t *, const char *);
+pcap_if_t *add_dev(pcap_if_list_t *, const char *, bpf_u_int32, const char *,
+ char *);
int add_addr_to_dev(pcap_if_t *, struct sockaddr *, size_t,
struct sockaddr *, size_t, struct sockaddr *, size_t,
struct sockaddr *dstaddr, size_t, char *errbuf);
-int pcap_add_if(pcap_if_t **, const char *, bpf_u_int32, const char *,
- char *);
-int add_or_find_if(pcap_if_t **, pcap_if_t **, const char *, bpf_u_int32,
- const char *, char *);
#ifndef _WIN32
-bpf_u_int32 if_flags_to_pcap_flags(const char *, u_int);
+pcap_if_t *find_or_add_if(pcap_if_list_t *, const char *, bpf_u_int32,
+ get_if_flags_func, char *);
+int add_addr_to_if(pcap_if_list_t *, const char *, bpf_u_int32,
+ get_if_flags_func,
+ struct sockaddr *, size_t, struct sockaddr *, size_t,
+ struct sockaddr *, size_t, struct sockaddr *, size_t, char *);
#endif
/*
@@ -462,6 +496,10 @@ int install_bpf_program(pcap_t *, struct bpf_program *);
int pcap_strcasecmp(const char *, const char *);
+#ifdef YYDEBUG
+extern int pcap_debug;
+#endif
+
#ifdef __cplusplus
}
#endif
diff --git a/contrib/libpcap/pcap-libdlpi.c b/contrib/libpcap/pcap-libdlpi.c
index 625f1e0a31ed5..a0d16693f6c2e 100644
--- a/contrib/libpcap/pcap-libdlpi.c
+++ b/contrib/libpcap/pcap-libdlpi.c
@@ -25,7 +25,7 @@
*/
#ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
#endif
#include <sys/types.h>
@@ -137,6 +137,17 @@ pcap_activate_libdlpi(pcap_t *p)
goto bad;
}
+ /*
+ * Turn a negative snapshot value (invalid), a snapshot value of
+ * 0 (unspecified), or a value bigger than the normal maximum
+ * value, into the maximum allowed value.
+ *
+ * If some application really *needs* a bigger snapshot
+ * length, we should just increase MAXIMUM_SNAPLEN.
+ */
+ if (p->snapshot <= 0 || p->snapshot > MAXIMUM_SNAPLEN)
+ p->snapshot = MAXIMUM_SNAPLEN;
+
/* Enable promiscuous mode. */
if (p->opt.promisc) {
retv = dlpromiscon(p, DL_PROMISC_PHYS);
@@ -209,8 +220,8 @@ pcap_activate_libdlpi(pcap_t *p)
*/
if (ioctl(p->fd, I_FLUSH, FLUSHR) != 0) {
status = PCAP_ERROR;
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "FLUSHR: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "FLUSHR");
goto bad;
}
@@ -276,13 +287,36 @@ is_dlpi_interface(const char *name _U_)
return (1);
}
+static int
+get_if_flags(const char *name _U_, bpf_u_int32 *flags _U_, char *errbuf _U_)
+{
+ /*
+ * Nothing we can do other than mark loopback devices as "the
+ * connected/disconnected status doesn't apply".
+ *
+ * XXX - on Solaris, can we do what the dladm command does,
+ * i.e. get a connected/disconnected indication from a kstat?
+ * (Note that you can also get the link speed, and possibly
+ * other information, from a kstat as well.)
+ */
+ if (*flags & PCAP_IF_LOOPBACK) {
+ /*
+ * Loopback devices aren't wireless, and "connected"/
+ * "disconnected" doesn't apply to them.
+ */
+ *flags |= PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE;
+ return (0);
+ }
+ return (0);
+}
+
/*
* In Solaris, the "standard" mechanism" i.e SIOCGLIFCONF will only find
* network links that are plumbed and are up. dlpi_walk(3DLPI) will find
* additional network links present in the system.
*/
int
-pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
+pcap_platform_finddevs(pcap_if_list_t *devlistp, char *errbuf)
{
int retv = 0;
@@ -293,23 +327,36 @@ pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
/*
* Get the list of regular interfaces first.
*/
- if (pcap_findalldevs_interfaces(alldevsp, errbuf, is_dlpi_interface) == -1)
+ if (pcap_findalldevs_interfaces(devlistp, errbuf,
+ is_dlpi_interface, get_if_flags) == -1)
return (-1); /* failure */
/* dlpi_walk() for loopback will be added here. */
+ /*
+ * Find all DLPI devices in the current zone.
+ *
+ * XXX - will pcap_findalldevs_interfaces() find any devices
+ * outside the current zone? If not, the only reason to call
+ * it would be to get the interface addresses.
+ */
dlpi_walk(list_interfaces, &lw, 0);
if (lw.lw_err != 0) {
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "dlpi_walk: %s", pcap_strerror(lw.lw_err));
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ lw.lw_err, "dlpi_walk");
retv = -1;
goto done;
}
/* Add linkname if it does not exist on the list. */
for (entry = lw.lw_list; entry != NULL; entry = entry->lnl_next) {
- if (pcap_add_if(alldevsp, entry->linkname, 0, NULL, errbuf) < 0)
+ /*
+ * If it isn't already in the list of devices, try to
+ * add it.
+ */
+ if (find_or_add_dev(devlistp, entry->linkname, 0, get_if_flags,
+ NULL, errbuf) == NULL)
retv = -1;
}
done:
@@ -437,3 +484,12 @@ pcap_create_interface(const char *device _U_, char *ebuf)
p->activate_op = pcap_activate_libdlpi;
return (p);
}
+
+/*
+ * Libpcap version string.
+ */
+const char *
+pcap_lib_version(void)
+{
+ return (PCAP_VERSION_STRING);
+}
diff --git a/contrib/libpcap/pcap-linktype.manmisc b/contrib/libpcap/pcap-linktype.manmisc
deleted file mode 100644
index fb9d40be0bb65..0000000000000
--- a/contrib/libpcap/pcap-linktype.manmisc
+++ /dev/null
@@ -1,48 +0,0 @@
-.\" Copyright (c) 1987, 1988, 1989, 1990, 1991, 1992, 1994, 1995, 1996, 1997
-.\" The Regents of the University of California. All rights reserved.
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that: (1) source code distributions
-.\" retain the above copyright notice and this paragraph in its entirety, (2)
-.\" distributions including binary code include the above copyright notice and
-.\" this paragraph in its entirety in the documentation or other materials
-.\" provided with the distribution, and (3) all advertising materials mentioning
-.\" features or use of this software display the following acknowledgement:
-.\" ``This product includes software developed by the University of California,
-.\" Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
-.\" the University nor the names of its contributors may be used to endorse
-.\" or promote products derived from this software without specific prior
-.\" written permission.
-.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
-.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
-.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
-.\"
-.TH PCAP-LINKTYPE 7 "12 March 2011"
-.SH NAME
-pcap-linktype \- link-layer header types supported by libpcap
-.SH DESCRIPTION
-For a live capture or ``savefile'', libpcap supplies, as the return
-value of the
-.BR pcap_datalink (3PCAP)
-routine, a value that indicates the type of link-layer header at the
-beginning of the packets it provides. This is not necessarily the type
-of link-layer header that the packets being captured have on the network
-from which they're being captured; for example, packets from an IEEE
-802.11 network might be provided by libpcap with Ethernet headers that
-the network adapter or the network adapter driver generates from the
-802.11 headers. The names for those values begin with
-.BR DLT_ ,
-so they are sometimes called "DLT_ values".
-.PP
-The values stored in the link-layer header type field in the savefile
-header are, in most but not all cases, the same as the values returned
-by
-.BR pcap_datalink() .
-The names for those values begin with
-.BR LINKTYPE_ .
-.PP
-The link-layer header types supported by libpcap are described at
-http://www.tcpdump.org/linktypes.html.
-.SH SEE ALSO
-pcap_datalink(3PCAP)
diff --git a/contrib/libpcap/pcap-linux.c b/contrib/libpcap/pcap-linux.c
index 924df42af0615..a35a379c46226 100644
--- a/contrib/libpcap/pcap-linux.c
+++ b/contrib/libpcap/pcap-linux.c
@@ -113,7 +113,7 @@
#define _GNU_SOURCE
#ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
#endif
#include <errno.h>
@@ -336,6 +336,8 @@ struct pcap_linux {
/*
* Prototypes for internal functions and methods.
*/
+static int get_if_flags(const char *, bpf_u_int32 *, char *);
+static int is_wifi(int, const char *);
static void map_arphrd_to_dlt(pcap_t *, int, int, const char *, int);
#ifdef HAVE_PF_PACKET_SOCKETS
static short int map_packet_type_to_sll_type(short int);
@@ -404,12 +406,52 @@ static int pcap_read_linux_mmap_v2(pcap_t *, int, pcap_handler , u_char *);
static int pcap_read_linux_mmap_v3(pcap_t *, int, pcap_handler , u_char *);
#endif
static int pcap_setfilter_linux_mmap(pcap_t *, struct bpf_program *);
-static int pcap_setnonblock_mmap(pcap_t *p, int nonblock, char *errbuf);
-static int pcap_getnonblock_mmap(pcap_t *p, char *errbuf);
+static int pcap_setnonblock_mmap(pcap_t *p, int nonblock);
+static int pcap_getnonblock_mmap(pcap_t *p);
static void pcap_oneshot_mmap(u_char *user, const struct pcap_pkthdr *h,
const u_char *bytes);
#endif
+/*
+ * In pre-3.0 kernels, the tp_vlan_tci field is set to whatever the
+ * vlan_tci field in the skbuff is. 0 can either mean "not on a VLAN"
+ * or "on VLAN 0". There is no flag set in the tp_status field to
+ * distinguish between them.
+ *
+ * In 3.0 and later kernels, if there's a VLAN tag present, the tp_vlan_tci
+ * field is set to the VLAN tag, and the TP_STATUS_VLAN_VALID flag is set
+ * in the tp_status field, otherwise the tp_vlan_tci field is set to 0 and
+ * the TP_STATUS_VLAN_VALID flag isn't set in the tp_status field.
+ *
+ * With a pre-3.0 kernel, we cannot distinguish between packets with no
+ * VLAN tag and packets on VLAN 0, so we will mishandle some packets, and
+ * there's nothing we can do about that.
+ *
+ * So, on those systems, which never set the TP_STATUS_VLAN_VALID flag, we
+ * continue the behavior of earlier libpcaps, wherein we treated packets
+ * with a VLAN tag of 0 as being packets without a VLAN tag rather than packets
+ * on VLAN 0. We do this by treating packets with a tp_vlan_tci of 0 and
+ * with the TP_STATUS_VLAN_VALID flag not set in tp_status as not having
+ * VLAN tags. This does the right thing on 3.0 and later kernels, and
+ * continues the old unfixably-imperfect behavior on pre-3.0 kernels.
+ *
+ * If TP_STATUS_VLAN_VALID isn't defined, we test it as the 0x10 bit; it
+ * has that value in 3.0 and later kernels.
+ */
+#ifdef TP_STATUS_VLAN_VALID
+ #define VLAN_VALID(hdr, hv) ((hv)->tp_vlan_tci != 0 || ((hdr)->tp_status & TP_STATUS_VLAN_VALID))
+#else
+ /*
+ * This is being compiled on a system that lacks TP_STATUS_VLAN_VALID,
+ * so we testwith the value it has in the 3.0 and later kernels, so
+ * we can test it if we're running on a system that has it. (If we're
+ * running on a system that doesn't have it, it won't be set in the
+ * tp_status field, so the tests of it will always fail; that means
+ * we behave the way we did before we introduced this macro.)
+ */
+ #define VLAN_VALID(hdr, hv) ((hv)->tp_vlan_tci != 0 || ((hdr)->tp_status & 0x10))
+#endif
+
#ifdef TP_STATUS_VLAN_TPID_VALID
# define VLAN_TPID(hdr, hv) (((hv)->tp_vlan_tpid || ((hdr)->tp_status & TP_STATUS_VLAN_TPID_VALID)) ? (hv)->tp_vlan_tpid : ETH_P_8021Q)
#else
@@ -425,7 +467,7 @@ static int iface_get_id(int fd, const char *device, char *ebuf);
static int iface_get_mtu(int fd, const char *device, char *ebuf);
static int iface_get_arptype(int fd, const char *device, char *ebuf);
#ifdef HAVE_PF_PACKET_SOCKETS
-static int iface_bind(int fd, int ifindex, char *ebuf);
+static int iface_bind(int fd, int ifindex, char *ebuf, int protocol);
#ifdef IW_MODE_MONITOR
static int has_wext(int sock_fd, const char *device, char *ebuf);
#endif /* IW_MODE_MONITOR */
@@ -488,8 +530,8 @@ pcap_create_interface(const char *device, char *ebuf)
handle->tstamp_precision_count = 2;
handle->tstamp_precision_list = malloc(2 * sizeof(u_int));
if (handle->tstamp_precision_list == NULL) {
- pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
+ errno, "malloc");
pcap_close(handle);
return NULL;
}
@@ -575,9 +617,8 @@ get_mac80211_phydev(pcap_t *handle, const char *device, char *phydev_path,
free(pathstr);
return 0;
}
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "%s: Can't readlink %s: %s", device, pathstr,
- strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "%s: Can't readlink %s", device, pathstr);
free(pathstr);
return PCAP_ERROR;
}
@@ -772,8 +813,8 @@ add_mon_if(pcap_t *handle, int sock_fd, struct nl80211_state *state,
*/
handlep->mondevice = strdup(mondevice);
if (handlep->mondevice == NULL) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "strdup: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "strdup");
/*
* Get rid of the monitor device.
*/
@@ -938,9 +979,9 @@ added:
memset(&ifr, 0, sizeof(ifr));
strlcpy(ifr.ifr_name, handlep->mondevice, sizeof(ifr.ifr_name));
if (ioctl(sock_fd, SIOCGIFFLAGS, &ifr) == -1) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "%s: Can't get flags for %s: %s", device,
- handlep->mondevice, strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "%s: Can't get flags for %s", device,
+ handlep->mondevice);
del_mon_if(handle, sock_fd, &nlstate, device,
handlep->mondevice);
nl80211_cleanup(&nlstate);
@@ -948,9 +989,9 @@ added:
}
ifr.ifr_flags |= IFF_UP|IFF_RUNNING;
if (ioctl(sock_fd, SIOCSIFFLAGS, &ifr) == -1) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "%s: Can't set flags for %s: %s", device,
- handlep->mondevice, strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "%s: Can't set flags for %s", device,
+ handlep->mondevice);
del_mon_if(handle, sock_fd, &nlstate, device,
handlep->mondevice);
nl80211_cleanup(&nlstate);
@@ -1008,6 +1049,17 @@ is_bonding_device(int fd, const char *device)
}
#endif /* IW_MODE_MONITOR */
+static int pcap_protocol(pcap_t *handle)
+{
+ int protocol;
+
+ protocol = handle->opt.protocol;
+ if (protocol == 0)
+ protocol = ETH_P_ALL;
+
+ return htons(protocol);
+}
+
static int
pcap_can_set_rfmon_linux(pcap_t *handle)
{
@@ -1059,10 +1111,10 @@ pcap_can_set_rfmon_linux(pcap_t *handle)
* (We assume that if we have Wireless Extensions support
* we also have PF_PACKET support.)
*/
- sock_fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
+ sock_fd = socket(PF_PACKET, SOCK_RAW, pcap_protocol(handle));
if (sock_fd == -1) {
- (void)pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "socket: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "socket");
return PCAP_ERROR;
}
@@ -1086,8 +1138,8 @@ pcap_can_set_rfmon_linux(pcap_t *handle)
}
if (errno == ENODEV) {
/* The device doesn't even exist. */
- (void)pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "SIOCGIWMODE failed: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "SIOCGIWMODE failed");
close(sock_fd);
return PCAP_ERROR_NO_SUCH_DEVICE;
}
@@ -1446,6 +1498,17 @@ pcap_activate_linux(pcap_t *handle)
goto fail;
}
+ /*
+ * Turn a negative snapshot value (invalid), a snapshot value of
+ * 0 (unspecified), or a value bigger than the normal maximum
+ * value, into the maximum allowed value.
+ *
+ * If some application really *needs* a bigger snapshot
+ * length, we should just increase MAXIMUM_SNAPLEN.
+ */
+ if (handle->snapshot <= 0 || handle->snapshot > MAXIMUM_SNAPLEN)
+ handle->snapshot = MAXIMUM_SNAPLEN;
+
handle->inject_op = pcap_inject_linux;
handle->setfilter_op = pcap_setfilter_linux;
handle->setdirection_op = pcap_setdirection_linux;
@@ -1473,8 +1536,8 @@ pcap_activate_linux(pcap_t *handle)
handlep->device = strdup(device);
if (handlep->device == NULL) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "strdup: %s",
- pcap_strerror(errno) );
+ pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "strdup");
return PCAP_ERROR;
}
@@ -1570,8 +1633,8 @@ pcap_activate_linux(pcap_t *handle)
if (setsockopt(handle->fd, SOL_SOCKET, SO_RCVBUF,
&handle->opt.buffer_size,
sizeof(handle->opt.buffer_size)) == -1) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "SO_RCVBUF: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf,
+ PCAP_ERRBUF_SIZE, errno, "SO_RCVBUF");
status = PCAP_ERROR;
goto fail;
}
@@ -1581,8 +1644,8 @@ pcap_activate_linux(pcap_t *handle)
handle->buffer = malloc(handle->bufsize + handle->offset);
if (!handle->buffer) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "malloc: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "malloc");
status = PCAP_ERROR;
goto fail;
}
@@ -1606,7 +1669,7 @@ fail:
* error occured.
*/
static int
-pcap_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user)
+pcap_read_linux(pcap_t *handle, int max_packets _U_, pcap_handler callback, u_char *user)
{
/*
* Currently, on Linux only one packet is delivered per read,
@@ -1691,7 +1754,7 @@ pcap_read_packet(pcap_t *handle, pcap_handler callback, u_char *userdata)
#else
struct sockaddr from;
#endif
-#if defined(HAVE_PACKET_AUXDATA) && defined(HAVE_LINUX_TPACKET_AUXDATA_TP_VLAN_TCI)
+#if defined(HAVE_PACKET_AUXDATA) && defined(HAVE_STRUCT_TPACKET_AUXDATA_TP_VLAN_TCI)
struct iovec iov;
struct msghdr msg;
struct cmsghdr *cmsg;
@@ -1699,9 +1762,9 @@ pcap_read_packet(pcap_t *handle, pcap_handler callback, u_char *userdata)
struct cmsghdr cmsg;
char buf[CMSG_SPACE(sizeof(struct tpacket_auxdata))];
} cmsg_buf;
-#else /* defined(HAVE_PACKET_AUXDATA) && defined(HAVE_LINUX_TPACKET_AUXDATA_TP_VLAN_TCI) */
+#else /* defined(HAVE_PACKET_AUXDATA) && defined(HAVE_STRUCT_TPACKET_AUXDATA_TP_VLAN_TCI) */
socklen_t fromlen;
-#endif /* defined(HAVE_PACKET_AUXDATA) && defined(HAVE_LINUX_TPACKET_AUXDATA_TP_VLAN_TCI) */
+#endif /* defined(HAVE_PACKET_AUXDATA) && defined(HAVE_STRUCT_TPACKET_AUXDATA_TP_VLAN_TCI) */
int packet_len, caplen;
struct pcap_pkthdr pcap_header;
@@ -1740,7 +1803,7 @@ pcap_read_packet(pcap_t *handle, pcap_handler callback, u_char *userdata)
*/
bp = (u_char *)handle->buffer + handle->offset;
-#if defined(HAVE_PACKET_AUXDATA) && defined(HAVE_LINUX_TPACKET_AUXDATA_TP_VLAN_TCI)
+#if defined(HAVE_PACKET_AUXDATA) && defined(HAVE_STRUCT_TPACKET_AUXDATA_TP_VLAN_TCI)
msg.msg_name = &from;
msg.msg_namelen = sizeof(from);
msg.msg_iov = &iov;
@@ -1751,7 +1814,7 @@ pcap_read_packet(pcap_t *handle, pcap_handler callback, u_char *userdata)
iov.iov_len = handle->bufsize - offset;
iov.iov_base = bp + offset;
-#endif /* defined(HAVE_PACKET_AUXDATA) && defined(HAVE_LINUX_TPACKET_AUXDATA_TP_VLAN_TCI) */
+#endif /* defined(HAVE_PACKET_AUXDATA) && defined(HAVE_STRUCT_TPACKET_AUXDATA_TP_VLAN_TCI) */
do {
/*
@@ -1767,15 +1830,15 @@ pcap_read_packet(pcap_t *handle, pcap_handler callback, u_char *userdata)
return PCAP_ERROR_BREAK;
}
-#if defined(HAVE_PACKET_AUXDATA) && defined(HAVE_LINUX_TPACKET_AUXDATA_TP_VLAN_TCI)
+#if defined(HAVE_PACKET_AUXDATA) && defined(HAVE_STRUCT_TPACKET_AUXDATA_TP_VLAN_TCI)
packet_len = recvmsg(handle->fd, &msg, MSG_TRUNC);
-#else /* defined(HAVE_PACKET_AUXDATA) && defined(HAVE_LINUX_TPACKET_AUXDATA_TP_VLAN_TCI) */
+#else /* defined(HAVE_PACKET_AUXDATA) && defined(HAVE_STRUCT_TPACKET_AUXDATA_TP_VLAN_TCI) */
fromlen = sizeof(from);
packet_len = recvfrom(
handle->fd, bp + offset,
handle->bufsize - offset, MSG_TRUNC,
(struct sockaddr *) &from, &fromlen);
-#endif /* defined(HAVE_PACKET_AUXDATA) && defined(HAVE_LINUX_TPACKET_AUXDATA_TP_VLAN_TCI) */
+#endif /* defined(HAVE_PACKET_AUXDATA) && defined(HAVE_STRUCT_TPACKET_AUXDATA_TP_VLAN_TCI) */
} while (packet_len == -1 && errno == EINTR);
/* Check if an error occured */
@@ -1799,8 +1862,8 @@ pcap_read_packet(pcap_t *handle, pcap_handler callback, u_char *userdata)
return PCAP_ERROR;
default:
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "recvfrom: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf,
+ PCAP_ERRBUF_SIZE, errno, "recvfrom");
return PCAP_ERROR;
}
}
@@ -1856,7 +1919,12 @@ pcap_read_packet(pcap_t *handle, pcap_handler callback, u_char *userdata)
hdrp->sll_protocol = from.sll_protocol;
}
-#if defined(HAVE_PACKET_AUXDATA) && defined(HAVE_LINUX_TPACKET_AUXDATA_TP_VLAN_TCI)
+ /*
+ * Start out with no VLAN information.
+ */
+ aux_data.vlan_tag_present = 0;
+ aux_data.vlan_tag = 0;
+#if defined(HAVE_PACKET_AUXDATA) && defined(HAVE_STRUCT_TPACKET_AUXDATA_TP_VLAN_TCI)
if (handlep->vlan_offset != -1) {
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
struct tpacket_auxdata *aux;
@@ -1865,18 +1933,22 @@ pcap_read_packet(pcap_t *handle, pcap_handler callback, u_char *userdata)
if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct tpacket_auxdata)) ||
cmsg->cmsg_level != SOL_PACKET ||
- cmsg->cmsg_type != PACKET_AUXDATA)
+ cmsg->cmsg_type != PACKET_AUXDATA) {
+ /*
+ * This isn't a PACKET_AUXDATA auxiliary
+ * data item.
+ */
continue;
+ }
aux = (struct tpacket_auxdata *)CMSG_DATA(cmsg);
-#if defined(TP_STATUS_VLAN_VALID)
- if ((aux->tp_vlan_tci == 0) && !(aux->tp_status & TP_STATUS_VLAN_VALID))
-#else
- if (aux->tp_vlan_tci == 0) /* this is ambigious but without the
- TP_STATUS_VLAN_VALID flag, there is
- nothing that we can do */
-#endif
+ if (!VLAN_VALID(aux, aux)) {
+ /*
+ * There is no VLAN information in the
+ * auxiliary data.
+ */
continue;
+ }
len = (u_int)packet_len > iov.iov_len ? iov.iov_len : (u_int)packet_len;
if (len < (u_int)handlep->vlan_offset)
@@ -1898,11 +1970,14 @@ pcap_read_packet(pcap_t *handle, pcap_handler callback, u_char *userdata)
tag->vlan_tpid = htons(VLAN_TPID(aux, aux));
tag->vlan_tci = htons(aux->tp_vlan_tci);
- /* store vlan tci to bpf_aux_data struct for userland bpf filter */
-#if defined(TP_STATUS_VLAN_VALID)
- aux_data.vlan_tag = htons(aux->tp_vlan_tci) & 0x0fff;
- aux_data.vlan_tag_present = (aux->tp_status & TP_STATUS_VLAN_VALID);
-#endif
+ /*
+ * Save a flag indicating that we have a VLAN tag,
+ * and the VLAN TCI, to bpf_aux_data struct for
+ * use by the BPF filter if we're doing the
+ * filtering in userland.
+ */
+ aux_data.vlan_tag_present = 1;
+ aux_data.vlan_tag = htons(aux->tp_vlan_tci) & 0x0fff;
/*
* Add the tag to the packet lengths.
@@ -1910,7 +1985,7 @@ pcap_read_packet(pcap_t *handle, pcap_handler callback, u_char *userdata)
packet_len += VLAN_TAG_LEN;
}
}
-#endif /* defined(HAVE_PACKET_AUXDATA) && defined(HAVE_LINUX_TPACKET_AUXDATA_TP_VLAN_TCI) */
+#endif /* defined(HAVE_PACKET_AUXDATA) && defined(HAVE_STRUCT_TPACKET_AUXDATA_TP_VLAN_TCI) */
#endif /* HAVE_PF_PACKET_SOCKETS */
/*
@@ -1964,16 +2039,16 @@ pcap_read_packet(pcap_t *handle, pcap_handler callback, u_char *userdata)
#if defined(SIOCGSTAMPNS) && defined(SO_TIMESTAMPNS)
if (handle->opt.tstamp_precision == PCAP_TSTAMP_PRECISION_NANO) {
if (ioctl(handle->fd, SIOCGSTAMPNS, &pcap_header.ts) == -1) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "SIOCGSTAMPNS: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf,
+ PCAP_ERRBUF_SIZE, errno, "SIOCGSTAMPNS");
return PCAP_ERROR;
}
} else
#endif
{
if (ioctl(handle->fd, SIOCGSTAMP, &pcap_header.ts) == -1) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "SIOCGSTAMP: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf,
+ PCAP_ERRBUF_SIZE, errno, "SIOCGSTAMP");
return PCAP_ERROR;
}
}
@@ -2002,7 +2077,7 @@ pcap_read_packet(pcap_t *handle, pcap_handler callback, u_char *userdata)
* We count them here even if we can get the packet count
* from the kernel, as we can only determine at run time
* whether we'll be able to get it from the kernel (if
- * HAVE_TPACKET_STATS isn't defined, we can't get it from
+ * HAVE_STRUCT_TPACKET_STATS isn't defined, we can't get it from
* the kernel, but if it is defined, the library might
* have been built with a 2.4 or later kernel, but we
* might be running on a 2.2[.x] kernel without Alexey
@@ -2070,8 +2145,8 @@ pcap_inject_linux(pcap_t *handle, const void *buf, size_t size)
ret = send(handle->fd, buf, size, 0);
if (ret == -1) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "send");
return (-1);
}
return (ret);
@@ -2089,7 +2164,7 @@ static int
pcap_stats_linux(pcap_t *handle, struct pcap_stat *stats)
{
struct pcap_linux *handlep = handle->priv;
-#ifdef HAVE_TPACKET_STATS
+#ifdef HAVE_STRUCT_TPACKET_STATS
#ifdef HAVE_TPACKET3
/*
* For sockets using TPACKET_V1 or TPACKET_V2, the extra
@@ -2110,7 +2185,7 @@ pcap_stats_linux(pcap_t *handle, struct pcap_stat *stats)
struct tpacket_stats kstats;
#endif /* HAVE_TPACKET3 */
socklen_t len = sizeof (struct tpacket_stats);
-#endif /* HAVE_TPACKET_STATS */
+#endif /* HAVE_STRUCT_TPACKET_STATS */
long if_dropped = 0;
@@ -2124,7 +2199,7 @@ pcap_stats_linux(pcap_t *handle, struct pcap_stat *stats)
handlep->stat.ps_ifdrop += (handlep->proc_dropped - if_dropped);
}
-#ifdef HAVE_TPACKET_STATS
+#ifdef HAVE_STRUCT_TPACKET_STATS
/*
* Try to get the packet counts from the kernel.
*/
@@ -2192,8 +2267,8 @@ pcap_stats_linux(pcap_t *handle, struct pcap_stat *stats)
* is built on a system without "struct tpacket_stats".
*/
if (errno != EOPNOTSUPP) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "pcap_stats: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf,
+ PCAP_ERRBUF_SIZE, errno, "pcap_stats");
return -1;
}
}
@@ -2230,7 +2305,7 @@ pcap_stats_linux(pcap_t *handle, struct pcap_stat *stats)
}
static int
-add_linux_if(pcap_if_t **devlistp, const char *ifname, int fd, char *errbuf)
+add_linux_if(pcap_if_list_t *devlistp, const char *ifname, int fd, char *errbuf)
{
const char *p;
char name[512]; /* XXX - pick a size */
@@ -2278,20 +2353,19 @@ add_linux_if(pcap_if_t **devlistp, const char *ifname, int fd, char *errbuf)
if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifrflags) < 0) {
if (errno == ENXIO || errno == ENODEV)
return (0); /* device doesn't actually exist - ignore it */
- (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "SIOCGIFFLAGS: %.*s: %s",
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ errno, "SIOCGIFFLAGS: %.*s",
(int)sizeof(ifrflags.ifr_name),
- ifrflags.ifr_name,
- pcap_strerror(errno));
+ ifrflags.ifr_name);
return (-1);
}
/*
- * Add an entry for this interface, with no addresses.
+ * Add an entry for this interface, with no addresses, if it's
+ * not already in the list.
*/
- if (pcap_add_if(devlistp, name,
- if_flags_to_pcap_flags(name, ifrflags.ifr_flags), NULL,
- errbuf) == -1) {
+ if (find_or_add_if(devlistp, name, ifrflags.ifr_flags,
+ get_if_flags, errbuf) == NULL) {
/*
* Failure.
*/
@@ -2318,7 +2392,7 @@ add_linux_if(pcap_if_t **devlistp, const char *ifname, int fd, char *errbuf)
* Otherwise, we return 1 if we don't get an error and -1 if we do.
*/
static int
-scan_sys_class_net(pcap_if_t **devlistp, char *errbuf)
+scan_sys_class_net(pcap_if_list_t *devlistp, char *errbuf)
{
DIR *sys_class_net_d;
int fd;
@@ -2338,8 +2412,8 @@ scan_sys_class_net(pcap_if_t **devlistp, char *errbuf)
/*
* Fail if we got some other error.
*/
- (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "Can't open /sys/class/net: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ errno, "Can't open /sys/class/net");
return (-1);
}
@@ -2348,8 +2422,8 @@ scan_sys_class_net(pcap_if_t **devlistp, char *errbuf)
*/
fd = socket(PF_UNIX, SOCK_RAW, 0);
if (fd < 0) {
- (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "socket: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ errno, "socket");
(void)closedir(sys_class_net_d);
return (-1);
}
@@ -2416,9 +2490,8 @@ scan_sys_class_net(pcap_if_t **devlistp, char *errbuf)
* fail due to an error reading the directory?
*/
if (errno != 0) {
- (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "Error reading /sys/class/net: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ errno, "Error reading /sys/class/net");
ret = -1;
}
}
@@ -2436,7 +2509,7 @@ scan_sys_class_net(pcap_if_t **devlistp, char *errbuf)
* See comments from scan_sys_class_net().
*/
static int
-scan_proc_net_dev(pcap_if_t **devlistp, char *errbuf)
+scan_proc_net_dev(pcap_if_list_t *devlistp, char *errbuf)
{
FILE *proc_net_f;
int fd;
@@ -2456,8 +2529,8 @@ scan_proc_net_dev(pcap_if_t **devlistp, char *errbuf)
/*
* Fail if we got some other error.
*/
- (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "Can't open /proc/net/dev: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ errno, "Can't open /proc/net/dev");
return (-1);
}
@@ -2466,8 +2539,8 @@ scan_proc_net_dev(pcap_if_t **devlistp, char *errbuf)
*/
fd = socket(PF_UNIX, SOCK_RAW, 0);
if (fd < 0) {
- (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "socket: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ errno, "socket");
(void)fclose(proc_net_f);
return (-1);
}
@@ -2505,9 +2578,8 @@ scan_proc_net_dev(pcap_if_t **devlistp, char *errbuf)
* fail due to an error reading the file?
*/
if (ferror(proc_net_f)) {
- (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "Error reading /proc/net/dev: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ errno, "Error reading /proc/net/dev");
ret = -1;
}
}
@@ -2531,15 +2603,187 @@ can_be_bound(const char *name _U_)
return (1);
}
+/*
+ * Get additional flags for a device, using SIOCGIFMEDIA.
+ */
+static int
+get_if_flags(const char *name, bpf_u_int32 *flags, char *errbuf)
+{
+ int sock;
+ FILE *fh;
+ unsigned int arptype;
+ struct ifreq ifr;
+ struct ethtool_value info;
+
+ if (*flags & PCAP_IF_LOOPBACK) {
+ /*
+ * Loopback devices aren't wireless, and "connected"/
+ * "disconnected" doesn't apply to them.
+ */
+ *flags |= PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE;
+ return 0;
+ }
+
+ sock = socket(AF_INET, SOCK_DGRAM, 0);
+ if (sock == -1) {
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, errno,
+ "Can't create socket to get ethtool information for %s",
+ name);
+ return -1;
+ }
+
+ /*
+ * OK, what type of network is this?
+ * In particular, is it wired or wireless?
+ */
+ if (is_wifi(sock, name)) {
+ /*
+ * Wi-Fi, hence wireless.
+ */
+ *flags |= PCAP_IF_WIRELESS;
+ } else {
+ /*
+ * OK, what does /sys/class/net/{if}/type contain?
+ * (We don't use that for Wi-Fi, as it'll report
+ * "Ethernet", i.e. ARPHRD_ETHER, for non-monitor-
+ * mode devices.)
+ */
+ char *pathstr;
+
+ if (asprintf(&pathstr, "/sys/class/net/%s/type", name) == -1) {
+ pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "%s: Can't generate path name string for /sys/class/net device",
+ name);
+ close(sock);
+ return -1;
+ }
+ fh = fopen(pathstr, "r");
+ if (fh != NULL) {
+ if (fscanf(fh, "%u", &arptype) == 1) {
+ /*
+ * OK, we got an ARPHRD_ type; what is it?
+ */
+ switch (arptype) {
+
+#ifdef ARPHRD_LOOPBACK
+ case ARPHRD_LOOPBACK:
+ /*
+ * These are types to which
+ * "connected" and "disconnected"
+ * don't apply, so don't bother
+ * asking about it.
+ *
+ * XXX - add other types?
+ */
+ close(sock);
+ fclose(fh);
+ free(pathstr);
+ return 0;
+#endif
+
+ case ARPHRD_IRDA:
+ case ARPHRD_IEEE80211:
+ case ARPHRD_IEEE80211_PRISM:
+ case ARPHRD_IEEE80211_RADIOTAP:
+#ifdef ARPHRD_IEEE802154
+ case ARPHRD_IEEE802154:
+#endif
+#ifdef ARPHRD_IEEE802154_MONITOR
+ case ARPHRD_IEEE802154_MONITOR:
+#endif
+#ifdef ARPHRD_6LOWPAN
+ case ARPHRD_6LOWPAN:
+#endif
+ /*
+ * Various wireless types.
+ */
+ *flags |= PCAP_IF_WIRELESS;
+ break;
+ }
+ }
+ fclose(fh);
+ free(pathstr);
+ }
+ }
+
+#ifdef ETHTOOL_GLINK
+ memset(&ifr, 0, sizeof(ifr));
+ strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
+ info.cmd = ETHTOOL_GLINK;
+ ifr.ifr_data = (caddr_t)&info;
+ if (ioctl(sock, SIOCETHTOOL, &ifr) == -1) {
+ int save_errno = errno;
+
+ switch (save_errno) {
+
+ case EOPNOTSUPP:
+ case EINVAL:
+ /*
+ * OK, this OS version or driver doesn't support
+ * asking for this information.
+ * XXX - distinguish between "this doesn't
+ * support ethtool at all because it's not
+ * that type of device" vs. "this doesn't
+ * support ethtool even though it's that
+ * type of device", and return "unknown".
+ */
+ *flags |= PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE;
+ close(sock);
+ return 0;
+
+ case ENODEV:
+ /*
+ * OK, no such device.
+ * The user will find that out when they try to
+ * activate the device; just say "OK" and
+ * don't set anything.
+ */
+ close(sock);
+ return 0;
+
+ default:
+ /*
+ * Other error.
+ */
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ save_errno,
+ "%s: SIOCETHTOOL(ETHTOOL_GLINK) ioctl failed",
+ name);
+ close(sock);
+ return -1;
+ }
+ }
+
+ /*
+ * Is it connected?
+ */
+ if (info.data) {
+ /*
+ * It's connected.
+ */
+ *flags |= PCAP_IF_CONNECTION_STATUS_CONNECTED;
+ } else {
+ /*
+ * It's disconnected.
+ */
+ *flags |= PCAP_IF_CONNECTION_STATUS_DISCONNECTED;
+ }
+#endif
+
+ close(sock);
+ return 0;
+}
+
int
-pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
+pcap_platform_finddevs(pcap_if_list_t *devlistp, char *errbuf)
{
int ret;
/*
* Get the list of regular interfaces first.
*/
- if (pcap_findalldevs_interfaces(alldevsp, errbuf, can_be_bound) == -1)
+ if (pcap_findalldevs_interfaces(devlistp, errbuf, can_be_bound,
+ get_if_flags) == -1)
return (-1); /* failure */
/*
@@ -2550,22 +2794,26 @@ pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
* interfaces with no addresses, so you need to read "/sys/class/net"
* to get the names of the rest of the interfaces.
*/
- ret = scan_sys_class_net(alldevsp, errbuf);
+ ret = scan_sys_class_net(devlistp, errbuf);
if (ret == -1)
return (-1); /* failed */
if (ret == 0) {
/*
* No /sys/class/net; try reading /proc/net/dev instead.
*/
- if (scan_proc_net_dev(alldevsp, errbuf) == -1)
+ if (scan_proc_net_dev(devlistp, errbuf) == -1)
return (-1);
}
/*
* Add the "any" device.
+ * As it refers to all network devices, not to any particular
+ * network device, the notion of "connected" vs. "disconnected"
+ * doesn't apply.
*/
- if (pcap_add_if(alldevsp, "any", PCAP_IF_UP|PCAP_IF_RUNNING,
- any_descr, errbuf) < 0)
+ if (add_dev(devlistp, "any",
+ PCAP_IF_UP|PCAP_IF_RUNNING|PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE,
+ any_descr, errbuf) == NULL)
return (-1);
return (0);
@@ -2725,9 +2973,9 @@ pcap_setfilter_linux_common(pcap_t *handle, struct bpf_program *filter,
*/
if (handlep->filter_in_userland) {
if (reset_kernel_filter(handle) == -1) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "can't remove kernel filter: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf,
+ PCAP_ERRBUF_SIZE, errno,
+ "can't remove kernel filter");
err = -2; /* fatal error */
}
}
@@ -3226,7 +3474,7 @@ static void map_arphrd_to_dlt(pcap_t *handle, int sock_fd, int arptype,
* IP-over-FC on which somebody wants to capture
* packets.
*/
- handle->dlt_list = (u_int *) malloc(sizeof(u_int) * 2);
+ handle->dlt_list = (u_int *) malloc(sizeof(u_int) * 3);
/*
* If that fails, just leave the list empty.
*/
@@ -3295,6 +3543,13 @@ static void map_arphrd_to_dlt(pcap_t *handle, int sock_fd, int arptype,
/* handlep->cooked = 1; */
break;
+#ifndef ARPHRD_VSOCKMON
+#define ARPHRD_VSOCKMON 826
+#endif
+ case ARPHRD_VSOCKMON:
+ handle->linktype = DLT_VSOCK;
+ break;
+
default:
handle->linktype = -1;
break;
@@ -3317,6 +3572,7 @@ activate_new(pcap_t *handle)
struct pcap_linux *handlep = handle->priv;
const char *device = handle->opt.device;
int is_any_device = (strcmp(device, "any") == 0);
+ int protocol = pcap_protocol(handle);
int sock_fd = -1, arptype;
#ifdef HAVE_PACKET_AUXDATA
int val;
@@ -3335,8 +3591,8 @@ activate_new(pcap_t *handle)
* try a SOCK_RAW socket for the raw interface.
*/
sock_fd = is_any_device ?
- socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_ALL)) :
- socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
+ socket(PF_PACKET, SOCK_DGRAM, protocol) :
+ socket(PF_PACKET, SOCK_RAW, protocol);
if (sock_fd == -1) {
if (errno == EINVAL || errno == EAFNOSUPPORT) {
@@ -3347,8 +3603,8 @@ activate_new(pcap_t *handle)
return 0;
}
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "socket: %s",
- pcap_strerror(errno) );
+ pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "socket");
if (errno == EPERM || errno == EACCES) {
/*
* You don't have permission to open the
@@ -3449,15 +3705,14 @@ activate_new(pcap_t *handle)
* kernels) - reopen in cooked mode.
*/
if (close(sock_fd) == -1) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "close: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf,
+ PCAP_ERRBUF_SIZE, errno, "close");
return PCAP_ERROR;
}
- sock_fd = socket(PF_PACKET, SOCK_DGRAM,
- htons(ETH_P_ALL));
+ sock_fd = socket(PF_PACKET, SOCK_DGRAM, protocol);
if (sock_fd == -1) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "socket: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf,
+ PCAP_ERRBUF_SIZE, errno, "socket");
if (errno == EPERM || errno == EACCES) {
/*
* You don't have permission to
@@ -3518,7 +3773,7 @@ activate_new(pcap_t *handle)
}
if ((err = iface_bind(sock_fd, handlep->ifindex,
- handle->errbuf)) != 1) {
+ handle->errbuf, protocol)) != 1) {
close(sock_fd);
if (err < 0)
return err;
@@ -3581,8 +3836,8 @@ activate_new(pcap_t *handle)
mr.mr_type = PACKET_MR_PROMISC;
if (setsockopt(sock_fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP,
&mr, sizeof(mr)) == -1) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "setsockopt: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf,
+ PCAP_ERRBUF_SIZE, errno, "setsockopt");
close(sock_fd);
return PCAP_ERROR;
}
@@ -3594,8 +3849,8 @@ activate_new(pcap_t *handle)
val = 1;
if (setsockopt(sock_fd, SOL_PACKET, PACKET_AUXDATA, &val,
sizeof(val)) == -1 && errno != ENOPROTOOPT) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "setsockopt: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "setsockopt");
close(sock_fd);
return PCAP_ERROR;
}
@@ -3717,9 +3972,8 @@ activate_mmap(pcap_t *handle, int *status)
*/
handlep->oneshot_buffer = malloc(handle->snapshot);
if (handlep->oneshot_buffer == NULL) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "can't allocate oneshot buffer: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "can't allocate oneshot buffer");
*status = PCAP_ERROR;
return -1;
}
@@ -3822,10 +4076,9 @@ init_tpacket(pcap_t *handle, int version, const char *version_str)
return 1; /* no */
/* Failed to even find out; this is a fatal error. */
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "can't get %s header len on packet socket: %s",
- version_str,
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "can't get %s header len on packet socket",
+ version_str);
return -1;
}
handlep->tp_hdrlen = val;
@@ -3833,10 +4086,8 @@ init_tpacket(pcap_t *handle, int version, const char *version_str)
val = version;
if (setsockopt(handle->fd, SOL_PACKET, PACKET_VERSION, &val,
sizeof(val)) < 0) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "can't activate %s on packet socket: %s",
- version_str,
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "can't activate %s on packet socket", version_str);
return -1;
}
handlep->tp_version = version;
@@ -3845,9 +4096,8 @@ init_tpacket(pcap_t *handle, int version, const char *version_str)
val = VLAN_TAG_LEN;
if (setsockopt(handle->fd, SOL_PACKET, PACKET_RESERVE, &val,
sizeof(val)) < 0) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "can't set up reserve on packet socket: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "can't set up reserve on packet socket");
return -1;
}
@@ -3977,8 +4227,8 @@ prepare_tpacket_socket(pcap_t *handle)
/*
* Failed.
*/
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "uname failed: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf,
+ PCAP_ERRBUF_SIZE, errno, "uname failed");
return -1;
}
if (strcmp(utsname.machine, ISA_64_BIT) == 0) {
@@ -3999,6 +4249,8 @@ prepare_tpacket_socket(pcap_t *handle)
return 1;
}
+#define MAX(a,b) ((a)>(b)?(a):(b))
+
/*
* Attempt to set up memory-mapped access.
*
@@ -4042,10 +4294,10 @@ create_ring(pcap_t *handle, int *status)
#ifdef HAVE_TPACKET2
case TPACKET_V2:
#endif
- /* Note that with large snapshot length (say 64K, which is
- * the default for recent versions of tcpdump, the value that
- * "-s 0" has given for a long time with tcpdump, and the
- * default in Wireshark/TShark/dumpcap), if we use the snapshot
+ /* Note that with large snapshot length (say 256K, which is
+ * the default for recent versions of tcpdump, Wireshark,
+ * TShark, dumpcap or 64K, the value that "-s 0" has given for
+ * a long time with tcpdump), if we use the snapshot
* length to calculate the frame length, only a few frames
* will be available in the ring even with pretty
* large ring size (and a lot of memory will be unused).
@@ -4069,29 +4321,35 @@ create_ring(pcap_t *handle, int *status)
* based on the MTU, so that the MTU limits the maximum size
* of packets that we can receive.)
*
- * We don't do that if segmentation/fragmentation or receive
- * offload are enabled, so we don't get rudely surprised by
- * "packets" bigger than the MTU. */
+ * If segmentation/fragmentation or receive offload are
+ * enabled, we can get reassembled/aggregated packets larger
+ * than MTU, but bounded to 65535 plus the Ethernet overhead,
+ * due to kernel and protocol constraints */
frame_size = handle->snapshot;
if (handle->linktype == DLT_EN10MB) {
+ unsigned int max_frame_len;
int mtu;
int offload;
+ mtu = iface_get_mtu(handle->fd, handle->opt.device,
+ handle->errbuf);
+ if (mtu == -1) {
+ *status = PCAP_ERROR;
+ return -1;
+ }
offload = iface_get_offload(handle);
if (offload == -1) {
*status = PCAP_ERROR;
return -1;
}
- if (!offload) {
- mtu = iface_get_mtu(handle->fd, handle->opt.device,
- handle->errbuf);
- if (mtu == -1) {
- *status = PCAP_ERROR;
- return -1;
- }
- if (frame_size > (unsigned int)mtu + 18)
- frame_size = (unsigned int)mtu + 18;
- }
+ if (offload)
+ max_frame_len = MAX(mtu, 65535);
+ else
+ max_frame_len = mtu;
+ max_frame_len += 18;
+
+ if (frame_size > max_frame_len)
+ frame_size = max_frame_len;
}
/* NOTE: calculus matching those in tpacket_rcv()
@@ -4100,8 +4358,8 @@ create_ring(pcap_t *handle, int *status)
len = sizeof(sk_type);
if (getsockopt(handle->fd, SOL_SOCKET, SO_TYPE, &sk_type,
&len) < 0) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "getsockopt: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf,
+ PCAP_ERRBUF_SIZE, errno, "getsockopt");
*status = PCAP_ERROR;
return -1;
}
@@ -4115,8 +4373,8 @@ create_ring(pcap_t *handle, int *status)
* PACKET_RESERVE", in which case we fall back
* as best we can.
*/
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "getsockopt: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf,
+ PCAP_ERRBUF_SIZE, errno, "getsockopt");
*status = PCAP_ERROR;
return -1;
}
@@ -4155,7 +4413,14 @@ create_ring(pcap_t *handle, int *status)
*/
macoff = netoff - maclen;
req.tp_frame_size = TPACKET_ALIGN(macoff + frame_size);
- req.tp_frame_nr = handle->opt.buffer_size/req.tp_frame_size;
+ /*
+ * Round the buffer size up to a multiple of the
+ * frame size (rather than rounding down, which
+ * would give a buffer smaller than our caller asked
+ * for, and possibly give zero frames if the requested
+ * buffer size is too small for one frame).
+ */
+ req.tp_frame_nr = (handle->opt.buffer_size + req.tp_frame_size - 1)/req.tp_frame_size;
break;
#ifdef HAVE_TPACKET3
@@ -4163,11 +4428,18 @@ create_ring(pcap_t *handle, int *status)
/* The "frames" for this are actually buffers that
* contain multiple variable-sized frames.
*
- * We pick a "frame" size of 128K to leave enough
- * room for at least one reasonably-sized packet
+ * We pick a "frame" size of MAXIMUM_SNAPLEN to leave
+ * enough room for at least one reasonably-sized packet
* in the "frame". */
req.tp_frame_size = MAXIMUM_SNAPLEN;
- req.tp_frame_nr = handle->opt.buffer_size/req.tp_frame_size;
+ /*
+ * Round the buffer size up to a multiple of the
+ * "frame" size (rather than rounding down, which
+ * would give a buffer smaller than our caller asked
+ * for, and possibly give zero "frames" if the requested
+ * buffer size is too small for one "frame").
+ */
+ req.tp_frame_nr = (handle->opt.buffer_size + req.tp_frame_size - 1)/req.tp_frame_size;
break;
#endif
default:
@@ -4261,9 +4533,9 @@ create_ring(pcap_t *handle, int *status)
break;
default:
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "SIOCSHWTSTAMP failed: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf,
+ PCAP_ERRBUF_SIZE, errno,
+ "SIOCSHWTSTAMP failed");
*status = PCAP_ERROR;
return -1;
}
@@ -4289,9 +4561,9 @@ create_ring(pcap_t *handle, int *status)
}
if (setsockopt(handle->fd, SOL_PACKET, PACKET_TIMESTAMP,
(void *)&timesource, sizeof(timesource))) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "can't set PACKET_TIMESTAMP: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf,
+ PCAP_ERRBUF_SIZE, errno,
+ "can't set PACKET_TIMESTAMP");
*status = PCAP_ERROR;
return -1;
}
@@ -4339,9 +4611,8 @@ retry:
*/
return 0;
}
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "can't create rx ring on packet socket: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "can't create rx ring on packet socket");
*status = PCAP_ERROR;
return -1;
}
@@ -4351,8 +4622,8 @@ retry:
handlep->mmapbuf = mmap(0, handlep->mmapbuflen,
PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
if (handlep->mmapbuf == MAP_FAILED) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "can't mmap rx ring: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "can't mmap rx ring");
/* clear the allocated ring on error*/
destroy_ring(handle);
@@ -4364,9 +4635,8 @@ retry:
handle->cc = req.tp_frame_nr;
handle->buffer = malloc(handle->cc * sizeof(union thdr *));
if (!handle->buffer) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "can't allocate ring of frame headers: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "can't allocate ring of frame headers");
destroy_ring(handle);
*status = PCAP_ERROR;
@@ -4454,24 +4724,24 @@ pcap_cleanup_linux_mmap( pcap_t *handle )
static int
-pcap_getnonblock_mmap(pcap_t *p, char *errbuf)
+pcap_getnonblock_mmap(pcap_t *handle)
{
- struct pcap_linux *handlep = p->priv;
+ struct pcap_linux *handlep = handle->priv;
/* use negative value of timeout to indicate non blocking ops */
return (handlep->timeout<0);
}
static int
-pcap_setnonblock_mmap(pcap_t *p, int nonblock, char *errbuf)
+pcap_setnonblock_mmap(pcap_t *handle, int nonblock)
{
- struct pcap_linux *handlep = p->priv;
+ struct pcap_linux *handlep = handle->priv;
/*
* Set the file descriptor to non-blocking mode, as we use
* it for sending packets.
*/
- if (pcap_setnonblock_fd(p, nonblock, errbuf) == -1)
+ if (pcap_setnonblock_fd(handle, nonblock) == -1)
return -1;
/*
@@ -4556,9 +4826,9 @@ static int pcap_wait_for_frames_mmap(pcap_t *handle)
*/
ret = poll(&pollinfo, 1, handlep->poll_timeout);
if (ret < 0 && errno != EINTR) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "can't poll on packet socket: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf,
+ PCAP_ERRBUF_SIZE, errno,
+ "can't poll on packet socket");
return PCAP_ERROR;
} else if (ret > 0 &&
(pollinfo.revents & (POLLHUP|POLLRDHUP|POLLERR|POLLNVAL))) {
@@ -4596,10 +4866,9 @@ static int pcap_wait_for_frames_mmap(pcap_t *handle)
PCAP_ERRBUF_SIZE,
"The interface went down");
} else {
- pcap_snprintf(handle->errbuf,
- PCAP_ERRBUF_SIZE,
- "Error condition on packet socket: %s",
- strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf,
+ PCAP_ERRBUF_SIZE, errno,
+ "Error condition on packet socket");
}
return PCAP_ERROR;
}
@@ -4638,6 +4907,7 @@ static int pcap_handle_packet_mmap(
unsigned char *bp;
struct sockaddr_ll *sll;
struct pcap_pkthdr pcaphdr;
+ unsigned int snaplen = tp_snaplen;
/* perform sanity check on internal offset. */
if (tp_mac + tp_snaplen > handle->bufsize) {
@@ -4698,16 +4968,21 @@ static int pcap_handle_packet_mmap(
hdrp->sll_halen = htons(sll->sll_halen);
memcpy(hdrp->sll_addr, sll->sll_addr, SLL_ADDRLEN);
hdrp->sll_protocol = sll->sll_protocol;
+
+ snaplen += sizeof(struct sll_header);
}
if (handlep->filter_in_userland && handle->fcode.bf_insns) {
struct bpf_aux_data aux_data;
- aux_data.vlan_tag = tp_vlan_tci & 0x0fff;
aux_data.vlan_tag_present = tp_vlan_tci_valid;
+ aux_data.vlan_tag = tp_vlan_tci & 0x0fff;
- if (bpf_filter_with_aux_data(handle->fcode.bf_insns, bp,
- tp_len, tp_snaplen, &aux_data) == 0)
+ if (bpf_filter_with_aux_data(handle->fcode.bf_insns,
+ bp,
+ tp_len,
+ snaplen,
+ &aux_data) == 0)
return 0;
}
@@ -4987,11 +5262,7 @@ pcap_read_linux_mmap_v2(pcap_t *handle, int max_packets, pcap_handler callback,
h.h2->tp_snaplen,
h.h2->tp_sec,
handle->opt.tstamp_precision == PCAP_TSTAMP_PRECISION_NANO ? h.h2->tp_nsec : h.h2->tp_nsec / 1000,
-#if defined(TP_STATUS_VLAN_VALID)
- (h.h2->tp_vlan_tci || (h.h2->tp_status & TP_STATUS_VLAN_VALID)),
-#else
- h.h2->tp_vlan_tci != 0,
-#endif
+ VLAN_VALID(h.h2, h.h2),
h.h2->tp_vlan_tci,
VLAN_TPID(h.h2, h.h2));
if (ret == 1) {
@@ -5105,11 +5376,7 @@ again:
tp3_hdr->tp_snaplen,
tp3_hdr->tp_sec,
handle->opt.tstamp_precision == PCAP_TSTAMP_PRECISION_NANO ? tp3_hdr->tp_nsec : tp3_hdr->tp_nsec / 1000,
-#if defined(TP_STATUS_VLAN_VALID)
- (tp3_hdr->hv1.tp_vlan_tci || (tp3_hdr->tp_status & TP_STATUS_VLAN_VALID)),
-#else
- tp3_hdr->hv1.tp_vlan_tci != 0,
-#endif
+ VLAN_VALID(tp3_hdr, &tp3_hdr->hv1),
tp3_hdr->hv1.tp_vlan_tci,
VLAN_TPID(tp3_hdr, &tp3_hdr->hv1));
if (ret == 1) {
@@ -5257,8 +5524,8 @@ iface_get_id(int fd, const char *device, char *ebuf)
strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
if (ioctl(fd, SIOCGIFINDEX, &ifr) == -1) {
- pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
- "SIOCGIFINDEX: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
+ errno, "SIOCGIFINDEX");
return -1;
}
@@ -5271,7 +5538,7 @@ iface_get_id(int fd, const char *device, char *ebuf)
* or a PCAP_ERROR_ value on a hard error.
*/
static int
-iface_bind(int fd, int ifindex, char *ebuf)
+iface_bind(int fd, int ifindex, char *ebuf, int protocol)
{
struct sockaddr_ll sll;
int err;
@@ -5280,7 +5547,7 @@ iface_bind(int fd, int ifindex, char *ebuf)
memset(&sll, 0, sizeof(sll));
sll.sll_family = AF_PACKET;
sll.sll_ifindex = ifindex;
- sll.sll_protocol = htons(ETH_P_ALL);
+ sll.sll_protocol = protocol;
if (bind(fd, (struct sockaddr *) &sll, sizeof(sll)) == -1) {
if (errno == ENETDOWN) {
@@ -5293,8 +5560,8 @@ iface_bind(int fd, int ifindex, char *ebuf)
*/
return PCAP_ERROR_IFACE_NOT_UP;
} else {
- pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
- "bind: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
+ errno, "bind");
return PCAP_ERROR;
}
}
@@ -5302,8 +5569,8 @@ iface_bind(int fd, int ifindex, char *ebuf)
/* Any pending errors, e.g., network is down? */
if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &errlen) == -1) {
- pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
- "getsockopt: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
+ errno, "getsockopt");
return 0;
}
@@ -5317,8 +5584,8 @@ iface_bind(int fd, int ifindex, char *ebuf)
*/
return PCAP_ERROR_IFACE_NOT_UP;
} else if (err > 0) {
- pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
- "bind: %s", pcap_strerror(err));
+ pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
+ err, "bind");
return 0;
}
@@ -5343,8 +5610,8 @@ has_wext(int sock_fd, const char *device, char *ebuf)
sizeof ireq.ifr_ifrn.ifrn_name);
if (ioctl(sock_fd, SIOCGIWNAME, &ireq) >= 0)
return 1; /* yes */
- pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
- "%s: SIOCGIWNAME: %s", device, pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE, errno,
+ "%s: SIOCGIWNAME", device);
if (errno == ENODEV)
return PCAP_ERROR_NO_SUCH_DEVICE;
return 0;
@@ -5495,9 +5762,8 @@ enter_rfmon_mode_wext(pcap_t *handle, int sock_fd, const char *device)
/*
* Failed.
*/
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "%s: SIOCGIWPRIV: %s", device,
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf,
+ PCAP_ERRBUF_SIZE, errno, "%s: SIOCGIWPRIV", device);
return PCAP_ERROR;
}
@@ -5506,15 +5772,14 @@ enter_rfmon_mode_wext(pcap_t *handle, int sock_fd, const char *device)
*/
priv = malloc(ireq.u.data.length * sizeof (struct iw_priv_args));
if (priv == NULL) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "malloc: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf,
+ PCAP_ERRBUF_SIZE, errno, "malloc");
return PCAP_ERROR;
}
ireq.u.data.pointer = (void *)priv;
if (ioctl(sock_fd, SIOCGIWPRIV, &ireq) == -1) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "%s: SIOCGIWPRIV: %s", device,
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf,
+ PCAP_ERRBUF_SIZE, errno, "%s: SIOCGIWPRIV", device);
free(priv);
return PCAP_ERROR;
}
@@ -5768,8 +6033,8 @@ enter_rfmon_mode_wext(pcap_t *handle, int sock_fd, const char *device)
memset(&ifr, 0, sizeof(ifr));
strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
if (ioctl(sock_fd, SIOCGIFFLAGS, &ifr) == -1) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "%s: Can't get flags: %s", device, strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "%s: Can't get flags", device);
return PCAP_ERROR;
}
oldflags = 0;
@@ -5777,8 +6042,9 @@ enter_rfmon_mode_wext(pcap_t *handle, int sock_fd, const char *device)
oldflags = ifr.ifr_flags;
ifr.ifr_flags &= ~IFF_UP;
if (ioctl(sock_fd, SIOCSIFFLAGS, &ifr) == -1) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "%s: Can't set flags: %s", device, strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf,
+ PCAP_ERRBUF_SIZE, errno, "%s: Can't set flags",
+ device);
return PCAP_ERROR;
}
}
@@ -5796,8 +6062,9 @@ enter_rfmon_mode_wext(pcap_t *handle, int sock_fd, const char *device)
*/
ifr.ifr_flags = oldflags;
if (ioctl(sock_fd, SIOCSIFFLAGS, &ifr) == -1) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "%s: Can't set flags: %s", device, strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf,
+ PCAP_ERRBUF_SIZE, errno, "%s: Can't set flags",
+ device);
return PCAP_ERROR;
}
return PCAP_ERROR_RFMON_NOTSUP;
@@ -5880,9 +6147,8 @@ enter_rfmon_mode_wext(pcap_t *handle, int sock_fd, const char *device)
strlcpy(ireq.ifr_ifrn.ifrn_name, device,
sizeof ireq.ifr_ifrn.ifrn_name);
if (ioctl(sock_fd, SIOCGIWFREQ, &ireq) == -1) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "%s: SIOCGIWFREQ: %s", device,
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf,
+ PCAP_ERRBUF_SIZE, errno, "%s: SIOCGIWFREQ", device);
return PCAP_ERROR;
}
channel = ireq.u.freq.m;
@@ -5957,8 +6223,9 @@ enter_rfmon_mode_wext(pcap_t *handle, int sock_fd, const char *device)
if (oldflags != 0) {
ifr.ifr_flags = oldflags;
if (ioctl(sock_fd, SIOCSIFFLAGS, &ifr) == -1) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "%s: Can't set flags: %s", device, strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf,
+ PCAP_ERRBUF_SIZE, errno, "%s: Can't set flags",
+ device);
/*
* At least try to restore the old mode on the
@@ -6084,8 +6351,8 @@ iface_ethtool_get_ts_info(const char *device, pcap_t *handle, char *ebuf)
*/
fd = socket(PF_UNIX, SOCK_RAW, 0);
if (fd < 0) {
- (void)pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
- "socket for SIOCETHTOOL(ETHTOOL_GET_TS_INFO): %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
+ errno, "socket for SIOCETHTOOL(ETHTOOL_GET_TS_INFO)");
return -1;
}
@@ -6124,9 +6391,10 @@ iface_ethtool_get_ts_info(const char *device, pcap_t *handle, char *ebuf)
/*
* Other error.
*/
- pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
- "%s: SIOCETHTOOL(ETHTOOL_GET_TS_INFO) ioctl failed: %s", device,
- strerror(save_errno));
+ pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
+ save_errno,
+ "%s: SIOCETHTOOL(ETHTOOL_GET_TS_INFO) ioctl failed",
+ device);
return -1;
}
}
@@ -6226,9 +6494,9 @@ iface_ethtool_flag_ioctl(pcap_t *handle, int cmd, const char *cmdname)
*/
return 0;
}
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "%s: SIOCETHTOOL(%s) ioctl failed: %s", handle->opt.device,
- cmdname, strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "%s: SIOCETHTOOL(%s) ioctl failed",
+ handle->opt.device, cmdname);
return -1;
}
return eval.data;
@@ -6317,6 +6585,7 @@ static int
activate_old(pcap_t *handle)
{
struct pcap_linux *handlep = handle->priv;
+ int err;
int arptype;
struct ifreq ifr;
const char *device = handle->opt.device;
@@ -6327,9 +6596,10 @@ activate_old(pcap_t *handle)
handle->fd = socket(PF_INET, SOCK_PACKET, htons(ETH_P_ALL));
if (handle->fd == -1) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "socket: %s", pcap_strerror(errno));
- if (errno == EPERM || errno == EACCES) {
+ err = errno;
+ pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ err, "socket");
+ if (err == EPERM || err == EACCES) {
/*
* You don't have permission to open the
* socket.
@@ -6383,8 +6653,8 @@ activate_old(pcap_t *handle)
memset(&ifr, 0, sizeof(ifr));
strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
if (ioctl(handle->fd, SIOCGIFFLAGS, &ifr) == -1) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "SIOCGIFFLAGS: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf,
+ PCAP_ERRBUF_SIZE, errno, "SIOCGIFFLAGS");
return PCAP_ERROR;
}
if ((ifr.ifr_flags & IFF_PROMISC) == 0) {
@@ -6411,9 +6681,8 @@ activate_old(pcap_t *handle)
ifr.ifr_flags |= IFF_PROMISC;
if (ioctl(handle->fd, SIOCSIFFLAGS, &ifr) == -1) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "SIOCSIFFLAGS: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf,
+ PCAP_ERRBUF_SIZE, errno, "SIOCSIFFLAGS");
return PCAP_ERROR;
}
handlep->must_do_on_close |= MUST_CLEAR_PROMISC;
@@ -6521,22 +6790,22 @@ iface_bind_old(int fd, const char *device, char *ebuf)
memset(&saddr, 0, sizeof(saddr));
strlcpy(saddr.sa_data, device, sizeof(saddr.sa_data));
if (bind(fd, &saddr, sizeof(saddr)) == -1) {
- pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
- "bind: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
+ errno, "bind");
return -1;
}
/* Any pending errors, e.g., network is down? */
if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &errlen) == -1) {
- pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
- "getsockopt: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
+ errno, "getsockopt");
return -1;
}
if (err > 0) {
- pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
- "bind: %s", pcap_strerror(err));
+ pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
+ err, "bind");
return -1;
}
@@ -6561,8 +6830,8 @@ iface_get_mtu(int fd, const char *device, char *ebuf)
strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
if (ioctl(fd, SIOCGIFMTU, &ifr) == -1) {
- pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
- "SIOCGIFMTU: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
+ errno, "SIOCGIFMTU");
return -1;
}
@@ -6581,8 +6850,8 @@ iface_get_arptype(int fd, const char *device, char *ebuf)
strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
if (ioctl(fd, SIOCGIFHWADDR, &ifr) == -1) {
- pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
- "SIOCGIFHWADDR: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
+ errno, "SIOCGIFHWADDR");
if (errno == ENODEV) {
/*
* No such device.
@@ -6614,8 +6883,8 @@ fix_program(pcap_t *handle, struct sock_fprog *fcode, int is_mmapped)
len = handle->fcode.bf_len;
f = (struct bpf_insn *)malloc(prog_size);
if (f == NULL) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "malloc: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "malloc");
return -1;
}
memcpy(f, handle->fcode.bf_insns, prog_size);
@@ -6791,15 +7060,15 @@ set_kernel_filter(pcap_t *handle, struct sock_fprog *fcode)
*/
save_mode = fcntl(handle->fd, F_GETFL, 0);
if (save_mode == -1) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "can't get FD flags when changing filter: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf,
+ PCAP_ERRBUF_SIZE, errno,
+ "can't get FD flags when changing filter");
return -2;
}
if (fcntl(handle->fd, F_SETFL, save_mode | O_NONBLOCK) < 0) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "can't set nonblocking mode when changing filter: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf,
+ PCAP_ERRBUF_SIZE, errno,
+ "can't set nonblocking mode when changing filter");
return -2;
}
while (recv(handle->fd, &drain, sizeof drain, MSG_TRUNC) >= 0)
@@ -6814,15 +7083,15 @@ set_kernel_filter(pcap_t *handle, struct sock_fprog *fcode)
*/
(void)fcntl(handle->fd, F_SETFL, save_mode);
(void)reset_kernel_filter(handle);
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "recv failed when changing filter: %s",
- pcap_strerror(save_errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf,
+ PCAP_ERRBUF_SIZE, save_errno,
+ "recv failed when changing filter");
return -2;
}
if (fcntl(handle->fd, F_SETFL, save_mode) == -1) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "can't restore FD flags when changing filter: %s",
- pcap_strerror(save_errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf,
+ PCAP_ERRBUF_SIZE, errno,
+ "can't restore FD flags when changing filter");
return -2;
}
}
@@ -6851,9 +7120,9 @@ set_kernel_filter(pcap_t *handle, struct sock_fprog *fcode)
* Report it as a fatal error.
*/
if (reset_kernel_filter(handle) == -1) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "can't remove kernel total filter: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf,
+ PCAP_ERRBUF_SIZE, errno,
+ "can't remove kernel total filter");
return -2; /* fatal error */
}
@@ -6865,6 +7134,7 @@ set_kernel_filter(pcap_t *handle, struct sock_fprog *fcode)
static int
reset_kernel_filter(pcap_t *handle)
{
+ int ret;
/*
* setsockopt() barfs unless it get a dummy parameter.
* valgrind whines unless the value is initialized,
@@ -6873,7 +7143,45 @@ reset_kernel_filter(pcap_t *handle)
*/
int dummy = 0;
- return setsockopt(handle->fd, SOL_SOCKET, SO_DETACH_FILTER,
+ ret = setsockopt(handle->fd, SOL_SOCKET, SO_DETACH_FILTER,
&dummy, sizeof(dummy));
+ /*
+ * Ignore ENOENT - it means "we don't have a filter", so there
+ * was no filter to remove, and there's still no filter.
+ *
+ * Also ignore ENONET, as a lot of kernel versions had a
+ * typo where ENONET, rather than ENOENT, was returned.
+ */
+ if (ret == -1 && errno != ENOENT && errno != ENONET)
+ return -1;
+ return 0;
}
#endif
+
+int
+pcap_set_protocol(pcap_t *p, int protocol)
+{
+ if (pcap_check_activated(p))
+ return (PCAP_ERROR_ACTIVATED);
+ p->opt.protocol = protocol;
+ return (0);
+}
+
+/*
+ * Libpcap version string.
+ */
+const char *
+pcap_lib_version(void)
+{
+#ifdef HAVE_PACKET_RING
+ #if defined(HAVE_TPACKET3)
+ return (PCAP_VERSION_STRING " (with TPACKET_V3)");
+ #elif defined(HAVE_TPACKET2)
+ return (PCAP_VERSION_STRING " (with TPACKET_V2)");
+ #else
+ return (PCAP_VERSION_STRING " (with TPACKET_V1)");
+ #endif
+#else
+ return (PCAP_VERSION_STRING " (without TPACKET)");
+#endif
+}
diff --git a/contrib/libpcap/pcap-netfilter-linux.c b/contrib/libpcap/pcap-netfilter-linux.c
index bde648f3ea59b..d5c5dcdc48504 100644
--- a/contrib/libpcap/pcap-netfilter-linux.c
+++ b/contrib/libpcap/pcap-netfilter-linux.c
@@ -29,7 +29,7 @@
*/
#ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
#endif
#include "pcap-int.h"
@@ -82,37 +82,90 @@ struct pcap_netfilter {
u_int packets_nobufs; /* ENOBUFS counter */
};
-static int nfqueue_send_verdict(const pcap_t *handle, u_int16_t group_id, u_int32_t id, u_int32_t verdict);
+static int nfqueue_send_verdict(const pcap_t *handle, uint16_t group_id, u_int32_t id, u_int32_t verdict);
static int
netfilter_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user)
{
struct pcap_netfilter *handlep = handle->priv;
- const unsigned char *buf;
+ register u_char *bp, *ep;
int count = 0;
int len;
- /* ignore interrupt system call error */
- do {
- len = recv(handle->fd, handle->buffer, handle->bufsize, 0);
- if (handle->break_loop) {
- handle->break_loop = 0;
- return -2;
- }
- if(errno == ENOBUFS) handlep->packets_nobufs++;
- } while ((len == -1) && (errno == EINTR || errno == ENOBUFS));
-
- if (len < 0) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't receive packet %d:%s", errno, pcap_strerror(errno));
- return -1;
+ /*
+ * Has "pcap_breakloop()" been called?
+ */
+ if (handle->break_loop) {
+ /*
+ * Yes - clear the flag that indicates that it
+ * has, and return PCAP_ERROR_BREAK to indicate
+ * that we were told to break out of the loop.
+ */
+ handle->break_loop = 0;
+ return PCAP_ERROR_BREAK;
}
+ len = handle->cc;
+ if (len == 0) {
+ /*
+ * The buffer is empty; refill it.
+ *
+ * We ignore EINTR, as that might just be due to a signal
+ * being delivered - if the signal should interrupt the
+ * loop, the signal handler should call pcap_breakloop()
+ * to set handle->break_loop (we ignore it on other
+ * platforms as well).
+ */
+ do {
+ len = recv(handle->fd, handle->buffer, handle->bufsize, 0);
+ if (handle->break_loop) {
+ handle->break_loop = 0;
+ return PCAP_ERROR_BREAK;
+ }
+ if (errno == ENOBUFS)
+ handlep->packets_nobufs++;
+ } while ((len == -1) && (errno == EINTR || errno == ENOBUFS));
+
+ if (len < 0) {
+ pcap_fmt_errmsg_for_errno(handle->errbuf,
+ PCAP_ERRBUF_SIZE, errno, "Can't receive packet");
+ return PCAP_ERROR;
+ }
- buf = (unsigned char *)handle->buffer;
- while ((u_int)len >= NLMSG_SPACE(0)) {
- const struct nlmsghdr *nlh = (const struct nlmsghdr *) buf;
- u_int32_t msg_len;
+ bp = (unsigned char *)handle->buffer;
+ } else
+ bp = handle->bp;
+ ep = bp + len;
+ while (bp < ep) {
+ const struct nlmsghdr *nlh = (const struct nlmsghdr *) bp;
+ uint32_t msg_len;
nftype_t type = OTHER;
+ /*
+ * Has "pcap_breakloop()" been called?
+ * If so, return immediately - if we haven't read any
+ * packets, clear the flag and return PCAP_ERROR_BREAK
+ * to indicate that we were told to break out of the loop,
+ * otherwise leave the flag set, so that the *next* call
+ * will break out of the loop without having read any
+ * packets, and return the number of packets we've
+ * processed so far.
+ */
+ if (handle->break_loop) {
+ handle->bp = bp;
+ handle->cc = ep - bp;
+ if (count == 0) {
+ handle->break_loop = 0;
+ return PCAP_ERROR_BREAK;
+ } else
+ return count;
+ }
+ if (ep - bp < NLMSG_SPACE(0)) {
+ /*
+ * There's less than one netlink message left
+ * in the buffer. Give up.
+ */
+ break;
+ }
if (nlh->nlmsg_len < sizeof(struct nlmsghdr) || (u_int)len < nlh->nlmsg_len) {
pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Message truncated: (got: %d) (nlmsg_len: %u)", len, nlh->nlmsg_len);
@@ -205,12 +258,25 @@ netfilter_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_c
}
msg_len = NLMSG_ALIGN(nlh->nlmsg_len);
- if (msg_len > (u_int)len)
- msg_len = (u_int)len;
-
- len -= msg_len;
- buf += msg_len;
+ /*
+ * If the message length would run past the end of the
+ * buffer, truncate it to the remaining space in the
+ * buffer.
+ */
+ if (msg_len > ep - bp)
+ msg_len = ep - bp;
+
+ bp += msg_len;
+ if (count >= max_packets && !PACKET_COUNT_IS_UNLIMITED(max_packets)) {
+ handle->bp = bp;
+ handle->cc = ep - bp;
+ if (handle->cc < 0)
+ handle->cc = 0;
+ return count;
+ }
}
+
+ handle->cc = 0;
return count;
}
@@ -233,20 +299,20 @@ netfilter_stats_linux(pcap_t *handle, struct pcap_stat *stats)
}
static int
-netfilter_inject_linux(pcap_t *handle, const void *buf, size_t size)
+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");
return (-1);
}
struct my_nfattr {
- u_int16_t nfa_len;
- u_int16_t nfa_type;
+ uint16_t nfa_len;
+ uint16_t nfa_type;
void *data;
};
static int
-netfilter_send_config_msg(const pcap_t *handle, u_int16_t msg_type, int ack, u_int8_t family, u_int16_t res_id, const struct my_nfattr *mynfa)
+netfilter_send_config_msg(const pcap_t *handle, uint16_t msg_type, int ack, u_int8_t family, u_int16_t res_id, const struct my_nfattr *mynfa)
{
char buf[1024] __attribute__ ((aligned));
@@ -310,7 +376,7 @@ netfilter_send_config_msg(const pcap_t *handle, u_int16_t msg_type, int ack, u_i
if (snl.nl_pid != 0 || seq_id != nlh->nlmsg_seq) /* if not from kernel or wrong sequence skip */
continue;
- while ((u_int)len >= NLMSG_SPACE(0) && NLMSG_OK(nlh, len)) {
+ while ((u_int)len >= NLMSG_SPACE(0) && NLMSG_OK(nlh, (u_int)len)) {
if (nlh->nlmsg_type == NLMSG_ERROR || (nlh->nlmsg_type == NLMSG_DONE && nlh->nlmsg_flags & NLM_F_MULTI)) {
if (nlh->nlmsg_len < NLMSG_ALIGN(sizeof(struct nlmsgerr))) {
errno = EBADMSG;
@@ -327,13 +393,13 @@ netfilter_send_config_msg(const pcap_t *handle, u_int16_t msg_type, int ack, u_i
}
static int
-nflog_send_config_msg(const pcap_t *handle, u_int8_t family, u_int16_t group_id, const struct my_nfattr *mynfa)
+nflog_send_config_msg(const pcap_t *handle, uint8_t family, u_int16_t group_id, const struct my_nfattr *mynfa)
{
return netfilter_send_config_msg(handle, (NFNL_SUBSYS_ULOG << 8) | NFULNL_MSG_CONFIG, 1, family, group_id, mynfa);
}
static int
-nflog_send_config_cmd(const pcap_t *handle, u_int16_t group_id, u_int8_t cmd, u_int8_t family)
+nflog_send_config_cmd(const pcap_t *handle, uint16_t group_id, u_int8_t cmd, u_int8_t family)
{
struct nfulnl_msg_config_cmd msg;
struct my_nfattr nfa;
@@ -348,7 +414,7 @@ nflog_send_config_cmd(const pcap_t *handle, u_int16_t group_id, u_int8_t cmd, u_
}
static int
-nflog_send_config_mode(const pcap_t *handle, u_int16_t group_id, u_int8_t copy_mode, u_int32_t copy_range)
+nflog_send_config_mode(const pcap_t *handle, uint16_t group_id, u_int8_t copy_mode, u_int32_t copy_range)
{
struct nfulnl_msg_config_mode msg;
struct my_nfattr nfa;
@@ -364,7 +430,7 @@ nflog_send_config_mode(const pcap_t *handle, u_int16_t group_id, u_int8_t copy_m
}
static int
-nfqueue_send_verdict(const pcap_t *handle, u_int16_t group_id, u_int32_t id, u_int32_t verdict)
+nfqueue_send_verdict(const pcap_t *handle, uint16_t group_id, u_int32_t id, u_int32_t verdict)
{
struct nfqnl_msg_verdict_hdr msg;
struct my_nfattr nfa;
@@ -380,13 +446,13 @@ nfqueue_send_verdict(const pcap_t *handle, u_int16_t group_id, u_int32_t id, u_i
}
static int
-nfqueue_send_config_msg(const pcap_t *handle, u_int8_t family, u_int16_t group_id, const struct my_nfattr *mynfa)
+nfqueue_send_config_msg(const pcap_t *handle, uint8_t family, u_int16_t group_id, const struct my_nfattr *mynfa)
{
return netfilter_send_config_msg(handle, (NFNL_SUBSYS_QUEUE << 8) | NFQNL_MSG_CONFIG, 1, family, group_id, mynfa);
}
static int
-nfqueue_send_config_cmd(const pcap_t *handle, u_int16_t group_id, u_int8_t cmd, u_int16_t pf)
+nfqueue_send_config_cmd(const pcap_t *handle, uint16_t group_id, u_int8_t cmd, u_int16_t pf)
{
struct nfqnl_msg_config_cmd msg;
struct my_nfattr nfa;
@@ -402,7 +468,7 @@ nfqueue_send_config_cmd(const pcap_t *handle, u_int16_t group_id, u_int8_t cmd,
}
static int
-nfqueue_send_config_mode(const pcap_t *handle, u_int16_t group_id, u_int8_t copy_mode, u_int32_t copy_range)
+nfqueue_send_config_mode(const pcap_t *handle, uint16_t group_id, u_int8_t copy_mode, u_int32_t copy_range)
{
struct nfqnl_msg_config_params msg;
struct my_nfattr nfa;
@@ -479,6 +545,17 @@ netfilter_activate(pcap_t* handle)
group_count = 1;
}
+ /*
+ * Turn a negative snapshot value (invalid), a snapshot value of
+ * 0 (unspecified), or a value bigger than the normal maximum
+ * value, into the maximum allowed value.
+ *
+ * If some application really *needs* a bigger snapshot
+ * length, we should just increase MAXIMUM_SNAPLEN.
+ */
+ if (handle->snapshot <= 0 || handle->snapshot > MAXIMUM_SNAPLEN)
+ handle->snapshot = MAXIMUM_SNAPLEN;
+
/* Initialize some components of the pcap structure. */
handle->bufsize = 128 + handle->snapshot;
handle->offset = 0;
@@ -494,7 +571,8 @@ netfilter_activate(pcap_t* handle)
/* Create netlink socket */
handle->fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_NETFILTER);
if (handle->fd < 0) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't create raw socket %d:%s", errno, pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "Can't create raw socket");
return PCAP_ERROR;
}
@@ -512,54 +590,68 @@ netfilter_activate(pcap_t* handle)
handle->buffer = malloc(handle->bufsize);
if (!handle->buffer) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't allocate dump buffer: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "Can't allocate dump buffer");
goto close_fail;
}
if (type == NFLOG) {
if (nflog_send_config_cmd(handle, 0, NFULNL_CFG_CMD_PF_UNBIND, AF_INET) < 0) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "NFULNL_CFG_CMD_PF_UNBIND: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf,
+ PCAP_ERRBUF_SIZE, errno,
+ "NFULNL_CFG_CMD_PF_UNBIND");
goto close_fail;
}
if (nflog_send_config_cmd(handle, 0, NFULNL_CFG_CMD_PF_BIND, AF_INET) < 0) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "NFULNL_CFG_CMD_PF_BIND: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf,
+ PCAP_ERRBUF_SIZE, errno, "NFULNL_CFG_CMD_PF_BIND");
goto close_fail;
}
/* Bind socket to the nflog groups */
for (i = 0; i < group_count; i++) {
if (nflog_send_config_cmd(handle, groups[i], NFULNL_CFG_CMD_BIND, AF_UNSPEC) < 0) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't listen on group group index: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf,
+ PCAP_ERRBUF_SIZE, errno,
+ "Can't listen on group group index");
goto close_fail;
}
if (nflog_send_config_mode(handle, groups[i], NFULNL_COPY_PACKET, handle->snapshot) < 0) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "NFULNL_COPY_PACKET: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf,
+ PCAP_ERRBUF_SIZE, errno,
+ "NFULNL_COPY_PACKET");
goto close_fail;
}
}
} else {
if (nfqueue_send_config_cmd(handle, 0, NFQNL_CFG_CMD_PF_UNBIND, AF_INET) < 0) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "NFQNL_CFG_CMD_PF_UNBIND: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf,
+ PCAP_ERRBUF_SIZE, errno, "NFQNL_CFG_CMD_PF_UNBIND");
goto close_fail;
}
if (nfqueue_send_config_cmd(handle, 0, NFQNL_CFG_CMD_PF_BIND, AF_INET) < 0) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "NFQNL_CFG_CMD_PF_BIND: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf,
+ PCAP_ERRBUF_SIZE, errno, "NFQNL_CFG_CMD_PF_BIND");
goto close_fail;
}
/* Bind socket to the nfqueue groups */
for (i = 0; i < group_count; i++) {
if (nfqueue_send_config_cmd(handle, groups[i], NFQNL_CFG_CMD_BIND, AF_UNSPEC) < 0) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't listen on group group index: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf,
+ PCAP_ERRBUF_SIZE, errno,
+ "Can't listen on group group index");
goto close_fail;
}
if (nfqueue_send_config_mode(handle, groups[i], NFQNL_COPY_PACKET, handle->snapshot) < 0) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "NFQNL_COPY_PACKET: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf,
+ PCAP_ERRBUF_SIZE, errno,
+ "NFQNL_COPY_PACKET");
goto close_fail;
}
}
@@ -578,7 +670,8 @@ netfilter_activate(pcap_t* handle)
* Set the socket buffer size to the specified value.
*/
if (setsockopt(handle->fd, SOL_SOCKET, SO_RCVBUF, &handle->opt.buffer_size, sizeof(handle->opt.buffer_size)) == -1) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "SO_RCVBUF: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf,
+ PCAP_ERRBUF_SIZE, errno, "SO_RCVBUF");
goto close_fail;
}
}
@@ -635,7 +728,7 @@ netfilter_create(const char *device, char *ebuf, int *is_ours)
}
int
-netfilter_findalldevs(pcap_if_t **alldevsp, char *err_str)
+netfilter_findalldevs(pcap_if_list_t *devlistp, char *err_str)
{
int sock;
@@ -644,15 +737,23 @@ netfilter_findalldevs(pcap_if_t **alldevsp, char *err_str)
/* if netlink is not supported this is not fatal */
if (errno == EAFNOSUPPORT || errno == EPROTONOSUPPORT)
return 0;
- pcap_snprintf(err_str, PCAP_ERRBUF_SIZE, "Can't open netlink socket %d:%s",
- errno, pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(err_str, PCAP_ERRBUF_SIZE,
+ errno, "Can't open netlink socket");
return -1;
}
close(sock);
- if (pcap_add_if(alldevsp, NFLOG_IFACE, 0, "Linux netfilter log (NFLOG) interface", err_str) < 0)
+ /*
+ * The notion of "connected" vs. "disconnected" doesn't apply.
+ * XXX - what about "up" and "running"?
+ */
+ if (add_dev(devlistp, NFLOG_IFACE,
+ PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE,
+ "Linux netfilter log (NFLOG) interface", err_str) == NULL)
return -1;
- if (pcap_add_if(alldevsp, NFQUEUE_IFACE, 0, "Linux netfilter queue (NFQUEUE) interface", err_str) < 0)
+ if (add_dev(devlistp, NFQUEUE_IFACE,
+ PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE,
+ "Linux netfilter queue (NFQUEUE) interface", err_str) == NULL)
return -1;
return 0;
}
diff --git a/contrib/libpcap/pcap-netfilter-linux.h b/contrib/libpcap/pcap-netfilter-linux.h
index 01d9b394f5a80..97b73108fee47 100644
--- a/contrib/libpcap/pcap-netfilter-linux.h
+++ b/contrib/libpcap/pcap-netfilter-linux.h
@@ -31,5 +31,5 @@
/*
* Prototypes for netlink-related functions
*/
-int netfilter_findalldevs(pcap_if_t **alldevsp, char *err_str);
+int netfilter_findalldevs(pcap_if_list_t *devlistp, char *err_str);
pcap_t *netfilter_create(const char *device, char *ebuf, int *is_ours);
diff --git a/contrib/libpcap/pcap-netmap.c b/contrib/libpcap/pcap-netmap.c
new file mode 100644
index 0000000000000..f1505633fcaa3
--- /dev/null
+++ b/contrib/libpcap/pcap-netmap.c
@@ -0,0 +1,306 @@
+/*
+ * Copyright (C) 2014 Luigi Rizzo. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS''AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <poll.h>
+#include <ctype.h>
+#include <errno.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define NETMAP_WITH_LIBS
+#include <net/netmap_user.h>
+
+#include "pcap-int.h"
+#include "pcap-netmap.h"
+
+#ifndef __FreeBSD__
+ /*
+ * On FreeBSD we use IFF_PPROMISC which is in ifr_flagshigh.
+ * Remap to IFF_PROMISC on other platforms.
+ *
+ * XXX - DragonFly BSD?
+ */
+ #define IFF_PPROMISC IFF_PROMISC
+#endif /* __FreeBSD__ */
+
+struct pcap_netmap {
+ struct nm_desc *d; /* pointer returned by nm_open() */
+ pcap_handler cb; /* callback and argument */
+ u_char *cb_arg;
+ int must_clear_promisc; /* flag */
+ uint64_t rx_pkts; /* # of pkts received before the filter */
+};
+
+
+static int
+pcap_netmap_stats(pcap_t *p, struct pcap_stat *ps)
+{
+ struct pcap_netmap *pn = p->priv;
+
+ ps->ps_recv = pn->rx_pkts;
+ ps->ps_drop = 0;
+ ps->ps_ifdrop = 0;
+ return 0;
+}
+
+
+static void
+pcap_netmap_filter(u_char *arg, struct pcap_pkthdr *h, const u_char *buf)
+{
+ pcap_t *p = (pcap_t *)arg;
+ struct pcap_netmap *pn = p->priv;
+ const struct bpf_insn *pc = p->fcode.bf_insns;
+
+ ++pn->rx_pkts;
+ if (pc == NULL || bpf_filter(pc, buf, h->len, h->caplen))
+ pn->cb(pn->cb_arg, h, buf);
+}
+
+
+static int
+pcap_netmap_dispatch(pcap_t *p, int cnt, pcap_handler cb, u_char *user)
+{
+ int ret;
+ struct pcap_netmap *pn = p->priv;
+ struct nm_desc *d = pn->d;
+ struct pollfd pfd = { .fd = p->fd, .events = POLLIN, .revents = 0 };
+
+ pn->cb = cb;
+ pn->cb_arg = user;
+
+ for (;;) {
+ if (p->break_loop) {
+ p->break_loop = 0;
+ return PCAP_ERROR_BREAK;
+ }
+ /* nm_dispatch won't run forever */
+
+ ret = nm_dispatch((void *)d, cnt, (void *)pcap_netmap_filter, (void *)p);
+ if (ret != 0)
+ break;
+ errno = 0;
+ ret = poll(&pfd, 1, p->opt.timeout);
+ }
+ return ret;
+}
+
+
+/* XXX need to check the NIOCTXSYNC/poll */
+static int
+pcap_netmap_inject(pcap_t *p, const void *buf, size_t size)
+{
+ struct pcap_netmap *pn = p->priv;
+ struct nm_desc *d = pn->d;
+
+ return nm_inject(d, buf, size);
+}
+
+
+static int
+pcap_netmap_ioctl(pcap_t *p, u_long what, uint32_t *if_flags)
+{
+ struct pcap_netmap *pn = p->priv;
+ struct nm_desc *d = pn->d;
+ struct ifreq ifr;
+ int error, fd = d->fd;
+
+#ifdef linux
+ fd = socket(AF_INET, SOCK_DGRAM, 0);
+ if (fd < 0) {
+ fprintf(stderr, "Error: cannot get device control socket.\n");
+ return -1;
+ }
+#endif /* linux */
+ bzero(&ifr, sizeof(ifr));
+ strncpy(ifr.ifr_name, d->req.nr_name, sizeof(ifr.ifr_name));
+ switch (what) {
+ case SIOCSIFFLAGS:
+ /*
+ * The flags we pass in are 32-bit and unsigned.
+ *
+ * On most if not all UN*Xes, ifr_flags is 16-bit and
+ * signed, and the result of assigning a longer
+ * unsigned value to a shorter signed value is
+ * implementation-defined (even if, in practice, it'll
+ * do what's intended on all platforms we support
+ * result of assigning a 32-bit unsigned value).
+ * So we mask out the upper 16 bits.
+ */
+ ifr.ifr_flags = *if_flags & 0xffff;
+#ifdef __FreeBSD__
+ /*
+ * In FreeBSD, we need to set the high-order flags,
+ * as we're using IFF_PPROMISC, which is in those bits.
+ *
+ * XXX - DragonFly BSD?
+ */
+ ifr.ifr_flagshigh = *if_flags >> 16;
+#endif /* __FreeBSD__ */
+ break;
+ }
+ error = ioctl(fd, what, &ifr);
+ if (!error) {
+ switch (what) {
+ case SIOCGIFFLAGS:
+ /*
+ * The flags we return are 32-bit.
+ *
+ * On most if not all UN*Xes, ifr_flags is
+ * 16-bit and signed, and will get sign-
+ * extended, so that the upper 16 bits of
+ * those flags will be forced on. So we
+ * mask out the upper 16 bits of the
+ * sign-extended value.
+ */
+ *if_flags = ifr.ifr_flags & 0xffff;
+#ifdef __FreeBSD__
+ /*
+ * In FreeBSD, we need to return the
+ * high-order flags, as we're using
+ * IFF_PPROMISC, which is in those bits.
+ *
+ * XXX - DragonFly BSD?
+ */
+ *if_flags |= (ifr.ifr_flagshigh << 16);
+#endif /* __FreeBSD__ */
+ }
+ }
+#ifdef linux
+ close(fd);
+#endif /* linux */
+ return error ? -1 : 0;
+}
+
+
+static void
+pcap_netmap_close(pcap_t *p)
+{
+ struct pcap_netmap *pn = p->priv;
+ struct nm_desc *d = pn->d;
+ uint32_t if_flags = 0;
+
+ if (pn->must_clear_promisc) {
+ pcap_netmap_ioctl(p, SIOCGIFFLAGS, &if_flags); /* fetch flags */
+ if (if_flags & IFF_PPROMISC) {
+ if_flags &= ~IFF_PPROMISC;
+ pcap_netmap_ioctl(p, SIOCSIFFLAGS, &if_flags);
+ }
+ }
+ nm_close(d);
+ pcap_cleanup_live_common(p);
+}
+
+
+static int
+pcap_netmap_activate(pcap_t *p)
+{
+ struct pcap_netmap *pn = p->priv;
+ struct nm_desc *d;
+ uint32_t if_flags = 0;
+
+ d = nm_open(p->opt.device, NULL, 0, NULL);
+ if (d == NULL) {
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "netmap open: cannot access %s",
+ p->opt.device);
+ pcap_cleanup_live_common(p);
+ return (PCAP_ERROR);
+ }
+#if 0
+ fprintf(stderr, "%s device %s priv %p fd %d ports %d..%d\n",
+ __FUNCTION__, p->opt.device, d, d->fd,
+ d->first_rx_ring, d->last_rx_ring);
+#endif
+ pn->d = d;
+ p->fd = d->fd;
+
+ /*
+ * Turn a negative snapshot value (invalid), a snapshot value of
+ * 0 (unspecified), or a value bigger than the normal maximum
+ * value, into the maximum allowed value.
+ *
+ * If some application really *needs* a bigger snapshot
+ * length, we should just increase MAXIMUM_SNAPLEN.
+ */
+ if (p->snapshot <= 0 || p->snapshot > MAXIMUM_SNAPLEN)
+ p->snapshot = MAXIMUM_SNAPLEN;
+
+ if (p->opt.promisc && !(d->req.nr_ringid & NETMAP_SW_RING)) {
+ pcap_netmap_ioctl(p, SIOCGIFFLAGS, &if_flags); /* fetch flags */
+ if (!(if_flags & IFF_PPROMISC)) {
+ pn->must_clear_promisc = 1;
+ if_flags |= IFF_PPROMISC;
+ pcap_netmap_ioctl(p, SIOCSIFFLAGS, &if_flags);
+ }
+ }
+ p->linktype = DLT_EN10MB;
+ p->selectable_fd = p->fd;
+ p->read_op = pcap_netmap_dispatch;
+ p->inject_op = pcap_netmap_inject;
+ p->setfilter_op = install_bpf_program;
+ p->setdirection_op = NULL;
+ p->set_datalink_op = NULL;
+ p->getnonblock_op = pcap_getnonblock_fd;
+ p->setnonblock_op = pcap_setnonblock_fd;
+ p->stats_op = pcap_netmap_stats;
+ p->cleanup_op = pcap_netmap_close;
+
+ return (0);
+}
+
+
+pcap_t *
+pcap_netmap_create(const char *device, char *ebuf, int *is_ours)
+{
+ pcap_t *p;
+
+ *is_ours = (!strncmp(device, "netmap:", 7) || !strncmp(device, "vale", 4));
+ if (! *is_ours)
+ return NULL;
+ p = pcap_create_common(ebuf, sizeof (struct pcap_netmap));
+ if (p == NULL)
+ return (NULL);
+ p->activate_op = pcap_netmap_activate;
+ return (p);
+}
+
+/*
+ * The "device name" for netmap devices isn't a name for a device, it's
+ * an expression that indicates how the device should be set up, so
+ * there's no way to enumerate them.
+ */
+int
+pcap_netmap_findalldevs(pcap_if_list_t *devlistp _U_, char *err_str _U_)
+{
+ return 0;
+}
diff --git a/contrib/libpcap/pcap-netmap.h b/contrib/libpcap/pcap-netmap.h
new file mode 100644
index 0000000000000..6a414fca76f0e
--- /dev/null
+++ b/contrib/libpcap/pcap-netmap.h
@@ -0,0 +1,2 @@
+pcap_t *pcap_netmap_create(const char *, char *, int *);
+int pcap_netmap_findalldevs(pcap_if_list_t *devlistp, char *errbuf);
diff --git a/contrib/libpcap/pcap-new.c b/contrib/libpcap/pcap-new.c
index 494e425f8bb11..6fa52e6ece695 100644
--- a/contrib/libpcap/pcap-new.c
+++ b/contrib/libpcap/pcap-new.c
@@ -32,29 +32,26 @@
*/
#ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
#endif
+/*
+ * sockutils.h may include <crtdbg.h> on Windows, and pcap-int.h will
+ * include portability.h, and portability.h, on Windows, expects that
+ * <crtdbg.h> has already been included, so include sockutils.h first.
+ */
+#include "sockutils.h"
#include "pcap-int.h" // for the details of the pcap_t structure
#include "pcap-rpcap.h"
-#include "sockutils.h"
+#include "rpcap-protocol.h"
#include <errno.h> // for the errno variable
#include <stdlib.h> // for malloc(), free(), ...
#include <string.h> // for strstr, etc
-#ifndef WIN32
+#ifndef _WIN32
#include <dirent.h> // for readdir
#endif
-/* Keeps a list of all the opened connections in the active mode. */
-extern struct activehosts *activeHosts;
-
-/*
- * \brief Keeps the main socket identifier when we want to accept a new remote connection (active mode only).
- * See the documentation of pcap_remoteact_accept() and pcap_remoteact_cleanup() for more details.
- */
-SOCKET sockmain;
-
/* String identifier to be used in the pcap_findalldevs_ex() */
#define PCAP_TEXT_SOURCE_FILE "File"
/* String identifier to be used in the pcap_findalldevs_ex() */
@@ -62,21 +59,6 @@ SOCKET sockmain;
/* String identifier to be used in the pcap_findalldevs_ex() */
#define PCAP_TEXT_SOURCE_ON_LOCAL_HOST "on local host"
-/* String identifier to be used in the pcap_findalldevs_ex() */
-#define PCAP_TEXT_SOURCE_ON_REMOTE_HOST "on remote node"
-
-/*
-* Private data for capturing on WinPcap devices.
-*/
-struct pcap_win {
- int nonblock;
- int rfmon_selfstart; /* a flag tells whether the monitor mode is set by itself */
- int filtering_in_kernel; /* using kernel filter */
-
-#ifdef HAVE_DAG_API
- int dag_fcs_bits; /* Number of checksum bits from link layer */
-#endif
-};
/****************************************************
* *
@@ -86,24 +68,16 @@ struct pcap_win {
int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **alldevs, char *errbuf)
{
- SOCKET sockctrl; /* socket descriptor of the control connection */
- uint32 totread = 0; /* number of bytes of the payload read from the socket */
- int nread;
- 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 */
- struct rpcap_header header; /* structure that keeps the general header of the rpcap protocol */
- int i, j; /* temp variables */
- int naddr; /* temp var needed to avoid problems with IPv6 addresses */
- struct pcap_addr *addr; /* another such temp */
- int retval; /* store the return value of the functions */
- int nif; /* Number of interfaces listed */
- int active = 0; /* 'true' if we the other end-party is in active mode */
- char host[PCAP_BUF_SIZE], port[PCAP_BUF_SIZE], name[PCAP_BUF_SIZE], path[PCAP_BUF_SIZE], filename[PCAP_BUF_SIZE];
int type;
+ char name[PCAP_BUF_SIZE], path[PCAP_BUF_SIZE], filename[PCAP_BUF_SIZE];
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 *dev; /* Previous device into the pcap_if_t chain */
+ pcap_if_t *lastdev; /* Last device in the pcap_if_t list */
+ pcap_if_t *dev; /* Device we're adding to the pcap_if_t list */
+ /* List starts out empty. */
+ (*alldevs) = NULL;
+ lastdev = NULL;
if (strlen(source) > PCAP_BUF_SIZE)
{
@@ -123,9 +97,10 @@ int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **all
if (pcap_parsesrcstr(source, &type, NULL, NULL, NULL, errbuf) == -1)
return -1;
- if (type == PCAP_SRC_IFLOCAL)
+ switch (type)
{
- if (pcap_parsesrcstr(source, &type, host, NULL, NULL, errbuf) == -1)
+ case PCAP_SRC_IFLOCAL:
+ if (pcap_parsesrcstr(source, &type, NULL, NULL, NULL, errbuf) == -1)
return -1;
/* Initialize temporary string */
@@ -135,7 +110,7 @@ int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **all
if (pcap_findalldevs(alldevs, errbuf) == -1)
return -1;
- if ((alldevs == NULL) || (*alldevs == NULL))
+ if (*alldevs == NULL)
{
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"No interfaces found! Make sure libpcap/WinPcap is properly installed"
@@ -159,7 +134,10 @@ int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **all
dev->name = strdup(tmpstring);
if (dev->name == NULL)
{
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc() failed: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(errbuf,
+ PCAP_ERRBUF_SIZE, errno,
+ "malloc() failed");
+ pcap_freealldevs(*alldevs);
return -1;
}
@@ -178,7 +156,10 @@ int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **all
dev->description = strdup(tmpstring);
if (dev->description == NULL)
{
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc() failed: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(errbuf,
+ PCAP_ERRBUF_SIZE, errno,
+ "malloc() failed");
+ pcap_freealldevs(*alldevs);
return -1;
}
@@ -186,14 +167,11 @@ int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **all
}
return 0;
- }
- (*alldevs) = NULL;
-
- if (type == PCAP_SRC_FILE)
+ case PCAP_SRC_FILE:
{
size_t stringlen;
-#ifdef WIN32
+#ifdef _WIN32
WIN32_FIND_DATA filedata;
HANDLE filehandle;
#else
@@ -201,14 +179,14 @@ int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **all
DIR *unixdir;
#endif
- if (pcap_parsesrcstr(source, &type, host, port, name, errbuf) == -1)
+ if (pcap_parsesrcstr(source, &type, NULL, NULL, name, errbuf) == -1)
return -1;
/* Check that the filename is correct */
stringlen = strlen(name);
/* The directory must end with '\' in Win32 and '/' in UNIX */
-#ifdef WIN32
+#ifdef _WIN32
#define ENDING_CHAR '\\'
#else
#define ENDING_CHAR '/'
@@ -225,7 +203,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);
-#ifdef WIN32
+#ifdef _WIN32
/* To perform directory listing, Win32 must have an 'asterisk' as ending char */
if (name[stringlen - 1] != '*')
{
@@ -255,10 +233,11 @@ int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **all
}
#endif
+ /* Add all files we find to the list. */
do
{
-#ifdef WIN32
+#ifdef _WIN32
pcap_snprintf(filename, sizeof(filename), "%s%s", path, filedata.cFileName);
#else
pcap_snprintf(filename, sizeof(filename), "%s%s", path, filedata->d_name);
@@ -269,37 +248,54 @@ int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **all
if (fp)
{
/* allocate the main structure */
- if (*alldevs == NULL) /* This is in case it is the first file */
- {
- (*alldevs) = (pcap_if_t *)malloc(sizeof(pcap_if_t));
- dev = (*alldevs);
- }
- else
- {
- dev->next = (pcap_if_t *)malloc(sizeof(pcap_if_t));
- dev = dev->next;
- }
-
- /* check that the malloc() didn't fail */
+ dev = (pcap_if_t *)malloc(sizeof(pcap_if_t));
if (dev == NULL)
{
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc() failed: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(errbuf,
+ PCAP_ERRBUF_SIZE, errno,
+ "malloc() failed");
+ pcap_freealldevs(*alldevs);
return -1;
}
/* Initialize the structure to 'zero' */
memset(dev, 0, sizeof(pcap_if_t));
+ /* Append it to the list. */
+ if (lastdev == NULL)
+ {
+ /*
+ * List is empty, so it's also
+ * the first device.
+ */
+ *alldevs = dev;
+ }
+ else
+ {
+ /*
+ * Append after the last device.
+ */
+ lastdev->next = dev;
+ }
+ /* It's now the last device. */
+ lastdev = dev;
+
/* Create the new source identifier */
if (pcap_createsrcstr(tmpstring, PCAP_SRC_FILE, NULL, NULL, filename, errbuf) == -1)
+ {
+ pcap_freealldevs(*alldevs);
return -1;
+ }
stringlen = strlen(tmpstring);
dev->name = (char *)malloc(stringlen + 1);
if (dev->name == NULL)
{
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc() failed: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(errbuf,
+ PCAP_ERRBUF_SIZE, errno,
+ "malloc() failed");
+ pcap_freealldevs(*alldevs);
return -1;
}
@@ -317,7 +313,10 @@ int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **all
if (dev->description == NULL)
{
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc() failed: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(errbuf,
+ PCAP_ERRBUF_SIZE, errno,
+ "malloc() failed");
+ pcap_freealldevs(*alldevs);
return -1;
}
@@ -327,14 +326,14 @@ int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **all
pcap_close(fp);
}
}
-#ifdef WIN32
+#ifdef _WIN32
while (FindNextFile(filehandle, &filedata) != 0);
#else
while ( (filedata= readdir(unixdir)) != NULL);
#endif
-#ifdef WIN32
+#ifdef _WIN32
/* Close the search handle. */
FindClose(filehandle);
#endif
@@ -342,564 +341,21 @@ int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **all
return 0;
}
- /* If we come here, it is a remote host */
-
- /* 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 */
- sockctrl = rpcap_remoteact_getsock(host, &active, errbuf);
- if (sockctrl == INVALID_SOCKET)
- return -1;
-
- if (!active) {
- /*
- * We're not in active mode; let's try to open a new
- * control connection.
- */
- addrinfo = NULL;
-
- 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)) == -1)
- goto error;
-
- /* addrinfo is no longer used */
- freeaddrinfo(addrinfo);
- addrinfo = NULL;
-
- if (rpcap_sendauth(sockctrl, auth, errbuf) == -1)
- {
- sock_close(sockctrl, NULL, 0);
- return -1;
- }
- }
-
- /* RPCAP findalldevs command */
- rpcap_createhdr(&header, RPCAP_MSG_FINDALLIF_REQ, 0, 0);
-
- if (sock_send(sockctrl, (char *)&header, sizeof(struct rpcap_header), errbuf, PCAP_ERRBUF_SIZE) == -1)
- goto error;
-
- if (sock_recv(sockctrl, (char *)&header, sizeof(struct rpcap_header), SOCK_RECEIVEALL_YES, errbuf, PCAP_ERRBUF_SIZE) == -1)
- goto error;
-
- /* Checks if the message is correct */
- retval = rpcap_checkmsg(errbuf, sockctrl, &header, RPCAP_MSG_FINDALLIF_REPLY, RPCAP_MSG_ERROR, 0);
-
- if (retval != RPCAP_MSG_FINDALLIF_REPLY) /* the message is not the one expected */
- {
- switch (retval)
- {
- case -3: /* Unrecoverable network error */
- case -2: /* The other endpoint send a message that is not allowed here */
- case -1: /* The other endpoint has a version number that is not compatible with our */
- break;
-
- case RPCAP_MSG_ERROR: /* The other endpoint reported an error */
- break;
-
- default:
- {
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Internal error");
- break;
- };
- }
-
- if (!active)
- sock_close(sockctrl, NULL, 0);
-
- return -1;
- }
-
- /* read the number of interfaces */
- nif = ntohs(header.value);
-
- /* loop until all interfaces have been received */
- for (i = 0; i < nif; i++)
- {
- 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;
-
- tmpstring2[PCAP_BUF_SIZE] = 0;
-
- /* receive the findalldevs structure from remote host */
- nread = sock_recv(sockctrl, (char *)&findalldevs_if,
- sizeof(struct rpcap_findalldevs_if), SOCK_RECEIVEALL_YES,
- errbuf, PCAP_ERRBUF_SIZE);
- if (nread == -1)
- goto error;
- totread += nread;
-
- findalldevs_if.namelen = ntohs(findalldevs_if.namelen);
- findalldevs_if.desclen = ntohs(findalldevs_if.desclen);
- findalldevs_if.naddr = ntohs(findalldevs_if.naddr);
-
- /* allocate the main structure */
- if (i == 0)
- {
- (*alldevs) = (pcap_if_t *)malloc(sizeof(pcap_if_t));
- dev = (*alldevs);
- }
- else
- {
- dev->next = (pcap_if_t *)malloc(sizeof(pcap_if_t));
- dev = dev->next;
- }
-
- /* check that the malloc() didn't fail */
- if (dev == NULL)
- {
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc() failed: %s", pcap_strerror(errno));
- goto error;
- }
-
- /* Initialize the structure to 'zero' */
- memset(dev, 0, sizeof(pcap_if_t));
-
- /* allocate mem for name and description */
- if (findalldevs_if.namelen)
- {
-
- if (findalldevs_if.namelen >= sizeof(tmpstring))
- {
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Interface name too long");
- goto error;
- }
-
- /* Retrieve adapter name */
- nread = sock_recv(sockctrl, tmpstring,
- findalldevs_if.namelen, SOCK_RECEIVEALL_YES,
- errbuf, PCAP_ERRBUF_SIZE);
- if (nread == -1)
- goto error;
- totread += nread;
-
- tmpstring[findalldevs_if.namelen] = 0;
-
- /* Create the new device identifier */
- if (pcap_createsrcstr(tmpstring2, PCAP_SRC_IFREMOTE, host, port, tmpstring, errbuf) == -1)
- return -1;
-
- stringlen = strlen(tmpstring2);
-
- dev->name = (char *)malloc(stringlen + 1);
- if (dev->name == NULL)
- {
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc() failed: %s", pcap_strerror(errno));
- goto error;
- }
-
- /* Copy the new device name into the correct memory location */
- strlcpy(dev->name, tmpstring2, stringlen + 1);
- }
-
- if (findalldevs_if.desclen)
- {
- if (findalldevs_if.desclen >= sizeof(tmpstring))
- {
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Interface description too long");
- goto error;
- }
-
- /* Retrieve adapter description */
- nread = sock_recv(sockctrl, tmpstring,
- findalldevs_if.desclen, SOCK_RECEIVEALL_YES,
- errbuf, PCAP_ERRBUF_SIZE);
- if (nread == -1)
- goto error;
- totread += nread;
-
- 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)
- {
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc() failed: %s", pcap_strerror(errno));
- goto error;
- }
-
- /* Copy the new device description into the correct memory location */
- strlcpy(dev->description, tmpstring2, stringlen + 1);
- }
-
- dev->flags = ntohl(findalldevs_if.flags);
-
- naddr = 0;
- addr = NULL;
- /* loop until all addresses have been received */
- for (j = 0; j < findalldevs_if.naddr; j++)
- {
- struct rpcap_findalldevs_ifaddr ifaddr;
-
- /* Retrieve the interface addresses */
- nread = sock_recv(sockctrl, (char *)&ifaddr,
- sizeof(struct rpcap_findalldevs_ifaddr),
- SOCK_RECEIVEALL_YES, errbuf, PCAP_ERRBUF_SIZE);
- if (nread == -1)
- goto error;
- totread += nread;
-
- /*
- * WARNING libpcap bug: the address listing is
- * available only for AF_INET.
- *
- * XXX - IPv6?
- */
- if (ntohs(ifaddr.addr.ss_family) == AF_INET)
- {
- if (addr == NULL)
- {
- dev->addresses = (struct pcap_addr *) malloc(sizeof(struct pcap_addr));
- addr = dev->addresses;
- }
- else
- {
- addr->next = (struct pcap_addr *) malloc(sizeof(struct pcap_addr));
- addr = addr->next;
- }
- naddr++;
-
- if (addr == NULL)
- {
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc() failed: %s", pcap_strerror(errno));
- goto error;
- }
- addr->next = NULL;
-
- if (rpcap_deseraddr((struct sockaddr_storage *) &ifaddr.addr,
- (struct sockaddr_storage **) &addr->addr, errbuf) == -1)
- goto error;
- if (rpcap_deseraddr((struct sockaddr_storage *) &ifaddr.netmask,
- (struct sockaddr_storage **) &addr->netmask, errbuf) == -1)
- goto error;
- if (rpcap_deseraddr((struct sockaddr_storage *) &ifaddr.broadaddr,
- (struct sockaddr_storage **) &addr->broadaddr, errbuf) == -1)
- goto error;
- if (rpcap_deseraddr((struct sockaddr_storage *) &ifaddr.dstaddr,
- (struct sockaddr_storage **) &addr->dstaddr, errbuf) == -1)
- goto error;
-
- if ((addr->addr == NULL) && (addr->netmask == NULL) &&
- (addr->broadaddr == NULL) && (addr->dstaddr == NULL))
- {
- free(addr);
- addr = NULL;
- if (naddr == 1)
- naddr = 0; /* the first item of the list had NULL addresses */
- }
- }
- }
- }
-
- /* Checks if all the data has been read; if not, discard the data in excess */
- if (totread != ntohl(header.plen))
- {
- if (sock_discard(sockctrl, ntohl(header.plen) - totread, errbuf, PCAP_ERRBUF_SIZE) == 1)
- return -1;
- }
-
- /* Control connection has to be closed only in case the remote machine is in passive mode */
- if (!active)
- {
- /* DO not send RPCAP_CLOSE, since we did not open a pcap_t; no need to free resources */
- if (sock_close(sockctrl, errbuf, PCAP_ERRBUF_SIZE))
- return -1;
- }
-
- /* To avoid inconsistencies in the number of sock_init() */
- sock_cleanup();
-
- return 0;
-
-error:
- /*
- * In case there has been an error, I don't want to overwrite it with a new one
- * if the following call fails. I want to return always the original error.
- *
- * Take care: this connection can already be closed when we try to close it.
- * This happens because a previous error in the rpcapd, which requested to
- * closed the connection. In that case, we already recognized that into the
- * rpspck_isheaderok() and we already acknowledged the closing.
- * In that sense, this call is useless here (however it is needed in case
- * the client generates the error).
- *
- * Checks if all the data has been read; if not, discard the data in excess
- */
- if (totread != ntohl(header.plen))
- {
- if (sock_discard(sockctrl, ntohl(header.plen) - totread, NULL, 0) == 1)
- return -1;
- }
-
- /* Control connection has to be closed only in case the remote machine is in passive mode */
- if (!active)
- sock_close(sockctrl, NULL, 0);
-
- /* To avoid inconsistencies in the number of sock_init() */
- sock_cleanup();
-
- return -1;
-}
-
-int pcap_createsrcstr(char *source, int type, const char *host, const char *port, const char *name, char *errbuf)
-{
- switch (type)
- {
- case PCAP_SRC_FILE:
- {
- strlcpy(source, PCAP_SRC_FILE_STRING, PCAP_BUF_SIZE);
- if ((name) && (*name))
- {
- strlcat(source, name, PCAP_BUF_SIZE);
- return 0;
- }
- else
- {
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "The file name cannot be NULL.");
- return -1;
- }
- }
-
case PCAP_SRC_IFREMOTE:
- {
- strlcpy(source, PCAP_SRC_IF_STRING, PCAP_BUF_SIZE);
- if ((host) && (*host))
- {
- if ((strcspn(host, "aAbBcCdDeEfFgGhHjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ")) == strlen(host))
- {
- /* the host name does not contains alphabetic chars. So, it is a numeric address */
- /* In this case we have to include it between square brackets */
- strlcat(source, "[", PCAP_BUF_SIZE);
- strlcat(source, host, PCAP_BUF_SIZE);
- strlcat(source, "]", PCAP_BUF_SIZE);
- }
- else
- strlcat(source, host, PCAP_BUF_SIZE);
-
- if ((port) && (*port))
- {
- strlcat(source, ":", PCAP_BUF_SIZE);
- strlcat(source, port, PCAP_BUF_SIZE);
- }
-
- strlcat(source, "/", PCAP_BUF_SIZE);
- }
- else
- {
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "The host name cannot be NULL.");
- return -1;
- }
-
- if ((name) && (*name))
- strlcat(source, name, PCAP_BUF_SIZE);
-
- return 0;
- }
-
- case PCAP_SRC_IFLOCAL:
- {
- strlcpy(source, PCAP_SRC_IF_STRING, PCAP_BUF_SIZE);
-
- if ((name) && (*name))
- strlcat(source, name, PCAP_BUF_SIZE);
-
- return 0;
- }
+ return pcap_findalldevs_ex_remote(source, auth, alldevs, errbuf);
default:
- {
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "The interface type is not valid.");
+ strlcpy(errbuf, "Source type not supported", PCAP_ERRBUF_SIZE);
return -1;
}
- }
}
-int pcap_parsesrcstr(const char *source, int *type, char *host, char *port, char *name, char *errbuf)
-{
- char *ptr;
- int ntoken;
- char tmpname[PCAP_BUF_SIZE];
- char tmphost[PCAP_BUF_SIZE];
- char tmpport[PCAP_BUF_SIZE];
- int tmptype;
-
- /* Initialization stuff */
- tmpname[0] = 0;
- tmphost[0] = 0;
- tmpport[0] = 0;
-
- if (host)
- *host = 0;
- if (port)
- *port = 0;
- if (name)
- *name = 0;
-
- /* Look for a 'rpcap://' identifier */
- if ((ptr = strstr(source, PCAP_SRC_IF_STRING)) != NULL)
- {
- if (strlen(PCAP_SRC_IF_STRING) == strlen(source))
- {
- /* The source identifier contains only the 'rpcap://' string. */
- /* So, this is a local capture. */
- *type = PCAP_SRC_IFLOCAL;
- return 0;
- }
-
- ptr += strlen(PCAP_SRC_IF_STRING);
-
- if (strchr(ptr, '[')) /* This is probably a numeric address */
- {
- ntoken = sscanf(ptr, "[%[1234567890:.]]:%[^/]/%s", tmphost, tmpport, tmpname);
-
- if (ntoken == 1) /* probably the port is missing */
- ntoken = sscanf(ptr, "[%[1234567890:.]]/%s", tmphost, tmpname);
-
- tmptype = PCAP_SRC_IFREMOTE;
- }
- else
- {
- ntoken = sscanf(ptr, "%[^/:]:%[^/]/%s", tmphost, tmpport, tmpname);
-
- if (ntoken == 1)
- {
- /*
- * This can be due to two reasons:
- * - we want a remote capture, but the network port is missing
- * - we want to do a local capture
- * To distinguish between the two, we look for the '/' char
- */
- if (strchr(ptr, '/'))
- {
- /* We're on a remote capture */
- sscanf(ptr, "%[^/]/%s", tmphost, tmpname);
- tmptype = PCAP_SRC_IFREMOTE;
- }
- else
- {
- /* We're on a local capture */
- if (*ptr)
- strlcpy(tmpname, ptr, PCAP_BUF_SIZE);
-
- /* Clean the host name, since it is a remote capture */
- /* NOTE: the host name has been assigned in the previous "ntoken= sscanf(...)" line */
- tmphost[0] = 0;
-
- tmptype = PCAP_SRC_IFLOCAL;
- }
- }
- else
- tmptype = PCAP_SRC_IFREMOTE;
- }
-
- if (host)
- strlcpy(host, tmphost, PCAP_BUF_SIZE);
- if (port)
- strlcpy(port, tmpport, PCAP_BUF_SIZE);
- if (type)
- *type = tmptype;
-
- if (name)
- {
- /*
- * If the user wants the host name, but it cannot be located into the source string, return error
- * However, if the user is not interested in the interface name (e.g. if we're called by
- * pcap_findalldevs_ex(), which does not have interface name, do not return error
- */
- if (tmpname[0])
- {
- strlcpy(name, tmpname, PCAP_BUF_SIZE);
- }
- else
- {
- if (errbuf)
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "The interface name has not been specified in the source string.");
-
- return -1;
- }
- }
-
- return 0;
- }
-
- /* Look for a 'file://' identifier */
- if ((ptr = strstr(source, PCAP_SRC_FILE_STRING)) != NULL)
- {
- ptr += strlen(PCAP_SRC_FILE_STRING);
- if (*ptr)
- {
- if (name)
- strlcpy(name, ptr, PCAP_BUF_SIZE);
-
- if (type)
- *type = PCAP_SRC_FILE;
-
- return 0;
- }
- else
- {
- if (errbuf)
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "The file name has not been specified in the source string.");
-
- return -1;
- }
-
- }
-
- /* Backward compatibility; the user didn't use the 'rpcap://, file://' specifiers */
- if ((source) && (*source))
- {
- if (name)
- strlcpy(name, source, PCAP_BUF_SIZE);
-
- if (type)
- *type = PCAP_SRC_IFLOCAL;
-
- return 0;
- }
- else
- {
- if (errbuf)
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "The interface name has not been specified in the source string.");
-
- return -1;
- }
-};
-
pcap_t *pcap_open(const char *source, int snaplen, int flags, int read_timeout, struct pcap_rmtauth *auth, char *errbuf)
{
- char host[PCAP_BUF_SIZE], port[PCAP_BUF_SIZE], name[PCAP_BUF_SIZE];
+ char name[PCAP_BUF_SIZE];
int type;
pcap_t *fp;
- int result;
+ int status;
if (strlen(source) > PCAP_BUF_SIZE)
{
@@ -907,359 +363,92 @@ pcap_t *pcap_open(const char *source, int snaplen, int flags, int read_timeout,
return NULL;
}
- /* determine the type of the source (file, local, remote) */
- if (pcap_parsesrcstr(source, &type, host, port, name, errbuf) == -1)
+ /*
+ * Determine the type of the source (file, local, remote) and,
+ * if it's file or local, the name of the file or capture device.
+ */
+ if (pcap_parsesrcstr(source, &type, NULL, NULL, name, errbuf) == -1)
return NULL;
-
switch (type)
{
case PCAP_SRC_FILE:
- fp = pcap_open_offline(name, errbuf);
+ return pcap_open_offline(name, errbuf);
+
+ case PCAP_SRC_IFLOCAL:
+ fp = pcap_create(name, errbuf);
break;
case PCAP_SRC_IFREMOTE:
- fp = pcap_create(source, errbuf);
- if (fp == NULL)
- {
- return NULL;
- }
-
/*
- * Although we already have host, port and iface, we prefer TO PASS only 'pars' to the
- * pcap_open_remote() so that it has to call the pcap_parsesrcstr() again.
+ * Although we already have host, port and iface, we prefer
+ * to pass only 'source' to pcap_open_rpcap(), so that it
+ * has to call pcap_parsesrcstr() again.
* This is less optimized, but much clearer.
*/
-
- result = pcap_opensource_remote(fp, auth);
-
- if (result != 0)
- {
- pcap_close(fp);
- return NULL;
- }
-
- struct pcap_md *md; /* structure used when doing a remote live capture */
- md = (struct pcap_md *) ((u_char*)fp->priv + sizeof(struct pcap_win));
-
- fp->snapshot = snaplen;
- fp->opt.timeout = read_timeout;
- md->rmt_flags = flags;
- break;
-
- case PCAP_SRC_IFLOCAL:
-
- fp = pcap_open_live(name, snaplen, (flags & PCAP_OPENFLAG_PROMISCUOUS), read_timeout, errbuf);
-
-#ifdef WIN32
- /*
- * these flags are supported on Windows only
- */
- if (fp != NULL && fp->adapter != NULL)
- {
- /* disable loopback capture if requested */
- if (flags & PCAP_OPENFLAG_NOCAPTURE_LOCAL)
- {
- if (!PacketSetLoopbackBehavior(fp->adapter, NPF_DISABLE_LOOPBACK))
- {
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Unable to disable the capture of loopback packets.");
- pcap_close(fp);
- return NULL;
- }
- }
-
- /* set mintocopy to zero if requested */
- if (flags & PCAP_OPENFLAG_MAX_RESPONSIVENESS)
- {
- if (!PacketSetMinToCopy(fp->adapter, 0))
- {
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Unable to set max responsiveness.");
- pcap_close(fp);
- return NULL;
- }
- }
- }
-#endif /* WIN32 */
-
- break;
+ return pcap_open_rpcap(source, snaplen, flags, read_timeout, auth, errbuf);
default:
strlcpy(errbuf, "Source type not supported", PCAP_ERRBUF_SIZE);
return NULL;
}
- return fp;
-}
-
-struct pcap_samp *pcap_setsampling(pcap_t *p)
-{
- struct pcap_md *md; /* structure used when doing a remote live capture */
-
- md = (struct pcap_md *) ((u_char*)p->priv + sizeof(struct pcap_win));
- return &(md->rmt_samp);
-}
-
-SOCKET pcap_remoteact_accept(const char *address, const char *port, const char *hostlist, char *connectinghost, struct pcap_rmtauth *auth, char *errbuf)
-{
- /* socket-related variables */
- struct addrinfo hints; /* temporary struct to keep settings needed to open the new socket */
- struct addrinfo *addrinfo; /* keeps the addrinfo chain; required to open a new socket */
- struct sockaddr_storage from; /* generic sockaddr_storage variable */
- socklen_t fromlen; /* keeps the length of the sockaddr_storage variable */
- SOCKET sockctrl; /* keeps the main socket identifier */
- struct activehosts *temp, *prev; /* temp var needed to scan he host list chain */
-
- *connectinghost = 0; /* just in case */
-
- /* Prepare to open a new server socket */
- memset(&hints, 0, sizeof(struct addrinfo));
- /* WARNING Currently it supports only ONE socket family among ipv4 and IPv6 */
- hints.ai_family = AF_INET; /* PF_UNSPEC to have both IPv4 and IPv6 server */
- hints.ai_flags = AI_PASSIVE; /* Ready to a bind() socket */
- hints.ai_socktype = SOCK_STREAM;
-
- /* 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;
- /* Do the work */
- if ((port == NULL) || (port[0] == 0))
+ if (fp == NULL)
+ return (NULL);
+ status = pcap_set_snaplen(fp, snaplen);
+ if (status < 0)
+ goto fail;
+ if (flags & PCAP_OPENFLAG_PROMISCUOUS)
{
- if (sock_initaddress(address, RPCAP_DEFAULT_NETPORT_ACTIVE, &hints, &addrinfo, errbuf, PCAP_ERRBUF_SIZE) == -1)
- {
- SOCK_ASSERT(errbuf, 1);
- return -2;
- }
+ status = pcap_set_promisc(fp, 1);
+ if (status < 0)
+ goto fail;
}
- else
- {
- if (sock_initaddress(address, port, &hints, &addrinfo, errbuf, PCAP_ERRBUF_SIZE) == -1)
- {
- SOCK_ASSERT(errbuf, 1);
- return -2;
- }
- }
-
-
- if ((sockmain = sock_open(addrinfo, SOCKOPEN_SERVER, 1, errbuf, PCAP_ERRBUF_SIZE)) == -1)
- {
- SOCK_ASSERT(errbuf, 1);
- return -2;
- }
-
- /* Connection creation */
- fromlen = sizeof(struct sockaddr_storage);
-
- sockctrl = accept(sockmain, (struct sockaddr *) &from, &fromlen);
-
- /* We're not using sock_close, since we do not want to send a shutdown */
- /* (which is not allowed on a non-connected socket) */
- closesocket(sockmain);
- sockmain = 0;
-
- if (sockctrl == -1)
+ if (flags & PCAP_OPENFLAG_MAX_RESPONSIVENESS)
{
- sock_geterror("accept(): ", errbuf, PCAP_ERRBUF_SIZE);
- return -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);
- rpcap_senderror(sockctrl, errbuf, PCAP_ERR_REMOTEACCEPT, NULL);
- sock_close(sockctrl, NULL, 0);
- return -1;
- }
-
- /* checks if the connecting host is among the ones allowed */
- if (sock_check_hostlist((char *)hostlist, RPCAP_HOSTLIST_SEP, &from, errbuf, PCAP_ERRBUF_SIZE) < 0)
- {
- rpcap_senderror(sockctrl, errbuf, PCAP_ERR_REMOTEACCEPT, NULL);
- sock_close(sockctrl, NULL, 0);
- return -1;
- }
-
- /* Send authentication to the remote machine */
- if (rpcap_sendauth(sockctrl, auth, errbuf) == -1)
- {
- rpcap_senderror(sockctrl, errbuf, PCAP_ERR_REMOTEACCEPT, NULL);
- sock_close(sockctrl, NULL, 0);
- return -3;
- }
-
- /* Checks that this host does not already have a cntrl connection in place */
-
- /* Initialize pointers */
- temp = activeHosts;
- prev = NULL;
-
- while (temp)
- {
- /* This host already has an active connection in place, so I don't have to update the host list */
- if (sock_cmpaddr(&temp->host, &from) == 0)
- return sockctrl;
-
- prev = temp;
- temp = temp->next;
+ status = pcap_set_immediate_mode(fp, 1);
+ if (status < 0)
+ goto fail;
}
+#ifdef _WIN32
+ /*
+ * This flag is supported on Windows only.
+ * XXX - is there a way to support it with
+ * the capture mechanisms on UN*X? It's not
+ * exactly a "set direction" operation; I
+ * think it means "do not capture packets
+ * injected with pcap_sendpacket() or
+ * pcap_inject()".
+ */
+ /* disable loopback capture if requested */
+ if (flags & PCAP_OPENFLAG_NOCAPTURE_LOCAL)
+ fp->opt.nocapture_local = 1;
+#endif /* _WIN32 */
+ status = pcap_set_timeout(fp, read_timeout);
+ if (status < 0)
+ goto fail;
+ status = pcap_activate(fp);
+ if (status < 0)
+ goto fail;
+ return fp;
- /* The host does not exist in the list; so I have to update the list */
- if (prev)
- {
- prev->next = (struct activehosts *) malloc(sizeof(struct activehosts));
- temp = prev->next;
- }
+fail:
+ if (status == PCAP_ERROR)
+ pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s",
+ name, fp->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)",
+ name, pcap_statustostr(status), fp->errbuf);
else
- {
- activeHosts = (struct activehosts *) malloc(sizeof(struct activehosts));
- temp = activeHosts;
- }
-
- if (temp == NULL)
- {
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc() failed: %s", pcap_strerror(errno));
- rpcap_senderror(sockctrl, errbuf, PCAP_ERR_REMOTEACCEPT, NULL);
- sock_close(sockctrl, NULL, 0);
- return -1;
- }
-
- memcpy(&temp->host, &from, fromlen);
- temp->sockctrl = sockctrl;
- temp->next = NULL;
-
- return sockctrl;
+ pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s",
+ name, pcap_statustostr(status));
+ pcap_close(fp);
+ return NULL;
}
-int pcap_remoteact_close(const char *host, char *errbuf)
-{
- struct activehosts *temp, *prev; /* temp var needed to scan the host list chain */
- struct addrinfo hints, *addrinfo, *ai_next; /* temp var needed to translate between hostname to its address */
- int retval;
-
- temp = activeHosts;
- prev = NULL;
-
- /* retrieve the network address corresponding to 'host' */
- addrinfo = NULL;
- memset(&hints, 0, sizeof(struct addrinfo));
- hints.ai_family = PF_UNSPEC;
- hints.ai_socktype = SOCK_STREAM;
-
- retval = getaddrinfo(host, "0", &hints, &addrinfo);
- if (retval != 0)
- {
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "getaddrinfo() %s", gai_strerror(retval));
- return -1;
- }
-
- while (temp)
- {
- ai_next = addrinfo;
- while (ai_next)
- {
- if (sock_cmpaddr(&temp->host, (struct sockaddr_storage *) ai_next->ai_addr) == 0)
- {
- struct rpcap_header header;
-
- /* Close this connection */
- rpcap_createhdr(&header, RPCAP_MSG_CLOSE, 0, 0);
-
- /* I don't check for errors, since I'm going to close everything */
- sock_send(temp->sockctrl, (char *)&header, sizeof(struct rpcap_header), errbuf, PCAP_ERRBUF_SIZE);
-
- if (sock_close(temp->sockctrl, errbuf, PCAP_ERRBUF_SIZE))
- {
- /* To avoid inconsistencies in the number of sock_init() */
- sock_cleanup();
-
- return -1;
- }
-
- if (prev)
- prev->next = temp->next;
- else
- activeHosts = temp->next;
-
- freeaddrinfo(addrinfo);
-
- free(temp);
-
- /* To avoid inconsistencies in the number of sock_init() */
- sock_cleanup();
-
- return 0;
- }
-
- ai_next = ai_next->ai_next;
- }
- prev = temp;
- temp = temp->next;
- }
-
- if (addrinfo)
- freeaddrinfo(addrinfo);
-
- /* To avoid inconsistencies in the number of sock_init() */
- sock_cleanup();
-
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "The host you want to close the active connection is not known");
- return -1;
-}
-
-void pcap_remoteact_cleanup(void)
-{
- /* Very dirty, but it works */
- if (sockmain)
- {
- closesocket(sockmain);
-
- /* To avoid inconsistencies in the number of sock_init() */
- sock_cleanup();
- }
-
-}
-
-int pcap_remoteact_list(char *hostlist, char sep, int size, char *errbuf)
+struct pcap_samp *pcap_setsampling(pcap_t *p)
{
- struct activehosts *temp; /* temp var needed to scan the host list chain */
- size_t len;
- char hoststr[RPCAP_HOSTLIST_SIZE + 1];
-
- temp = activeHosts;
-
- len = 0;
- *hostlist = 0;
-
- while (temp)
- {
- /*int sock_getascii_addrport(const struct sockaddr_storage *sockaddr, char *address, int addrlen, char *port, int portlen, int flags, char *errbuf, int errbuflen) */
-
- /* Get the numeric form of the name of the connecting host */
- if (sock_getascii_addrport((struct sockaddr_storage *) &temp->host, hoststr,
- RPCAP_HOSTLIST_SIZE, NULL, 0, NI_NUMERICHOST, errbuf, PCAP_ERRBUF_SIZE) != -1)
- /* 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); */
- return -1;
- }
-
- len = len + strlen(hoststr) + 1 /* the separator */;
-
- if ((size < 0) || (len >= (size_t)size))
- {
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "The string you provided is not able to keep "
- "the hostnames for all the active connections");
- return -1;
- }
-
- strlcat(hostlist, hoststr, PCAP_ERRBUF_SIZE);
- hostlist[len - 1] = sep;
- hostlist[len] = 0;
-
- temp = temp->next;
- }
-
- return 0;
+ return &p->rmt_samp;
}
diff --git a/contrib/libpcap/pcap-nit.c b/contrib/libpcap/pcap-nit.c
index 1b626e215a22c..6a1a77c24c681 100644
--- a/contrib/libpcap/pcap-nit.c
+++ b/contrib/libpcap/pcap-nit.c
@@ -20,7 +20,7 @@
*/
#ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
#endif
#include <sys/types.h>
@@ -114,8 +114,8 @@ pcap_read_nit(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
if (cc < 0) {
if (errno == EWOULDBLOCK)
return (0);
- pcap_snprintf(p->errbuf, sizeof(p->errbuf), "pcap_read: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, sizeof(p->errbuf),
+ errno, "pcap_read");
return (-1);
}
bp = (u_char *)p->buffer;
@@ -206,8 +206,8 @@ pcap_inject_nit(pcap_t *p, const void *buf, size_t size)
strncpy(sa.sa_data, device, sizeof(sa.sa_data));
ret = sendto(p->fd, buf, size, 0, &sa, sizeof(sa));
if (ret == -1) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "send");
return (-1);
}
return (ret);
@@ -249,8 +249,8 @@ nit_setflags(pcap_t *p)
nioc.nioc_flags |= NF_PROMISC;
if (ioctl(p->fd, SIOCSNIT, &nioc) < 0) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "SIOCSNIT: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "SIOCSNIT");
return (-1);
}
return (0);
@@ -271,6 +271,17 @@ pcap_activate_nit(pcap_t *p)
return (PCAP_ERROR_RFMON_NOTSUP);
}
+ /*
+ * Turn a negative snapshot value (invalid), a snapshot value of
+ * 0 (unspecified), or a value bigger than the normal maximum
+ * value, into the maximum allowed value.
+ *
+ * If some application really *needs* a bigger snapshot
+ * length, we should just increase MAXIMUM_SNAPLEN.
+ */
+ if (p->snapshot <= 0 || p->snapshot > MAXIMUM_SNAPLEN)
+ p->snapshot = MAXIMUM_SNAPLEN;
+
if (p->snapshot < 96)
/*
* NIT requires a snapshot length of at least 96.
@@ -280,8 +291,8 @@ pcap_activate_nit(pcap_t *p)
memset(p, 0, sizeof(*p));
p->fd = fd = socket(AF_NIT, SOCK_RAW, NITPROTO_RAW);
if (fd < 0) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "socket: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "socket");
goto bad;
}
snit.snit_family = AF_NIT;
@@ -295,8 +306,8 @@ pcap_activate_nit(pcap_t *p)
* they might be the same error, if they both end up
* meaning "NIT doesn't know about that device".
*/
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "bind: %s: %s", snit.snit_ifname, pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "bind: %s", snit.snit_ifname);
goto bad;
}
if (nit_setflags(p) < 0)
@@ -310,7 +321,8 @@ pcap_activate_nit(pcap_t *p)
p->bufsize = BUFSPACE;
p->buffer = malloc(p->bufsize);
if (p->buffer == NULL) {
- strlcpy(p->errbuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "malloc");
goto bad;
}
@@ -377,8 +389,29 @@ can_be_bound(const char *name _U_)
return (1);
}
+static int
+get_if_flags(const char *name _U_, bpf_u_int32 *flags _U_, char *errbuf _U_)
+{
+ /*
+ * Nothing we can do.
+ * XXX - is there a way to find out whether an adapter has
+ * something plugged into it?
+ */
+ return (0);
+}
+
int
-pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
+pcap_platform_finddevs(pcap_if_list_t *devlistp, char *errbuf)
+{
+ return (pcap_findalldevs_interfaces(devlistp, errbuf, can_be_bound,
+ get_if_flags));
+}
+
+/*
+ * Libpcap version string.
+ */
+const char *
+pcap_lib_version(void)
{
- return (pcap_findalldevs_interfaces(alldevsp, errbuf, can_be_bound));
+ return (PCAP_VERSION_STRING);
}
diff --git a/contrib/libpcap/pcap-win32.c b/contrib/libpcap/pcap-npf.c
index d998637e6baa5..472b042104e5b 100644
--- a/contrib/libpcap/pcap-win32.c
+++ b/contrib/libpcap/pcap-npf.c
@@ -31,36 +31,34 @@
*
*/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <errno.h>
#define PCAP_DONT_INCLUDE_PCAP_BPF_H
#include <Packet32.h>
#include <pcap-int.h>
#include <pcap/dlt.h>
-#ifdef __MINGW32__
-#ifdef __MINGW64__
-#include <ntddndis.h>
-#else /*__MINGW64__*/
-#include <ddk/ntddndis.h>
-#include <ddk/ndis.h>
-#endif /*__MINGW64__*/
-#else /*__MINGW32__*/
-#include <ntddndis.h>
-#endif /*__MINGW32__*/
+
+/* Old-school MinGW have these headers in a different place.
+ */
+#if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)
+ #include <ddk/ntddndis.h>
+ #include <ddk/ndis.h>
+#else
+ #include <ntddndis.h> /* MSVC/TDM-MinGW/MinGW64 */
+#endif
+
#ifdef HAVE_DAG_API
-#include <dagnew.h>
-#include <dagapi.h>
+ #include <dagnew.h>
+ #include <dagapi.h>
#endif /* HAVE_DAG_API */
-#ifdef __MINGW32__
-int* _errno();
-#define errno (*_errno())
-#endif /* __MINGW32__ */
-#ifdef HAVE_REMOTE
-#include "pcap-rpcap.h"
-#endif /* HAVE_REMOTE */
-
-static int pcap_setfilter_win32_npf(pcap_t *, struct bpf_program *);
+
+static int pcap_setfilter_npf(pcap_t *, struct bpf_program *);
static int pcap_setfilter_win32_dag(pcap_t *, struct bpf_program *);
-static int pcap_getnonblock_win32(pcap_t *, char *);
-static int pcap_setnonblock_win32(pcap_t *, int, char *);
+static int pcap_getnonblock_npf(pcap_t *);
+static int pcap_setnonblock_npf(pcap_t *, int);
/*dimension of the buffer in the pcap_t structure*/
#define WIN32_DEFAULT_USER_BUFFER_SIZE 256000
@@ -75,6 +73,7 @@ static int pcap_setnonblock_win32(pcap_t *, int, char *);
* Private data for capturing on WinPcap devices.
*/
struct pcap_win {
+ ADAPTER *adapter; /* the packet32 ADAPTER for the device */
int nonblock;
int rfmon_selfstart; /* a flag tells whether the monitor mode is set by itself */
int filtering_in_kernel; /* using kernel filter */
@@ -82,16 +81,12 @@ struct pcap_win {
#ifdef HAVE_DAG_API
int dag_fcs_bits; /* Number of checksum bits from link layer */
#endif
-};
-BOOL WINAPI DllMain(
- HANDLE hinstDLL,
- DWORD dwReason,
- LPVOID lpvReserved
-)
-{
- return (TRUE);
-}
+#ifdef ENABLE_REMOTE
+ int samp_npkt; /* parameter needed for sampling, with '1 out of N' method has been requested */
+ struct timeval samp_time; /* parameter needed for sampling, with '1 every N ms' method has been requested */
+#endif
+};
/*
* Define stub versions of the monitor-mode support routines if this
@@ -123,7 +118,7 @@ static int
PacketGetMonitorMode(PCHAR AdapterName _U_)
{
/*
- * This should fail, so that pcap_activate_win32() returns
+ * This should fail, so that pcap_activate_npf() returns
* PCAP_ERROR_RFMON_NOTSUP if our caller requested monitor
* mode.
*/
@@ -131,37 +126,72 @@ PacketGetMonitorMode(PCHAR AdapterName _U_)
}
#endif
-/* Start winsock */
-int
-wsockinit(void)
-{
- WORD wVersionRequested;
- WSADATA wsaData;
- static int err = -1;
- static int done = 0;
-
- if (done)
- return (err);
-
- wVersionRequested = MAKEWORD( 1, 1);
- err = WSAStartup( wVersionRequested, &wsaData );
- atexit ((void(*)(void))WSACleanup);
- done = 1;
-
- if ( err != 0 )
- err = -1;
- return (err);
-}
+/*
+ * Sigh. PacketRequest() will have made a DeviceIoControl()
+ * call to the NPF driver to perform the OID request, with a
+ * BIOCQUERYOID ioctl. The kernel code should get back one
+ * of NDIS_STATUS_INVALID_OID, NDIS_STATUS_NOT_SUPPORTED,
+ * or NDIS_STATUS_NOT_RECOGNIZED if the OID request isn't
+ * supported by the OS or the driver, but that doesn't seem
+ * to make it to the caller of PacketRequest() in a
+ * reiable fashion.
+ */
+#define NDIS_STATUS_INVALID_OID 0xc0010017
+#define NDIS_STATUS_NOT_SUPPORTED 0xc00000bb /* STATUS_NOT_SUPPORTED */
+#define NDIS_STATUS_NOT_RECOGNIZED 0x00010001
-int
-pcap_wsockinit(void)
+static int
+oid_get_request(ADAPTER *adapter, bpf_u_int32 oid, void *data, size_t *lenp,
+ char *errbuf)
{
- return (wsockinit());
+ PACKET_OID_DATA *oid_data_arg;
+
+ /*
+ * Allocate a PACKET_OID_DATA structure to hand to PacketRequest().
+ * It should be big enough to hold "*lenp" bytes of data; it
+ * will actually be slightly larger, as PACKET_OID_DATA has a
+ * 1-byte data array at the end, standing in for the variable-length
+ * data that's actually there.
+ */
+ oid_data_arg = malloc(sizeof (PACKET_OID_DATA) + *lenp);
+ if (oid_data_arg == NULL) {
+ pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "Couldn't allocate argument buffer for PacketRequest");
+ return (PCAP_ERROR);
+ }
+
+ /*
+ * No need to copy the data - we're doing a fetch.
+ */
+ 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);
+ free(oid_data_arg);
+ return (-1);
+ }
+
+ /*
+ * Get the length actually supplied.
+ */
+ *lenp = oid_data_arg->Length;
+
+ /*
+ * Copy back the data we fetched.
+ */
+ memcpy(data, oid_data_arg->Data, *lenp);
+ free(oid_data_arg);
+ return (0);
}
static int
-pcap_stats_win32(pcap_t *p, struct pcap_stat *ps)
+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];
@@ -178,7 +208,7 @@ pcap_stats_win32(pcap_t *p, struct pcap_stat *ps)
* in would stomp on whatever comes after the structure passed
* to us.
*/
- if (!PacketGetStats(p->adapter, &bstats)) {
+ if (!PacketGetStats(pw->adapter, &bstats)) {
pcap_win32_err_to_str(GetLastError(), errbuf);
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"PacketGetStats error: %s", errbuf);
@@ -222,8 +252,9 @@ pcap_stats_win32(pcap_t *p, struct pcap_stat *ps)
* possibly-bogus values for statistics we can't provide.
*/
struct pcap_stat *
-pcap_stats_ex_win32(pcap_t *p, int *pcap_stat_size)
+pcap_stats_ex_npf(pcap_t *p, int *pcap_stat_size)
{
+ struct pcap_win *pw = p->priv;
struct bpf_stat bstats;
char errbuf[PCAP_ERRBUF_SIZE+1];
@@ -236,7 +267,7 @@ pcap_stats_ex_win32(pcap_t *p, int *pcap_stat_size)
* WinPcap's "struct bpf_stat". It might currently have the
* same layout, but let's not cheat.)
*/
- if (!PacketGetStatsEx(p->adapter, &bstats)) {
+ if (!PacketGetStatsEx(pw->adapter, &bstats)) {
pcap_win32_err_to_str(GetLastError(), errbuf);
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"PacketGetStatsEx error: %s", errbuf);
@@ -245,7 +276,7 @@ pcap_stats_ex_win32(pcap_t *p, int *pcap_stat_size)
p->stat.ps_recv = bstats.bs_recv;
p->stat.ps_drop = bstats.bs_drop;
p->stat.ps_ifdrop = bstats.ps_ifdrop;
-#ifdef HAVE_REMOTE
+#ifdef ENABLE_REMOTE
p->stat.ps_capt = bstats.bs_capt;
#endif
return (&p->stat);
@@ -253,9 +284,11 @@ pcap_stats_ex_win32(pcap_t *p, int *pcap_stat_size)
/* Set the dimension of the kernel-level capture buffer */
static int
-pcap_setbuff_win32(pcap_t *p, int dim)
+pcap_setbuff_npf(pcap_t *p, int dim)
{
- if(PacketSetBuff(p->adapter,dim)==FALSE)
+ struct pcap_win *pw = p->priv;
+
+ if(PacketSetBuff(pw->adapter,dim)==FALSE)
{
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: not enough memory to allocate the kernel buffer");
return (-1);
@@ -265,9 +298,11 @@ pcap_setbuff_win32(pcap_t *p, int dim)
/* Set the driver working mode */
static int
-pcap_setmode_win32(pcap_t *p, int mode)
+pcap_setmode_npf(pcap_t *p, int mode)
{
- if(PacketSetMode(p->adapter,mode)==FALSE)
+ struct pcap_win *pw = p->priv;
+
+ if(PacketSetMode(pw->adapter,mode)==FALSE)
{
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: working mode not recognized");
return (-1);
@@ -278,9 +313,11 @@ pcap_setmode_win32(pcap_t *p, int mode)
/*set the minimum amount of data that will release a read call*/
static int
-pcap_setmintocopy_win32(pcap_t *p, int size)
+pcap_setmintocopy_npf(pcap_t *p, int size)
{
- if(PacketSetMinToCopy(p->adapter, size)==FALSE)
+ struct pcap_win *pw = p->priv;
+
+ if(PacketSetMinToCopy(pw->adapter, size)==FALSE)
{
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: unable to set the requested mintocopy size");
return (-1);
@@ -289,61 +326,26 @@ pcap_setmintocopy_win32(pcap_t *p, int size)
}
static HANDLE
-pcap_getevent_win32(pcap_t *p)
+pcap_getevent_npf(pcap_t *p)
{
- return (PacketGetReadEvent(p->adapter));
+ struct pcap_win *pw = p->priv;
+
+ return (PacketGetReadEvent(pw->adapter));
}
static int
-pcap_oid_get_request_win32(pcap_t *p, bpf_u_int32 oid, void *data, size_t *lenp)
+pcap_oid_get_request_npf(pcap_t *p, bpf_u_int32 oid, void *data, size_t *lenp)
{
- PACKET_OID_DATA *oid_data_arg;
- char errbuf[PCAP_ERRBUF_SIZE+1];
-
- /*
- * Allocate a PACKET_OID_DATA structure to hand to PacketRequest().
- * It should be big enough to hold "*lenp" bytes of data; it
- * will actually be slightly larger, as PACKET_OID_DATA has a
- * 1-byte data array at the end, standing in for the variable-length
- * data that's actually there.
- */
- oid_data_arg = malloc(sizeof (PACKET_OID_DATA) + *lenp);
- if (oid_data_arg == NULL) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "Couldn't allocate argument buffer for PacketRequest");
- return (PCAP_ERROR);
- }
-
- /*
- * No need to copy the data - we're doing a fetch.
- */
- oid_data_arg->Oid = oid;
- oid_data_arg->Length = (ULONG)(*lenp); /* XXX - check for ridiculously large value? */
- if (!PacketRequest(p->adapter, FALSE, oid_data_arg)) {
- pcap_win32_err_to_str(GetLastError(), errbuf);
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "Error calling PacketRequest: %s", errbuf);
- free(oid_data_arg);
- return (PCAP_ERROR);
- }
-
- /*
- * Get the length actually supplied.
- */
- *lenp = oid_data_arg->Length;
+ struct pcap_win *pw = p->priv;
- /*
- * Copy back the data we fetched.
- */
- memcpy(data, oid_data_arg->Data, *lenp);
- free(oid_data_arg);
- return (0);
+ return (oid_get_request(pw->adapter, oid, data, lenp, p->errbuf));
}
static int
-pcap_oid_set_request_win32(pcap_t *p, bpf_u_int32 oid, const void *data,
+pcap_oid_set_request_npf(pcap_t *p, bpf_u_int32 oid, const void *data,
size_t *lenp)
{
+ struct pcap_win *pw = p->priv;
PACKET_OID_DATA *oid_data_arg;
char errbuf[PCAP_ERRBUF_SIZE+1];
@@ -364,7 +366,7 @@ pcap_oid_set_request_win32(pcap_t *p, bpf_u_int32 oid, const void *data,
oid_data_arg->Oid = oid;
oid_data_arg->Length = (ULONG)(*lenp); /* XXX - check for ridiculously large value? */
memcpy(oid_data_arg->Data, data, *lenp);
- if (!PacketRequest(p->adapter, TRUE, oid_data_arg)) {
+ 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);
@@ -385,18 +387,19 @@ pcap_oid_set_request_win32(pcap_t *p, bpf_u_int32 oid, const void *data,
}
static u_int
-pcap_sendqueue_transmit_win32(pcap_t *p, pcap_send_queue *queue, int sync)
+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 (p->adapter==NULL) {
+ if (pw->adapter==NULL) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"Cannot transmit a queue to an offline capture or to a TurboCap port");
return (0);
}
- res = PacketSendPackets(p->adapter,
+ res = PacketSendPackets(pw->adapter,
queue->buffer,
queue->len,
(BOOLEAN)sync);
@@ -411,7 +414,7 @@ pcap_sendqueue_transmit_win32(pcap_t *p, pcap_send_queue *queue, int sync)
}
static int
-pcap_setuserbuffer_win32(pcap_t *p, int size)
+pcap_setuserbuffer_npf(pcap_t *p, int size)
{
unsigned char *new_buff;
@@ -440,12 +443,13 @@ pcap_setuserbuffer_win32(pcap_t *p, int size)
}
static int
-pcap_live_dump_win32(pcap_t *p, char *filename, int maxsize, int maxpacks)
+pcap_live_dump_npf(pcap_t *p, char *filename, int maxsize, int maxpacks)
{
+ struct pcap_win *pw = p->priv;
BOOLEAN res;
/* Set the packet driver in dump mode */
- res = PacketSetMode(p->adapter, PACKET_MODE_DUMP);
+ res = PacketSetMode(pw->adapter, PACKET_MODE_DUMP);
if(res == FALSE){
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"Error setting dump mode");
@@ -453,7 +457,7 @@ pcap_live_dump_win32(pcap_t *p, char *filename, int maxsize, int maxpacks)
}
/* Set the name of the dump file */
- res = PacketSetDumpName(p->adapter, filename, (int)strlen(filename));
+ res = PacketSetDumpName(pw->adapter, filename, (int)strlen(filename));
if(res == FALSE){
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"Error setting kernel dump file name");
@@ -461,29 +465,38 @@ pcap_live_dump_win32(pcap_t *p, char *filename, int maxsize, int maxpacks)
}
/* Set the limits of the dump file */
- res = PacketSetDumpLimits(p->adapter, maxsize, maxpacks);
+ res = PacketSetDumpLimits(pw->adapter, maxsize, maxpacks);
+ if(res == FALSE) {
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "Error setting dump limit");
+ return (-1);
+ }
return (0);
}
static int
-pcap_live_dump_ended_win32(pcap_t *p, int sync)
+pcap_live_dump_ended_npf(pcap_t *p, int sync)
{
- return (PacketIsDumpEnded(p->adapter, (BOOLEAN)sync));
+ struct pcap_win *pw = p->priv;
+
+ return (PacketIsDumpEnded(pw->adapter, (BOOLEAN)sync));
}
static PAirpcapHandle
-pcap_get_airpcap_handle_win32(pcap_t *p)
+pcap_get_airpcap_handle_npf(pcap_t *p)
{
#ifdef HAVE_AIRPCAP_API
- return (PacketGetAirPcapHandle(p->adapter));
+ struct pcap_win *pw = p->priv;
+
+ return (PacketGetAirPcapHandle(pw->adapter));
#else
return (NULL);
#endif /* HAVE_AIRPCAP_API */
}
static int
-pcap_read_win32_npf(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
+pcap_read_npf(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
{
PACKET Packet;
int cc;
@@ -520,7 +533,7 @@ pcap_read_win32_npf(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
* the stack.
*/
PacketInitPacket(&Packet, (BYTE *)p->buffer, p->bufsize);
- if (!PacketReceivePacket(p->adapter, &Packet, TRUE)) {
+ if (!PacketReceivePacket(pw->adapter, &Packet, TRUE)) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read error: PacketReceivePacket failed");
return (PCAP_ERROR);
}
@@ -537,7 +550,7 @@ pcap_read_win32_npf(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
*/
#define bhp ((struct bpf_hdr *)bp)
ep = bp + cc;
- while (1) {
+ for (;;) {
register int caplen, hdrlen;
/*
@@ -579,6 +592,47 @@ pcap_read_win32_npf(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
if (pw->filtering_in_kernel ||
p->fcode.bf_insns == NULL ||
bpf_filter(p->fcode.bf_insns, datap, bhp->bh_datalen, caplen)) {
+#ifdef ENABLE_REMOTE
+ switch (p->rmt_samp.method) {
+
+ case PCAP_SAMP_1_EVERY_N:
+ pw->samp_npkt = (pw->samp_npkt + 1) % p->rmt_samp.value;
+
+ /* Discard all packets that are not '1 out of N' */
+ if (pw->samp_npkt != 0) {
+ bp += Packet_WORDALIGN(caplen + hdrlen);
+ continue;
+ }
+ break;
+
+ case PCAP_SAMP_FIRST_AFTER_N_MS:
+ {
+ struct pcap_pkthdr *pkt_header = (struct pcap_pkthdr*) bp;
+
+ /*
+ * Check if the timestamp of the arrived
+ * packet is smaller than our target time.
+ */
+ if (pkt_header->ts.tv_sec < pw->samp_time.tv_sec ||
+ (pkt_header->ts.tv_sec == pw->samp_time.tv_sec && pkt_header->ts.tv_usec < pw->samp_time.tv_usec)) {
+ bp += Packet_WORDALIGN(caplen + hdrlen);
+ continue;
+ }
+
+ /*
+ * The arrived packet is suitable for being
+ * delivered to our caller, so let's update
+ * the target time.
+ */
+ pw->samp_time.tv_usec = pkt_header->ts.tv_usec + p->rmt_samp.value * 1000;
+ if (pw->samp_time.tv_usec > 1000000) {
+ pw->samp_time.tv_sec = pkt_header->ts.tv_sec + pw->samp_time.tv_usec / 1000000;
+ pw->samp_time.tv_usec = pw->samp_time.tv_usec % 1000000;
+ }
+ }
+ }
+#endif /* ENABLE_REMOTE */
+
/*
* XXX A bpf_hdr matches a pcap_pkthdr.
*/
@@ -617,7 +671,7 @@ pcap_read_win32_dag(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
ULONGLONG ts;
int cc;
unsigned swt;
- unsigned dfp = p->adapter->DagFastProcess;
+ unsigned dfp = pw->adapter->DagFastProcess;
cc = p->cc;
if (cc == 0) /* Get new packets only if we have processed all the ones of the previous read */
@@ -635,7 +689,7 @@ pcap_read_win32_dag(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
* the stack.
*/
PacketInitPacket(&Packet, (BYTE *)p->buffer, p->bufsize);
- if (!PacketReceivePacket(p->adapter, &Packet, TRUE)) {
+ if (!PacketReceivePacket(pw->adapter, &Packet, TRUE)) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read error: PacketReceivePacket failed");
return (-1);
}
@@ -644,7 +698,7 @@ pcap_read_win32_dag(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
if(cc == 0)
/* The timeout has expired but we no packets arrived */
return (0);
- header = (dag_record_t*)p->adapter->DagBuffer;
+ header = (dag_record_t*)pw->adapter->DagBuffer;
}
else
header = (dag_record_t*)p->bp;
@@ -778,26 +832,17 @@ pcap_read_win32_dag(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
/* Send a packet to the network */
static int
-pcap_inject_win32(pcap_t *p, const void *buf, size_t size){
- LPPACKET PacketToSend;
-
- PacketToSend=PacketAllocatePacket();
-
- if (PacketToSend == NULL)
- {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send error: PacketAllocatePacket failed");
- return (-1);
- }
+pcap_inject_npf(pcap_t *p, const void *buf, size_t size)
+{
+ struct pcap_win *pw = p->priv;
+ PACKET pkt;
- PacketInitPacket(PacketToSend, (PVOID)buf, (UINT)size);
- if(PacketSendPacket(p->adapter,PacketToSend,TRUE) == FALSE){
+ PacketInitPacket(&pkt, (PVOID)buf, size);
+ if(PacketSendPacket(pw->adapter,&pkt,TRUE) == FALSE) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send error: PacketSendPacket failed");
- PacketFreePacket(PacketToSend);
return (-1);
}
- PacketFreePacket(PacketToSend);
-
/*
* We assume it all got sent if "PacketSendPacket()" succeeded.
* "pcap_inject()" is expected to return the number of bytes
@@ -807,12 +852,13 @@ pcap_inject_win32(pcap_t *p, const void *buf, size_t size){
}
static void
-pcap_cleanup_win32(pcap_t *p)
+pcap_cleanup_npf(pcap_t *p)
{
struct pcap_win *pw = p->priv;
- if (p->adapter != NULL) {
- PacketCloseAdapter(p->adapter);
- p->adapter = NULL;
+
+ if (pw->adapter != NULL) {
+ PacketCloseAdapter(pw->adapter);
+ pw->adapter = NULL;
}
if (pw->rfmon_selfstart)
{
@@ -822,73 +868,13 @@ pcap_cleanup_win32(pcap_t *p)
}
static int
-pcap_activate_win32(pcap_t *p)
+pcap_activate_npf(pcap_t *p)
{
struct pcap_win *pw = p->priv;
NetType type;
int res;
char errbuf[PCAP_ERRBUF_SIZE+1];
-#ifdef HAVE_REMOTE
- char host[PCAP_BUF_SIZE + 1];
- char port[PCAP_BUF_SIZE + 1];
- char name[PCAP_BUF_SIZE + 1];
- int srctype;
- int opensource_remote_result;
-
- struct pcap_md *md; /* structure used when doing a remote live capture */
- md = (struct pcap_md *) ((u_char*)p->priv + sizeof(struct pcap_win));
-
- /*
- Retrofit; we have to make older applications compatible with the remote capture
- So, we're calling the pcap_open_remote() from here, that is a very dirty thing.
- Obviously, we cannot exploit all the new features; for instance, we cannot
- send authentication, we cannot use a UDP data connection, and so on.
- */
- if (pcap_parsesrcstr(p->opt.device, &srctype, host, port, name, p->errbuf))
- return PCAP_ERROR;
-
- if (srctype == PCAP_SRC_IFREMOTE)
- {
- opensource_remote_result = pcap_opensource_remote(p, NULL);
-
- if (opensource_remote_result != 0)
- return opensource_remote_result;
-
- md->rmt_flags = (p->opt.promisc) ? PCAP_OPENFLAG_PROMISCUOUS : 0;
-
- return 0;
- }
-
- if (srctype == PCAP_SRC_IFLOCAL)
- {
- /*
- * If it starts with rpcap://, cut down the string
- */
- if (strncmp(p->opt.device, PCAP_SRC_IF_STRING, strlen(PCAP_SRC_IF_STRING)) == 0)
- {
- size_t len = strlen(p->opt.device) - strlen(PCAP_SRC_IF_STRING) + 1;
- char *new_string;
- /*
- * allocate a new string and free the old one
- */
- if (len > 0)
- {
- new_string = (char*)malloc(len);
- if (new_string != NULL)
- {
- char *tmp;
- strcpy_s(new_string, len, p->opt.device + strlen(PCAP_SRC_IF_STRING));
- tmp = p->opt.device;
- p->opt.device = new_string;
- free(tmp);
- }
- }
- }
- }
-
-#endif /* HAVE_REMOTE */
-
if (p->opt.rfmon) {
/*
* Monitor mode is supported on Windows Vista and later.
@@ -920,11 +906,11 @@ pcap_activate_win32(pcap_t *p)
}
/* Init WinSock */
- wsockinit();
+ pcap_wsockinit();
- p->adapter = PacketOpenAdapter(p->opt.device);
+ pw->adapter = PacketOpenAdapter(p->opt.device);
- if (p->adapter == NULL)
+ if (pw->adapter == NULL)
{
/* Adapter detected but we are not able to open it. Return failure. */
pcap_win32_err_to_str(GetLastError(), errbuf);
@@ -938,7 +924,7 @@ pcap_activate_win32(pcap_t *p)
}
/*get network type*/
- if(PacketGetNetType (p->adapter,&type) == FALSE)
+ if(PacketGetNetType (pw->adapter,&type) == FALSE)
{
pcap_win32_err_to_str(GetLastError(), errbuf);
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
@@ -1025,11 +1011,22 @@ pcap_activate_win32(pcap_t *p)
break;
}
+ /*
+ * Turn a negative snapshot value (invalid), a snapshot value of
+ * 0 (unspecified), or a value bigger than the normal maximum
+ * value, into the maximum allowed value.
+ *
+ * If some application really *needs* a bigger snapshot
+ * length, we should just increase MAXIMUM_SNAPLEN.
+ */
+ if (p->snapshot <= 0 || p->snapshot > MAXIMUM_SNAPLEN)
+ p->snapshot = MAXIMUM_SNAPLEN;
+
/* Set promiscuous mode */
if (p->opt.promisc)
{
- if (PacketSetHwFilter(p->adapter,NDIS_PACKET_TYPE_PROMISCUOUS) == FALSE)
+ if (PacketSetHwFilter(pw->adapter,NDIS_PACKET_TYPE_PROMISCUOUS) == FALSE)
{
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "failed to set hardware filter to promiscuous mode");
goto bad;
@@ -1037,7 +1034,17 @@ pcap_activate_win32(pcap_t *p)
}
else
{
- if (PacketSetHwFilter(p->adapter,NDIS_PACKET_TYPE_ALL_LOCAL) == FALSE)
+ /* NDIS_PACKET_TYPE_ALL_LOCAL selects "All packets sent by installed
+ * protocols and all packets indicated by the NIC" but if no protocol
+ * drivers (like TCP/IP) are installed, NDIS_PACKET_TYPE_DIRECTED,
+ * NDIS_PACKET_TYPE_BROADCAST, and NDIS_PACKET_TYPE_MULTICAST are needed to
+ * capture incoming frames.
+ */
+ if (PacketSetHwFilter(pw->adapter,
+ NDIS_PACKET_TYPE_ALL_LOCAL |
+ NDIS_PACKET_TYPE_DIRECTED |
+ NDIS_PACKET_TYPE_BROADCAST |
+ NDIS_PACKET_TYPE_MULTICAST) == FALSE)
{
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "failed to set hardware filter to non-promiscuous mode");
goto bad;
@@ -1047,7 +1054,7 @@ pcap_activate_win32(pcap_t *p)
/* Set the buffer size */
p->bufsize = WIN32_DEFAULT_USER_BUFFER_SIZE;
- if(!(p->adapter->Flags & INFO_FLAG_DAG_CARD))
+ if(!(pw->adapter->Flags & INFO_FLAG_DAG_CARD))
{
/*
* Traditional Adapter
@@ -1059,7 +1066,7 @@ pcap_activate_win32(pcap_t *p)
if (p->opt.buffer_size == 0)
p->opt.buffer_size = WIN32_DEFAULT_KERNEL_BUFFER_SIZE;
- if(PacketSetBuff(p->adapter,p->opt.buffer_size)==FALSE)
+ if(PacketSetBuff(pw->adapter,p->opt.buffer_size)==FALSE)
{
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: not enough memory to allocate the kernel buffer");
goto bad;
@@ -1068,14 +1075,15 @@ pcap_activate_win32(pcap_t *p)
p->buffer = malloc(p->bufsize);
if (p->buffer == NULL)
{
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "malloc");
goto bad;
}
if (p->opt.immediate)
{
/* tell the driver to copy the buffer as soon as data arrives */
- if(PacketSetMinToCopy(p->adapter,0)==FALSE)
+ if(PacketSetMinToCopy(pw->adapter,0)==FALSE)
{
pcap_win32_err_to_str(GetLastError(), errbuf);
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
@@ -1087,7 +1095,7 @@ pcap_activate_win32(pcap_t *p)
else
{
/* tell the driver to copy the buffer only if it contains at least 16K */
- if(PacketSetMinToCopy(p->adapter,16000)==FALSE)
+ if(PacketSetMinToCopy(pw->adapter,16000)==FALSE)
{
pcap_win32_err_to_str(GetLastError(), errbuf);
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
@@ -1096,13 +1104,14 @@ pcap_activate_win32(pcap_t *p)
goto bad;
}
}
- }
- else
+ } else {
+ /*
+ * Dag Card
+ */
#ifdef HAVE_DAG_API
- {
- /*
- * Dag Card
- */
+ /*
+ * We have DAG support.
+ */
LONG status;
HKEY dagkey;
DWORD lptype;
@@ -1136,20 +1145,34 @@ pcap_activate_win32(pcap_t *p)
while(FALSE);
- p->snapshot = PacketSetSnapLen(p->adapter, snaplen);
+ p->snapshot = PacketSetSnapLen(pw->adapter, p->snapshot);
/* Set the length of the FCS associated to any packet. This value
* will be subtracted to the packet length */
- pw->dag_fcs_bits = p->adapter->DagFcsLen;
- }
-#else
- goto bad;
+ pw->dag_fcs_bits = pw->adapter->DagFcsLen;
+#else /* HAVE_DAG_API */
+ /*
+ * No DAG support.
+ */
+ goto bad;
#endif /* HAVE_DAG_API */
+ }
- PacketSetReadTimeout(p->adapter, p->opt.timeout);
+ PacketSetReadTimeout(pw->adapter, p->opt.timeout);
+
+ /* disable loopback capture if requested */
+ if (p->opt.nocapture_local)
+ {
+ if (!PacketSetLoopbackBehavior(pw->adapter, NPF_DISABLE_LOOPBACK))
+ {
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "Unable to disable the capture of loopback packets.");
+ goto bad;
+ }
+ }
#ifdef HAVE_DAG_API
- if(p->adapter->Flags & INFO_FLAG_DAG_CARD)
+ if(pw->adapter->Flags & INFO_FLAG_DAG_CARD)
{
/* install dag specific handlers for read and setfilter */
p->read_op = pcap_read_win32_dag;
@@ -1159,35 +1182,48 @@ pcap_activate_win32(pcap_t *p)
{
#endif /* HAVE_DAG_API */
/* install traditional npf handlers for read and setfilter */
- p->read_op = pcap_read_win32_npf;
- p->setfilter_op = pcap_setfilter_win32_npf;
+ p->read_op = pcap_read_npf;
+ p->setfilter_op = pcap_setfilter_npf;
#ifdef HAVE_DAG_API
}
#endif /* HAVE_DAG_API */
p->setdirection_op = NULL; /* Not implemented. */
/* XXX - can this be implemented on some versions of Windows? */
- p->inject_op = pcap_inject_win32;
+ p->inject_op = pcap_inject_npf;
p->set_datalink_op = NULL; /* can't change data link type */
- p->getnonblock_op = pcap_getnonblock_win32;
- p->setnonblock_op = pcap_setnonblock_win32;
- p->stats_op = pcap_stats_win32;
- p->stats_ex_op = pcap_stats_ex_win32;
- p->setbuff_op = pcap_setbuff_win32;
- p->setmode_op = pcap_setmode_win32;
- p->setmintocopy_op = pcap_setmintocopy_win32;
- p->getevent_op = pcap_getevent_win32;
- p->oid_get_request_op = pcap_oid_get_request_win32;
- p->oid_set_request_op = pcap_oid_set_request_win32;
- p->sendqueue_transmit_op = pcap_sendqueue_transmit_win32;
- p->setuserbuffer_op = pcap_setuserbuffer_win32;
- p->live_dump_op = pcap_live_dump_win32;
- p->live_dump_ended_op = pcap_live_dump_ended_win32;
- p->get_airpcap_handle_op = pcap_get_airpcap_handle_win32;
- p->cleanup_op = pcap_cleanup_win32;
+ p->getnonblock_op = pcap_getnonblock_npf;
+ p->setnonblock_op = pcap_setnonblock_npf;
+ p->stats_op = pcap_stats_npf;
+ p->stats_ex_op = pcap_stats_ex_npf;
+ p->setbuff_op = pcap_setbuff_npf;
+ p->setmode_op = pcap_setmode_npf;
+ p->setmintocopy_op = pcap_setmintocopy_npf;
+ p->getevent_op = pcap_getevent_npf;
+ p->oid_get_request_op = pcap_oid_get_request_npf;
+ p->oid_set_request_op = pcap_oid_set_request_npf;
+ p->sendqueue_transmit_op = pcap_sendqueue_transmit_npf;
+ p->setuserbuffer_op = pcap_setuserbuffer_npf;
+ p->live_dump_op = pcap_live_dump_npf;
+ p->live_dump_ended_op = pcap_live_dump_ended_npf;
+ p->get_airpcap_handle_op = pcap_get_airpcap_handle_npf;
+ p->cleanup_op = pcap_cleanup_npf;
+
+ /*
+ * XXX - this is only done because WinPcap supported
+ * pcap_fileno() returning the hFile HANDLE from the
+ * ADAPTER structure. We make no general guarantees
+ * that the caller can do anything useful with it.
+ *
+ * (Not that we make any general guarantee of that
+ * sort on UN*X, either, any more, given that not
+ * all capture devices are regular OS network
+ * interfaces.)
+ */
+ p->handle = pw->adapter->hFile;
return (0);
bad:
- pcap_cleanup_win32(p);
+ pcap_cleanup_npf(p);
return (PCAP_ERROR);
}
@@ -1195,7 +1231,7 @@ bad:
* Check if rfmon mode is supported on the pcap_t for Windows systems.
*/
static int
-pcap_can_set_rfmon_win32(pcap_t *p)
+pcap_can_set_rfmon_npf(pcap_t *p)
{
return (PacketIsMonitorModeSupported(p->opt.device) == 1);
}
@@ -1205,25 +1241,21 @@ pcap_create_interface(const char *device _U_, char *ebuf)
{
pcap_t *p;
-#ifdef HAVE_REMOTE
- p = pcap_create_common(ebuf, sizeof(struct pcap_win) + sizeof(struct pcap_md));
-#else
p = pcap_create_common(ebuf, sizeof(struct pcap_win));
-#endif /* HAVE_REMOTE */
if (p == NULL)
return (NULL);
- p->activate_op = pcap_activate_win32;
- p->can_set_rfmon_op = pcap_can_set_rfmon_win32;
+ p->activate_op = pcap_activate_npf;
+ p->can_set_rfmon_op = pcap_can_set_rfmon_npf;
return (p);
}
static int
-pcap_setfilter_win32_npf(pcap_t *p, struct bpf_program *fp)
+pcap_setfilter_npf(pcap_t *p, struct bpf_program *fp)
{
struct pcap_win *pw = p->priv;
- if(PacketSetBpf(p->adapter,fp)==FALSE){
+ if(PacketSetBpf(pw->adapter,fp)==FALSE){
/*
* Kernel filter not installed.
*
@@ -1290,17 +1322,13 @@ pcap_setfilter_win32_dag(pcap_t *p, struct bpf_program *fp) {
/* Install a user level filter */
if (install_bpf_program(p, fp) < 0)
- {
- pcap_snprintf(p->errbuf, sizeof(p->errbuf),
- "setfilter, unable to install the filter: %s", pcap_strerror(errno));
return (-1);
- }
return (0);
}
static int
-pcap_getnonblock_win32(pcap_t *p, char *errbuf)
+pcap_getnonblock_npf(pcap_t *p)
{
struct pcap_win *pw = p->priv;
@@ -1313,7 +1341,7 @@ pcap_getnonblock_win32(pcap_t *p, char *errbuf)
}
static int
-pcap_setnonblock_win32(pcap_t *p, int nonblock, char *errbuf)
+pcap_setnonblock_npf(pcap_t *p, int nonblock)
{
struct pcap_win *pw = p->priv;
int newtimeout;
@@ -1321,7 +1349,8 @@ pcap_setnonblock_win32(pcap_t *p, int nonblock, char *errbuf)
if (nonblock) {
/*
- * Set the read timeout to -1 for non-blocking mode.
+ * Set the packet buffer timeout to -1 for non-blocking
+ * mode.
*/
newtimeout = -1;
} else {
@@ -1335,9 +1364,9 @@ pcap_setnonblock_win32(pcap_t *p, int nonblock, char *errbuf)
*/
newtimeout = p->opt.timeout;
}
- if (!PacketSetReadTimeout(p->adapter, newtimeout)) {
+ if (!PacketSetReadTimeout(pw->adapter, newtimeout)) {
pcap_win32_err_to_str(GetLastError(), win_errbuf);
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"PacketSetReadTimeout: %s", win_errbuf);
return (-1);
}
@@ -1346,7 +1375,7 @@ pcap_setnonblock_win32(pcap_t *p, int nonblock, char *errbuf)
}
static int
-pcap_add_if_win32(pcap_if_t **devlist, char *name, bpf_u_int32 flags,
+pcap_add_if_npf(pcap_if_list_t *devlistp, char *name, bpf_u_int32 flags,
const char *description, char *errbuf)
{
pcap_if_t *curdev;
@@ -1359,8 +1388,8 @@ pcap_add_if_win32(pcap_if_t **devlist, char *name, bpf_u_int32 flags,
/*
* Add an entry for this interface, with no addresses.
*/
- if (add_or_find_if(&curdev, devlist, name, flags, description,
- errbuf) == -1) {
+ curdev = add_dev(devlistp, name, flags, description, errbuf);
+ if (curdev == NULL) {
/*
* Failure.
*/
@@ -1391,8 +1420,6 @@ pcap_add_if_win32(pcap_if_t **devlist, char *name, bpf_u_int32 flags,
* "curdev" is an entry for this interface; add an entry for
* this address to its list of addresses.
*/
- if(curdev == NULL)
- break;
res = add_addr_to_dev(curdev,
(struct sockaddr *)&if_addrs[if_addr_size].IPAddress,
sizeof (struct sockaddr_storage),
@@ -1414,10 +1441,244 @@ pcap_add_if_win32(pcap_if_t **devlist, char *name, bpf_u_int32 flags,
return (res);
}
+static int
+get_if_flags(const char *name, bpf_u_int32 *flags, char *errbuf)
+{
+ char *name_copy;
+ ADAPTER *adapter;
+ int status;
+ size_t len;
+ NDIS_HARDWARE_STATUS hardware_status;
+#ifdef OID_GEN_PHYSICAL_MEDIUM
+ NDIS_PHYSICAL_MEDIUM phys_medium;
+ bpf_u_int32 gen_physical_medium_oids[] = {
+ #ifdef OID_GEN_PHYSICAL_MEDIUM_EX
+ OID_GEN_PHYSICAL_MEDIUM_EX,
+ #endif
+ OID_GEN_PHYSICAL_MEDIUM
+ };
+#define N_GEN_PHYSICAL_MEDIUM_OIDS (sizeof gen_physical_medium_oids / sizeof gen_physical_medium_oids[0])
+ size_t i;
+#endif /* OID_GEN_PHYSICAL_MEDIUM */
+#ifdef OID_GEN_LINK_STATE
+ NDIS_LINK_STATE link_state;
+#endif
+ int connect_status;
+
+ if (*flags & PCAP_IF_LOOPBACK) {
+ /*
+ * Loopback interface, so the connection status doesn't
+ * apply. and it's not wireless (or wired, for that
+ * matter...). We presume it's up and running.
+ */
+ *flags |= PCAP_IF_UP | PCAP_IF_RUNNING | PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE;
+ return (0);
+ }
+
+ /*
+ * We need to open the adapter to get this information.
+ *
+ * XXX - PacketOpenAdapter() takes a non-const pointer
+ * as an argument, so we make a copy of the argument and
+ * pass that to it.
+ */
+ name_copy = strdup(name);
+ adapter = PacketOpenAdapter(name_copy);
+ free(name_copy);
+ if (adapter == NULL) {
+ /*
+ * Give up; if they try to open this device, it'll fail.
+ */
+ return (0);
+ }
+
+#ifdef HAVE_AIRPCAP_API
+ /*
+ * Airpcap.sys do not support the below 'OID_GEN_x' values.
+ * Just set these flags (and none of the '*flags' entered with).
+ */
+ if (PacketGetAirPcapHandle(adapter)) {
+ /*
+ * Must be "up" and "running" if the above if succeeded.
+ */
+ *flags = PCAP_IF_UP | PCAP_IF_RUNNING;
+
+ /*
+ * An airpcap device is a wireless device (duh!)
+ */
+ *flags |= PCAP_IF_WIRELESS;
+
+ /*
+ * A "network assosiation state" makes no sense for airpcap.
+ */
+ *flags |= PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE;
+ PacketCloseAdapter(adapter);
+ return (0);
+ }
+#endif
+
+ /*
+ * Get the hardware status, and derive "up" and "running" from
+ * that.
+ */
+ len = sizeof (hardware_status);
+ status = oid_get_request(adapter, OID_GEN_HARDWARE_STATUS,
+ &hardware_status, &len, errbuf);
+ if (status == 0) {
+ switch (hardware_status) {
+
+ case NdisHardwareStatusReady:
+ /*
+ * "Available and capable of sending and receiving
+ * data over the wire", so up and running.
+ */
+ *flags |= PCAP_IF_UP | PCAP_IF_RUNNING;
+ break;
+
+ case NdisHardwareStatusInitializing:
+ case NdisHardwareStatusReset:
+ /*
+ * "Initializing" or "Resetting", so up, but
+ * not running.
+ */
+ *flags |= PCAP_IF_UP;
+ break;
+
+ case NdisHardwareStatusClosing:
+ case NdisHardwareStatusNotReady:
+ /*
+ * "Closing" or "Not ready", so neither up nor
+ * running.
+ */
+ break;
+ }
+ } else {
+ /*
+ * Can't get the hardware status, so assume both up and
+ * running.
+ */
+ *flags |= PCAP_IF_UP | PCAP_IF_RUNNING;
+ }
+
+ /*
+ * Get the network type.
+ */
+#ifdef OID_GEN_PHYSICAL_MEDIUM
+ /*
+ * Try the OIDs we have for this, in order.
+ */
+ for (i = 0; i < N_GEN_PHYSICAL_MEDIUM_OIDS; i++) {
+ len = sizeof (phys_medium);
+ status = oid_get_request(adapter, gen_physical_medium_oids[i],
+ &phys_medium, &len, errbuf);
+ if (status == 0) {
+ /*
+ * Success.
+ */
+ break;
+ }
+ /*
+ * Failed. We can't determine whether it failed
+ * because that particular OID isn't supported
+ * or because some other problem occurred, so we
+ * just drive on and try the next OID.
+ */
+ }
+ if (status == 0) {
+ /*
+ * We got the physical medium.
+ */
+ switch (phys_medium) {
+
+ case NdisPhysicalMediumWirelessLan:
+ case NdisPhysicalMediumWirelessWan:
+ case NdisPhysicalMediumNative802_11:
+ case NdisPhysicalMediumBluetooth:
+ case NdisPhysicalMediumUWB:
+ case NdisPhysicalMediumIrda:
+ /*
+ * Wireless.
+ */
+ *flags |= PCAP_IF_WIRELESS;
+ break;
+
+ default:
+ /*
+ * Not wireless.
+ */
+ break;
+ }
+ }
+#endif
+
+ /*
+ * Get the connection status.
+ */
+#ifdef OID_GEN_LINK_STATE
+ len = sizeof(link_state);
+ status = oid_get_request(adapter, OID_GEN_LINK_STATE, &link_state,
+ &len, errbuf);
+ if (status == 0) {
+ /*
+ * NOTE: this also gives us the receive and transmit
+ * link state.
+ */
+ switch (link_state.MediaConnectState) {
+
+ case MediaConnectStateConnected:
+ /*
+ * It's connected.
+ */
+ *flags |= PCAP_IF_CONNECTION_STATUS_CONNECTED;
+ break;
+
+ case MediaConnectStateDisconnected:
+ /*
+ * It's disconnected.
+ */
+ *flags |= PCAP_IF_CONNECTION_STATUS_DISCONNECTED;
+ break;
+ }
+ }
+#else
+ /*
+ * OID_GEN_LINK_STATE isn't supported because it's not in our SDK.
+ */
+ status = -1;
+#endif
+ if (status == -1) {
+ /*
+ * OK, OID_GEN_LINK_STATE didn't work, try
+ * OID_GEN_MEDIA_CONNECT_STATUS.
+ */
+ status = oid_get_request(adapter, OID_GEN_MEDIA_CONNECT_STATUS,
+ &connect_status, &len, errbuf);
+ if (status == 0) {
+ switch (connect_status) {
+
+ case NdisMediaStateConnected:
+ /*
+ * It's connected.
+ */
+ *flags |= PCAP_IF_CONNECTION_STATUS_CONNECTED;
+ break;
+
+ case NdisMediaStateDisconnected:
+ /*
+ * It's disconnected.
+ */
+ *flags |= PCAP_IF_CONNECTION_STATUS_DISCONNECTED;
+ break;
+ }
+ }
+ }
+ PacketCloseAdapter(adapter);
+ return (0);
+}
+
int
-pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
+pcap_platform_finddevs(pcap_if_list_t *devlistp, char *errbuf)
{
- pcap_if_t *devlist = NULL;
int ret = 0;
const char *desc;
char *AdaptersName;
@@ -1456,13 +1717,9 @@ pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
}
}
- if (NameLength > 0)
- AdaptersName = (char*) malloc(NameLength);
- else
- {
- *alldevsp = NULL;
+ if (NameLength <= 0)
return 0;
- }
+ AdaptersName = (char*) malloc(NameLength);
if (AdaptersName == NULL)
{
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Cannot allocate enough memory to list the adapters.");
@@ -1516,11 +1773,21 @@ pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
flags |= PCAP_IF_LOOPBACK;
}
#endif
+ /*
+ * Get additional flags.
+ */
+ if (get_if_flags(name, &flags, errbuf) == -1) {
+ /*
+ * Failure.
+ */
+ ret = -1;
+ break;
+ }
/*
* Add an entry for this interface.
*/
- if (pcap_add_if_win32(&devlist, name, flags, desc,
+ if (pcap_add_if_npf(devlistp, name, flags, desc,
errbuf) == -1) {
/*
* Failure.
@@ -1532,17 +1799,300 @@ pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
desc += strlen(desc) + 1;
}
- if (ret == -1) {
+ free(AdaptersName);
+ return (ret);
+}
+
+/*
+ * Return the name of a network interface attached to the system, or NULL
+ * if none can be found. The interface must be configured up; the
+ * lowest unit number is preferred; loopback is ignored.
+ *
+ * In the best of all possible worlds, this would be the same as on
+ * UN*X, but there may be software that expects this to return a
+ * full list of devices after the first device.
+ */
+#define ADAPTERSNAME_LEN 8192
+char *
+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 */
+ dwVersion = GetVersion(); /* get the OS version */
+#pragma warning (pop)
+ dwWindowsMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
+
+ if (dwVersion >= 0x80000000 && dwWindowsMajorVersion >= 4) {
+ /*
+ * Windows 95, 98, ME.
+ */
+ ULONG NameLength = ADAPTERSNAME_LEN;
+ static char AdaptersName[ADAPTERSNAME_LEN];
+
+ if (PacketGetAdapterNames(AdaptersName,&NameLength) )
+ return (AdaptersName);
+ else
+ return NULL;
+ } else {
+ /*
+ * Windows NT (NT 4.0 and later).
+ * Convert the names to Unicode for backward compatibility.
+ */
+ ULONG NameLength = ADAPTERSNAME_LEN;
+ static WCHAR AdaptersName[ADAPTERSNAME_LEN];
+ size_t BufferSpaceLeft;
+ char *tAstr;
+ WCHAR *Unameptr;
+ char *Adescptr;
+ size_t namelen, i;
+ WCHAR *TAdaptersName = (WCHAR*)malloc(ADAPTERSNAME_LEN * sizeof(WCHAR));
+ int NAdapts = 0;
+
+ if(TAdaptersName == NULL)
+ {
+ (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "memory allocation failure");
+ return NULL;
+ }
+
+ if ( !PacketGetAdapterNames((PTSTR)TAdaptersName,&NameLength) )
+ {
+ pcap_win32_err_to_str(GetLastError(), our_errbuf);
+ (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "PacketGetAdapterNames: %s", our_errbuf);
+ free(TAdaptersName);
+ return NULL;
+ }
+
+
+ BufferSpaceLeft = ADAPTERSNAME_LEN * sizeof(WCHAR);
+ tAstr = (char*)TAdaptersName;
+ Unameptr = AdaptersName;
+
+ /*
+ * Convert the device names to Unicode into AdapterName.
+ */
+ do {
+ /*
+ * Length of the name, including the terminating
+ * NUL.
+ */
+ namelen = strlen(tAstr) + 1;
+
+ /*
+ * Do we have room for the name in the Unicode
+ * buffer?
+ */
+ if (BufferSpaceLeft < namelen * sizeof(WCHAR)) {
+ /*
+ * No.
+ */
+ goto quit;
+ }
+ BufferSpaceLeft -= namelen * sizeof(WCHAR);
+
+ /*
+ * Copy the name, converting ASCII to Unicode.
+ * namelen includes the NUL, so we copy it as
+ * well.
+ */
+ for (i = 0; i < namelen; i++)
+ *Unameptr++ = *tAstr++;
+
+ /*
+ * Count this adapter.
+ */
+ NAdapts++;
+ } while (namelen != 1);
+
+ /*
+ * Copy the descriptions, but don't convert them from
+ * ASCII to Unicode.
+ */
+ Adescptr = (char *)Unameptr;
+ while(NAdapts--)
+ {
+ size_t desclen;
+
+ desclen = strlen(tAstr) + 1;
+
+ /*
+ * Do we have room for the name in the Unicode
+ * buffer?
+ */
+ if (BufferSpaceLeft < desclen) {
+ /*
+ * No.
+ */
+ goto quit;
+ }
+
+ /*
+ * Just copy the ASCII string.
+ * namelen includes the NUL, so we copy it as
+ * well.
+ */
+ memcpy(Adescptr, tAstr, desclen);
+ Adescptr += desclen;
+ tAstr += desclen;
+ BufferSpaceLeft -= desclen;
+ }
+
+ quit:
+ free(TAdaptersName);
+ return (char *)(AdaptersName);
+ }
+}
+
+/*
+ * We can't use the same code that we use on UN*X, as that's doing
+ * UN*X-specific calls.
+ *
+ * We don't just fetch the entire list of devices, search for the
+ * particular device, and use its first IPv4 address, as that's too
+ * much work to get just one device's netmask.
+ */
+int
+pcap_lookupnet(const char *device, bpf_u_int32 *netp, bpf_u_int32 *maskp,
+ char *errbuf)
+{
+ /*
+ * We need only the first IPv4 address, so we must scan the array returned by PacketGetNetInfo()
+ * in order to skip non IPv4 (i.e. IPv6 addresses)
+ */
+ npf_if_addr if_addrs[MAX_NETWORK_ADDRESSES];
+ LONG if_addr_size = MAX_NETWORK_ADDRESSES;
+ struct sockaddr_in *t_addr;
+ LONG i;
+
+ if (!PacketGetNetInfoEx((void *)device, if_addrs, &if_addr_size)) {
+ *netp = *maskp = 0;
+ return (0);
+ }
+
+ for(i = 0; i < if_addr_size; i++)
+ {
+ if(if_addrs[i].IPAddress.ss_family == AF_INET)
+ {
+ t_addr = (struct sockaddr_in *) &(if_addrs[i].IPAddress);
+ *netp = t_addr->sin_addr.S_un.S_addr;
+ t_addr = (struct sockaddr_in *) &(if_addrs[i].SubnetMask);
+ *maskp = t_addr->sin_addr.S_un.S_addr;
+
+ *netp &= *maskp;
+ return (0);
+ }
+
+ }
+
+ *netp = *maskp = 0;
+ return (0);
+}
+
+static const char *pcap_lib_version_string;
+
+#ifdef HAVE_VERSION_H
+/*
+ * libpcap being built for Windows, as part of a WinPcap/Npcap source
+ * 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.)
+ */
+#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) {
/*
- * We had an error; free the list we've been constructing.
+ * Generate the version string.
*/
- if (devlist != NULL) {
- pcap_freealldevs(devlist);
- devlist = NULL;
+ 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
+ * version.
+ */
+ pcap_lib_version_string = pcap_version_string;
+ } else {
+ /*
+ * WinPcap 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
+ * 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);
}
+ pcap_lib_version_string = full_pcap_version_string;
}
+ return (pcap_lib_version_string);
+}
- *alldevsp = devlist;
- free(AdaptersName);
- return (ret);
+#else /* HAVE_VERSION_H */
+
+/*
+ * 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;
+ }
+ return (pcap_lib_version_string);
}
+#endif /* HAVE_VERSION_H */
diff --git a/contrib/libpcap/pcap-null.c b/contrib/libpcap/pcap-null.c
index b5fa3ab91fabf..92a5e2d8649b6 100644
--- a/contrib/libpcap/pcap-null.c
+++ b/contrib/libpcap/pcap-null.c
@@ -20,17 +20,11 @@
*/
#ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
#endif
-#include <sys/param.h> /* optionally get BSD define */
-
#include <string.h>
-#ifdef HAVE_OS_PROTO_H
-#include "os-proto.h"
-#endif
-
#include "pcap-int.h"
static char nosup[] = "live packet capture not supported on this system";
@@ -43,11 +37,29 @@ pcap_create_interface(const char *device _U_, char *ebuf)
}
int
-pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
+pcap_platform_finddevs(pcap_if_list_t *devlistp, char *errbuf)
{
/*
* There are no interfaces on which we can capture.
*/
- *alldevsp = NULL;
return (0);
}
+
+#ifdef _WIN32
+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);
+ return (-1);
+}
+#endif
+
+/*
+ * Libpcap version string.
+ */
+const char *
+pcap_lib_version(void)
+{
+ return (PCAP_VERSION_STRING);
+}
diff --git a/contrib/libpcap/pcap-pf.c b/contrib/libpcap/pcap-pf.c
index 73469086d8a46..fde97bacd05ec 100644
--- a/contrib/libpcap/pcap-pf.c
+++ b/contrib/libpcap/pcap-pf.c
@@ -23,7 +23,7 @@
*/
#ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
#endif
#include <sys/types.h>
@@ -127,8 +127,8 @@ pcap_read_pf(pcap_t *pc, int cnt, pcap_handler callback, u_char *user)
(void)lseek(pc->fd, 0L, SEEK_SET);
goto again;
}
- pcap_snprintf(pc->errbuf, sizeof(pc->errbuf), "pf read: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(pc->errbuf,
+ sizeof(pc->errbuf), errno, "pf read");
return (-1);
}
bp = (u_char *)pc->buffer + pc->offset;
@@ -232,8 +232,8 @@ pcap_inject_pf(pcap_t *p, const void *buf, size_t size)
ret = write(p->fd, buf, size);
if (ret == -1) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "send");
return (-1);
}
return (ret);
@@ -302,6 +302,7 @@ pcap_activate_pf(pcap_t *p)
int backlog = -1; /* request the most */
struct enfilter Filter;
struct endevp devparams;
+ int err;
/*
* Initially try a read/write open (to allow the inject
@@ -329,11 +330,31 @@ pcap_activate_pf(pcap_t *p)
if (p->fd == -1 && errno == EACCES)
p->fd = pfopen(p->opt.device, O_RDONLY);
if (p->fd < 0) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "pf open: %s: %s\n\
-your system may not be properly configured; see the packetfilter(4) man page\n",
- p->opt.device, pcap_strerror(errno));
+ if (errno == EACCES) {
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "pf open: %s: Permission denied\n"
+"your system may not be properly configured; see the packetfilter(4) man page",
+ p->opt.device);
+ err = PCAP_ERROR_PERM_DENIED;
+ } else {
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "pf open: %s", p->opt.device);
+ err = PCAP_ERROR;
+ }
goto bad;
}
+
+ /*
+ * Turn a negative snapshot value (invalid), a snapshot value of
+ * 0 (unspecified), or a value bigger than the normal maximum
+ * value, into the maximum allowed value.
+ *
+ * If some application really *needs* a bigger snapshot
+ * length, we should just increase MAXIMUM_SNAPLEN.
+ */
+ if (p->snapshot <= 0 || p->snapshot > MAXIMUM_SNAPLEN)
+ p->snapshot = MAXIMUM_SNAPLEN;
+
pf->OrigMissed = -1;
enmode = ENTSTAMP|ENNONEXCL;
if (!p->opt.immediate)
@@ -341,8 +362,9 @@ your system may not be properly configured; see the packetfilter(4) man page\n",
if (p->opt.promisc)
enmode |= ENPROMISC;
if (ioctl(p->fd, EIOCMBIS, (caddr_t)&enmode) < 0) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCMBIS: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "EIOCMBIS");
+ err = PCAP_ERROR;
goto bad;
}
#ifdef ENCOPYALL
@@ -352,14 +374,16 @@ your system may not be properly configured; see the packetfilter(4) man page\n",
#endif
/* set the backlog */
if (ioctl(p->fd, EIOCSETW, (caddr_t)&backlog) < 0) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCSETW: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "EIOCSETW");
+ err = PCAP_ERROR;
goto bad;
}
/* discover interface type */
if (ioctl(p->fd, EIOCDEVP, (caddr_t)&devparams) < 0) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCDEVP: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "EIOCDEVP");
+ err = PCAP_ERROR;
goto bad;
}
/* HACK: to compile prior to Ultrix 4.2 */
@@ -442,6 +466,7 @@ your system may not be properly configured; see the packetfilter(4) man page\n",
*/
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"unknown data-link type %u", devparams.end_dev_type);
+ err = PCAP_ERROR;
goto bad;
}
/* set truncation */
@@ -453,8 +478,9 @@ your system may not be properly configured; see the packetfilter(4) man page\n",
} else
p->fddipad = 0;
if (ioctl(p->fd, EIOCTRUNCATE, (caddr_t)&p->snapshot) < 0) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCTRUNCATE: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "EIOCTRUNCATE");
+ err = PCAP_ERROR;
goto bad;
}
/* accept all packets */
@@ -462,8 +488,9 @@ your system may not be properly configured; see the packetfilter(4) man page\n",
Filter.enf_Priority = 37; /* anything > 2 */
Filter.enf_FilterLen = 0; /* means "always true" */
if (ioctl(p->fd, EIOCSETF, (caddr_t)&Filter) < 0) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCSETF: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "EIOCSETF");
+ err = PCAP_ERROR;
goto bad;
}
@@ -472,8 +499,9 @@ your system may not be properly configured; see the packetfilter(4) man page\n",
timeout.tv_sec = p->opt.timeout / 1000;
timeout.tv_usec = (p->opt.timeout * 1000) % 1000000;
if (ioctl(p->fd, EIOCSRTIMEOUT, (caddr_t)&timeout) < 0) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCSRTIMEOUT: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "EIOCSRTIMEOUT");
+ err = PCAP_ERROR;
goto bad;
}
}
@@ -481,7 +509,9 @@ your system may not be properly configured; see the packetfilter(4) man page\n",
p->bufsize = BUFSPACE;
p->buffer = malloc(p->bufsize + p->offset);
if (p->buffer == NULL) {
- strlcpy(p->errbuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "malloc");
+ err = PCAP_ERROR;
goto bad;
}
@@ -502,7 +532,7 @@ your system may not be properly configured; see the packetfilter(4) man page\n",
return (0);
bad:
pcap_cleanup_live_common(p);
- return (PCAP_ERROR);
+ return (err);
}
pcap_t *
@@ -528,10 +558,32 @@ can_be_bound(const char *name _U_)
return (1);
}
+static int
+get_if_flags(const char *name _U_, bpf_u_int32 *flags _U_, char *errbuf _U_)
+{
+ /*
+ * Nothing we can do other than mark loopback devices as "the
+ * connected/disconnected status doesn't apply".
+ *
+ * XXX - is there a way to find out whether an adapter has
+ * something plugged into it?
+ */
+ if (*flags & PCAP_IF_LOOPBACK) {
+ /*
+ * Loopback devices aren't wireless, and "connected"/
+ * "disconnected" doesn't apply to them.
+ */
+ *flags |= PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE;
+ return (0);
+ }
+ return (0);
+}
+
int
-pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
+pcap_platform_finddevs(pcap_if_list_t *devlistp, char *errbuf)
{
- return (pcap_findalldevs_interfaces(alldevsp, errbuf, can_be_bound));
+ return (pcap_findalldevs_interfaces(devlistp, errbuf, can_be_bound,
+ get_if_flags));
}
static int
@@ -560,8 +612,8 @@ pcap_setfilter_pf(pcap_t *p, struct bpf_program *fp)
* Yes. Try to install the filter.
*/
if (ioctl(p->fd, BIOCSETF, (caddr_t)fp) < 0) {
- pcap_snprintf(p->errbuf, sizeof(p->errbuf),
- "BIOCSETF: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf,
+ sizeof(p->errbuf), errno, "BIOCSETF");
return (-1);
}
@@ -620,3 +672,12 @@ pcap_setfilter_pf(pcap_t *p, struct bpf_program *fp)
pf->filtering_in_kernel = 0;
return (0);
}
+
+/*
+ * Libpcap version string.
+ */
+const char *
+pcap_lib_version(void)
+{
+ return (PCAP_VERSION_STRING);
+}
diff --git a/contrib/libpcap/pcap-rdmasniff.c b/contrib/libpcap/pcap-rdmasniff.c
new file mode 100644
index 0000000000000..c50fe3fd693f0
--- /dev/null
+++ b/contrib/libpcap/pcap-rdmasniff.c
@@ -0,0 +1,436 @@
+/*
+ * Copyright (c) 2017 Pure Storage, Inc.
+ * 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. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcap-int.h"
+#include "pcap-rdmasniff.h"
+
+#include <infiniband/verbs.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+
+#if !defined(IBV_FLOW_ATTR_SNIFFER)
+#define IBV_FLOW_ATTR_SNIFFER 3
+#endif
+
+static const int RDMASNIFF_NUM_RECEIVES = 128;
+static const int RDMASNIFF_RECEIVE_SIZE = 10000;
+
+struct pcap_rdmasniff {
+ struct ibv_device * rdma_device;
+ struct ibv_context * context;
+ struct ibv_comp_channel * channel;
+ struct ibv_pd * pd;
+ struct ibv_cq * cq;
+ struct ibv_qp * qp;
+ struct ibv_flow * flow;
+ struct ibv_mr * mr;
+ u_char * oneshot_buffer;
+ unsigned port_num;
+ int cq_event;
+ u_int packets_recv;
+};
+
+static int
+rdmasniff_stats(pcap_t *handle, struct pcap_stat *stat)
+{
+ struct pcap_rdmasniff *priv = handle->priv;
+
+ stat->ps_recv = priv->packets_recv;
+ stat->ps_drop = 0;
+ stat->ps_ifdrop = 0;
+
+ return 0;
+}
+
+static void
+rdmasniff_cleanup(pcap_t *handle)
+{
+ struct pcap_rdmasniff *priv = handle->priv;
+
+ ibv_dereg_mr(priv->mr);
+ ibv_destroy_flow(priv->flow);
+ ibv_destroy_qp(priv->qp);
+ ibv_destroy_cq(priv->cq);
+ ibv_dealloc_pd(priv->pd);
+ ibv_destroy_comp_channel(priv->channel);
+ ibv_close_device(priv->context);
+ free(priv->oneshot_buffer);
+
+ pcap_cleanup_live_common(handle);
+}
+
+static void
+rdmasniff_post_recv(pcap_t *handle, uint64_t wr_id)
+{
+ struct pcap_rdmasniff *priv = handle->priv;
+ struct ibv_sge sg_entry;
+ struct ibv_recv_wr wr, *bad_wr;
+
+ sg_entry.length = RDMASNIFF_RECEIVE_SIZE;
+ sg_entry.addr = (uintptr_t) handle->buffer + RDMASNIFF_RECEIVE_SIZE * wr_id;
+ sg_entry.lkey = priv->mr->lkey;
+
+ wr.wr_id = wr_id;
+ wr.num_sge = 1;
+ wr.sg_list = &sg_entry;
+ wr.next = NULL;
+
+ ibv_post_recv(priv->qp, &wr, &bad_wr);
+}
+
+static int
+rdmasniff_read(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user)
+{
+ struct pcap_rdmasniff *priv = handle->priv;
+ struct ibv_cq *ev_cq;
+ void *ev_ctx;
+ struct ibv_wc wc;
+ struct pcap_pkthdr pkth;
+ u_char *pktd;
+ int count = 0;
+
+ if (!priv->cq_event) {
+ while (ibv_get_cq_event(priv->channel, &ev_cq, &ev_ctx) < 0) {
+ if (errno != EINTR) {
+ return PCAP_ERROR;
+ }
+ if (handle->break_loop) {
+ handle->break_loop = 0;
+ return PCAP_ERROR_BREAK;
+ }
+ }
+ ibv_ack_cq_events(priv->cq, 1);
+ ibv_req_notify_cq(priv->cq, 0);
+ priv->cq_event = 1;
+ }
+
+ while (count < max_packets || PACKET_COUNT_IS_UNLIMITED(max_packets)) {
+ if (ibv_poll_cq(priv->cq, 1, &wc) != 1) {
+ priv->cq_event = 0;
+ break;
+ }
+
+ if (wc.status != IBV_WC_SUCCESS) {
+ fprintf(stderr, "failed WC wr_id %lld status %d/%s\n",
+ (unsigned long long) wc.wr_id,
+ wc.status, ibv_wc_status_str(wc.status));
+ continue;
+ }
+
+ pkth.len = wc.byte_len;
+ pkth.caplen = min(pkth.len, (u_int)handle->snapshot);
+ gettimeofday(&pkth.ts, NULL);
+
+ pktd = (u_char *) handle->buffer + wc.wr_id * RDMASNIFF_RECEIVE_SIZE;
+
+ if (handle->fcode.bf_insns == NULL ||
+ bpf_filter(handle->fcode.bf_insns, pktd, pkth.len, pkth.caplen)) {
+ callback(user, &pkth, pktd);
+ ++priv->packets_recv;
+ ++count;
+ }
+
+ rdmasniff_post_recv(handle, wc.wr_id);
+
+ if (handle->break_loop) {
+ handle->break_loop = 0;
+ return PCAP_ERROR_BREAK;
+ }
+ }
+
+ return count;
+}
+
+static void
+rdmasniff_oneshot(u_char *user, const struct pcap_pkthdr *h, const u_char *bytes)
+{
+ struct oneshot_userdata *sp = (struct oneshot_userdata *) user;
+ pcap_t *handle = sp->pd;
+ struct pcap_rdmasniff *priv = handle->priv;
+
+ *sp->hdr = *h;
+ memcpy(priv->oneshot_buffer, bytes, h->caplen);
+ *sp->pkt = priv->oneshot_buffer;
+}
+
+static int
+rdmasniff_activate(pcap_t *handle)
+{
+ struct pcap_rdmasniff *priv = handle->priv;
+ struct ibv_qp_init_attr qp_init_attr;
+ struct ibv_qp_attr qp_attr;
+ struct ibv_flow_attr flow_attr;
+ struct ibv_port_attr port_attr;
+ int i;
+
+ priv->context = ibv_open_device(priv->rdma_device);
+ if (!priv->context) {
+ pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
+ "Failed to open device %s", handle->opt.device);
+ goto error;
+ }
+
+ priv->pd = ibv_alloc_pd(priv->context);
+ if (!priv->pd) {
+ pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
+ "Failed to alloc PD for device %s", handle->opt.device);
+ goto error;
+ }
+
+ priv->channel = ibv_create_comp_channel(priv->context);
+ if (!priv->channel) {
+ pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
+ "Failed to create comp channel for device %s", handle->opt.device);
+ goto error;
+ }
+
+ priv->cq = ibv_create_cq(priv->context, RDMASNIFF_NUM_RECEIVES,
+ NULL, priv->channel, 0);
+ if (!priv->cq) {
+ pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
+ "Failed to create CQ for device %s", handle->opt.device);
+ goto error;
+ }
+
+ ibv_req_notify_cq(priv->cq, 0);
+
+ memset(&qp_init_attr, 0, sizeof qp_init_attr);
+ qp_init_attr.send_cq = qp_init_attr.recv_cq = priv->cq;
+ qp_init_attr.cap.max_recv_wr = RDMASNIFF_NUM_RECEIVES;
+ qp_init_attr.cap.max_recv_sge = 1;
+ qp_init_attr.qp_type = IBV_QPT_RAW_PACKET;
+ priv->qp = ibv_create_qp(priv->pd, &qp_init_attr);
+ if (!priv->qp) {
+ pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
+ "Failed to create QP for device %s", handle->opt.device);
+ goto error;
+ }
+
+ memset(&qp_attr, 0, sizeof qp_attr);
+ qp_attr.qp_state = IBV_QPS_INIT;
+ qp_attr.port_num = priv->port_num;
+ if (ibv_modify_qp(priv->qp, &qp_attr, IBV_QP_STATE | IBV_QP_PORT)) {
+ pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
+ "Failed to modify QP to INIT for device %s", handle->opt.device);
+ goto error;
+ }
+
+ memset(&qp_attr, 0, sizeof qp_attr);
+ qp_attr.qp_state = IBV_QPS_RTR;
+ if (ibv_modify_qp(priv->qp, &qp_attr, IBV_QP_STATE)) {
+ pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
+ "Failed to modify QP to RTR for device %s", handle->opt.device);
+ goto error;
+ }
+
+ memset(&flow_attr, 0, sizeof flow_attr);
+ flow_attr.type = IBV_FLOW_ATTR_SNIFFER;
+ flow_attr.size = sizeof flow_attr;
+ flow_attr.port = priv->port_num;
+ priv->flow = ibv_create_flow(priv->qp, &flow_attr);
+ if (!priv->flow) {
+ pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
+ "Failed to create flow for device %s", handle->opt.device);
+ goto error;
+ }
+
+ handle->bufsize = RDMASNIFF_NUM_RECEIVES * RDMASNIFF_RECEIVE_SIZE;
+ handle->buffer = malloc(handle->bufsize);
+ if (!handle->buffer) {
+ pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
+ "Failed to allocate receive buffer for device %s", handle->opt.device);
+ goto error;
+ }
+
+ priv->oneshot_buffer = malloc(RDMASNIFF_RECEIVE_SIZE);
+ if (!priv->oneshot_buffer) {
+ pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
+ "Failed to allocate oneshot buffer for device %s", handle->opt.device);
+ goto error;
+ }
+
+ priv->mr = ibv_reg_mr(priv->pd, handle->buffer, handle->bufsize, IBV_ACCESS_LOCAL_WRITE);
+ if (!priv->mr) {
+ pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
+ "Failed to register MR for device %s", handle->opt.device);
+ goto error;
+ }
+
+
+ for (i = 0; i < RDMASNIFF_NUM_RECEIVES; ++i) {
+ rdmasniff_post_recv(handle, i);
+ }
+
+ if (!ibv_query_port(priv->context, priv->port_num, &port_attr) &&
+ port_attr.link_layer == IBV_LINK_LAYER_INFINIBAND) {
+ handle->linktype = DLT_INFINIBAND;
+ } else {
+ handle->linktype = DLT_EN10MB;
+ }
+
+ if (handle->snapshot <= 0 || handle->snapshot > RDMASNIFF_RECEIVE_SIZE)
+ handle->snapshot = RDMASNIFF_RECEIVE_SIZE;
+
+ handle->offset = 0;
+ handle->read_op = rdmasniff_read;
+ handle->stats_op = rdmasniff_stats;
+ handle->cleanup_op = rdmasniff_cleanup;
+ handle->setfilter_op = install_bpf_program;
+ handle->setdirection_op = NULL;
+ handle->set_datalink_op = NULL;
+ handle->getnonblock_op = pcap_getnonblock_fd;
+ handle->setnonblock_op = pcap_setnonblock_fd;
+ handle->oneshot_callback = rdmasniff_oneshot;
+ handle->selectable_fd = priv->channel->fd;
+
+ return 0;
+
+error:
+ if (priv->mr) {
+ ibv_dereg_mr(priv->mr);
+ }
+
+ if (priv->flow) {
+ ibv_destroy_flow(priv->flow);
+ }
+
+ if (priv->qp) {
+ ibv_destroy_qp(priv->qp);
+ }
+
+ if (priv->cq) {
+ ibv_destroy_cq(priv->cq);
+ }
+
+ if (priv->channel) {
+ ibv_destroy_comp_channel(priv->channel);
+ }
+
+ if (priv->pd) {
+ ibv_dealloc_pd(priv->pd);
+ }
+
+ if (priv->context) {
+ ibv_close_device(priv->context);
+ }
+
+ if (priv->oneshot_buffer) {
+ free(priv->oneshot_buffer);
+ }
+
+ return PCAP_ERROR;
+}
+
+pcap_t *
+rdmasniff_create(const char *device, char *ebuf, int *is_ours)
+{
+ struct pcap_rdmasniff *priv;
+ struct ibv_device **dev_list;
+ int numdev;
+ size_t namelen;
+ const char *port;
+ unsigned port_num;
+ int i;
+ pcap_t *p = NULL;
+
+ *is_ours = 0;
+
+ dev_list = ibv_get_device_list(&numdev);
+ if (!dev_list || !numdev) {
+ return NULL;
+ }
+
+ namelen = strlen(device);
+
+ port = strchr(device, ':');
+ if (port) {
+ port_num = strtoul(port + 1, NULL, 10);
+ if (port_num > 0) {
+ namelen = port - device;
+ } else {
+ port_num = 1;
+ }
+ } else {
+ port_num = 1;
+ }
+
+ for (i = 0; i < numdev; ++i) {
+ if (strlen(dev_list[i]->name) == namelen &&
+ !strncmp(device, dev_list[i]->name, namelen)) {
+ *is_ours = 1;
+
+ p = pcap_create_common(ebuf, sizeof (struct pcap_rdmasniff));
+ if (p) {
+ p->activate_op = rdmasniff_activate;
+ priv = p->priv;
+ priv->rdma_device = dev_list[i];
+ priv->port_num = port_num;
+ }
+ break;
+ }
+ }
+
+ ibv_free_device_list(dev_list);
+ return p;
+}
+
+int
+rdmasniff_findalldevs(pcap_if_list_t *devlistp, char *err_str)
+{
+ struct ibv_device **dev_list;
+ int numdev;
+ int i;
+ int ret = 0;
+
+ dev_list = ibv_get_device_list(&numdev);
+ if (!dev_list || !numdev) {
+ return 0;
+ }
+
+ for (i = 0; i < numdev; ++i) {
+ /*
+ * XXX - do the notions of "up", "running", or
+ * "connected" apply here?
+ */
+ if (!add_dev(devlistp, dev_list[i]->name, 0, "RDMA sniffer", err_str)) {
+ ret = -1;
+ goto out;
+ }
+ }
+
+out:
+ ibv_free_device_list(dev_list);
+ return ret;
+}
diff --git a/contrib/libpcap/pcap-rdmasniff.h b/contrib/libpcap/pcap-rdmasniff.h
new file mode 100644
index 0000000000000..ff1f3c20d75ca
--- /dev/null
+++ b/contrib/libpcap/pcap-rdmasniff.h
@@ -0,0 +1,2 @@
+pcap_t *rdmasniff_create(const char *device, char *ebuf, int *is_ours);
+int rdmasniff_findalldevs(pcap_if_list_t *devlistp, char *err_str);
diff --git a/contrib/libpcap/pcap-rpcap-int.h b/contrib/libpcap/pcap-rpcap-int.h
new file mode 100644
index 0000000000000..e707a85f70757
--- /dev/null
+++ b/contrib/libpcap/pcap-rpcap-int.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2002 - 2005 NetGroup, Politecnico di Torino (Italy)
+ * Copyright (c) 2005 - 2008 CACE Technologies, Davis (California)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Politecnico di Torino, CACE Technologies
+ * nor the names of its contributors may be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __PCAP_RPCAP_INT_H__
+#define __PCAP_RPCAP_INT_H__
+
+#include "pcap.h"
+#include "sockutils.h" /* Needed for some structures (like SOCKET, sockaddr_in) which are used here */
+
+/*
+ * \file pcap-rpcap-int.h
+ *
+ * This file keeps all the definitions used by the RPCAP client and server,
+ * other than the protocol definitions.
+ *
+ * \warning All the RPCAP functions that are allowed to return a buffer containing
+ * the error description can return max PCAP_ERRBUF_SIZE characters.
+ * However there is no guarantees that the string will be zero-terminated.
+ * Best practice is to define the errbuf variable as a char of size 'PCAP_ERRBUF_SIZE+1'
+ * and to insert manually the termination char at the end of the buffer. This will
+ * guarantee that no buffer overflows occur even if we use the printf() to show
+ * the error on the screen.
+ */
+
+/*********************************************************
+ * *
+ * General definitions / typedefs for the RPCAP protocol *
+ * *
+ *********************************************************/
+
+/*
+ * \brief Buffer used by socket functions to send-receive packets.
+ * In case you plan to have messages larger than this value, you have to increase it.
+ */
+#define RPCAP_NETBUF_SIZE 64000
+
+/*********************************************************
+ * *
+ * Exported function prototypes *
+ * *
+ *********************************************************/
+void rpcap_createhdr(struct rpcap_header *header, uint8 type, uint16 value, uint32 length);
+int rpcap_senderror(SOCKET sock, char *error, unsigned short errcode, char *errbuf);
+
+#endif
diff --git a/contrib/libpcap/pcap-rpcap.c b/contrib/libpcap/pcap-rpcap.c
index b954058df9393..42f381c862737 100644
--- a/contrib/libpcap/pcap-rpcap.c
+++ b/contrib/libpcap/pcap-rpcap.c
@@ -32,53 +32,114 @@
*/
#ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
#endif
+#include "ftmacros.h"
+
#include <string.h> /* for strlen(), ... */
#include <stdlib.h> /* for malloc(), free(), ... */
#include <stdarg.h> /* for functions with variable number of arguments */
#include <errno.h> /* for the errno variable */
+#include "sockutils.h"
#include "pcap-int.h"
+#include "rpcap-protocol.h"
#include "pcap-rpcap.h"
-#include "sockutils.h"
/*
- * \file pcap-rpcap.c
- *
- * This file keeps all the new funtions that are needed for the RPCAP protocol.
- * Almost all the pcap functions need to be modified in order to become compatible
- * with the RPCAP protocol. However, you can find here only the ones that are completely new.
- *
- * This file keeps also the functions that are 'private', i.e. are needed by the RPCAP
- * protocol but are not exported to the user.
+ * This file contains the pcap module for capturing from a remote machine's
+ * interfaces using the RPCAP protocol.
*
- * \warning All the RPCAP functions that are allowed to return a buffer containing
- * the error description can return max PCAP_ERRBUF_SIZE characters.
+ * WARNING: All the RPCAP functions that are allowed to return a buffer
+ * containing the error description can return max PCAP_ERRBUF_SIZE characters.
* However there is no guarantees that the string will be zero-terminated.
- * Best practice is to define the errbuf variable as a char of size 'PCAP_ERRBUF_SIZE+1'
- * and to insert manually a NULL character at the end of the buffer. This will
- * guarantee that no buffer overflows occur even if we use the printf() to show
- * the error on the screen.
+ * Best practice is to define the errbuf variable as a char of size
+ * 'PCAP_ERRBUF_SIZE+1' and to insert manually a NULL character at the end
+ * of the buffer. This will guarantee that no buffer overflows occur even
+ * if we use the printf() to show the error on the screen.
+ *
+ * XXX - actually, null-terminating the error string is part of the
+ * contract for the pcap API; if there's any place in the pcap code
+ * that doesn't guarantee null-termination, even at the expense of
+ * cutting the message short, that's a bug and needs to be fixed.
*/
-#define PCAP_STATS_STANDARD 0 /* Used by pcap_stats_remote to see if we want standard or extended statistics */
-#define PCAP_STATS_EX 1 /* Used by pcap_stats_remote to see if we want standard or extended statistics */
+#define PCAP_STATS_STANDARD 0 /* Used by pcap_stats_rpcap to see if we want standard or extended statistics */
+#ifdef _WIN32
+#define PCAP_STATS_EX 1 /* Used by pcap_stats_rpcap to see if we want standard or extended statistics */
+#endif
+
+/*
+ * \brief Keeps a list of all the opened connections in the active mode.
+ *
+ * This structure defines a linked list of items that are needed to keep the info required to
+ * manage the active mode.
+ * In other words, when a new connection in active mode starts, this structure is updated so that
+ * it reflects the list of active mode connections currently opened.
+ * This structure is required by findalldevs() and open_remote() to see if they have to open a new
+ * control connection toward the host, or they already have a control connection in place.
+ */
+struct activehosts
+{
+ struct sockaddr_storage host;
+ SOCKET sockctrl;
+ uint8 protocol_version;
+ struct activehosts *next;
+};
/* Keeps a list of all the opened connections in the active mode. */
-struct activehosts *activeHosts;
+static struct activehosts *activeHosts;
/*
- * Private data for capturing on WinPcap devices.
+ * Keeps the main socket identifier when we want to accept a new remote
+ * connection (active mode only).
+ * See the documentation of pcap_remoteact_accept() and
+ * pcap_remoteact_cleanup() for more details.
*/
-struct pcap_win {
- int nonblock;
- int rfmon_selfstart; /* a flag tells whether the monitor mode is set by itself */
- int filtering_in_kernel; /* using kernel filter */
+static SOCKET sockmain;
-#ifdef HAVE_DAG_API
- int dag_fcs_bits; /* Number of checksum bits from link layer */
-#endif
+/*
+ * Private data for capturing remotely using the rpcap protocol.
+ */
+struct pcap_rpcap {
+ /*
+ * This is '1' if we're the network client; it is needed by several
+ * functions (such as pcap_setfilter()) to know whether they have
+ * to use the socket or have to open the local adapter.
+ */
+ int rmt_clientside;
+
+ SOCKET rmt_sockctrl; /* socket ID of the socket used for the control connection */
+ SOCKET rmt_sockdata; /* socket ID of the socket used for the data connection */
+ int rmt_flags; /* we have to save flags, since they are passed by the pcap_open_live(), but they are used by the pcap_startcapture() */
+ int rmt_capstarted; /* 'true' if the capture is already started (needed to knoe if we have to call the pcap_startcapture() */
+ char *currentfilter; /* Pointer to a buffer (allocated at run-time) that stores the current filter. Needed when flag PCAP_OPENFLAG_NOCAPTURE_RPCAP is turned on. */
+
+ uint8 protocol_version; /* negotiated protocol version */
+
+ unsigned int TotNetDrops; /* keeps the number of packets that have been dropped by the network */
+
+ /*
+ * This keeps the number of packets that have been received by the
+ * application.
+ *
+ * Packets dropped by the kernel buffer are not counted in this
+ * variable. It is always equal to (TotAccepted - TotDrops),
+ * except for the case of remote capture, in which we have also
+ * packets in flight, i.e. that have been transmitted by the remote
+ * host, but that have not been received (yet) from the client.
+ * In this case, (TotAccepted - TotDrops - TotNetDrops) gives a
+ * wrong result, since this number does not corresponds always to
+ * the number of packet received by the application. For this reason,
+ * in the remote capture we need another variable that takes into
+ * account of the number of packets actually received by the
+ * application.
+ */
+ unsigned int TotCapt;
+
+ struct pcap_stat stat;
+ /* XXX */
+ struct pcap *next; /* list of open pcaps that need stuff cleared on close */
};
/****************************************************
@@ -86,14 +147,23 @@ struct pcap_win {
* Locally defined functions *
* *
****************************************************/
-static int rpcap_checkver(SOCKET sock, struct rpcap_header *header, char *errbuf);
-static struct pcap_stat *rpcap_stats_remote(pcap_t *p, struct pcap_stat *ps, int mode);
+static struct pcap_stat *rpcap_stats_rpcap(pcap_t *p, struct pcap_stat *ps, int mode);
static int pcap_pack_bpffilter(pcap_t *fp, char *sendbuf, int *sendbufidx, struct bpf_program *prog);
static int pcap_createfilter_norpcappkt(pcap_t *fp, struct bpf_program *prog);
static int pcap_updatefilter_remote(pcap_t *fp, struct bpf_program *prog);
-static int pcap_setfilter_remote(pcap_t *fp, struct bpf_program *prog);
-static int pcap_setsampling_remote(pcap_t *p);
-
+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);
+static int rpcap_process_msg_header(SOCKET sock, uint8 ver, uint8 request_type, struct rpcap_header *header, char *errbuf);
+static int rpcap_recv(SOCKET sock, void *buffer, size_t toread, uint32 *plen, char *errbuf);
+static void rpcap_msg_err(SOCKET sockctrl, uint32 plen, char *remote_errbuf);
+static int rpcap_discard(SOCKET sock, uint32 len, char *errbuf);
+static int rpcap_read_packet_msg(SOCKET sock, pcap_t *p, size_t size);
/****************************************************
* *
@@ -102,21 +172,67 @@ static int pcap_setsampling_remote(pcap_t *p);
****************************************************/
/*
- * \ingroup remote_pri_func
- *
- * \brief It traslates (i.e. de-serializes) a 'sockaddr_storage' structure from
- * the network byte order to the host byte order.
- *
- * It accepts a 'sockaddr_storage' structure as it is received from the network and it
- * converts it into the host byte order (by means of a set of ntoh() ).
- * The function will allocate the 'sockaddrout' variable according to the address family
- * in use. In case the address does not belong to the AF_INET nor AF_INET6 families,
- * 'sockaddrout' is not allocated and a NULL pointer is returned.
- * This usually happens because that address does not exist on the other host, so the
- * RPCAP daemon sent a 'sockaddr_storage' structure containing all 'zero' values.
- *
- * \param sockaddrin: a 'sockaddr_storage' pointer to the variable that has to be
- * de-serialized.
+ * This function translates (i.e. de-serializes) a 'rpcap_sockaddr'
+ * structure from the network byte order to a 'sockaddr_in" or
+ * 'sockaddr_in6' structure in the host byte order.
+ *
+ * It accepts an 'rpcap_sockaddr' structure as it is received from the
+ * network, and checks the address family field against various values
+ * to see whether it looks like an IPv4 address, an IPv6 address, or
+ * neither of those. It checks for multiple values in order to try
+ * to handle older rpcap daemons that sent the native OS's 'sockaddr_in'
+ * or 'sockaddr_in6' structures over the wire with some members
+ * byte-swapped, and to handle the fact that AF_INET6 has different
+ * values on different OSes.
+ *
+ * For IPv4 addresses, it converts the address family to host byte
+ * order from network byte order and puts it into the structure,
+ * sets the length if a sockaddr structure has a length, converts the
+ * port number to host byte order from network byte order and puts
+ * it into the structure, copies over the IPv4 address, and zeroes
+ * out the zero padding.
+ *
+ * For IPv6 addresses, it converts the address family to host byte
+ * order from network byte order and puts it into the structure,
+ * sets the length if a sockaddr structure has a length, converts the
+ * port number and flow information to host byte order from network
+ * byte order and puts them into the structure, copies over the IPv6
+ * address, and converts the scope ID to host byte order from network
+ * byte order and puts it into the structure.
+ *
+ * The function will allocate the 'sockaddrout' variable according to the
+ * address family in use. In case the address does not belong to the
+ * AF_INET nor AF_INET6 families, 'sockaddrout' is not allocated and a
+ * NULL pointer is returned. This usually happens because that address
+ * does not exist on the other host, or is of an address family other
+ * than AF_INET or AF_INET6, so the RPCAP daemon sent a 'sockaddr_storage'
+ * structure containing all 'zero' values.
+ *
+ * Older RPCAPDs sent the addresses over the wire in the OS's native
+ * structure format. For most OSes, this looks like the over-the-wire
+ * format, but might have a different value for AF_INET6 than the value
+ * on the machine receiving the reply. For OSes with the newer BSD-style
+ * sockaddr structures, this has, instead of a 2-byte address family,
+ * a 1-byte structure length followed by a 1-byte address family. The
+ * RPCAPD code would put the address family in network byte order before
+ * sending it; that would set it to 0 on a little-endian machine, as
+ * htons() of any value between 1 and 255 would result in a value > 255,
+ * with its lower 8 bits zero, so putting that back into a 1-byte field
+ * would set it to 0.
+ *
+ * Therefore, for older RPCAPDs running on an OS with newer BSD-style
+ * sockaddr structures, the family field, if treated as a big-endian
+ * (network byte order) 16-bit field, would be:
+ *
+ * (length << 8) | family if sent by a big-endian machine
+ * (length << 8) if sent by a little-endian machine
+ *
+ * For current RPCAPDs, and for older RPCAPDs running on an OS with
+ * older BSD-style sockaddr structures, the family field, if treated
+ * as a big-endian 16-bit field, would just contain the family.
+ *
+ * \param sockaddrin: a 'rpcap_sockaddr' pointer to the variable that has
+ * to be de-serialized.
*
* \param sockaddrout: a 'sockaddr_storage' pointer to the variable that will contain
* the de-serialized data. The structure returned can be either a 'sockaddr_in' or 'sockaddr_in6'.
@@ -134,63 +250,114 @@ static int pcap_setsampling_remote(pcap_t *p);
*
* \warning The sockaddrout (if not NULL) must be deallocated by the user.
*/
-int rpcap_deseraddr(struct sockaddr_storage *sockaddrin, struct sockaddr_storage **sockaddrout, char *errbuf)
+
+/*
+ * Possible IPv4 family values other than the designated over-the-wire value,
+ * which is 2 (because everybody uses 2 for AF_INET4).
+ */
+#define SOCKADDR_IN_LEN 16 /* length of struct sockaddr_in */
+#define SOCKADDR_IN6_LEN 28 /* length of struct sockaddr_in6 */
+#define NEW_BSD_AF_INET_BE ((SOCKADDR_IN_LEN << 8) | 2)
+#define NEW_BSD_AF_INET_LE (SOCKADDR_IN_LEN << 8)
+
+/*
+ * Possible IPv6 family values other than the designated over-the-wire value,
+ * which is 23 (because that's what Windows uses, and most RPCAP servers
+ * out there are probably running Windows, as WinPcap includes the server
+ * but few if any UN*Xes build and ship it).
+ *
+ * The new BSD sockaddr structure format was in place before 4.4-Lite, so
+ * all the free-software BSDs use it.
+ */
+#define NEW_BSD_AF_INET6_BSD_BE ((SOCKADDR_IN6_LEN << 8) | 24) /* NetBSD, OpenBSD, BSD/OS */
+#define NEW_BSD_AF_INET6_FREEBSD_BE ((SOCKADDR_IN6_LEN << 8) | 28) /* FreeBSD, DragonFly BSD */
+#define NEW_BSD_AF_INET6_DARWIN_BE ((SOCKADDR_IN6_LEN << 8) | 30) /* macOS, iOS, anything else Darwin-based */
+#define NEW_BSD_AF_INET6_LE (SOCKADDR_IN6_LEN << 8)
+#define LINUX_AF_INET6 10
+#define HPUX_AF_INET6 22
+#define AIX_AF_INET6 24
+#define SOLARIS_AF_INET6 26
+
+static int
+rpcap_deseraddr(struct rpcap_sockaddr *sockaddrin, struct sockaddr_storage **sockaddrout, char *errbuf)
{
/* Warning: we support only AF_INET and AF_INET6 */
- if (ntohs(sockaddrin->ss_family) == AF_INET)
+ switch (ntohs(sockaddrin->family))
{
- struct sockaddr_in *sockaddr;
-
- sockaddr = (struct sockaddr_in *) sockaddrin;
- sockaddr->sin_family = ntohs(sockaddr->sin_family);
- sockaddr->sin_port = ntohs(sockaddr->sin_port);
+ case RPCAP_AF_INET:
+ case NEW_BSD_AF_INET_BE:
+ case NEW_BSD_AF_INET_LE:
+ {
+ struct rpcap_sockaddr_in *sockaddrin_ipv4;
+ struct sockaddr_in *sockaddrout_ipv4;
(*sockaddrout) = (struct sockaddr_storage *) malloc(sizeof(struct sockaddr_in));
if ((*sockaddrout) == NULL)
{
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc() failed: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ errno, "malloc() failed");
return -1;
}
- memcpy(*sockaddrout, sockaddr, sizeof(struct sockaddr_in));
- return 0;
- }
- if (ntohs(sockaddrin->ss_family) == AF_INET6)
- {
- struct sockaddr_in6 *sockaddr;
+ sockaddrin_ipv4 = (struct rpcap_sockaddr_in *) sockaddrin;
+ sockaddrout_ipv4 = (struct sockaddr_in *) (*sockaddrout);
+ sockaddrout_ipv4->sin_family = AF_INET;
+ sockaddrout_ipv4->sin_port = ntohs(sockaddrin_ipv4->port);
+ memcpy(&sockaddrout_ipv4->sin_addr, &sockaddrin_ipv4->addr, sizeof(sockaddrout_ipv4->sin_addr));
+ memset(sockaddrout_ipv4->sin_zero, 0, sizeof(sockaddrout_ipv4->sin_zero));
+ break;
+ }
- sockaddr = (struct sockaddr_in6 *) sockaddrin;
- sockaddr->sin6_family = ntohs(sockaddr->sin6_family);
- sockaddr->sin6_port = ntohs(sockaddr->sin6_port);
- sockaddr->sin6_flowinfo = ntohl(sockaddr->sin6_flowinfo);
- sockaddr->sin6_scope_id = ntohl(sockaddr->sin6_scope_id);
+#ifdef AF_INET6
+ case RPCAP_AF_INET6:
+ case NEW_BSD_AF_INET6_BSD_BE:
+ case NEW_BSD_AF_INET6_FREEBSD_BE:
+ case NEW_BSD_AF_INET6_DARWIN_BE:
+ case NEW_BSD_AF_INET6_LE:
+ case LINUX_AF_INET6:
+ case HPUX_AF_INET6:
+ case AIX_AF_INET6:
+ case SOLARIS_AF_INET6:
+ {
+ struct rpcap_sockaddr_in6 *sockaddrin_ipv6;
+ struct sockaddr_in6 *sockaddrout_ipv6;
(*sockaddrout) = (struct sockaddr_storage *) malloc(sizeof(struct sockaddr_in6));
if ((*sockaddrout) == NULL)
{
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc() failed: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ errno, "malloc() failed");
return -1;
}
- memcpy(*sockaddrout, sockaddr, sizeof(struct sockaddr_in6));
- return 0;
- }
+ sockaddrin_ipv6 = (struct rpcap_sockaddr_in6 *) sockaddrin;
+ sockaddrout_ipv6 = (struct sockaddr_in6 *) (*sockaddrout);
+ sockaddrout_ipv6->sin6_family = AF_INET6;
+ sockaddrout_ipv6->sin6_port = ntohs(sockaddrin_ipv6->port);
+ sockaddrout_ipv6->sin6_flowinfo = ntohl(sockaddrin_ipv6->flowinfo);
+ memcpy(&sockaddrout_ipv6->sin6_addr, &sockaddrin_ipv6->addr, sizeof(sockaddrout_ipv6->sin6_addr));
+ sockaddrout_ipv6->sin6_scope_id = ntohl(sockaddrin_ipv6->scope_id);
+ break;
+ }
+#endif
- /* It is neither AF_INET nor AF_INET6 */
- *sockaddrout = NULL;
+ default:
+ /*
+ * It is neither AF_INET nor AF_INET6 (or, if the OS doesn't
+ * support AF_INET6, it's not AF_INET).
+ */
+ *sockaddrout = NULL;
+ break;
+ }
return 0;
}
-/* \ingroup remote_pri_func
- *
- * \brief It reads a packet from the network socket. This does not make use of
- * callback (hence the "nocb" string into its name).
- *
- * This function is called by the several pcap_next_ex() when they detect that
- * we have a remote capture and they are the client side. In that case, they need
- * to read packets from the socket.
+/*
+ * This function reads a packet from the network socket. It does not
+ * deliver the packet to a pcap_dispatch()/pcap_loop() callback (hence
+ * the "nocb" string into its name).
*
- * Parameters and return values are exactly the same of the pcap_next_ex().
+ * This function is called by pcap_read_rpcap().
*
- * \warning By choice, this function does not make use of semaphores. A smarter
+ * WARNING: By choice, this function does not make use of semaphores. A smarter
* implementation should put a semaphore into the data thread, and a signal will
* be raised as soon as there is data into the socket buffer.
* However this is complicated and it does not bring any advantages when reading
@@ -202,24 +369,22 @@ int rpcap_deseraddr(struct sockaddr_storage *sockaddrin, struct sockaddr_storage
* timeout/2 and then it checks again. If packets are still missing, it returns,
* otherwise it reads packets.
*/
-static int pcap_read_nocb_remote(pcap_t *p, struct pcap_pkthdr **pkt_header, u_char **pkt_data)
+static int pcap_read_nocb_remote(pcap_t *p, struct pcap_pkthdr *pkt_header, u_char **pkt_data)
{
+ struct pcap_rpcap *pr = p->priv; /* structure used when doing a remote live capture */
struct rpcap_header *header; /* general header according to the RPCAP format */
- struct rpcap_pkthdr *net_pkt_header; /* header of the packet */
- char netbuf[RPCAP_NETBUF_SIZE]; /* size of the network buffer in which the packet is copied, just for UDP */
- uint32 totread; /* number of bytes (of payload) currently read from the network (referred to the current pkt) */
- int nread;
+ struct rpcap_pkthdr *net_pkt_header; /* header of the packet, from the message */
+ u_char *net_pkt_data; /* packet data from the message */
+ uint32 plen;
int retval; /* generic return value */
+ int msglen;
/* Structures needed for the select() call */
- fd_set rfds; /* set of socket descriptors we have to check */
struct timeval tv; /* maximum time the select() can block waiting for data */
- struct pcap_md *md; /* structure used when doing a remote live capture */
-
- md = (struct pcap_md *) ((u_char*)p->priv + sizeof(struct pcap_win));
+ fd_set rfds; /* set of socket descriptors we have to check */
/*
- * Define the read timeout, to be used in the select()
+ * Define the packet buffer timeout, to be used in the select()
* 'timeout', in pcap_t, is in milliseconds; we have to convert it into sec and microsec
*/
tv.tv_sec = p->opt.timeout / 1000;
@@ -232,11 +397,18 @@ static int pcap_read_nocb_remote(pcap_t *p, struct pcap_pkthdr **pkt_header, u_c
* 'fp->rmt_sockdata' has always to be set before calling the select(),
* since it is cleared by the select()
*/
- FD_SET(md->rmt_sockdata, &rfds);
+ FD_SET(pr->rmt_sockdata, &rfds);
- retval = select((int) md->rmt_sockdata + 1, &rfds, NULL, NULL, &tv);
+ retval = select((int) pr->rmt_sockdata + 1, &rfds, NULL, NULL, &tv);
if (retval == -1)
{
+#ifndef _WIN32
+ if (errno == EINTR)
+ {
+ /* Interrupted. */
+ return 0;
+ }
+#endif
sock_geterror("select(): ", p->errbuf, PCAP_ERRBUF_SIZE);
return -1;
}
@@ -246,190 +418,286 @@ static int pcap_read_nocb_remote(pcap_t *p, struct pcap_pkthdr **pkt_header, u_c
return 0;
/*
- * data is here; so, let's copy it into the user buffer.
- * I'm going to read a new packet; so I reset the number of bytes (payload only) read
- */
- totread = 0;
-
- /*
* We have to define 'header' as a pointer to a larger buffer,
* because in case of UDP we have to read all the message within a single call
*/
- header = (struct rpcap_header *) netbuf;
- net_pkt_header = (struct rpcap_pkthdr *) (netbuf + sizeof(struct rpcap_header));
+ header = (struct rpcap_header *) p->buffer;
+ net_pkt_header = (struct rpcap_pkthdr *) ((char *)p->buffer + sizeof(struct rpcap_header));
+ net_pkt_data = (u_char *)p->buffer + sizeof(struct rpcap_header) + sizeof(struct rpcap_pkthdr);
- if (md->rmt_flags & PCAP_OPENFLAG_DATATX_UDP)
+ if (pr->rmt_flags & PCAP_OPENFLAG_DATATX_UDP)
{
/* Read the entire message from the network */
- if (sock_recv(md->rmt_sockdata, netbuf, RPCAP_NETBUF_SIZE, SOCK_RECEIVEALL_NO, p->errbuf, PCAP_ERRBUF_SIZE) == -1)
+ msglen = sock_recv_dgram(pr->rmt_sockdata, p->buffer,
+ p->bufsize, p->errbuf, PCAP_ERRBUF_SIZE);
+ if (msglen == -1)
+ {
+ /* Network error. */
+ return -1;
+ }
+ if (msglen == -3)
+ {
+ /* Interrupted receive. */
+ return 0;
+ }
+ if ((size_t)msglen < sizeof(struct rpcap_header))
+ {
+ /*
+ * Message is shorter than an rpcap header.
+ */
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "UDP packet message is shorter than an rpcap header");
return -1;
+ }
+ plen = ntohl(header->plen);
+ if ((size_t)msglen < sizeof(struct rpcap_header) + plen)
+ {
+ /*
+ * Message is shorter than the header claims it
+ * is.
+ */
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "UDP packet message is shorter than its rpcap header claims");
+ return -1;
+ }
}
else
{
- if (sock_recv(md->rmt_sockdata, netbuf, sizeof(struct rpcap_header), SOCK_RECEIVEALL_YES, p->errbuf, PCAP_ERRBUF_SIZE) == -1)
- return -1;
- }
-
- /* Checks if the message is correct */
- retval = rpcap_checkmsg(p->errbuf, md->rmt_sockdata, header, RPCAP_MSG_PACKET, 0);
+ int status;
- if (retval != RPCAP_MSG_PACKET) /* the message is not the one expected */
- {
- switch (retval)
+ if ((size_t)p->cc < sizeof(struct rpcap_header))
{
- case -3: /* Unrecoverable network error */
- return -1; /* Do nothing; just exit from here; the error code is already into the errbuf */
-
- case -2: /* The other endpoint sent a message that is not allowed here */
- case -1: /* The other endpoint has a version number that is not compatible with our */
- return 0; /* Return 'no packets received' */
+ /*
+ * We haven't read any of the packet header yet.
+ * The size we should get is the size of the
+ * packet header.
+ */
+ status = rpcap_read_packet_msg(pr->rmt_sockdata, p,
+ sizeof(struct rpcap_header));
+ if (status == -1)
+ {
+ /* Network error. */
+ return -1;
+ }
+ if (status == -3)
+ {
+ /* Interrupted receive. */
+ return 0;
+ }
+ }
- default:
- SOCK_ASSERT("Internal error", 1);
- return 0; /* Return 'no packets received' */
+ /*
+ * We have the header, so we know how long the
+ * message payload is. The size we should get
+ * is the size of the packet header plus the
+ * size of the payload.
+ */
+ plen = ntohl(header->plen);
+ if (plen > p->bufsize - sizeof(struct rpcap_header))
+ {
+ /*
+ * This is bigger than the largest
+ * record we'd expect. (We do it by
+ * subtracting in order to avoid an
+ * overflow.)
+ */
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "Server sent us a message larger than the largest expected packet message");
+ return -1;
+ }
+ status = rpcap_read_packet_msg(pr->rmt_sockdata, p,
+ sizeof(struct rpcap_header) + plen);
+ if (status == -1)
+ {
+ /* Network error. */
+ return -1;
}
+ if (status == -3)
+ {
+ /* Interrupted receive. */
+ return 0;
+ }
+
+ /*
+ * We have the entire message; reset the buffer pointer
+ * and count, as the next read should start a new
+ * message.
+ */
+ p->bp = p->buffer;
+ p->cc = 0;
}
- /* In case of TCP, read the remaining of the packet from the socket */
- if (!(md->rmt_flags & PCAP_OPENFLAG_DATATX_UDP))
+ /*
+ * We have the entire message.
+ */
+ header->plen = plen;
+
+ /*
+ * Did the server specify the version we negotiated?
+ */
+ if (rpcap_check_msg_ver(pr->rmt_sockdata, pr->protocol_version,
+ header, p->errbuf) == -1)
{
- /* Read the RPCAP packet header from the network */
- nread = sock_recv(md->rmt_sockdata, (char *)net_pkt_header,
- sizeof(struct rpcap_pkthdr), SOCK_RECEIVEALL_YES,
- p->errbuf, PCAP_ERRBUF_SIZE);
- if (nread == -1)
- return -1;
- totread += nread;
+ return 0; /* Return 'no packets received' */
}
- if ((ntohl(net_pkt_header->caplen) + sizeof(struct pcap_pkthdr)) <= p->bufsize)
+ /*
+ * Is this a RPCAP_MSG_PACKET message?
+ */
+ if (header->type != RPCAP_MSG_PACKET)
{
- /* Initialize returned structures */
- *pkt_header = (struct pcap_pkthdr *) p->buffer;
- *pkt_data = (u_char*)p->buffer + sizeof(struct pcap_pkthdr);
+ return 0; /* Return 'no packets received' */
+ }
- (*pkt_header)->caplen = ntohl(net_pkt_header->caplen);
- (*pkt_header)->len = ntohl(net_pkt_header->len);
- (*pkt_header)->ts.tv_sec = ntohl(net_pkt_header->timestamp_sec);
- (*pkt_header)->ts.tv_usec = ntohl(net_pkt_header->timestamp_usec);
+ if (ntohl(net_pkt_header->caplen) > plen)
+ {
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "Packet's captured data goes past the end of the received packet message.");
+ return -1;
+ }
- /*
- * I don't update the counter of the packets dropped by the network since we're using TCP,
- * therefore no packets are dropped. Just update the number of packets received correctly
- */
- md->TotCapt++;
+ /* Fill in packet header */
+ pkt_header->caplen = ntohl(net_pkt_header->caplen);
+ pkt_header->len = ntohl(net_pkt_header->len);
+ pkt_header->ts.tv_sec = ntohl(net_pkt_header->timestamp_sec);
+ pkt_header->ts.tv_usec = ntohl(net_pkt_header->timestamp_usec);
- /* Copies the packet into the data buffer */
- if (md->rmt_flags & PCAP_OPENFLAG_DATATX_UDP)
- {
- unsigned int npkt;
+ /* Supply a pointer to the beginning of the packet data */
+ *pkt_data = net_pkt_data;
- /*
- * In case of UDP the packet has already been read, we have to copy it into 'buffer'.
- * Another option should be to declare 'netbuf' as 'static'. However this prevents
- * using several pcap instances within the same process (because the static buffer is shared among
- * all processes)
- */
- memcpy(*pkt_data, netbuf + sizeof(struct rpcap_header) + sizeof(struct rpcap_pkthdr), (*pkt_header)->caplen);
+ /*
+ * I don't update the counter of the packets dropped by the network since we're using TCP,
+ * therefore no packets are dropped. Just update the number of packets received correctly
+ */
+ pr->TotCapt++;
- /* We're using UDP, so we need to update the counter of the packets dropped by the network */
- npkt = ntohl(net_pkt_header->npkt);
+ if (pr->rmt_flags & PCAP_OPENFLAG_DATATX_UDP)
+ {
+ unsigned int npkt;
- if (md->TotCapt != npkt)
- {
- md->TotNetDrops += (npkt - md->TotCapt);
- md->TotCapt = npkt;
- }
+ /* We're using UDP, so we need to update the counter of the packets dropped by the network */
+ npkt = ntohl(net_pkt_header->npkt);
- }
- else
+ if (pr->TotCapt != npkt)
{
- /* In case of TCP, read the remaining of the packet from the socket */
- nread = sock_recv(md->rmt_sockdata, *pkt_data,
- (*pkt_header)->caplen, SOCK_RECEIVEALL_YES,
- p->errbuf, PCAP_ERRBUF_SIZE);
- if (nread == -1)
- return -1;
- totread += nread;
-
- /* Checks if all the data has been read; if not, discard the data in excess */
- /* This check has to be done only on TCP connections */
- if (totread != ntohl(header->plen))
- sock_discard(md->rmt_sockdata, ntohl(header->plen) - totread, NULL, 0);
+ pr->TotNetDrops += (npkt - pr->TotCapt);
+ pr->TotCapt = npkt;
}
-
-
- /* Packet read successfully */
- return 1;
- }
- else
- {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Received a packet that is larger than the internal buffer size.");
- return -1;
}
+ /* Packet read successfully */
+ return 1;
}
-/* \ingroup remote_pri_func
- *
- * \brief It reads a packet from the network socket.
- *
- * This function is called by the several pcap_read() when they detect that
- * we have a remote capture and they are the client side. In that case, they need
- * to read packets from the socket.
+/*
+ * This function reads a packet from the network socket.
*
* This function relies on the pcap_read_nocb_remote to deliver packets. The
* difference, here, is that as soon as a packet is read, it is delivered
* to the application by means of a callback function.
- *
- * Parameters and return values are exactly the same of the pcap_read().
*/
-static int pcap_read_remote(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
+static int pcap_read_rpcap(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
{
- struct pcap_pkthdr *pkt_header;
+ struct pcap_rpcap *pr = p->priv; /* structure used when doing a remote live capture */
+ struct pcap_pkthdr pkt_header;
u_char *pkt_data;
int n = 0;
+ int ret;
+
+ /*
+ * If this is client-side, and we haven't already started
+ * the capture, start it now.
+ */
+ if (pr->rmt_clientside)
+ {
+ /* We are on an remote capture */
+ if (!pr->rmt_capstarted)
+ {
+ /*
+ * The capture isn't started yet, so try to
+ * start it.
+ */
+ if (pcap_startcapture_remote(p))
+ return -1;
+ }
+ }
- while ((n < cnt) || (cnt < 0))
+ while (n < cnt || PACKET_COUNT_IS_UNLIMITED(cnt))
{
- if (pcap_read_nocb_remote(p, &pkt_header, &pkt_data) == 1)
+ /*
+ * Has "pcap_breakloop()" been called?
+ */
+ if (p->break_loop) {
+ /*
+ * Yes - clear the flag that indicates that it
+ * has, and return PCAP_ERROR_BREAK to indicate
+ * that we were told to break out of the loop.
+ */
+ p->break_loop = 0;
+ return (PCAP_ERROR_BREAK);
+ }
+
+ /*
+ * Read some packets.
+ */
+ ret = pcap_read_nocb_remote(p, &pkt_header, &pkt_data);
+ if (ret == 1)
{
- (*callback)(user, pkt_header, pkt_data);
+ /*
+ * We got a packet. Hand it to the callback
+ * and count it so we can return the count.
+ */
+ (*callback)(user, &pkt_header, pkt_data);
n++;
}
+ else if (ret == -1)
+ {
+ /* Error. */
+ return ret;
+ }
else
+ {
+ /*
+ * No packet; this could mean that we timed
+ * out, or that we got interrupted, or that
+ * we got a bad packet.
+ *
+ * Were we told to break out of the loop?
+ */
+ if (p->break_loop) {
+ /*
+ * Yes.
+ */
+ p->break_loop = 0;
+ return (PCAP_ERROR_BREAK);
+ }
+ /* No - return the number of packets we've processed. */
return n;
+ }
}
return n;
}
-/* \ingroup remote_pri_func
- *
- * \brief It sends a CLOSE command to the capture server.
- *
- * This function is called when the user wants to close a pcap_t adapter.
- * In case we're capturing from the network, it sends a command to the other
- * peer that says 'ok, let's stop capturing'.
- * This function is called automatically when the user calls the pcap_close().
+/*
+ * This function sends a CLOSE command to the capture server.
*
- * Parameters and return values are exactly the same of the pcap_close().
+ * It is called when the user calls pcap_close(). It sends a command
+ * to our peer that says 'ok, let's stop capturing'.
*
- * \warning Since we're closing the connection, we do not check for errors.
+ * WARNING: Since we're closing the connection, we do not check for errors.
*/
-static void pcap_cleanup_remote(pcap_t *fp)
+static void pcap_cleanup_rpcap(pcap_t *fp)
{
+ struct pcap_rpcap *pr = fp->priv; /* structure used when doing a remote live capture */
struct rpcap_header header; /* header of the RPCAP packet */
struct activehosts *temp; /* temp var needed to scan the host list chain, to detect if we're in active mode */
- int active = 0; /* active mode or not? */
- struct pcap_md *md; /* structure used when doing a remote live capture */
-
- md = (struct pcap_md *) ((u_char*)fp->priv + sizeof(struct pcap_win));
+ int active = 0; /* active mode or not? */
/* detect if we're in active mode */
temp = activeHosts;
while (temp)
{
- if (temp->sockctrl == md->rmt_sockctrl)
+ if (temp->sockctrl == pr->rmt_sockctrl)
{
active = 1;
break;
@@ -439,61 +707,75 @@ static void pcap_cleanup_remote(pcap_t *fp)
if (!active)
{
- rpcap_createhdr(&header, RPCAP_MSG_CLOSE, 0, 0);
+ rpcap_createhdr(&header, pr->protocol_version,
+ RPCAP_MSG_CLOSE, 0, 0);
- /* I don't check for errors, since I'm going to close everything */
- sock_send(md->rmt_sockctrl, (char *)&header, sizeof(struct rpcap_header), NULL, 0);
+ /*
+ * Send the close request; don't report any errors, as
+ * we're closing this pcap_t, and have no place to report
+ * the error. No reply is sent to this message.
+ */
+ (void)sock_send(pr->rmt_sockctrl, (char *)&header,
+ sizeof(struct rpcap_header), NULL, 0);
}
else
{
- rpcap_createhdr(&header, RPCAP_MSG_ENDCAP_REQ, 0, 0);
+ rpcap_createhdr(&header, pr->protocol_version,
+ RPCAP_MSG_ENDCAP_REQ, 0, 0);
- /* I don't check for errors, since I'm going to close everything */
- sock_send(md->rmt_sockctrl, (char *)&header, sizeof(struct rpcap_header), NULL, 0);
-
- /* wait for the answer */
- /* Don't check what we got, since the present libpcap does not uses this pcap_t anymore */
- sock_recv(md->rmt_sockctrl, (char *)&header, sizeof(struct rpcap_header), SOCK_RECEIVEALL_YES, NULL, 0);
-
- if (ntohl(header.plen) != 0)
- sock_discard(md->rmt_sockctrl, ntohl(header.plen), NULL, 0);
+ /*
+ * Send the end capture request; don't report any errors,
+ * as we're closing this pcap_t, and have no place to
+ * report the error.
+ */
+ if (sock_send(pr->rmt_sockctrl, (char *)&header,
+ sizeof(struct rpcap_header), NULL, 0) == 0)
+ {
+ /*
+ * Wait for the answer; don't report any errors,
+ * as we're closing this pcap_t, and have no
+ * place to report the error.
+ */
+ if (rpcap_process_msg_header(pr->rmt_sockctrl,
+ pr->protocol_version, RPCAP_MSG_ENDCAP_REQ,
+ &header, NULL) == 0)
+ {
+ (void)rpcap_discard(pr->rmt_sockctrl,
+ header.plen, NULL);
+ }
+ }
}
- if (md->rmt_sockdata)
+ if (pr->rmt_sockdata)
{
- sock_close(md->rmt_sockdata, NULL, 0);
- md->rmt_sockdata = 0;
+ sock_close(pr->rmt_sockdata, NULL, 0);
+ pr->rmt_sockdata = 0;
}
- if ((!active) && (md->rmt_sockctrl))
- sock_close(md->rmt_sockctrl, NULL, 0);
+ if ((!active) && (pr->rmt_sockctrl))
+ sock_close(pr->rmt_sockctrl, NULL, 0);
- md->rmt_sockctrl = 0;
+ pr->rmt_sockctrl = 0;
- if (md->currentfilter)
+ if (pr->currentfilter)
{
- free(md->currentfilter);
- md->currentfilter = NULL;
+ free(pr->currentfilter);
+ pr->currentfilter = NULL;
}
/* To avoid inconsistencies in the number of sock_init() */
sock_cleanup();
}
-/* \ingroup remote_pri_func
- *
- * \brief It retrieves network statistics from the other peer.
- *
- * This function is just a void cointainer, since the work is done by the rpcap_stats_remote().
- * See that funcion for more details.
- *
- * Parameters and return values are exactly the same of the pcap_stats().
+/*
+ * This function retrieves network statistics from our peer;
+ * it provides only the standard statistics.
*/
-static int pcap_stats_remote(pcap_t *p, struct pcap_stat *ps)
+static int pcap_stats_rpcap(pcap_t *p, struct pcap_stat *ps)
{
struct pcap_stat *retval;
- retval = rpcap_stats_remote(p, ps, PCAP_STATS_STANDARD);
+ retval = rpcap_stats_rpcap(p, ps, PCAP_STATS_STANDARD);
if (retval)
return 0;
@@ -502,414 +784,236 @@ static int pcap_stats_remote(pcap_t *p, struct pcap_stat *ps)
}
#ifdef _WIN32
-/* \ingroup remote_pri_func
- *
- * \brief It retrieves network statistics from the other peer.
- *
- * This function is just a void cointainer, since the work is done by the rpcap_stats_remote().
- * See that funcion for more details.
- *
- * Parameters and return values are exactly the same of the pcap_stats_ex().
+/*
+ * This function retrieves network statistics from our peer;
+ * it provides the additional statistics supported by pcap_stats_ex().
*/
-static struct pcap_stat *pcap_stats_ex_remote(pcap_t *p, int *pcap_stat_size)
+static struct pcap_stat *pcap_stats_ex_rpcap(pcap_t *p, int *pcap_stat_size)
{
*pcap_stat_size = sizeof (p->stat);
/* PCAP_STATS_EX (third param) means 'extended pcap_stats()' */
- return (rpcap_stats_remote(p, &(p->stat), PCAP_STATS_EX));
+ return (rpcap_stats_rpcap(p, &(p->stat), PCAP_STATS_EX));
}
#endif
-/* \ingroup remote_pri_func
- *
- * \brief It retrieves network statistics from the other peer.
- *
- * This function can be called in two modes:
- * - PCAP_STATS_STANDARD: if we want just standard statistics (i.e. the pcap_stats() )
- * - PCAP_STATS_EX: if we want extended statistics (i.e. the pcap_stats_ex() )
- *
- * This 'mode' parameter is needed because in the standard pcap_stats() the variable that keeps the
- * statistics is allocated by the user. Unfortunately, this structure has been extended in order
- * to keep new stats. However, if the user has a smaller structure and it passes it to the pcap_stats,
- * thid function will try to fill in more data than the size of the structure, so that the application
- * goes in memory overflow.
- * So, we need to know it we have to copy just the standard fields, or the extended fields as well.
- *
- * In case we want to copy the extended fields as well, the problem of memory overflow does no
- * longer exist because the structure pcap_stat is no longer allocated by the program;
- * it is allocated by the library instead.
+/*
+ * This function retrieves network statistics from our peer. It
+ * is used by the two previous functions.
+ *
+ * It can be called in two modes:
+ * - PCAP_STATS_STANDARD: if we want just standard statistics (i.e.,
+ * for pcap_stats())
+ * - PCAP_STATS_EX: if we want extended statistics (i.e., for
+ * pcap_stats_ex())
+ *
+ * This 'mode' parameter is needed because in pcap_stats() the variable that
+ * keeps the statistics is allocated by the user. On Windows, this structure
+ * has been extended in order to keep new stats. However, if the user has a
+ * smaller structure and it passes it to pcap_stats(), this function will
+ * try to fill in more data than the size of the structure, so that memory
+ * after the structure will be overwritten.
+ *
+ * So, we need to know it we have to copy just the standard fields, or the
+ * extended fields as well.
+ *
+ * In case we want to copy the extended fields as well, the problem of
+ * memory overflow no longer exists because the structure that's filled
+ * in is part of the pcap_t, so that it can be guaranteed to be large
+ * enough for the additional statistics.
*
* \param p: the pcap_t structure related to the current instance.
*
- * \param ps: a 'pcap_stat' structure, needed for compatibility with pcap_stat(), in which
- * the structure is allocated by the user. In case of pcap_stats_ex, this structure and the
- * function return value point to the same variable.
+ * \param ps: a pointer to a 'pcap_stat' structure, needed for compatibility
+ * with pcap_stat(), where the structure is allocated by the user. In case
+ * of pcap_stats_ex(), this structure and the function return value point
+ * to the same variable.
*
* \param mode: one of PCAP_STATS_STANDARD or PCAP_STATS_EX.
*
* \return The structure that keeps the statistics, or NULL in case of error.
* The error string is placed in the pcap_t structure.
*/
-static struct pcap_stat *rpcap_stats_remote(pcap_t *p, struct pcap_stat *ps, int mode)
+static struct pcap_stat *rpcap_stats_rpcap(pcap_t *p, struct pcap_stat *ps, int mode)
{
+ struct pcap_rpcap *pr = p->priv; /* structure used when doing a remote live capture */
struct rpcap_header header; /* header of the RPCAP packet */
struct rpcap_stats netstats; /* statistics sent on the network */
- uint32 totread = 0; /* number of bytes of the payload read from the socket */
- int nread;
- int retval; /* temp variable which stores functions return value */
- struct pcap_md *md; /* structure used when doing a remote live capture */
+ uint32 plen; /* data remaining in the message */
- md = (struct pcap_md *) ((u_char*)p->priv + sizeof(struct pcap_win));
+#ifdef _WIN32
+ if (mode != PCAP_STATS_STANDARD && mode != PCAP_STATS_EX)
+#else
+ if (mode != PCAP_STATS_STANDARD)
+#endif
+ {
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "Invalid stats mode %d", mode);
+ return NULL;
+ }
/*
- * If the capture has still to start, we cannot ask statistics to the other peer,
- * so we return a fake number
+ * If the capture has not yet started, we cannot request statistics
+ * for the capture from our peer, so we return 0 for all statistics,
+ * as nothing's been seen yet.
*/
- if (!md->rmt_capstarted)
+ if (!pr->rmt_capstarted)
{
- if (mode == PCAP_STATS_STANDARD)
- {
- ps->ps_drop = 0;
- ps->ps_ifdrop = 0;
- ps->ps_recv = 0;
- }
- else
+ ps->ps_drop = 0;
+ ps->ps_ifdrop = 0;
+ ps->ps_recv = 0;
+#ifdef _WIN32
+ if (mode == PCAP_STATS_EX)
{
ps->ps_capt = 0;
- ps->ps_drop = 0;
- ps->ps_ifdrop = 0;
- ps->ps_netdrop = 0;
- ps->ps_recv = 0;
ps->ps_sent = 0;
+ ps->ps_netdrop = 0;
}
+#endif /* _WIN32 */
return ps;
}
- rpcap_createhdr(&header, RPCAP_MSG_STATS_REQ, 0, 0);
+ rpcap_createhdr(&header, pr->protocol_version,
+ RPCAP_MSG_STATS_REQ, 0, 0);
/* Send the PCAP_STATS command */
- if (sock_send(md->rmt_sockctrl, (char *)&header, sizeof(struct rpcap_header), p->errbuf, PCAP_ERRBUF_SIZE))
- goto error;
-
- /* Receive the RPCAP stats reply message */
- if (sock_recv(md->rmt_sockctrl, (char *)&header, sizeof(struct rpcap_header), SOCK_RECEIVEALL_YES, p->errbuf, PCAP_ERRBUF_SIZE) == -1)
- goto error;
-
- /* Checks if the message is correct */
- retval = rpcap_checkmsg(p->errbuf, md->rmt_sockctrl, &header, RPCAP_MSG_STATS_REPLY, RPCAP_MSG_ERROR, 0);
-
- if (retval != RPCAP_MSG_STATS_REPLY) /* the message is not the one expected */
- {
- switch (retval)
- {
- case -3: /* Unrecoverable network error */
- case -2: /* The other endpoint send a message that is not allowed here */
- case -1: /* The other endpoint has a version number that is not compatible with our */
- goto error;
+ if (sock_send(pr->rmt_sockctrl, (char *)&header,
+ sizeof(struct rpcap_header), p->errbuf, PCAP_ERRBUF_SIZE) < 0)
+ return NULL; /* Unrecoverable network error */
- case RPCAP_MSG_ERROR: /* The other endpoint reported an error */
- /* Update totread, since the rpcap_checkmsg() already purged the buffer */
- totread = ntohl(header.plen);
-
- /* Do nothing; just exit; the error code is already into the errbuf */
- goto error;
+ /* Receive and process the reply message header. */
+ if (rpcap_process_msg_header(pr->rmt_sockctrl, pr->protocol_version,
+ RPCAP_MSG_STATS_REQ, &header, p->errbuf) == -1)
+ return NULL; /* Error */
- default:
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Internal error");
- goto error;
- }
- }
+ plen = header.plen;
- nread = sock_recv(md->rmt_sockctrl, (char *)&netstats,
- sizeof(struct rpcap_stats), SOCK_RECEIVEALL_YES,
- p->errbuf, PCAP_ERRBUF_SIZE);
- if (nread == -1)
+ /* Read the reply body */
+ if (rpcap_recv(pr->rmt_sockctrl, (char *)&netstats,
+ sizeof(struct rpcap_stats), &plen, p->errbuf) == -1)
goto error;
- totread += nread;
- if (mode == PCAP_STATS_STANDARD)
- {
- ps->ps_drop = ntohl(netstats.krnldrop);
- ps->ps_ifdrop = ntohl(netstats.ifdrop);
- ps->ps_recv = ntohl(netstats.ifrecv);
- }
- else
+ ps->ps_drop = ntohl(netstats.krnldrop);
+ ps->ps_ifdrop = ntohl(netstats.ifdrop);
+ ps->ps_recv = ntohl(netstats.ifrecv);
+#ifdef _WIN32
+ if (mode == PCAP_STATS_EX)
{
- ps->ps_capt = md->TotCapt;
- ps->ps_drop = ntohl(netstats.krnldrop);
- ps->ps_ifdrop = ntohl(netstats.ifdrop);
- ps->ps_netdrop = md->TotNetDrops;
- ps->ps_recv = ntohl(netstats.ifrecv);
+ ps->ps_capt = pr->TotCapt;
+ ps->ps_netdrop = pr->TotNetDrops;
ps->ps_sent = ntohl(netstats.svrcapt);
}
+#endif /* _WIN32 */
- /* Checks if all the data has been read; if not, discard the data in excess */
- if (totread != ntohl(header.plen))
- {
- if (sock_discard(md->rmt_sockctrl, ntohl(header.plen) - totread, NULL, 0) == 1)
- goto error;
- }
+ /* Discard the rest of the message. */
+ if (rpcap_discard(pr->rmt_sockctrl, plen, p->errbuf) == -1)
+ goto error;
return ps;
error:
- if (totread != ntohl(header.plen))
- sock_discard(md->rmt_sockctrl, ntohl(header.plen) - totread, NULL, 0);
+ /*
+ * Discard the rest of the message.
+ * We already reported an error; if this gets an error, just
+ * drive on.
+ */
+ (void)rpcap_discard(pr->rmt_sockctrl, plen, NULL);
return NULL;
}
-/* \ingroup remote_pri_func
- *
- * \brief It opens a remote adapter by opening an RPCAP connection and so on.
- *
- * This function does basically the job of pcap_open_live() for a remote interface.
- * In other words, we have a pcap_read for win32, which reads packets from NPF,
- * another for LINUX, and so on. Now, we have a pcap_opensource_remote() as well.
- * The difference, here, is the capture thread does not start until the
- * pcap_startcapture_remote() is called.
- *
- * This is because, in remote capture, we cannot start capturing data as soon ad the
- * 'open adapter' command is sent. Suppose the remote adapter is already overloaded;
- * if we start a capture (which, by default, has a NULL filter) the new traffic can
- * saturate the network.
- *
- * Instead, we want to "open" the adapter, then send a "start capture" command only
- * when we're ready to start the capture.
- * This funtion does this job: it sends a "open adapter" command (according to the
- * RPCAP protocol), but it does not start the capture.
+/*
+ * This function returns the entry in the list of active hosts for this
+ * active connection (active mode only), or NULL if there is no
+ * active connection or an error occurred. It is just for internal
+ * use.
*
- * Since the other libpcap functions do not share this way of life, we have to make
- * some dirty things in order to make everyting working.
+ * \param host: a string that keeps the host name of the host for which we
+ * want to get the socket ID for that active connection.
*
- * \param fp: A pointer to a pcap_t structure that has been previously created with
- * \ref pcap_create().
- * \param source: see pcap_open().
- * \param auth: see pcap_open().
+ * \param error: a pointer to an int that is set to 1 if an error occurred
+ * and 0 otherwise.
*
- * \return 0 in case of success, -1 otherwise. In case of success, the pcap_t pointer in fp can be
- * used as a parameter to the following calls (pcap_compile() and so on). In case of
- * problems, fp->errbuf contains a text explanation of error.
+ * \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).
*
- * \warning In case we call the pcap_compile() and the capture is not started, the filter
- * will be saved into the pcap_t structure, and it will be sent to the other host later
- * (when the pcap_startcapture_remote() is called).
+ * \return the entry for this host in the list of active connections
+ * if found, NULL if it's not found or there's an error.
*/
-int pcap_opensource_remote(pcap_t *fp, struct pcap_rmtauth *auth)
+static struct activehosts *
+rpcap_remoteact_getsock(const char *host, int *error, char *errbuf)
{
- char host[PCAP_BUF_SIZE], ctrlport[PCAP_BUF_SIZE], iface[PCAP_BUF_SIZE];
-
- 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 */
- uint32 totread = 0; /* number of bytes of the payload read from the socket */
- int nread;
- int retval; /* store the return value of the functions */
- int active = 0; /* '1' if we're in active mode */
-
- /* socket-related variables */
- struct addrinfo hints; /* temp, needed to open a socket connection */
- struct addrinfo *addrinfo; /* temp, needed to open a socket connection */
- SOCKET sockctrl = 0; /* socket descriptor of the control connection */
-
- /* RPCAP-related variables */
- struct rpcap_header header; /* header of the RPCAP packet */
- struct rpcap_openreply openreply; /* open reply message */
-
- struct pcap_md *md; /* structure used when doing a remote live capture */
-
- md = (struct pcap_md *) ((u_char*)fp->priv + sizeof(struct pcap_win));
-
-
- /*
- * 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(fp->opt.device, &retval, host, ctrlport, iface, fp->errbuf) == -1)
- return -1;
-
- if (retval != PCAP_SRC_IFREMOTE)
- {
- pcap_snprintf(fp->errbuf, PCAP_ERRBUF_SIZE, "This function is able to open only remote interfaces");
- return -1;
- }
+ struct activehosts *temp; /* temp var needed to scan the host list chain */
+ struct addrinfo hints, *addrinfo, *ai_next; /* temp var needed to translate between hostname to its address */
+ int retval;
+ /* retrieve the network address corresponding to 'host' */
addrinfo = NULL;
+ memset(&hints, 0, sizeof(struct addrinfo));
+ hints.ai_family = PF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
- /*
- * 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(fp->errbuf, PCAP_ERRBUF_SIZE) == -1)
- return -1;
-
- sockctrl = rpcap_remoteact_getsock(host, &active, fp->errbuf);
- if (sockctrl == INVALID_SOCKET)
- return -1;
-
- if (!active)
+ retval = getaddrinfo(host, "0", &hints, &addrinfo);
+ if (retval != 0)
{
- /*
- * 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 == NULL) || (ctrlport[0] == 0))
- {
- /* the user chose not to specify the port */
- if (sock_initaddress(host, RPCAP_DEFAULT_NETPORT, &hints, &addrinfo, fp->errbuf, PCAP_ERRBUF_SIZE) == -1)
- return -1;
- }
- else
- {
- /* the user chose not to specify the port */
- if (sock_initaddress(host, ctrlport, &hints, &addrinfo, fp->errbuf, PCAP_ERRBUF_SIZE) == -1)
- return -1;
- }
-
- if ((sockctrl = sock_open(addrinfo, SOCKOPEN_CLIENT, 0, fp->errbuf, PCAP_ERRBUF_SIZE)) == INVALID_SOCKET)
- goto error;
-
- freeaddrinfo(addrinfo);
- addrinfo = NULL;
-
- if (rpcap_sendauth(sockctrl, auth, fp->errbuf) == -1)
- goto error;
+ pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "getaddrinfo() %s",
+ gai_strerror(retval));
+ *error = 1;
+ return NULL;
}
- /*
- * Now it's time to start playing with the RPCAP protocol
- * RPCAP open command: create the request message
- */
- if (sock_bufferize(NULL, sizeof(struct rpcap_header), NULL,
- &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, fp->errbuf, PCAP_ERRBUF_SIZE))
- goto error;
-
- rpcap_createhdr((struct rpcap_header *) sendbuf, RPCAP_MSG_OPEN_REQ, 0, (uint32) strlen(iface));
-
- if (sock_bufferize(iface, (int) strlen(iface), sendbuf, &sendbufidx,
- RPCAP_NETBUF_SIZE, SOCKBUF_BUFFERIZE, fp->errbuf, PCAP_ERRBUF_SIZE))
- goto error;
-
- if (sock_send(sockctrl, sendbuf, sendbufidx, fp->errbuf, PCAP_ERRBUF_SIZE))
- goto error;
-
- /* Receive the RPCAP open reply message */
- if (sock_recv(sockctrl, (char *)&header, sizeof(struct rpcap_header), SOCK_RECEIVEALL_YES, fp->errbuf, PCAP_ERRBUF_SIZE) == -1)
- goto error;
-
- /* Checks if the message is correct */
- retval = rpcap_checkmsg(fp->errbuf, sockctrl, &header, RPCAP_MSG_OPEN_REPLY, RPCAP_MSG_ERROR, 0);
+ temp = activeHosts;
- if (retval != RPCAP_MSG_OPEN_REPLY) /* the message is not the one expected */
+ while (temp)
{
- switch (retval)
+ ai_next = addrinfo;
+ while (ai_next)
{
- case -3: /* Unrecoverable network error */
- case -2: /* The other endpoint send a message that is not allowed here */
- case -1: /* The other endpoint has a version number that is not compatible with our */
- goto error;
-
- case RPCAP_MSG_ERROR: /* The other endpoint reported an error */
- /* Update totread, since the rpcap_checkmsg() already purged the buffer */
- totread = ntohl(header.plen);
- /* Do nothing; just exit; the error code is already into the errbuf */
- goto error;
+ if (sock_cmpaddr(&temp->host, (struct sockaddr_storage *) ai_next->ai_addr) == 0)
+ {
+ *error = 0;
+ freeaddrinfo(addrinfo);
+ return temp;
+ }
- default:
- pcap_snprintf(fp->errbuf, PCAP_ERRBUF_SIZE, "Internal error");
- goto error;
+ ai_next = ai_next->ai_next;
}
+ temp = temp->next;
}
- nread = sock_recv(sockctrl, (char *)&openreply,
- sizeof(struct rpcap_openreply), SOCK_RECEIVEALL_YES,
- fp->errbuf, PCAP_ERRBUF_SIZE);
- if (nread == -1)
- goto error;
- totread += nread;
-
- /* Set proper fields into the pcap_t struct */
- fp->linktype = ntohl(openreply.linktype);
- fp->tzoff = ntohl(openreply.tzoff);
- md->rmt_sockctrl = sockctrl;
- md->rmt_clientside = 1;
-
-
- /* This code is duplicated from the end of this function */
- fp->read_op = pcap_read_remote;
- fp->setfilter_op = pcap_setfilter_remote;
- fp->getnonblock_op = NULL; /* This is not implemented in remote capture */
- fp->setnonblock_op = NULL; /* This is not implemented in remote capture */
- fp->stats_op = pcap_stats_remote;
-#ifdef _WIN32
- fp->stats_ex_op = pcap_stats_ex_remote;
-#endif
- fp->cleanup_op = pcap_cleanup_remote;
-
- /* Checks if all the data has been read; if not, discard the data in excess */
- if (totread != ntohl(header.plen))
- {
- if (sock_discard(sockctrl, ntohl(header.plen) - totread, NULL, 0) == 1)
- goto error;
- }
- return 0;
-
-error:
- /*
- * When the connection has been established, we have to close it. So, at the
- * beginning of this function, if an error occur we return immediately with
- * a return NULL; when the connection is established, we have to come here
- * ('goto error;') in order to close everything properly.
- *
- * Checks if all the data has been read; if not, discard the data in excess
- */
- if (totread != ntohl(header.plen))
- sock_discard(sockctrl, ntohl(header.plen) - totread, NULL, 0);
-
if (addrinfo)
freeaddrinfo(addrinfo);
- if (!active)
- sock_close(sockctrl, NULL, 0);
-
- return -1;
+ /*
+ * The host for which you want to get the socket ID does not have an
+ * active connection.
+ */
+ *error = 0;
+ return NULL;
}
-/* \ingroup remote_pri_func
- *
- * \brief It starts a remote capture.
- *
- * This function is requires since the RPCAP protocol decouples the 'open' from the
- * 'start capture' functions.
- * This function takes all the parameters needed (which have been stored into the pcap_t structure)
- * and sends them to the server.
- * If everything is fine, it creates a new child thread that reads data from the network
- * and puts data it into the user buffer.
- * The pcap_read() will read data from the user buffer, as usual.
+/*
+ * This function starts a remote capture.
*
- * The remote capture acts like a new "kernel", which puts packets directly into
- * the buffer pointed by pcap_t.
- * In fact, this function does not rely on a kernel that reads packets and put them
- * into the user buffer; it has to do that on its own.
+ * This function is required since the RPCAP protocol decouples the 'open'
+ * from the 'start capture' functions.
+ * This function takes all the parameters needed (which have been stored
+ * into the pcap_t structure) and sends them to the server.
*
* \param fp: the pcap_t descriptor of the device currently open.
*
- * \return '0' if everything is fine, '-1' otherwise. The error message (if one)
- * is returned into the 'errbuf' field of the pcap_t structure.
+ * \return '0' if everything is fine, '-1' otherwise. The error message
+ * (if one) is returned into the 'errbuf' field of the pcap_t structure.
*/
-int pcap_startcapture_remote(pcap_t *fp)
+static int pcap_startcapture_remote(pcap_t *fp)
{
+ struct pcap_rpcap *pr = fp->priv; /* structure used when doing a remote live capture */
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 */
- char portdata[PCAP_BUF_SIZE]; /* temp variable needed to keep the network port for the the data connection */
- uint32 totread = 0; /* number of bytes of the payload read from the socket */
- int nread;
- int retval; /* store the return value of the functions */
+ char portdata[PCAP_BUF_SIZE]; /* temp variable needed to keep the network port for the data connection */
+ uint32 plen;
int active = 0; /* '1' if we're in active mode */
struct activehosts *temp; /* temp var needed to scan the host list chain, to detect if we're in active mode */
char host[INET6_ADDRSTRLEN + 1]; /* numeric name of the other host */
@@ -928,12 +1032,10 @@ int pcap_startcapture_remote(pcap_t *fp)
struct rpcap_startcapreply startcapreply; /* start capture reply message */
/* Variables related to the buffer setting */
- int res, itemp;
+ int res;
+ socklen_t itemp;
int sockbufsize = 0;
-
- struct pcap_md *md; /* structure used when doing a remote live capture */
-
- md = (struct pcap_md *) ((u_char*)fp->priv + sizeof(struct pcap_win));
+ uint32 server_sockbufsize;
/*
* Let's check if sampling has been required.
@@ -942,12 +1044,11 @@ int pcap_startcapture_remote(pcap_t *fp)
if (pcap_setsampling_remote(fp) != 0)
return -1;
-
/* detect if we're in active mode */
temp = activeHosts;
while (temp)
{
- if (temp->sockctrl == md->rmt_sockctrl)
+ if (temp->sockctrl == pr->rmt_sockctrl)
{
active = 1;
break;
@@ -965,10 +1066,10 @@ int pcap_startcapture_remote(pcap_t *fp)
* so I would have to call getpeername() anyway
*/
saddrlen = sizeof(struct sockaddr_storage);
- if (getpeername(md->rmt_sockctrl, (struct sockaddr *) &saddr, &saddrlen) == -1)
+ if (getpeername(pr->rmt_sockctrl, (struct sockaddr *) &saddr, &saddrlen) == -1)
{
sock_geterror("getsockname(): ", fp->errbuf, PCAP_ERRBUF_SIZE);
- goto error;
+ goto error_nodiscard;
}
ai_family = ((struct sockaddr_storage *) &saddr)->ss_family;
@@ -977,7 +1078,7 @@ int pcap_startcapture_remote(pcap_t *fp)
sizeof(host), NULL, 0, NI_NUMERICHOST))
{
sock_geterror("getnameinfo(): ", fp->errbuf, PCAP_ERRBUF_SIZE);
- goto error;
+ goto error_nodiscard;
}
/*
@@ -985,7 +1086,7 @@ int pcap_startcapture_remote(pcap_t *fp)
* - we're using TCP, and the user wants us to be in active mode
* - we're using UDP
*/
- if ((active) || (md->rmt_flags & PCAP_OPENFLAG_DATATX_UDP))
+ if ((active) || (pr->rmt_flags & PCAP_OPENFLAG_DATATX_UDP))
{
/*
* We have to create a new socket to receive packets
@@ -995,16 +1096,16 @@ int pcap_startcapture_remote(pcap_t *fp)
memset(&hints, 0, sizeof(struct addrinfo));
/* TEMP addrinfo is NULL in case of active */
hints.ai_family = ai_family; /* Use the same address family of the control socket */
- hints.ai_socktype = (md->rmt_flags & PCAP_OPENFLAG_DATATX_UDP) ? SOCK_DGRAM : SOCK_STREAM;
+ hints.ai_socktype = (pr->rmt_flags & PCAP_OPENFLAG_DATATX_UDP) ? SOCK_DGRAM : SOCK_STREAM;
hints.ai_flags = AI_PASSIVE; /* Data connection is opened by the server toward the client */
/* Let's the server pick up a free network port for us */
if (sock_initaddress(NULL, "0", &hints, &addrinfo, fp->errbuf, PCAP_ERRBUF_SIZE) == -1)
- goto error;
+ goto error_nodiscard;
if ((sockdata = sock_open(addrinfo, SOCKOPEN_SERVER,
1 /* max 1 connection in queue */, fp->errbuf, PCAP_ERRBUF_SIZE)) == INVALID_SOCKET)
- goto error;
+ goto error_nodiscard;
/* addrinfo is no longer used */
freeaddrinfo(addrinfo);
@@ -1015,7 +1116,7 @@ int pcap_startcapture_remote(pcap_t *fp)
if (getsockname(sockdata, (struct sockaddr *) &saddr, &saddrlen) == -1)
{
sock_geterror("getsockname(): ", fp->errbuf, PCAP_ERRBUF_SIZE);
- goto error;
+ goto error_nodiscard;
}
/* Get the local port the system picked up */
@@ -1023,7 +1124,7 @@ int pcap_startcapture_remote(pcap_t *fp)
0, portdata, sizeof(portdata), NI_NUMERICSERV))
{
sock_geterror("getnameinfo(): ", fp->errbuf, PCAP_ERRBUF_SIZE);
- goto error;
+ goto error_nodiscard;
}
}
@@ -1033,17 +1134,18 @@ int pcap_startcapture_remote(pcap_t *fp)
*/
if (sock_bufferize(NULL, sizeof(struct rpcap_header), NULL,
&sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, fp->errbuf, PCAP_ERRBUF_SIZE))
- goto error;
+ goto error_nodiscard;
- rpcap_createhdr((struct rpcap_header *) sendbuf, RPCAP_MSG_STARTCAP_REQ, 0,
- sizeof(struct rpcap_startcapreq) + sizeof(struct rpcap_filter) + fp->fcode.bf_len * sizeof(struct rpcap_filterbpf_insn));
+ rpcap_createhdr((struct rpcap_header *) sendbuf,
+ pr->protocol_version, RPCAP_MSG_STARTCAP_REQ, 0,
+ sizeof(struct rpcap_startcapreq) + sizeof(struct rpcap_filter) + fp->fcode.bf_len * sizeof(struct rpcap_filterbpf_insn));
/* Fill the structure needed to open an adapter remotely */
startcapreq = (struct rpcap_startcapreq *) &sendbuf[sendbufidx];
if (sock_bufferize(NULL, sizeof(struct rpcap_startcapreq), NULL,
&sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, fp->errbuf, PCAP_ERRBUF_SIZE))
- goto error;
+ goto error_nodiscard;
memset(startcapreq, 0, sizeof(struct rpcap_startcapreq));
@@ -1052,7 +1154,7 @@ int pcap_startcapture_remote(pcap_t *fp)
startcapreq->read_timeout = htonl(fp->opt.timeout);
/* portdata on the openreq is meaningful only if we're in active mode */
- if ((active) || (md->rmt_flags & PCAP_OPENFLAG_DATATX_UDP))
+ if ((active) || (pr->rmt_flags & PCAP_OPENFLAG_DATATX_UDP))
{
sscanf(portdata, "%d", (int *)&(startcapreq->portdata)); /* cast to avoid a compiler warning */
startcapreq->portdata = htons(startcapreq->portdata);
@@ -1061,9 +1163,9 @@ int pcap_startcapture_remote(pcap_t *fp)
startcapreq->snaplen = htonl(fp->snapshot);
startcapreq->flags = 0;
- if (md->rmt_flags & PCAP_OPENFLAG_PROMISCUOUS)
+ if (pr->rmt_flags & PCAP_OPENFLAG_PROMISCUOUS)
startcapreq->flags |= RPCAP_STARTCAPREQ_FLAG_PROMISC;
- if (md->rmt_flags & PCAP_OPENFLAG_DATATX_UDP)
+ if (pr->rmt_flags & PCAP_OPENFLAG_DATATX_UDP)
startcapreq->flags |= RPCAP_STARTCAPREQ_FLAG_DGRAM;
if (active)
startcapreq->flags |= RPCAP_STARTCAPREQ_FLAG_SERVEROPEN;
@@ -1072,46 +1174,22 @@ int pcap_startcapture_remote(pcap_t *fp)
/* Pack the capture filter */
if (pcap_pack_bpffilter(fp, &sendbuf[sendbufidx], &sendbufidx, &fp->fcode))
- goto error;
+ goto error_nodiscard;
- if (sock_send(md->rmt_sockctrl, sendbuf, sendbufidx, fp->errbuf, PCAP_ERRBUF_SIZE))
- goto error;
+ if (sock_send(pr->rmt_sockctrl, sendbuf, sendbufidx, fp->errbuf,
+ PCAP_ERRBUF_SIZE) < 0)
+ goto error_nodiscard;
+ /* Receive and process the reply message header. */
+ if (rpcap_process_msg_header(pr->rmt_sockctrl, pr->protocol_version,
+ RPCAP_MSG_STARTCAP_REQ, &header, fp->errbuf) == -1)
+ goto error_nodiscard;
- /* Receive the RPCAP start capture reply message */
- if (sock_recv(md->rmt_sockctrl, (char *)&header, sizeof(struct rpcap_header), SOCK_RECEIVEALL_YES, fp->errbuf, PCAP_ERRBUF_SIZE) == -1)
- goto error;
+ plen = header.plen;
- /* Checks if the message is correct */
- retval = rpcap_checkmsg(fp->errbuf, md->rmt_sockctrl, &header, RPCAP_MSG_STARTCAP_REPLY, RPCAP_MSG_ERROR, 0);
-
- if (retval != RPCAP_MSG_STARTCAP_REPLY) /* the message is not the one expected */
- {
- switch (retval)
- {
- case -3: /* Unrecoverable network error */
- case -2: /* The other endpoint send a message that is not allowed here */
- case -1: /* The other endpoint has a version number that is not compatible with our */
- goto error;
-
- case RPCAP_MSG_ERROR: /* The other endpoint reported an error */
- /* Update totread, since the rpcap_checkmsg() already purged the buffer */
- totread = ntohl(header.plen);
- /* Do nothing; just exit; the error code is already into the errbuf */
- goto error;
-
- default:
- pcap_snprintf(fp->errbuf, PCAP_ERRBUF_SIZE, "Internal error");
- goto error;
- }
- }
-
- nread = sock_recv(md->rmt_sockctrl, (char *)&startcapreply,
- sizeof(struct rpcap_startcapreply), SOCK_RECEIVEALL_YES,
- fp->errbuf, PCAP_ERRBUF_SIZE);
- if (nread == -1)
+ if (rpcap_recv(pr->rmt_sockctrl, (char *)&startcapreply,
+ sizeof(struct rpcap_startcapreply), &plen, fp->errbuf) == -1)
goto error;
- totread += nread;
/*
* In case of UDP data stream, the connection is always opened by the daemon
@@ -1124,14 +1202,13 @@ int pcap_startcapture_remote(pcap_t *fp)
* to tell the port we're using to the remote side; in case we're accepting a TCP
* connection, we have to wait this info from the remote side.
*/
-
- if (!(md->rmt_flags & PCAP_OPENFLAG_DATATX_UDP))
+ if (!(pr->rmt_flags & PCAP_OPENFLAG_DATATX_UDP))
{
if (!active)
{
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = ai_family; /* Use the same address family of the control socket */
- hints.ai_socktype = (md->rmt_flags & PCAP_OPENFLAG_DATATX_UDP) ? SOCK_DGRAM : SOCK_STREAM;
+ hints.ai_socktype = (pr->rmt_flags & PCAP_OPENFLAG_DATATX_UDP) ? SOCK_DGRAM : SOCK_STREAM;
pcap_snprintf(portdata, PCAP_BUF_SIZE, "%d", ntohs(startcapreply.portdata));
/* Let's the server pick up a free network port for us */
@@ -1154,7 +1231,7 @@ int pcap_startcapture_remote(pcap_t *fp)
socktemp = accept(sockdata, (struct sockaddr *) &saddr, &saddrlen);
- if (socktemp == -1)
+ if (socktemp == INVALID_SOCKET)
{
sock_geterror("accept(): ", fp->errbuf, PCAP_ERRBUF_SIZE);
goto error;
@@ -1167,11 +1244,14 @@ int pcap_startcapture_remote(pcap_t *fp)
}
/* Let's save the socket of the data connection */
- md->rmt_sockdata = sockdata;
+ pr->rmt_sockdata = sockdata;
- /* Allocates WinPcap/libpcap user buffer, which is a socket buffer in case of a remote capture */
- /* It has the same size of the one used on the other side of the connection */
- fp->bufsize = ntohl(startcapreply.bufsize);
+ /*
+ * Set the size of the socket buffer for the data socket.
+ * It has the same size as the local capture buffer used
+ * on the other side of the connection.
+ */
+ server_sockbufsize = ntohl(startcapreply.bufsize);
/* Let's get the actual size of the socket buffer */
itemp = sizeof(sockbufsize);
@@ -1180,66 +1260,81 @@ int pcap_startcapture_remote(pcap_t *fp)
if (res == -1)
{
sock_geterror("pcap_startcapture_remote()", fp->errbuf, PCAP_ERRBUF_SIZE);
- SOCK_ASSERT(fp->errbuf, 1);
+ SOCK_DEBUG_MESSAGE(fp->errbuf);
}
/*
- * Warning: on some kernels (e.g. Linux), the size of the user buffer does not take
- * into account the pcap_header and such, and it is set equal to the snaplen.
- * In my view, this is wrong (the meaning of the bufsize became a bit strange).
- * So, here bufsize is the whole size of the user buffer.
- * In case the bufsize returned is too small, let's adjust it accordingly.
+ * Warning: on some kernels (e.g. Linux), the size of the user
+ * buffer does not take into account the pcap_header and such,
+ * and it is set equal to the snaplen.
+ *
+ * In my view, this is wrong (the meaning of the bufsize became
+ * a bit strange). So, here bufsize is the whole size of the
+ * user buffer. In case the bufsize returned is too small,
+ * let's adjust it accordingly.
*/
- if (fp->bufsize <= (u_int) fp->snapshot)
- fp->bufsize += sizeof(struct pcap_pkthdr);
+ if (server_sockbufsize <= (u_int) fp->snapshot)
+ server_sockbufsize += sizeof(struct pcap_pkthdr);
/* if the current socket buffer is smaller than the desired one */
- if ((u_int) sockbufsize < fp->bufsize)
+ if ((u_int) sockbufsize < server_sockbufsize)
{
- /* Loop until the buffer size is OK or the original socket buffer size is larger than this one */
- while (1)
+ /*
+ * Loop until the buffer size is OK or the original
+ * socket buffer size is larger than this one.
+ */
+ for (;;)
{
- res = setsockopt(sockdata, SOL_SOCKET, SO_RCVBUF, (char *)&(fp->bufsize), sizeof(fp->bufsize));
+ res = setsockopt(sockdata, SOL_SOCKET, SO_RCVBUF,
+ (char *)&(server_sockbufsize),
+ sizeof(server_sockbufsize));
if (res == 0)
break;
/*
- * If something goes wrong, half the buffer size (checking that it does not become smaller than
- * the current one)
+ * If something goes wrong, halve the buffer size
+ * (checking that it does not become smaller than
+ * the current one).
*/
- fp->bufsize /= 2;
+ server_sockbufsize /= 2;
- if ((u_int) sockbufsize >= fp->bufsize)
+ if ((u_int) sockbufsize >= server_sockbufsize)
{
- fp->bufsize = sockbufsize;
+ server_sockbufsize = sockbufsize;
break;
}
}
}
/*
- * Let's allocate the packet; this is required in order to put the packet somewhere when
- * extracting data from the socket
- * Since buffering has already been done in the socket buffer, here we need just a buffer,
- * whose size is equal to the pcap header plus the snapshot length
+ * Let's allocate the packet; this is required in order to put
+ * the packet somewhere when extracting data from the socket.
+ * Since buffering has already been done in the socket buffer,
+ * here we need just a buffer whose size is equal to the
+ * largest possible packet message for the snapshot size,
+ * namely the length of the message header plus the length
+ * of the packet header plus the snapshot length.
*/
- fp->bufsize = fp->snapshot + sizeof(struct pcap_pkthdr);
+ fp->bufsize = sizeof(struct rpcap_header) + sizeof(struct rpcap_pkthdr) + fp->snapshot;
fp->buffer = (u_char *)malloc(fp->bufsize);
if (fp->buffer == NULL)
{
- pcap_snprintf(fp->errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(fp->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "malloc");
goto error;
}
+ /*
+ * The buffer is currently empty.
+ */
+ fp->bp = fp->buffer;
+ fp->cc = 0;
- /* Checks if all the data has been read; if not, discard the data in excess */
- if (totread != ntohl(header.plen))
- {
- if (sock_discard(md->rmt_sockctrl, ntohl(header.plen) - totread, NULL, 0) == 1)
- goto error;
- }
+ /* Discard the rest of the message. */
+ if (rpcap_discard(pr->rmt_sockctrl, plen, fp->errbuf) == -1)
+ goto error;
/*
* In case the user does not want to capture RPCAP packets, let's update the filter
@@ -1247,22 +1342,22 @@ int pcap_startcapture_remote(pcap_t *fp)
* because when we generate the 'start capture' we do not know (yet) all the ports
* we're currently using.
*/
- if (md->rmt_flags & PCAP_OPENFLAG_NOCAPTURE_RPCAP)
+ if (pr->rmt_flags & PCAP_OPENFLAG_NOCAPTURE_RPCAP)
{
struct bpf_program fcode;
if (pcap_createfilter_norpcappkt(fp, &fcode) == -1)
goto error;
- /* We cannot use 'pcap_setfilter_remote' because formally the capture has not been started yet */
- /* (the 'fp->rmt_capstarted' variable will be updated some lines below) */
+ /* We cannot use 'pcap_setfilter_rpcap' because formally the capture has not been started yet */
+ /* (the 'pr->rmt_capstarted' variable will be updated some lines below) */
if (pcap_updatefilter_remote(fp, &fcode) == -1)
goto error;
pcap_freecode(&fcode);
}
- md->rmt_capstarted = 1;
+ pr->rmt_capstarted = 1;
return 0;
error:
@@ -1271,42 +1366,52 @@ error:
* beginning of this function, if an error occur we return immediately with
* a return NULL; when the connection is established, we have to come here
* ('goto error;') in order to close everything properly.
- *
- * Checks if all the data has been read; if not, discard the data in excess
*/
- if (totread != ntohl(header.plen))
- sock_discard(md->rmt_sockctrl, ntohl(header.plen) - totread, NULL, 0);
+ /*
+ * Discard the rest of the message.
+ * We already reported an error; if this gets an error, just
+ * drive on.
+ */
+ (void)rpcap_discard(pr->rmt_sockctrl, plen, NULL);
+
+error_nodiscard:
if ((sockdata) && (sockdata != -1)) /* we can be here because sockdata said 'error' */
sock_close(sockdata, NULL, 0);
if (!active)
- sock_close(md->rmt_sockctrl, NULL, 0);
+ sock_close(pr->rmt_sockctrl, NULL, 0);
+
+ if (addrinfo != NULL)
+ freeaddrinfo(addrinfo);
/*
* We do not have to call pcap_close() here, because this function is always called
* by the user in case something bad happens
*/
- // if (fp)
- // {
- // pcap_close(fp);
- // fp= NULL;
- // }
+#if 0
+ if (fp)
+ {
+ pcap_close(fp);
+ fp= NULL;
+ }
+#endif
return -1;
}
/*
- * \brief Takes a bpf program and sends it to the other host.
+ * This function takes a bpf program and sends it to the other host.
*
* This function can be called in two cases:
- * - the pcap_startcapture() is called (we have to send the filter along with
- * the 'start capture' command)
- * - we want to udpate the filter during a capture (i.e. the pcap_setfilter()
- * is called when the capture is still on)
+ * - pcap_startcapture_remote() is called (we have to send the filter
+ * along with the 'start capture' command)
+ * - we want to udpate the filter during a capture (i.e. pcap_setfilter()
+ * after the capture has been started)
*
- * This function serializes the filter into the sending buffer ('sendbuf', passed
- * as a parameter) and return back. It does not send anything on the network.
+ * This function serializes the filter into the sending buffer ('sendbuf',
+ * passed as a parameter) and return back. It does not send anything on
+ * the network.
*
* \param fp: the pcap_t descriptor of the device currently opened.
*
@@ -1327,7 +1432,6 @@ static int pcap_pack_bpffilter(pcap_t *fp, char *sendbuf, int *sendbufidx, struc
struct bpf_program fake_prog; /* To be used just in case the user forgot to set a filter */
unsigned int i;
-
if (prog->bf_len == 0) /* No filters have been specified; so, let's apply a "fake" filter */
{
if (pcap_compile(fp, &fake_prog, NULL /* buffer */, 1, 0) == -1)
@@ -1366,99 +1470,107 @@ static int pcap_pack_bpffilter(pcap_t *fp, char *sendbuf, int *sendbufidx, struc
return 0;
}
-/* \ingroup remote_pri_func
- *
- * \brief Update a filter on a remote host.
+/*
+ * This function updates a filter on a remote host.
*
- * This function is called when the user wants to update a filter.
- * In case we're capturing from the network, it sends the filter to the other peer.
- * This function is *not* called automatically when the user calls the pcap_setfilter().
+ * It is called when the user wants to update a filter.
+ * In case we're capturing from the network, it sends the filter to our
+ * peer.
+ * This function is *not* called automatically when the user calls
+ * pcap_setfilter().
* There will be two cases:
- * - the capture is already on: in this case, pcap_setfilter() calls pcap_updatefilter_remote()
- * - the capture has not started yet: in this case, pcap_setfilter() stores the filter into
- * the pcap_t structure, and then the filter is sent with the pcap_startcap().
- *
- * Parameters and return values are exactly the same of the pcap_setfilter().
- *
- * \warning This function *does not* clear the packet currently into the buffers. Therefore,
- * the user has to expect to receive some packets that are related to the previous filter.
- * If you want to discard all the packets before applying a new filter, you have to close
- * the current capture session and start a new one.
+ * - the capture has been started: in this case, pcap_setfilter_rpcap()
+ * calls pcap_updatefilter_remote()
+ * - the capture has not started yet: in this case, pcap_setfilter_rpcap()
+ * stores the filter into the pcap_t structure, and then the filter is
+ * sent with pcap_startcap().
+ *
+ * WARNING This function *does not* clear the packet currently into the
+ * buffers. Therefore, the user has to expect to receive some packets
+ * that are related to the previous filter. If you want to discard all
+ * the packets before applying a new filter, you have to close the
+ * current capture session and start a new one.
+ *
+ * XXX - we really should have pcap_setfilter() always discard packets
+ * received with the old filter, and have a separate pcap_setfilter_noflush()
+ * function that doesn't discard any packets.
*/
static int pcap_updatefilter_remote(pcap_t *fp, struct bpf_program *prog)
{
- int retval; /* general variable used to keep the return value of other functions */
- 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 */
+ struct pcap_rpcap *pr = fp->priv; /* structure used when doing a remote live capture */
+ 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 */
struct rpcap_header header; /* To keep the reply message */
- struct pcap_md *md; /* structure used when doing a remote live capture */
-
- md = (struct pcap_md *) ((u_char*)fp->priv + sizeof(struct pcap_win));
-
if (sock_bufferize(NULL, sizeof(struct rpcap_header), NULL, &sendbufidx,
RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, fp->errbuf, PCAP_ERRBUF_SIZE))
return -1;
- rpcap_createhdr((struct rpcap_header *) sendbuf, RPCAP_MSG_UPDATEFILTER_REQ, 0,
- sizeof(struct rpcap_filter) + prog->bf_len * sizeof(struct rpcap_filterbpf_insn));
+ rpcap_createhdr((struct rpcap_header *) sendbuf,
+ pr->protocol_version, RPCAP_MSG_UPDATEFILTER_REQ, 0,
+ sizeof(struct rpcap_filter) + prog->bf_len * sizeof(struct rpcap_filterbpf_insn));
if (pcap_pack_bpffilter(fp, &sendbuf[sendbufidx], &sendbufidx, prog))
return -1;
- if (sock_send(md->rmt_sockctrl, sendbuf, sendbufidx, fp->errbuf, PCAP_ERRBUF_SIZE))
+ if (sock_send(pr->rmt_sockctrl, sendbuf, sendbufidx, fp->errbuf,
+ PCAP_ERRBUF_SIZE) < 0)
return -1;
- /* Waits for the answer */
- if (sock_recv(md->rmt_sockctrl, (char *)&header, sizeof(struct rpcap_header), SOCK_RECEIVEALL_YES, fp->errbuf, PCAP_ERRBUF_SIZE) == -1)
+ /* Receive and process the reply message header. */
+ if (rpcap_process_msg_header(pr->rmt_sockctrl, pr->protocol_version,
+ RPCAP_MSG_UPDATEFILTER_REQ, &header, fp->errbuf) == -1)
return -1;
- /* Checks if the message is correct */
- retval = rpcap_checkmsg(fp->errbuf, md->rmt_sockctrl, &header, RPCAP_MSG_UPDATEFILTER_REPLY, 0);
+ /*
+ * It shouldn't have any contents; discard it if it does.
+ */
+ if (rpcap_discard(pr->rmt_sockctrl, header.plen, fp->errbuf) == -1)
+ return -1;
- if (retval != RPCAP_MSG_UPDATEFILTER_REPLY) /* the message is not the one expected */
- {
- switch (retval)
- {
- case -3: /* Unrecoverable network error */
- case -2: /* The other endpoint sent a message that is not allowed here */
- case -1: /* The other endpoint has a version number that is not compatible with our */
- /* Do nothing; just exit from here; the error code is already into the errbuf */
- return -1;
+ return 0;
+}
- default:
- SOCK_ASSERT("Internal error", 0);
- return -1;
- }
- }
+static void
+pcap_save_current_filter_rpcap(pcap_t *fp, const char *filter)
+{
+ struct pcap_rpcap *pr = fp->priv; /* structure used when doing a remote live capture */
- if (ntohl(header.plen) != 0) /* the message has an unexpected size */
+ /*
+ * Check if:
+ * - We are on an remote capture
+ * - we do not want to capture RPCAP traffic
+ *
+ * If so, we have to save the current filter, because we have to
+ * add some piece of stuff later
+ */
+ if (pr->rmt_clientside &&
+ (pr->rmt_flags & PCAP_OPENFLAG_NOCAPTURE_RPCAP))
{
- if (sock_discard(md->rmt_sockctrl, ntohl(header.plen), fp->errbuf, PCAP_ERRBUF_SIZE) == -1)
- return -1;
- }
+ if (pr->currentfilter)
+ free(pr->currentfilter);
- return 0;
+ if (filter == NULL)
+ filter = "";
+
+ pr->currentfilter = strdup(filter);
+ }
}
/*
- * \ingroup remote_pri_func
- *
- * \brief Send a filter to a remote host.
+ * This function sends a filter to a remote host.
*
* This function is called when the user wants to set a filter.
- * In case we're capturing from the network, it sends the filter to the other peer.
- * This function is called automatically when the user calls the pcap_setfilter().
+ * It sends the filter to our peer.
+ * This function is called automatically when the user calls pcap_setfilter().
*
- * Parameters and return values are exactly the same of the pcap_setfilter().
+ * Parameters and return values are exactly the same of pcap_setfilter().
*/
-static int pcap_setfilter_remote(pcap_t *fp, struct bpf_program *prog)
+static int pcap_setfilter_rpcap(pcap_t *fp, struct bpf_program *prog)
{
- struct pcap_md *md; /* structure used when doing a remote live capture */
-
- md = (struct pcap_md *) ((u_char*)fp->priv + sizeof(struct pcap_win));
+ struct pcap_rpcap *pr = fp->priv; /* structure used when doing a remote live capture */
- if (!md->rmt_capstarted)
+ if (!pr->rmt_capstarted)
{
/* copy filter into the pcap_t structure */
if (install_bpf_program(fp, prog) == -1)
@@ -1474,9 +1586,8 @@ static int pcap_setfilter_remote(pcap_t *fp, struct bpf_program *prog)
}
/*
- * \ingroup remote_pri_func
- *
- * \brief Update the current filter in order not to capture rpcap packets.
+ * This function updates the current filter in order not to capture rpcap
+ * packets.
*
* This function is called *only* when the user wants exclude RPCAP packets
* related to the current session from the captured packets.
@@ -1486,13 +1597,11 @@ static int pcap_setfilter_remote(pcap_t *fp, struct bpf_program *prog)
*/
static int pcap_createfilter_norpcappkt(pcap_t *fp, struct bpf_program *prog)
{
+ struct pcap_rpcap *pr = fp->priv; /* structure used when doing a remote live capture */
int RetVal = 0;
- struct pcap_md *md; /* structure used when doing a remote live capture */
-
- md = (struct pcap_md *) ((u_char*)fp->priv + sizeof(struct pcap_win));
/* We do not want to capture our RPCAP traffic. So, let's update the filter */
- if (md->rmt_flags & PCAP_OPENFLAG_NOCAPTURE_RPCAP)
+ if (pr->rmt_flags & PCAP_OPENFLAG_NOCAPTURE_RPCAP)
{
struct sockaddr_storage saddr; /* temp, needed to retrieve the network data port chosen on the local machine */
socklen_t saddrlen; /* temp, needed to retrieve the network data port chosen on the local machine */
@@ -1505,9 +1614,9 @@ static int pcap_createfilter_norpcappkt(pcap_t *fp, struct bpf_program *prog)
const int newstringsize = 1024;
size_t currentfiltersize;
- /* Get the name/port of the other peer */
+ /* Get the name/port of our peer */
saddrlen = sizeof(struct sockaddr_storage);
- if (getpeername(md->rmt_sockctrl, (struct sockaddr *) &saddr, &saddrlen) == -1)
+ if (getpeername(pr->rmt_sockctrl, (struct sockaddr *) &saddr, &saddrlen) == -1)
{
sock_geterror("getpeername(): ", fp->errbuf, PCAP_ERRBUF_SIZE);
return -1;
@@ -1522,7 +1631,7 @@ static int pcap_createfilter_norpcappkt(pcap_t *fp, struct bpf_program *prog)
/* We cannot check the data port, because this is available only in case of TCP sockets */
/* Get the name/port of the current host */
- if (getsockname(md->rmt_sockctrl, (struct sockaddr *) &saddr, &saddrlen) == -1)
+ if (getsockname(pr->rmt_sockctrl, (struct sockaddr *) &saddr, &saddrlen) == -1)
{
sock_geterror("getsockname(): ", fp->errbuf, PCAP_ERRBUF_SIZE);
return -1;
@@ -1537,7 +1646,7 @@ static int pcap_createfilter_norpcappkt(pcap_t *fp, struct bpf_program *prog)
}
/* Let's now check the data port */
- if (getsockname(md->rmt_sockdata, (struct sockaddr *) &saddr, &saddrlen) == -1)
+ if (getsockname(pr->rmt_sockdata, (struct sockaddr *) &saddr, &saddrlen) == -1)
{
sock_geterror("getsockname(): ", fp->errbuf, PCAP_ERRBUF_SIZE);
return -1;
@@ -1550,7 +1659,7 @@ static int pcap_createfilter_norpcappkt(pcap_t *fp, struct bpf_program *prog)
return -1;
}
- currentfiltersize = strlen(md->currentfilter);
+ currentfiltersize = pr->currentfilter ? strlen(pr->currentfilter) : 0;
newfilter = (char *)malloc(currentfiltersize + newstringsize + 1);
@@ -1558,7 +1667,7 @@ static int pcap_createfilter_norpcappkt(pcap_t *fp, struct bpf_program *prog)
{
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)",
- md->currentfilter, myaddress, peeraddress, myctrlport, peerctrlport, myaddress, peeraddress, mydataport);
+ pr->currentfilter, myaddress, peeraddress, myctrlport, peerctrlport, myaddress, peeraddress, mydataport);
}
else
{
@@ -1569,14 +1678,18 @@ static int pcap_createfilter_norpcappkt(pcap_t *fp, struct bpf_program *prog)
newfilter[currentfiltersize + newstringsize] = 0;
- /* This is only an hack to make the pcap_compile() working properly */
- md->rmt_clientside = 0;
+ /*
+ * This is only an hack to prevent the save_current_filter
+ * routine, which will be called when we call pcap_compile(),
+ * from saving the modified filter.
+ */
+ pr->rmt_clientside = 0;
if (pcap_compile(fp, prog, newfilter, 1, 0) == -1)
RetVal = -1;
- /* This is only an hack to make the pcap_compile() working properly */
- md->rmt_clientside = 1;
+ /* Undo the hack. */
+ pr->rmt_clientside = 1;
free(newfilter);
}
@@ -1585,87 +1698,82 @@ static int pcap_createfilter_norpcappkt(pcap_t *fp, struct bpf_program *prog)
}
/*
- * \ingroup remote_pri_func
- *
- * \brief Set sampling parameters in the remote host.
+ * This function sets sampling parameters in the remote host.
*
- * This function is called when the user wants to set activate sampling on the remote host.
+ * It is called when the user wants to set activate sampling on the
+ * remote host.
*
* Sampling parameters are defined into the 'pcap_t' structure.
*
* \param p: the pcap_t descriptor of the device currently opened.
*
- * \return '0' if everything is OK, '-1' is something goes wrong. The error message is returned
- * in the 'errbuf' member of the pcap_t structure.
+ * \return '0' if everything is OK, '-1' is something goes wrong. The
+ * error message is returned in the 'errbuf' member of the pcap_t structure.
*/
-static int pcap_setsampling_remote(pcap_t *p)
+static int pcap_setsampling_remote(pcap_t *fp)
{
- int retval; /* general variable used to keep the return value of other functions */
+ struct pcap_rpcap *pr = fp->priv; /* structure used when doing a remote live capture */
char sendbuf[RPCAP_NETBUF_SIZE];/* temporary buffer in which data to be sent is buffered */
- int sendbufidx = 0; /* index which keeps the number of bytes currently buffered */
+ int sendbufidx = 0; /* index which keeps the number of bytes currently buffered */
struct rpcap_header header; /* To keep the reply message */
struct rpcap_sampling *sampling_pars; /* Structure that is needed to send sampling parameters to the remote host */
- struct pcap_md *md; /* structure used when doing a remote live capture */
-
- md = (struct pcap_md *) ((u_char*)p->priv + sizeof(struct pcap_win));
/* If no samping is requested, return 'ok' */
- if (md->rmt_samp.method == PCAP_SAMP_NOSAMP)
+ if (fp->rmt_samp.method == PCAP_SAMP_NOSAMP)
return 0;
+ /*
+ * Check for sampling parameters that don't fit in a message.
+ * We'll let the server complain about invalid parameters
+ * that do fit into the message.
+ */
+ if (fp->rmt_samp.method < 0 || fp->rmt_samp.method > 255) {
+ pcap_snprintf(fp->errbuf, PCAP_ERRBUF_SIZE,
+ "Invalid sampling method %d", fp->rmt_samp.method);
+ return -1;
+ }
+ if (fp->rmt_samp.value < 0 || fp->rmt_samp.value > 65535) {
+ pcap_snprintf(fp->errbuf, PCAP_ERRBUF_SIZE,
+ "Invalid sampling value %d", fp->rmt_samp.value);
+ return -1;
+ }
+
if (sock_bufferize(NULL, sizeof(struct rpcap_header), NULL,
- &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, p->errbuf, PCAP_ERRBUF_SIZE))
+ &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, fp->errbuf, PCAP_ERRBUF_SIZE))
return -1;
- rpcap_createhdr((struct rpcap_header *) sendbuf, RPCAP_MSG_SETSAMPLING_REQ, 0, sizeof(struct rpcap_sampling));
+ rpcap_createhdr((struct rpcap_header *) sendbuf,
+ pr->protocol_version, RPCAP_MSG_SETSAMPLING_REQ, 0,
+ sizeof(struct rpcap_sampling));
/* Fill the structure needed to open an adapter remotely */
sampling_pars = (struct rpcap_sampling *) &sendbuf[sendbufidx];
if (sock_bufferize(NULL, sizeof(struct rpcap_sampling), NULL,
- &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, p->errbuf, PCAP_ERRBUF_SIZE))
+ &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, fp->errbuf, PCAP_ERRBUF_SIZE))
return -1;
memset(sampling_pars, 0, sizeof(struct rpcap_sampling));
- sampling_pars->method = md->rmt_samp.method;
- sampling_pars->value = htonl(md->rmt_samp.value);
+ sampling_pars->method = (uint8)fp->rmt_samp.method;
+ sampling_pars->value = (uint16)htonl(fp->rmt_samp.value);
- if (sock_send(md->rmt_sockctrl, sendbuf, sendbufidx, p->errbuf, PCAP_ERRBUF_SIZE))
+ if (sock_send(pr->rmt_sockctrl, sendbuf, sendbufidx, fp->errbuf,
+ PCAP_ERRBUF_SIZE) < 0)
return -1;
- /* Waits for the answer */
- if (sock_recv(md->rmt_sockctrl, (char *)&header, sizeof(struct rpcap_header), SOCK_RECEIVEALL_YES, p->errbuf, PCAP_ERRBUF_SIZE) == -1)
+ /* Receive and process the reply message header. */
+ if (rpcap_process_msg_header(pr->rmt_sockctrl, pr->protocol_version,
+ RPCAP_MSG_SETSAMPLING_REQ, &header, fp->errbuf) == -1)
return -1;
- /* Checks if the message is correct */
- retval = rpcap_checkmsg(p->errbuf, md->rmt_sockctrl, &header, RPCAP_MSG_SETSAMPLING_REPLY, 0);
-
- if (retval != RPCAP_MSG_SETSAMPLING_REPLY) /* the message is not the one expected */
- {
- switch (retval)
- {
- case -3: /* Unrecoverable network error */
- case -2: /* The other endpoint sent a message that is not allowed here */
- case -1: /* The other endpoint has a version number that is not compatible with our */
- case RPCAP_MSG_ERROR:
- /* Do nothing; just exit from here; the error code is already into the errbuf */
- return -1;
-
- default:
- SOCK_ASSERT("Internal error", 0);
- return -1;
- }
- }
-
- if (ntohl(header.plen) != 0) /* the message has an unexpected size */
- {
- if (sock_discard(md->rmt_sockctrl, ntohl(header.plen), p->errbuf, PCAP_ERRBUF_SIZE) == -1)
- return -1;
- }
+ /*
+ * It shouldn't have any contents; discard it if it does.
+ */
+ if (rpcap_discard(pr->rmt_sockctrl, header.plen, fp->errbuf) == -1)
+ return -1;
return 0;
-
}
/*********************************************************
@@ -1674,90 +1782,123 @@ static int pcap_setsampling_remote(pcap_t *p)
* *
*********************************************************/
-
-/* \ingroup remote_pri_func
- * \brief It sends a RPCAP error to the other peer.
- *
- * This function has to be called when the main program detects an error. This function
- * will send on the other peer the 'buffer' specified by the user.
- * This function *does not* request a RPCAP CLOSE connection. A CLOSE command must be sent
- * explicitly by the program, since we do not know it the error can be recovered in some
- * way or it is a non-recoverable one.
+/*
+ * 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.
*
* \param sock: the socket we are currently using.
*
- * \param error: an user-allocated (and '0' terminated) buffer that contains the error
- * description that has to be transmitted on the other peer. The error message cannot
- * be longer than PCAP_ERRBUF_SIZE.
+ * \param ver: pointer to variable holding protocol version number to send
+ * and to set to the protocol version number in the reply.
*
- * \param errcode: a integer which tells the other party the type of error we had;
- * currently is is not too much used.
+ * \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 network problem.
+ * \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, '-1' if some errors occurred. The error message is returned
- * in the 'errbuf' variable.
+ * \return '0' if everything is fine, '-1' for an error. For errors,
+ * an error message string is returned in the 'errbuf' variable.
*/
-int rpcap_senderror(SOCKET sock, char *error, unsigned short errcode, char *errbuf)
+static int rpcap_doauth(SOCKET sockctrl, uint8 *ver, struct pcap_rmtauth *auth, char *errbuf)
{
- 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 */
- uint16 length;
-
- length = (uint16)strlen(error);
+ int status;
- if (length > PCAP_ERRBUF_SIZE)
- length = PCAP_ERRBUF_SIZE;
-
- rpcap_createhdr((struct rpcap_header *) sendbuf, RPCAP_MSG_ERROR, errcode, length);
-
- if (sock_bufferize(NULL, sizeof(struct rpcap_header), NULL, &sendbufidx,
- RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errbuf, PCAP_ERRBUF_SIZE))
+ /*
+ * 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;
+ }
- if (sock_bufferize(error, length, sendbuf, &sendbufidx,
- RPCAP_NETBUF_SIZE, SOCKBUF_BUFFERIZE, errbuf, PCAP_ERRBUF_SIZE))
+ /*
+ * 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 (sock_send(sock, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE))
+ }
+ 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;
-
- return 0;
+ }
+ pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "rpcap_sendauth() returned %d", status);
+ return -1;
}
-/* \ingroup remote_pri_func
- * \brief Sends the authentication message.
+/*
+ * This function sends the authentication message.
*
* It sends the authentication parameters on the control socket.
- * This function is required in order to open the connection with the other end party.
+ * It is required in order to open the connection with the other end party.
*
* \param sock: the socket we are currently using.
*
- * \param auth: authentication parameters that have to be sent.
+ * \param ver: pointer to variable holding protocol version number to send
+ * and to set to the protocol version number in the reply.
*
- * \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 network problem
- * of the fact that the authorization failed.
+ * \param auth: authentication parameters that have to be sent.
*
- * \return '0' if everything is fine, '-1' if some errors occurred. The error message is returned
- * in the 'errbuf' variable.
- * The error message could be also 'the authentication failed'.
+ * \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.
*/
-int rpcap_sendauth(SOCKET sock, struct pcap_rmtauth *auth, char *errbuf)
+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 */
+ 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;
- int retval; /* temp variable which stores functions return value */
+ size_t str_length;
if (auth)
{
- auth_type = auth->type;
-
switch (auth->type)
{
case RPCAP_RMTAUTH_NULL:
@@ -1766,14 +1907,34 @@ int rpcap_sendauth(SOCKET sock, struct pcap_rmtauth *auth, char *errbuf)
case RPCAP_RMTAUTH_PWD:
length = sizeof(struct rpcap_auth);
- if (auth->username) length += (uint16) strlen(auth->username);
- if (auth->password) length += (uint16) strlen(auth->password);
+ if (auth->username)
+ {
+ str_length = strlen(auth->username);
+ if (str_length > 65535)
+ {
+ pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "User name is too long (> 65535 bytes)");
+ return -1;
+ }
+ length += (uint16)str_length;
+ }
+ if (auth->password)
+ {
+ str_length = strlen(auth->password);
+ if (str_length > 65535)
+ {
+ pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Password is too long (> 65535 bytes)");
+ return -1;
+ }
+ length += (uint16)str_length;
+ }
break;
default:
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Authentication type not recognized.");
return -1;
}
+
+ auth_type = (uint16)auth->type;
}
else
{
@@ -1786,7 +1947,8 @@ int rpcap_sendauth(SOCKET sock, struct pcap_rmtauth *auth, char *errbuf)
&sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errbuf, PCAP_ERRBUF_SIZE))
return -1;
- rpcap_createhdr((struct rpcap_header *) sendbuf, RPCAP_MSG_AUTH_REQ, 0, length);
+ rpcap_createhdr((struct rpcap_header *) sendbuf, *ver,
+ RPCAP_MSG_AUTH_REQ, 0, length);
rpauth = (struct rpcap_auth *) &sendbuf[sendbufidx];
@@ -1800,9 +1962,8 @@ int rpcap_sendauth(SOCKET sock, struct pcap_rmtauth *auth, char *errbuf)
if (auth_type == RPCAP_RMTAUTH_PWD)
{
-
if (auth->username)
- rpauth->slen1 = (uint16) strlen(auth->username);
+ rpauth->slen1 = (uint16)strlen(auth->username);
else
rpauth->slen1 = 0;
@@ -1811,7 +1972,7 @@ int rpcap_sendauth(SOCKET sock, struct pcap_rmtauth *auth, char *errbuf)
return -1;
if (auth->password)
- rpauth->slen2 = (uint16) strlen(auth->password);
+ rpauth->slen2 = (uint16)strlen(auth->password);
else
rpauth->slen2 = 0;
@@ -1823,267 +1984,872 @@ int rpcap_sendauth(SOCKET sock, struct pcap_rmtauth *auth, char *errbuf)
rpauth->slen2 = htons(rpauth->slen2);
}
- if (sock_send(sock, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE))
+ if (sock_send(sock, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) < 0)
return -1;
- if (sock_recv(sock, (char *)&header, sizeof(struct rpcap_header), SOCK_RECEIVEALL_YES, errbuf, PCAP_ERRBUF_SIZE) == -1)
+ /* Receive the reply */
+ if (rpcap_recv_msg_header(sock, &header, errbuf) == -1)
return -1;
- retval = rpcap_checkmsg(errbuf, sock, &header, RPCAP_MSG_AUTH_REPLY, RPCAP_MSG_ERROR, 0);
-
- if (retval != RPCAP_MSG_AUTH_REPLY) /* the message is not the one expected */
+ if (rpcap_check_msg_type(sock, RPCAP_MSG_AUTH_REQ, &header,
+ &errcode, errbuf) == -1)
{
- switch (retval)
+ /* Error message - or something else, which is a protocol error. */
+ if (header.type == RPCAP_MSG_ERROR &&
+ errcode == PCAP_ERR_WRONGVER)
{
- case -3: /* Unrecoverable network error */
- case -2: /* The other endpoint sent a message that is not allowed here */
- case -1: /* The other endpoint has a version number that is not compatible with our */
- /* Do nothing; just exit from here; the error code is already into the errbuf */
- return -1;
-
- case RPCAP_MSG_ERROR:
- return -1;
+ /*
+ * 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;
+ }
- default:
- SOCK_ASSERT("Internal error", 0);
- return -1;
+ /*
+ * OK, use that version, and tell our caller to
+ * try again.
+ */
+ *ver = header.ver;
+ return -2;
}
- }
- if (ntohl(header.plen))
- {
- if (sock_discard(sock, ntohl(header.plen), errbuf, PCAP_ERRBUF_SIZE))
- return -1;
+ /*
+ * Other error - unrecoverable.
+ */
+ return -1;
}
+ /*
+ * OK, it's an authentication reply, so they're OK with the
+ * protocol version we sent.
+ *
+ * Discard the rest of it.
+ */
+ if (rpcap_discard(sock, header.plen, errbuf) == -1)
+ return -1;
+
return 0;
}
-/* \ingroup remote_pri_func
- * \brief Creates a structure of type rpcap_header.
+/* We don't currently support non-blocking mode. */
+static int
+pcap_getnonblock_rpcap(pcap_t *p)
+{
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "Non-blocking mode isn't supported for capturing remotely with rpcap");
+ return (-1);
+}
+
+static int
+pcap_setnonblock_rpcap(pcap_t *p, int nonblock _U_)
+{
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "Non-blocking mode isn't supported for capturing remotely with rpcap");
+ return (-1);
+}
+
+/*
+ * This function opens a remote adapter by opening an RPCAP connection and
+ * so on.
*
- * This function is provided just because the creation of an rpcap header is quite a common
- * task. It accepts all the values that appears into an rpcap_header, and it puts them in
- * place using the proper hton() calls.
+ * It does the job of pcap_open_live() for a remote interface; it's called
+ * by pcap_open() for remote interfaces.
*
- * \param header: a pointer to a user-allocated buffer which will contain the serialized
- * header, ready to be sent on the network.
+ * We do not start the capture until pcap_startcapture_remote() is called.
*
- * \param type: a value (in the host by order) which will be placed into the header.type
- * field and that represents the type of the current message.
+ * This is because, when doing a remote capture, we cannot start capturing
+ * data as soon as the 'open adapter' command is sent. Suppose the remote
+ * adapter is already overloaded; if we start a capture (which, by default,
+ * has a NULL filter) the new traffic can saturate the network.
*
- * \param value: a value (in the host by order) which will be placed into the header.value
- * field and that has a message-dependent meaning.
+ * Instead, we want to "open" the adapter, then send a "start capture"
+ * command only when we're ready to start the capture.
+ * This function does this job: it sends an "open adapter" command
+ * (according to the RPCAP protocol), but it does not start the capture.
*
- * \param length: a value (in the host by order) which will be placed into the header.length
- * field and that represents the payload length of the message.
+ * Since the other libpcap functions do not share this way of life, we
+ * have to do some dirty things in order to make everything work.
*
- * \return Nothing. The serialized header is returned into the 'header' variable.
- */
-void rpcap_createhdr(struct rpcap_header *header, uint8 type, uint16 value, uint32 length)
-{
- memset(header, 0, sizeof(struct rpcap_header));
-
- header->ver = RPCAP_VERSION;
- header->type = type;
- header->value = htons(value);
- header->plen = htonl(length);
-}
-
-/* ingroup remote_pri_func
- * \brief Checks if the header of the received message is correct.
+ * \param source: see pcap_open().
+ * \param snaplen: see pcap_open().
+ * \param flags: see pcap_open().
+ * \param read_timeout: see pcap_open().
+ * \param auth: see pcap_open().
+ * \param errbuf: see pcap_open().
*
- * This function is a way to easily check if the message received, in a certain
- * state of the RPCAP protocol Finite State Machine, is valid. This function accepts,
- * as a parameter, the list of message types that are allowed in a certain situation,
- * and it returns the one which occurs.
+ * \return a pcap_t pointer in case of success, NULL otherwise. In case of
+ * success, the pcap_t pointer can be used as a parameter to the following
+ * calls (pcap_compile() and so on). In case of problems, errbuf contains
+ * a text explanation of error.
*
- * \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 either problem
- * occurred inside this function (e.g. a network problem in case it tries to send an
- * error on the other peer and the send() call fails), an error message which has been
- * sent to us from the other party, or a version error (the message receive has a version
- * number that is incompatible with our).
- *
- * \param sock: the socket that has to be used to receive data. This function can
- * read data from socket in case the version contained into the message is not compatible
- * with our. In that case, all the message is purged from the socket, so that the following
- * recv() calls will return a new message.
- *
- * \param header: a pointer to and 'rpcap_header' structure that keeps the data received from
- * the network (still in network byte order) and that has to be checked.
- *
- * \param first: this function has a variable number of parameters. From this point on,
- * all the messages that are valid in this context must be passed as parameters.
- * The message type list must be terminated with a '0' value, the null message type,
- * which means 'no more types to check'. The RPCAP protocol does not define anything with
- * message type equal to zero, so there is no ambiguity in using this value as a list terminator.
- *
- * \return The message type of the message that has been detected. In case of errors (e.g. the
- * header contains a type that is not listed among the allowed types), this function will
- * return the following codes:
- * - (-1) if the version is incompatible.
- * - (-2) if the code is not among the one listed into the parameters list
- * - (-3) if a network error (connection reset, ...)
- * - RPCAP_MSG_ERROR if the message is an error message (it follow that the RPCAP_MSG_ERROR
- * could not be present in the allowed message-types list, because this function checks
- * for errors anyway)
- *
- * In case either the version is incompatible or nothing matches (i.e. it returns '-1' or '-2'),
- * it discards the message body (i.e. it reads the remaining part of the message from the
- * network and it discards it) so that the application is ready to receive a new message.
+ * WARNING: In case we call pcap_compile() and the capture has not yet
+ * been started, the filter will be saved into the pcap_t structure,
+ * and it will be sent to the other host later (when
+ * pcap_startcapture_remote() is called).
*/
-int rpcap_checkmsg(char *errbuf, SOCKET sock, struct rpcap_header *header, uint8 first, ...)
+pcap_t *pcap_open_rpcap(const char *source, int snaplen, int flags, int read_timeout, struct pcap_rmtauth *auth, char *errbuf)
{
- va_list ap;
- uint8 type;
- int32 len;
+ pcap_t *fp;
+ 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 */
- va_start(ap, first);
+ /* RPCAP-related variables */
+ struct rpcap_header header; /* header of the RPCAP packet */
+ struct rpcap_openreply openreply; /* open reply message */
- /* Check if the present version of the protocol can handle this message */
- if (rpcap_checkver(sock, header, errbuf))
+ fp = pcap_create_common(errbuf, sizeof (struct pcap_rpcap));
+ if (fp == NULL)
{
- SOCK_ASSERT(errbuf, 1);
+ return NULL;
+ }
+ source_str = strdup(source);
+ if (source_str == NULL) {
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ errno, "malloc");
+ return NULL;
+ }
- va_end(ap);
- return -1;
+ /*
+ * Turn a negative snapshot value (invalid), a snapshot value of
+ * 0 (unspecified), or a value bigger than the normal maximum
+ * value, into the maximum allowed value.
+ *
+ * If some application really *needs* a bigger snapshot
+ * length, we should just increase MAXIMUM_SNAPLEN.
+ *
+ * XXX - should we leave this up to the remote server to
+ * do?
+ */
+ if (snaplen <= 0 || snaplen > MAXIMUM_SNAPLEN)
+ snaplen = MAXIMUM_SNAPLEN;
+
+ fp->opt.device = source_str;
+ fp->snapshot = snaplen;
+ fp->opt.timeout = read_timeout;
+ pr = fp->priv;
+ 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.
+ */
+ if (pcap_parsesrcstr(fp->opt.device, &retval, host, ctrlport, iface, errbuf) == -1)
+ {
+ 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;
}
- type = first;
+ /*
+ * 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;
+ }
- while (type != 0)
+ /* 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;
+ }
+
/*
- * The message matches with one of the types listed
- * There is no need of conversions since both values are uint8
- *
- * Check if the other side reported an error.
- * If yes, it retrieves it and it returns it back to the caller
+ * We're not in active mode; let's try to open a new
+ * control connection.
*/
- if (header->type == RPCAP_MSG_ERROR)
- {
- len = ntohl(header->plen);
+ memset(&hints, 0, sizeof(struct addrinfo));
+ hints.ai_family = PF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
- if (len >= PCAP_ERRBUF_SIZE)
+ 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)
{
- if (sock_recv(sock, errbuf, PCAP_ERRBUF_SIZE - 1, SOCK_RECEIVEALL_YES, errbuf, PCAP_ERRBUF_SIZE))
- return -3;
+ 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
+ */
+ if (sock_bufferize(NULL, sizeof(struct rpcap_header), NULL,
+ &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errbuf, PCAP_ERRBUF_SIZE))
+ goto error_nodiscard;
+
+ rpcap_createhdr((struct rpcap_header *) sendbuf, protocol_version,
+ RPCAP_MSG_OPEN_REQ, 0, (uint32) strlen(iface));
+
+ if (sock_bufferize(iface, (int) strlen(iface), sendbuf, &sendbufidx,
+ RPCAP_NETBUF_SIZE, SOCKBUF_BUFFERIZE, errbuf, PCAP_ERRBUF_SIZE))
+ goto error_nodiscard;
+
+ if (sock_send(sockctrl, sendbuf, sendbufidx, errbuf,
+ PCAP_ERRBUF_SIZE) < 0)
+ goto error_nodiscard;
+
+ /* Receive and process the reply message header. */
+ if (rpcap_process_msg_header(sockctrl, protocol_version,
+ RPCAP_MSG_OPEN_REQ, &header, errbuf) == -1)
+ goto error_nodiscard;
+ plen = header.plen;
+
+ /* Read the reply body */
+ if (rpcap_recv(sockctrl, (char *)&openreply,
+ sizeof(struct rpcap_openreply), &plen, errbuf) == -1)
+ goto error;
+
+ /* Discard the rest of the message, if there is any. */
+ if (rpcap_discard(pr->rmt_sockctrl, plen, errbuf) == -1)
+ goto error_nodiscard;
+
+ /* Set proper fields into the pcap_t struct */
+ fp->linktype = ntohl(openreply.linktype);
+ fp->tzoff = ntohl(openreply.tzoff);
+ pr->rmt_sockctrl = sockctrl;
+ pr->protocol_version = protocol_version;
+ pr->rmt_clientside = 1;
+
+ /* This code is duplicated from the end of this function */
+ fp->read_op = pcap_read_rpcap;
+ fp->save_current_filter_op = pcap_save_current_filter_rpcap;
+ fp->setfilter_op = pcap_setfilter_rpcap;
+ fp->getnonblock_op = pcap_getnonblock_rpcap;
+ fp->setnonblock_op = pcap_setnonblock_rpcap;
+ fp->stats_op = pcap_stats_rpcap;
+#ifdef _WIN32
+ fp->stats_ex_op = pcap_stats_ex_rpcap;
+#endif
+ fp->cleanup_op = pcap_cleanup_rpcap;
+
+ fp->activated = 1;
+ return fp;
+
+error:
+ /*
+ * When the connection has been established, we have to close it. So, at the
+ * beginning of this function, if an error occur we return immediately with
+ * a return NULL; when the connection is established, we have to come here
+ * ('goto error;') in order to close everything properly.
+ */
+
+ /*
+ * Discard the rest of the message.
+ * We already reported an error; if this gets an error, just
+ * drive on.
+ */
+ (void)rpcap_discard(pr->rmt_sockctrl, plen, NULL);
+
+error_nodiscard:
+ if (!active)
+ sock_close(sockctrl, NULL, 0);
+
+ pcap_close(fp);
+ return NULL;
+}
+
+/* String identifier to be used in the pcap_findalldevs_ex() */
+#define PCAP_TEXT_SOURCE_ADAPTER "Network adapter"
+/* String identifier to be used in the pcap_findalldevs_ex() */
+#define PCAP_TEXT_SOURCE_ON_REMOTE_HOST "on remote node"
+
+static void
+freeaddr(struct pcap_addr *addr)
+{
+ free(addr->addr);
+ free(addr->netmask);
+ free(addr->broadaddr);
+ free(addr->dstaddr);
+ free(addr);
+}
+
+int
+pcap_findalldevs_ex_remote(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;
+ struct rpcap_header header; /* structure that keeps the general header of the rpcap protocol */
+ 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 */
+ pcap_if_t *dev; /* Device we're adding to the pcap_if_t list */
+
+ /* List starts out empty. */
+ (*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)
+ {
+ 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;
+ }
- sock_discard(sock, len - (PCAP_ERRBUF_SIZE - 1), NULL, 0);
+ /* addrinfo is no longer used */
+ freeaddrinfo(addrinfo);
+ addrinfo = NULL;
- /* Put '\0' at the end of the string */
- errbuf[PCAP_ERRBUF_SIZE - 1] = 0;
+ if (rpcap_doauth(sockctrl, &protocol_version, auth, errbuf) == -1)
+ {
+ sock_close(sockctrl, NULL, 0);
+ return -1;
+ }
+ active = 0;
+ }
+
+ /* RPCAP findalldevs command */
+ rpcap_createhdr(&header, protocol_version, RPCAP_MSG_FINDALLIF_REQ,
+ 0, 0);
+
+ if (sock_send(sockctrl, (char *)&header, sizeof(struct rpcap_header),
+ errbuf, PCAP_ERRBUF_SIZE) < 0)
+ goto error_nodiscard;
+
+ /* Receive and process the reply message header. */
+ if (rpcap_process_msg_header(sockctrl, protocol_version,
+ RPCAP_MSG_FINDALLIF_REQ, &header, errbuf) == -1)
+ goto error_nodiscard;
+
+ plen = header.plen;
+
+ /* read the number of interfaces */
+ nif = ntohs(header.value);
+
+ /* loop until all interfaces have been received */
+ for (i = 0; i < nif; i++)
+ {
+ 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;
+
+ /* receive the findalldevs structure from remote host */
+ if (rpcap_recv(sockctrl, (char *)&findalldevs_if,
+ sizeof(struct rpcap_findalldevs_if), &plen, errbuf) == -1)
+ goto error;
+
+ findalldevs_if.namelen = ntohs(findalldevs_if.namelen);
+ findalldevs_if.desclen = ntohs(findalldevs_if.desclen);
+ findalldevs_if.naddr = ntohs(findalldevs_if.naddr);
+
+ /* allocate the main structure */
+ dev = (pcap_if_t *)malloc(sizeof(pcap_if_t));
+ if (dev == NULL)
+ {
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ errno, "malloc() failed");
+ goto error;
+ }
+
+ /* Initialize the structure to 'zero' */
+ memset(dev, 0, sizeof(pcap_if_t));
+
+ /* Append it to the list. */
+ if (lastdev == NULL)
+ {
+ /*
+ * List is empty, so it's also the first device.
+ */
+ *alldevs = dev;
+ }
+ else
+ {
+ /*
+ * Append after the last device.
+ */
+ lastdev->next = dev;
+ }
+ /* It's now the last device. */
+ lastdev = dev;
+
+ /* allocate mem for name and description */
+ if (findalldevs_if.namelen)
+ {
+
+ if (findalldevs_if.namelen >= sizeof(tmpstring))
+ {
+ pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Interface name too long");
+ goto error;
}
- else
+
+ /* Retrieve adapter name */
+ if (rpcap_recv(sockctrl, tmpstring,
+ findalldevs_if.namelen, &plen, errbuf) == -1)
+ goto error;
+
+ tmpstring[findalldevs_if.namelen] = 0;
+
+ /* Create the new device identifier */
+ if (pcap_createsrcstr(tmpstring2, PCAP_SRC_IFREMOTE, host, port, tmpstring, errbuf) == -1)
+ return -1;
+
+ stringlen = strlen(tmpstring2);
+
+ dev->name = (char *)malloc(stringlen + 1);
+ if (dev->name == NULL)
{
- if (sock_recv(sock, errbuf, len, SOCK_RECEIVEALL_YES, errbuf, PCAP_ERRBUF_SIZE) == -1)
- return -3;
+ 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);
+ }
- /* Put '\0' at the end of the string */
- errbuf[len] = 0;
+ if (findalldevs_if.desclen)
+ {
+ if (findalldevs_if.desclen >= sizeof(tmpstring))
+ {
+ pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Interface description too long");
+ goto error;
}
+ /* Retrieve adapter description */
+ if (rpcap_recv(sockctrl, tmpstring,
+ findalldevs_if.desclen, &plen, errbuf) == -1)
+ goto error;
+
+ 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);
- va_end(ap);
- return header->type;
+ if (dev->description == NULL)
+ {
+ 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);
}
- if (header->type == type)
+ dev->flags = ntohl(findalldevs_if.flags);
+
+ prevaddr = NULL;
+ /* loop until all addresses have been received */
+ for (j = 0; j < findalldevs_if.naddr; j++)
{
- va_end(ap);
- return header->type;
+ struct rpcap_findalldevs_ifaddr ifaddr;
+
+ /* Retrieve the interface addresses */
+ if (rpcap_recv(sockctrl, (char *)&ifaddr,
+ sizeof(struct rpcap_findalldevs_ifaddr),
+ &plen, errbuf) == -1)
+ goto error;
+
+ /*
+ * Deserialize all the address components.
+ */
+ addr = (struct pcap_addr *) malloc(sizeof(struct pcap_addr));
+ if (addr == NULL)
+ {
+ pcap_fmt_errmsg_for_errno(errbuf,
+ PCAP_ERRBUF_SIZE, errno, "malloc() failed");
+ goto error;
+ }
+ addr->next = NULL;
+ addr->addr = NULL;
+ addr->netmask = NULL;
+ addr->broadaddr = NULL;
+ addr->dstaddr = NULL;
+
+ if (rpcap_deseraddr(&ifaddr.addr,
+ (struct sockaddr_storage **) &addr->addr, errbuf) == -1)
+ {
+ freeaddr(addr);
+ goto error;
+ }
+ if (rpcap_deseraddr(&ifaddr.netmask,
+ (struct sockaddr_storage **) &addr->netmask, errbuf) == -1)
+ {
+ freeaddr(addr);
+ goto error;
+ }
+ if (rpcap_deseraddr(&ifaddr.broadaddr,
+ (struct sockaddr_storage **) &addr->broadaddr, errbuf) == -1)
+ {
+ freeaddr(addr);
+ goto error;
+ }
+ if (rpcap_deseraddr(&ifaddr.dstaddr,
+ (struct sockaddr_storage **) &addr->dstaddr, errbuf) == -1)
+ {
+ freeaddr(addr);
+ goto error;
+ }
+
+ if ((addr->addr == NULL) && (addr->netmask == NULL) &&
+ (addr->broadaddr == NULL) && (addr->dstaddr == NULL))
+ {
+ /*
+ * None of the addresses are IPv4 or IPv6
+ * addresses, so throw this entry away.
+ */
+ free(addr);
+ }
+ else
+ {
+ /*
+ * Add this entry to the list.
+ */
+ if (prevaddr == NULL)
+ {
+ dev->addresses = addr;
+ }
+ else
+ {
+ prevaddr->next = addr;
+ }
+ prevaddr = addr;
+ }
}
+ }
- /* get next argument */
- type = va_arg(ap, int);
+ /* Discard the rest of the message. */
+ if (rpcap_discard(sockctrl, plen, errbuf) == 1)
+ return -1;
+
+ /* Control connection has to be closed only in case the remote machine is in passive mode */
+ if (!active)
+ {
+ /* DO not send RPCAP_CLOSE, since we did not open a pcap_t; no need to free resources */
+ if (sock_close(sockctrl, errbuf, PCAP_ERRBUF_SIZE))
+ return -1;
}
- /* we already have an error, so please discard this one */
- sock_discard(sock, ntohl(header->plen), NULL, 0);
+ /* To avoid inconsistencies in the number of sock_init() */
+ sock_cleanup();
+
+ return 0;
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "The other endpoint sent a message that is not allowed here.");
- SOCK_ASSERT(errbuf, 1);
+error:
+ /*
+ * In case there has been an error, I don't want to overwrite it with a new one
+ * if the following call fails. I want to return always the original error.
+ *
+ * Take care: this connection can already be closed when we try to close it.
+ * This happens because a previous error in the rpcapd, which requested to
+ * closed the connection. In that case, we already recognized that into the
+ * rpspck_isheaderok() and we already acknowledged the closing.
+ * In that sense, this call is useless here (however it is needed in case
+ * the client generates the error).
+ *
+ * Checks if all the data has been read; if not, discard the data in excess
+ */
+ (void) rpcap_discard(sockctrl, plen, NULL);
+
+error_nodiscard:
+ /* Control connection has to be closed only in case the remote machine is in passive mode */
+ if (!active)
+ sock_close(sockctrl, NULL, 0);
+
+ /* To avoid inconsistencies in the number of sock_init() */
+ sock_cleanup();
- va_end(ap);
- return -2;
+ /* Free whatever interfaces we've allocated. */
+ pcap_freealldevs(*alldevs);
+
+ return -1;
}
-/* \ingroup remote_pri_func
- * \brief Checks if the version contained into the message is compatible with
- * the one handled by this implementation.
- *
- * Right now, this function does not have any sophisticated task: if the versions
- * are different, it returns -1 and it discards the message.
- * It is expected that in the future this message will become more complex.
- *
- * \param sock: the socket that has to be used to receive data. This function can
- * read data from socket in case the version contained into the message is not compatible
- * with our. In that case, all the message is purged from the socket, so that the following
- * recv() calls will return a new (clean) message.
- *
- * \param header: a pointer to and 'rpcap_header' structure that keeps the data received from
- * the network (still in network byte order) and that has to be checked.
- *
- * \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). The error message is
- * "incompatible version".
+/*
+ * Active mode routines.
*
- * \return '0' if everything is fine, '-1' if some errors occurred. The error message is returned
- * in the 'errbuf' variable.
+ * The old libpcap API is somewhat ugly, and makes active mode difficult
+ * to implement; we provide some APIs for it that work only with rpcap.
*/
-static int rpcap_checkver(SOCKET sock, struct rpcap_header *header, char *errbuf)
+
+SOCKET pcap_remoteact_accept(const char *address, const char *port, const char *hostlist, char *connectinghost, struct pcap_rmtauth *auth, char *errbuf)
{
+ /* socket-related variables */
+ struct addrinfo hints; /* temporary struct to keep settings needed to open the new socket */
+ struct addrinfo *addrinfo; /* keeps the addrinfo chain; required to open a new socket */
+ struct sockaddr_storage from; /* generic sockaddr_storage variable */
+ socklen_t fromlen; /* keeps the length of the sockaddr_storage variable */
+ SOCKET sockctrl; /* keeps the main socket identifier */
+ uint8 protocol_version; /* negotiated protocol version */
+ struct activehosts *temp, *prev; /* temp var needed to scan he host list chain */
+
+ *connectinghost = 0; /* just in case */
+
+ /* Prepare to open a new server socket */
+ memset(&hints, 0, sizeof(struct addrinfo));
+ /* WARNING Currently it supports only ONE socket family among ipv4 and IPv6 */
+ hints.ai_family = AF_INET; /* PF_UNSPEC to have both IPv4 and IPv6 server */
+ hints.ai_flags = AI_PASSIVE; /* Ready to a bind() socket */
+ hints.ai_socktype = SOCK_STREAM;
+
+ /* 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 (SOCKET)-1;
+
+ /* Do the work */
+ if ((port == NULL) || (port[0] == 0))
+ {
+ if (sock_initaddress(address, RPCAP_DEFAULT_NETPORT_ACTIVE, &hints, &addrinfo, errbuf, PCAP_ERRBUF_SIZE) == -1)
+ {
+ SOCK_DEBUG_MESSAGE(errbuf);
+ return (SOCKET)-2;
+ }
+ }
+ else
+ {
+ if (sock_initaddress(address, port, &hints, &addrinfo, errbuf, PCAP_ERRBUF_SIZE) == -1)
+ {
+ SOCK_DEBUG_MESSAGE(errbuf);
+ return (SOCKET)-2;
+ }
+ }
+
+
+ if ((sockmain = sock_open(addrinfo, SOCKOPEN_SERVER, 1, errbuf, PCAP_ERRBUF_SIZE)) == INVALID_SOCKET)
+ {
+ SOCK_DEBUG_MESSAGE(errbuf);
+ freeaddrinfo(addrinfo);
+ return (SOCKET)-2;
+ }
+ freeaddrinfo(addrinfo);
+
+ /* Connection creation */
+ fromlen = sizeof(struct sockaddr_storage);
+
+ sockctrl = accept(sockmain, (struct sockaddr *) &from, &fromlen);
+
+ /* We're not using sock_close, since we do not want to send a shutdown */
+ /* (which is not allowed on a non-connected socket) */
+ closesocket(sockmain);
+ sockmain = 0;
+
+ if (sockctrl == INVALID_SOCKET)
+ {
+ 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);
+ rpcap_senderror(sockctrl, 0, PCAP_ERR_REMOTEACCEPT, errbuf, NULL);
+ sock_close(sockctrl, NULL, 0);
+ return (SOCKET)-1;
+ }
+
+ /* checks if the connecting host is among the ones allowed */
+ if (sock_check_hostlist((char *)hostlist, RPCAP_HOSTLIST_SEP, &from, errbuf, PCAP_ERRBUF_SIZE) < 0)
+ {
+ rpcap_senderror(sockctrl, 0, PCAP_ERR_REMOTEACCEPT, errbuf, NULL);
+ sock_close(sockctrl, NULL, 0);
+ return (SOCKET)-1;
+ }
+
/*
- * This is a sample function.
- *
- * In the real world, you have to check at the type code,
- * and decide accordingly.
+ * Send authentication to the remote machine.
*/
+ if (rpcap_doauth(sockctrl, &protocol_version, auth, errbuf) == -1)
+ {
+ /* Unrecoverable error. */
+ rpcap_senderror(sockctrl, 0, PCAP_ERR_REMOTEACCEPT, errbuf, NULL);
+ sock_close(sockctrl, NULL, 0);
+ return (SOCKET)-3;
+ }
- if (header->ver != RPCAP_VERSION)
+ /* Checks that this host does not already have a cntrl connection in place */
+
+ /* Initialize pointers */
+ temp = activeHosts;
+ prev = NULL;
+
+ while (temp)
{
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Incompatible version number: message discarded.");
+ /* This host already has an active connection in place, so I don't have to update the host list */
+ if (sock_cmpaddr(&temp->host, &from) == 0)
+ return sockctrl;
- /* we already have an error, so please discard this one */
- sock_discard(sock, ntohl(header->plen), NULL, 0);
- return -1;
+ prev = temp;
+ temp = temp->next;
}
- return 0;
+ /* The host does not exist in the list; so I have to update the list */
+ if (prev)
+ {
+ prev->next = (struct activehosts *) malloc(sizeof(struct activehosts));
+ temp = prev->next;
+ }
+ else
+ {
+ activeHosts = (struct activehosts *) malloc(sizeof(struct activehosts));
+ temp = activeHosts;
+ }
+
+ if (temp == NULL)
+ {
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ errno, "malloc() failed");
+ rpcap_senderror(sockctrl, protocol_version, PCAP_ERR_REMOTEACCEPT, errbuf, NULL);
+ sock_close(sockctrl, NULL, 0);
+ return (SOCKET)-1;
+ }
+
+ memcpy(&temp->host, &from, fromlen);
+ temp->sockctrl = sockctrl;
+ temp->protocol_version = protocol_version;
+ temp->next = NULL;
+
+ return sockctrl;
}
-/* \ingroup remote_pri_func
- *
- * \brief It returns the socket currently used for this active connection
- * (active mode only) and provides an indication of whether this connection
- * is in active mode or not.
- *
- * This function is just for internal use; it returns the socket ID of the
- * active connection currently opened.
- *
- * \param host: a string that keeps the host name of the host for which we
- * want to get the socket ID for that active connection.
- *
- * \param isactive: a pointer to an int that is set to 1 if there's an
- * active connection to that host and 0 otherwise.
- *
- * \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).
- *
- * \return the socket identifier if everything is fine, '0' if this host
- * is not in the active host list. An indication of whether this host
- * is in the active host list is returned into the isactive variable.
- * It returns 'INVALID_SOCKET' in case of error. The error message is
- * returned into the errbuf variable.
- */
-SOCKET rpcap_remoteact_getsock(const char *host, int *isactive, char *errbuf)
+int pcap_remoteact_close(const char *host, char *errbuf)
{
- struct activehosts *temp; /* temp var needed to scan the host list chain */
+ struct activehosts *temp, *prev; /* temp var needed to scan the host list chain */
struct addrinfo hints, *addrinfo, *ai_next; /* temp var needed to translate between hostname to its address */
int retval;
+ temp = activeHosts;
+ prev = NULL;
+
/* retrieve the network address corresponding to 'host' */
addrinfo = NULL;
memset(&hints, 0, sizeof(struct addrinfo));
@@ -2094,34 +2860,451 @@ SOCKET rpcap_remoteact_getsock(const char *host, int *isactive, char *errbuf)
if (retval != 0)
{
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "getaddrinfo() %s", gai_strerror(retval));
- *isactive = 0;
- return INVALID_SOCKET;
+ return -1;
}
- temp = activeHosts;
-
while (temp)
{
ai_next = addrinfo;
while (ai_next)
{
- if (sock_cmpaddr(&temp->host, (struct sockaddr_storage *) ai_next->ai_addr) == 0) {
- *isactive = 1;
- return (temp->sockctrl);
+ if (sock_cmpaddr(&temp->host, (struct sockaddr_storage *) ai_next->ai_addr) == 0)
+ {
+ struct rpcap_header header;
+ int status = 0;
+
+ /* Close this connection */
+ rpcap_createhdr(&header, temp->protocol_version,
+ RPCAP_MSG_CLOSE, 0, 0);
+
+ /*
+ * Don't check for errors, since we're
+ * just cleaning up.
+ */
+ if (sock_send(temp->sockctrl,
+ (char *)&header,
+ sizeof(struct rpcap_header), errbuf,
+ PCAP_ERRBUF_SIZE) < 0)
+ {
+ /*
+ * Let that error be the one we
+ * report.
+ */
+ (void)sock_close(temp->sockctrl, NULL,
+ 0);
+ status = -1;
+ }
+ else
+ {
+ if (sock_close(temp->sockctrl, errbuf,
+ PCAP_ERRBUF_SIZE) == -1)
+ status = -1;
+ }
+
+ /*
+ * Remove the host from the list of active
+ * hosts.
+ */
+ if (prev)
+ prev->next = temp->next;
+ else
+ activeHosts = temp->next;
+
+ freeaddrinfo(addrinfo);
+
+ free(temp);
+
+ /* To avoid inconsistencies in the number of sock_init() */
+ sock_cleanup();
+
+ return status;
}
ai_next = ai_next->ai_next;
}
+ prev = temp;
temp = temp->next;
}
if (addrinfo)
freeaddrinfo(addrinfo);
+ /* To avoid inconsistencies in the number of sock_init() */
+ sock_cleanup();
+
+ pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "The host you want to close the active connection is not known");
+ return -1;
+}
+
+void pcap_remoteact_cleanup(void)
+{
+ /* Very dirty, but it works */
+ if (sockmain)
+ {
+ closesocket(sockmain);
+
+ /* To avoid inconsistencies in the number of sock_init() */
+ sock_cleanup();
+ }
+
+}
+
+int pcap_remoteact_list(char *hostlist, char sep, int size, char *errbuf)
+{
+ struct activehosts *temp; /* temp var needed to scan the host list chain */
+ size_t len;
+ char hoststr[RPCAP_HOSTLIST_SIZE + 1];
+
+ temp = activeHosts;
+
+ len = 0;
+ *hostlist = 0;
+
+ while (temp)
+ {
+ /*int sock_getascii_addrport(const struct sockaddr_storage *sockaddr, char *address, int addrlen, char *port, int portlen, int flags, char *errbuf, int errbuflen) */
+
+ /* Get the numeric form of the name of the connecting host */
+ if (sock_getascii_addrport((struct sockaddr_storage *) &temp->host, hoststr,
+ RPCAP_HOSTLIST_SIZE, NULL, 0, NI_NUMERICHOST, errbuf, PCAP_ERRBUF_SIZE) != -1)
+ /* 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); */
+ return -1;
+ }
+
+ len = len + strlen(hoststr) + 1 /* the separator */;
+
+ if ((size < 0) || (len >= (size_t)size))
+ {
+ pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "The string you provided is not able to keep "
+ "the hostnames for all the active connections");
+ return -1;
+ }
+
+ strlcat(hostlist, hoststr, PCAP_ERRBUF_SIZE);
+ hostlist[len - 1] = sep;
+ hostlist[len] = 0;
+
+ temp = temp->next;
+ }
+
+ return 0;
+}
+
+/*
+ * Receive the header of a message.
+ */
+static int rpcap_recv_msg_header(SOCKET sock, struct rpcap_header *header, char *errbuf)
+{
+ int nrecv;
+
+ nrecv = sock_recv(sock, (char *) header, sizeof(struct rpcap_header),
+ SOCK_RECEIVEALL_YES|SOCK_EOF_IS_ERROR, errbuf,
+ PCAP_ERRBUF_SIZE);
+ if (nrecv == -1)
+ {
+ /* Network error. */
+ return -1;
+ }
+ header->plen = ntohl(header->plen);
+ return 0;
+}
+
+/*
+ * Make sure the protocol version of a received message is what we were
+ * expecting.
+ */
+static int rpcap_check_msg_ver(SOCKET sock, uint8 expected_ver, struct rpcap_header *header, char *errbuf)
+{
/*
- * The host for which you want to get the socket ID does not have an
- * active connection.
+ * Did the server specify the version we negotiated?
*/
- *isactive = 0;
+ if (header->ver != expected_ver)
+ {
+ /*
+ * Discard the rest of the message.
+ */
+ if (rpcap_discard(sock, header->plen, errbuf) == -1)
+ return -1;
+
+ /*
+ * Tell our caller that it's not the negotiated version.
+ */
+ if (errbuf != NULL)
+ {
+ pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "Server sent us a message with version %u when we were expecting %u",
+ header->ver, expected_ver);
+ }
+ return -1;
+ }
+ return 0;
+}
+
+/*
+ * Check the message type of a received message, which should either be
+ * the expected message type or RPCAP_MSG_ERROR.
+ */
+static int rpcap_check_msg_type(SOCKET sock, uint8 request_type, struct rpcap_header *header, uint16 *errcode, char *errbuf)
+{
+ const char *request_type_string;
+ const char *msg_type_string;
+
+ /*
+ * What type of message is it?
+ */
+ if (header->type == RPCAP_MSG_ERROR)
+ {
+ /*
+ * The server reported an error.
+ * Hand that error back to our caller.
+ */
+ *errcode = ntohs(header->value);
+ rpcap_msg_err(sock, header->plen, errbuf);
+ return -1;
+ }
+
+ *errcode = 0;
+
+ /*
+ * For a given request type value, the expected reply type value
+ * is the request type value with ORed with RPCAP_MSG_IS_REPLY.
+ */
+ if (header->type != (request_type | RPCAP_MSG_IS_REPLY))
+ {
+ /*
+ * This isn't a reply to the request we sent.
+ */
+
+ /*
+ * Discard the rest of the message.
+ */
+ if (rpcap_discard(sock, header->plen, errbuf) == -1)
+ return -1;
+
+ /*
+ * Tell our caller about it.
+ */
+ request_type_string = rpcap_msg_type_string(request_type);
+ msg_type_string = rpcap_msg_type_string(header->type);
+ if (errbuf != NULL)
+ {
+ if (request_type_string == NULL)
+ {
+ /* This should not happen. */
+ pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "rpcap_check_msg_type called for request message with type %u",
+ request_type);
+ return -1;
+ }
+ if (msg_type_string != NULL)
+ pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "%s message received in response to a %s message",
+ msg_type_string, request_type_string);
+ else
+ pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "Message of unknown type %u message received in response to a %s request",
+ header->type, request_type_string);
+ }
+ return -1;
+ }
+
+ return 0;
+}
+
+/*
+ * Receive and process the header of a message.
+ */
+static int rpcap_process_msg_header(SOCKET sock, uint8 expected_ver, uint8 request_type, struct rpcap_header *header, char *errbuf)
+{
+ uint16 errcode;
+
+ if (rpcap_recv_msg_header(sock, header, errbuf) == -1)
+ {
+ /* Network error. */
+ return -1;
+ }
+
+ /*
+ * Did the server specify the version we negotiated?
+ */
+ if (rpcap_check_msg_ver(sock, expected_ver, header, errbuf) == -1)
+ return -1;
+
+ /*
+ * Check the message type.
+ */
+ return rpcap_check_msg_type(sock, request_type, header,
+ &errcode, errbuf);
+}
+
+/*
+ * Read data from a message.
+ * If we're trying to read more data that remains, puts an error
+ * message into errmsgbuf and returns -2. Otherwise, tries to read
+ * the data and, if that succeeds, subtracts the amount read from
+ * the number of bytes of data that remains.
+ * Returns 0 on success, logs a message and returns -1 on a network
+ * error.
+ */
+static int rpcap_recv(SOCKET sock, void *buffer, size_t toread, uint32 *plen, char *errbuf)
+{
+ int nread;
+
+ if (toread > *plen)
+ {
+ /* The server sent us a bad message */
+ pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Message payload is too short");
+ return -1;
+ }
+ nread = sock_recv(sock, buffer, toread,
+ SOCK_RECEIVEALL_YES|SOCK_EOF_IS_ERROR, errbuf, PCAP_ERRBUF_SIZE);
+ if (nread == -1)
+ {
+ return -1;
+ }
+ *plen -= nread;
+ return 0;
+}
+
+/*
+ * This handles the RPCAP_MSG_ERROR message.
+ */
+static void rpcap_msg_err(SOCKET sockctrl, uint32 plen, char *remote_errbuf)
+{
+ char errbuf[PCAP_ERRBUF_SIZE];
+
+ if (plen >= PCAP_ERRBUF_SIZE)
+ {
+ /*
+ * Message is too long; just read as much of it as we
+ * can into the buffer provided, and discard the rest.
+ */
+ if (sock_recv(sockctrl, remote_errbuf, PCAP_ERRBUF_SIZE - 1,
+ SOCK_RECEIVEALL_YES|SOCK_EOF_IS_ERROR, errbuf,
+ PCAP_ERRBUF_SIZE) == -1)
+ {
+ // Network error.
+ pcap_snprintf(remote_errbuf, PCAP_ERRBUF_SIZE, "Read of error message from client failed: %s", errbuf);
+ return;
+ }
+
+ /*
+ * Null-terminate it.
+ */
+ remote_errbuf[PCAP_ERRBUF_SIZE - 1] = '\0';
+
+ /*
+ * Throw away the rest.
+ */
+ (void)rpcap_discard(sockctrl, plen - (PCAP_ERRBUF_SIZE - 1), remote_errbuf);
+ }
+ else if (plen == 0)
+ {
+ /* Empty error string. */
+ remote_errbuf[0] = '\0';
+ }
+ else
+ {
+ if (sock_recv(sockctrl, remote_errbuf, plen,
+ SOCK_RECEIVEALL_YES|SOCK_EOF_IS_ERROR, errbuf,
+ PCAP_ERRBUF_SIZE) == -1)
+ {
+ // Network error.
+ pcap_snprintf(remote_errbuf, PCAP_ERRBUF_SIZE, "Read of error message from client failed: %s", errbuf);
+ return;
+ }
+
+ /*
+ * Null-terminate it.
+ */
+ remote_errbuf[plen] = '\0';
+ }
+}
+
+/*
+ * Discard data from a connection.
+ * Mostly used to discard wrong-sized messages.
+ * Returns 0 on success, logs a message and returns -1 on a network
+ * error.
+ */
+static int rpcap_discard(SOCKET sock, uint32 len, char *errbuf)
+{
+ if (len != 0)
+ {
+ if (sock_discard(sock, len, errbuf, PCAP_ERRBUF_SIZE) == -1)
+ {
+ // Network error.
+ return -1;
+ }
+ }
+ return 0;
+}
+
+/*
+ * Read bytes into the pcap_t's buffer until we have the specified
+ * number of bytes read or we get an error or interrupt indication.
+ */
+static int rpcap_read_packet_msg(SOCKET sock, pcap_t *p, size_t size)
+{
+ u_char *bp;
+ int cc;
+ int bytes_read;
+
+ bp = p->bp;
+ cc = p->cc;
+
+ /*
+ * Loop until we have the amount of data requested or we get
+ * an error or interrupt.
+ */
+ while ((size_t)cc < size)
+ {
+ /*
+ * We haven't read all of the packet header yet.
+ * Read what remains, which could be all of it.
+ */
+ bytes_read = sock_recv(sock, bp, size - cc,
+ SOCK_RECEIVEALL_NO|SOCK_EOF_IS_ERROR, p->errbuf,
+ PCAP_ERRBUF_SIZE);
+ if (bytes_read == -1)
+ {
+ /*
+ * Network error. Update the read pointer and
+ * byte count, and return an error indication.
+ */
+ p->bp = bp;
+ p->cc = cc;
+ return -1;
+ }
+ if (bytes_read == -3)
+ {
+ /*
+ * Interrupted receive. Update the read
+ * pointer and byte count, and return
+ * an interrupted indication.
+ */
+ p->bp = bp;
+ p->cc = cc;
+ return -3;
+ }
+ if (bytes_read == 0)
+ {
+ /*
+ * EOF - server terminated the connection.
+ * Update the read pointer and byte count, and
+ * return an error indication.
+ */
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "The server terminated the connection.");
+ return -1;
+ }
+ bp += bytes_read;
+ cc += bytes_read;
+ }
+ p->bp = bp;
+ p->cc = cc;
return 0;
}
diff --git a/contrib/libpcap/pcap-rpcap.h b/contrib/libpcap/pcap-rpcap.h
index f84e8ba525778..be31c40d18310 100644
--- a/contrib/libpcap/pcap-rpcap.h
+++ b/contrib/libpcap/pcap-rpcap.h
@@ -1,465 +1,49 @@
/*
- * Copyright (c) 2002 - 2005 NetGroup, Politecnico di Torino (Italy)
- * Copyright (c) 2005 - 2008 CACE Technologies, Davis (California)
- * All rights reserved.
+ * Copyright (c) 1994, 1995, 1996
+ * 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.
+ * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the Politecnico di Torino, CACE Technologies
- * nor the names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#ifndef __PCAP_RPCAP_H__
-#define __PCAP_RPCAP_H__
-
-
-#include "pcap.h"
-#include "sockutils.h" /* Needed for some structures (like SOCKET, sockaddr_in) which are used here */
-
-
-/*
- * \file pcap-pcap.h
- *
- * This file keeps all the new definitions and typedefs that are exported to the user and
- * that are needed for the RPCAP protocol.
- *
- * \warning All the RPCAP functions that are allowed to return a buffer containing
- * the error description can return max PCAP_ERRBUF_SIZE characters.
- * However there is no guarantees that the string will be zero-terminated.
- * Best practice is to define the errbuf variable as a char of size 'PCAP_ERRBUF_SIZE+1'
- * and to insert manually the termination char at the end of the buffer. This will
- * guarantee that no buffer overflows occur even if we use the printf() to show
- * the error on the screen.
- *
- * \warning This file declares some typedefs that MUST be of a specific size.
- * These definitions (i.e. typedefs) could need to be changed on other platforms than
- * Intel IA32.
- *
- * \warning This file defines some structures that are used to transfer data on the network.
- * Be careful that you compiler MUST not insert padding into these structures
- * for better alignment.
- * These structures have been created in order to be correctly aligned to a 32 bits
- * boundary, but be careful in any case.
- */
-
-
-
-
-
-
-
-
-/*********************************************************
- * *
- * General definitions / typedefs for the RPCAP protocol *
- * *
- *********************************************************/
-
-/* All the following structures and typedef belongs to the Private Documentation */
-/*
- * \addtogroup remote_pri_struct
- * \{
- */
-
-#define RPCAP_DEFAULT_NETPORT "2002" /* Default port on which the RPCAP daemon is waiting for connections. */
-/* Default port on which the client workstation is waiting for connections in case of active mode. */
-#define RPCAP_DEFAULT_NETPORT_ACTIVE "2003"
-#define RPCAP_DEFAULT_NETADDR "" /* Default network address on which the RPCAP daemon binds to. */
-#define RPCAP_VERSION 0 /* Present version of the RPCAP protocol (0 = Experimental). */
-#define RPCAP_TIMEOUT_INIT 90 /* Initial timeout for RPCAP connections (default: 90 sec) */
-#define RPCAP_TIMEOUT_RUNTIME 180 /* Run-time timeout for RPCAP connections (default: 3 min) */
-#define RPCAP_ACTIVE_WAIT 30 /* Waiting time between two attempts to open a connection, in active mode (default: 30 sec) */
-#define RPCAP_SUSPEND_WRONGAUTH 1 /* If the authentication is wrong, stops 1 sec before accepting a new auth message */
-
-/*
- * \brief Buffer used by socket functions to send-receive packets.
- * In case you plan to have messages larger than this value, you have to increase it.
- */
-#define RPCAP_NETBUF_SIZE 64000
-
-
-/*
- * \brief Separators used for the host list.
- *
- * It is used:
- * - by the rpcapd daemon, when you types a list of allowed connecting hosts
- * - by the rpcap in active mode, when the client waits for incoming connections from other hosts
- */
-#define RPCAP_HOSTLIST_SEP " ,;\n\r"
-
-
-
-
-/* WARNING: These could need to be changed on other platforms */
-typedef unsigned char uint8; /* Provides an 8-bits unsigned integer */
-typedef unsigned short uint16; /* Provides a 16-bits unsigned integer */
-typedef unsigned int uint32; /* Provides a 32-bits unsigned integer */
-typedef int int32; /* Provides a 32-bits integer */
-
-
-
-
-/*
- * \brief Keeps a list of all the opened connections in the active mode.
- *
- * This structure defines a linked list of items that are needed to keep the info required to
- * manage the active mode.
- * In other words, when a new connection in active mode starts, this structure is updated so that
- * it reflects the list of active mode connections currently opened.
- * This structure is required by findalldevs() and open_remote() to see if they have to open a new
- * control connection toward the host, or they already have a control connection in place.
- */
-struct activehosts
-{
- struct sockaddr_storage host;
- SOCKET sockctrl;
- struct activehosts *next;
-};
-
-
-/*********************************************************
- * *
- * Protocol messages formats *
- * *
- *********************************************************/
-/* WARNING Take care you compiler does not insert padding for better alignments into these structs */
-
-
-/* Common header for all the RPCAP messages */
-struct rpcap_header
-{
- uint8 ver; /* RPCAP version number */
- uint8 type; /* RPCAP message type (error, findalldevs, ...) */
- uint16 value; /* Message-dependent value (not always used) */
- uint32 plen; /* Length of the payload of this RPCAP message */
-};
-
-
-/* Format of the message for the interface description (findalldevs command) */
-struct rpcap_findalldevs_if
-{
- uint16 namelen; /* Length of the interface name */
- uint16 desclen; /* Length of the interface description */
- uint32 flags; /* Interface flags */
- uint16 naddr; /* Number of addresses */
- uint16 dummy; /* Must be zero */
-};
-
-
-/* Format of the message for the address listing (findalldevs command) */
-struct rpcap_findalldevs_ifaddr
-{
- struct sockaddr_storage addr; /* Network address */
- struct sockaddr_storage netmask; /* Netmask for that address */
- struct sockaddr_storage broadaddr; /* Broadcast address for that address */
- struct sockaddr_storage dstaddr; /* P2P destination address for that address */
-};
-
-
-
-/*
- * \brief Format of the message of the connection opening reply (open command).
- *
- * This structure transfers over the network some of the values useful on the client side.
- */
-struct rpcap_openreply
-{
- int32 linktype; /* Link type */
- int32 tzoff; /* Timezone offset */
-};
-
-
-
-/* Format of the message that starts a remote capture (startcap command) */
-struct rpcap_startcapreq
-{
- uint32 snaplen; /* Length of the snapshot (number of bytes to capture for each packet) */
- uint32 read_timeout; /* Read timeout in milliseconds */
- uint16 flags; /* Flags (see RPCAP_STARTCAPREQ_FLAG_xxx) */
- uint16 portdata; /* Network port on which the client is waiting at (if 'serveropen') */
-};
-
-
-/* Format of the reply message that devoted to start a remote capture (startcap reply command) */
-struct rpcap_startcapreply
-{
- int32 bufsize; /* Size of the user buffer allocated by WinPcap; it can be different from the one we chose */
- uint16 portdata; /* Network port on which the server is waiting at (passive mode only) */
- uint16 dummy; /* Must be zero */
-};
-
-
-/*
- * \brief Format of the header which encapsulates captured packets when transmitted on the network.
+ * 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 message requires the general header as well, since we want to be able to exchange
- * more information across the network in the future (for example statistics, and kind like that).
+ * 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.
*/
-struct rpcap_pkthdr
-{
- uint32 timestamp_sec; /* 'struct timeval' compatible, it represents the 'tv_sec' field */
- uint32 timestamp_usec; /* 'struct timeval' compatible, it represents the 'tv_usec' field */
- uint32 caplen; /* Length of portion present in the capture */
- uint32 len; /* Real length this packet (off wire) */
- uint32 npkt; /* Ordinal number of the packet (i.e. the first one captured has '1', the second one '2', etc) */
-};
-
-
-/* General header used for the pcap_setfilter() command; keeps just the number of BPF instructions */
-struct rpcap_filter
-{
- uint16 filtertype; /* type of the filter transferred (BPF instructions, ...) */
- uint16 dummy; /* Must be zero */
- uint32 nitems; /* Number of items contained into the filter (e.g. BPF instructions for BPF filters) */
-};
-
-
-/* Structure that keeps a single BPF instuction; it is repeated 'ninsn' times according to the 'rpcap_filterbpf' header */
-struct rpcap_filterbpf_insn
-{
- uint16 code; /* opcode of the instruction */
- uint8 jt; /* relative offset to jump to in case of 'true' */
- uint8 jf; /* relative offset to jump to in case of 'false' */
- int32 k; /* instruction-dependent value */
-};
-
-
-/* Structure that keeps the data required for the authentication on the remote host */
-struct rpcap_auth
-{
- uint16 type; /* Authentication type */
- uint16 dummy; /* Must be zero */
- uint16 slen1; /* Length of the first authentication item (e.g. username) */
- uint16 slen2; /* Length of the second authentication item (e.g. password) */
-};
-
-
-/* Structure that keeps the statistics about the number of packets captured, dropped, etc. */
-struct rpcap_stats
-{
- uint32 ifrecv; /* Packets received by the kernel filter (i.e. pcap_stats.ps_recv) */
- uint32 ifdrop; /* Packets dropped by the network interface (e.g. not enough buffers) (i.e. pcap_stats.ps_ifdrop) */
- uint32 krnldrop; /* Packets dropped by the kernel filter (i.e. pcap_stats.ps_drop) */
- uint32 svrcapt; /* Packets captured by the RPCAP daemon and sent on the network */
-};
-
-
-/* Structure that is needed to set sampling parameters */
-struct rpcap_sampling
-{
- uint8 method; /* Sampling method */
- uint8 dummy1; /* Must be zero */
- uint16 dummy2; /* Must be zero */
- uint32 value; /* Parameter related to the sampling method */
-};
+#ifndef pcap_rpcap_h
+#define pcap_rpcap_h
/*
- * Private data for doing a live capture.
+ * Internal interfaces for "pcap_open()".
*/
-struct pcap_md {
- struct pcap_stat stat;
- /* XXX */
- int use_bpf; /* using kernel filter */
- u_long TotPkts; /* can't overflow for 79 hrs on ether */
- u_long TotAccepted; /* count accepted by filter */
- u_long TotDrops; /* count of dropped packets */
- long TotMissed; /* missed by i/f during this run */
- long OrigMissed; /* missed by i/f before this run */
- char *device; /* device name */
- int timeout; /* timeout for buffering */
- int must_clear; /* stuff we must clear when we close */
- struct pcap *next; /* list of open pcaps that need stuff cleared on close */
-#ifdef linux
- int sock_packet; /* using Linux 2.0 compatible interface */
- int cooked; /* using SOCK_DGRAM rather than SOCK_RAW */
- int ifindex; /* interface index of device we're bound to */
- int lo_ifindex; /* interface index of the loopback device */
- u_int packets_read; /* count of packets read with recvfrom() */
- bpf_u_int32 oldmode; /* mode to restore when turning monitor mode off */
- u_int tp_version; /* version of tpacket_hdr for mmaped ring */
- u_int tp_hdrlen; /* hdrlen of tpacket_hdr for mmaped ring */
-#endif /* linux */
-
-#ifdef HAVE_DAG_API
-#ifdef HAVE_DAG_STREAMS_API
- u_char *dag_mem_bottom;/* DAG card current memory bottom pointer */
- u_char *dag_mem_top; /* DAG card current memory top pointer */
-#else /* HAVE_DAG_STREAMS_API */
- void *dag_mem_base; /* DAG card memory base address */
- u_int dag_mem_bottom; /* DAG card current memory bottom offset */
- u_int dag_mem_top; /* DAG card current memory top offset */
-#endif /* HAVE_DAG_STREAMS_API */
- int dag_fcs_bits; /* Number of checksum bits from link layer */
- int dag_offset_flags; /* Flags to pass to dag_offset(). */
- int dag_stream; /* DAG stream number */
- int dag_timeout; /* timeout specified to pcap_open_live.
- * Same as in linux above, introduce
- * generally?
- */
-#endif /* HAVE_DAG_API */
-#ifdef HAVE_ZEROCOPY_BPF
- /*
- * Zero-copy read buffer -- for zero-copy BPF. 'buffer' above will
- * alternative between these two actual mmap'd buffers as required.
- * As there is a header on the front size of the mmap'd buffer, only
- * some of the buffer is exposed to libpcap as a whole via bufsize;
- * zbufsize is the true size. zbuffer tracks the current zbuf
- * associated with buffer so that it can be used to decide which the
- * next buffer to read will be.
- */
- u_char *zbuf1, *zbuf2, *zbuffer;
- u_int zbufsize;
- u_int zerocopy;
- u_int interrupted;
- struct timespec firstsel;
- /*
- * If there's currently a buffer being actively processed, then it is
- * referenced here; 'buffer' is also pointed at it, but offset by the
- * size of the header.
- */
- struct bpf_zbuf_header *bzh;
-#endif /* HAVE_ZEROCOPY_BPF */
-
-
-
-#ifdef HAVE_REMOTE
- /*
- * There is really a mess with previous variables, and it seems to me that they are not used
- * (they are used in pcap_pf.c only). I think we have to start using them.
- * The meaning is the following:
- *
- * - TotPkts: the amount of packets received by the bpf filter, *before* applying the filter
- * - TotAccepted: the amount of packets that satisfies the filter
- * - TotDrops: the amount of packet that were dropped into the kernel buffer because of lack of space
- * - TotMissed: the amount of packets that were dropped by the physical interface; it is basically
- * the value of the hardware counter into the card. This number is never put to zero, so this number
- * takes into account the *total* number of interface drops starting from the interface power-on.
- * - OrigMissed: the amount of packets that were dropped by the interface *when the capture begins*.
- * This value is used to detect the number of packets dropped by the interface *during the present
- * capture*, so that (ps_ifdrops= TotMissed - OrigMissed).
- */
- unsigned int TotNetDrops; /* keeps the number of packets that have been dropped by the network */
- /*
- * \brief It keeps the number of packets that have been received by the application.
- *
- * Packets dropped by the kernel buffer are not counted in this variable. The variable is always
- * equal to (TotAccepted - TotDrops), except for the case of remote capture, in which we have also
- * packets in flight, i.e. that have been transmitted by the remote host, but that have not been
- * received (yet) from the client. In this case, (TotAccepted - TotDrops - TotNetDrops) gives a
- * wrong result, since this number does not corresponds always to the number of packet received by
- * the application. For this reason, in the remote capture we need another variable that takes
- * into account of the number of packets actually received by the application.
- */
- unsigned int TotCapt;
-
- /*! \brief '1' if we're the network client; needed by several functions (like pcap_setfilter() ) to know if
- they have to use the socket or they have to open the local adapter. */
- int rmt_clientside;
-
- SOCKET rmt_sockctrl; //!< socket ID of the socket used for the control connection
- SOCKET rmt_sockdata; //!< socket ID of the socket used for the data connection
- int rmt_flags; //!< we have to save flags, since they are passed by the pcap_open_live(), but they are used by the pcap_startcapture()
- int rmt_capstarted; //!< 'true' if the capture is already started (needed to knoe if we have to call the pcap_startcapture()
- struct pcap_samp rmt_samp; //!< Keeps the parameters related to the sampling process.
- char *currentfilter; //!< Pointer to a buffer (allocated at run-time) that stores the current filter. Needed when flag PCAP_OPENFLAG_NOCAPTURE_RPCAP is turned on.
-#endif /* HAVE_REMOTE */
+pcap_t *pcap_open_rpcap(const char *source, int snaplen, int flags,
+ int read_timeout, struct pcap_rmtauth *auth, char *errbuf);
-};
-
-
-/* Messages field coding */
-#define RPCAP_MSG_ERROR 1 /* Message that keeps an error notification */
-#define RPCAP_MSG_FINDALLIF_REQ 2 /* Request to list all the remote interfaces */
-#define RPCAP_MSG_OPEN_REQ 3 /* Request to open a remote device */
-#define RPCAP_MSG_STARTCAP_REQ 4 /* Request to start a capture on a remote device */
-#define RPCAP_MSG_UPDATEFILTER_REQ 5 /* Send a compiled filter into the remote device */
-#define RPCAP_MSG_CLOSE 6 /* Close the connection with the remote peer */
-#define RPCAP_MSG_PACKET 7 /* This is a 'data' message, which carries a network packet */
-#define RPCAP_MSG_AUTH_REQ 8 /* Message that keeps the authentication parameters */
-#define RPCAP_MSG_STATS_REQ 9 /* It requires to have network statistics */
-#define RPCAP_MSG_ENDCAP_REQ 10 /* Stops the current capture, keeping the device open */
-#define RPCAP_MSG_SETSAMPLING_REQ 11 /* Set sampling parameters */
-
-#define RPCAP_MSG_FINDALLIF_REPLY (128+RPCAP_MSG_FINDALLIF_REQ) /* Keeps the list of all the remote interfaces */
-#define RPCAP_MSG_OPEN_REPLY (128+RPCAP_MSG_OPEN_REQ) /* The remote device has been opened correctly */
-#define RPCAP_MSG_STARTCAP_REPLY (128+RPCAP_MSG_STARTCAP_REQ) /* The capture is starting correctly */
-#define RPCAP_MSG_UPDATEFILTER_REPLY (128+RPCAP_MSG_UPDATEFILTER_REQ) /* The filter has been applied correctly on the remote device */
-#define RPCAP_MSG_AUTH_REPLY (128+RPCAP_MSG_AUTH_REQ) /* Sends a message that says 'ok, authorization successful' */
-#define RPCAP_MSG_STATS_REPLY (128+RPCAP_MSG_STATS_REQ) /* Message that keeps the network statistics */
-#define RPCAP_MSG_ENDCAP_REPLY (128+RPCAP_MSG_ENDCAP_REQ) /* Confirms that the capture stopped successfully */
-#define RPCAP_MSG_SETSAMPLING_REPLY (128+RPCAP_MSG_SETSAMPLING_REQ) /* Confirms that the capture stopped successfully */
-
-#define RPCAP_STARTCAPREQ_FLAG_PROMISC 1 /* Enables promiscuous mode (default: disabled) */
-#define RPCAP_STARTCAPREQ_FLAG_DGRAM 2 /* Use a datagram (i.e. UDP) connection for the data stream (default: use TCP)*/
-#define RPCAP_STARTCAPREQ_FLAG_SERVEROPEN 4 /* The server has to open the data connection toward the client */
-#define RPCAP_STARTCAPREQ_FLAG_INBOUND 8 /* Capture only inbound packets (take care: the flag has no effects with promiscuous enabled) */
-#define RPCAP_STARTCAPREQ_FLAG_OUTBOUND 16 /* Capture only outbound packets (take care: the flag has no effects with promiscuous enabled) */
-
-#define RPCAP_UPDATEFILTER_BPF 1 /* This code tells us that the filter is encoded with the BPF/NPF syntax */
-
-
-/* Network error codes */
-#define PCAP_ERR_NETW 1 /* Network error */
-#define PCAP_ERR_INITTIMEOUT 2 /* The RPCAP initial timeout has expired */
-#define PCAP_ERR_AUTH 3 /* Generic authentication error */
-#define PCAP_ERR_FINDALLIF 4 /* Generic findalldevs error */
-#define PCAP_ERR_NOREMOTEIF 5 /* The findalldevs was ok, but the remote end had no interfaces to list */
-#define PCAP_ERR_OPEN 6 /* Generic pcap_open error */
-#define PCAP_ERR_UPDATEFILTER 7 /* Generic updatefilter error */
-#define PCAP_ERR_GETSTATS 8 /* Generic pcap_stats error */
-#define PCAP_ERR_READEX 9 /* Generic pcap_next_ex error */
-#define PCAP_ERR_HOSTNOAUTH 10 /* The host is not authorized to connect to this server */
-#define PCAP_ERR_REMOTEACCEPT 11 /* Generic pcap_remoteaccept error */
-#define PCAP_ERR_STARTCAPTURE 12 /* Generic pcap_startcapture error */
-#define PCAP_ERR_ENDCAPTURE 13 /* Generic pcap_endcapture error */
-#define PCAP_ERR_RUNTIMETIMEOUT 14 /* The RPCAP run-time timeout has expired */
-#define PCAP_ERR_SETSAMPLING 15 /* Error during the settings of sampling parameters */
-#define PCAP_ERR_WRONGMSG 16 /* The other end endpoint sent a message which has not been recognized */
-#define PCAP_ERR_WRONGVER 17 /* The other end endpoint has a version number that is not compatible with our */
/*
- * \}
- * // end of private documentation
+ * Internal interfaces for "pcap_findalldevs_ex()".
*/
-
-
-/*********************************************************
- * *
- * Exported function prototypes *
- * *
- *********************************************************/
-int pcap_opensource_remote(pcap_t *p, struct pcap_rmtauth *auth);
-int pcap_startcapture_remote(pcap_t *fp);
-
-void rpcap_createhdr(struct rpcap_header *header, uint8 type, uint16 value, uint32 length);
-int rpcap_deseraddr(struct sockaddr_storage *sockaddrin, struct sockaddr_storage **sockaddrout, char *errbuf);
-int rpcap_checkmsg(char *errbuf, SOCKET sock, struct rpcap_header *header, uint8 first, ...);
-int rpcap_senderror(SOCKET sock, char *error, unsigned short errcode, char *errbuf);
-int rpcap_sendauth(SOCKET sock, struct pcap_rmtauth *auth, char *errbuf);
-
-SOCKET rpcap_remoteact_getsock(const char *host, int *isactive, char *errbuf);
+int pcap_findalldevs_ex_remote(char *source, struct pcap_rmtauth *auth,
+ pcap_if_t **alldevs, char *errbuf);
#endif
-
diff --git a/contrib/libpcap/pcap-savefile.manfile b/contrib/libpcap/pcap-savefile.manfile
deleted file mode 100644
index 3b14d2ce239c2..0000000000000
--- a/contrib/libpcap/pcap-savefile.manfile
+++ /dev/null
@@ -1,133 +0,0 @@
-.\" Copyright (c) 1994, 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: (1) source code distributions
-.\" retain the above copyright notice and this paragraph in its entirety, (2)
-.\" distributions including binary code include the above copyright notice and
-.\" this paragraph in its entirety in the documentation or other materials
-.\" provided with the distribution, and (3) all advertising materials mentioning
-.\" features or use of this software display the following acknowledgement:
-.\" ``This product includes software developed by the University of California,
-.\" Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
-.\" the University nor the names of its contributors may be used to endorse
-.\" or promote products derived from this software without specific prior
-.\" written permission.
-.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
-.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
-.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
-.\"
-.TH PCAP-SAVEFILE 5 "29 July 2013"
-.SH NAME
-pcap-savefile \- libpcap savefile format
-.SH DESCRIPTION
-NOTE: applications and libraries should, if possible, use libpcap to
-read savefiles, rather than having their own code to read savefiles.
-If, in the future, a new file format is supported by libpcap,
-applications and libraries using libpcap to read savefiles will be able
-to read the new format of savefiles, but applications and libraries
-using their own code to read savefiles will have to be changed to
-support the new file format.
-.PP
-``Savefiles'' read and written by libpcap and applications using libpcap
-start with a per-file header. The format of the per-file header is:
-.RS
-.TS
-box;
-c s
-c | c
-c s.
-Magic number
-_
-Major version Minor version
-_
-Time zone offset
-_
-Time stamp accuracy
-_
-Snapshot length
-_
-Link-layer header type
-.TE
-.RE
-.PP
-All fields in the per-file header are in the byte order of the host
-writing the file. Normally, the first field in the per-file header is a
-4-byte magic number, with the value 0xa1b2c3d4. The magic number, when
-read by a host with the same byte order as the host that wrote the file,
-will have the value 0xa1b2c3d4, and, when read by a host with the
-opposite byte order as the host that wrote the file, will have the value
-0xd4c3b2a1. That allows software reading the file to determine whether
-the byte order of the host that wrote the file is the same as the byte
-order of the host on which the file is being read, and thus whether the
-values in the per-file and per-packet headers need to be byte-swapped.
-.PP
-If the magic number has the value 0xa1b23c4d (with the two nibbles of
-the two lower-order bytes of the magic number swapped), which would be
-read as 0xa1b23c4d by a host with the same byte order as the host that
-wrote the file and as 0x4d3cb2a1 by a host with the opposite byte order
-as the host that wrote the file, the file format is the same as for
-regular files, except that the time stamps for packets are given in
-seconds and nanoseconds rather than seconds and microseconds.
-.PP
-Following this are:
-.IP
-A 2-byte file format major version number; the current version number is
-2.
-.IP
-A 2-byte file format minor version number; the current version number is
-4.
-.IP
-A 4-byte time zone offset; this is always 0.
-.IP
-A 4-byte number giving the accuracy of time stamps in the file; this is
-always 0.
-.IP
-A 4-byte number giving the "snapshot length" of the capture; packets
-longer than the snapshot length are truncated to the snapshot length, so
-that, if the snapshot length is
-.IR N ,
-only the first
-.I N
-bytes of a packet longer than
-.I N
-bytes will be saved in the capture.
-.IP
-a 4-byte number giving the link-layer header type for packets in the
-capture; see
-.BR pcap-linktype (7)
-for the
-.B LINKTYPE_
-values that can appear in this field.
-.PP
-Following the per-file header are zero or more packets; each packet
-begins with a per-packet header, which is immediately followed by the
-raw packet data. The format of the per-packet header is:
-.RS
-.TS
-box;
-c.
-Time stamp, seconds value
-_
-Time stamp, microseconds or nanoseconds value
-_
-Length of captured packet data
-_
-Un-truncated length of the packet data
-.TE
-.RE
-.PP
-All fields in the per-packet header are in the byte order of the host
-writing the file. The per-packet header begins with a time stamp giving
-the approximate time the packet was captured; the time stamp consists of
-a 4-byte value, giving the time in seconds since January 1, 1970,
-00:00:00 UTC, followed by a 4-byte value, giving the time in
-microseconds or nanoseconds since that second, depending on the magic
-number in the file header. Following that are a 4-byte value giving the
-number of bytes of captured data that follow the per-packet header and a
-4-byte value giving the number of bytes that would have been present had
-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(7)
diff --git a/contrib/libpcap/pcap-septel.c b/contrib/libpcap/pcap-septel.c
index 88dc89df62dc4..0471153fdc7a6 100644
--- a/contrib/libpcap/pcap-septel.c
+++ b/contrib/libpcap/pcap-septel.c
@@ -15,7 +15,7 @@
*/
#ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
#endif
#include <sys/param.h>
@@ -43,7 +43,8 @@
static int septel_setfilter(pcap_t *p, struct bpf_program *fp);
static int septel_stats(pcap_t *p, struct pcap_stat *ps);
-static int septel_setnonblock(pcap_t *p, int nonblock, char *errbuf);
+static int septel_getnonblock(pcap_t *p);
+static int septel_setnonblock(pcap_t *p, int nonblock);
/*
* Private data for capturing on Septel devices.
@@ -197,6 +198,17 @@ static pcap_t *septel_activate(pcap_t* handle) {
/* Initialize some components of the pcap structure. */
handle->linktype = DLT_MTP2;
+ /*
+ * Turn a negative snapshot value (invalid), a snapshot value of
+ * 0 (unspecified), or a value bigger than the normal maximum
+ * value, into the maximum allowed value.
+ *
+ * If some application really *needs* a bigger snapshot
+ * length, we should just increase MAXIMUM_SNAPLEN.
+ */
+ if (handle->snapshot <= 0 || handle->snapshot > MAXIMUM_SNAPLEN)
+ handle->snapshot = MAXIMUM_SNAPLEN;
+
handle->bufsize = 0;
/*
@@ -208,7 +220,7 @@ static pcap_t *septel_activate(pcap_t* handle) {
handle->inject_op = septel_inject;
handle->setfilter_op = septel_setfilter;
handle->set_datalink_op = NULL; /* can't change data link type */
- handle->getnonblock_op = pcap_getnonblock_fd;
+ handle->getnonblock_op = septel_getnonblock;
handle->setnonblock_op = septel_setnonblock;
handle->stats_op = septel_stats;
@@ -237,6 +249,15 @@ pcap_t *septel_create(const char *device, char *ebuf, int *is_ours) {
return NULL;
p->activate_op = septel_activate;
+ /*
+ * Set these up front, so that, even if our client tries
+ * to set non-blocking mode before we're activated, or
+ * query the state of non-blocking mode, they get an error,
+ * rather than having the non-blocking mode option set
+ * for use later.
+ */
+ p->getnonblock_op = septel_getnonblock;
+ p->setnonblock_op = septel_setnonblock;
return p;
}
@@ -252,10 +273,14 @@ static int septel_stats(pcap_t *p, struct pcap_stat *ps) {
int
-septel_findalldevs(pcap_if_t **devlistp, char *errbuf)
+septel_findalldevs(pcap_if_list_t *devlistp, char *errbuf)
{
- return (pcap_add_if(devlistp,"septel",0,
- "Intel/Septel device",errbuf));
+ /*
+ * XXX - do the notions of "up", "running", or "connected" apply here?
+ */
+ if (add_dev(devlistp,"septel",0,"Intel/Septel device",errbuf) == NULL)
+ return -1;
+ return 0;
}
@@ -275,20 +300,29 @@ static int septel_setfilter(pcap_t *p, struct bpf_program *fp) {
/* Make our private copy of the filter */
- if (install_bpf_program(p, fp) < 0) {
- pcap_snprintf(p->errbuf, sizeof(p->errbuf),
- "malloc: %s", pcap_strerror(errno));
+ if (install_bpf_program(p, fp) < 0)
return -1;
- }
return (0);
}
+/*
+ * We don't support non-blocking mode. I'm not sure what we'd
+ * do to support it and, given that we don't support select()/
+ * poll()/epoll_wait()/kevent() etc., it probably doesn't
+ * matter.
+ */
+static int
+septel_getnonblock(pcap_t *p)
+{
+ fprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Non-blocking mode not supported on Septel devices");
+ return (-1);
+}
static int
-septel_setnonblock(pcap_t *p, int nonblock, char *errbuf)
+septel_setnonblock(pcap_t *p, int nonblock _U_)
{
- fprintf(errbuf, PCAP_ERRBUF_SIZE, "Non-blocking mode not supported on Septel devices");
+ fprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Non-blocking mode not supported on Septel devices");
return (-1);
}
@@ -302,9 +336,8 @@ septel_setnonblock(pcap_t *p, int nonblock, char *errbuf)
* There are no regular interfaces, just Septel interfaces.
*/
int
-pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
+pcap_platform_finddevs(pcap_if_list_t *devlistp, char *errbuf)
{
- *alldevsp = NULL;
return (0);
}
@@ -318,4 +351,13 @@ pcap_create_interface(const char *device, char *errbuf)
"This version of libpcap only supports Septel cards");
return (NULL);
}
+
+/*
+ * Libpcap version string.
+ */
+const char *
+pcap_lib_version(void)
+{
+ return (PCAP_VERSION_STRING " (Septel-only)");
+}
#endif
diff --git a/contrib/libpcap/pcap-septel.h b/contrib/libpcap/pcap-septel.h
index b6e1168b0ef85..0e648b20c6018 100644
--- a/contrib/libpcap/pcap-septel.h
+++ b/contrib/libpcap/pcap-septel.h
@@ -10,4 +10,4 @@
*/
pcap_t *septel_create(const char *device, char *ebuf, int *is_ours);
-int septel_findalldevs(pcap_if_t **devlistp, char *errbuf);
+int septel_findalldevs(pcap_if_list_t *devlistp, char *errbuf);
diff --git a/contrib/libpcap/pcap-sita.c b/contrib/libpcap/pcap-sita.c
index 1cd5f7510a041..7c42791aab8b7 100644
--- a/contrib/libpcap/pcap-sita.c
+++ b/contrib/libpcap/pcap-sita.c
@@ -25,7 +25,7 @@
*/
#ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
#endif
#include <stdio.h>
@@ -293,7 +293,8 @@ int acn_parse_hosts_file(char *errbuf) { /* returns: -1 = error, 0 = OK */
continue; /* and ignore the entry */
}
if ((ptr2 = (char *)malloc(strlen(ptr) + 1)) == NULL) {
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ errno, "malloc");
continue;
}
strcpy(ptr2, ptr); /* copy the IP address into our malloc'ed memory */
@@ -582,7 +583,8 @@ static int process_client_data (char *errbuf) { /* returns: -1 = error, 0
ptr = u->imsg; /* point to the start of the msg for this IOP */
while (ptr < (u->imsg + u->len)) {
if ((iff = malloc(sizeof(pcap_if_t))) == NULL) {
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(errbuf,
+ PCAP_ERRBUF_SIZE, errno, "malloc");
return -1;
}
memset((char *)iff, 0, sizeof(pcap_if_t)); /* bzero() is deprecated, replaced with memset() */
@@ -591,7 +593,9 @@ static int process_client_data (char *errbuf) { /* returns: -1 = error, 0
if (*ptr) { /* if there is a count for the name */
if ((iff->name = malloc(*ptr + 1)) == NULL) { /* get that amount of space */
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(errbuf,
+ PCAP_ERRBUF_SIZE, errno,
+ "malloc");
return -1;
}
memcpy(iff->name, (ptr + 1), *ptr); /* copy the name into the malloc'ed space */
@@ -602,7 +606,9 @@ static int process_client_data (char *errbuf) { /* returns: -1 = error, 0
if (*ptr) { /* if there is a count for the description */
if ((iff->description = malloc(*ptr + 1)) == NULL) { /* get that amount of space */
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(errbuf,
+ PCAP_ERRBUF_SIZE, errno,
+ "malloc");
return -1;
}
memcpy(iff->description, (ptr + 1), *ptr); /* copy the name into the malloc'ed space */
@@ -622,7 +628,9 @@ static int process_client_data (char *errbuf) { /* returns: -1 = error, 0
prev_addr = 0;
while (address_count--) {
if ((addr = malloc(sizeof(pcap_addr_t))) == NULL) {
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(errbuf,
+ PCAP_ERRBUF_SIZE, errno,
+ "malloc");
return -1;
}
memset((char *)addr, 0, sizeof(pcap_addr_t)); /* bzero() is deprecated, replaced with memset() */
@@ -630,7 +638,9 @@ static int process_client_data (char *errbuf) { /* returns: -1 = error, 0
if (prev_addr) prev_addr->next = addr; /* insert a forward link */
if (*ptr) { /* if there is a count for the address */
if ((s = malloc(sizeof(struct sockaddr_in))) == NULL) { /* get that amount of space */
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(errbuf,
+ PCAP_ERRBUF_SIZE,
+ errno, "malloc");
return -1;
}
memset((char *)s, 0, sizeof(struct sockaddr_in)); /* bzero() is deprecated, replaced with memset() */
@@ -642,7 +652,9 @@ static int process_client_data (char *errbuf) { /* returns: -1 = error, 0
ptr++; /* then forwards one more for the 'length of the address' field */
if (*ptr) { /* process any netmask */
if ((s = malloc(sizeof(struct sockaddr_in))) == NULL) {
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(errbuf,
+ PCAP_ERRBUF_SIZE,
+ errno, "malloc");
return -1;
}
/* bzero() is deprecated, replaced with memset() */
@@ -656,7 +668,9 @@ static int process_client_data (char *errbuf) { /* returns: -1 = error, 0
ptr++;
if (*ptr) { /* process any broadcast address */
if ((s = malloc(sizeof(struct sockaddr_in))) == NULL) {
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(errbuf,
+ PCAP_ERRBUF_SIZE,
+ errno, "malloc");
return -1;
}
/* bzero() is deprecated, replaced with memset() */
@@ -670,7 +684,9 @@ static int process_client_data (char *errbuf) { /* returns: -1 = error, 0
ptr++;
if (*ptr) { /* process any destination address */
if ((s = malloc(sizeof(struct sockaddr_in))) == NULL) {
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(errbuf,
+ PCAP_ERRBUF_SIZE,
+ errno, "malloc");
return -1;
}
/* bzero() is deprecated, replaced with memset() */
@@ -689,7 +705,8 @@ static int process_client_data (char *errbuf) { /* returns: -1 = error, 0
newname = translate_IOP_to_pcap_name(u, iff->name, interfaceType); /* add a translation entry and get a point to the mangled name */
bigger_buffer = realloc(iff->name, strlen(newname) + 1));
if (bigger_buffer == NULL) { /* we now re-write the name stored in the interface list */
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "realloc: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(errbuf,
+ PCAP_ERRBUF_SIZE, errno, "realloc");
return -1;
}
iff->name = bigger_buffer;
@@ -821,9 +838,9 @@ static int acn_open_live(const char *name, char *errbuf, int *linktype) { /* re
int chassis, geoslot;
unit_t *u;
iface_t *p;
- pcap_if_t *alldevsp;
+ pcap_if_list_t devlist;
- pcap_platform_finddevs(&alldevsp, errbuf);
+ pcap_platform_finddevs(&devlist, errbuf);
for (chassis = 0; chassis <= MAX_CHASSIS; chassis++) { /* scan the table... */
for (geoslot = 0; geoslot <= MAX_GEOSLOT; geoslot++) {
u = &units[chassis][geoslot];
@@ -992,6 +1009,18 @@ static int pcap_activate_sita(pcap_t *handle) {
&handle->linktype);
if (fd == -1)
return PCAP_ERROR;
+
+ /*
+ * Turn a negative snapshot value (invalid), a snapshot value of
+ * 0 (unspecified), or a value bigger than the normal maximum
+ * value, into the maximum allowed value.
+ *
+ * If some application really *needs* a bigger snapshot
+ * length, we should just increase MAXIMUM_SNAPLEN.
+ */
+ if (handle->snapshot <= 0 || handle->snapshot > MAXIMUM_SNAPLEN)
+ handle->snapshot = MAXIMUM_SNAPLEN;
+
handle->fd = fd;
handle->bufsize = handle->snapshot;
@@ -999,8 +1028,8 @@ static int pcap_activate_sita(pcap_t *handle) {
handle->buffer = malloc(handle->bufsize + handle->offset);
if (!handle->buffer) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "malloc: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "malloc");
pcap_cleanup_acn(handle);
return PCAP_ERROR;
}
@@ -1025,7 +1054,7 @@ pcap_t *pcap_create_interface(const char *device _U_, char *ebuf) {
return (p);
}
-int pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf) {
+int pcap_platform_finddevs(pcap_if_list_t *devlistp, char *errbuf) {
//printf("pcap_findalldevs()\n"); // fulko
@@ -1042,8 +1071,17 @@ int pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf) {
//printf("pcap_findalldevs() returning BAD after findalldevs\n"); // fulko
return -1;
}
- *alldevsp = acn_if_list;
+ devlistp->beginning = acn_if_list;
acn_if_list = 0; /* then forget our list head, because someone will call pcap_freealldevs() to empty the malloc'ed stuff */
//printf("pcap_findalldevs() returning ZERO OK\n"); // fulko
return 0;
}
+
+/*
+ * Libpcap version string.
+ */
+const char *
+pcap_lib_version(void)
+{
+ return PCAP_VERSION_STRING " (SITA-only)";
+}
diff --git a/contrib/libpcap/pcap-snf.c b/contrib/libpcap/pcap-snf.c
index 207c495926b19..4eae0b3993161 100644
--- a/contrib/libpcap/pcap-snf.c
+++ b/contrib/libpcap/pcap-snf.c
@@ -1,19 +1,23 @@
#ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
#endif
+#ifndef _WIN32
#include <sys/param.h>
+#endif /* !_WIN32 */
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
+#ifndef _WIN32
#include <netinet/in.h>
#include <sys/mman.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
+#endif /* !_WIN32 */
#include <snf.h>
#if SNF_VERSION_API >= 0x0003
@@ -30,10 +34,10 @@ struct pcap_snf {
snf_handle_t snf_handle; /* opaque device handle */
snf_ring_t snf_ring; /* opaque device ring handle */
#ifdef SNF_HAVE_INJECT_API
- snf_inject_t snf_inj; /* inject handle, if inject is used */
+ snf_inject_t snf_inj; /* inject handle, if inject is used */
#endif
- int snf_timeout;
- int snf_boardnum;
+ int snf_timeout;
+ int snf_boardnum;
};
static int
@@ -51,8 +55,8 @@ snf_pcap_stats(pcap_t *p, struct pcap_stat *ps)
int rc;
if ((rc = snf_ring_getstats(snfps->snf_ring, &stats))) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "snf_get_stats: %s",
- pcap_strerror(rc));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ rc, "snf_get_stats");
return -1;
}
ps->ps_recv = stats.ring_pkt_recv + stats.ring_pkt_overflow;
@@ -67,8 +71,8 @@ snf_platform_cleanup(pcap_t *p)
struct pcap_snf *ps = p->priv;
#ifdef SNF_HAVE_INJECT_API
- if (ps->snf_inj)
- snf_inject_close(ps->snf_inj);
+ if (ps->snf_inj)
+ snf_inject_close(ps->snf_inj);
#endif
snf_ring_close(ps->snf_ring);
snf_close(ps->snf_handle);
@@ -76,7 +80,7 @@ snf_platform_cleanup(pcap_t *p)
}
static int
-snf_getnonblock(pcap_t *p, char *errbuf)
+snf_getnonblock(pcap_t *p)
{
struct pcap_snf *ps = p->priv;
@@ -84,7 +88,7 @@ snf_getnonblock(pcap_t *p, char *errbuf)
}
static int
-snf_setnonblock(pcap_t *p, int nonblock, char *errbuf)
+snf_setnonblock(pcap_t *p, int nonblock)
{
struct pcap_snf *ps = p->priv;
@@ -107,9 +111,10 @@ snf_timestamp_to_timeval(const int64_t ts_nanosec, const int tstamp_precision)
{
struct timeval tv;
long tv_nsec;
+ const static struct timeval zero_timeval;
- if (ts_nanosec == 0)
- return (struct timeval) { 0, 0 };
+ if (ts_nanosec == 0)
+ return zero_timeval;
tv.tv_sec = ts_nanosec / _NSEC_PER_SEC;
tv_nsec = (ts_nanosec % _NSEC_PER_SEC);
@@ -161,8 +166,8 @@ snf_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
continue;
}
else {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "snf_read: %s",
- pcap_strerror(err));
+ pcap_fmt_errmsg_for_errno(p->errbuf,
+ PCAP_ERRBUF_SIZE, err, "snf_read");
return -1;
}
}
@@ -212,25 +217,25 @@ snf_inject(pcap_t *p, const void *buf _U_, size_t size _U_)
{
#ifdef SNF_HAVE_INJECT_API
struct pcap_snf *ps = p->priv;
- int rc;
- if (ps->snf_inj == NULL) {
- rc = snf_inject_open(ps->snf_boardnum, 0, &ps->snf_inj);
- if (rc) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "snf_inject_open: %s", pcap_strerror(rc));
- return (-1);
- }
- }
-
- rc = snf_inject_send(ps->snf_inj, -1, 0, buf, size);
- if (!rc) {
- return (size);
- }
- else {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "snf_inject_send: %s",
- pcap_strerror(rc));
- return (-1);
- }
+ int rc;
+ if (ps->snf_inj == NULL) {
+ rc = snf_inject_open(ps->snf_boardnum, 0, &ps->snf_inj);
+ if (rc) {
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ rc, "snf_inject_open");
+ return (-1);
+ }
+ }
+
+ rc = snf_inject_send(ps->snf_inj, -1, 0, buf, size);
+ if (!rc) {
+ return (size);
+ }
+ else {
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ rc, "snf_inject_send");
+ return (-1);
+ }
#else
strlcpy(p->errbuf, "Sending packets isn't supported with this snf version",
PCAP_ERRBUF_SIZE);
@@ -248,8 +253,7 @@ snf_activate(pcap_t* p)
int flags = -1, ring_id = -1;
if (device == NULL) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "device is NULL: %s", pcap_strerror(errno));
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "device is NULL");
return -1;
}
@@ -262,15 +266,22 @@ snf_activate(pcap_t* p)
else
nr = NULL;
+
+ /* Allow pcap_set_buffer_size() to set dataring_size.
+ * Default is zero which allows setting from env SNF_DATARING_SIZE.
+ * pcap_set_buffer_size() is in bytes while snf_open() accepts values
+ * between 0 and 1048576 in Megabytes. Values in this range are
+ * mapped to 1MB.
+ */
err = snf_open(ps->snf_boardnum,
0, /* let SNF API parse SNF_NUM_RINGS, if set */
NULL, /* default RSS, or use SNF_RSS_FLAGS env */
- 0, /* default to SNF_DATARING_SIZE from env */
+ (p->opt.buffer_size > 0 && p->opt.buffer_size < 1048576) ? 1048576 : p->opt.buffer_size, /* default to SNF_DATARING_SIZE from env */
flags, /* may want pshared */
&ps->snf_handle);
if (err != 0) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "snf_open failed: %s", pcap_strerror(err));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ err, "snf_open failed");
return -1;
}
@@ -279,12 +290,22 @@ snf_activate(pcap_t* p)
}
err = snf_ring_open_id(ps->snf_handle, ring_id, &ps->snf_ring);
if (err != 0) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "snf_ring_open_id(ring=%d) failed: %s",
- ring_id, pcap_strerror(err));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ err, "snf_ring_open_id(ring=%d) failed", ring_id);
return -1;
}
+ /*
+ * Turn a negative snapshot value (invalid), a snapshot value of
+ * 0 (unspecified), or a value bigger than the normal maximum
+ * value, into the maximum allowed value.
+ *
+ * If some application really *needs* a bigger snapshot
+ * length, we should just increase MAXIMUM_SNAPLEN.
+ */
+ if (p->snapshot <= 0 || p->snapshot > MAXIMUM_SNAPLEN)
+ p->snapshot = MAXIMUM_SNAPLEN;
+
if (p->opt.timeout <= 0)
ps->snf_timeout = -1;
else
@@ -292,15 +313,17 @@ snf_activate(pcap_t* p)
err = snf_start(ps->snf_handle);
if (err != 0) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "snf_start failed: %s", pcap_strerror(err));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ err, "snf_start failed");
return -1;
}
/*
* "select()" and "poll()" don't work on snf descriptors.
*/
+#ifndef _WIN32
p->selectable_fd = -1;
+#endif /* !_WIN32 */
p->linktype = DLT_EN10MB;
p->read_op = snf_read;
p->inject_op = snf_inject;
@@ -312,107 +335,177 @@ snf_activate(pcap_t* p)
p->stats_op = snf_pcap_stats;
p->cleanup_op = snf_platform_cleanup;
#ifdef SNF_HAVE_INJECT_API
- ps->snf_inj = NULL;
+ ps->snf_inj = NULL;
#endif
return 0;
}
#define MAX_DESC_LENGTH 128
int
-snf_findalldevs(pcap_if_t **devlistp, char *errbuf)
+snf_findalldevs(pcap_if_list_t *devlistp, char *errbuf)
{
- pcap_if_t *devlist = NULL,*curdev,*prevdev;
- pcap_addr_t *curaddr;
+ pcap_if_t *dev;
+#ifdef _WIN32
+ struct sockaddr_in addr;
+#endif
struct snf_ifaddrs *ifaddrs, *ifa;
+ char name[MAX_DESC_LENGTH];
char desc[MAX_DESC_LENGTH];
- int ret;
+ int ret, allports = 0, merge = 0;
+ const char *nr = NULL;
- if (snf_init(SNF_VERSION_API))
+ if (snf_init(SNF_VERSION_API)) {
+ (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "snf_getifaddrs: snf_init failed");
return (-1);
+ }
if (snf_getifaddrs(&ifaddrs) || ifaddrs == NULL)
{
- (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "snf_getifaddrs: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ errno, "snf_getifaddrs");
return (-1);
}
- ifa = ifaddrs;
- while (ifa)
- {
- /*
- * Allocate a new entry
- */
- curdev = (pcap_if_t *)malloc(sizeof(pcap_if_t));
- if (curdev == NULL) {
- (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "snf_findalldevs malloc: %s", pcap_strerror(errno));
- return (-1);
- }
- if (devlist == NULL) /* save first entry */
- devlist = curdev;
- else
- prevdev->next = curdev;
- /*
- * Fill in the entry.
- */
- curdev->next = NULL;
- curdev->name = strdup(ifa->snf_ifa_name);
- if (curdev->name == NULL) {
+ if ((nr = getenv("SNF_FLAGS")) && *nr) {
+ errno = 0;
+ merge = strtol(nr, NULL, 0);
+ if (errno) {
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "snf_findalldevs strdup: %s", pcap_strerror(errno));
- free(curdev);
+ "snf_getifaddrs: SNF_FLAGS is not a valid number");
return (-1);
}
- (void)pcap_snprintf(desc,MAX_DESC_LENGTH,"Myricom snf%d",
- ifa->snf_ifa_portnum);
- curdev->description = strdup(desc);
- if (curdev->description == NULL) {
- (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "snf_findalldevs strdup1: %s", pcap_strerror(errno));
- free(curdev->name);
- free(curdev);
- return (-1);
- }
- curdev->addresses = NULL;
- curdev->flags = 0;
+ merge = merge & SNF_F_AGGREGATE_PORTMASK;
+ }
- curaddr = (pcap_addr_t *)malloc(sizeof(pcap_addr_t));
- if (curaddr == NULL) {
- (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "snf_findalldevs malloc1: %s", pcap_strerror(errno));
- free(curdev->description);
- free(curdev->name);
- free(curdev);
- return (-1);
- }
- curdev->addresses = curaddr;
- curaddr->next = NULL;
- curaddr->addr = (struct sockaddr*)malloc(sizeof(struct sockaddr_storage));
- if (curaddr->addr == NULL) {
- (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "malloc2: %s", pcap_strerror(errno));
- free(curdev->description);
- free(curdev->name);
- free(curaddr);
- free(curdev);
- return (-1);
+ for (ifa = ifaddrs; ifa != NULL; ifa = ifa->snf_ifa_next) {
+ /*
+ * Myricom SNF adapter ports may appear as regular
+ * network interfaces, which would already have been
+ * added to the list of adapters by pcap_platform_finddevs()
+ * if this isn't an SNF-only version of libpcap.
+ *
+ * Our create routine intercepts pcap_create() calls for
+ * those interfaces and arranges that they will be
+ * opened using the SNF API instead.
+ *
+ * So if we already have an entry for the device, we
+ * don't add an additional entry for it, we just
+ * update the description for it, if any, to indicate
+ * which snfN device it is. Otherwise, we add an entry
+ * for it.
+ *
+ * In either case, if SNF_F_AGGREGATE_PORTMASK is set
+ * in SNF_FLAGS, we add this port to the bitmask
+ * of ports, which we use to generate a device
+ * we can use to capture on all ports.
+ *
+ * Generate the description string. If port aggregation
+ * is set, use 2^{port number} as the unit number,
+ * rather than {port number}.
+ *
+ * XXX - do entries in this list have IP addresses for
+ * the port? If so, should we add them to the
+ * entry for the device, if they're not already in the
+ * list of IP addresses for the device?
+ */
+ (void)pcap_snprintf(desc,MAX_DESC_LENGTH,"Myricom %ssnf%d",
+ merge ? "Merge Bitmask Port " : "",
+ merge ? 1 << ifa->snf_ifa_portnum : ifa->snf_ifa_portnum);
+ /*
+ * Add the port to the bitmask.
+ */
+ if (merge)
+ allports |= 1 << ifa->snf_ifa_portnum;
+ /*
+ * See if there's already an entry for the device
+ * with the name ifa->snf_ifa_name.
+ */
+ dev = find_dev(devlistp, ifa->snf_ifa_name);
+ if (dev != NULL) {
+ /*
+ * Yes. Update its description.
+ */
+ char *desc_str;
+
+ desc_str = strdup(desc);
+ if (desc_str == NULL) {
+ pcap_fmt_errmsg_for_errno(errbuf,
+ PCAP_ERRBUF_SIZE, errno,
+ "snf_findalldevs strdup");
+ return -1;
+ }
+ free(dev->description);
+ dev->description = desc_str;
+ } else {
+ /*
+ * No. Add an entry for it.
+ *
+ * XXX - is there a notion of "up" or "running",
+ * and can we determine whether something's
+ * plugged into the adapter and set
+ * PCAP_IF_CONNECTION_STATUS_CONNECTED or
+ * PCAP_IF_CONNECTION_STATUS_DISCONNECTED?
+ */
+ dev = add_dev(devlistp, ifa->snf_ifa_name, 0, desc,
+ errbuf);
+ if (dev == NULL)
+ return -1;
+#ifdef _WIN32
+ /*
+ * On Windows, fill in IP# from device name
+ */
+ ret = inet_pton(AF_INET, dev->name, &addr.sin_addr);
+ if (ret == 1) {
+ /*
+ * Successful conversion of device name
+ * to IPv4 address.
+ */
+ addr.sin_family = AF_INET;
+ if (add_addr_to_dev(dev, &addr, sizeof(addr),
+ NULL, 0, NULL, 0, NULL, 0, errbuf) == -1)
+ return -1;
+ } else if (ret == -1) {
+ /*
+ * Error.
+ */
+ pcap_fmt_errmsg_for_errno(errbuf,
+ PCAP_ERRBUF_SIZE, errno,
+ "sinf_findalldevs inet_pton");
+ return -1;
+ }
+#endif _WIN32
}
- curaddr->addr->sa_family = AF_INET;
- curaddr->netmask = NULL;
- curaddr->broadaddr = NULL;
- curaddr->dstaddr = NULL;
- curaddr->next = NULL;
-
- prevdev = curdev;
- ifa = ifa->snf_ifa_next;
}
snf_freeifaddrs(ifaddrs);
- *devlistp = devlist;
-
/*
- * There are no platform-specific devices since each device
- * exists as a regular Ethernet device.
- */
+ * Create a snfX entry if port aggregation is enabled
+ */
+ if (merge) {
+ /*
+ * Add a new entry with all ports bitmask
+ */
+ (void)pcap_snprintf(name,MAX_DESC_LENGTH,"snf%d",allports);
+ (void)pcap_snprintf(desc,MAX_DESC_LENGTH,"Myricom Merge Bitmask All Ports snf%d",
+ allports);
+ /*
+ * XXX - is there any notion of "up" and "running" that
+ * would apply to this device, given that it handles
+ * multiple ports?
+ *
+ * Presumably, there's no notion of "connected" vs.
+ * "disconnected", as "is this plugged into a network?"
+ * would be a per-port property.
+ */
+ if (add_dev(devlistp, name,
+ PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE, desc,
+ errbuf) == NULL)
+ return (-1);
+ /*
+ * XXX - should we give it a list of addresses with all
+ * the addresses for all the ports?
+ */
+ }
+
return 0;
}
@@ -443,7 +536,7 @@ snf_create(const char *device, char *ebuf, int *is_ours)
devlen = strlen(device) + 1;
ifa = ifaddrs;
while (ifa) {
- if (!strncmp(device, ifa->snf_ifa_name, devlen)) {
+ if (strncmp(device, ifa->snf_ifa_name, devlen) == 0) {
boardnum = ifa->snf_ifa_boardnum;
break;
}
@@ -461,7 +554,7 @@ snf_create(const char *device, char *ebuf, int *is_ours)
/* Nope, not a supported name */
*is_ours = 0;
return NULL;
- }
+ }
}
/* OK, it's probably ours. */
@@ -478,8 +571,8 @@ snf_create(const char *device, char *ebuf, int *is_ours)
p->tstamp_precision_count = 2;
p->tstamp_precision_list = malloc(2 * sizeof(u_int));
if (p->tstamp_precision_list == NULL) {
- pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE, errno,
+ "malloc");
pcap_close(p);
return NULL;
}
@@ -498,12 +591,11 @@ snf_create(const char *device, char *ebuf, int *is_ours)
*/
/*
- * There are no regular interfaces, just DAG interfaces.
+ * There are no regular interfaces, just SNF interfaces.
*/
int
-pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
+pcap_platform_finddevs(pcap_if_list_t *devlistp, char *errbuf)
{
- *alldevsp = NULL;
return (0);
}
@@ -517,4 +609,13 @@ pcap_create_interface(const char *device, char *errbuf)
"This version of libpcap only supports SNF cards");
return NULL;
}
+
+/*
+ * Libpcap version string.
+ */
+const char *
+pcap_lib_version(void)
+{
+ return (PCAP_VERSION_STRING " (SNF-only)");
+}
#endif
diff --git a/contrib/libpcap/pcap-snf.h b/contrib/libpcap/pcap-snf.h
index c9d7722bf4fc8..ffc64adf3673e 100644
--- a/contrib/libpcap/pcap-snf.h
+++ b/contrib/libpcap/pcap-snf.h
@@ -1,2 +1,2 @@
pcap_t *snf_create(const char *, char *, int *);
-int snf_findalldevs(pcap_if_t **devlistp, char *errbuf);
+int snf_findalldevs(pcap_if_list_t *devlistp, char *errbuf);
diff --git a/contrib/libpcap/pcap-snit.c b/contrib/libpcap/pcap-snit.c
index 79349456bbac1..9c6fbd48e7b83 100644
--- a/contrib/libpcap/pcap-snit.c
+++ b/contrib/libpcap/pcap-snit.c
@@ -24,7 +24,7 @@
*/
#ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
#endif
#include <sys/types.h>
@@ -130,8 +130,8 @@ pcap_read_snit(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
if (cc < 0) {
if (errno == EWOULDBLOCK)
return (0);
- pcap_snprintf(p->errbuf, sizeof(p->errbuf), "pcap_read: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, sizeof(p->errbuf),
+ errno, "pcap_read");
return (-1);
}
bp = (u_char *)p->buffer;
@@ -223,8 +223,8 @@ pcap_inject_snit(pcap_t *p, const void *buf, size_t size)
data.len = size;
ret = putmsg(p->fd, &ctl, &data);
if (ret == -1) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "send");
return (-1);
}
return (ret);
@@ -247,8 +247,8 @@ nit_setflags(pcap_t *p)
si.ic_len = sizeof(zero);
si.ic_dp = (char *)&zero;
if (ioctl(p->fd, I_STR, (char *)&si) < 0) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "NIOCSCHUNK: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "NIOCSCHUNK");
return (-1);
}
}
@@ -260,8 +260,8 @@ nit_setflags(pcap_t *p)
si.ic_len = sizeof(timeout);
si.ic_dp = (char *)&timeout;
if (ioctl(p->fd, I_STR, (char *)&si) < 0) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "NIOCSTIME: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "NIOCSTIME");
return (-1);
}
}
@@ -272,8 +272,8 @@ nit_setflags(pcap_t *p)
si.ic_len = sizeof(flags);
si.ic_dp = (char *)&flags;
if (ioctl(p->fd, I_STR, (char *)&si) < 0) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "NIOCSFLAGS: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "NIOCSFLAGS");
return (-1);
}
return (0);
@@ -287,6 +287,7 @@ pcap_activate_snit(pcap_t *p)
int chunksize = CHUNKSIZE;
int fd;
static const char dev[] = "/dev/nit";
+ int err;
if (p->opt.rfmon) {
/*
@@ -296,6 +297,17 @@ pcap_activate_snit(pcap_t *p)
return (PCAP_ERROR_RFMON_NOTSUP);
}
+ /*
+ * Turn a negative snapshot value (invalid), a snapshot value of
+ * 0 (unspecified), or a value bigger than the normal maximum
+ * value, into the maximum allowed value.
+ *
+ * If some application really *needs* a bigger snapshot
+ * length, we should just increase MAXIMUM_SNAPLEN.
+ */
+ if (p->snapshot <= 0 || p->snapshot > MAXIMUM_SNAPLEN)
+ p->snapshot = MAXIMUM_SNAPLEN;
+
if (p->snapshot < 96)
/*
* NIT requires a snapshot length of at least 96.
@@ -320,20 +332,26 @@ pcap_activate_snit(pcap_t *p)
if (fd < 0 && errno == EACCES)
p->fd = fd = open(dev, O_RDONLY);
if (fd < 0) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s", dev,
- pcap_strerror(errno));
+ if (errno == EACCES)
+ err = PCAP_ERROR_PERM_DENIED;
+ else
+ err = PCAP_ERROR;
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "%s", dev);
goto bad;
}
/* arrange to get discrete messages from the STREAM and use NIT_BUF */
if (ioctl(fd, I_SRDOPT, (char *)RMSGD) < 0) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "I_SRDOPT: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "I_SRDOPT");
+ err = PCAP_ERROR;
goto bad;
}
if (ioctl(fd, I_PUSH, "nbuf") < 0) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "push nbuf: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "push nbuf");
+ err = PCAP_ERROR;
goto bad;
}
/* set the chunksize */
@@ -342,8 +360,9 @@ pcap_activate_snit(pcap_t *p)
si.ic_len = sizeof(chunksize);
si.ic_dp = (char *)&chunksize;
if (ioctl(fd, I_STR, (char *)&si) < 0) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "NIOCSCHUNK: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "NIOCSCHUNK");
+ err = PCAP_ERROR;
goto bad;
}
@@ -359,8 +378,9 @@ pcap_activate_snit(pcap_t *p)
* Is there one that means "that device doesn't support
* STREAMS NIT"?
*/
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "NIOCBIND: %s: %s",
- ifr.ifr_name, pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "NIOCBIND: %s", ifr.ifr_name);
+ err = PCAP_ERROR;
goto bad;
}
@@ -369,12 +389,15 @@ pcap_activate_snit(pcap_t *p)
si.ic_len = sizeof(p->snapshot);
si.ic_dp = (char *)&p->snapshot;
if (ioctl(fd, I_STR, (char *)&si) < 0) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "NIOCSSNAP: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "NIOCSSNAP");
+ err = PCAP_ERROR;
goto bad;
}
- if (nit_setflags(p) < 0)
+ if (nit_setflags(p) < 0) {
+ err = PCAP_ERROR;
goto bad;
+ }
(void)ioctl(fd, I_FLUSH, (char *)FLUSHR);
/*
@@ -385,7 +408,9 @@ pcap_activate_snit(pcap_t *p)
p->bufsize = BUFSPACE;
p->buffer = malloc(p->bufsize);
if (p->buffer == NULL) {
- strlcpy(p->errbuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "malloc");
+ err = PCAP_ERROR;
goto bad;
}
@@ -427,7 +452,7 @@ pcap_activate_snit(pcap_t *p)
return (0);
bad:
pcap_cleanup_live_common(p);
- return (PCAP_ERROR);
+ return (err);
}
pcap_t *
@@ -453,8 +478,29 @@ can_be_bound(const char *name _U_)
return (1);
}
+static int
+get_if_flags(const char *name _U_, bpf_u_int32 *flags _U_, char *errbuf _U_)
+{
+ /*
+ * Nothing we can do.
+ * XXX - is there a way to find out whether an adapter has
+ * something plugged into it?
+ */
+ return (0);
+}
+
int
-pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
+pcap_platform_finddevs(pcap_if_list_t *devlistp, char *errbuf)
+{
+ return (pcap_findalldevs_interfaces(devlistp, errbuf, can_be_bound,
+ get_if_flags));
+}
+
+/*
+ * Libpcap version string.
+ */
+const char *
+pcap_lib_version(void)
{
- return (pcap_findalldevs_interfaces(alldevsp, errbuf, can_be_bound));
+ return (PCAP_VERSION_STRING);
}
diff --git a/contrib/libpcap/pcap-snoop.c b/contrib/libpcap/pcap-snoop.c
index 2bc0bac58cdd3..a598bae5fe1f0 100644
--- a/contrib/libpcap/pcap-snoop.c
+++ b/contrib/libpcap/pcap-snoop.c
@@ -20,7 +20,7 @@
*/
#ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
#endif
#include <sys/param.h>
@@ -95,8 +95,8 @@ again:
case EWOULDBLOCK:
return (0); /* XXX */
}
- pcap_snprintf(p->errbuf, sizeof(p->errbuf),
- "read: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, sizeof(p->errbuf),
+ errno, "read");
return (-1);
}
sh = (struct snoopheader *)p->buffer;
@@ -104,7 +104,7 @@ again:
/*
* XXX - Sigh, snoop_packetlen is a 16 bit quantity. If we
- * got a short length, but read a full sized snoop packet,
+ * got a short length, but read a full sized snoop pakcet,
* assume we overflowed and add back the 64K...
*/
if (cc == (p->snapshot + sizeof(struct snoopheader)) &&
@@ -150,8 +150,8 @@ pcap_inject_snoop(pcap_t *p, const void *buf, size_t size)
*/
ret = write(p->fd, buf, size);
if (ret == -1) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "send");
return (-1);
}
return (ret);
@@ -167,8 +167,8 @@ pcap_stats_snoop(pcap_t *p, struct pcap_stat *ps)
rs = &rawstats;
memset(rs, 0, sizeof(*rs));
if (ioctl(p->fd, SIOCRAWSTATS, (char *)rs) < 0) {
- pcap_snprintf(p->errbuf, sizeof(p->errbuf),
- "SIOCRAWSTATS: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, sizeof(p->errbuf),
+ errno, "SIOCRAWSTATS");
return (-1);
}
@@ -212,8 +212,8 @@ pcap_activate_snoop(pcap_t *p)
fd = socket(PF_RAW, SOCK_RAW, RAWPROTO_SNOOP);
if (fd < 0) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "snoop socket: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "snoop socket");
goto bad;
}
p->fd = fd;
@@ -228,14 +228,14 @@ pcap_activate_snoop(pcap_t *p)
* they might be the same error, if they both end up
* meaning "snoop doesn't know about that device".
*/
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "snoop bind: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "snoop bind");
goto bad;
}
memset(&sf, 0, sizeof(sf));
if (ioctl(fd, SIOCADDSNOOP, &sf) < 0) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "SIOCADDSNOOP: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "SIOCADDSNOOP");
goto bad;
}
if (p->opt.buffer_size != 0)
@@ -323,6 +323,17 @@ pcap_activate_snoop(pcap_t *p)
return (PCAP_ERROR_RFMON_NOTSUP);
}
+ /*
+ * Turn a negative snapshot value (invalid), a snapshot value of
+ * 0 (unspecified), or a value bigger than the normal maximum
+ * value, into the maximum allowed value.
+ *
+ * If some application really *needs* a bigger snapshot
+ * length, we should just increase MAXIMUM_SNAPLEN.
+ */
+ if (p->snapshot <= 0 || p->snapshot > MAXIMUM_SNAPLEN)
+ p->snapshot = MAXIMUM_SNAPLEN;
+
#ifdef SIOCGIFMTU
/*
* XXX - IRIX appears to give you an error if you try to set the
@@ -332,8 +343,8 @@ pcap_activate_snoop(pcap_t *p)
*/
(void)strncpy(ifr.ifr_name, p->opt.device, sizeof(ifr.ifr_name));
if (ioctl(fd, SIOCGIFMTU, (char *)&ifr) < 0) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "SIOCGIFMTU: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "SIOCGIFMTU");
goto bad;
}
/*
@@ -366,22 +377,22 @@ pcap_activate_snoop(pcap_t *p)
if (snooplen < 0)
snooplen = 0;
if (ioctl(fd, SIOCSNOOPLEN, &snooplen) < 0) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "SIOCSNOOPLEN: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "SIOCSNOOPLEN");
goto bad;
}
v = 1;
if (ioctl(fd, SIOCSNOOPING, &v) < 0) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "SIOCSNOOPING: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "SIOCSNOOPING");
goto bad;
}
p->bufsize = 4096; /* XXX */
p->buffer = malloc(p->bufsize);
if (p->buffer == NULL) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "malloc: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "malloc");
goto bad;
}
@@ -428,8 +439,29 @@ can_be_bound(const char *name _U_)
return (1);
}
+static int
+get_if_flags(const char *name _U_, bpf_u_int32 *flags _U_, char *errbuf _U_)
+{
+ /*
+ * Nothing we can do.
+ * XXX - is there a way to find out whether an adapter has
+ * something plugged into it?
+ */
+ return (0);
+}
+
int
-pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
+pcap_platform_finddevs(pcap_if_list_t *devlistp, char *errbuf)
+{
+ return (pcap_findalldevs_interfaces(devlistp, errbuf, can_be_bound,
+ get_if_flags));
+}
+
+/*
+ * Libpcap version string.
+ */
+const char *
+pcap_lib_version(void)
{
- return (pcap_findalldevs_interfaces(alldevsp, errbuf, can_be_bound));
+ return (PCAP_VERSION_STRING);
}
diff --git a/contrib/libpcap/pcap-stdinc.h b/contrib/libpcap/pcap-stdinc.h
deleted file mode 100644
index a1be680988650..0000000000000
--- a/contrib/libpcap/pcap-stdinc.h
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (c) 2002 - 2005 NetGroup, Politecnico di Torino (Italy)
- * Copyright (c) 2005 - 2009 CACE Technologies, Inc. Davis (California)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the Politecnico di Torino nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * Copyright (C) 1999 WIDE Project.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the project nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE PROJECT 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 PROJECT 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 pcap_stdinc_h
-#define pcap_stdinc_h
-
-/*
- * Avoids a compiler warning in case this was already defined
- * (someone defined _WINSOCKAPI_ when including 'windows.h', in order
- * to prevent it from including 'winsock.h')
- */
-#ifdef _WINSOCKAPI_
-#undef _WINSOCKAPI_
-#endif
-
-#include <winsock2.h>
-#include <fcntl.h>
-#include <time.h>
-#include <io.h>
-
-#include <ws2tcpip.h>
-
-#if defined(_MSC_VER)
- /*
- * MSVC.
- */
- #if _MSC_VER >= 1800
- /*
- * VS 2013 or newer; we have <inttypes.h>.
- */
- #include <inttypes.h>
-
- #define u_int8_t uint8_t
- #define u_int16_t uint16_t
- #define u_int32_t uint32_t
- #define u_int64_t uint64_t
- #else
- /*
- * Earlier VS; we have to define this stuff ourselves.
- */
- #ifndef HAVE_U_INT8_T
- typedef unsigned char u_int8_t;
- typedef signed char int8_t;
- #endif
-
- #ifndef HAVE_U_INT16_T
- typedef unsigned short u_int16_t;
- typedef signed short int16_t;
- #endif
-
- #ifndef HAVE_U_INT32_T
- typedef unsigned int u_int32_t;
- typedef signed int int32_t;
- #endif
-
- #ifndef HAVE_U_INT64_T
- #ifdef _MSC_EXTENSIONS
- typedef unsigned _int64 u_int64_t;
- typedef _int64 int64_t;
- #else /* _MSC_EXTENSIONS */
- typedef unsigned long long u_int64_t;
- typedef long long int64_t;
- #endif
- #endif
- #endif
-#elif defined(__MINGW32__)
- #include <stdint.h>
-#endif
-
-#endif /* pcap_stdinc_h */
diff --git a/contrib/libpcap/pcap-tc.c b/contrib/libpcap/pcap-tc.c
index 768dbd7c5f810..38c7024504627 100644
--- a/contrib/libpcap/pcap-tc.c
+++ b/contrib/libpcap/pcap-tc.c
@@ -30,7 +30,7 @@
*/
#ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
#endif
#include <pcap.h>
@@ -120,8 +120,8 @@ typedef struct _TC_FUNCTIONS
static pcap_if_t* TcCreatePcapIfFromPort(TC_PORT port);
static int TcSetDatalink(pcap_t *p, int dlt);
-static int TcGetNonBlock(pcap_t *p, char *errbuf);
-static int TcSetNonBlock(pcap_t *p, int nonblock, char *errbuf);
+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 TcRead(pcap_t *p, int cnt, pcap_handler callback, u_char *user);
@@ -433,7 +433,7 @@ struct pcap_tc {
};
int
-TcFindAllDevs(pcap_if_t **alldevsp, char *errbuf)
+TcFindAllDevs(pcap_if_list_t *devlist, char *errbuf)
{
TC_API_LOAD_STATUS loadStatus;
ULONG numPorts;
@@ -476,13 +476,15 @@ TcFindAllDevs(pcap_if_t **alldevsp, char *errbuf)
/*
* append it at the end
*/
- if (*alldevsp == NULL)
+ if (devlistp->beginning == NULL)
{
- *alldevsp = dev;
+ devlistp->beginning = dev;
}
else
{
- for(cursor = *alldevsp; cursor->next != NULL; cursor = cursor->next);
+ for (cursor = devlistp->beginning;
+ cursor->next != NULL;
+ cursor = cursor->next);
cursor->next = dev;
}
}
@@ -570,6 +572,17 @@ TcActivate(pcap_t *p)
}
/*
+ * Turn a negative snapshot value (invalid), a snapshot value of
+ * 0 (unspecified), or a value bigger than the normal maximum
+ * value, into the maximum allowed value.
+ *
+ * If some application really *needs* a bigger snapshot
+ * length, we should just increase MAXIMUM_SNAPLEN.
+ */
+ if (p->snapshot <= 0 || p->snapshot > MAXIMUM_SNAPLEN)
+ p->snapshot = MAXIMUM_SNAPLEN;
+
+ /*
* Initialize the PPI fixed fields
*/
pPpiHeader = (PPPI_HEADER)pt->PpiPacket;
@@ -763,36 +776,48 @@ TcCreate(const char *device, char *ebuf, int *is_ours)
return NULL;
p->activate_op = TcActivate;
+ /*
+ * Set these up front, so that, even if our client tries
+ * to set non-blocking mode before we're activated, or
+ * query the state of non-blocking mode, they get an error,
+ * rather than having the non-blocking mode option set
+ * for use later.
+ */
+ p->getnonblock_op = TcGetNonBlock;
+ p->setnonblock_op = TcSetNonBlock;
return p;
}
static int TcSetDatalink(pcap_t *p, int dlt)
{
/*
- * always return 0, as the check is done by pcap_set_datalink
+ * We don't have to do any work here; pcap_set_datalink() checks
+ * whether the value is in the list of DLT_ values we
+ * supplied, so we don't have to, and, if it is valid, sets
+ * p->linktype to the new value; we don't have to do anything
+ * in hardware, we just use what's in p->linktype.
+ *
+ * We do have to have a routine, however, so that pcap_set_datalink()
+ * doesn't think we don't support setting the link-layer header
+ * type at all.
*/
return 0;
}
-static int TcGetNonBlock(pcap_t *p, char *errbuf)
+static int TcGetNonBlock(pcap_t *p)
{
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "Getting the non blocking status is not available for TurboCap ports");
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "Getting the non blocking status is not available for TurboCap ports");
- return -1;
-
+ "Non-blocking mode isn't supported for TurboCap ports");
+ return -1;
}
-static int TcSetNonBlock(pcap_t *p, int nonblock, char *errbuf)
+
+static int TcSetNonBlock(pcap_t *p, int nonblock)
{
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "Setting the non blocking status is not available for TurboCap ports");
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "Setting the non blocking status is not available for TurboCap ports");
- return -1;
+ "Non-blocking mode isn't supported for TurboCap ports");
+ return -1;
}
-
static void TcCleanup(pcap_t *p)
{
struct pcap_tc *pt = p->priv;
@@ -1081,7 +1106,7 @@ TcStats(pcap_t *p, struct pcap_stat *ps)
s.ps_drop = 0xFFFFFFFF;
}
-#if defined(_WIN32) && defined(HAVE_REMOTE)
+#if defined(_WIN32) && defined(ENABLE_REMOTE)
s.ps_capt = pt->TcAcceptedCount;
#endif
*ps = s;
@@ -1105,8 +1130,6 @@ TcSetFilter(pcap_t *p, struct bpf_program *fp)
/* Install a user level filter */
if (install_bpf_program(p, fp) < 0)
{
- pcap_snprintf(p->errbuf, sizeof(p->errbuf),
- "setfilter, unable to install the filter: %s", pcap_strerror(errno));
return -1;
}
@@ -1166,7 +1189,7 @@ TcStatsEx(pcap_t *p, int *pcap_stat_size)
p->stat.ps_drop = 0xFFFFFFFF;
}
-#ifdef HAVE_REMOTE
+#if defined(_WIN32) && defined(ENABLE_REMOTE)
p->stat.ps_capt = pt->TcAcceptedCount;
#endif
diff --git a/contrib/libpcap/pcap-tc.h b/contrib/libpcap/pcap-tc.h
index 59ddec262c6a4..f7b2d12def49e 100644
--- a/contrib/libpcap/pcap-tc.h
+++ b/contrib/libpcap/pcap-tc.h
@@ -49,6 +49,6 @@ pcap_t *
TcCreate(const char *device, char *ebuf, int *is_ours);
int
-TcFindAllDevs(pcap_if_t **alldevsp, char *errbuf);
+TcFindAllDevs(pcap_if_list_t *devlistp, char *errbuf);
#endif
diff --git a/contrib/libpcap/pcap-tstamp.manmisc b/contrib/libpcap/pcap-tstamp.manmisc
deleted file mode 100644
index bfcee97a5f3f0..0000000000000
--- a/contrib/libpcap/pcap-tstamp.manmisc
+++ /dev/null
@@ -1,132 +0,0 @@
-.\"
-.\" Copyright (c) 1987, 1988, 1989, 1990, 1991, 1992, 1994, 1995, 1996, 1997
-.\" The Regents of the University of California. All rights reserved.
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that: (1) source code distributions
-.\" retain the above copyright notice and this paragraph in its entirety, (2)
-.\" distributions including binary code include the above copyright notice and
-.\" this paragraph in its entirety in the documentation or other materials
-.\" provided with the distribution, and (3) all advertising materials mentioning
-.\" features or use of this software display the following acknowledgement:
-.\" ``This product includes software developed by the University of California,
-.\" Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
-.\" the University nor the names of its contributors may be used to endorse
-.\" or promote products derived from this software without specific prior
-.\" written permission.
-.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
-.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
-.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
-.\"
-.TH PCAP-TSTAMP 7 "21 December 2013"
-.SH NAME
-pcap-tstamp \- packet time stamps in libpcap
-.SH DESCRIPTION
-When capturing traffic, each packet is given a time stamp representing,
-for incoming packets, the arrival time of the packet and, for outgoing
-packets, the transmission time of the packet. This time is an
-approximation of the arrival or transmission time. If it is supplied by
-the operating system running on the host on which the capture is being
-done, there are several reasons why it might not precisely represent the
-arrival or transmission time:
-.IP
-if the time stamp is applied to the packet when the networking stack
-receives the packet, the networking stack might not see the packet until
-an interrupt is delivered for the packet or a timer event causes the
-networking device driver to poll for packets, and the time stamp might
-not be applied until the packet has had some processing done by other
-code in the networking stack, so there might be a significant delay
-between the time when the last bit of the packet is received by the
-capture device and when the networking stack time-stamps the packet;
-.IP
-the timer used to generate the time stamps might have low resolution,
-for example, it might be a timer updated once per host operating system
-timer tick, with the host operating system timer ticking once every few
-milliseconds;
-.IP
-a high-resolution timer might use a counter that runs at a rate
-dependent on the processor clock speed, and that clock speed might be
-adjusted upwards or downwards over time and the timer might not be able
-to compensate for all those adjustments;
-.IP
-the host operating system's clock might be adjusted over time to match a
-time standard to which the host is being synchronized, which might be
-done by temporarily slowing down or speeding up the clock or by making a
-single adjustment;
-.IP
-different CPU cores on a multi-core or multi-processor system might be
-running at different speeds, or might not have time counters all
-synchronized, so packets time-stamped by different cores might not have
-consistent time stamps.
-.LP
-In addition, packets time-stamped by different cores might be
-time-stamped in one order and added to the queue of packets for libpcap
-to read in another order, so time stamps might not be monotonically
-increasing.
-.LP
-Some capture devices on some platforms can provide time stamps for
-packets; those time stamps are usually high-resolution time stamps, and
-are usually applied to the packet when the first or last bit of the
-packet arrives, and are thus more accurate than time stamps provided by
-the host operating system. Those time stamps might not, however, be
-synchronized with the host operating system's clock, so that, for
-example, the time stamp of a packet might not correspond to the time
-stamp of an event on the host triggered by the arrival of that packet.
-.LP
-Depending on the capture device and the software on the host, libpcap
-might allow different types of time stamp to be used. The
-.BR pcap_list_tstamp_types (3PCAP)
-routine provides, for a packet capture handle created by
-.BR pcap_create (3PCAP)
-but not yet activated by
-.BR pcap_activate (3PCAP),
-a list of time stamp types supported by the capture device for that
-handle.
-The list might be empty, in which case no choice of time stamp type is
-offered for that capture device. If the list is not empty, the
-.BR pcap_set_tstamp_type (3PCAP)
-routine can be used after a
-.B pcap_create()
-call and before a
-.B pcap_activate()
-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()
-and accepted by
-.BR pcap_tstamp_type_name_to_val() .
-.RS 5
-.TP 5
-.BR PCAP_TSTAMP_HOST " - " host
-Time stamp provided by the host on which the capture is being done. The
-precision of this time stamp is unspecified; it might or might not be
-synchronized with the host operating system's clock.
-.TP 5
-.BR PCAP_TSTAMP_HOST_LOWPREC " - " host_lowprec
-Time stamp provided by the host on which the capture is being done.
-This is a low-precision time stamp, synchronized with the host operating
-system's clock.
-.TP 5
-.BR PCAP_TSTAMP_HOST_HIPREC " - " host_hiprec
-Time stamp provided by the host on which the capture is being done.
-This is a high-precision time stamp; it might or might not be
-synchronized with the host operating system's clock. It might be more
-expensive to fetch than
-.BR PCAP_TSTAMP_HOST_LOWPREC .
-.TP 5
-.BR PCAP_TSTAMP_ADAPTER " - " adapter
-Time stamp provided by the network adapter on which the capture is being
-done. This is a high-precision time stamp, synchronized with the host
-operating system's clock.
-.TP 5
-.BR PCAP_TSTAMP_ADAPTER_UNSYNCED " - " adapter_unsynced
-Time stamp provided by the network adapter on which the capture is being
-done. This is a high-precision time stamp; it is not synchronized with
-the host operating system's clock.
-.RE
-.SH SEE ALSO
-pcap_set_tstamp_type(3PCAP),
-pcap_list_tstamp_types(3PCAP),
-pcap_tstamp_type_val_to_name(3PCAP),
-pcap_tstamp_type_name_to_val(3PCAP)
diff --git a/contrib/libpcap/pcap-tstamp.manmisc.in b/contrib/libpcap/pcap-tstamp.manmisc.in
index 2e1ef61d1f46e..38c56518334e6 100644
--- a/contrib/libpcap/pcap-tstamp.manmisc.in
+++ b/contrib/libpcap/pcap-tstamp.manmisc.in
@@ -165,11 +165,13 @@ 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)
+\%pcap_fopen_offline_with_tstamp_precision(3PCAP),
+\%pcap_get_tstamp_precision(3PCAP)
+.ad
diff --git a/contrib/libpcap/pcap-types.h b/contrib/libpcap/pcap-types.h
new file mode 100644
index 0000000000000..9614f9f1de51b
--- /dev/null
+++ b/contrib/libpcap/pcap-types.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2002 - 2005 NetGroup, Politecnico di Torino (Italy)
+ * Copyright (c) 2005 - 2009 CACE Technologies, Inc. Davis (California)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Politecnico di Torino nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef pcap_types_h
+#define pcap_types_h
+
+/*
+ * Get u_int defined, by hook or by crook.
+ */
+#ifdef _WIN32
+
+ /*
+ * This defines u_int.
+ */
+ #include <winsock2.h>
+#else /* _WIN32 */
+ /*
+ * This defines u_int, among other types.
+ */
+ #include <sys/types.h>
+#endif
+
+#endif /* pcap_types_h */
diff --git a/contrib/libpcap/pcap-usb-linux.c b/contrib/libpcap/pcap-usb-linux.c
index fb1188a7d33c4..6f8adf65eab57 100644
--- a/contrib/libpcap/pcap-usb-linux.c
+++ b/contrib/libpcap/pcap-usb-linux.c
@@ -34,7 +34,7 @@
*/
#ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
#endif
#include "pcap-int.h"
@@ -56,6 +56,7 @@
#include <netinet/in.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
+#include <sys/utsname.h>
#ifdef HAVE_LINUX_USBDEVICE_FS_H
/*
* We might need <linux/compiler.h> to define __user for
@@ -85,8 +86,8 @@
#endif
struct mon_bin_stats {
- u_int32_t queued;
- u_int32_t dropped;
+ uint32_t queued;
+ uint32_t dropped;
};
struct mon_bin_get {
@@ -138,25 +139,131 @@ static int usb_inject_linux(pcap_t *, const void *, size_t);
static int usb_setdirection_linux(pcap_t *, pcap_direction_t);
static void usb_cleanup_linux_mmap(pcap_t *);
+static int
+have_binary_usbmon(void)
+{
+ struct utsname utsname;
+ char *version_component, *endp;
+ int major, minor, subminor;
+
+ if (uname(&utsname) == 0) {
+ /*
+ * 2.6.21 is the first release with the binary-mode
+ * USB monitoring.
+ */
+ version_component = utsname.release;
+ major = strtol(version_component, &endp, 10);
+ if (endp != version_component && *endp == '.') {
+ /*
+ * OK, that was a valid major version.
+ * Is it 3 or greater? If so, we have binary
+ * mode support.
+ */
+ if (major >= 3)
+ return 1;
+
+ /*
+ * Is it 1 or less? If so, we don't have binary
+ * mode support. (In fact, we don't have any
+ * USB monitoring....)
+ */
+ if (major <= 1)
+ return 0;
+ }
+
+ /*
+ * OK, this is a 2.x kernel.
+ * What's the minor version?
+ */
+ version_component = endp + 1;
+ minor = strtol(version_component, &endp, 10);
+ if (endp != version_component &&
+ (*endp == '.' || *endp == '\0')) {
+ /*
+ * OK, that was a valid minor version.
+ * Is is 2.6 or later? (There shouldn't be a
+ * "later", as 2.6.x went to 3.x, but we'll
+ * check anyway.)
+ */
+ if (minor < 6) {
+ /*
+ * No, so no binary support (did 2.4 have
+ * any USB monitoring at all?)
+ */
+ return 0;
+ }
+
+ /*
+ * OK, this is a 2.6.x kernel.
+ * What's the subminor version?
+ */
+ version_component = endp + 1;
+ subminor = strtol(version_component, &endp, 10);
+ if (endp != version_component &&
+ (*endp == '.' || *endp == '\0')) {
+ /*
+ * OK, that was a valid subminor version.
+ * Is it 21 or greater?
+ */
+ if (subminor >= 21) {
+ /*
+ * Yes - we have binary mode
+ * support.
+ */
+ return 1;
+ }
+ }
+ }
+ }
+
+ /*
+ * Either uname() failed, in which case we just say "no binary
+ * mode support", or we don't have binary mode support.
+ */
+ return 0;
+}
+
/* facility to add an USB device to the device list*/
static int
-usb_dev_add(pcap_if_t** alldevsp, int n, char *err_str)
+usb_dev_add(pcap_if_list_t *devlistp, int n, char *err_str)
{
char dev_name[10];
char dev_descr[30];
pcap_snprintf(dev_name, 10, USB_IFACE"%d", n);
- pcap_snprintf(dev_descr, 30, "USB bus number %d", n);
+ /*
+ * XXX - is there any notion of "up" and "running"?
+ */
+ if (n == 0) {
+ /*
+ * As this refers to all buses, there's no notion of
+ * "connected" vs. "disconnected", as that's a property
+ * that would apply to a particular USB interface.
+ */
+ if (add_dev(devlistp, dev_name,
+ PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE,
+ "All USB buses", err_str) == NULL)
+ return -1;
+ } else {
+ /*
+ * XXX - is there a way to determine whether anything's
+ * plugged into this bus interface or not, and set
+ * PCAP_IF_CONNECTION_STATUS_CONNECTED or
+ * PCAP_IF_CONNECTION_STATUS_DISCONNECTED?
+ */
+ pcap_snprintf(dev_descr, 30, "USB bus number %d", n);
+ if (add_dev(devlistp, dev_name, 0, dev_descr, err_str) == NULL)
+ return -1;
+ }
- if (pcap_add_if(alldevsp, dev_name, 0,
- dev_descr, err_str) < 0)
- return -1;
return 0;
}
int
-usb_findalldevs(pcap_if_t **alldevsp, char *err_str)
+usb_findalldevs(pcap_if_list_t *devlistp, char *err_str)
{
- int fd;
+ char usb_mon_dir[PATH_MAX];
+ char *usb_mon_prefix;
+ size_t usb_mon_prefix_len;
struct dirent* data;
int ret = 0;
DIR* dir;
@@ -164,87 +271,113 @@ usb_findalldevs(pcap_if_t **alldevsp, char *err_str)
char* name;
size_t len;
- /*
- * Do we have a "scan all buses" device?
- * First, try the binary device.
- */
- fd = open(LINUX_USB_MON_DEV"0", O_RDONLY, 0);
- if (fd >= 0) {
+ if (have_binary_usbmon()) {
/*
- * Yes.
+ * We have binary-mode support.
+ * What do the device names look like?
+ * Split LINUX_USB_MON_DEV into a directory that we'll
+ * scan and a file name prefix that we'll check for.
*/
- close(fd);
- if (pcap_add_if(alldevsp, "usbmon0", 0, "All USB buses",
- err_str) < 0)
- return -1;
- } else {
- /*
- * No binary device; do we have the text device?
- */
- fd = open(USB_TEXT_DIR"/0t", O_RDONLY, 0);
- if (fd < 0) {
- /*
- * Not at the new location; try the old location.
- */
- fd = open(USB_TEXT_DIR_OLD"/0t", O_RDONLY, 0);
- }
- if (fd >= 0) {
+ strlcpy(usb_mon_dir, LINUX_USB_MON_DEV, sizeof usb_mon_dir);
+ usb_mon_prefix = strrchr(usb_mon_dir, '/');
+ if (usb_mon_prefix == NULL) {
/*
- * We found it.
+ * This "shouldn't happen". Just give up if it
+ * does.
*/
- close(fd);
- if (pcap_add_if(alldevsp, "usbmon0", 0, "All USB buses",
- err_str) < 0)
- return -1;
+ return 0;
}
- }
+ *usb_mon_prefix++ = '\0';
+ usb_mon_prefix_len = strlen(usb_mon_prefix);
- /*
- * Now look for individual USB buses.
- *
- * First, try scanning sysfs USB bus directory.
- */
- dir = opendir(SYS_USB_BUS_DIR);
- if (dir != NULL) {
- while ((ret == 0) && ((data = readdir(dir)) != 0)) {
- name = data->d_name;
+ /*
+ * Open the directory and scan it.
+ */
+ dir = opendir(usb_mon_dir);
+ if (dir != NULL) {
+ while ((ret == 0) && ((data = readdir(dir)) != 0)) {
+ name = data->d_name;
- if (strncmp(name, "usb", 3) != 0)
- continue;
+ /*
+ * Is this a usbmon device?
+ */
+ if (strncmp(name, usb_mon_prefix, usb_mon_prefix_len) != 0)
+ continue; /* no */
- if (sscanf(&name[3], "%d", &n) == 0)
- continue;
+ /*
+ * What's the device number?
+ */
+ if (sscanf(&name[usb_mon_prefix_len], "%d", &n) == 0)
+ continue; /* failed */
- ret = usb_dev_add(alldevsp, n, err_str);
+ ret = usb_dev_add(devlistp, n, err_str);
+ }
+
+ closedir(dir);
}
+ return 0;
+ } else {
+ /*
+ * We have only text mode support.
+ * We don't look for the text devices because we can't
+ * look for them without root privileges, and we don't
+ * want to require root privileges to enumerate devices
+ * (we want to let the user to try a device and get
+ * an error, rather than seeing no devices and asking
+ * "why am I not seeing devices" and forcing a long
+ * process of poking to figure out whether it's "no
+ * privileges" or "your kernel is too old" or "the
+ * usbmon module isn't loaded" or...).
+ *
+ * Instead, we look to see what buses we have.
+ * If the kernel is so old that it doesn't have
+ * binary-mode support, it's also so old that
+ * it doesn't have a "scan all buses" device.
+ *
+ * First, try scanning sysfs USB bus directory.
+ */
+ dir = opendir(SYS_USB_BUS_DIR);
+ if (dir != NULL) {
+ while ((ret == 0) && ((data = readdir(dir)) != 0)) {
+ name = data->d_name;
- closedir(dir);
- return ret;
- }
+ if (strncmp(name, "usb", 3) != 0)
+ continue;
- /* That didn't work; try scanning procfs USB bus directory. */
- dir = opendir(PROC_USB_BUS_DIR);
- if (dir != NULL) {
- while ((ret == 0) && ((data = readdir(dir)) != 0)) {
- name = data->d_name;
- len = strlen(name);
+ if (sscanf(&name[3], "%d", &n) == 0)
+ continue;
- /* if this file name does not end with a number it's not of our interest */
- if ((len < 1) || !isdigit(name[--len]))
- continue;
- while (isdigit(name[--len]));
- if (sscanf(&name[len+1], "%d", &n) != 1)
- continue;
+ ret = usb_dev_add(devlistp, n, err_str);
+ }
- ret = usb_dev_add(alldevsp, n, err_str);
+ closedir(dir);
+ return 0;
}
- closedir(dir);
- return ret;
- }
+ /* That didn't work; try scanning procfs USB bus directory. */
+ dir = opendir(PROC_USB_BUS_DIR);
+ if (dir != NULL) {
+ while ((ret == 0) && ((data = readdir(dir)) != 0)) {
+ name = data->d_name;
+ len = strlen(name);
+
+ /* if this file name does not end with a number it's not of our interest */
+ if ((len < 1) || !isdigit(name[--len]))
+ continue;
+ while (isdigit(name[--len]));
+ if (sscanf(&name[len+1], "%d", &n) != 1)
+ continue;
+
+ ret = usb_dev_add(devlistp, n, err_str);
+ }
- /* neither of them worked */
- return 0;
+ closedir(dir);
+ return ret;
+ }
+
+ /* neither of them worked */
+ return 0;
+ }
}
static
@@ -283,7 +416,7 @@ probe_devices(int bus)
struct usbdevfs_ctrltransfer ctrl;
struct dirent* data;
int ret = 0;
- char buf[40];
+ char buf[sizeof("/dev/bus/usb/000/") + NAME_MAX];
DIR* dir;
/* scan usb bus directories for device nodes */
@@ -309,7 +442,7 @@ probe_devices(int bus)
* Sigh. Different kernels have different member names
* for this structure.
*/
-#ifdef HAVE_USBDEVFS_CTRLTRANSFER_BREQUESTTYPE
+#ifdef HAVE_STRUCT_USBDEVFS_CTRLTRANSFER_BREQUESTTYPE
ctrl.bRequestType = USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE;
ctrl.bRequest = USB_REQ_GET_DESCRIPTOR;
ctrl.wValue = USB_DT_DEVICE << 8;
@@ -382,6 +515,17 @@ usb_activate(pcap_t* handle)
struct pcap_usb_linux *handlep = handle->priv;
char full_path[USB_LINE_LEN];
+ /*
+ * Turn a negative snapshot value (invalid), a snapshot value of
+ * 0 (unspecified), or a value bigger than the normal maximum
+ * value, into the maximum allowed value.
+ *
+ * If some application really *needs* a bigger snapshot
+ * length, we should just increase MAXIMUM_SNAPLEN.
+ */
+ if (handle->snapshot <= 0 || handle->snapshot > MAXIMUM_SNAPLEN)
+ handle->snapshot = MAXIMUM_SNAPLEN;
+
/* Initialize some components of the pcap structure. */
handle->bufsize = handle->snapshot;
handle->offset = 0;
@@ -402,12 +546,54 @@ usb_activate(pcap_t* handle)
return PCAP_ERROR;
}
- /*now select the read method: try to open binary interface */
- pcap_snprintf(full_path, USB_LINE_LEN, LINUX_USB_MON_DEV"%d", handlep->bus_index);
- handle->fd = open(full_path, O_RDONLY, 0);
- if (handle->fd >= 0)
+ if (have_binary_usbmon())
{
- if (handle->opt.rfmon) {
+ /*
+ * We have binary-mode support.
+ * Try to open the binary interface.
+ */
+ pcap_snprintf(full_path, USB_LINE_LEN, LINUX_USB_MON_DEV"%d", handlep->bus_index);
+ handle->fd = open(full_path, O_RDONLY, 0);
+ if (handle->fd < 0)
+ {
+ /*
+ * The attempt failed; why?
+ */
+ switch (errno) {
+
+ case ENOENT:
+ /*
+ * The device doesn't exist.
+ * That could either mean that there's
+ * no support for monitoring USB buses
+ * (which probably means "the usbmon
+ * module isn't loaded") or that there
+ * is but that *particular* device
+ * doesn't exist (no "scan all buses"
+ * device if the bus index is 0, no
+ * such bus if the bus index isn't 0).
+ */
+ return PCAP_ERROR_NO_SUCH_DEVICE;
+
+ case EACCES:
+ /*
+ * We didn't have permission to open it.
+ */
+ return PCAP_ERROR_PERM_DENIED;
+
+ default:
+ /*
+ * Something went wrong.
+ */
+ pcap_fmt_errmsg_for_errno(handle->errbuf,
+ PCAP_ERRBUF_SIZE, errno,
+ "Can't open USB bus file %s", full_path);
+ return PCAP_ERROR;
+ }
+ }
+
+ if (handle->opt.rfmon)
+ {
/*
* Monitor mode doesn't apply to USB devices.
*/
@@ -415,8 +601,9 @@ usb_activate(pcap_t* handle)
return PCAP_ERROR_RFMON_NOTSUP;
}
- /* binary api is available, try to use fast mmap access */
- if (usb_mmap(handle)) {
+ /* try to use fast mmap access */
+ if (usb_mmap(handle))
+ {
handle->linktype = DLT_USB_LINUX_MMAPPED;
handle->stats_op = usb_stats_linux_bin;
handle->read_op = usb_read_linux_mmap;
@@ -426,8 +613,8 @@ usb_activate(pcap_t* handle)
#endif
/*
- * "handle->fd" is a real file, so "select()" and
- * "poll()" work on it.
+ * "handle->fd" is a real file, so
+ * "select()" and "poll()" work on it.
*/
handle->selectable_fd = handle->fd;
return 0;
@@ -441,7 +628,10 @@ usb_activate(pcap_t* handle)
#endif
}
else {
- /*Binary interface not available, try open text interface */
+ /*
+ * We don't have binary mode support.
+ * Try opening the text-mode device.
+ */
pcap_snprintf(full_path, USB_LINE_LEN, USB_TEXT_DIR"/%dt", handlep->bus_index);
handle->fd = open(full_path, O_RDONLY, 0);
if (handle->fd < 0)
@@ -456,14 +646,43 @@ usb_activate(pcap_t* handle)
handle->fd = open(full_path, O_RDONLY, 0);
}
if (handle->fd < 0) {
- /* no more fallback, give it up*/
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "Can't open USB bus file %s: %s", full_path, strerror(errno));
- return PCAP_ERROR;
+ /*
+ * Is the problem that we didn't have
+ * sufficient permission to open it?
+ */
+ if (errno == EACCES) {
+ /*
+ * Yes - return that error.
+ */
+ return PCAP_ERROR_PERM_DENIED;
+ }
+
+ /*
+ * No - was the problem something other
+ * than "it doesn't exist"?
+ */
+ if (errno != ENOENT) {
+ /*
+ * Yes - return *that* error.
+ */
+ pcap_fmt_errmsg_for_errno(handle->errbuf,
+ PCAP_ERRBUF_SIZE, errno,
+ "Can't open USB bus file %s",
+ full_path);
+ return PCAP_ERROR;
+ }
+
+ /*
+ * No. Report that as "no such device".
+ * (That could mean "no such USB bus"
+ * or "monitoring not supported".)
+ */
+ return PCAP_ERROR_NO_SUCH_DEVICE;
}
}
- if (handle->opt.rfmon) {
+ if (handle->opt.rfmon)
+ {
/*
* Monitor mode doesn't apply to USB devices.
*/
@@ -485,8 +704,8 @@ usb_activate(pcap_t* handle)
* buffer */
handle->buffer = malloc(handle->bufsize);
if (!handle->buffer) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "malloc: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "malloc");
close(handle->fd);
return PCAP_ERROR;
}
@@ -505,7 +724,7 @@ ascii_to_int(char c)
* format description
*/
static int
-usb_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user)
+usb_read_linux(pcap_t *handle, int max_packets _U_, pcap_handler callback, u_char *user)
{
/* see:
* /usr/src/linux/Documentation/usb/usbmon.txt
@@ -536,8 +755,8 @@ usb_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *u
if (errno == EAGAIN)
return 0; /* no data there */
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "Can't read from fd %d: %s", handle->fd, strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "Can't read from fd %d", handle->fd);
return -1;
}
@@ -563,9 +782,8 @@ usb_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *u
/* don't use usbmon provided timestamp, since it have low precision*/
if (gettimeofday(&pkth.ts, NULL) < 0)
{
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "Can't get timestamp for message '%s' %d:%s",
- string, errno, strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "Can't get timestamp for message '%s'", string);
return -1;
}
uhdr->ts_sec = pkth.ts.tv_sec;
@@ -703,7 +921,7 @@ got:
}
static int
-usb_inject_linux(pcap_t *handle, const void *buf, size_t size)
+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");
@@ -734,9 +952,9 @@ usb_stats_linux(pcap_t *handle, struct pcap_stat *stats)
fd = open(string, O_RDONLY, 0);
}
if (fd < 0) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "Can't open USB stats file %s: %s",
- string, strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf,
+ PCAP_ERRBUF_SIZE, errno,
+ "Can't open USB stats file %s", string);
return -1;
}
}
@@ -803,8 +1021,8 @@ usb_stats_linux_bin(pcap_t *handle, struct pcap_stat *stats)
ret = ioctl(handle->fd, MON_IOCG_STATS, &st);
if (ret < 0)
{
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "Can't read stats from fd %d:%s ", handle->fd, strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "Can't read stats from fd %d", handle->fd);
return -1;
}
@@ -819,7 +1037,7 @@ usb_stats_linux_bin(pcap_t *handle, struct pcap_stat *stats)
* <linux-kernel-source>/drivers/usb/mon/mon_bin.c binary ABI
*/
static int
-usb_read_linux_bin(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user)
+usb_read_linux_bin(pcap_t *handle, int max_packets _U_, pcap_handler callback, u_char *user)
{
struct pcap_usb_linux *handlep = handle->priv;
struct mon_bin_get info;
@@ -846,8 +1064,8 @@ usb_read_linux_bin(pcap_t *handle, int max_packets, pcap_handler callback, u_cha
if (errno == EAGAIN)
return 0; /* no data there */
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "Can't read from fd %d: %s", handle->fd, strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "Can't read from fd %d", handle->fd);
return -1;
}
@@ -917,8 +1135,9 @@ usb_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback, u_ch
if (errno == EAGAIN)
return 0; /* no data there */
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "Can't mfetch fd %d: %s", handle->fd, strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf,
+ PCAP_ERRBUF_SIZE, errno, "Can't mfetch fd %d",
+ handle->fd);
return -1;
}
@@ -958,8 +1177,8 @@ usb_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback, u_ch
/* flush pending events*/
if (ioctl(handle->fd, MON_IOCH_MFLUSH, nflush) == -1) {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "Can't mflush fd %d: %s", handle->fd, strerror(errno));
+ pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "Can't mflush fd %d", handle->fd);
return -1;
}
return packets;
diff --git a/contrib/libpcap/pcap-usb-linux.h b/contrib/libpcap/pcap-usb-linux.h
index 234a262f9093c..3ddc12f4840de 100644
--- a/contrib/libpcap/pcap-usb-linux.h
+++ b/contrib/libpcap/pcap-usb-linux.h
@@ -34,5 +34,5 @@
/*
* Prototypes for USB-related functions
*/
-int usb_findalldevs(pcap_if_t **alldevsp, char *err_str);
+int usb_findalldevs(pcap_if_list_t *devlistp, char *err_str);
pcap_t *usb_create(const char *device, char *ebuf, int *is_ours);
diff --git a/contrib/libpcap/pcap.3pcap b/contrib/libpcap/pcap.3pcap
deleted file mode 100644
index 79713e615dd79..0000000000000
--- a/contrib/libpcap/pcap.3pcap
+++ /dev/null
@@ -1,905 +0,0 @@
-.\" Copyright (c) 1994, 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: (1) source code distributions
-.\" retain the above copyright notice and this paragraph in its entirety, (2)
-.\" distributions including binary code include the above copyright notice and
-.\" this paragraph in its entirety in the documentation or other materials
-.\" provided with the distribution, and (3) all advertising materials mentioning
-.\" features or use of this software display the following acknowledgement:
-.\" ``This product includes software developed by the University of California,
-.\" Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
-.\" the University nor the names of its contributors may be used to endorse
-.\" or promote products derived from this software without specific prior
-.\" written permission.
-.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
-.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
-.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
-.\"
-.TH PCAP 3PCAP "16 April 2014"
-.SH NAME
-pcap \- Packet Capture library
-.SH SYNOPSIS
-.nf
-.ft B
-#include <pcap/pcap.h>
-.LP
-.ft B
-.ft
-.fi
-.SH DESCRIPTION
-The Packet Capture library
-provides a high level interface to packet capture systems. All packets
-on the network, even those destined for other hosts, are accessible
-through this mechanism.
-It also supports saving captured packets to a ``savefile'', and reading
-packets from a ``savefile''.
-.SS Opening a capture handle for reading
-To open a handle for a live capture, given the name of the network or
-other interface on which the capture should be done, call
-.BR pcap_create (),
-set the appropriate options on the handle, and then activate it with
-.BR pcap_activate ().
-.PP
-To obtain a list of devices that can be opened for a live capture, call
-.BR pcap_findalldevs ();
-to free the list returned by
-.BR pcap_findalldevs (),
-call
-.BR pcap_freealldevs ().
-.BR pcap_lookupdev ()
-will return the first device on that list that is not a ``loopback``
-network interface.
-.PP
-To open a handle for a ``savefile'' from which to read packets, given the
-pathname of the ``savefile'', call
-.BR pcap_open_offline ();
-to set up a handle for a ``savefile'', given a
-.B "FILE\ *"
-referring to a file already opened for reading, call
-.BR pcap_fopen_offline ().
-.PP
-In order to get a ``fake''
-.B pcap_t
-for use in routines that require a
-.B pcap_t
-as an argument, such as routines to open a ``savefile'' for writing and
-to compile a filter expression, call
-.BR pcap_open_dead ().
-.PP
-.BR pcap_create (),
-.BR pcap_open_offline (),
-.BR pcap_fopen_offline (),
-and
-.BR pcap_open_dead ()
-return a pointer to a
-.BR pcap_t ,
-which is the handle used for reading packets from the capture stream or
-the ``savefile'', and for finding out information about the capture
-stream or ``savefile''.
-To close a handle, use
-.BR pcap_close ().
-.PP
-The options that can be set on a capture handle include
-.IP "snapshot length"
-If, when capturing, you capture the entire contents of the packet, that
-requires more CPU time to copy the packet to your application, more disk
-and possibly network bandwidth to write the packet data to a file, and
-more disk space to save the packet. If you don't need the entire
-contents of the packet - for example, if you are only interested in the
-TCP headers of packets - you can set the "snapshot length" for the
-capture to an appropriate value. If the snapshot length is set to
-.IR snaplen ,
-and
-.I snaplen
-is less
-than the size of a packet that is captured, only the first
-.I snaplen
-bytes of that packet will be captured and provided as packet data.
-.IP
-A snapshot length of 65535 should be sufficient, on most if not all
-networks, to capture all the data available from the packet.
-.IP
-The snapshot length is set with
-.BR pcap_set_snaplen ().
-.IP "promiscuous mode"
-On broadcast LANs such as Ethernet, if the network isn't switched, or if
-the adapter is connected to a "mirror port" on a switch to which all
-packets passing through the switch are sent, a network adapter receives
-all packets on the LAN, including unicast or multicast packets not sent
-to a network address that the network adapter isn't configured to
-recognize.
-.IP
-Normally, the adapter will discard those packets; however, many network
-adapters support "promiscuous mode", which is a mode in which all
-packets, even if they are not sent to an address that the adapter
-recognizes, are provided to the host. This is useful for passively
-capturing traffic between two or more other hosts for analysis.
-.IP
-Note that even if an application does not set promiscuous mode, the
-adapter could well be in promiscuous mode for some other reason.
-.IP
-For now, this doesn't work on the "any" device; if an argument of "any"
-or NULL is supplied, the setting of promiscuous mode is ignored.
-.IP
-Promiscuous mode is set with
-.BR pcap_set_promisc ().
-.IP "monitor mode"
-On IEEE 802.11 wireless LANs, even if an adapter is in promiscuous mode,
-it will supply to the host only frames for the network with which it's
-associated. It might also supply only data frames, not management or
-control frames, and might not provide the 802.11 header or radio
-information pseudo-header for those frames.
-.IP
-In "monitor mode", sometimes also called "rfmon mode" (for "Radio
-Frequency MONitor"), the adapter will supply all frames that it
-receives, with 802.11 headers, and might supply a pseudo-header with
-radio information about the frame as well.
-.IP
-Note that in monitor mode the adapter might disassociate from the
-network with which it's associated, so that you will not be able to use
-any wireless networks with that adapter. This could prevent accessing
-files on a network server, or resolving host names or network addresses,
-if you are capturing in monitor mode and are not connected to another
-network with another adapter.
-.IP
-Monitor mode is set with
-.BR pcap_set_rfmon (),
-and
-.BR pcap_can_set_rfmon ()
-can be used to determine whether an adapter can be put into monitor
-mode.
-.IP "read timeout"
-If, when capturing, packets are delivered as soon as they arrive, the
-application capturing the packets will be woken up for each packet as it
-arrives, and might have to make one or more calls to the operating
-system to fetch each packet.
-.IP
-If, instead, packets are not delivered as soon as they arrive, but are
-delivered after a short delay (called a "read timeout"), more than one
-packet can be accumulated before the packets are delivered, so that a
-single wakeup would be done for multiple packets, and each set of calls
-made to the operating system would supply multiple packets, rather than
-a single packet. This reduces the per-packet CPU overhead if packets
-are arriving at a high rate, increasing the number of packets per second
-that can be captured.
-.IP
-The read timeout is required so that an application won't wait for the
-operating system's capture buffer to fill up before packets are
-delivered; if packets are arriving slowly, that wait could take an
-arbitrarily long period of time.
-.IP
-Not all platforms support a read timeout; on platforms that
-don't, the read timeout is ignored. A zero value for the timeout,
-on platforms that support a read timeout,
-will cause a read to wait forever to allow enough packets to
-arrive, with no timeout.
-.IP
-.BR NOTE :
-the read timeout cannot be used to cause calls that read
-packets to return within a limited period of time, because, on some
-platforms, the read timeout isn't supported, and, on other platforms,
-the timer doesn't start until at least one packet arrives. This means
-that the read timeout should
-.B NOT
-be used, for example, in an interactive application to allow the packet
-capture loop to ``poll'' for user input periodically, as there's no
-guarantee that a call reading packets will return after the timeout
-expires even if no packets have arrived.
-.IP
-The read timeout is set with
-.BR pcap_set_timeout ().
-.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
-some platforms, the buffer's size can be set; a size that's too small
-could mean that, if too many packets are being captured and the snapshot
-length doesn't limit the amount of data that's buffered, packets could
-be dropped if the buffer fills up before the application can read
-packets from it, while a size that's too large could use more
-non-pageable operating system memory than is necessary to prevent
-packets from being dropped.
-.IP
-The buffer size is set with
-.BR pcap_set_buffer_size ().
-.IP "timestamp type"
-On some platforms, the time stamp given to packets on live captures can
-come from different sources that can have different resolutions or that
-can have different relationships to the time values for the current time
-supplied by routines on the native operating system. See
-.BR pcap-tstamp (7)
-for a list of time stamp types.
-.IP
-The time stamp type is set with
-.BR pcap_set_tstamp_type ().
-.PP
-Reading packets from a network interface may require that you have
-special privileges:
-.TP
-.B Under SunOS 3.x or 4.x with NIT or BPF:
-You must have read access to
-.I /dev/nit
-or
-.IR /dev/bpf* .
-.TP
-.B Under Solaris with DLPI:
-You must have read/write access to the network pseudo device, e.g.
-.IR /dev/le .
-On at least some versions of Solaris, however, this is not sufficient to
-allow
-.I tcpdump
-to capture in promiscuous mode; on those versions of Solaris, you must
-be root, or the application capturing packets
-must be installed setuid to root, in order to capture in promiscuous
-mode. Note that, on many (perhaps all) interfaces, if you don't capture
-in promiscuous mode, you will not see any outgoing packets, so a capture
-not done in promiscuous mode may not be very useful.
-.IP
-In newer versions of Solaris, you must have been given the
-.B net_rawaccess
-privilege; this is both necessary and sufficient to give you access to the
-network pseudo-device - there is no need to change the privileges on
-that device. A user can be given that privilege by, for example, adding
-that privilege to the user's
-.B defaultpriv
-key with the
-.B usermod (1M)
-command.
-.TP
-.B Under HP-UX with DLPI:
-You must be root or the application capturing packets must be installed
-setuid to root.
-.TP
-.B Under IRIX with snoop:
-You must be root or the application capturing packets must be installed
-setuid to root.
-.TP
-.B Under Linux:
-You must be root or the application capturing packets must be installed
-setuid to root (unless your distribution has a kernel
-that supports capability bits such as CAP_NET_RAW and code to allow
-those capability bits to be given to particular accounts and to cause
-those bits to be set on a user's initial processes when they log in, in
-which case you must have CAP_NET_RAW in order to capture and
-CAP_NET_ADMIN to enumerate network devices with, for example, the
-.B \-D
-flag).
-.TP
-.B Under ULTRIX and Digital UNIX/Tru64 UNIX:
-Any user may capture network traffic.
-However, no user (not even the super-user) can capture in promiscuous
-mode on an interface unless the super-user has enabled promiscuous-mode
-operation on that interface using
-.IR pfconfig (8),
-and no user (not even the super-user) can capture unicast traffic
-received by or sent by the machine on an interface unless the super-user
-has enabled copy-all-mode operation on that interface using
-.IR pfconfig ,
-so
-.I useful
-packet capture on an interface probably requires that either
-promiscuous-mode or copy-all-mode operation, or both modes of
-operation, be enabled on that interface.
-.TP
-.B Under BSD (this includes Mac OS X):
-You must have read access to
-.I /dev/bpf*
-on systems that don't have a cloning BPF device, or to
-.I /dev/bpf
-on systems that do.
-On BSDs with a devfs (this includes Mac OS X), this might involve more
-than just having somebody with super-user access setting the ownership
-or permissions on the BPF devices - it might involve configuring devfs
-to set the ownership or permissions every time the system is booted,
-if the system even supports that; if it doesn't support that, you might
-have to find some other way to make that happen at boot time.
-.PP
-Reading a saved packet file doesn't require special privileges.
-.PP
-The packets read from the handle may include a ``pseudo-header''
-containing various forms of packet meta-data, and probably includes a
-link-layer header whose contents can differ for different network
-interfaces. To determine the format of the packets supplied by the
-handle, call
-.BR pcap_datalink ();
-.I http://www.tcpdump.org/linktypes.html
-lists the values it returns and describes the packet formats that
-correspond to those values.
-.PP
-Do
-.B NOT
-assume that the packets for a given capture or ``savefile`` will have
-any given link-layer header type, such as
-.B DLT_EN10MB
-for Ethernet. For example, the "any" device on Linux will have a
-link-layer header type of
-.B DLT_LINUX_SLL
-even if all devices on the system at the time the "any" device is opened
-have some other data link type, such as
-.B DLT_EN10MB
-for Ethernet.
-.PP
-To obtain the
-.B "FILE\ *"
-corresponding to a
-.B pcap_t
-opened for a ``savefile'', call
-.BR pcap_file ().
-.TP
-.B Routines
-.RS
-.TP
-.BR pcap_create (3PCAP)
-get a
-.B pcap_t
-for live capture
-.TP
-.BR pcap_activate (3PCAP)
-activate a
-.B pcap_t
-for live capture
-.TP
-.BR pcap_findalldevs (3PCAP)
-get a list of devices that can be opened for a live capture
-.TP
-.BR pcap_freealldevs (3PCAP)
-free list of devices
-.TP
-.BR pcap_lookupdev (3PCAP)
-get first non-loopback device on that list
-.TP
-.BR pcap_open_offline (3PCAP)
-open a
-.B pcap_t
-for a ``savefile'', given a pathname
-.TP
-.BR pcap_fopen_offline (3PCAP)
-open a
-.B pcap_t
-for a ``savefile'', given a
-.B "FILE\ *"
-.TP
-.BR pcap_open_dead (3PCAP)
-create a ``fake''
-.B pcap_t
-.TP
-.BR pcap_close (3PCAP)
-close a
-.B pcap_t
-.TP
-.BR pcap_set_snaplen (3PCAP)
-set the snapshot length for a not-yet-activated
-.B pcap_t
-for live capture
-.TP
-.BR pcap_snapshot (3PCAP)
-get the snapshot length for a
-.B pcap_t
-.TP
-.BR pcap_set_promisc (3PCAP)
-set promiscuous mode for a not-yet-activated
-.B pcap_t
-for live capture
-.TP
-.BR pcap_set_rfmon (3PCAP)
-set monitor mode for a not-yet-activated
-.B pcap_t
-for live capture
-.TP
-.BR pcap_can_set_rfmon (3PCAP)
-determine whether monitor mode can be set for a
-.B pcap_t
-for live capture
-.TP
-.BR pcap_set_timeout (3PCAP)
-set read timeout 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
-for live capture
-.TP
-.BR pcap_set_tstamp_type (3PCAP)
-set time stamp type for a not-yet-activated
-.B pcap_t
-for live capture
-.TP
-.BR pcap_list_tstamp_types (3PCAP)
-get list of available time stamp types for a not-yet-activated
-.B pcap_t
-for live capture
-.TP
-.BR pcap_free_tstamp_types (3PCAP)
-free list of available time stamp types
-.TP
-.BR pcap_tstamp_type_val_to_name (3PCAP)
-get name for a time stamp type
-.TP
-.BR pcap_tstamp_type_val_to_description (3PCAP)
-get description for a time stamp type
-.TP
-.BR pcap_tstamp_type_name_to_val (3PCAP)
-get time stamp type corresponding to a name
-.TP
-.BR pcap_datalink (3PCAP)
-get link-layer header type for a
-.B pcap_t
-.TP
-.BR pcap_file (3PCAP)
-get the
-.B "FILE\ *"
-for a
-.B pcap_t
-opened for a ``savefile''
-.TP
-.BR pcap_is_swapped (3PCAP)
-determine whether a ``savefile'' being read came from a machine with the
-opposite byte order
-.TP
-.BR pcap_major_version (3PCAP)
-.PD 0
-.TP
-.BR pcap_minor_version (3PCAP)
-get the major and minor version of the file format version for a
-``savefile''
-.PD
-.RE
-.SS Selecting a link-layer header type for a live capture
-Some devices may provide more than one link-layer header type. To
-obtain a list of all link-layer header types provided by a device, call
-.BR pcap_list_datalinks ()
-on an activated
-.B pcap_t
-for the device.
-To free a list of link-layer header types, call
-.BR pcap_free_datalinks ().
-To set the link-layer header type for a device, call
-.BR pcap_set_datalink ().
-This should be done after the device has been activated but before any
-packets are read and before any filters are compiled or installed.
-.TP
-.B Routines
-.RS
-.TP
-.BR pcap_list_datalinks (3PCAP)
-get a list of link-layer header types for a device
-.TP
-.BR pcap_free_datalinks (3PCAP)
-free list of link-layer header types
-.TP
-.BR pcap_set_datalink (3PCAP)
-set link-layer header type for a device
-.TP
-.BR pcap_datalink_val_to_name (3PCAP)
-get name for a link-layer header type
-.TP
-.BR pcap_datalink_val_to_description (3PCAP)
-get description for a link-layer header type
-.TP
-.BR pcap_datalink_name_to_val (3PCAP)
-get link-layer header type corresponding to a name
-.RE
-.SS Reading packets
-Packets are read with
-.BR pcap_dispatch ()
-or
-.BR pcap_loop (),
-which process one or more packets, calling a callback routine for each
-packet, or with
-.BR pcap_next ()
-or
-.BR pcap_next_ex (),
-which return the next packet.
-The callback for
-.BR pcap_dispatch ()
-and
-.BR pcap_loop ()
-is supplied a pointer to a
-.IR "struct pcap_pkthdr" ,
-which includes the following members:
-.RS
-.TP
-.B ts
-a
-.I struct timeval
-containing the time when the packet was captured
-.TP
-.B caplen
-a
-.I bpf_u_int32
-giving the number of bytes of the packet that are available from the
-capture
-.TP
-.B len
-a
-.I bpf_u_int32
-giving the length of the packet, in bytes (which might be more than the
-number of bytes available from the capture, if the length of the packet
-is larger than the maximum number of bytes to capture).
-.RE
-.PP
-The callback is also supplied a
-.I const u_char
-pointer to the first
-.B caplen
-(as given in the
-.I struct pcap_pkthdr
-mentioned above)
-bytes of data from the packet. This won't necessarily be the entire
-packet; to capture the entire packet, you will have to provide a value
-for
-.I snaplen
-in your call to
-.BR pcap_set_snaplen ()
-that is sufficiently large to get all of the packet's data - a value of
-65535 should be sufficient on most if not all networks). When reading
-from a ``savefile'', the snapshot length specified when the capture was
-performed will limit the amount of packet data available.
-.PP
-.BR pcap_next ()
-is passed an argument that points to a
-.I struct pcap_pkthdr
-structure, and fills it in with the time stamp and length values for the
-packet. It returns a
-.I const u_char
-to the first
-.B caplen
-bytes of the packet on success, and NULL on error.
-.PP
-.BR pcap_next_ex ()
-is passed two pointer arguments, one of which points to a
-.IR struct pcap_pkthdr *
-and one of which points to a
-.IR "const u_char" *.
-It sets the first pointer to point to a
-.I struct pcap_pkthdr
-structure with the time stamp and length values for the packet, and sets
-the second pointer to point to the first
-.B caplen
-bytes of the packet.
-.PP
-To force the loop in
-.BR pcap_dispatch ()
-or
-.BR pcap_loop ()
-to terminate, call
-.BR pcap_breakloop ().
-.PP
-By default, when reading packets from an interface opened for a live
-capture,
-.BR pcap_dispatch (),
-.BR pcap_next (),
-and
-.BR pcap_next_ex ()
-will, if no packets are currently available to be read, block waiting
-for packets to become available. On some, but
-.I not
-all, platforms, if a read timeout was specified, the wait will terminate
-after the read timeout expires; applications should be prepared for
-this, as it happens on some platforms, but should not rely on it, as it
-does not happen on other platforms.
-.PP
-A handle can be put into ``non-blocking mode'', so that those routines
-will, rather than blocking, return an indication that no packets are
-available to read. Call
-.BR pcap_setnonblock ()
-to put a handle into non-blocking mode or to take it out of non-blocking
-mode; call
-.BR pcap_getnonblock ()
-to determine whether a handle is in non-blocking mode. Note that
-non-blocking mode does not work correctly in Mac OS X 10.6.
-.PP
-Non-blocking mode is often combined with routines such as
-.BR select (2)
-or
-.BR poll (2)
-or other routines a platform offers to wait for the availability of data
-on any of a set of descriptors. To obtain, for a handle, a descriptor
-that can be used in those routines, call
-.BR pcap_get_selectable_fd ().
-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
-reasons, one or more of those routines will not work properly with the
-descriptor; the documentation for
-.BR pcap_get_selectable_fd ()
-gives details.
-.TP
-.B Routines
-.RS
-.TP
-.BR pcap_dispatch (3PCAP)
-read a bufferful of packets from a
-.B pcap_t
-open for a live capture or the full set of packets from a
-.B pcap_t
-open for a ``savefile''
-.TP
-.BR pcap_loop (3PCAP)
-read packets from a
-.B pcap_t
-until an interrupt or error occurs
-.TP
-.BR pcap_next (3PCAP)
-read the next packet from a
-.B pcap_t
-without an indication whether an error occurred
-.TP
-.BR pcap_next_ex (3PCAP)
-read the next packet from a
-.B pcap_t
-with an error indication on an error
-.TP
-.BR pcap_breakloop (3PCAP)
-prematurely terminate the loop in
-.BR pcap_dispatch ()
-or
-.BR pcap_loop ()
-.TP
-.BR pcap_setnonblock (3PCAP)
-set or clear non-blocking mode on a
-.B pcap_t
-.TP
-.BR pcap_getnonblock (3PCAP)
-get the state of non-blocking mode for a
-.B pcap_t
-.TP
-.BR pcap_get_selectable_fd (3PCAP)
-attempt to get a descriptor for a
-.B pcap_t
-that can be used in calls such as
-.BR select (2)
-and
-.BR poll (2)
-.RE
-.SS Filters
-In order to cause only certain packets to be returned when reading
-packets, a filter can be set on a handle. For a live capture, the
-filtering will be performed in kernel mode, if possible, to avoid
-copying ``uninteresting'' packets from the kernel to user mode.
-.PP
-A filter can be specified as a text string; the syntax and semantics of
-the string are as described by
-.BR pcap-filter (7).
-A filter string is compiled into a program in a pseudo-machine-language
-by
-.BR pcap_compile ()
-and the resulting program can be made a filter for a handle with
-.BR pcap_setfilter ().
-The result of
-.BR pcap_compile ()
-can be freed with a call to
-.BR pcap_freecode ().
-.BR pcap_compile ()
-may require a network mask for certain expressions in the filter string;
-.BR pcap_lookupnet ()
-can be used to find the network address and network mask for a given
-capture device.
-.PP
-A compiled filter can also be applied directly to a packet that has been
-read using
-.BR pcap_offline_filter ().
-.TP
-.B Routines
-.RS
-.TP
-.BR pcap_compile (3PCAP)
-compile filter expression to a pseudo-machine-language code program
-.TP
-.BR pcap_freecode (3PCAP)
-free a filter program
-.TP
-.BR pcap_setfilter (3PCAP)
-set filter for a
-.B pcap_t
-.TP
-.BR pcap_lookupnet (3PCAP)
-get network address and network mask for a capture device
-.TP
-.BR pcap_offline_filter (3PCAP)
-apply a filter program to a packet
-.RE
-.SS Incoming and outgoing packets
-By default, libpcap will attempt to capture both packets sent by the
-machine and packets received by the machine. To limit it to capturing
-only packets received by the machine or, if possible, only packets sent
-by the machine, call
-.BR pcap_setdirection ().
-.TP
-.BR Routines
-.RS
-.TP
-.BR pcap_setdirection (3PCAP)
-specify whether to capture incoming packets, outgoing packets, or both
-.RE
-.SS Capture statistics
-To get statistics about packets received and dropped in a live capture,
-call
-.BR pcap_stats ().
-.TP
-.B Routines
-.RS
-.TP
-.BR pcap_stats (3PCAP)
-get capture statistics
-.RE
-.SS Opening a handle for writing captured packets
-To open a ``savefile`` to which to write packets, given the pathname the
-``savefile'' should have, call
-.BR pcap_dump_open ().
-To open a ``savefile`` to which to write packets, given the pathname the
-``savefile'' should have, call
-.BR pcap_dump_open ();
-to set up a handle for a ``savefile'', given a
-.B "FILE\ *"
-referring to a file already opened for writing, call
-.BR pcap_dump_fopen ().
-They each return pointers to a
-.BR pcap_dumper_t ,
-which is the handle used for writing packets to the ``savefile''. If it
-succeeds, it will have created the file if it doesn't exist and
-truncated the file if it does exist.
-To close a
-.BR pcap_dumper_t ,
-call
-.BR pcap_dump_close ().
-.TP
-.B Routines
-.RS
-.TP
-.BR pcap_dump_open (3PCAP)
-open a
-.B pcap_dumper_t
-for a ``savefile``, given a pathname
-.TP
-.BR pcap_dump_fopen (3PCAP)
-open a
-.B pcap_dumper_t
-for a ``savefile``, given a
-.B "FILE\ *"
-.TP
-.BR pcap_dump_close (3PCAP)
-close a
-.B pcap_dumper_t
-.TP
-.BR pcap_dump_file (3PCAP)
-get the
-.B "FILE\ *"
-for a
-.B pcap_dumper_t
-opened for a ``savefile''
-.RE
-.SS Writing packets
-To write a packet to a
-.BR pcap_dumper_t ,
-call
-.BR pcap_dump ().
-Packets written with
-.BR pcap_dump ()
-may be buffered, rather than being immediately written to the
-``savefile''. Closing the
-.B pcap_dumper_t
-will cause all buffered-but-not-yet-written packets to be written to the
-``savefile''.
-To force all packets written to the
-.BR pcap_dumper_t ,
-and not yet written to the ``savefile'' because they're buffered by the
-.BR pcap_dumper_t ,
-to be written to the ``savefile'', without closing the
-.BR pcap_dumper_t ,
-call
-.BR pcap_dump_flush ().
-.TP
-.B Routines
-.RS
-.TP
-.BR pcap_dump (3PCAP)
-write packet to a
-.B pcap_dumper_t
-.TP
-.BR pcap_dump_flush (3PCAP)
-flush buffered packets written to a
-.B pcap_dumper_t
-to the ``savefile''
-.TP
-.BR pcap_dump_ftell (3PCAP)
-get current file position for a
-.B pcap_dumper_t
-.RE
-.SS Injecting packets
-If you have the required privileges, you can inject packets onto a
-network with a
-.B pcap_t
-for a live capture, using
-.BR pcap_inject ()
-or
-.BR pcap_sendpacket ().
-(The two routines exist for compatibility with both OpenBSD and WinPcap;
-they perform the same function, but have different return values.)
-.TP
-.B Routines
-.RS
-.TP
-.BR pcap_inject (3PCAP)
-.PD 0
-.TP
-.BR pcap_sendpacket (3PCAP)
-transmit a packet
-.PD
-.RE
-.SS Reporting errors
-Some routines return error or warning status codes; to convert them to a
-string, use
-.BR pcap_statustostr ().
-.TP
-.B Routines
-.RS
-.TP
-.BR pcap_statustostr (3PCAP)
-get a string for an error or warning status code
-.RE
-.SS Getting library version information
-To get a string giving version information about libpcap, call
-.BR pcap_lib_version ().
-.TP
-.B Routines
-.RS
-.TP
-.BR pcap_lib_version (3PCAP)
-get library version string
-.RE
-.SH BACKWARDS COMPATIBILITY
-.PP
-In versions of libpcap prior to 1.0, the
-.B pcap.h
-header file was not in a
-.B pcap
-directory on most platforms; if you are writing an application that must
-work on versions of libpcap prior to 1.0, include
-.BR <pcap.h> ,
-which will include
-.B <pcap/pcap.h>
-for you, rather than including
-.BR <pcap/pcap.h> .
-.PP
-.BR pcap_create ()
-and
-.BR pcap_activate ()
-were not available in versions of libpcap prior to 1.0; if you are
-writing an application that must work on versions of libpcap prior to
-1.0, either use
-.BR pcap_open_live ()
-to get a handle for a live capture or, if you want to be able to use the
-additional capabilities offered by using
-.BR pcap_create ()
-and
-.BR pcap_activate (),
-use an
-.BR autoconf (1)
-script or some other configuration script to check whether the libpcap
-1.0 APIs are available and use them only if they are.
-.SH SEE ALSO
-autoconf(1), tcpdump(1), tcpslice(1), pcap-filter(7), pfconfig(8),
-usermod(1M)
-.SH AUTHORS
-The original authors of libpcap are:
-.LP
-Van Jacobson,
-Craig Leres and
-Steven McCanne, all of the
-Lawrence Berkeley National Laboratory, University of California, Berkeley, CA.
-.LP
-The current version is available from "The Tcpdump Group"'s Web site at
-.LP
-.RS
-.I http://www.tcpdump.org/
-.RE
-.SH BUGS
-Please send problems, bugs, questions, desirable enhancements, etc. to:
-.LP
-.RS
-tcpdump-workers@lists.tcpdump.org
-.RE
diff --git a/contrib/libpcap/pcap.3pcap.in b/contrib/libpcap/pcap.3pcap.in
index 93478f1cd30f7..cf15941210bca 100644
--- a/contrib/libpcap/pcap.3pcap.in
+++ b/contrib/libpcap/pcap.3pcap.in
@@ -17,7 +17,7 @@
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\"
-.TH PCAP 3PCAP "8 March 2015"
+.TH PCAP 3PCAP "20 January 2017"
.SH NAME
pcap \- Packet Capture library
.SH SYNOPSIS
@@ -150,45 +150,46 @@ and
.BR pcap_can_set_rfmon ()
can be used to determine whether an adapter can be put into monitor
mode.
-.IP "read timeout"
+.IP "packet buffer timeout"
If, when capturing, packets are delivered as soon as they arrive, the
application capturing the packets will be woken up for each packet as it
arrives, and might have to make one or more calls to the operating
system to fetch each packet.
.IP
If, instead, packets are not delivered as soon as they arrive, but are
-delivered after a short delay (called a "read timeout"), more than one
-packet can be accumulated before the packets are delivered, so that a
-single wakeup would be done for multiple packets, and each set of calls
-made to the operating system would supply multiple packets, rather than
-a single packet. This reduces the per-packet CPU overhead if packets
-are arriving at a high rate, increasing the number of packets per second
-that can be captured.
+delivered after a short delay (called a "packet buffer timeout"), more
+than one packet can be accumulated before the packets are delivered, so
+that a single wakeup would be done for multiple packets, and each set of
+calls made to the operating system would supply multiple packets, rather
+than a single packet. This reduces the per-packet CPU overhead if
+packets are arriving at a high rate, increasing the number of packets
+per second that can be captured.
.IP
-The read timeout is required so that an application won't wait for the
-operating system's capture buffer to fill up before packets are
+The packet buffer timeout is required so that an application won't wait
+for the operating system's capture buffer to fill up before packets are
delivered; if packets are arriving slowly, that wait could take an
arbitrarily long period of time.
.IP
-Not all platforms support a read timeout; on platforms that
-don't, the read timeout is ignored. A zero value for the timeout,
-on platforms that support a read timeout,
-will cause a read to wait forever to allow enough packets to
-arrive, with no timeout.
+Not all platforms support a packet buffer timeout; on platforms that
+don't, the packet buffer timeout is ignored. A zero value for the
+timeout, on platforms that support a packet buffer timeout, will cause a
+read to wait forever to allow enough packets to arrive, with no timeout.
+A negative value is invalid; the result of setting the timeout to a
+negative value is unpredictable.
.IP
.BR NOTE :
-the read timeout cannot be used to cause calls that read
+the packet buffer timeout cannot be used to cause calls that read
packets to return within a limited period of time, because, on some
-platforms, the read timeout isn't supported, and, on other platforms,
-the timer doesn't start until at least one packet arrives. This means
-that the read timeout should
+platforms, the packet buffer timeout isn't supported, and, on other
+platforms, the timer doesn't start until at least one packet arrives.
+This means that the packet buffer timeout should
.B NOT
be used, for example, in an interactive application to allow the packet
capture loop to ``poll'' for user input periodically, as there's no
guarantee that a call reading packets will return after the timeout
expires even if no packets have arrived.
.IP
-The read timeout is set with
+The packet buffer timeout is set with
.BR pcap_set_timeout ().
.IP "buffer size"
Packets that arrive for a capture are stored in a buffer, so that they
@@ -244,7 +245,7 @@ that device. A user can be given that privilege by, for example, adding
that privilege to the user's
.B defaultpriv
key with the
-.B usermod (1M)
+.B usermod (@MAN_ADMIN_COMMANDS@)
command.
.TP
.B Under HP-UX with DLPI:
@@ -282,13 +283,13 @@ packet capture on an interface probably requires that either
promiscuous-mode or copy-all-mode operation, or both modes of
operation, be enabled on that interface.
.TP
-.B Under BSD (this includes Mac OS X):
+.B Under BSD (this includes macOS):
You must have read access to
.I /dev/bpf*
on systems that don't have a cloning BPF device, or to
.I /dev/bpf
on systems that do.
-On BSDs with a devfs (this includes Mac OS X), this might involve more
+On BSDs with a devfs (this includes macOS), this might involve more
than just having somebody with super-user access setting the ownership
or permissions on the BPF devices - it might involve configuring devfs
to set the ownership or permissions every time the system is booted,
@@ -395,6 +396,11 @@ set promiscuous mode for a not-yet-activated
.B pcap_t
for live capture
.TP
+.BR pcap_set_protocol (3PCAP)
+set capture protocol for a not-yet-activated
+.B pcap_t
+for live capture (Linux only)
+.TP
.BR pcap_set_rfmon (3PCAP)
set monitor mode for a not-yet-activated
.B pcap_t
@@ -406,7 +412,7 @@ determine whether monitor mode can be set for a
for live capture
.TP
.BR pcap_set_timeout (3PCAP)
-set read timeout for a not-yet-activated
+set packet buffer timeout for a not-yet-activated
.B pcap_t
for live capture
.TP
@@ -600,12 +606,13 @@ and
will, if no packets are currently available to be read, block waiting
for packets to become available. On some, but
.I not
-all, platforms, if a read timeout was specified, the wait will terminate
-after the read timeout expires; applications should be prepared for
-this, as it happens on some platforms, but should not rely on it, as it
-does not happen on other platforms. Note that the wait might, or might
-not, terminate even if no packets are available; applications should be
-prepared for this to happen, but must not rely on it happening.
+all, platforms, if a packet buffer timeout was specified, the wait will
+terminate after the packet buffer timeout expires; applications should
+be prepared for this, as it happens on some platforms, but should not
+rely on it, as it does not happen on other platforms. Note that the
+wait might, or might not, terminate even if no packets are available;
+applications should be prepared for this to happen, but must not rely on
+it happening.
.PP
A handle can be put into ``non-blocking mode'', so that those routines
will, rather than blocking, return an indication that no packets are
@@ -633,12 +640,12 @@ descriptor; the documentation for
.BR pcap_get_selectable_fd ()
gives details. Note that, just as an attempt to read packets from a
.B pcap_t
-may not return any packets if the read timeout expires, a
+may not return any packets if the packet buffer timeout expires, a
.BR select (),
.BR poll (),
-or other such call may, if the read timeout expires, indicate that a
-descriptor is ready to read even if there are no packets available to
-read.
+or other such call may, if the packet buffer timeout expires, indicate
+that a descriptor is ready to read even if there are no packets
+available to read.
.TP
.B Routines
.RS
@@ -915,7 +922,7 @@ script or some other configuration script to check whether the libpcap
1.0 APIs are available and use them only if they are.
.SH SEE ALSO
autoconf(1), tcpdump(1), tcpslice(1), pcap-filter(@MAN_MISC_INFO@), pfconfig(8),
-usermod(1M)
+usermod(@MAN_ADMIN_COMMANDS@)
.SH AUTHORS
The original authors of libpcap are:
.LP
@@ -930,8 +937,9 @@ The current version is available from "The Tcpdump Group"'s Web site at
.I http://www.tcpdump.org/
.RE
.SH BUGS
-Please send problems, bugs, questions, desirable enhancements, etc. to:
+To report a security issue please send an e-mail to security@tcpdump.org.
.LP
-.RS
-tcpdump-workers@lists.tcpdump.org
-.RE
+To report bugs and other problems, contribute patches, request a
+feature, provide generic feedback etc please see the file
+.I CONTRIBUTING
+in the libpcap source tree root.
diff --git a/contrib/libpcap/pcap.c b/contrib/libpcap/pcap.c
index 1590346cf8f6f..3337bcb3196a9 100644
--- a/contrib/libpcap/pcap.c
+++ b/contrib/libpcap/pcap.c
@@ -32,24 +32,28 @@
*/
#ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
#endif
-#ifdef _WIN32
-#include <pcap-stdinc.h>
-#else /* _WIN32 */
-#if HAVE_INTTYPES_H
-#include <inttypes.h>
-#elif HAVE_STDINT_H
-#include <stdint.h>
+#include <pcap-types.h>
+#ifndef _WIN32
+#include <sys/param.h>
+#ifndef MSDOS
+#include <sys/file.h>
#endif
-#ifdef HAVE_SYS_BITYPES_H
-#include <sys/bitypes.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#ifdef HAVE_SYS_SOCKIO_H
+#include <sys/sockio.h>
#endif
-#include <sys/types.h>
-#include <sys/mman.h>
+
+struct mbuf; /* Squelch compiler warnings on some platforms for */
+struct rtentry; /* declarations in <net/if.h> */
+#include <net/if.h>
+#include <netinet/in.h>
#endif /* _WIN32 */
+#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -58,6 +62,11 @@
#endif
#include <fcntl.h>
#include <errno.h>
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#else
+#define INT_MAX 2147483647
+#endif
#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
@@ -69,6 +78,8 @@
#include "pcap-int.h"
+#include "optimize.h"
+
#ifdef HAVE_DAG_API
#include "pcap-dag.h"
#endif /* HAVE_DAG_API */
@@ -102,16 +113,88 @@
#endif
#ifdef PCAP_SUPPORT_NETMAP
-pcap_t* pcap_netmap_create(const char *device, char *ebuf, int *is_ours);
+#include "pcap-netmap.h"
#endif
#ifdef PCAP_SUPPORT_DBUS
#include "pcap-dbus.h"
#endif
+#ifdef PCAP_SUPPORT_RDMASNIFF
+#include "pcap-rdmasniff.h"
+#endif
+
+#ifdef _WIN32
+/*
+ * DllMain(), required when built as a Windows DLL.
+ */
+BOOL WINAPI DllMain(
+ HANDLE hinstDLL,
+ DWORD dwReason,
+ LPVOID lpvReserved
+)
+{
+ return (TRUE);
+}
+
+/*
+ * Start WinSock.
+ * Exported in case some applications using WinPcap called it,
+ * even though it wasn't exported.
+ */
+int
+wsockinit(void)
+{
+ WORD wVersionRequested;
+ WSADATA wsaData;
+ static int err = -1;
+ static int done = 0;
+
+ if (done)
+ return (err);
+
+ wVersionRequested = MAKEWORD( 1, 1);
+ err = WSAStartup( wVersionRequested, &wsaData );
+ atexit ((void(*)(void))WSACleanup);
+ done = 1;
+
+ if ( err != 0 )
+ err = -1;
+ return (err);
+}
+
+/*
+ * This is the exported function; new programs should call this.
+ */
+int
+pcap_wsockinit(void)
+{
+ return (wsockinit());
+}
+#endif /* _WIN32 */
+
+/*
+ * String containing the library version.
+ * Not explicitly exported via a header file - the right API to use
+ * is pcap_lib_version() - but some programs included it, so we
+ * provide it.
+ *
+ * We declare it here, right before defining it, to squelch any
+ * warnings we might get from compilers about the lack of a
+ * declaration.
+ */
+PCAP_API char pcap_version[];
+PCAP_API_DEF char pcap_version[] = PACKAGE_VERSION;
+
static int
pcap_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 (PCAP_ERROR);
+ }
/* 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");
@@ -123,6 +206,12 @@ pcap_not_initialized(pcap_t *pcap)
static void *
pcap_not_initialized_ptr(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");
return (NULL);
@@ -131,6 +220,12 @@ pcap_not_initialized_ptr(pcap_t *pcap)
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");
return (INVALID_HANDLE_VALUE);
@@ -139,6 +234,12 @@ pcap_getevent_not_initialized(pcap_t *pcap)
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");
return (0);
@@ -147,6 +248,12 @@ pcap_sendqueue_transmit_not_initialized(pcap_t *pcap, pcap_send_queue* queue, in
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");
return (NULL);
@@ -195,8 +302,8 @@ pcap_list_tstamp_types(pcap_t *p, int **tstamp_typesp)
*tstamp_typesp = (int*)calloc(sizeof(**tstamp_typesp),
p->tstamp_type_count);
if (*tstamp_typesp == NULL) {
- (void)pcap_snprintf(p->errbuf, sizeof(p->errbuf),
- "malloc: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, sizeof(p->errbuf),
+ errno, "malloc");
return (PCAP_ERROR);
}
(void)memcpy(*tstamp_typesp, p->tstamp_type_list,
@@ -300,13 +407,17 @@ pcap_next_ex(pcap_t *p, struct pcap_pkthdr **pkt_header,
return (p->read_op(p, 1, p->oneshot_callback, (u_char *)&s));
}
+/*
+ * Implementation of a pcap_if_list_t.
+ */
+struct pcap_if_list {
+ pcap_if_t *beginning;
+};
+
static struct capture_source_type {
- int (*findalldevs_op)(pcap_if_t **, char *);
+ int (*findalldevs_op)(pcap_if_list_t *, char *);
pcap_t *(*create_op)(const char *, char *, int *);
} capture_source_types[] = {
-#ifdef PCAP_SUPPORT_NETMAP
- { NULL, pcap_netmap_create },
-#endif
#ifdef HAVE_DAG_API
{ dag_findalldevs, dag_create },
#endif
@@ -331,9 +442,15 @@ static struct capture_source_type {
#ifdef PCAP_SUPPORT_NETFILTER
{ netfilter_findalldevs, netfilter_create },
#endif
+#ifdef PCAP_SUPPORT_NETMAP
+ { pcap_netmap_findalldevs, pcap_netmap_create },
+#endif
#ifdef PCAP_SUPPORT_DBUS
{ dbus_findalldevs, dbus_create },
#endif
+#ifdef PCAP_SUPPORT_RDMASNIFF
+ { rdmasniff_findalldevs, rdmasniff_create },
+#endif
{ NULL, NULL }
};
@@ -347,35 +464,1503 @@ int
pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
{
size_t i;
+ pcap_if_list_t devlist;
/*
* Find all the local network interfaces on which we
* can capture.
*/
- if (pcap_platform_finddevs(alldevsp, errbuf) == -1)
+ devlist.beginning = NULL;
+ if (pcap_platform_finddevs(&devlist, errbuf) == -1) {
+ /*
+ * Failed - free all of the entries we were given
+ * before we failed.
+ */
+ if (devlist.beginning != NULL)
+ pcap_freealldevs(devlist.beginning);
+ *alldevsp = NULL;
return (-1);
+ }
/*
* Ask each of the non-local-network-interface capture
* source types what interfaces they have.
*/
for (i = 0; capture_source_types[i].findalldevs_op != NULL; i++) {
- if (capture_source_types[i].findalldevs_op(alldevsp, errbuf) == -1) {
+ if (capture_source_types[i].findalldevs_op(&devlist, errbuf) == -1) {
/*
* We had an error; free the list we've been
* constructing.
*/
- if (*alldevsp != NULL) {
- pcap_freealldevs(*alldevsp);
- *alldevsp = NULL;
+ if (devlist.beginning != NULL)
+ pcap_freealldevs(devlist.beginning);
+ *alldevsp = NULL;
+ return (-1);
+ }
+ }
+
+ /*
+ * Return the first entry of the list of all devices.
+ */
+ *alldevsp = devlist.beginning;
+ return (0);
+}
+
+static struct sockaddr *
+dup_sockaddr(struct sockaddr *sa, size_t sa_length)
+{
+ struct sockaddr *newsa;
+
+ if ((newsa = malloc(sa_length)) == NULL)
+ return (NULL);
+ return (memcpy(newsa, sa, sa_length));
+}
+
+/*
+ * Construct a "figure of merit" for an interface, for use when sorting
+ * the list of interfaces, in which interfaces that are up are superior
+ * to interfaces that aren't up, interfaces that are up and running are
+ * superior to interfaces that are up but not running, and non-loopback
+ * interfaces that are up and running are superior to loopback interfaces,
+ * and interfaces with the same flags have a figure of merit that's higher
+ * the lower the instance number.
+ *
+ * The goal is to try to put the interfaces most likely to be useful for
+ * capture at the beginning of the list.
+ *
+ * The figure of merit, which is lower the "better" the interface is,
+ * has the uppermost bit set if the interface isn't running, the bit
+ * below that set if the interface isn't up, the bit below that set
+ * if the interface is a loopback interface, and the interface index
+ * in the 29 bits below that. (Yes, we assume u_int is 32 bits.)
+ */
+static u_int
+get_figure_of_merit(pcap_if_t *dev)
+{
+ const char *cp;
+ u_int n;
+
+ if (strcmp(dev->name, "any") == 0) {
+ /*
+ * Give the "any" device an artificially high instance
+ * number, so it shows up after all other non-loopback
+ * interfaces.
+ */
+ n = 0x1FFFFFFF; /* 29 all-1 bits */
+ } else {
+ /*
+ * A number at the end of the device name string is
+ * assumed to be an instance number. Add 1 to the
+ * instance number, and use 0 for "no instance
+ * number", so we don't put "no instance number"
+ * devices and "instance 0" devices together.
+ */
+ cp = dev->name + strlen(dev->name) - 1;
+ while (cp-1 >= dev->name && *(cp-1) >= '0' && *(cp-1) <= '9')
+ cp--;
+ if (*cp >= '0' && *cp <= '9')
+ n = atoi(cp) + 1;
+ else
+ n = 0;
+ }
+ if (!(dev->flags & PCAP_IF_RUNNING))
+ n |= 0x80000000;
+ if (!(dev->flags & PCAP_IF_UP))
+ n |= 0x40000000;
+
+ /*
+ * Give non-wireless interfaces that aren't disconnected a better
+ * figure of merit than interfaces that are disconnected, as
+ * "disconnected" should indicate that the interface isn't
+ * plugged into a network and thus won't give you any traffic.
+ *
+ * For wireless interfaces, it means "associated with a network",
+ * which we presume not to necessarily prevent capture, as you
+ * might run the adapter in some flavor of monitor mode.
+ */
+ if (!(dev->flags & PCAP_IF_WIRELESS) &&
+ (dev->flags & PCAP_IF_CONNECTION_STATUS) == PCAP_IF_CONNECTION_STATUS_DISCONNECTED)
+ n |= 0x20000000;
+
+ /*
+ * Sort loopback devices after non-loopback devices, *except* for
+ * disconnected devices.
+ */
+ if (dev->flags & PCAP_IF_LOOPBACK)
+ n |= 0x10000000;
+
+ return (n);
+}
+
+#ifndef _WIN32
+/*
+ * Try to get a description for a given device.
+ * Returns a mallocated description if it could and NULL if it couldn't.
+ *
+ * XXX - on FreeBSDs that support it, should it get the sysctl named
+ * "dev.{adapter family name}.{adapter unit}.%desc" to get a description
+ * of the adapter? Note that "dev.an.0.%desc" is "Aironet PC4500/PC4800"
+ * with my Cisco 350 card, so the name isn't entirely descriptive. The
+ * "dev.an.0.%pnpinfo" has a better description, although one might argue
+ * that the problem is really a driver bug - if it can find out that it's
+ * a Cisco 340 or 350, rather than an old Aironet card, it should use
+ * that in the description.
+ *
+ * Do NetBSD, DragonflyBSD, or OpenBSD support this as well? FreeBSD
+ * and OpenBSD let you get a description, but it's not generated by the OS,
+ * it's set with another ioctl that ifconfig supports; we use that to get
+ * a description in FreeBSD and OpenBSD, but if there is no such
+ * description available, it still might be nice to get some description
+ * string based on the device type or something such as that.
+ *
+ * In macOS, the System Configuration framework can apparently return
+ * names in 10.4 and later.
+ *
+ * It also appears that freedesktop.org's HAL offers an "info.product"
+ * string, but the HAL specification says it "should not be used in any
+ * UI" and "subsystem/capability specific properties" should be used
+ * instead and, in any case, I think HAL is being deprecated in
+ * favor of other stuff such as DeviceKit. DeviceKit doesn't appear
+ * to have any obvious product information for devices, but maybe
+ * I haven't looked hard enough.
+ *
+ * Using the System Configuration framework, or HAL, or DeviceKit, or
+ * whatever, would require that libpcap applications be linked with
+ * the frameworks/libraries in question. That shouldn't be a problem
+ * for programs linking with the shared version of libpcap (unless
+ * you're running on AIX - which I think is the only UN*X that doesn't
+ * support linking a shared library with other libraries on which it
+ * depends, and having an executable linked only with the first shared
+ * library automatically pick up the other libraries when started -
+ * and using HAL or whatever). Programs linked with the static
+ * version of libpcap would have to use pcap-config with the --static
+ * flag in order to get the right linker flags in order to pick up
+ * the additional libraries/frameworks; those programs need that anyway
+ * for libpcap 1.1 and beyond on Linux, as, by default, it requires
+ * -lnl.
+ *
+ * Do any other UN*Xes, or desktop environments support getting a
+ * description?
+ */
+static char *
+#ifdef SIOCGIFDESCR
+get_if_description(const char *name)
+{
+ char *description = NULL;
+ int s;
+ struct ifreq ifrdesc;
+#ifndef IFDESCRSIZE
+ size_t descrlen = 64;
+#else
+ size_t descrlen = IFDESCRSIZE;
+#endif /* IFDESCRSIZE */
+
+ /*
+ * Get the description for the interface.
+ */
+ memset(&ifrdesc, 0, sizeof ifrdesc);
+ strlcpy(ifrdesc.ifr_name, name, sizeof ifrdesc.ifr_name);
+ s = socket(AF_INET, SOCK_DGRAM, 0);
+ if (s >= 0) {
+#ifdef __FreeBSD__
+ /*
+ * On FreeBSD, if the buffer isn't big enough for the
+ * description, the ioctl succeeds, but the description
+ * isn't copied, ifr_buffer.length is set to the description
+ * length, and ifr_buffer.buffer is set to NULL.
+ */
+ for (;;) {
+ free(description);
+ if ((description = malloc(descrlen)) != NULL) {
+ ifrdesc.ifr_buffer.buffer = description;
+ ifrdesc.ifr_buffer.length = descrlen;
+ if (ioctl(s, SIOCGIFDESCR, &ifrdesc) == 0) {
+ if (ifrdesc.ifr_buffer.buffer ==
+ description)
+ break;
+ else
+ descrlen = ifrdesc.ifr_buffer.length;
+ } else {
+ /*
+ * Failed to get interface description.
+ */
+ free(description);
+ description = NULL;
+ break;
+ }
+ } else
+ break;
+ }
+#else /* __FreeBSD__ */
+ /*
+ * The only other OS that currently supports
+ * SIOCGIFDESCR is OpenBSD, and it has no way
+ * to get the description length - it's clamped
+ * to a maximum of IFDESCRSIZE.
+ */
+ if ((description = malloc(descrlen)) != NULL) {
+ ifrdesc.ifr_data = (caddr_t)description;
+ if (ioctl(s, SIOCGIFDESCR, &ifrdesc) != 0) {
+ /*
+ * Failed to get interface description.
+ */
+ free(description);
+ description = NULL;
}
+ }
+#endif /* __FreeBSD__ */
+ close(s);
+ if (description != NULL && strlen(description) == 0) {
+ /*
+ * Description is empty, so discard it.
+ */
+ free(description);
+ description = NULL;
+ }
+ }
+
+#ifdef __FreeBSD__
+ /*
+ * For FreeBSD, if we didn't get a description, and this is
+ * a device with a name of the form usbusN, label it as a USB
+ * bus.
+ */
+ if (description == NULL) {
+ if (strncmp(name, "usbus", 5) == 0) {
+ /*
+ * OK, it begins with "usbus".
+ */
+ long busnum;
+ char *p;
+
+ errno = 0;
+ busnum = strtol(name + 5, &p, 10);
+ if (errno == 0 && p != name + 5 && *p == '\0' &&
+ busnum >= 0 && busnum <= INT_MAX) {
+ /*
+ * OK, it's a valid number that's not
+ * bigger than INT_MAX. Construct
+ * a description from it.
+ */
+ 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);
+ }
+ }
+ }
+ }
+#endif
+ return (description);
+#else /* SIOCGIFDESCR */
+get_if_description(const char *name _U_)
+{
+ return (NULL);
+#endif /* SIOCGIFDESCR */
+}
+
+/*
+ * Look for a given device in the specified list of devices.
+ *
+ * If we find it, return a pointer to its entry.
+ *
+ * If we don't find it, attempt to add an entry for it, with the specified
+ * IFF_ flags and description, and, if that succeeds, return a pointer to
+ * the new entry, otherwise return NULL and set errbuf to an error message.
+ */
+pcap_if_t *
+find_or_add_if(pcap_if_list_t *devlistp, const char *name,
+ bpf_u_int32 if_flags, get_if_flags_func get_flags_func, char *errbuf)
+{
+ bpf_u_int32 pcap_flags;
+
+ /*
+ * Convert IFF_ flags to pcap flags.
+ */
+ pcap_flags = 0;
+#ifdef IFF_LOOPBACK
+ if (if_flags & IFF_LOOPBACK)
+ pcap_flags |= PCAP_IF_LOOPBACK;
+#else
+ /*
+ * We don't have IFF_LOOPBACK, so look at the device name to
+ * see if it looks like a loopback device.
+ */
+ if (name[0] == 'l' && name[1] == 'o' &&
+ (isdigit((unsigned char)(name[2])) || name[2] == '\0')
+ pcap_flags |= PCAP_IF_LOOPBACK;
+#endif
+#ifdef IFF_UP
+ if (if_flags & IFF_UP)
+ pcap_flags |= PCAP_IF_UP;
+#endif
+#ifdef IFF_RUNNING
+ if (if_flags & IFF_RUNNING)
+ pcap_flags |= PCAP_IF_RUNNING;
+#endif
+
+ /*
+ * Attempt to find an entry for this device; if we don't find one,
+ * attempt to add one.
+ */
+ return (find_or_add_dev(devlistp, name, pcap_flags,
+ get_flags_func, get_if_description(name), errbuf));
+}
+
+/*
+ * Look for a given device in the specified list of devices.
+ *
+ * If we find it, then, if the specified address isn't null, add it to
+ * the list of addresses for the device and return 0.
+ *
+ * If we don't find it, attempt to add an entry for it, with the specified
+ * IFF_ flags and description, and, if that succeeds, add the specified
+ * address to its list of addresses if that address is non-null, and
+ * return 0, otherwise return -1 and set errbuf to an error message.
+ *
+ * (We can get called with a null address because we might get a list
+ * of interface name/address combinations from the underlying OS, with
+ * the address being absent in some cases, rather than a list of
+ * interfaces with each interface having a list of addresses, so this
+ * call may be the only call made to add to the list, and we want to
+ * add interfaces even if they have no addresses.)
+ */
+int
+add_addr_to_if(pcap_if_list_t *devlistp, const char *name,
+ bpf_u_int32 if_flags, get_if_flags_func get_flags_func,
+ struct sockaddr *addr, size_t addr_size,
+ struct sockaddr *netmask, size_t netmask_size,
+ struct sockaddr *broadaddr, size_t broadaddr_size,
+ struct sockaddr *dstaddr, size_t dstaddr_size,
+ char *errbuf)
+{
+ pcap_if_t *curdev;
+
+ /*
+ * Check whether the device exists and, if not, add it.
+ */
+ curdev = find_or_add_if(devlistp, name, if_flags, get_flags_func,
+ errbuf);
+ if (curdev == NULL) {
+ /*
+ * Error - give up.
+ */
+ return (-1);
+ }
+
+ if (addr == NULL) {
+ /*
+ * There's no address to add; this entry just meant
+ * "here's a new interface".
+ */
+ return (0);
+ }
+
+ /*
+ * "curdev" is an entry for this interface, and we have an
+ * address for it; add an entry for that address to the
+ * interface's list of addresses.
+ */
+ return (add_addr_to_dev(curdev, addr, addr_size, netmask,
+ netmask_size, broadaddr, broadaddr_size, dstaddr,
+ dstaddr_size, errbuf));
+}
+#endif /* _WIN32 */
+
+/*
+ * Add an entry to the list of addresses for an interface.
+ * "curdev" is the entry for that interface.
+ */
+int
+add_addr_to_dev(pcap_if_t *curdev,
+ struct sockaddr *addr, size_t addr_size,
+ struct sockaddr *netmask, size_t netmask_size,
+ struct sockaddr *broadaddr, size_t broadaddr_size,
+ struct sockaddr *dstaddr, size_t dstaddr_size,
+ char *errbuf)
+{
+ pcap_addr_t *curaddr, *prevaddr, *nextaddr;
+
+ /*
+ * Allocate the new entry and fill it in.
+ */
+ curaddr = (pcap_addr_t *)malloc(sizeof(pcap_addr_t));
+ if (curaddr == NULL) {
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ errno, "malloc");
+ return (-1);
+ }
+
+ curaddr->next = NULL;
+ if (addr != NULL && addr_size != 0) {
+ curaddr->addr = (struct sockaddr *)dup_sockaddr(addr, addr_size);
+ if (curaddr->addr == NULL) {
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ errno, "malloc");
+ free(curaddr);
+ return (-1);
+ }
+ } else
+ curaddr->addr = NULL;
+
+ if (netmask != NULL && netmask_size != 0) {
+ curaddr->netmask = (struct sockaddr *)dup_sockaddr(netmask, netmask_size);
+ if (curaddr->netmask == NULL) {
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ errno, "malloc");
+ if (curaddr->addr != NULL)
+ free(curaddr->addr);
+ free(curaddr);
+ return (-1);
+ }
+ } else
+ curaddr->netmask = NULL;
+
+ if (broadaddr != NULL && broadaddr_size != 0) {
+ curaddr->broadaddr = (struct sockaddr *)dup_sockaddr(broadaddr, broadaddr_size);
+ if (curaddr->broadaddr == NULL) {
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ errno, "malloc");
+ if (curaddr->netmask != NULL)
+ free(curaddr->netmask);
+ if (curaddr->addr != NULL)
+ free(curaddr->addr);
+ free(curaddr);
+ return (-1);
+ }
+ } else
+ curaddr->broadaddr = NULL;
+
+ if (dstaddr != NULL && dstaddr_size != 0) {
+ curaddr->dstaddr = (struct sockaddr *)dup_sockaddr(dstaddr, dstaddr_size);
+ if (curaddr->dstaddr == NULL) {
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ errno, "malloc");
+ if (curaddr->broadaddr != NULL)
+ free(curaddr->broadaddr);
+ if (curaddr->netmask != NULL)
+ free(curaddr->netmask);
+ if (curaddr->addr != NULL)
+ free(curaddr->addr);
+ free(curaddr);
return (-1);
}
+ } else
+ curaddr->dstaddr = NULL;
+
+ /*
+ * Find the end of the list of addresses.
+ */
+ for (prevaddr = curdev->addresses; prevaddr != NULL; prevaddr = nextaddr) {
+ nextaddr = prevaddr->next;
+ if (nextaddr == NULL) {
+ /*
+ * This is the end of the list.
+ */
+ break;
+ }
+ }
+
+ if (prevaddr == NULL) {
+ /*
+ * The list was empty; this is the first member.
+ */
+ curdev->addresses = curaddr;
+ } else {
+ /*
+ * "prevaddr" is the last member of the list; append
+ * this member to it.
+ */
+ prevaddr->next = curaddr;
}
return (0);
}
+/*
+ * Look for a given device in the specified list of devices.
+ *
+ * If we find it, return 0 and set *curdev_ret to point to it.
+ *
+ * If we don't find it, attempt to add an entry for it, with the specified
+ * flags and description, and, if that succeeds, return 0, otherwise
+ * return -1 and set errbuf to an error message.
+ */
+pcap_if_t *
+find_or_add_dev(pcap_if_list_t *devlistp, const char *name, bpf_u_int32 flags,
+ get_if_flags_func get_flags_func, const char *description, char *errbuf)
+{
+ pcap_if_t *curdev;
+
+ /*
+ * Is there already an entry in the list for this device?
+ */
+ curdev = find_dev(devlistp, name);
+ if (curdev != NULL) {
+ /*
+ * Yes, return it.
+ */
+ return (curdev);
+ }
+
+ /*
+ * No, we didn't find it.
+ */
+
+ /*
+ * Try to get additional flags for the device.
+ */
+ if ((*get_flags_func)(name, &flags, errbuf) == -1) {
+ /*
+ * Failed.
+ */
+ return (NULL);
+ }
+
+ /*
+ * Now, try to add it to the list of devices.
+ */
+ return (add_dev(devlistp, name, flags, description, errbuf));
+}
+
+/*
+ * Look for a given device in the specified list of devices, and return
+ * the entry for it if we find it or NULL if we don't.
+ */
+pcap_if_t *
+find_dev(pcap_if_list_t *devlistp, const char *name)
+{
+ pcap_if_t *curdev;
+
+ /*
+ * Is there an entry in the list for this device?
+ */
+ for (curdev = devlistp->beginning; curdev != NULL;
+ curdev = curdev->next) {
+ if (strcmp(name, curdev->name) == 0) {
+ /*
+ * We found it, so, yes, there is. No need to
+ * add it. Provide the entry we found to our
+ * caller.
+ */
+ return (curdev);
+ }
+ }
+
+ /*
+ * No.
+ */
+ return (NULL);
+}
+
+/*
+ * Attempt to add an entry for a device, with the specified flags
+ * and description, and, if that succeeds, return 0 and return a pointer
+ * to the new entry, otherwise return NULL and set errbuf to an error
+ * message.
+ *
+ * If we weren't given a description, try to get one.
+ */
+pcap_if_t *
+add_dev(pcap_if_list_t *devlistp, const char *name, bpf_u_int32 flags,
+ const char *description, char *errbuf)
+{
+ pcap_if_t *curdev, *prevdev, *nextdev;
+ u_int this_figure_of_merit, nextdev_figure_of_merit;
+
+ curdev = malloc(sizeof(pcap_if_t));
+ if (curdev == NULL) {
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ errno, "malloc");
+ return (NULL);
+ }
+
+ /*
+ * Fill in the entry.
+ */
+ curdev->next = NULL;
+ curdev->name = strdup(name);
+ if (curdev->name == NULL) {
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ errno, "malloc");
+ free(curdev);
+ return (NULL);
+ }
+ if (description == NULL) {
+ /*
+ * We weren't handed a description for the interface.
+ */
+ curdev->description = NULL;
+ } else {
+ /*
+ * We were handed a description; make a copy.
+ */
+ curdev->description = strdup(description);
+ if (curdev->description == NULL) {
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ errno, "malloc");
+ free(curdev->name);
+ free(curdev);
+ return (NULL);
+ }
+ }
+ curdev->addresses = NULL; /* list starts out as empty */
+ curdev->flags = flags;
+
+ /*
+ * Add it to the list, in the appropriate location.
+ * First, get the "figure of merit" for this interface.
+ */
+ this_figure_of_merit = get_figure_of_merit(curdev);
+
+ /*
+ * Now look for the last interface with an figure of merit
+ * less than or equal to the new interface's figure of merit.
+ *
+ * We start with "prevdev" being NULL, meaning we're before
+ * the first element in the list.
+ */
+ prevdev = NULL;
+ for (;;) {
+ /*
+ * Get the interface after this one.
+ */
+ if (prevdev == NULL) {
+ /*
+ * The next element is the first element.
+ */
+ nextdev = devlistp->beginning;
+ } else
+ nextdev = prevdev->next;
+
+ /*
+ * Are we at the end of the list?
+ */
+ if (nextdev == NULL) {
+ /*
+ * Yes - we have to put the new entry after "prevdev".
+ */
+ break;
+ }
+
+ /*
+ * Is the new interface's figure of merit less
+ * than the next interface's figure of merit,
+ * meaning that the new interface is better
+ * than the next interface?
+ */
+ nextdev_figure_of_merit = get_figure_of_merit(nextdev);
+ if (this_figure_of_merit < nextdev_figure_of_merit) {
+ /*
+ * Yes - we should put the new entry
+ * before "nextdev", i.e. after "prevdev".
+ */
+ break;
+ }
+
+ prevdev = nextdev;
+ }
+
+ /*
+ * Insert before "nextdev".
+ */
+ curdev->next = nextdev;
+
+ /*
+ * Insert after "prevdev" - unless "prevdev" is null,
+ * in which case this is the first interface.
+ */
+ if (prevdev == NULL) {
+ /*
+ * This is the first interface. Make it
+ * the first element in the list of devices.
+ */
+ devlistp->beginning = curdev;
+ } else
+ prevdev->next = curdev;
+ return (curdev);
+}
+
+/*
+ * Free a list of interfaces.
+ */
+void
+pcap_freealldevs(pcap_if_t *alldevs)
+{
+ pcap_if_t *curdev, *nextdev;
+ pcap_addr_t *curaddr, *nextaddr;
+
+ for (curdev = alldevs; curdev != NULL; curdev = nextdev) {
+ nextdev = curdev->next;
+
+ /*
+ * Free all addresses.
+ */
+ for (curaddr = curdev->addresses; curaddr != NULL; curaddr = nextaddr) {
+ nextaddr = curaddr->next;
+ if (curaddr->addr)
+ free(curaddr->addr);
+ if (curaddr->netmask)
+ free(curaddr->netmask);
+ if (curaddr->broadaddr)
+ free(curaddr->broadaddr);
+ if (curaddr->dstaddr)
+ free(curaddr->dstaddr);
+ free(curaddr);
+ }
+
+ /*
+ * Free the name string.
+ */
+ free(curdev->name);
+
+ /*
+ * Free the description string, if any.
+ */
+ if (curdev->description != NULL)
+ free(curdev->description);
+
+ /*
+ * Free the interface.
+ */
+ free(curdev);
+ }
+}
+
+/*
+ * pcap-npf.c has its own pcap_lookupdev(), for compatibility reasons, as
+ * it actually returns the names of all interfaces, with a NUL separator
+ * between them; some callers may depend on that.
+ *
+ * MS-DOS has its own pcap_lookupdev(), but that might be useful only
+ * as an optimization.
+ *
+ * In all other cases, we just use pcap_findalldevs() to get a list of
+ * devices, and pick from that list.
+ */
+#if !defined(HAVE_PACKET32) && !defined(MSDOS)
+/*
+ * Return the name of a network interface attached to the system, or NULL
+ * if none can be found. The interface must be configured up; the
+ * lowest unit number is preferred; loopback is ignored.
+ */
+char *
+pcap_lookupdev(char *errbuf)
+{
+ pcap_if_t *alldevs;
+#ifdef _WIN32
+ /*
+ * Windows - use the same size as the old WinPcap 3.1 code.
+ * XXX - this is probably bigger than it needs to be.
+ */
+ #define IF_NAMESIZE 8192
+#else
+ /*
+ * UN*X - use the system's interface name size.
+ * XXX - that might not be large enough for capture devices
+ * that aren't regular network interfaces.
+ */
+ /* for old BSD systems, including bsdi3 */
+ #ifndef IF_NAMESIZE
+ #define IF_NAMESIZE IFNAMSIZ
+ #endif
+#endif
+ static char device[IF_NAMESIZE + 1];
+ char *ret;
+
+ if (pcap_findalldevs(&alldevs, errbuf) == -1)
+ return (NULL);
+
+ if (alldevs == NULL || (alldevs->flags & PCAP_IF_LOOPBACK)) {
+ /*
+ * There are no devices on the list, or the first device
+ * on the list is a loopback device, which means there
+ * are no non-loopback devices on the list. This means
+ * we can't return any device.
+ *
+ * XXX - why not return a loopback device? If we can't
+ * capture on it, it won't be on the list, and if it's
+ * 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",
+ PCAP_ERRBUF_SIZE);
+ ret = NULL;
+ } else {
+ /*
+ * Return the name of the first device on the list.
+ */
+ (void)strlcpy(device, alldevs->name, sizeof(device));
+ ret = device;
+ }
+
+ pcap_freealldevs(alldevs);
+ return (ret);
+}
+#endif /* !defined(HAVE_PACKET32) && !defined(MSDOS) */
+
+#if !defined(_WIN32) && !defined(MSDOS)
+/*
+ * We don't just fetch the entire list of devices, search for the
+ * particular device, and use its first IPv4 address, as that's too
+ * much work to get just one device's netmask.
+ *
+ * If we had an API to get attributes for a given device, we could
+ * use that.
+ */
+int
+pcap_lookupnet(const char *device, bpf_u_int32 *netp, bpf_u_int32 *maskp,
+ char *errbuf)
+{
+ register int fd;
+ register struct sockaddr_in *sin4;
+ struct ifreq ifr;
+
+ /*
+ * The pseudo-device "any" listens on all interfaces and therefore
+ * has the network address and -mask "0.0.0.0" therefore catching
+ * all traffic. Using NULL for the interface is the same as "any".
+ */
+ if (!device || strcmp(device, "any") == 0
+#ifdef HAVE_DAG_API
+ || strstr(device, "dag") != NULL
+#endif
+#ifdef HAVE_SEPTEL_API
+ || strstr(device, "septel") != NULL
+#endif
+#ifdef PCAP_SUPPORT_BT
+ || strstr(device, "bluetooth") != NULL
+#endif
+#ifdef PCAP_SUPPORT_USB
+ || strstr(device, "usbmon") != NULL
+#endif
+#ifdef HAVE_SNF_API
+ || strstr(device, "snf") != NULL
+#endif
+#ifdef PCAP_SUPPORT_NETMAP
+ || strncmp(device, "netmap:", 7) == 0
+ || strncmp(device, "vale", 4) == 0
+#endif
+ ) {
+ *netp = *maskp = 0;
+ return 0;
+ }
+
+ fd = socket(AF_INET, SOCK_DGRAM, 0);
+ if (fd < 0) {
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ errno, "socket");
+ return (-1);
+ }
+ memset(&ifr, 0, sizeof(ifr));
+#ifdef linux
+ /* XXX Work around Linux kernel bug */
+ ifr.ifr_addr.sa_family = AF_INET;
+#endif
+ (void)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,
+ "%s: no IPv4 address assigned", device);
+ } else {
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ errno, "SIOCGIFADDR: %s", device);
+ }
+ (void)close(fd);
+ return (-1);
+ }
+ sin4 = (struct sockaddr_in *)&ifr.ifr_addr;
+ *netp = sin4->sin_addr.s_addr;
+ memset(&ifr, 0, sizeof(ifr));
+#ifdef linux
+ /* XXX Work around Linux kernel bug */
+ ifr.ifr_addr.sa_family = AF_INET;
+#endif
+ (void)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);
+ (void)close(fd);
+ return (-1);
+ }
+ (void)close(fd);
+ *maskp = sin4->sin_addr.s_addr;
+ if (*maskp == 0) {
+ if (IN_CLASSA(*netp))
+ *maskp = IN_CLASSA_NET;
+ else if (IN_CLASSB(*netp))
+ *maskp = IN_CLASSB_NET;
+ else if (IN_CLASSC(*netp))
+ *maskp = IN_CLASSC_NET;
+ else {
+ (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "inet class for 0x%x unknown", *netp);
+ return (-1);
+ }
+ }
+ *netp &= *maskp;
+ return (0);
+}
+#endif /* !defined(_WIN32) && !defined(MSDOS) */
+
+#ifdef ENABLE_REMOTE
+#include "pcap-rpcap.h"
+
+/*
+ * Extract a substring from a string.
+ */
+static char *
+get_substring(const char *p, size_t len, char *ebuf)
+{
+ char *token;
+
+ token = malloc(len + 1);
+ if (token == NULL) {
+ pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
+ errno, "malloc");
+ return (NULL);
+ }
+ memcpy(token, p, len);
+ token[len] = '\0';
+ return (token);
+}
+
+/*
+ * Parse a capture source that might be a URL.
+ *
+ * If the source is not a URL, *schemep, *userinfop, *hostp, and *portp
+ * are set to NULL, *pathp is set to point to the source, and 0 is
+ * returned.
+ *
+ * If source is a URL, and the URL refers to a local device (a special
+ * case of rpcap:), *schemep, *userinfop, *hostp, and *portp are set
+ * to NULL, *pathp is set to point to the device name, and 0 is returned.
+ *
+ * If source is a URL, and it's not a special case that refers to a local
+ * device, and the parse succeeds:
+ *
+ * *schemep is set to point to an allocated string containing the scheme;
+ *
+ * if user information is present in the URL, *userinfop is set to point
+ * to an allocated string containing the user information, otherwise
+ * it's set to NULL;
+ *
+ * if host information is present in the URL, *hostp is set to point
+ * to an allocated string containing the host information, otherwise
+ * it's set to NULL;
+ *
+ * if a port number is present in the URL, *portp is set to point
+ * to an allocated string containing the port number, otherwise
+ * it's set to NULL;
+ *
+ * *pathp is set to point to an allocated string containing the
+ * path;
+ *
+ * and 0 is returned.
+ *
+ * If the parse fails, ebuf is set to an error string, and -1 is returned.
+ */
+static int
+pcap_parse_source(const char *source, char **schemep, char **userinfop,
+ char **hostp, char **portp, char **pathp, char *ebuf)
+{
+ char *colonp;
+ size_t scheme_len;
+ char *scheme;
+ const char *endp;
+ size_t authority_len;
+ char *authority;
+ char *parsep, *atsignp, *bracketp;
+ char *userinfo, *host, *port, *path;
+
+ /*
+ * Start out returning nothing.
+ */
+ *schemep = NULL;
+ *userinfop = NULL;
+ *hostp = NULL;
+ *portp = NULL;
+ *pathp = NULL;
+
+ /*
+ * RFC 3986 says:
+ *
+ * URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
+ *
+ * hier-part = "//" authority path-abempty
+ * / path-absolute
+ * / path-rootless
+ * / path-empty
+ *
+ * authority = [ userinfo "@" ] host [ ":" port ]
+ *
+ * userinfo = *( unreserved / pct-encoded / sub-delims / ":" )
+ *
+ * Step 1: look for the ":" at the end of the scheme.
+ * A colon in the source is *NOT* sufficient to indicate that
+ * this is a URL, as interface names on some platforms might
+ * include colons (e.g., I think some Solaris interfaces
+ * might).
+ */
+ colonp = strchr(source, ':');
+ if (colonp == NULL) {
+ /*
+ * The source is the device to open.
+ * Return a NULL pointer for the scheme, user information,
+ * host, and port, and return the device as the path.
+ */
+ *pathp = strdup(source);
+ if (*pathp == NULL) {
+ pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
+ errno, "malloc");
+ return (-1);
+ }
+ return (0);
+ }
+
+ /*
+ * All schemes must have "//" after them, i.e. we only support
+ * hier-part = "//" authority path-abempty, not
+ * hier-part = path-absolute
+ * hier-part = path-rootless
+ * hier-part = path-empty
+ *
+ * We need that in order to distinguish between a local device
+ * name that happens to contain a colon and a URI.
+ */
+ if (strncmp(colonp + 1, "//", 2) != 0) {
+ /*
+ * The source is the device to open.
+ * Return a NULL pointer for the scheme, user information,
+ * host, and port, and return the device as the path.
+ */
+ *pathp = strdup(source);
+ if (*pathp == NULL) {
+ pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
+ errno, "malloc");
+ return (-1);
+ }
+ return (0);
+ }
+
+ /*
+ * XXX - check whether the purported scheme could be a scheme?
+ */
+
+ /*
+ * OK, this looks like a URL.
+ * Get the scheme.
+ */
+ scheme_len = colonp - source;
+ scheme = malloc(scheme_len + 1);
+ if (scheme == NULL) {
+ pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
+ errno, "malloc");
+ return (-1);
+ }
+ memcpy(scheme, source, scheme_len);
+ scheme[scheme_len] = '\0';
+
+ /*
+ * Treat file: specially - take everything after file:// as
+ * 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");
+ return (-1);
+ }
+ return (0);
+ }
+
+ /*
+ * The WinPcap documentation says you can specify a local
+ * interface with "rpcap://{device}"; we special-case
+ * that here. If the scheme is "rpcap", and there are
+ * no slashes past the "//", we just return the device.
+ *
+ * XXX - %-escaping?
+ */
+ if (pcap_strcasecmp(scheme, "rpcap") == 0 &&
+ strchr(colonp + 3, '/') == NULL) {
+ /*
+ * Local device.
+ *
+ * Return a NULL pointer for the scheme, user information,
+ * host, and port, and return the device as the path.
+ */
+ free(scheme);
+ *pathp = strdup(colonp + 3);
+ if (*pathp == NULL) {
+ pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
+ errno, "malloc");
+ return (-1);
+ }
+ return (0);
+ }
+
+ /*
+ * OK, now start parsing the authority.
+ * Get token, terminated with / or terminated at the end of
+ * the string.
+ */
+ authority_len = strcspn(colonp + 3, "/");
+ authority = get_substring(colonp + 3, authority_len, ebuf);
+ if (authority == NULL) {
+ /*
+ * Error.
+ */
+ free(scheme);
+ return (-1);
+ }
+ endp = colonp + 3 + authority_len;
+
+ /*
+ * Now carve the authority field into its components.
+ */
+ parsep = authority;
+
+ /*
+ * Is there a userinfo field?
+ */
+ atsignp = strchr(parsep, '@');
+ if (atsignp != NULL) {
+ /*
+ * Yes.
+ */
+ size_t userinfo_len;
+
+ userinfo_len = atsignp - parsep;
+ userinfo = get_substring(parsep, userinfo_len, ebuf);
+ if (userinfo == NULL) {
+ /*
+ * Error.
+ */
+ free(authority);
+ free(scheme);
+ return (-1);
+ }
+ parsep = atsignp + 1;
+ } else {
+ /*
+ * No.
+ */
+ userinfo = NULL;
+ }
+
+ /*
+ * Is there a host field?
+ */
+ if (*parsep == '\0') {
+ /*
+ * No; there's no host field or port field.
+ */
+ host = NULL;
+ port = NULL;
+ } else {
+ /*
+ * Yes.
+ */
+ size_t host_len;
+
+ /*
+ * Is it an IP-literal?
+ */
+ if (*parsep == '[') {
+ /*
+ * Yes.
+ * 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.
+ */
+ bracketp = strchr(parsep, ']');
+ if (bracketp == NULL) {
+ /*
+ * There's no closing square bracket.
+ */
+ pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
+ "IP-literal in URL doesn't end with ]");
+ free(userinfo);
+ free(authority);
+ free(scheme);
+ return (-1);
+ }
+ if (*(bracketp + 1) != '\0' &&
+ *(bracketp + 1) != ':') {
+ /*
+ * There's extra crud after the
+ * closing square bracketn.
+ */
+ pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE,
+ "Extra text after IP-literal in URL");
+ free(userinfo);
+ free(authority);
+ free(scheme);
+ return (-1);
+ }
+ host_len = (bracketp - 1) - parsep;
+ host = get_substring(parsep + 1, host_len, ebuf);
+ if (host == NULL) {
+ /*
+ * Error.
+ */
+ free(userinfo);
+ free(authority);
+ free(scheme);
+ return (-1);
+ }
+ parsep = bracketp + 1;
+ } else {
+ /*
+ * No.
+ * Treat everything up to a : or the end of
+ * the string as the host.
+ */
+ host_len = strcspn(parsep, ":");
+ host = get_substring(parsep, host_len, ebuf);
+ if (host == NULL) {
+ /*
+ * Error.
+ */
+ free(userinfo);
+ free(authority);
+ free(scheme);
+ return (-1);
+ }
+ parsep = parsep + host_len;
+ }
+
+ /*
+ * Is there a port field?
+ */
+ if (*parsep == ':') {
+ /*
+ * Yes. It's the rest of the authority field.
+ */
+ size_t port_len;
+
+ parsep++;
+ port_len = strlen(parsep);
+ port = get_substring(parsep, port_len, ebuf);
+ if (port == NULL) {
+ /*
+ * Error.
+ */
+ free(host);
+ free(userinfo);
+ free(authority);
+ free(scheme);
+ return (-1);
+ }
+ } else {
+ /*
+ * No.
+ */
+ port = NULL;
+ }
+ }
+ free(authority);
+
+ /*
+ * Everything else is the path. Strip off the leading /.
+ */
+ if (*endp == '\0')
+ path = strdup("");
+ else
+ path = strdup(endp + 1);
+ if (path == NULL) {
+ pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
+ errno, "malloc");
+ free(port);
+ free(host);
+ free(userinfo);
+ free(scheme);
+ return (-1);
+ }
+ *schemep = scheme;
+ *userinfop = userinfo;
+ *hostp = host;
+ *portp = port;
+ *pathp = path;
+ return (0);
+}
+
+int
+pcap_createsrcstr(char *source, int type, const char *host, const char *port,
+ const char *name, char *errbuf)
+{
+ switch (type) {
+
+ case PCAP_SRC_FILE:
+ strlcpy(source, PCAP_SRC_FILE_STRING, PCAP_BUF_SIZE);
+ if (name != NULL && *name != '\0') {
+ strlcat(source, name, PCAP_BUF_SIZE);
+ return (0);
+ } else {
+ pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "The file name cannot be NULL.");
+ return (-1);
+ }
+
+ case PCAP_SRC_IFREMOTE:
+ strlcpy(source, PCAP_SRC_IF_STRING, PCAP_BUF_SIZE);
+ if (host != NULL && *host != '\0') {
+ if (strchr(host, ':') != NULL) {
+ /*
+ * The host name contains a colon, so it's
+ * 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);
+ } else
+ strlcat(source, host, PCAP_BUF_SIZE);
+
+ if (port != NULL && *port != '\0') {
+ strlcat(source, ":", PCAP_BUF_SIZE);
+ strlcat(source, port, PCAP_BUF_SIZE);
+ }
+
+ strlcat(source, "/", PCAP_BUF_SIZE);
+ } else {
+ pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "The host name cannot be NULL.");
+ return (-1);
+ }
+
+ if (name != NULL && *name != '\0')
+ strlcat(source, name, PCAP_BUF_SIZE);
+
+ return (0);
+
+ case PCAP_SRC_IFLOCAL:
+ strlcpy(source, PCAP_SRC_IF_STRING, PCAP_BUF_SIZE);
+
+ if (name != NULL && *name != '\0')
+ strlcat(source, name, PCAP_BUF_SIZE);
+
+ return (0);
+
+ default:
+ pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "The interface type is not valid.");
+ return (-1);
+ }
+}
+
+int
+pcap_parsesrcstr(const char *source, int *type, char *host, char *port,
+ char *name, char *errbuf)
+{
+ char *scheme, *tmpuserinfo, *tmphost, *tmpport, *tmppath;
+
+ /* Initialization stuff */
+ if (host)
+ *host = '\0';
+ if (port)
+ *port = '\0';
+ if (name)
+ *name = '\0';
+
+ /* Parse the source string */
+ if (pcap_parse_source(source, &scheme, &tmpuserinfo, &tmphost,
+ &tmpport, &tmppath, errbuf) == -1) {
+ /*
+ * Fail.
+ */
+ return (-1);
+ }
+
+ if (scheme == NULL) {
+ /*
+ * Local device.
+ */
+ if (name && tmppath)
+ strlcpy(name, tmppath, PCAP_BUF_SIZE);
+ if (type)
+ *type = PCAP_SRC_IFLOCAL;
+ free(tmppath);
+ free(tmpport);
+ free(tmphost);
+ free(tmpuserinfo);
+ return (0);
+ }
+
+ if (strcmp(scheme, "rpcap") == 0) {
+ /*
+ * rpcap://
+ *
+ * pcap_parse_source() has already handled the case of
+ * rpcap://device
+ */
+ if (host && tmphost) {
+ if (tmpuserinfo)
+ pcap_snprintf(host, PCAP_BUF_SIZE, "%s@%s",
+ tmpuserinfo, tmphost);
+ else
+ strlcpy(host, tmphost, PCAP_BUF_SIZE);
+ }
+ if (port && tmpport)
+ strlcpy(port, tmpport, PCAP_BUF_SIZE);
+ if (name && tmppath)
+ strlcpy(name, tmppath, PCAP_BUF_SIZE);
+ if (type)
+ *type = PCAP_SRC_IFREMOTE;
+ free(tmppath);
+ free(tmpport);
+ free(tmphost);
+ free(tmpuserinfo);
+ free(scheme);
+ return (0);
+ }
+
+ if (strcmp(scheme, "file") == 0) {
+ /*
+ * file://
+ */
+ if (name && tmppath)
+ strlcpy(name, tmppath, PCAP_BUF_SIZE);
+ if (type)
+ *type = PCAP_SRC_FILE;
+ free(tmppath);
+ free(tmpport);
+ free(tmphost);
+ free(tmpuserinfo);
+ free(scheme);
+ return (0);
+ }
+
+ /*
+ * Neither rpcap: nor file:; just treat the entire string
+ * as a local device.
+ */
+ if (name)
+ strlcpy(name, source, PCAP_BUF_SIZE);
+ if (type)
+ *type = PCAP_SRC_IFLOCAL;
+ free(tmppath);
+ free(tmpport);
+ free(tmphost);
+ free(tmpuserinfo);
+ free(scheme);
+ return (0);
+}
+#endif
+
pcap_t *
pcap_create(const char *device, char *errbuf)
{
@@ -408,8 +1993,9 @@ pcap_create(const char *device, char *errbuf)
length = wcslen((wchar_t *)device);
device_str = (char *)malloc(length + 1);
if (device_str == NULL) {
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "malloc: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(errbuf,
+ PCAP_ERRBUF_SIZE, errno,
+ "malloc");
return (NULL);
}
@@ -420,8 +2006,8 @@ pcap_create(const char *device, char *errbuf)
device_str = strdup(device);
}
if (device_str == NULL) {
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "malloc: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ errno, "malloc");
return (NULL);
}
@@ -471,6 +2057,18 @@ pcap_create(const char *device, char *errbuf)
return (p);
}
+/*
+ * Set nonblocking mode on an unactivated pcap_t; this sets a flag
+ * checked by pcap_activate(), which sets the mode after calling
+ * the activate routine.
+ */
+static int
+pcap_setnonblock_unactivated(pcap_t *p, int nonblock)
+{
+ p->opt.nonblock = nonblock;
+ return (0);
+}
+
static void
initialize_ops(pcap_t *p)
{
@@ -485,7 +2083,6 @@ initialize_ops(pcap_t *p)
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->setnonblock_op = (setnonblock_op_t)pcap_not_initialized;
p->stats_op = (stats_op_t)pcap_not_initialized;
#ifdef _WIN32
p->stats_ex_op = (stats_ex_op_t)pcap_not_initialized_ptr;
@@ -530,8 +2127,8 @@ pcap_alloc_pcap_t(char *ebuf, size_t size)
*/
chunk = malloc(sizeof (pcap_t) + size);
if (chunk == NULL) {
- pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
+ errno, "malloc");
return (NULL);
}
memset(chunk, 0, sizeof (pcap_t) + size);
@@ -541,10 +2138,15 @@ pcap_alloc_pcap_t(char *ebuf, size_t size)
*/
p = (pcap_t *)chunk;
-#ifndef _WIN32
+#ifdef _WIN32
+ p->handle = INVALID_HANDLE_VALUE; /* not opened yet */
+#else /* _WIN32 */
p->fd = -1; /* not opened yet */
+#ifndef MSDOS
p->selectable_fd = -1;
-#endif
+ p->required_select_timeout = NULL;
+#endif /* MSDOS */
+#endif /* _WIN32 */
if (size == 0) {
/* No private data was requested. */
@@ -577,10 +2179,17 @@ pcap_create_common(char *ebuf, size_t size)
*/
p->can_set_rfmon_op = pcap_cant_set_rfmon;
+ /*
+ * If pcap_setnonblock() is called on a not-yet-activated
+ * pcap_t, default to setting a flag and turning
+ * on non-blocking mode when activated.
+ */
+ p->setnonblock_op = pcap_setnonblock_unactivated;
+
initialize_ops(p);
/* put in some defaults*/
- p->snapshot = MAXIMUM_SNAPLEN; /* max packet size */
+ p->snapshot = 0; /* max packet size unspecified */
p->opt.timeout = 0; /* no timeout specified */
p->opt.buffer_size = 0; /* use the platform's default */
p->opt.promisc = 0;
@@ -588,6 +2197,15 @@ pcap_create_common(char *ebuf, size_t size)
p->opt.immediate = 0;
p->opt.tstamp_type = -1; /* default to not setting time stamp type */
p->opt.tstamp_precision = PCAP_TSTAMP_PRECISION_MICRO;
+ /*
+ * Platform-dependent options.
+ */
+#ifdef __linux__
+ p->opt.protocol = 0;
+#endif
+#ifdef _WIN32
+ p->opt.nocapture_local = 0;
+#endif
/*
* Start out with no BPF code generation flags set.
@@ -613,16 +2231,6 @@ pcap_set_snaplen(pcap_t *p, int snaplen)
{
if (pcap_check_activated(p))
return (PCAP_ERROR_ACTIVATED);
-
- /*
- * Turn invalid values, or excessively large values, into
- * the maximum allowed value.
- *
- * If some application really *needs* a bigger snapshot
- * length, we should just increase MAXIMUM_SNAPLEN.
- */
- if (snaplen <= 0 || snaplen > MAXIMUM_SNAPLEN)
- snaplen = MAXIMUM_SNAPLEN;
p->snapshot = snaplen;
return (0);
}
@@ -793,9 +2401,25 @@ pcap_activate(pcap_t *p)
if (pcap_check_activated(p))
return (PCAP_ERROR_ACTIVATED);
status = p->activate_op(p);
- if (status >= 0)
+ if (status >= 0) {
+ /*
+ * If somebody requested non-blocking mode before
+ * calling pcap_activate(), turn it on now.
+ */
+ if (p->opt.nonblock) {
+ status = p->setnonblock_op(p, 1);
+ if (status < 0) {
+ /*
+ * Failed. Undo everything done by
+ * the activate operation.
+ */
+ p->cleanup_op(p);
+ initialize_ops(p);
+ return (status);
+ }
+ }
p->activated = 1;
- else {
+ } else {
if (p->errbuf[0] == '\0') {
/*
* No error message supplied by the activate routine;
@@ -821,6 +2445,53 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, char *er
{
pcap_t *p;
int status;
+#ifdef ENABLE_REMOTE
+ char host[PCAP_BUF_SIZE + 1];
+ char port[PCAP_BUF_SIZE + 1];
+ char name[PCAP_BUF_SIZE + 1];
+ int srctype;
+
+ /*
+ * Retrofit - we have to make older applications compatible with
+ * remote capture.
+ * So we're calling pcap_open_remote() from here; this is a very
+ * dirty hack.
+ * Obviously, we cannot exploit all the new features; for instance,
+ * we cannot send authentication, we cannot use a UDP data connection,
+ * and so on.
+ */
+ if (pcap_parsesrcstr(device, &srctype, host, port, name, errbuf))
+ return (NULL);
+
+ if (srctype == PCAP_SRC_IFREMOTE) {
+ /*
+ * Although we already have host, port and iface, we prefer
+ * to pass only 'device' to pcap_open_rpcap(), so that it has
+ * to call pcap_parsesrcstr() again.
+ * This is less optimized, but much clearer.
+ */
+ return (pcap_open_rpcap(device, snaplen,
+ promisc ? PCAP_OPENFLAG_PROMISCUOUS : 0, to_ms,
+ NULL, errbuf));
+ }
+ if (srctype == PCAP_SRC_FILE) {
+ pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "unknown URL scheme \"file\"");
+ return (NULL);
+ }
+ if (srctype == PCAP_SRC_IFLOCAL) {
+ /*
+ * If it starts with rpcap://, that refers to a local device
+ * (no host part in the URL). Remove the rpcap://, and
+ * fall through to the regular open path.
+ */
+ if (strncmp(device, PCAP_SRC_IF_STRING, strlen(PCAP_SRC_IF_STRING)) == 0) {
+ size_t len = strlen(device) - strlen(PCAP_SRC_IF_STRING) + 1;
+
+ if (len > 0)
+ device += strlen(PCAP_SRC_IF_STRING);
+ }
+ }
+#endif /* ENABLE_REMOTE */
p = pcap_create(device, errbuf);
if (p == NULL)
@@ -954,8 +2625,8 @@ pcap_list_datalinks(pcap_t *p, int **dlt_buffer)
*/
*dlt_buffer = (int*)malloc(sizeof(**dlt_buffer));
if (*dlt_buffer == NULL) {
- (void)pcap_snprintf(p->errbuf, sizeof(p->errbuf),
- "malloc: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, sizeof(p->errbuf),
+ errno, "malloc");
return (PCAP_ERROR);
}
**dlt_buffer = p->linktype;
@@ -963,8 +2634,8 @@ pcap_list_datalinks(pcap_t *p, int **dlt_buffer)
} else {
*dlt_buffer = (int*)calloc(sizeof(**dlt_buffer), p->dlt_count);
if (*dlt_buffer == NULL) {
- (void)pcap_snprintf(p->errbuf, sizeof(p->errbuf),
- "malloc: %s", pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, sizeof(p->errbuf),
+ errno, "malloc");
return (PCAP_ERROR);
}
(void)memcpy(*dlt_buffer, p->dlt_list,
@@ -1279,6 +2950,15 @@ static struct dlt_choice dlt_choices[] = {
DLT_CHOICE(WATTSTOPPER_DLM, "WattStopper Digital Lighting Management (DLM) and Legrand Nitoo Open protocol"),
DLT_CHOICE(ISO_14443, "ISO 14443 messages"),
DLT_CHOICE(RDS, "IEC 62106 Radio Data System groups"),
+ DLT_CHOICE(USB_DARWIN, "USB with Darwin header"),
+ DLT_CHOICE(OPENFLOW, "OpenBSD DLT_OPENFLOW"),
+ DLT_CHOICE(SDLC, "IBM SDLC frames"),
+ DLT_CHOICE(TI_LLN_SNIFFER, "TI LLN sniffer frames"),
+ DLT_CHOICE(VSOCK, "Linux vsock"),
+ DLT_CHOICE(NORDIC_BLE, "Nordic Semiconductor Bluetooth LE sniffer frames"),
+ 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_SENTINEL
};
@@ -1401,6 +3081,14 @@ pcap_minor_version(pcap_t *p)
return (p->version_minor);
}
+int
+pcap_bufsize(pcap_t *p)
+{
+ if (!p->activated)
+ return (PCAP_ERROR_NOT_ACTIVATED);
+ return (p->bufsize);
+}
+
FILE *
pcap_file(pcap_t *p)
{
@@ -1413,8 +3101,8 @@ pcap_fileno(pcap_t *p)
#ifndef _WIN32
return (p->fd);
#else
- if (p->adapter != NULL)
- return ((int)(DWORD)p->adapter->hFile);
+ if (p->handle != INVALID_HANDLE_VALUE)
+ return ((int)(DWORD)p->handle);
else
return (PCAP_ERROR);
#endif
@@ -1426,6 +3114,12 @@ pcap_get_selectable_fd(pcap_t *p)
{
return (p->selectable_fd);
}
+
+struct timeval *
+pcap_get_required_select_timeout(pcap_t *p)
+{
+ return (p->required_select_timeout);
+}
#endif
void
@@ -1445,14 +3139,18 @@ pcap_getnonblock(pcap_t *p, char *errbuf)
{
int ret;
- ret = p->getnonblock_op(p, errbuf);
+ ret = p->getnonblock_op(p);
if (ret == -1) {
/*
- * In case somebody depended on the bug wherein
- * the error message was put into p->errbuf
- * by pcap_getnonblock_fd().
+ * The get nonblock operation sets p->errbuf; this
+ * function *shouldn't* have had a separate errbuf
+ * argument, as it didn't need one, but I goofed
+ * when adding it.
+ *
+ * We copy the error message to errbuf, so callers
+ * can find it in either place.
*/
- strlcpy(p->errbuf, errbuf, PCAP_ERRBUF_SIZE);
+ strlcpy(errbuf, p->errbuf, PCAP_ERRBUF_SIZE);
}
return (ret);
}
@@ -1463,14 +3161,14 @@ pcap_getnonblock(pcap_t *p, char *errbuf)
*/
#if !defined(_WIN32) && !defined(MSDOS)
int
-pcap_getnonblock_fd(pcap_t *p, char *errbuf)
+pcap_getnonblock_fd(pcap_t *p)
{
int fdflags;
fdflags = fcntl(p->fd, F_GETFL, 0);
if (fdflags == -1) {
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "F_GETFL: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "F_GETFL");
return (-1);
}
if (fdflags & O_NONBLOCK)
@@ -1485,14 +3183,18 @@ pcap_setnonblock(pcap_t *p, int nonblock, char *errbuf)
{
int ret;
- ret = p->setnonblock_op(p, nonblock, errbuf);
+ ret = p->setnonblock_op(p, nonblock);
if (ret == -1) {
/*
- * In case somebody depended on the bug wherein
- * the error message was put into p->errbuf
- * by pcap_setnonblock_fd().
+ * The set nonblock operation sets p->errbuf; this
+ * function *shouldn't* have had a separate errbuf
+ * argument, as it didn't need one, but I goofed
+ * when adding it.
+ *
+ * We copy the error message to errbuf, so callers
+ * can find it in either place.
*/
- strlcpy(p->errbuf, errbuf, PCAP_ERRBUF_SIZE);
+ strlcpy(errbuf, p->errbuf, PCAP_ERRBUF_SIZE);
}
return (ret);
}
@@ -1505,14 +3207,14 @@ pcap_setnonblock(pcap_t *p, int nonblock, char *errbuf)
* needs to do some additional work.)
*/
int
-pcap_setnonblock_fd(pcap_t *p, int nonblock, char *errbuf)
+pcap_setnonblock_fd(pcap_t *p, int nonblock)
{
int fdflags;
fdflags = fcntl(p->fd, F_GETFL, 0);
if (fdflags == -1) {
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "F_GETFL: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "F_GETFL");
return (-1);
}
if (nonblock)
@@ -1520,8 +3222,8 @@ pcap_setnonblock_fd(pcap_t *p, int nonblock, char *errbuf)
else
fdflags &= ~O_NONBLOCK;
if (fcntl(p->fd, F_SETFL, fdflags) == -1) {
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "F_SETFL: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "F_SETFL");
return (-1);
}
return (0);
@@ -1625,9 +3327,9 @@ pcap_strerror(int errnum)
#ifdef HAVE_STRERROR
#ifdef _WIN32
static char errbuf[PCAP_ERRBUF_SIZE];
- errno_t errno;
- errno = strerror_s(errbuf, PCAP_ERRBUF_SIZE, errnum);
- if (errno != 0) /* errno = 0 if successful */
+ 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);
return (errbuf);
#else
@@ -1674,14 +3376,6 @@ pcap_stats(pcap_t *p, struct pcap_stat *ps)
return (p->stats_op(p, ps));
}
-static int
-pcap_stats_dead(pcap_t *p, struct pcap_stat *ps _U_)
-{
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "Statistics aren't available from a pcap_open_dead pcap_t");
- return (-1);
-}
-
#ifdef _WIN32
struct pcap_stat *
pcap_stats_ex(pcap_t *p, int *pcap_stat_size)
@@ -1695,86 +3389,36 @@ pcap_setbuff(pcap_t *p, int dim)
return (p->setbuff_op(p, dim));
}
-static int
-pcap_setbuff_dead(pcap_t *p, int dim)
-{
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "The kernel buffer size cannot be set on a pcap_open_dead pcap_t");
- return (-1);
-}
-
int
pcap_setmode(pcap_t *p, int mode)
{
return (p->setmode_op(p, mode));
}
-static int
-pcap_setmode_dead(pcap_t *p, int mode)
-{
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "impossible to set mode on a pcap_open_dead pcap_t");
- return (-1);
-}
-
int
pcap_setmintocopy(pcap_t *p, int size)
{
return (p->setmintocopy_op(p, size));
}
-static int
-pcap_setmintocopy_dead(pcap_t *p, int size)
-{
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "The mintocopy parameter cannot be set on a pcap_open_dead pcap_t");
- return (-1);
-}
-
HANDLE
pcap_getevent(pcap_t *p)
{
return (p->getevent_op(p));
}
-static HANDLE
-pcap_getevent_dead(pcap_t *p)
-{
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "A pcap_open_dead pcap_t has no event handle");
- return (INVALID_HANDLE_VALUE);
-}
-
int
pcap_oid_get_request(pcap_t *p, bpf_u_int32 oid, void *data, size_t *lenp)
{
return (p->oid_get_request_op(p, oid, data, lenp));
}
-static int
-pcap_oid_get_request_dead(pcap_t *p, bpf_u_int32 oid _U_, void *data _U_,
- size_t *lenp _U_)
-{
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "An OID get request cannot be performed on a pcap_open_dead pcap_t");
- return (PCAP_ERROR);
-}
-
int
pcap_oid_set_request(pcap_t *p, bpf_u_int32 oid, const void *data, size_t *lenp)
{
return (p->oid_set_request_op(p, oid, data, lenp));
}
-static int
-pcap_oid_set_request_dead(pcap_t *p, bpf_u_int32 oid _U_, const void *data _U_,
- size_t *lenp _U_)
-{
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "An OID set request cannot be performed on a pcap_open_dead pcap_t");
- return (PCAP_ERROR);
-}
-
pcap_send_queue *
pcap_sendqueue_alloc(u_int memsize)
{
@@ -1830,56 +3474,24 @@ pcap_sendqueue_transmit(pcap_t *p, pcap_send_queue *queue, int sync)
return (p->sendqueue_transmit_op(p, queue, sync));
}
-static u_int
-pcap_sendqueue_transmit_dead(pcap_t *p, pcap_send_queue *queue, int sync)
-{
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "Packets cannot be transmitted on a pcap_open_dead pcap_t");
- return (0);
-}
-
int
pcap_setuserbuffer(pcap_t *p, int size)
{
return (p->setuserbuffer_op(p, size));
}
-static int
-pcap_setuserbuffer_dead(pcap_t *p, int size)
-{
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "The user buffer cannot be set on a pcap_open_dead pcap_t");
- return (-1);
-}
-
int
pcap_live_dump(pcap_t *p, char *filename, int maxsize, int maxpacks)
{
return (p->live_dump_op(p, filename, maxsize, maxpacks));
}
-static int
-pcap_live_dump_dead(pcap_t *p, char *filename, int maxsize, int maxpacks)
-{
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "Live packet dumping cannot be performed on a pcap_open_dead pcap_t");
- return (-1);
-}
-
int
pcap_live_dump_ended(pcap_t *p, int sync)
{
return (p->live_dump_ended_op(p, sync));
}
-static int
-pcap_live_dump_ended_dead(pcap_t *p, int sync)
-{
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "Live packet dumping cannot be performed on a pcap_open_dead pcap_t");
- return (-1);
-}
-
PAirpcapHandle
pcap_get_airpcap_handle(pcap_t *p)
{
@@ -1892,12 +3504,6 @@ pcap_get_airpcap_handle(pcap_t *p)
}
return (handle);
}
-
-static PAirpcapHandle
-pcap_get_airpcap_handle_dead(pcap_t *p)
-{
- return (NULL);
-}
#endif
/*
@@ -2020,66 +3626,6 @@ pcap_cleanup_live_common(pcap_t *p)
#endif
}
-static void
-pcap_cleanup_dead(pcap_t *p _U_)
-{
- /* Nothing to do. */
-}
-
-pcap_t *
-pcap_open_dead_with_tstamp_precision(int linktype, int snaplen, u_int precision)
-{
- pcap_t *p;
-
- switch (precision) {
-
- case PCAP_TSTAMP_PRECISION_MICRO:
- case PCAP_TSTAMP_PRECISION_NANO:
- break;
-
- default:
- return NULL;
- }
- p = malloc(sizeof(*p));
- if (p == NULL)
- return NULL;
- memset (p, 0, sizeof(*p));
- p->snapshot = snaplen;
- p->linktype = linktype;
- p->opt.tstamp_precision = precision;
- p->stats_op = pcap_stats_dead;
-#ifdef _WIN32
- p->stats_ex_op = (stats_ex_op_t)pcap_not_initialized_ptr;
- p->setbuff_op = pcap_setbuff_dead;
- p->setmode_op = pcap_setmode_dead;
- p->setmintocopy_op = pcap_setmintocopy_dead;
- p->getevent_op = pcap_getevent_dead;
- p->oid_get_request_op = pcap_oid_get_request_dead;
- p->oid_set_request_op = pcap_oid_set_request_dead;
- p->sendqueue_transmit_op = pcap_sendqueue_transmit_dead;
- p->setuserbuffer_op = pcap_setuserbuffer_dead;
- p->live_dump_op = pcap_live_dump_dead;
- p->live_dump_ended_op = pcap_live_dump_ended_dead;
- p->get_airpcap_handle_op = pcap_get_airpcap_handle_dead;
-#endif
- p->cleanup_op = pcap_cleanup_dead;
-
- /*
- * A "dead" pcap_t never requires special BPF code generation.
- */
- p->bpf_codegen_flags = 0;
-
- p->activated = 1;
- return (p);
-}
-
-pcap_t *
-pcap_open_dead(int linktype, int snaplen)
-{
- return (pcap_open_dead_with_tstamp_precision(linktype, snaplen,
- PCAP_TSTAMP_PRECISION_MICRO));
-}
-
/*
* API compatible with WinPcap's "send a packet" routine - returns -1
* on error, 0 otherwise.
@@ -2131,160 +3677,251 @@ pcap_offline_filter(const struct bpf_program *fp, const struct pcap_pkthdr *h,
return (0);
}
-#include "pcap_version.h"
+static int
+pcap_can_set_rfmon_dead(pcap_t *p)
+{
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "Rfmon mode doesn't apply on a pcap_open_dead pcap_t");
+ return (PCAP_ERROR);
+}
+
+static int
+pcap_read_dead(pcap_t *p, int cnt _U_, pcap_handler callback _U_,
+ u_char *user _U_)
+{
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "Packets aren't available from a pcap_open_dead pcap_t");
+ return (-1);
+}
+
+static int
+pcap_inject_dead(pcap_t *p, const void *buf _U_, size_t size _U_)
+{
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "Packets can't be sent on a pcap_open_dead pcap_t");
+ return (-1);
+}
+
+static int
+pcap_setfilter_dead(pcap_t *p, struct bpf_program *fp _U_)
+{
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "A filter cannot be set on a pcap_open_dead pcap_t");
+ return (-1);
+}
+
+static int
+pcap_setdirection_dead(pcap_t *p, pcap_direction_t d _U_)
+{
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "The packet direction cannot be set on a pcap_open_dead pcap_t");
+ return (-1);
+}
+
+static int
+pcap_set_datalink_dead(pcap_t *p, int dlt _U_)
+{
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "The link-layer header type cannot be set on a pcap_open_dead pcap_t");
+ return (-1);
+}
+
+static int
+pcap_getnonblock_dead(pcap_t *p)
+{
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "A pcap_open_dead pcap_t does not have a non-blocking mode setting");
+ return (-1);
+}
+
+static int
+pcap_setnonblock_dead(pcap_t *p, int nonblock _U_)
+{
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "A pcap_open_dead pcap_t does not have a non-blocking mode setting");
+ return (-1);
+}
+
+static int
+pcap_stats_dead(pcap_t *p, struct pcap_stat *ps _U_)
+{
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "Statistics aren't available from a pcap_open_dead pcap_t");
+ return (-1);
+}
#ifdef _WIN32
+struct pcap_stat *
+pcap_stats_ex_dead(pcap_t *p, int *pcap_stat_size _U_)
+{
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "Statistics aren't available from a pcap_open_dead pcap_t");
+ return (NULL);
+}
-static char *full_pcap_version_string;
+static int
+pcap_setbuff_dead(pcap_t *p, int dim)
+{
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "The kernel buffer size cannot be set on a pcap_open_dead pcap_t");
+ return (-1);
+}
-#ifdef HAVE_VERSION_H
-/*
- * libpcap being built for Windows, as part of a WinPcap/Npcap source
- * 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.)
- */
-#include "../../version.h"
+static int
+pcap_setmode_dead(pcap_t *p, int mode)
+{
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "impossible to set mode on a pcap_open_dead pcap_t");
+ return (-1);
+}
-static const char wpcap_version_string[] = WINPCAP_VER_STRING;
-static const char pcap_version_string_fmt[] =
- WINPCAP_PRODUCT_NAME " version %s, based on %s";
-static const char pcap_version_string_packet_dll_fmt[] =
- WINPCAP_PRODUCT_NAME " version %s (packet.dll version %s), based on %s";
+static int
+pcap_setmintocopy_dead(pcap_t *p, int size)
+{
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "The mintocopy parameter cannot be set on a pcap_open_dead pcap_t");
+ return (-1);
+}
-const char *
-pcap_lib_version(void)
+static HANDLE
+pcap_getevent_dead(pcap_t *p)
{
- char *packet_version_string;
- size_t full_pcap_version_string_len;
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "A pcap_open_dead pcap_t has no event handle");
+ return (INVALID_HANDLE_VALUE);
+}
- if (full_pcap_version_string == NULL) {
- /*
- * Generate the version string.
- */
- packet_version_string = PacketGetVersion();
- if (strcmp(wpcap_version_string, packet_version_string) == 0) {
- /*
- * WinPcap version string and packet.dll version
- * string are the same; just report the WinPcap
- * version.
- */
- full_pcap_version_string_len =
- (sizeof pcap_version_string_fmt - 4) +
- strlen(wpcap_version_string) +
- strlen(pcap_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_fmt,
- wpcap_version_string,
- pcap_version_string);
- } else {
- /*
- * WinPcap 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
- * versions.
- */
- full_pcap_version_string_len =
- (sizeof pcap_version_string_packet_dll_fmt - 6) +
- strlen(wpcap_version_string) +
- strlen(packet_version_string) +
- strlen(pcap_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,
- wpcap_version_string,
- packet_version_string,
- pcap_version_string);
- }
- }
- return (full_pcap_version_string);
+static int
+pcap_oid_get_request_dead(pcap_t *p, bpf_u_int32 oid _U_, void *data _U_,
+ size_t *lenp _U_)
+{
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "An OID get request cannot be performed on a pcap_open_dead pcap_t");
+ return (PCAP_ERROR);
}
-#else /* HAVE_VERSION_H */
+static int
+pcap_oid_set_request_dead(pcap_t *p, bpf_u_int32 oid _U_, const void *data _U_,
+ size_t *lenp _U_)
+{
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "An OID set request cannot be performed on a pcap_open_dead pcap_t");
+ return (PCAP_ERROR);
+}
-/*
- * libpcap being built for Windows, not as part of a WinPcap/Npcap source
- * tree.
- */
-static const char pcap_version_string_packet_dll_fmt[] =
- "%s (packet.dll version %s)";
-const char *
-pcap_lib_version(void)
+static u_int
+pcap_sendqueue_transmit_dead(pcap_t *p, pcap_send_queue *queue, int sync)
{
- char *packet_version_string;
- size_t full_pcap_version_string_len;
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "Packets cannot be transmitted on a pcap_open_dead pcap_t");
+ return (0);
+}
- if (full_pcap_version_string == NULL) {
- /*
- * Generate the version string. Report the packet.dll
- * version.
- */
- packet_version_string = PacketGetVersion();
- full_pcap_version_string_len =
- (sizeof pcap_version_string_packet_dll_fmt - 4) +
- strlen(pcap_version_string) +
- 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,
- pcap_version_string,
- packet_version_string);
- }
- return (full_pcap_version_string);
+static int
+pcap_setuserbuffer_dead(pcap_t *p, int size)
+{
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "The user buffer cannot be set on a pcap_open_dead pcap_t");
+ return (-1);
}
-#endif /* HAVE_VERSION_H */
+static int
+pcap_live_dump_dead(pcap_t *p, char *filename, int maxsize, int maxpacks)
+{
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "Live packet dumping cannot be performed on a pcap_open_dead pcap_t");
+ return (-1);
+}
-#elif defined(MSDOS)
+static int
+pcap_live_dump_ended_dead(pcap_t *p, int sync)
+{
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "Live packet dumping cannot be performed on a pcap_open_dead pcap_t");
+ return (-1);
+}
+
+static PAirpcapHandle
+pcap_get_airpcap_handle_dead(pcap_t *p)
+{
+ return (NULL);
+}
+#endif /* _WIN32 */
-static char *full_pcap_version_string;
+static void
+pcap_cleanup_dead(pcap_t *p _U_)
+{
+ /* Nothing to do. */
+}
-const char *
-pcap_lib_version (void)
+pcap_t *
+pcap_open_dead_with_tstamp_precision(int linktype, int snaplen, u_int precision)
{
- char *packet_version_string;
- size_t full_pcap_version_string_len;
- static char dospfx[] = "DOS-";
+ pcap_t *p;
+
+ switch (precision) {
+
+ case PCAP_TSTAMP_PRECISION_MICRO:
+ case PCAP_TSTAMP_PRECISION_NANO:
+ break;
- if (full_pcap_version_string == NULL) {
+ default:
/*
- * Generate the version string.
+ * This doesn't really matter, but we don't have any way
+ * to report particular errors, so the only failure we
+ * should have is a memory allocation failure. Just
+ * pick microsecond precision.
*/
- full_pcap_version_string_len =
- sizeof dospfx + strlen(pcap_version_string);
- full_pcap_version_string =
- malloc(full_pcap_version_string_len);
- if (full_pcap_version_string == NULL)
- return (NULL);
- strcpy(full_pcap_version_string, dospfx);
- strcat(full_pcap_version_string, pcap_version_string);
+ precision = PCAP_TSTAMP_PRECISION_MICRO;
+ break;
}
- return (full_pcap_version_string);
-}
+ p = malloc(sizeof(*p));
+ if (p == NULL)
+ return NULL;
+ memset (p, 0, sizeof(*p));
+ p->snapshot = snaplen;
+ p->linktype = linktype;
+ p->opt.tstamp_precision = precision;
+ p->can_set_rfmon_op = pcap_can_set_rfmon_dead;
+ p->read_op = pcap_read_dead;
+ p->inject_op = pcap_inject_dead;
+ p->setfilter_op = pcap_setfilter_dead;
+ p->setdirection_op = pcap_setdirection_dead;
+ p->set_datalink_op = pcap_set_datalink_dead;
+ p->getnonblock_op = pcap_getnonblock_dead;
+ p->setnonblock_op = pcap_setnonblock_dead;
+ p->stats_op = pcap_stats_dead;
+#ifdef _WIN32
+ p->stats_ex_op = pcap_stats_ex_dead;
+ p->setbuff_op = pcap_setbuff_dead;
+ p->setmode_op = pcap_setmode_dead;
+ p->setmintocopy_op = pcap_setmintocopy_dead;
+ p->getevent_op = pcap_getevent_dead;
+ p->oid_get_request_op = pcap_oid_get_request_dead;
+ p->oid_set_request_op = pcap_oid_set_request_dead;
+ p->sendqueue_transmit_op = pcap_sendqueue_transmit_dead;
+ p->setuserbuffer_op = pcap_setuserbuffer_dead;
+ p->live_dump_op = pcap_live_dump_dead;
+ p->live_dump_ended_op = pcap_live_dump_ended_dead;
+ p->get_airpcap_handle_op = pcap_get_airpcap_handle_dead;
+#endif
+ p->cleanup_op = pcap_cleanup_dead;
-#else /* UN*X */
+ /*
+ * A "dead" pcap_t never requires special BPF code generation.
+ */
+ p->bpf_codegen_flags = 0;
-const char *
-pcap_lib_version(void)
+ p->activated = 1;
+ return (p);
+}
+
+pcap_t *
+pcap_open_dead(int linktype, int snaplen)
{
- return (pcap_version_string);
+ return (pcap_open_dead_with_tstamp_precision(linktype, snaplen,
+ PCAP_TSTAMP_PRECISION_MICRO));
}
-#endif
#ifdef YYDEBUG
/*
@@ -2304,32 +3941,6 @@ PCAP_API void pcap_set_parser_debug(int value);
PCAP_API_DEF void
pcap_set_parser_debug(int value)
{
- extern int pcap_debug;
-
pcap_debug = value;
}
#endif
-
-#ifdef BDEBUG
-/*
- * Set the internal "debug printout" flag for the filter expression optimizer.
- * The code to print that stuff is present only if BDEBUG is defined, so
- * the flag, and the routine to set it, are defined only if BDEBUG is
- * defined.
- *
- * This is intended for libpcap developers, not for general use.
- * If you want to set these in a program, you'll have to declare this
- * routine yourself, with the appropriate DLL import attribute on Windows;
- * it's not declared in any header file, and won't be declared in any
- * header file provided by libpcap.
- */
-PCAP_API void pcap_set_optimizer_debug(int value);
-
-PCAP_API_DEF void
-pcap_set_optimizer_debug(int value)
-{
- extern int pcap_optimizer_debug;
-
- pcap_optimizer_debug = value;
-}
-#endif
diff --git a/contrib/libpcap/pcap/bluetooth.h b/contrib/libpcap/pcap/bluetooth.h
index c5f378abbe789..15dc5a827da2a 100644
--- a/contrib/libpcap/pcap/bluetooth.h
+++ b/contrib/libpcap/pcap/bluetooth.h
@@ -34,12 +34,14 @@
#ifndef lib_pcap_bluetooth_h
#define lib_pcap_bluetooth_h
+#include <pcap/pcap-inttypes.h>
+
/*
* Header prepended libpcap to each bluetooth h4 frame,
* fields are in network byte order
*/
typedef struct _pcap_bluetooth_h4_header {
- u_int32_t direction; /* if first bit is set direction is incoming */
+ uint32_t direction; /* if first bit is set direction is incoming */
} pcap_bluetooth_h4_header;
/*
@@ -47,9 +49,8 @@ typedef struct _pcap_bluetooth_h4_header {
* fields are in network byte order
*/
typedef struct _pcap_bluetooth_linux_monitor_header {
- u_int16_t adapter_id;
- u_int16_t opcode;
+ uint16_t adapter_id;
+ uint16_t opcode;
} pcap_bluetooth_linux_monitor_header;
-
#endif
diff --git a/contrib/libpcap/pcap/bpf.h b/contrib/libpcap/pcap/bpf.h
index 1a63d603008c2..1a953a9b71d89 100644
--- a/contrib/libpcap/pcap/bpf.h
+++ b/contrib/libpcap/pcap/bpf.h
@@ -68,7 +68,7 @@
#if !defined(_NET_BPF_H_) && !defined(_NET_BPF_H_INCLUDED) && !defined(_BPF_H_) && !defined(_H_BPF) && !defined(lib_pcap_bpf_h)
#define lib_pcap_bpf_h
-#include <pcap/export-defs.h>
+#include <pcap/funcattrs.h>
#ifdef __cplusplus
extern "C" {
@@ -254,15 +254,9 @@ struct bpf_aux_data {
#define BPF_STMT(code, k) { (u_short)(code), 0, 0, k }
#define BPF_JUMP(code, k, jt, jf) { (u_short)(code), jt, jf, k }
-#if __STDC__ || defined(__cplusplus)
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 *);
-#else
-PCAP_API int bpf_validate();
-PCAP_API u_int bpf_filter();
-extern u_int bpf_filter_with_aux_data();
-#endif
/*
* Number of scratch memory words (for BPF_LD|BPF_MEM and BPF_ST).
diff --git a/contrib/libpcap/pcap/can_socketcan.h b/contrib/libpcap/pcap/can_socketcan.h
index 68d2a131c8ae2..332d9ff5d5a91 100644
--- a/contrib/libpcap/pcap/can_socketcan.h
+++ b/contrib/libpcap/pcap/can_socketcan.h
@@ -39,16 +39,18 @@
#ifndef lib_pcap_can_socketcan_h
#define lib_pcap_can_socketcan_h
+#include <pcap/pcap-inttypes.h>
+
/*
* SocketCAN header, as per Documentation/networking/can.txt in the
* Linux source.
*/
typedef struct {
- u_int32_t can_id;
- u_int8_t payload_length;
- u_int8_t pad;
- u_int8_t reserved1;
- u_int8_t reserved2;
+ uint32_t can_id;
+ uint8_t payload_length;
+ uint8_t pad;
+ uint8_t reserved1;
+ uint8_t reserved2;
} pcap_can_socketcan_hdr;
#endif
diff --git a/contrib/libpcap/pcap/compiler-tests.h b/contrib/libpcap/pcap/compiler-tests.h
new file mode 100644
index 0000000000000..5e17853a7734a
--- /dev/null
+++ b/contrib/libpcap/pcap/compiler-tests.h
@@ -0,0 +1,163 @@
+/* -*- 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_compiler_tests_h
+#define lib_pcap_compiler_tests_h
+
+/*
+ * This was introduced by Clang:
+ *
+ * http://clang.llvm.org/docs/LanguageExtensions.html#has-attribute
+ *
+ * in some version (which version?); it has been picked up by GCC 5.0.
+ */
+#ifndef __has_attribute
+ /*
+ * It's a macro, so you can check whether it's defined to check
+ * whether it's supported.
+ *
+ * If it's not, define it to always return 0, so that we move on to
+ * the fallback checks.
+ */
+ #define __has_attribute(x) 0
+#endif
+
+/*
+ * Note that the C90 spec's "6.8.1 Conditional inclusion" and the
+ * C99 spec's and C11 spec's "6.10.1 Conditional inclusion" say:
+ *
+ * Prior to evaluation, macro invocations in the list of preprocessing
+ * tokens that will become the controlling constant expression are
+ * replaced (except for those macro names modified by the defined unary
+ * operator), just as in normal text. If the token "defined" is
+ * generated as a result of this replacement process or use of the
+ * "defined" unary operator does not match one of the two specified
+ * forms prior to macro replacement, the behavior is undefined.
+ *
+ * so you shouldn't use defined() in a #define that's used in #if or
+ * #elif. Some versions of Clang, for example, will warn about this.
+ *
+ * Instead, we check whether the pre-defined macros for particular
+ * compilers are defined and, if not, define the "is this version XXX
+ * or a later version of this compiler" macros as 0.
+ */
+
+/*
+ * Check whether this is GCC major.minor or a later release, or some
+ * compiler that claims to be "just like GCC" of that version or a
+ * later release.
+ */
+
+#if ! defined(__GNUC__)
+#define PCAP_IS_AT_LEAST_GNUC_VERSION(major, minor) 0
+#else
+#define PCAP_IS_AT_LEAST_GNUC_VERSION(major, minor) \
+ (__GNUC__ > (major) || \
+ (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor)))
+#endif
+
+/*
+ * Check whether this is Clang major.minor or a later release.
+ */
+
+#if !defined(__clang__)
+#define PCAP_IS_AT_LEAST_CLANG_VERSION(major, minor) 0
+#else
+#define PCAP_IS_AT_LEAST_CLANG_VERSION(major, minor) \
+ (__clang_major__ > (major) || \
+ (__clang_major__ == (major) && __clang_minor__ >= (minor)))
+#endif
+
+/*
+ * Check whether this is Sun C/SunPro C/Oracle Studio major.minor
+ * or a later release.
+ *
+ * The version number in __SUNPRO_C is encoded in hex BCD, with the
+ * uppermost hex digit being the major version number, the next
+ * one or two hex digits being the minor version number, and
+ * the last digit being the patch version.
+ *
+ * It represents the *compiler* version, not the product version;
+ * see
+ *
+ * https://sourceforge.net/p/predef/wiki/Compilers/
+ *
+ * for a partial mapping, which we assume continues for later
+ * 12.x product releases.
+ */
+
+#if ! defined(__SUNPRO_C)
+#define PCAP_IS_AT_LEAST_SUNC_VERSION(major,minor) 0
+#else
+#define PCAP_SUNPRO_VERSION_TO_BCD(major, minor) \
+ (((minor) >= 10) ? \
+ (((major) << 12) | (((minor)/10) << 8) | (((minor)%10) << 4)) : \
+ (((major) << 8) | ((minor) << 4)))
+#define PCAP_IS_AT_LEAST_SUNC_VERSION(major,minor) \
+ (__SUNPRO_C >= PCAP_SUNPRO_VERSION_TO_BCD((major), (minor)))
+#endif
+
+/*
+ * Check whether this is IBM XL C major.minor or a later release.
+ *
+ * The version number in __xlC__ has the major version in the
+ * upper 8 bits and the minor version in the lower 8 bits.
+ */
+
+#if ! defined(__xlC__)
+#define PCAP_IS_AT_LEAST_XL_C_VERSION(major,minor) 0
+#else
+#define PCAP_IS_AT_LEAST_XL_C_VERSION(major, minor) \
+ (__xlC__ >= (((major) << 8) | (minor)))
+#endif
+
+/*
+ * Check whether this is HP aC++/HP C major.minor or a later release.
+ *
+ * The version number in __HP_aCC is encoded in zero-padded decimal BCD,
+ * with the "A." stripped off, the uppermost two decimal digits being
+ * the major version number, the next two decimal digits being the minor
+ * version number, and the last two decimal digits being the patch version.
+ * (Strip off the A., remove the . between the major and minor version
+ * number, and add two digits of patch.)
+ */
+
+#if ! defined(__HP_aCC)
+#define PCAP_IS_AT_LEAST_HP_C_VERSION(major,minor) 0
+#else
+#define PCAP_IS_AT_LEAST_HP_C_VERSION(major,minor) \
+ (__HP_aCC >= ((major)*10000 + (minor)*100))
+#endif
+
+#endif /* lib_pcap_funcattrs_h */
diff --git a/contrib/libpcap/pcap/dlt.h b/contrib/libpcap/pcap/dlt.h
index b88303c149e2c..44c36ef8a5697 100644
--- a/contrib/libpcap/pcap/dlt.h
+++ b/contrib/libpcap/pcap/dlt.h
@@ -120,9 +120,9 @@
/*
* 18 is used for DLT_PFSYNC in OpenBSD, NetBSD, DragonFly BSD and
- * Mac OS X; don't use it for anything else. (FreeBSD uses 121,
- * which collides with DLT_HHDLC, even though it doesn't use 18
- * for anything and doesn't appear to have ever used it for anything.)
+ * macOS; don't use it for anything else. (FreeBSD uses 121, which
+ * collides with DLT_HHDLC, even though it doesn't use 18 for
+ * anything and doesn't appear to have ever used it for anything.)
*
* We define it as 18 on those platforms; it is, unfortunately, used
* for DLT_CIP in Suse 6.3, so we don't define it as DLT_PFSYNC
@@ -340,7 +340,7 @@
*
* FreeBSD's libpcap won't map a link-layer header type of 18 - i.e.,
* DLT_PFSYNC files from OpenBSD and possibly older versions of NetBSD,
- * DragonFly BSD, and OS X - to DLT_PFSYNC, so code built with FreeBSD's
+ * DragonFly BSD, and macOS - to DLT_PFSYNC, so code built with FreeBSD's
* libpcap won't treat those files as DLT_PFSYNC files.
*
* Other libpcaps won't map a link-layer header type of 121 to DLT_PFSYNC;
@@ -740,8 +740,13 @@
* nothing); requested by Mikko Saarnivala <mikko.saarnivala@sensinode.com>.
* For this one, we expect the FCS to be present at the end of the frame;
* if the frame has no FCS, DLT_IEEE802_15_4_NOFCS should be used.
+ *
+ * We keep the name DLT_IEEE802_15_4 as an alias for backwards
+ * compatibility, but, again, this should *only* be used for 802.15.4
+ * frames that include the FCS.
*/
-#define DLT_IEEE802_15_4 195
+#define DLT_IEEE802_15_4_WITHFCS 195
+#define DLT_IEEE802_15_4 DLT_IEEE802_15_4_WITHFCS
/*
* Various link-layer types, with a pseudo-header, for SITA
@@ -946,14 +951,14 @@
* the pseudo-header is:
*
* struct dl_ipnetinfo {
- * u_int8_t dli_version;
- * u_int8_t dli_family;
- * u_int16_t dli_htype;
- * u_int32_t dli_pktlen;
- * u_int32_t dli_ifindex;
- * u_int32_t dli_grifindex;
- * u_int32_t dli_zsrc;
- * u_int32_t dli_zdst;
+ * uint8_t dli_version;
+ * uint8_t dli_family;
+ * uint16_t dli_htype;
+ * uint32_t dli_pktlen;
+ * uint32_t dli_ifindex;
+ * uint32_t dli_grifindex;
+ * uint32_t dli_zsrc;
+ * uint32_t dli_zdst;
* };
*
* dli_version is 2 for the current version of the pseudo-header.
@@ -1229,7 +1234,7 @@
* So I'll just give them one; hopefully this will show up in a
* libpcap release in time for them to get this into 10.10 Big Sur
* or whatever Mavericks' successor is called. LINKTYPE_PKTAP
- * will be 258 *even on OS X*; that is *intentional*, so that
+ * will be 258 *even on macOS*; that is *intentional*, so that
* PKTAP files look the same on *all* OSes (different OSes can have
* different numerical values for a given DLT_, but *MUST NOT* have
* different values for what goes in a file, as files can be moved
@@ -1241,9 +1246,9 @@
* and that will continue to be DLT_USER2 on Darwin-based OSes. That way,
* binary compatibility with Mavericks is preserved for programs using
* this version of libpcap. This does mean that if you were using
- * DLT_USER2 for some capture device on OS X, you can't do so with
+ * DLT_USER2 for some capture device on macOS, you can't do so with
* this version of libpcap, just as you can't with Apple's libpcap -
- * on OS X, they define DLT_PKTAP to be DLT_USER2, so programs won't
+ * on macOS, they define DLT_PKTAP to be DLT_USER2, so programs won't
* be able to distinguish between PKTAP and whatever you were using
* DLT_USER2 for.
*
@@ -1303,6 +1308,66 @@
#define DLT_RDS 265
/*
+ * USB packets, beginning with a Darwin (macOS, etc.) header.
+ */
+#define DLT_USB_DARWIN 266
+
+/*
+ * OpenBSD DLT_OPENFLOW.
+ */
+#define DLT_OPENFLOW 267
+
+/*
+ * SDLC frames containing SNA PDUs.
+ */
+#define DLT_SDLC 268
+
+/*
+ * per "Selvig, Bjorn" <b.selvig@ti.com> used for
+ * TI protocol sniffer.
+ */
+#define DLT_TI_LLN_SNIFFER 269
+
+/*
+ * per: Erik de Jong <erikdejong at gmail.com> for
+ * https://github.com/eriknl/LoRaTap/releases/tag/v0.1
+ */
+#define DLT_LORATAP 270
+
+/*
+ * per: Stefanha at gmail.com for
+ * http://lists.sandelman.ca/pipermail/tcpdump-workers/2017-May/000772.html
+ * and: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/vsockmon.h
+ * for: http://qemu-project.org/Features/VirtioVsock
+ */
+#define DLT_VSOCK 271
+
+/*
+ * Nordic Semiconductor Bluetooth LE sniffer.
+ */
+#define DLT_NORDIC_BLE 272
+
+/*
+ * Excentis DOCSIS 3.1 RF sniffer (XRA-31)
+ * per: bruno.verstuyft at excentis.com
+ * http://www.xra31.com/xra-header
+ */
+#define DLT_DOCSIS31_XRA31 273
+
+/*
+ * mPackets, as specified by IEEE 802.3br Figure 99-4, starting
+ * with the preamble and always ending with a CRC field.
+ */
+#define DLT_ETHERNET_MPACKET 274
+
+/*
+ * DisplayPort AUX channel monitoring data as specified by VESA
+ * DisplayPort(DP) Standard preceeded by a pseudo-header.
+ * per dirk.eibach at gdsys.cc
+ */
+#define DLT_DISPLAYPORT_AUX 275
+
+/*
* In case the code that includes this file (directly or indirectly)
* has also included OS files that happen to define DLT_MATCHING_MAX,
* with a different value (perhaps because that OS hasn't picked up
@@ -1312,7 +1377,7 @@
#ifdef DLT_MATCHING_MAX
#undef DLT_MATCHING_MAX
#endif
-#define DLT_MATCHING_MAX 265 /* highest value in the "matching" range */
+#define DLT_MATCHING_MAX 275 /* highest value in the "matching" range */
/*
* DLT and savefile link type values are split into a class and
diff --git a/contrib/libpcap/pcap/export-defs.h b/contrib/libpcap/pcap/export-defs.h
deleted file mode 100644
index a2350579dc4ed..0000000000000
--- a/contrib/libpcap/pcap/export-defs.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/* -*- 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_export_defs_h
-#define lib_pcap_export_defs_h
-
-/*
- * PCAP_API_DEF must be used when defining *data* exported from
- * libpcap. It can be used when defining *functions* exported
- * from libpcap, but it doesn't have to be used there. It
- * should not be used in declarations in headers.
- *
- * PCAP_API must be used when *declaring* data or functions
- * exported from libpcap; PCAP_API_DEF won't work on all platforms.
- */
-
-/*
- * Check whether this is GCC major.minor or a later release, or some
- * compiler that claims to be "just like GCC" of that version or a
- * later release.
- */
-#define IS_AT_LEAST_GNUC_VERSION(major, minor) \
- (defined(__GNUC__) && \
- (__GNUC__ > (major) || \
- (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor))))
-
-#if defined(_WIN32)
- #ifdef BUILDING_PCAP
- /*
- * We're compiling libpcap, so we should export functions in our
- * API.
- */
- #define PCAP_API_DEF __declspec(dllexport)
- #else
- #define PCAP_API_DEF __declspec(dllimport)
- #endif
-#elif defined(MSDOS)
- /* XXX - does this need special treatment? */
- #define PCAP_API_DEF
-#else /* UN*X */
- #ifdef BUILDING_PCAP
- /*
- * We're compiling libpcap, so we should export functions in our API.
- * The compiler might be configured not to export functions from a
- * shared library by default, so we might have to explicitly mark
- * functions as exported.
- */
- #if IS_AT_LEAST_GNUC_VERSION(3, 4)
- /*
- * GCC 3.4 or later, or some compiler asserting compatibility with
- * GCC 3.4 or later, so we have __attribute__((visibility()).
- */
- #define PCAP_API_DEF __attribute__((visibility("default")))
- #elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550)
- /*
- * Sun C 5.5 or later, so we have __global.
- * (Sun C 5.9 and later also have __attribute__((visibility()),
- * but there's no reason to prefer it with Sun C.)
- */
- #define PCAP_API_DEF __global
- #else
- /*
- * We don't have anything to say.
- */
- #define PCAP_API_DEF
- #endif
- #else
- /*
- * We're not building libpcap.
- */
- #define PCAP_API_DEF
- #endif
-#endif /* _WIN32/MSDOS/UN*X */
-
-#define PCAP_API PCAP_API_DEF extern
-
-#endif /* lib_pcap_export_defs_h */
diff --git a/contrib/libpcap/pcap/funcattrs.h b/contrib/libpcap/pcap/funcattrs.h
new file mode 100644
index 0000000000000..a8b1932f4c6e1
--- /dev/null
+++ b/contrib/libpcap/pcap/funcattrs.h
@@ -0,0 +1,261 @@
+/* -*- 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_funcattrs_h
+#define lib_pcap_funcattrs_h
+
+#include <pcap/compiler-tests.h>
+
+/*
+ * Attributes to apply to functions and their arguments, using various
+ * compiler-specific extensions.
+ */
+
+/*
+ * PCAP_API_DEF must be used when defining *data* exported from
+ * libpcap. It can be used when defining *functions* exported
+ * from libpcap, but it doesn't have to be used there. It
+ * should not be used in declarations in headers.
+ *
+ * PCAP_API must be used when *declaring* data or functions
+ * exported from libpcap; PCAP_API_DEF won't work on all platforms.
+ */
+
+#if defined(_WIN32)
+ /*
+ * For Windows:
+ *
+ * when building libpcap:
+ *
+ * if we're building it as a DLL, we have to declare API
+ * functions with __declspec(dllexport);
+ *
+ * if we're building it as a static library, we don't want
+ * to do so.
+ *
+ * when using libpcap:
+ *
+ * if we're using the DLL, calls to its functions are a
+ * little more efficient if they're declared with
+ * __declspec(dllimport);
+ *
+ * if we're not using the dll, we don't want to declare
+ * them that way.
+ *
+ * So:
+ *
+ * if pcap_EXPORTS is defined, we define PCAP_API_DEF as
+ * __declspec(dllexport);
+ *
+ * if PCAP_DLL is defined, we define PCAP_API_DEF as
+ * __declspec(dllimport);
+ *
+ * otherwise, we define PCAP_API_DEF as nothing.
+ */
+ #if defined(pcap_EXPORTS)
+ /*
+ * We're compiling libpcap as a DLL, so we should export functions
+ * in our API.
+ */
+ #define PCAP_API_DEF __declspec(dllexport)
+ #elif defined(PCAP_DLL)
+ /*
+ * We're using libpcap as a DLL, so the calls will be a little more
+ * efficient if we explicitly import the functions.
+ */
+ #define PCAP_API_DEF __declspec(dllimport)
+ #else
+ /*
+ * Either we're building libpcap as a static library, or we're using
+ * it as a static library, or we don't know for certain that we're
+ * using it as a dynamic library, so neither import nor export the
+ * functions explicitly.
+ */
+ #define PCAP_API_DEF
+ #endif
+#elif defined(MSDOS)
+ /* XXX - does this need special treatment? */
+ #define PCAP_API_DEF
+#else /* UN*X */
+ #ifdef pcap_EXPORTS
+ /*
+ * We're compiling libpcap as a (dynamic) shared library, so we should
+ * export functions in our API. The compiler might be configured not
+ * to export functions from a shared library by default, so we might
+ * have to explicitly mark functions as exported.
+ */
+ #if PCAP_IS_AT_LEAST_GNUC_VERSION(3,4) \
+ || PCAP_IS_AT_LEAST_XL_C_VERSION(12,0)
+ /*
+ * GCC 3.4 or later, or some compiler asserting compatibility with
+ * GCC 3.4 or later, or XL C 13.0 or later, so we have
+ * __attribute__((visibility()).
+ */
+ #define PCAP_API_DEF __attribute__((visibility("default")))
+ #elif PCAP_IS_AT_LEAST_SUNC_VERSION(5,5)
+ /*
+ * Sun C 5.5 or later, so we have __global.
+ * (Sun C 5.9 and later also have __attribute__((visibility()),
+ * but there's no reason to prefer it with Sun C.)
+ */
+ #define PCAP_API_DEF __global
+ #else
+ /*
+ * We don't have anything to say.
+ */
+ #define PCAP_API_DEF
+ #endif
+ #else
+ /*
+ * We're not building libpcap.
+ */
+ #define PCAP_API_DEF
+ #endif
+#endif /* _WIN32/MSDOS/UN*X */
+
+#define PCAP_API PCAP_API_DEF extern
+
+/*
+ * PCAP_NORETURN, before a function declaration, means "this function
+ * never returns". (It must go before the function declaration, e.g.
+ * "extern PCAP_NORETURN func(...)" rather than after the function
+ * declaration, as the MSVC version has to go before the declaration.)
+ *
+ * PCAP_NORETURN_DEF, before a function *definition*, means "this
+ * function never returns"; it would be used only for static functions
+ * that are defined before any use, and thus have no declaration.
+ * (MSVC doesn't support that; I guess the "decl" in "__declspec"
+ * means "declaration", and __declspec doesn't work with definitions.)
+ */
+#if __has_attribute(noreturn) \
+ || PCAP_IS_AT_LEAST_GNUC_VERSION(2,5) \
+ || PCAP_IS_AT_LEAST_SUNC_VERSION(5,9) \
+ || 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.
+ */
+ #define PCAP_NORETURN __attribute((noreturn))
+ #define PCAP_NORETURN_DEF __attribute((noreturn))
+#elif defined(_MSC_VER)
+ /*
+ * MSVC.
+ */
+ #define PCAP_NORETURN __declspec(noreturn)
+ #define PCAP_NORETURN_DEF
+#else
+ #define PCAP_NORETURN
+ #define PCAP_NORETURN_DEF
+#endif
+
+/*
+ * PCAP_PRINTFLIKE(x,y), after a function declaration, means "this function
+ * does printf-style formatting, with the xth argument being the format
+ * string and the yth argument being the first argument for the format
+ * string".
+ */
+#if __has_attribute(__format__) \
+ || PCAP_IS_AT_LEAST_GNUC_VERSION(2,3) \
+ || 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
+ * and later (do any earlier versions of XL C support this?),
+ * or HP aCC A.06.10 and later.
+ */
+ #define PCAP_PRINTFLIKE(x,y) __attribute__((__format__(__printf__,x,y)))
+#else
+ #define PCAP_PRINTFLIKE(x,y)
+#endif
+
+/*
+ * PCAP_DEPRECATED(func, msg), after a function declaration, marks the
+ * function as deprecated.
+ *
+ * The first argument is the name of the function; the second argument is
+ * a string giving the warning message to use if the compiler supports that.
+ *
+ * (Thank you, Microsoft, for requiring the function name.)
+ */
+#if __has_attribute(deprecated) \
+ || PCAP_IS_AT_LEAST_GNUC_VERSION(4,5) \
+ || 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.
+ *
+ * Those support __attribute__((deprecated(msg))) (we assume, perhaps
+ * incorrectly, that anything that supports __has_attribute() is
+ * recent enough to support __attribute__((deprecated(msg)))).
+ */
+ #define PCAP_DEPRECATED(func, msg) __attribute__((deprecated(msg)))
+#elif PCAP_IS_AT_LEAST_GNUC_VERSION(3,1)
+ /*
+ * GCC 3.1 through 4.4.
+ *
+ * Those support __attribute__((deprecated)) but not
+ * __attribute__((deprecated(msg))).
+ */
+ #define PCAP_DEPRECATED(func, msg) __attribute__((deprecated))
+#elif (defined(_MSC_VER) && (_MSC_VER >= 1500)) && !defined(BUILDING_PCAP)
+ /*
+ * MSVC from Visual Studio 2008 or later, and we're not building
+ * libpcap itself.
+ *
+ * If we *are* building libpcap, we don't want this, as it'll warn
+ * us even if we *define* the function.
+ */
+ #define PCAP_DEPRECATED(func, msg) __pragma(deprecated(func))
+#else
+ #define PCAP_DEPRECATED(func, msg)
+#endif
+
+/*
+ * For flagging arguments as format strings in MSVC.
+ */
+#ifdef _MSC_VER
+ #include <sal.h>
+ #if _MSC_VER > 1400
+ #define PCAP_FORMAT_STRING(p) _Printf_format_string_ p
+ #else
+ #define PCAP_FORMAT_STRING(p) __format_string p
+ #endif
+#else
+ #define PCAP_FORMAT_STRING(p) p
+#endif
+
+#endif /* lib_pcap_funcattrs_h */
diff --git a/contrib/libpcap/pcap/namedb.h b/contrib/libpcap/pcap/namedb.h
index 73fb40a4cf3ff..c66846d3451bd 100644
--- a/contrib/libpcap/pcap/namedb.h
+++ b/contrib/libpcap/pcap/namedb.h
@@ -60,9 +60,7 @@ PCAP_API u_char *pcap_ether_hostton(const char*);
PCAP_API u_char *pcap_ether_aton(const char *);
PCAP_API bpf_u_int32 **pcap_nametoaddr(const char *);
-#ifdef INET6
PCAP_API struct addrinfo *pcap_nametoaddrinfo(const char *);
-#endif
PCAP_API bpf_u_int32 pcap_nametonetaddr(const char *);
PCAP_API int pcap_nametoport(const char *, int *, int *);
diff --git a/contrib/libpcap/pcap/nflog.h b/contrib/libpcap/pcap/nflog.h
index a3867cdd6cbcf..29a71d2d3fb57 100644
--- a/contrib/libpcap/pcap/nflog.h
+++ b/contrib/libpcap/pcap/nflog.h
@@ -28,6 +28,8 @@
#ifndef lib_pcap_nflog_h
#define lib_pcap_nflog_h
+#include <pcap/pcap-inttypes.h>
+
/*
* Structure of an NFLOG header and TLV parts, as described at
* http://www.tcpdump.org/linktypes/LINKTYPE_NFLOG.html
@@ -40,32 +42,32 @@
* data, etc.).
*/
typedef struct nflog_hdr {
- u_int8_t nflog_family; /* address family */
- u_int8_t nflog_version; /* version */
- u_int16_t nflog_rid; /* resource ID */
+ uint8_t nflog_family; /* address family */
+ uint8_t nflog_version; /* version */
+ uint16_t nflog_rid; /* resource ID */
} nflog_hdr_t;
typedef struct nflog_tlv {
- u_int16_t tlv_length; /* tlv length */
- u_int16_t tlv_type; /* tlv type */
+ uint16_t tlv_length; /* tlv length */
+ uint16_t tlv_type; /* tlv type */
/* value follows this */
} nflog_tlv_t;
typedef struct nflog_packet_hdr {
- u_int16_t hw_protocol; /* hw protocol */
- u_int8_t hook; /* netfilter hook */
- u_int8_t pad; /* padding to 32 bits */
+ uint16_t hw_protocol; /* hw protocol */
+ uint8_t hook; /* netfilter hook */
+ uint8_t pad; /* padding to 32 bits */
} nflog_packet_hdr_t;
typedef struct nflog_hwaddr {
- u_int16_t hw_addrlen; /* address length */
- u_int16_t pad; /* padding to 32-bit boundary */
- u_int8_t hw_addr[8]; /* address, up to 8 bytes */
+ uint16_t hw_addrlen; /* address length */
+ uint16_t pad; /* padding to 32-bit boundary */
+ uint8_t hw_addr[8]; /* address, up to 8 bytes */
} nflog_hwaddr_t;
typedef struct nflog_timestamp {
- u_int64_t sec;
- u_int64_t usec;
+ uint64_t sec;
+ uint64_t usec;
} nflog_timestamp_t;
/*
diff --git a/contrib/libpcap/pcap/pcap-inttypes.h b/contrib/libpcap/pcap/pcap-inttypes.h
new file mode 100644
index 0000000000000..af2c23c877edf
--- /dev/null
+++ b/contrib/libpcap/pcap/pcap-inttypes.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2002 - 2005 NetGroup, Politecnico di Torino (Italy)
+ * Copyright (c) 2005 - 2009 CACE Technologies, Inc. Davis (California)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Politecnico di Torino nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef pcap_pcap_inttypes_h
+#define pcap_pcap_inttypes_h
+
+/*
+ * Get the integer types and PRi[doux]64 values from C99 <inttypes.h>
+ * defined, by hook or by crook.
+ */
+#if defined(_MSC_VER)
+ /*
+ * Compiler is MSVC.
+ */
+ #if _MSC_VER >= 1800
+ /*
+ * VS 2013 or newer; we have <inttypes.h>.
+ */
+ #include <inttypes.h>
+ #else
+ /*
+ * Earlier VS; we have to define this stuff ourselves.
+ */
+ typedef unsigned char uint8_t;
+ typedef signed char int8_t;
+ typedef unsigned short uint16_t;
+ typedef signed short int16_t;
+ typedef unsigned int uint32_t;
+ typedef signed int int32_t;
+ #ifdef _MSC_EXTENSIONS
+ typedef unsigned _int64 uint64_t;
+ typedef _int64 int64_t;
+ #else /* _MSC_EXTENSIONS */
+ typedef unsigned long long uint64_t;
+ typedef long long int64_t;
+ #endif
+ #endif
+
+ /*
+ * These may be defined by <inttypes.h>.
+ *
+ * XXX - for MSVC, we always want the _MSC_EXTENSIONS versions.
+ * What about other compilers? If, as the MinGW Web site says MinGW
+ * does, the other compilers just use Microsoft's run-time library,
+ * then they should probably use the _MSC_EXTENSIONS even if the
+ * compiler doesn't define _MSC_EXTENSIONS.
+ *
+ * XXX - we currently aren't using any of these, but this allows
+ * their use in the future.
+ */
+ #ifndef PRId64
+ #ifdef _MSC_EXTENSIONS
+ #define PRId64 "I64d"
+ #else
+ #define PRId64 "lld"
+ #endif
+ #endif /* PRId64 */
+
+ #ifndef PRIo64
+ #ifdef _MSC_EXTENSIONS
+ #define PRIo64 "I64o"
+ #else
+ #define PRIo64 "llo"
+ #endif
+ #endif /* PRIo64 */
+
+ #ifndef PRIx64
+ #ifdef _MSC_EXTENSIONS
+ #define PRIx64 "I64x"
+ #else
+ #define PRIx64 "llx"
+ #endif
+ #endif
+
+ #ifndef PRIu64
+ #ifdef _MSC_EXTENSIONS
+ #define PRIu64 "I64u"
+ #else
+ #define PRIu64 "llu"
+ #endif
+ #endif
+#elif defined(__MINGW32__) || !defined(_WIN32)
+ /*
+ * Compiler is MinGW or target is UN*X or MS-DOS. Just use
+ * <inttypes.h>.
+ */
+ #include <inttypes.h>
+#endif
+
+#endif /* pcap/pcap-inttypes.h */
diff --git a/contrib/libpcap/pcap/pcap.h b/contrib/libpcap/pcap/pcap.h
index 9c27712441f0e..f809dd1145e4d 100644
--- a/contrib/libpcap/pcap/pcap.h
+++ b/contrib/libpcap/pcap/pcap.h
@@ -32,22 +32,61 @@
* SUCH DAMAGE.
*/
+/*
+ * Remote packet capture mechanisms and extensions from WinPcap:
+ *
+ * Copyright (c) 2002 - 2003
+ * NetGroup, Politecnico di Torino (Italy)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Politecnico di Torino nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
#ifndef lib_pcap_pcap_h
#define lib_pcap_pcap_h
-#include <pcap/export-defs.h>
+#include <pcap/funcattrs.h>
+
+#include <pcap/pcap-inttypes.h>
#if defined(_WIN32)
- #include <pcap-stdinc.h>
+ #include <winsock2.h> /* u_int, u_char etc. */
+ #include <io.h> /* _get_osfhandle() */
#elif defined(MSDOS)
- #include <sys/types.h>
- #include <sys/socket.h> /* u_int, u_char etc. */
+ #include <sys/types.h> /* u_int, u_char etc. */
+ #include <sys/socket.h>
#else /* UN*X */
- #include <sys/types.h>
+ #include <sys/types.h> /* u_int, u_char etc. */
#include <sys/time.h>
#endif /* _WIN32/MSDOS/UN*X */
-#include <net/bpf.h>
+#ifndef PCAP_DONT_INCLUDE_PCAP_BPF_H
+#include <pcap/bpf.h>
+#endif
#include <stdio.h>
@@ -170,11 +209,11 @@ struct pcap_stat {
u_int ps_recv; /* number of packets received */
u_int ps_drop; /* number of packets dropped */
u_int ps_ifdrop; /* drops by interface -- only supported on some platforms */
-#if defined(_WIN32) && defined(HAVE_REMOTE)
+#ifdef _WIN32
u_int ps_capt; /* number of packets that reach the application */
u_int ps_sent; /* number of packets sent by the server on the network */
u_int ps_netdrop; /* number of packets lost on the network */
-#endif /* _WIN32 && HAVE_REMOTE */
+#endif /* _WIN32 */
};
#ifdef MSDOS
@@ -221,9 +260,15 @@ struct pcap_if {
bpf_u_int32 flags; /* PCAP_IF_ interface flags */
};
-#define PCAP_IF_LOOPBACK 0x00000001 /* interface is loopback */
-#define PCAP_IF_UP 0x00000002 /* interface is up */
-#define PCAP_IF_RUNNING 0x00000004 /* interface is running */
+#define PCAP_IF_LOOPBACK 0x00000001 /* interface is loopback */
+#define PCAP_IF_UP 0x00000002 /* interface is up */
+#define PCAP_IF_RUNNING 0x00000004 /* interface is running */
+#define PCAP_IF_WIRELESS 0x00000008 /* interface is wireless (*NOT* necessarily Wi-Fi!) */
+#define PCAP_IF_CONNECTION_STATUS 0x00000030 /* connection status: */
+#define PCAP_IF_CONNECTION_STATUS_UNKNOWN 0x00000000 /* unknown */
+#define PCAP_IF_CONNECTION_STATUS_CONNECTED 0x00000010 /* connected */
+#define PCAP_IF_CONNECTION_STATUS_DISCONNECTED 0x00000020 /* disconnected */
+#define PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE 0x00000030 /* not applicable */
/*
* Representation of an interface address.
@@ -273,7 +318,14 @@ typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *,
*/
#define PCAP_NETMASK_UNKNOWN 0xffffffff
-PCAP_API char *pcap_lookupdev(char *);
+/*
+ * We're deprecating pcap_lookupdev() for various reasons (not
+ * thread-safe, can behave weirdly with WinPcap). Callers
+ * should use pcap_findalldevs() and use the first device.
+ */
+PCAP_API char *pcap_lookupdev(char *)
+PCAP_DEPRECATED(pcap_lookupdev, "use 'pcap_findalldevs' and use the first device");
+
PCAP_API int pcap_lookupnet(const char *, bpf_u_int32 *, bpf_u_int32 *, char *);
PCAP_API pcap_t *pcap_create(const char *, char *);
@@ -295,6 +347,10 @@ PCAP_API int pcap_tstamp_type_name_to_val(const char *);
PCAP_API const char *pcap_tstamp_type_val_to_name(int);
PCAP_API const char *pcap_tstamp_type_val_to_description(int);
+#ifdef __linux__
+PCAP_API int pcap_set_protocol(pcap_t *, int);
+#endif
+
/*
* Time stamp types.
* Not all systems and interfaces will necessarily support all of these.
@@ -358,7 +414,16 @@ PCAP_API pcap_t *pcap_open_offline(const char *, char *);
PCAP_API pcap_t *pcap_hopen_offline(intptr_t, char *);
/*
* If we're building libpcap, these are internal routines in savefile.c,
- * so we mustn't define them as macros.
+ * so we must not define them as macros.
+ *
+ * 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_fopen_offline_with_tstamp_precision(f,p,b) \
@@ -407,6 +472,7 @@ PCAP_API int pcap_snapshot(pcap_t *);
PCAP_API int pcap_is_swapped(pcap_t *);
PCAP_API int pcap_major_version(pcap_t *);
PCAP_API int pcap_minor_version(pcap_t *);
+PCAP_API int pcap_bufsize(pcap_t *);
/* XXX */
PCAP_API FILE *pcap_file(pcap_t *);
@@ -421,6 +487,7 @@ PCAP_API pcap_dumper_t *pcap_dump_fopen(pcap_t *, FILE *fp);
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 *);
+PCAP_API int64_t pcap_dump_ftell64(pcap_dumper_t *);
PCAP_API int pcap_dump_flush(pcap_dumper_t *);
PCAP_API void pcap_dump_close(pcap_dumper_t *);
PCAP_API void pcap_dump(u_char *, const struct pcap_pkthdr *, const u_char *);
@@ -428,6 +495,21 @@ PCAP_API void pcap_dump(u_char *, const struct pcap_pkthdr *, const u_char *);
PCAP_API int pcap_findalldevs(pcap_if_t **, char *);
PCAP_API void pcap_freealldevs(pcap_if_t *);
+/*
+ * We return a pointer to the version string, rather than exporting the
+ * version string directly.
+ *
+ * On at least some UNIXes, if you import data from a shared library into
+ * an program, the data is bound into the program binary, so if the string
+ * in the version of the library with which the program was linked isn't
+ * the same as the string in the version of the library with which the
+ * program is being run, various undesirable things may happen (warnings,
+ * the string being the one from the version of the library with which the
+ * program was linked, or even weirder things, such as the string being the
+ * one from the library but being truncated).
+ *
+ * On Windows, the string is constructed at run time.
+ */
PCAP_API const char *pcap_lib_version(void);
/*
@@ -455,7 +537,7 @@ PCAP_API void bpf_dump(const struct bpf_program *, int);
*/
struct pcap_send_queue
{
- u_int maxlen; /* Maximum size of the the queue, in bytes. This
+ u_int maxlen; /* Maximum size of the queue, in bytes. This
variable contains the size of the buffer field. */
u_int len; /* Current size of the queue, in bytes. */
char *buffer; /* Buffer containing the packets to be sent. */
@@ -521,13 +603,368 @@ PCAP_API void bpf_dump(const struct bpf_program *, int);
*/
PCAP_API int pcap_get_selectable_fd(pcap_t *);
+ PCAP_API struct timeval *pcap_get_required_select_timeout(pcap_t *);
#endif /* _WIN32/MSDOS/UN*X */
-#ifdef HAVE_REMOTE
- /* Includes most of the public stuff that is needed for the remote capture */
- #include <remote-ext.h>
-#endif /* HAVE_REMOTE */
+/*
+ * Remote capture definitions.
+ *
+ * These routines are only present if libpcap has been configured to
+ * include remote capture support.
+ */
+
+/*
+ * The maximum buffer size in which address, port, interface names are kept.
+ *
+ * In case the adapter name or such is larger than this value, it is truncated.
+ * This is not used by the user; however it must be aware that an hostname / interface
+ * name longer than this value will be truncated.
+ */
+#define PCAP_BUF_SIZE 1024
+
+/*
+ * The type of input source, passed to pcap_open().
+ */
+#define PCAP_SRC_FILE 2 /* local savefile */
+#define PCAP_SRC_IFLOCAL 3 /* local network interface */
+#define PCAP_SRC_IFREMOTE 4 /* interface on a remote host, using RPCAP */
+
+/*
+ * The formats allowed by pcap_open() are the following:
+ * - file://path_and_filename [opens a local file]
+ * - rpcap://devicename [opens the selected device devices available on the local host, without using the RPCAP protocol]
+ * - rpcap://host/devicename [opens the selected device available on a remote host]
+ * - rpcap://host:port/devicename [opens the selected device available on a remote host, using a non-standard port for RPCAP]
+ * - adaptername [to open a local adapter; kept for compability, but it is strongly discouraged]
+ * - (NULL) [to open the first local adapter; kept for compability, but it is strongly discouraged]
+ *
+ * The formats allowed by the pcap_findalldevs_ex() are the following:
+ * - file://folder/ [lists all the files in the given folder]
+ * - rpcap:// [lists all local adapters]
+ * - rpcap://host:port/ [lists the devices available on a remote host]
+ *
+ * Referring to the 'host' and 'port' parameters, they can be either numeric or literal. Since
+ * IPv6 is fully supported, these are the allowed formats:
+ *
+ * - host (literal): e.g. host.foo.bar
+ * - host (numeric IPv4): e.g. 10.11.12.13
+ * - host (numeric IPv4, IPv6 style): e.g. [10.11.12.13]
+ * - host (numeric IPv6): e.g. [1:2:3::4]
+ * - port: can be either numeric (e.g. '80') or literal (e.g. 'http')
+ *
+ * Here you find some allowed examples:
+ * - rpcap://host.foo.bar/devicename [everything literal, no port number]
+ * - rpcap://host.foo.bar:1234/devicename [everything literal, with port number]
+ * - rpcap://10.11.12.13/devicename [IPv4 numeric, no port number]
+ * - rpcap://10.11.12.13:1234/devicename [IPv4 numeric, with port number]
+ * - rpcap://[10.11.12.13]:1234/devicename [IPv4 numeric with IPv6 format, with port number]
+ * - rpcap://[1:2:3::4]/devicename [IPv6 numeric, no port number]
+ * - rpcap://[1:2:3::4]:1234/devicename [IPv6 numeric, with port number]
+ * - rpcap://[1:2:3::4]:http/devicename [IPv6 numeric, with literal port number]
+ */
+
+/*
+ * URL schemes for capture source.
+ */
+/*
+ * This string indicates that the user wants to open a capture from a
+ * local file.
+ */
+#define PCAP_SRC_FILE_STRING "file://"
+/*
+ * This string indicates that the user wants to open a capture from a
+ * network interface. This string does not necessarily involve the use
+ * of the RPCAP protocol. If the interface required resides on the local
+ * host, the RPCAP protocol is not involved and the local functions are used.
+ */
+#define PCAP_SRC_IF_STRING "rpcap://"
+
+/*
+ * Flags to pass to pcap_open().
+ */
+
+/*
+ * Specifies whether promiscuous mode is to be used.
+ */
+#define PCAP_OPENFLAG_PROMISCUOUS 0x00000001
+
+/*
+ * Specifies, for an RPCAP capture, whether the data transfer (in
+ * case of a remote capture) has to be done with UDP protocol.
+ *
+ * If it is '1' if you want a UDP data connection, '0' if you want
+ * a TCP data connection; control connection is always TCP-based.
+ * A UDP connection is much lighter, but it does not guarantee that all
+ * the captured packets arrive to the client workstation. Moreover,
+ * it could be harmful in case of network congestion.
+ * This flag is meaningless if the source is not a remote interface.
+ * In that case, it is simply ignored.
+ */
+#define PCAP_OPENFLAG_DATATX_UDP 0x00000002
+
+/*
+ * Specifies wheether the remote probe will capture its own generated
+ * traffic.
+ *
+ * In case the remote probe uses the same interface to capture traffic
+ * and to send data back to the caller, the captured traffic includes
+ * the RPCAP traffic as well. If this flag is turned on, the RPCAP
+ * traffic is excluded from the capture, so that the trace returned
+ * back to the collector is does not include this traffic.
+ *
+ * Has no effect on local interfaces or savefiles.
+ */
+#define PCAP_OPENFLAG_NOCAPTURE_RPCAP 0x00000004
+
+/*
+ * Specifies whether the local adapter will capture its own generated traffic.
+ *
+ * This flag tells the underlying capture driver to drop the packets
+ * that were sent by itself. This is useful when building applications
+ * such as bridges that should ignore the traffic they just sent.
+ *
+ * Supported only on Windows.
+ */
+#define PCAP_OPENFLAG_NOCAPTURE_LOCAL 0x00000008
+
+/*
+ * This flag configures the adapter for maximum responsiveness.
+ *
+ * In presence of a large value for nbytes, WinPcap waits for the arrival
+ * of several packets before copying the data to the user. This guarantees
+ * a low number of system calls, i.e. lower processor usage, i.e. better
+ * performance, which is good for applications like sniffers. If the user
+ * sets the PCAP_OPENFLAG_MAX_RESPONSIVENESS flag, the capture driver will
+ * copy the packets as soon as the application is ready to receive them.
+ * This is suggested for real time applications (such as, for example,
+ * a bridge) that need the best responsiveness.
+ *
+ * The equivalent with pcap_create()/pcap_activate() is "immediate mode".
+ */
+#define PCAP_OPENFLAG_MAX_RESPONSIVENESS 0x00000010
+
+/*
+ * Remote authentication methods.
+ * These are used in the 'type' member of the pcap_rmtauth structure.
+ */
+
+/*
+ * NULL authentication.
+ *
+ * The 'NULL' authentication has to be equal to 'zero', so that old
+ * applications can just put every field of struct pcap_rmtauth to zero,
+ * and it does work.
+ */
+#define RPCAP_RMTAUTH_NULL 0
+/*
+ * Username/password authentication.
+ *
+ * With this type of authentication, the RPCAP protocol will use the username/
+ * password provided to authenticate the user on the remote machine. If the
+ * authentication is successful (and the user has the right to open network
+ * devices) the RPCAP connection will continue; otherwise it will be dropped.
+ *
+ * *******NOTE********: the username and password are sent over the network
+ * to the capture server *IN CLEAR TEXT*. Don't use this on a network
+ * that you don't completely control! (And be *really* careful in your
+ * definition of "completely"!)
+ */
+#define RPCAP_RMTAUTH_PWD 1
+
+/*
+ * This structure keeps the information needed to autheticate the user
+ * on a remote machine.
+ *
+ * The remote machine can either grant or refuse the access according
+ * to the information provided.
+ * In case the NULL authentication is required, both 'username' and
+ * 'password' can be NULL pointers.
+ *
+ * This structure is meaningless if the source is not a remote interface;
+ * in that case, the functions which requires such a structure can accept
+ * a NULL pointer as well.
+ */
+struct pcap_rmtauth
+{
+ /*
+ * \brief Type of the authentication required.
+ *
+ * In order to provide maximum flexibility, we can support different types
+ * of authentication based on the value of this 'type' variable. The currently
+ * supported authentication methods are defined into the
+ * \link remote_auth_methods Remote Authentication Methods Section\endlink.
+ */
+ int type;
+ /*
+ * \brief Zero-terminated string containing the username that has to be
+ * used on the remote machine for authentication.
+ *
+ * This field is meaningless in case of the RPCAP_RMTAUTH_NULL authentication
+ * and it can be NULL.
+ */
+ char *username;
+ /*
+ * \brief Zero-terminated string containing the password that has to be
+ * used on the remote machine for authentication.
+ *
+ * This field is meaningless in case of the RPCAP_RMTAUTH_NULL authentication
+ * and it can be NULL.
+ */
+ char *password;
+};
+
+/*
+ * This routine can open a savefile, a local device, or a device on
+ * a remote machine running an RPCAP server.
+ *
+ * For opening a savefile, the pcap_open_offline routines can be used,
+ * and will work just as well; code using them will work on more
+ * platforms than code using pcap_open() to open savefiles.
+ *
+ * For opening a local device, pcap_open_live() can be used; it supports
+ * most of the capabilities that pcap_open() supports, and code using it
+ * will work on more platforms than code using pcap_open(). pcap_create()
+ * and pcap_activate() can also be used; they support all capabilities
+ * that pcap_open() supports, except for the Windows-only
+ * PCAP_OPENFLAG_NOCAPTURE_LOCAL, and support additional capabilities.
+ *
+ * For opening a remote capture, pcap_open() is currently the only
+ * API available.
+ */
+PCAP_API pcap_t *pcap_open(const char *source, int snaplen, int flags,
+ int read_timeout, struct pcap_rmtauth *auth, char *errbuf);
+PCAP_API int pcap_createsrcstr(char *source, int type, const char *host,
+ const char *port, const char *name, char *errbuf);
+PCAP_API int pcap_parsesrcstr(const char *source, int *type, char *host,
+ char *port, char *name, char *errbuf);
+
+/*
+ * This routine can scan a directory for savefiles, list local capture
+ * devices, or list capture devices on a remote machine running an RPCAP
+ * server.
+ *
+ * For scanning for savefiles, it can be used on both UN*X systems and
+ * Windows systems; for each directory entry it sees, it tries to open
+ * the file as a savefile using pcap_open_offline(), and only includes
+ * it in the list of files if the open succeeds, so it filters out
+ * files for which the user doesn't have read permission, as well as
+ * files that aren't valid savefiles readable by libpcap.
+ *
+ * For listing local capture devices, it's just a wrapper around
+ * pcap_findalldevs(); code using pcap_findalldevs() will work on more
+ * platforms than code using pcap_findalldevs_ex().
+ *
+ * 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);
+
+/*
+ * Sampling methods.
+ *
+ * These allow pcap_loop(), pcap_dispatch(), pcap_next(), and pcap_next_ex()
+ * to see only a sample of packets, rather than all packets.
+ *
+ * Currently, they work only on Windows local captures.
+ */
+
+/*
+ * Specifies that no sampling is to be done on the current capture.
+ *
+ * In this case, no sampling algorithms are applied to the current capture.
+ */
+#define PCAP_SAMP_NOSAMP 0
+
+/*
+ * Specifies that only 1 out of N packets must be returned to the user.
+ *
+ * In this case, the 'value' field of the 'pcap_samp' structure indicates the
+ * number of packets (minus 1) that must be discarded before one packet got
+ * accepted.
+ * In other words, if 'value = 10', the first packet is returned to the
+ * caller, while the following 9 are discarded.
+ */
+#define PCAP_SAMP_1_EVERY_N 1
+
+/*
+ * Specifies that we have to return 1 packet every N milliseconds.
+ *
+ * In this case, the 'value' field of the 'pcap_samp' structure indicates
+ * the 'waiting time' in milliseconds before one packet got accepted.
+ * In other words, if 'value = 10', the first packet is returned to the
+ * caller; the next returned one will be the first packet that arrives
+ * when 10ms have elapsed.
+ */
+#define PCAP_SAMP_FIRST_AFTER_N_MS 2
+
+/*
+ * This structure defines the information related to sampling.
+ *
+ * In case the sampling is requested, the capturing device should read
+ * only a subset of the packets coming from the source. The returned packets
+ * depend on the sampling parameters.
+ *
+ * WARNING: The sampling process is applied *after* the filtering process.
+ * In other words, packets are filtered first, then the sampling process
+ * selects a subset of the 'filtered' packets and it returns them to the
+ * caller.
+ */
+struct pcap_samp
+{
+ /*
+ * Method used for sampling; see above.
+ */
+ int method;
+
+ /*
+ * This value depends on the sampling method defined.
+ * For its meaning, see above.
+ */
+ int value;
+};
+
+/*
+ * New functions.
+ */
+PCAP_API struct pcap_samp *pcap_setsampling(pcap_t *p);
+
+/*
+ * RPCAP active mode.
+ */
+
+/* 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);
+PCAP_API int pcap_remoteact_list(char *hostlist, char sep, int size,
+ char *errbuf);
+PCAP_API int pcap_remoteact_close(const char *host, char *errbuf);
+PCAP_API void pcap_remoteact_cleanup(void);
#ifdef __cplusplus
}
diff --git a/contrib/libpcap/pcap/sll.h b/contrib/libpcap/pcap/sll.h
index b46d15f25d83f..c4d08862d64e0 100644
--- a/contrib/libpcap/pcap/sll.h
+++ b/contrib/libpcap/pcap/sll.h
@@ -80,12 +80,14 @@
#define SLL_HDR_LEN 16 /* total header length */
#define SLL_ADDRLEN 8 /* length of address field */
+#include <pcap/pcap-inttypes.h>
+
struct sll_header {
- u_int16_t sll_pkttype; /* packet type */
- u_int16_t sll_hatype; /* link-layer address type */
- u_int16_t sll_halen; /* link-layer address length */
- u_int8_t sll_addr[SLL_ADDRLEN]; /* link-layer address */
- u_int16_t sll_protocol; /* protocol */
+ 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 */
+ uint16_t sll_protocol; /* protocol */
};
/*
diff --git a/contrib/libpcap/pcap/usb.h b/contrib/libpcap/pcap/usb.h
index 26a9046b44ed1..e485ec85d024c 100644
--- a/contrib/libpcap/pcap/usb.h
+++ b/contrib/libpcap/pcap/usb.h
@@ -34,6 +34,8 @@
#ifndef lib_pcap_usb_h
#define lib_pcap_usb_h
+#include <pcap/pcap-inttypes.h>
+
/*
* possible transfer mode
*/
@@ -55,11 +57,11 @@
* Appears at the front of each Control S-type packet in DLT_USB captures.
*/
typedef struct _usb_setup {
- u_int8_t bmRequestType;
- u_int8_t bRequest;
- u_int16_t wValue;
- u_int16_t wIndex;
- u_int16_t wLength;
+ uint8_t bmRequestType;
+ uint8_t bRequest;
+ uint16_t wValue;
+ uint16_t wIndex;
+ uint16_t wLength;
} pcap_usb_setup;
/*
@@ -75,19 +77,19 @@ typedef struct _iso_rec {
* Appears at the front of each packet in DLT_USB_LINUX captures.
*/
typedef struct _usb_header {
- u_int64_t id;
- u_int8_t event_type;
- u_int8_t transfer_type;
- u_int8_t endpoint_number;
- u_int8_t device_address;
- u_int16_t bus_id;
+ uint64_t id;
+ uint8_t event_type;
+ uint8_t transfer_type;
+ uint8_t endpoint_number;
+ uint8_t device_address;
+ uint16_t bus_id;
char setup_flag;/*if !=0 the urb setup header is not present*/
char data_flag; /*if !=0 no urb data is present*/
int64_t ts_sec;
int32_t ts_usec;
int32_t status;
- u_int32_t urb_len;
- u_int32_t data_len; /* amount of urb data really present in this event*/
+ uint32_t urb_len;
+ uint32_t data_len; /* amount of urb data really present in this event*/
pcap_usb_setup setup;
} pcap_usb_header;
@@ -100,27 +102,27 @@ typedef struct _usb_header {
* Appears at the front of each packet in DLT_USB_LINUX_MMAPPED captures.
*/
typedef struct _usb_header_mmapped {
- u_int64_t id;
- u_int8_t event_type;
- u_int8_t transfer_type;
- u_int8_t endpoint_number;
- u_int8_t device_address;
- u_int16_t bus_id;
+ uint64_t id;
+ uint8_t event_type;
+ uint8_t transfer_type;
+ uint8_t endpoint_number;
+ uint8_t device_address;
+ uint16_t bus_id;
char setup_flag;/*if !=0 the urb setup header is not present*/
char data_flag; /*if !=0 no urb data is present*/
int64_t ts_sec;
int32_t ts_usec;
int32_t status;
- u_int32_t urb_len;
- u_int32_t data_len; /* amount of urb data really present in this event*/
+ uint32_t urb_len;
+ uint32_t data_len; /* amount of urb data really present in this event*/
union {
pcap_usb_setup setup;
iso_rec iso;
} s;
int32_t interval; /* for Interrupt and Isochronous events */
int32_t start_frame; /* for Isochronous events */
- u_int32_t xfer_flags; /* copy of URB's transfer flags */
- u_int32_t ndesc; /* number of isochronous descriptors */
+ uint32_t xfer_flags; /* copy of URB's transfer flags */
+ uint32_t ndesc; /* number of isochronous descriptors */
} pcap_usb_header_mmapped;
/*
@@ -133,9 +135,9 @@ typedef struct _usb_header_mmapped {
*/
typedef struct _usb_isodesc {
int32_t status;
- u_int32_t offset;
- u_int32_t len;
- u_int8_t pad[4];
+ uint32_t offset;
+ uint32_t len;
+ uint8_t pad[4];
} usb_isodesc;
#endif
diff --git a/contrib/libpcap/pcap/vlan.h b/contrib/libpcap/pcap/vlan.h
index 021f612907f85..b29dd73cd3acc 100644
--- a/contrib/libpcap/pcap/vlan.h
+++ b/contrib/libpcap/pcap/vlan.h
@@ -34,9 +34,11 @@
#ifndef lib_pcap_vlan_h
#define lib_pcap_vlan_h
+#include <pcap/pcap-inttypes.h>
+
struct vlan_tag {
- u_int16_t vlan_tpid; /* ETH_P_8021Q */
- u_int16_t vlan_tci; /* VLAN TCI */
+ uint16_t vlan_tpid; /* ETH_P_8021Q */
+ uint16_t vlan_tci; /* VLAN TCI */
};
#define VLAN_TAG_LEN 4
diff --git a/contrib/libpcap/pcap_breakloop.3pcap b/contrib/libpcap/pcap_breakloop.3pcap
index 3f9327b198ef1..4818c70fc365b 100644
--- a/contrib/libpcap/pcap_breakloop.3pcap
+++ b/contrib/libpcap/pcap_breakloop.3pcap
@@ -62,9 +62,21 @@ packets arrive and the call completes.
Note also that, in a multi-threaded application, if one thread is
blocked in pcap_dispatch(), pcap_loop(), pcap_next(), or pcap_next_ex(),
a call to pcap_breakloop() in a different thread will not unblock that
-thread; you will need to use whatever mechanism the OS provides for
+thread.
+.ft R
+You will need to use whatever mechanism the OS provides for
breaking a thread out of blocking calls in order to unblock the thread,
-such as thread cancellation in systems that support POSIX threads.
+such as thread cancellation or thread signalling in systems that support
+POSIX threads, or
+.B SetEvent()
+on the result of
+.B pcap_getevent()
+on a
+.B pcap_t
+on which the thread is blocked on Windows. Asynchronous procedure calls
+will not work on Windows, as a thread blocked on a
+.B pcap_t
+will not be in an alertable state.
.ft R
.PP
Note that
diff --git a/contrib/libpcap/pcap_compile.3pcap b/contrib/libpcap/pcap_compile.3pcap
deleted file mode 100644
index b64882bdb01d3..0000000000000
--- a/contrib/libpcap/pcap_compile.3pcap
+++ /dev/null
@@ -1,70 +0,0 @@
-.\" Copyright (c) 1994, 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: (1) source code distributions
-.\" retain the above copyright notice and this paragraph in its entirety, (2)
-.\" distributions including binary code include the above copyright notice and
-.\" this paragraph in its entirety in the documentation or other materials
-.\" provided with the distribution, and (3) all advertising materials mentioning
-.\" features or use of this software display the following acknowledgement:
-.\" ``This product includes software developed by the University of California,
-.\" Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
-.\" the University nor the names of its contributors may be used to endorse
-.\" or promote products derived from this software without specific prior
-.\" written permission.
-.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
-.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
-.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
-.\"
-.TH PCAP_COMPILE 3PCAP "1 December 2009"
-.SH NAME
-pcap_compile \- compile a filter expression
-.SH SYNOPSIS
-.nf
-.ft B
-#include <pcap/pcap.h>
-.ft
-.LP
-.ft B
-int pcap_compile(pcap_t *p, struct bpf_program *fp,
-.ti +8
-const char *str, int optimize, bpf_u_int32 netmask);
-.ft
-.fi
-.SH DESCRIPTION
-.B pcap_compile()
-is used to compile the string
-.I str
-into a filter program. See
-.BR pcap-filter (7)
-for the syntax of that string.
-.I program
-is a pointer to a
-.I bpf_program
-struct and is filled in by
-.BR pcap_compile() .
-.I optimize
-controls whether optimization on the resulting code is performed.
-.I netmask
-specifies the IPv4 netmask of the network on which packets are being
-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
-for IPv4 broadcast addresses will fail to compile, but all other tests in
-the filter program will be OK.
-.SH RETURN VALUE
-.B pcap_compile()
-returns 0 on success and \-1 on failure.
-If \-1 is returned,
-.B pcap_geterr()
-or
-.B pcap_perror()
-may be called with
-.I p
-as an argument to fetch or display the error text.
-.SH SEE ALSO
-pcap(3PCAP), pcap_setfilter(3PCAP), pcap_freecode(3PCAP),
-pcap_geterr(3PCAP), pcap-filter(7)
diff --git a/contrib/libpcap/pcap_compile.3pcap.in b/contrib/libpcap/pcap_compile.3pcap.in
index 2bd0eb4694403..9abeed82f251c 100644
--- a/contrib/libpcap/pcap_compile.3pcap.in
+++ b/contrib/libpcap/pcap_compile.3pcap.in
@@ -55,6 +55,16 @@ 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
for IPv4 broadcast addresses will fail to compile, but all other tests in
the filter program will be OK.
+.LP
+NOTE: in libpcap 1.8.0 and later,
+.B pcap_compile()
+can be used in multiple threads within a single process. However, in
+earlier versions of libpcap, it is
+.I not
+safe to use
+.B pcap_compile()
+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.
diff --git a/contrib/libpcap/pcap_datalink.3pcap b/contrib/libpcap/pcap_datalink.3pcap
deleted file mode 100644
index 8b3c828c73b77..0000000000000
--- a/contrib/libpcap/pcap_datalink.3pcap
+++ /dev/null
@@ -1,68 +0,0 @@
-.\" Copyright (c) 1994, 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: (1) source code distributions
-.\" retain the above copyright notice and this paragraph in its entirety, (2)
-.\" distributions including binary code include the above copyright notice and
-.\" this paragraph in its entirety in the documentation or other materials
-.\" provided with the distribution, and (3) all advertising materials mentioning
-.\" features or use of this software display the following acknowledgement:
-.\" ``This product includes software developed by the University of California,
-.\" Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
-.\" the University nor the names of its contributors may be used to endorse
-.\" or promote products derived from this software without specific prior
-.\" written permission.
-.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
-.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
-.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
-.\"
-.TH PCAP_DATALINK 3PCAP "13 October 2013"
-.SH NAME
-pcap_datalink \- get the link-layer header type
-.SH SYNOPSIS
-.nf
-.ft B
-#include <pcap/pcap.h>
-.ft
-.LP
-.ft B
-int pcap_datalink(pcap_t *p);
-.ft
-.fi
-.SH DESCRIPTION
-.B pcap_datalink()
-returns the link-layer header type for the live capture or ``savefile''
-specified by
-.IR p .
-.PP
-It must not be called on a pcap descriptor created by
-.B pcap_create()
-that has not yet been activated by
-.BR pcap_activate() .
-.PP
-.I http://www.tcpdump.org/linktypes.html
-lists the values
-.B pcap_datalink()
-can return and describes the packet formats that
-correspond to those values.
-.PP
-Do
-.B NOT
-assume that the packets for a given capture or ``savefile`` will have
-any given link-layer header type, such as
-.B DLT_EN10MB
-for Ethernet. For example, the "any" device on Linux will have a
-link-layer header type of
-.B DLT_LINUX_SLL
-even if all devices on the system at the time the "any" device is opened
-have some other data link type, such as
-.B DLT_EN10MB
-for Ethernet.
-.SH RETURN VALUE
-.B pcap_datalink()
-returns the link-layer header type on success and
-.B PCAP_ERROR_NOT_ACTIVATED
-if called on a capture handle that has been created but not activated.
-.SH SEE ALSO
-pcap(3PCAP), pcap-linktype(7)
diff --git a/contrib/libpcap/pcap_dump_ftell.3pcap b/contrib/libpcap/pcap_dump_ftell.3pcap
index 757e9482bafd6..01dbc64c7230c 100644
--- a/contrib/libpcap/pcap_dump_ftell.3pcap
+++ b/contrib/libpcap/pcap_dump_ftell.3pcap
@@ -19,7 +19,7 @@
.\"
.TH PCAP_DUMP_FTELL 3PCAP "3 January 2014"
.SH NAME
-pcap_dump_ftell \- get the current file offset for a savefile being written
+pcap_dump_ftell, pcap_dump_ftell64 \- get the current file offset for a savefile being written
.SH SYNOPSIS
.nf
.ft B
@@ -28,6 +28,8 @@ pcap_dump_ftell \- get the current file offset for a savefile being written
.LP
.ft B
long pcap_dump_ftell(pcap_dumper_t *p);
+.ft B
+int64_t pcap_dump_ftell64(pcap_dumper_t *p);
.ft
.fi
.SH DESCRIPTION
@@ -38,5 +40,18 @@ number of bytes written by
and
.BR pcap_dump() .
\-1 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.
+.B pcap_dump_ftell64()
+returns the current file position in a
+.BR int64_t ,
+so if file offsets that don't fit in a
+.B long
+but that fit in a
+.B int64_t
+are supported, this will return the file offset without truncation.
+\-1 is returned on error.
.SH SEE ALSO
pcap(3PCAP), pcap_dump_open(3PCAP), pcap_dump(3PCAP)
diff --git a/contrib/libpcap/pcap_dump_open.3pcap b/contrib/libpcap/pcap_dump_open.3pcap
deleted file mode 100644
index 4d32665368830..0000000000000
--- a/contrib/libpcap/pcap_dump_open.3pcap
+++ /dev/null
@@ -1,85 +0,0 @@
-.\" Copyright (c) 1994, 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: (1) source code distributions
-.\" retain the above copyright notice and this paragraph in its entirety, (2)
-.\" distributions including binary code include the above copyright notice and
-.\" this paragraph in its entirety in the documentation or other materials
-.\" provided with the distribution, and (3) all advertising materials mentioning
-.\" features or use of this software display the following acknowledgement:
-.\" ``This product includes software developed by the University of California,
-.\" Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
-.\" the University nor the names of its contributors may be used to endorse
-.\" or promote products derived from this software without specific prior
-.\" written permission.
-.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
-.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
-.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
-.\"
-.TH PCAP_DUMP_OPEN 3PCAP "5 April 2008"
-.SH NAME
-pcap_dump_open, pcap_dump_fopen \- open a file to which to write packets
-.SH SYNOPSIS
-.nf
-.ft B
-#include <pcap/pcap.h>
-.ft
-.nf
-.LP
-.ft B
-pcap_dumper_t *pcap_dump_open(pcap_t *p, const char *fname);
-pcap_dumper_t *pcap_dump_fopen(pcap_t *p, FILE *fp);
-.ft
-.fi
-.SH DESCRIPTION
-.B pcap_dump_open()
-is called to open a ``savefile'' for writing.
-.I fname
-specifies the name of the file to open. The file will have
-the same format as those used by
-.BR tcpdump (1)
-and
-.BR tcpslice (1).
-The name "-" is a synonym
-for
-.BR stdout .
-.PP
-.B pcap_dump_fopen()
-is called to write data to an existing open stream
-.IR fp .
-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()
-and activated by an earlier call to
-.BR pcap_activate() ,
-or returned by an earlier call to
-.BR pcap_open_offline() ,
-.BR pcap_open_live() ,
-or
-.BR pcap_open_dead() .
-The link-layer type and snapshot length from
-.I p
-are used as the link-layer type and snapshot length of the output file.
-.SH RETURN VALUES
-A pointer to a
-.B pcap_dumper_t
-structure to use in subsequent
-.B pcap_dump()
-and
-.B pcap_dump_close()
-calls is returned on success.
-.B NULL
-is returned on failure.
-If
-.B NULL
-is returned,
-.B pcap_geterr(\fIp\fB)
-can be used to get the error text.
-.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-savefile(5)
diff --git a/contrib/libpcap/pcap_dump_open.3pcap.in b/contrib/libpcap/pcap_dump_open.3pcap.in
index 3f91d13bf88a5..80d1a5c62c5de 100644
--- a/contrib/libpcap/pcap_dump_open.3pcap.in
+++ b/contrib/libpcap/pcap_dump_open.3pcap.in
@@ -91,6 +91,6 @@ is returned,
can be used to get the error text.
.SH SEE ALSO
pcap(3PCAP), pcap_create(3PCAP), pcap_activate(3PCAP),
-pcap_open_offline(3PCAP), pcap_open_live(3PCAP), pcap_open_dead(3PCAP),
+\%pcap_open_offline(3PCAP), pcap_open_live(3PCAP), pcap_open_dead(3PCAP),
pcap_dump(3PCAP), pcap_dump_close(3PCAP), pcap_geterr(3PCAP),
-pcap-savefile(@MAN_FILE_FORMATS@)
+\%pcap-savefile(@MAN_FILE_FORMATS@)
diff --git a/contrib/libpcap/pcap_fileno.3pcap b/contrib/libpcap/pcap_fileno.3pcap
index 7aeb06947b1be..e8c9ac4d4ac60 100644
--- a/contrib/libpcap/pcap_fileno.3pcap
+++ b/contrib/libpcap/pcap_fileno.3pcap
@@ -63,4 +63,4 @@ it returns \-1.
.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_fopen_offline(3PCAP), pcap_open_dead(3PCAP)
diff --git a/contrib/libpcap/pcap_findalldevs.3pcap b/contrib/libpcap/pcap_findalldevs.3pcap
index 2dd3e59b9c931..9523e008a69c3 100644
--- a/contrib/libpcap/pcap_findalldevs.3pcap
+++ b/contrib/libpcap/pcap_findalldevs.3pcap
@@ -98,6 +98,30 @@ set if the device is up
.TP
.B PCAP_IF_RUNNING
set if the device is running
+.TP
+.B PCAP_IF_WIRELESS
+set if the device is a wireless interface; this includes IrDA as well as
+radio-based networks such as IEEE 802.15.4 and IEEE 802.11, so it
+doesn't just mean Wi-Fi
+.TP
+.B PCAP_IF_CONNECTION_STATUS
+a bitmask for an indication of whether the adapter is connected or not;
+for wireless interfaces, "connected" means "associated with a network"
+.TP
+The possible values for the connection status bits are:
+.TP
+.B PCAP_IF_CONNECTION_STATUS_UNKNOWN
+it's unknown whether the adapter is connected or not
+.TP
+.B PCAP_IF_CONNECTION_STATUS_CONNECTED
+the adapter is connected
+.TP
+.B PCAP_IF_CONNECTION_STATUS_DISCONNECTED
+the adapter is disconnected
+.TP
+.B PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE
+the notion of "connected" and "disconnected" don't apply to this
+interface; for example, it doesn't apply to a loopback device
.RE
.RE
.PP
diff --git a/contrib/libpcap/pcap_get_required_select_timeout.3pcap b/contrib/libpcap/pcap_get_required_select_timeout.3pcap
new file mode 100644
index 0000000000000..09b393484deef
--- /dev/null
+++ b/contrib/libpcap/pcap_get_required_select_timeout.3pcap
@@ -0,0 +1,84 @@
+.\" Copyright (c) 1994, 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: (1) source code distributions
+.\" retain the above copyright notice and this paragraph in its entirety, (2)
+.\" distributions including binary code include the above copyright notice and
+.\" this paragraph in its entirety in the documentation or other materials
+.\" provided with the distribution, and (3) all advertising materials mentioning
+.\" features or use of this software display the following acknowledgement:
+.\" ``This product includes software developed by the University of California,
+.\" Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+.\" the University nor the names of its contributors may be used to endorse
+.\" or promote products derived from this software without specific prior
+.\" written permission.
+.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+.\"
+.TH PCAP_GET_REQUIRED_SELECT_TIMEOUT 3PCAP "19 January 2018"
+.SH NAME
+pcap_get_required_select_timeout \- get a file descriptor on which a
+select() can be done for a live capture
+.SH SYNOPSIS
+.nf
+.ft B
+#include <pcap/pcap.h>
+.ft
+.LP
+.ft B
+struct timeval *pcap_get_required_select_timeout(pcap_t *p);
+.ft
+.fi
+.SH DESCRIPTION
+.B pcap_get_required_select_timeout()
+returns, on UNIX, a pointer to a
+.B struct timeval
+containing a value that must be used as the minimum timeout in
+.BR select() ,
+.BR poll() ,
+.BR epoll_wait() ,
+and
+.B kevent()
+calls if
+.B pcap_get_selectable_fd()
+returns \-1.
+.PP
+The timeout that should be used in those calls must be no larger than
+the smallest of all timeouts returned by
+.B pcap_get_required_select_timeout()
+for devices from which packets will be captured.
+.PP
+The device for which
+.B pcap_get_selectable_fd()
+returned \-1 must be put in non-blocking mode with
+.BR pcap_setnonblock() ,
+and an attempt must always be made to read packets from the device
+when the
+.BR select() ,
+.BR poll() ,
+.BR epoll_wait() ,
+or
+.B kevent()
+call returns.
+.PP
+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()
+or
+.B pcap_next_ex()
+will return 0 in this case, but will not block.
+.PP
+.B pcap_get_required_select_timeout()
+is not available on Windows.
+.SH RETURN VALUE
+A pointer to a
+.B struct timeval
+is returned if the timeout is required; otherwise
+.B NULL
+is returned.
+.SH SEE ALSO
+pcap(3PCAP), pcap_get_selectable_fd(3PCAP), select(2), poll(2),
+epoll_wait(2), kqueue(2)
diff --git a/contrib/libpcap/pcap_get_selectable_fd.3pcap b/contrib/libpcap/pcap_get_selectable_fd.3pcap
index 86b0c2683fa36..160a23f7dacab 100644
--- a/contrib/libpcap/pcap_get_selectable_fd.3pcap
+++ b/contrib/libpcap/pcap_get_selectable_fd.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 "18 October 2014"
+.TH PCAP_GET_SELECTABLE_FD 3PCAP "20 January 2017"
.SH NAME
pcap_get_selectable_fd \- get a file descriptor on which a select() can
be done for a live capture
@@ -38,26 +38,41 @@ which one can
do a
.BR select() ,
.BR poll() ,
+.BR epoll_wait() ,
+.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. Some network
-devices opened with
+a descriptor exists, or \-1, if no such descriptor exists.
+.PP
+Some network devices opened with
.B pcap_create()
and
.BR pcap_activate() ,
or with
.BR pcap_open_live() ,
-do not support
-.B select()
-or
-.B poll()
-(for example, regular network devices on FreeBSD 4.3 and 4.4, and Endace
-DAG devices), so \-1 is returned for those devices.
+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
+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()
+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() ,
+and an attempt must always be made to read packets from the device
+when the call returns. If
+.B pcap_get_required_select_timeout()
+returns
+.BR NULL ,
+it is not possible to wait for packets to arrive on the device in an
+event loop.
.PP
-Note that a descriptor on which a read can be done without blocking may,
-on some platforms, not have any packets to read if the read timeout has
-expired. A call to
+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()
+or
+.B pcap_next_ex()
will return 0 in this case, but will not block.
.PP
Note that in:
@@ -70,59 +85,55 @@ OpenBSD prior to OpenBSD 2.4;
.IP
Mac OS X prior to Mac OS X 10.7;
.PP
-.B select()
+.BR select() ,
+.BR poll() ,
and
-.B poll()
+.B kevent()
do not work correctly on BPF devices;
.B pcap_get_selectable_fd()
will return a file descriptor on most of those versions (the exceptions
being FreeBSD 4.3 and 4.4), but a simple
-.B select()
-or
-.B poll()
-will not indicate that the descriptor is readable until a full buffer's
-worth of packets is received, even if the read timeout expires before
-then. To work around this, an application that uses
-.B select()
+.BR select() ,
+.BR poll() ,
or
-.B poll()
-to wait for packets to arrive must put the
+.B kevent()
+call will not indicate that the descriptor is readable until a full
+buffer's worth of packets is received, even if the packet timeout
+expires before then. To work around this, code that uses
+those calls to wait for packets to arrive must put the
.B pcap_t
-in non-blocking mode, and must arrange that the
-.B select()
-or
-.B poll()
-have a timeout less than or equal to the read timeout,
+in non-blocking mode, and must arrange that the call
+have a timeout less than or equal to the packet buffer timeout,
and must try to read packets after that timeout expires, regardless of
-whether
-.B select()
-or
-.B poll()
-indicated that the file descriptor for the
+whether the call indicated that the file descriptor for the
.B pcap_t
is ready to be read or not. (That workaround will not work in FreeBSD
-4.3 and later; however, in FreeBSD 4.6 and later,
-.B select()
-and
-.B poll()
+4.3 and later; however, in FreeBSD 4.6 and later, those calls
work correctly on BPF devices, so the workaround isn't necessary,
although it does no harm.)
.PP
Note also that
.B poll()
+and
+.B kevent()
doesn't work on character special files, including BPF devices, in Mac
OS X 10.4 and 10.5, so, while
.B select()
can be used on the descriptor returned by
.BR pcap_get_selectable_fd() ,
.B poll()
-cannot be used on it those versions of Mac OS X. Kqueues also don't
-work on that descriptor.
+and
+.B kevent()
+cannot be used on it those versions of Mac OS X.
.BR poll() ,
-but not kqueues, work on that descriptor in Mac OS X releases prior to
+but not
+.BR kevent() ,
+works on that descriptor in Mac OS X releases prior to
10.4;
.B poll()
-and kqueues work on that descriptor in Mac OS X 10.6 and later.
+and
+.B kevent()
+work on that descriptor in Mac OS X 10.6 and later.
.PP
.B pcap_get_selectable_fd()
is not available on Windows.
@@ -130,4 +141,5 @@ is not available on Windows.
A selectable file descriptor is returned if one exists; otherwise, \-1
is returned.
.SH SEE ALSO
-pcap(3PCAP), select(2), poll(2)
+pcap(3PCAP), pcap_get_required_select_timeout(3PCAP),
+pcap_setnonblock(3PCAP), select(2), poll(2), epoll_wait(2), kqueue(2)
diff --git a/contrib/libpcap/pcap_get_tstamp_precision.3pcap b/contrib/libpcap/pcap_get_tstamp_precision.3pcap
deleted file mode 100644
index dc633fad9bf0b..0000000000000
--- a/contrib/libpcap/pcap_get_tstamp_precision.3pcap
+++ /dev/null
@@ -1,52 +0,0 @@
-.\"Copyright (c) 2013, Michal Sekletar
-.\"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. The names of the authors may not be used to endorse or promote
-.\" products derived from this software without specific prior
-.\" written permission.
-.\"
-.\"THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
-.\"IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
-.\"WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
-
-.TH PCAP_GET_TSTAMP_PRECISION 3PCAP "27 August 2013"
-.SH NAME
-pcap_get_tstamp_precision \- get the time stamp precision returned in
-captures
-.SH SYNOPSIS
-.nf
-.ft B
-#include <pcap/pcap.h>
-.ft
-.LP
-.ft B
-int pcap_get_tstamp_precision(pcap_t *p);
-.ft
-.fi
-.SH DESCRIPTION
-.B pcap_get_tstamp_precision()
-returns the precision of the time stamp returned in packet captures on the pcap
-descriptor.
-.SH RETURN VALUE
-.B pcap_get_tstamp_precision()
-returns
-.B PCAP_TSTAMP_PRECISION_MICRO
-or
-.BR PCAP_TSTAMP_PRECISION_NANO ,
-which indicates
-that pcap captures contains time stamps in microseconds or nanoseconds
-respectively.
-.SH SEE ALSO
-pcap(3PCAP),
-pcap_set_tstamp_precision(3PCAP),
-pcap-tstamp(7)
diff --git a/contrib/libpcap/pcap_list_datalinks.3pcap b/contrib/libpcap/pcap_list_datalinks.3pcap
deleted file mode 100644
index 3c9a170713686..0000000000000
--- a/contrib/libpcap/pcap_list_datalinks.3pcap
+++ /dev/null
@@ -1,73 +0,0 @@
-.\" Copyright (c) 1994, 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: (1) source code distributions
-.\" retain the above copyright notice and this paragraph in its entirety, (2)
-.\" distributions including binary code include the above copyright notice and
-.\" this paragraph in its entirety in the documentation or other materials
-.\" provided with the distribution, and (3) all advertising materials mentioning
-.\" features or use of this software display the following acknowledgement:
-.\" ``This product includes software developed by the University of California,
-.\" Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
-.\" the University nor the names of its contributors may be used to endorse
-.\" or promote products derived from this software without specific prior
-.\" written permission.
-.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
-.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
-.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
-.\"
-.TH PCAP_LIST_DATALINKS 3PCAP "17 September 2013"
-.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
-.SH SYNOPSIS
-.nf
-.ft B
-#include <pcap/pcap.h>
-.ft
-.LP
-.ft B
-int pcap_list_datalinks(pcap_t *p, int **dlt_buf);
-void pcap_free_datalinks(int *dlt_list);
-.ft
-.fi
-.SH DESCRIPTION
-.B pcap_list_datalinks()
-is used to get a list of the supported link-layer header types of the
-interface associated with the pcap descriptor.
-.B pcap_list_datalinks()
-allocates an array to hold the list and sets
-.IR *dlt_buf
-to point to that array.
-.LP
-The caller is responsible for freeing the array with
-.BR pcap_free_datalinks() ,
-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()
-that has not yet been activated by
-.BR pcap_activate() .
-.SH RETURN VALUE
-.B pcap_list_datalinks()
-returns the number of link-layer header types in the array on success,
-.B PCAP_ERROR_NOT_ACTIVATED
-if called on a capture handle that has been created but not activated,
-and
-.B PCAP_ERROR
-(\-1) on other errors.
-If
-.B PCAP_ERROR
-is returned,
-.B pcap_geterr()
-or
-.B pcap_perror()
-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_datalink_val_to_name(3PCAP),
-pcap-linktype(7)
diff --git a/contrib/libpcap/pcap_list_tstamp_types.3pcap b/contrib/libpcap/pcap_list_tstamp_types.3pcap
deleted file mode 100644
index 6d1f16f1d307b..0000000000000
--- a/contrib/libpcap/pcap_list_tstamp_types.3pcap
+++ /dev/null
@@ -1,70 +0,0 @@
-.\"
-.\" Copyright (c) 1994, 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: (1) source code distributions
-.\" retain the above copyright notice and this paragraph in its entirety, (2)
-.\" distributions including binary code include the above copyright notice and
-.\" this paragraph in its entirety in the documentation or other materials
-.\" provided with the distribution, and (3) all advertising materials mentioning
-.\" features or use of this software display the following acknowledgement:
-.\" ``This product includes software developed by the University of California,
-.\" Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
-.\" the University nor the names of its contributors may be used to endorse
-.\" or promote products derived from this software without specific prior
-.\" written permission.
-.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
-.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
-.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
-.\"
-.TH PCAP_LIST_TSTAMP_TYPES 3PCAP "21 August 2010"
-.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
-.SH SYNOPSIS
-.nf
-.ft B
-#include <pcap/pcap.h>
-.ft
-.LP
-.ft B
-int pcap_list_tstamp_types(pcap_t *p, int **tstamp_typesp);
-void pcap_free_tstamp_types(int *tstamp_types);
-.ft
-.fi
-.SH DESCRIPTION
-.B pcap_list_tstamp_types()
-is used to get a list of the supported time stamp types of the interface
-associated with the pcap descriptor.
-.B pcap_list_tstamp_types()
-allocates an array to hold the list and sets
-.I *tstamp_typesp
-to point to the array.
-See
-.BR pcap-tstamp (7)
-for a list of all the time stamp types.
-.PP
-The caller is responsible for freeing the array with
-.BR pcap_free_tstamp_types() ,
-which frees the list pointed to by
-.IR tstamp_types .
-.SH RETURN VALUE
-.B pcap_list_tstamp_types()
-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.
-If
-.B PCAP_ERROR
-is returned,
-.B pcap_geterr()
-or
-.B pcap_perror()
-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_tstamp_type_val_to_name(3PCAP),
-pcap-tstamp(7)
diff --git a/contrib/libpcap/pcap_lookupdev.3pcap b/contrib/libpcap/pcap_lookupdev.3pcap
index aaa3a2013aa78..45c4ef8bfb70a 100644
--- a/contrib/libpcap/pcap_lookupdev.3pcap
+++ b/contrib/libpcap/pcap_lookupdev.3pcap
@@ -32,10 +32,18 @@ char errbuf[PCAP_ERRBUF_SIZE];
.ft
.LP
.ft B
-char *pcap_lookupdev(char *errbuf);
+[DEPRECATED] char *pcap_lookupdev(char *errbuf);
.ft
.fi
.SH DESCRIPTION
+.B This interface is obsoleted by
+.BR pcap_findalldevs (3PCAP).
+To find a default device on which to capture, call
+.B pcap_findalldevs()
+and, if the list it returns is not empty, use the first device in the
+list. (If the list is empty, there are no devices on which capture is
+possible.)
+.LP
.B pcap_lookupdev()
returns a pointer to a string giving the name of a network device
suitable for use with
@@ -58,3 +66,15 @@ chars.
.SH SEE ALSO
pcap(3PCAP), pcap_create(3PCAP), pcap_activate(3PCAP),
pcap_open_live(3PCAP), pcap_lookupnet(3PCAP)
+.SH BUGS
+The pointer returned by
+.B pcap_lookupdev()
+points to a static buffer; subsequent calls to
+.B pcap_lookupdev()
+in the same thread, or calls to
+.B pcap_lookupdev()
+in another thread, may overwrite that buffer.
+.LP
+In WinPcap, this function may return a UTF-16 string rather than an
+ASCII or UTF-8 string.
+
diff --git a/contrib/libpcap/pcap_loop.3pcap b/contrib/libpcap/pcap_loop.3pcap
index 0eaf6e5e598c4..15ad41012b407 100644
--- a/contrib/libpcap/pcap_loop.3pcap
+++ b/contrib/libpcap/pcap_loop.3pcap
@@ -17,7 +17,7 @@
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\"
-.TH PCAP_LOOP 3PCAP "18 October 2014"
+.TH PCAP_LOOP 3PCAP "20 January 2017"
.SH NAME
pcap_loop, pcap_dispatch \- process packets from a live capture or savefile
.SH SYNOPSIS
@@ -51,7 +51,7 @@ reached when reading from a ``savefile'',
is called, or an error occurs.
It does
.B not
-return when live read timeouts occur.
+return when live packet buffer timeouts occur.
A value of \-1 or 0 for
.I cnt
is equivalent to infinity, so that packets are processed until another
@@ -166,18 +166,18 @@ terminated due to a call to
before any packets were processed.
It does
.B not
-return when live read timeouts occur; instead, it attempts to read more
-packets.
+return when live packet buffer timeouts occur; instead, it attempts to
+read more packets.
.PP
.B pcap_dispatch()
returns the number of packets processed on success; this can be 0 if no
packets were read from a live capture (if, for example, they were
discarded because they didn't pass the packet filter, or if, on
-platforms that support a read 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
+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
.B pcap_breakloop()
before any packets were processed.
diff --git a/contrib/libpcap/pcap_major_version.3pcap b/contrib/libpcap/pcap_major_version.3pcap
index 8334e16c34c65..0793063f886e4 100644
--- a/contrib/libpcap/pcap_major_version.3pcap
+++ b/contrib/libpcap/pcap_major_version.3pcap
@@ -41,7 +41,7 @@ returns the major number of the file format of the ``savefile'' and
returns the minor number of the file format of the ``savefile''. The
version number is stored in the ``savefile''; note that the meaning of
its values depends on the type of ``savefile'' (for example, pcap or
-pcap-NG).
+pcapng).
.PP
If
.I p
diff --git a/contrib/libpcap/pcap_next_ex.3pcap b/contrib/libpcap/pcap_next_ex.3pcap
index d69e7283d826a..f975ccfd0516d 100644
--- a/contrib/libpcap/pcap_next_ex.3pcap
+++ b/contrib/libpcap/pcap_next_ex.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 "7 April 2014"
+.TH PCAP_NEXT_EX 3PCAP "20 January 2017"
.SH NAME
pcap_next_ex, pcap_next \- read the next packet from a pcap_t
.SH SYNOPSIS
@@ -112,12 +112,11 @@ have some other data link type, such as
for Ethernet.
.SH RETURN VALUE
.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 timeout expired,
-\-1 if an error occurred while reading the packet, and \-2 if
-packets are being read from a ``savefile'' and there are no more
-packets to read from the savefile.
-If \-1 is returned,
+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
+are being read from a ``savefile'' and there are no more packets to read
+from the savefile. If \-1 is returned,
.B pcap_geterr()
or
.B pcap_perror()
@@ -128,14 +127,14 @@ as an argument to fetch or display the error text.
.B pcap_next()
returns a pointer to the packet data on success, and returns
.B NULL
-if an error occurred, or if no packets were read from a live
-capture (if, for example, they were discarded because they didn't pass
-the packet filter, or if, on platforms that support a read 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
+if an error occurred, or if no packets were read from a live capture
+(if, for example, they were discarded because they didn't pass the
+packet filter, or if, on platforms that support a packet buffer timeout
+that starts before any packets arrive, the timeout expires before any
+packets arrive, or if the file descriptor for the capture device is in
non-blocking mode and no packets were available to be read), or if no
-more packets are available in a ``savefile.'' Unfortunately, there is
-no way to determine whether an error occurred or not.
+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)
diff --git a/contrib/libpcap/pcap_open_dead.3pcap b/contrib/libpcap/pcap_open_dead.3pcap
deleted file mode 100644
index 8fb2a3d6dcf4b..0000000000000
--- a/contrib/libpcap/pcap_open_dead.3pcap
+++ /dev/null
@@ -1,79 +0,0 @@
-.\" Copyright (c) 1994, 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: (1) source code distributions
-.\" retain the above copyright notice and this paragraph in its entirety, (2)
-.\" distributions including binary code include the above copyright notice and
-.\" this paragraph in its entirety in the documentation or other materials
-.\" provided with the distribution, and (3) all advertising materials mentioning
-.\" features or use of this software display the following acknowledgement:
-.\" ``This product includes software developed by the University of California,
-.\" Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
-.\" the University nor the names of its contributors may be used to endorse
-.\" or promote products derived from this software without specific prior
-.\" written permission.
-.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
-.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
-.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
-.\"
-.TH PCAP_OPEN_DEAD 3PCAP "1 July 2013"
-.SH NAME
-pcap_open_dead, pcap_open_dead_with_tstamp_precision \- open a fake
-pcap_t for compiling filters or opening a capture for output
-.SH SYNOPSIS
-.nf
-.ft B
-#include <pcap/pcap.h>
-.ft
-.LP
-.ft B
-pcap_t *pcap_open_dead(int linktype, int snaplen);
-pcap_t *pcap_open_dead_with_tstamp_precision(int linktype, int snaplen,
- u_int precision);
-.ft
-.fi
-.SH DESCRIPTION
-.PP
-.B pcap_open_dead()
-and
-.B pcap_open_dead_with_tstamp_precision()
-are used for creating a
-.B pcap_t
-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() ,
-and
-.B pcap_dump_close()
-to write a savefile if there is no
-.B pcap_t
-that supplies the packets to be written.
-.PP
-.I linktype
-specifies the link-layer type for the
-.BR pcap_t .
-.PP
-.I snaplen
-specifies the snapshot length for the
-.BR pcap_t .
-.PP
-When
-.BR pcap_open_dead_with_tstamp_precision() ,
-is used to create a
-.B pcap_t
-for use with
-.BR pcap_dump_open() ,
-.I precision
-specifies the time stamp precision for packets;
-.B PCAP_TSTAMP_PRECISION_MICRO
-should be specified if the packets to be written have time stamps in
-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() .
-.SH SEE ALSO
-pcap(3PCAP), pcap_compile(3PCAP), pcap_dump_open(3PCAP),
-pcap-linktype(7)
diff --git a/contrib/libpcap/pcap_open_dead.3pcap.in b/contrib/libpcap/pcap_open_dead.3pcap.in
index a3dc5921074bd..621e75b5b58a1 100644
--- a/contrib/libpcap/pcap_open_dead.3pcap.in
+++ b/contrib/libpcap/pcap_open_dead.3pcap.in
@@ -76,4 +76,4 @@ seconds and nanoseconds. Its value does not affect
.BR pcap_compile() .
.SH SEE ALSO
pcap(3PCAP), pcap_compile(3PCAP), pcap_dump_open(3PCAP),
-pcap-linktype(@MAN_MISC_INFO@)
+\%pcap-linktype(@MAN_MISC_INFO@)
diff --git a/contrib/libpcap/pcap_open_live.3pcap b/contrib/libpcap/pcap_open_live.3pcap
index 8c5d47469b6a4..d9ce8eec14468 100644
--- a/contrib/libpcap/pcap_open_live.3pcap
+++ b/contrib/libpcap/pcap_open_live.3pcap
@@ -17,7 +17,7 @@
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\"
-.TH PCAP_OPEN_LIVE 3PCAP "3 January 2014"
+.TH PCAP_OPEN_LIVE 3PCAP "20 January 2017"
.SH NAME
pcap_open_live \- open a device for capturing
.SH SYNOPSIS
@@ -56,7 +56,10 @@ specifies the snapshot length to be set on the handle.
specifies if the interface is to be put into promiscuous mode.
.PP
.I to_ms
-specifies the read timeout in milliseconds.
+specifies the packet buffer timeout, as a non-negative value, in
+milliseconds. (See
+.BR pcap (3PCAP)
+for an explanation of the packet buffer timeout.)
.SH RETURN VALUE
.B pcap_open_live()
returns a
diff --git a/contrib/libpcap/pcap_open_offline.3pcap b/contrib/libpcap/pcap_open_offline.3pcap
deleted file mode 100644
index 02fc611e8c890..0000000000000
--- a/contrib/libpcap/pcap_open_offline.3pcap
+++ /dev/null
@@ -1,109 +0,0 @@
-.\" Copyright (c) 1994, 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: (1) source code distributions
-.\" retain the above copyright notice and this paragraph in its entirety, (2)
-.\" distributions including binary code include the above copyright notice and
-.\" this paragraph in its entirety in the documentation or other materials
-.\" provided with the distribution, and (3) all advertising materials mentioning
-.\" features or use of this software display the following acknowledgement:
-.\" ``This product includes software developed by the University of California,
-.\" Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
-.\" the University nor the names of its contributors may be used to endorse
-.\" or promote products derived from this software without specific prior
-.\" written permission.
-.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
-.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
-.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
-.\"
-.TH PCAP_OPEN_OFFLINE 3PCAP "1 July 2013"
-.SH NAME
-pcap_open_offline, pcap_open_offline_with_tstamp_precision,
-pcap_fopen_offline, pcap_fopen_offline_with_tstamp_precision \- open a saved capture file for reading
-.SH SYNOPSIS
-.nf
-.ft B
-#include <pcap/pcap.h>
-.ft
-.LP
-.nf
-.ft B
-char errbuf[PCAP_ERRBUF_SIZE];
-.ft
-.LP
-.ft B
-pcap_t *pcap_open_offline(const char *fname, char *errbuf);
-pcap_t *pcap_open_offline_with_tstamp_precision(const char *fname,
- u_int precision, char *errbuf);
-pcap_t *pcap_fopen_offline(FILE *fp, char *errbuf);
-pcap_t *pcap_fopen_offline_with_tstamp_precision(FILE *fp,
- u_int precision, char *errbuf);
-.ft
-.fi
-.SH DESCRIPTION
-.B pcap_open_offline()
-and
-.B pcap_open_offline_with_tstamp_precision()
-are called to open a ``savefile'' for reading.
-.PP
-.I fname
-specifies the name of the file to open. The file can have the pcap file
-format as described in
-.BR pcap-savefile (5),
-which is the file format used by, among other programs,
-.BR tcpdump (1)
-and
-.BR tcpslice (1),
-or can have the pcap-ng file format, although not all pcap-ng files can
-be read.
-The name "-" is a synonym for
-.BR stdin .
-.PP
-.B pcap_open_offline_with_tstamp_precision()
-takes an additional
-.I precision
-argument specifying the time stamp precision desired;
-if
-.B PCAP_TSTAMP_PRECISION_MICRO
-is specified, packet time stamps will be supplied in seconds and
-microseconds,
-and if
-.B PCAP_TSTAMP_PRECISION_NANO
-is specified, packet time stamps will be supplied in seconds and
-nanoseconds. If the time stamps in the file do not have the same
-precision as the requested precision, they will be scaled up or down as
-necessary before being supplied.
-.PP
-Alternatively, you may call
-.B pcap_fopen_offline()
-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
-.I precision
-argument as described above.
-Note that on Windows, that stream should be opened in binary mode.
-.SH RETURN VALUE
-.BR pcap_open_offline() ,
-.BR pcap_open_offline_with_tstamp_precision() ,
-.BR pcap_fopen_offline() ,
-and
-.B pcap_fopen_offline_with_tstamp_precision()
-return a
-.I pcap_t *
-on success and
-.B NULL
-on failure.
-If
-.B NULL
-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 SEE ALSO
-pcap(3PCAP), pcap-savefile(5)
diff --git a/contrib/libpcap/pcap_open_offline.3pcap.in b/contrib/libpcap/pcap_open_offline.3pcap.in
index 7fe551eefa288..9bbffcee3b078 100644
--- a/contrib/libpcap/pcap_open_offline.3pcap.in
+++ b/contrib/libpcap/pcap_open_offline.3pcap.in
@@ -55,7 +55,7 @@ which is the file format used by, among other programs,
.BR tcpdump (1)
and
.BR tcpslice (1),
-or can have the pcap-ng file format, although not all pcap-ng files can
+or can have the pcapng file format, although not all pcapng files can
be read.
The name "-" is a synonym for
.BR stdin .
diff --git a/contrib/libpcap/pcap_set_protocol.3pcap b/contrib/libpcap/pcap_set_protocol.3pcap
new file mode 100644
index 0000000000000..9d4a23165312f
--- /dev/null
+++ b/contrib/libpcap/pcap_set_protocol.3pcap
@@ -0,0 +1,67 @@
+.\" Copyright (c) 1994, 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: (1) source code distributions
+.\" retain the above copyright notice and this paragraph in its entirety, (2)
+.\" distributions including binary code include the above copyright notice and
+.\" this paragraph in its entirety in the documentation or other materials
+.\" provided with the distribution, and (3) all advertising materials mentioning
+.\" features or use of this software display the following acknowledgement:
+.\" ``This product includes software developed by the University of California,
+.\" Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+.\" the University nor the names of its contributors may be used to endorse
+.\" or promote products derived from this software without specific prior
+.\" written permission.
+.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+.\"
+.TH PCAP_SET_PROTOCOL 3PCAP "3 January 2014"
+.SH NAME
+pcap_set_protocol \- set capture protocol for a not-yet-activated
+capture handle
+.SH SYNOPSIS
+.nf
+.ft B
+#include <pcap/pcap.h>
+.LP
+.ft B
+int pcap_set_protocol(pcap_t *p, int protocol);
+.ft
+.fi
+.SH DESCRIPTION
+On network interface devices on Linux,
+.B pcap_set_protocol()
+sets the protocol to be used in the
+.BR socket (2)
+call to create a capture socket when the handle is activated. The
+argument is a link-layer protocol value, such as the values in the
+.B <linux/if_ether.h>
+header file, specified in host byte order.
+If
+.I protocol
+is non-zero, packets of that protocol will be captured when the
+handle is activated, otherwise, all packets will be captured. This
+function is only provided on Linux, and, if it is used on any device
+other than a network interface, it will have no effect.
+.LP
+It should not be used in portable code; instead, a filter should be
+specified with
+.BR pcap_setfilter() .
+.LP
+If a given network interface provides a standard link-layer header, with
+a standard packet type, but provides some packet types with a different
+socket-layer protocol type from the one in the link-layer header, that
+packet type cannot be filtered with a filter specified with
+.B pcap_setfilter()
+but can be filtered by specifying the socket-layer protocol type using
+.BR pcap_set_protocol() .
+.SH RETURN VALUE
+.B pcap_set_protocol()
+returns 0 on success or
+.B PCAP_ERROR_ACTIVATED
+if called on a capture handle that has been activated.
+.SH SEE ALSO
+pcap(3PCAP), pcap_create(3PCAP), pcap_activate(3PCAP), socket(2),
+pcap_setfilter(3PCAP)
diff --git a/contrib/libpcap/pcap_set_timeout.3pcap b/contrib/libpcap/pcap_set_timeout.3pcap
index a89327f2ebd29..8cb8cb6487d8c 100644
--- a/contrib/libpcap/pcap_set_timeout.3pcap
+++ b/contrib/libpcap/pcap_set_timeout.3pcap
@@ -17,10 +17,10 @@
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\"
-.TH PCAP_SET_TIMEOUT 3PCAP "1 December 2015"
+.TH PCAP_SET_TIMEOUT 3PCAP "20 January 2017"
.SH NAME
-pcap_set_timeout \- set the read timeout for a not-yet-activated
-capture handle
+pcap_set_timeout \- set the packet buffer timeout for a
+not-yet-activated capture handle
.SH SYNOPSIS
.nf
.ft B
@@ -32,12 +32,15 @@ int pcap_set_timeout(pcap_t *p, int to_ms);
.fi
.SH DESCRIPTION
.B pcap_set_timeout()
-sets the read timeout that will be used on a capture handle when
-the handle is activated to
+sets the packet buffer timeout that will be used on a capture handle
+when the handle is activated to
.IR to_ms ,
-which is in units of milliseconds.
+which is in units of milliseconds. (See
+.BR pcap (3PCAP)
+for an explanation of the packet buffer timeout.)
.LP
-The behavior, if the timeout isn't specified, is undefined. We
+The behavior, if the timeout isn't specified, is undefined, as is the
+behavior if the timeout is set to zero or to a negative value. We
recommend always setting the timeout to a non-zero value unless
immediate mode is set, in which case the timeout has no effect.
.SH RETURN VALUE
@@ -47,4 +50,4 @@ returns 0 on success or
if called on a capture handle that has been activated.
.SH SEE ALSO
pcap(3PCAP), pcap_create(3PCAP), pcap_activate(3PCAP),
-pcap_set_immediate_mode(3PCAP)
+\%pcap_set_immediate_mode(3PCAP)
diff --git a/contrib/libpcap/pcap_set_tstamp_precision.3pcap b/contrib/libpcap/pcap_set_tstamp_precision.3pcap
deleted file mode 100644
index 4420cba4b9980..0000000000000
--- a/contrib/libpcap/pcap_set_tstamp_precision.3pcap
+++ /dev/null
@@ -1,61 +0,0 @@
-.\"Copyright (c) 2013, Michal Sekletar
-.\"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. The names of the authors may not be used to endorse or promote
-.\" products derived from this software without specific prior
-.\" written permission.
-.\"
-.\"THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
-.\"IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
-.\"WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
-
-.TH PCAP_SET_TSTAMP_PRECISION 3PCAP "27 August 2013"
-.SH NAME
-pcap_set_tstamp_precision \- set the time stamp precision returned in
-captures
-.SH SYNOPSIS
-.nf
-.ft B
-#include <pcap/pcap.h>
-.ft
-.LP
-.ft B
-int pcap_set_tstamp_precision(pcap_t *p, int tstamp_precision);
-.ft
-.fi
-.SH DESCRIPTION
-.B pcap_set_tstamp_precision()
-sets the precision of the time stamp desired for packets captured on the pcap
-descriptor to the type specified by
-.IR tstamp_precision .
-It must be called on a pcap descriptor created by
-.B pcap_create()
-that has not yet been activated by
-.BR pcap_activate() .
-Two time stamp precisions are supported, microseconds and nanoseconds. One can
-use options
-.B PCAP_TSTAMP_PRECISION_MICRO and
-.B PCAP_TSTAMP_PRECISION_NANO
-to request desired precision. By default, time stamps are in microseconds.
-.SH RETURN VALUE
-.B pcap_set_tstamp_type()
-returns 0 on success if the specified time stamp precision is expected to be
-supported by the operating system,
-.B PCAP_ERROR_TSTAMP_PRECISION_NOTSUP
-if operating system does not support requested time stamp precision,
-.B PCAP_ERROR_ACTIVATED
-if called on a capture handle that has been activated.
-.SH SEE ALSO
-pcap(3PCAP),
-pcap_get_tstamp_precision(3PCAP),
-pcap-tstamp(7)
diff --git a/contrib/libpcap/pcap_set_tstamp_type.3pcap b/contrib/libpcap/pcap_set_tstamp_type.3pcap
deleted file mode 100644
index b31b945e7eea5..0000000000000
--- a/contrib/libpcap/pcap_set_tstamp_type.3pcap
+++ /dev/null
@@ -1,65 +0,0 @@
-.\"
-.\" Copyright (c) 1994, 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: (1) source code distributions
-.\" retain the above copyright notice and this paragraph in its entirety, (2)
-.\" distributions including binary code include the above copyright notice and
-.\" this paragraph in its entirety in the documentation or other materials
-.\" provided with the distribution, and (3) all advertising materials mentioning
-.\" features or use of this software display the following acknowledgement:
-.\" ``This product includes software developed by the University of California,
-.\" Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
-.\" the University nor the names of its contributors may be used to endorse
-.\" or promote products derived from this software without specific prior
-.\" written permission.
-.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
-.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
-.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
-.\"
-.TH PCAP_SET_TSTAMP_TYPE 3PCAP "21 August 2010"
-.SH NAME
-pcap_set_tstamp_type \- set the time stamp type to be used by a
-capture device
-.SH SYNOPSIS
-.nf
-.ft B
-#include <pcap/pcap.h>
-.ft
-.LP
-.ft B
-int pcap_set_tstamp_type(pcap_t *p, int tstamp_type);
-.ft
-.fi
-.SH DESCRIPTION
-.B pcap_set_tstamp_type()
-sets the the type of time stamp desired for packets captured on the pcap
-descriptor to the type specified by
-.IR tstamp_type .
-It must be called on a pcap descriptor created by
-.B pcap_create()
-that has not yet been activated by
-.BR pcap_activate() .
-.B pcap_list_tstamp_types()
-will give a list of the time stamp types supported by a given capture
-device.
-See
-.BR pcap-tstamp (7)
-for a list of all the time stamp types.
-.SH RETURN VALUE
-.B pcap_set_tstamp_type()
-returns 0 on success if the specified time stamp type is expected to be
-supported by the capture device,
-.B PCAP_WARNING_TSTAMP_TYPE_NOTSUP
-on success if the specified time stamp type is not supported by the
-capture device,
-.B PCAP_ERROR_ACTIVATED
-if called on a capture handle that has been activated, and
-.B PCAP_ERROR_CANTSET_TSTAMP_TYPE
-if the capture device doesn't support setting the time stamp type.
-.SH SEE ALSO
-pcap(3PCAP),
-pcap_list_tstamp_types(3PCAP),
-pcap_tstamp_type_name_to_val(3PCAP),
-pcap-tstamp(7)
diff --git a/contrib/libpcap/pcap_set_tstamp_type.3pcap.in b/contrib/libpcap/pcap_set_tstamp_type.3pcap.in
index e58cdd4b0d776..7899da3106a41 100644
--- a/contrib/libpcap/pcap_set_tstamp_type.3pcap.in
+++ b/contrib/libpcap/pcap_set_tstamp_type.3pcap.in
@@ -34,7 +34,7 @@ int pcap_set_tstamp_type(pcap_t *p, int tstamp_type);
.fi
.SH DESCRIPTION
.B pcap_set_tstamp_type()
-sets the the type of time stamp desired for packets captured on the pcap
+sets the type of time stamp desired for packets captured on the pcap
descriptor to the type specified by
.IR tstamp_type .
It must be called on a pcap descriptor created by
diff --git a/contrib/libpcap/pcap_version.h.in b/contrib/libpcap/pcap_version.h.in
deleted file mode 100644
index 3104c8ea15794..0000000000000
--- a/contrib/libpcap/pcap_version.h.in
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * We make the version string static, and return a pointer to it, rather
- * than exporting the version string directly. On at least some UNIXes,
- * if you import data from a shared library into an program, the data is
- * bound into the program binary, so if the string in the version of the
- * library with which the program was linked isn't the same as the
- * string in the version of the library with which the program is being
- * run, various undesirable things may happen (warnings, the string
- * being the one from the version of the library with which the program
- * was linked, or even weirder things, such as the string being the one
- * from the library but being truncated).
- */
-static const char pcap_version_string[] = "libpcap version %%LIBPCAP_VERSION%%";
diff --git a/contrib/libpcap/portability.h b/contrib/libpcap/portability.h
index 8a6bf40e8bb4c..b36125421390e 100644
--- a/contrib/libpcap/portability.h
+++ b/contrib/libpcap/portability.h
@@ -39,6 +39,8 @@
* flavors of UN*X.
*/
+#include "pcap/funcattrs.h"
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -47,7 +49,7 @@ extern "C" {
/*
* Macro that does the same thing as strlcpy().
*/
- #ifdef _MSC_VER
+ #if defined(_MSC_VER) || defined(__MINGW32__)
/*
* strncpy_s() is supported at least back to Visual
* Studio 2005.
@@ -63,44 +65,37 @@ extern "C" {
#endif
#endif
-/*
- * For flagging arguments as format strings in MSVC.
- */
-#if _MSC_VER >= 1400
- #include <sal.h>
- #if _MSC_VER > 1400
- #define FORMAT_STRING(p) _Printf_format_string_ p
- #else
- #define FORMAT_STRING(p) __format_string p
- #endif
-#else
- #define FORMAT_STRING(p) p
-#endif
-
-#ifdef _MSC_VER
- #define strdup _strdup
- #define sscanf sscanf_s
- #define setbuf(x, y) \
- setvbuf((x), (y), _IONBF, 0)
- #define fopen(x, y) \
- fopen_safe((x), (y))
- FILE *fopen_safe(const char *filename, const char* mode);
-#endif
-
-#if defined(_MSC_VER) || defined(__MINGW32__)
+#ifndef HAVE_STRLCAT
+ /*
+ * Macro that does the same thing as strlcat().
+ */
+ #if defined(_MSC_VER) || defined(__MINGW32__)
+ /*
+ * strncat_s() is supported at least back to Visual
+ * Studio 2005.
+ */
#define strlcat(x, y, z) \
strncat_s((x), (z), (y), _TRUNCATE)
+ #else
+ /*
+ * ANSI C says strncat() always null-terminates its first argument,
+ * so 1) we don't need to explicitly null-terminate the string
+ * ourselves and 2) we need to leave room for the null terminator.
+ */
+ #define strlcat(x, y, z) \
+ strncat((x), (y), (z) - strlen((x)) - 1)
+ #endif
#endif
#ifdef _MSC_VER
/*
- * MSVC.
+ * If <crtdbg.h> has been included, and _DEBUG is defined, and
+ * __STDC__ is zero, <crtdbg.h> will define strdup() to call
+ * _strdup_dbg(). So if it's already defined, don't redefine
+ * it.
*/
- #if _MSC_VER >= 1900
- /*
- * VS 2015 or newer; we have snprintf() function.
- */
- #define HAVE_SNPRINTF
+ #ifndef strdup
+ #define strdup _strdup
#endif
#endif
@@ -129,11 +124,8 @@ extern "C" {
#ifdef HAVE_SNPRINTF
#define pcap_snprintf snprintf
#else
-extern int pcap_snprintf(char *, size_t, FORMAT_STRING(const char *), ...)
-#ifdef __ATTRIBUTE___FORMAT_OK
- __attribute__((format (printf, 3, 4)))
-#endif /* __ATTRIBUTE___FORMAT_OK */
- ;
+extern int pcap_snprintf(char *, size_t, PCAP_FORMAT_STRING(const char *), ...)
+ PCAP_PRINTFLIKE(3, 4);
#endif
#ifdef HAVE_VSNPRINTF
@@ -145,7 +137,7 @@ extern int pcap_vsnprintf(char *, size_t, const char *, va_list ap);
#ifdef HAVE_STRTOK_R
#define pcap_strtok_r strtok_r
#else
- #ifdef _MSC_VER
+ #ifdef _WIN32
/*
* Microsoft gives it a different name.
*/
@@ -155,55 +147,11 @@ extern int pcap_vsnprintf(char *, size_t, const char *, va_list ap);
* Define it ourselves.
*/
#define NEED_STRTOK_R
- extern int pcap_strtok_r(char *, const char *, char **);
+ extern char *pcap_strtok_r(char *, const char *, char **);
#endif
#endif /* HAVE_STRTOK_R */
#ifdef _WIN32
- /*
- * These may be defined by <inttypes.h>.
- *
- * XXX - for MSVC, we always want the _MSC_EXTENSIONS versions.
- * What about other compilers? If, as the MinGW Web site says MinGW
- * does, the other compilers just use Microsoft's run-time library,
- * then they should probably use the _MSC_EXTENSIONS even if the
- * compiler doesn't define _MSC_EXTENSIONS.
- *
- * XXX - we currently aren't using any of these, but this allows
- * their use in the future.
- */
- #ifndef PRId64
- #ifdef _MSC_EXTENSIONS
- #define PRId64 "I64d"
- #else
- #define PRId64 "lld"
- #endif
- #endif /* PRId64 */
-
- #ifndef PRIo64
- #ifdef _MSC_EXTENSIONS
- #define PRIo64 "I64o"
- #else
- #define PRIo64 "llo"
- #endif
- #endif /* PRIo64 */
-
- #ifndef PRIx64
- #ifdef _MSC_EXTENSIONS
- #define PRIx64 "I64x"
- #else
- #define PRIx64 "llx"
- #endif
- #endif
-
- #ifndef PRIu64
- #ifdef _MSC_EXTENSIONS
- #define PRIu64 "I64u"
- #else
- #define PRIu64 "llu"
- #endif
- #endif
-
#if !defined(__cplusplus)
#define inline __inline
#endif
diff --git a/contrib/libpcap/remote-ext.h b/contrib/libpcap/remote-ext.h
deleted file mode 100644
index ed2f9bb2be849..0000000000000
--- a/contrib/libpcap/remote-ext.h
+++ /dev/null
@@ -1,467 +0,0 @@
-/*
- * Copyright (c) 2002 - 2003
- * NetGroup, Politecnico di Torino (Italy)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the Politecnico di Torino nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-
-#ifndef __REMOTE_EXT_H__
-#define __REMOTE_EXT_H__
-
-
-#ifndef HAVE_REMOTE
-#error Please do not include this file directly. Just define HAVE_REMOTE and then include pcap.h
-#endif
-
-/*// Definition for Microsoft Visual Studio */
-#if _MSC_VER > 1000
-#pragma once
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * \file remote-ext.h
- *
- * The goal of this file it to include most of the new definitions that should be
- * placed into the pcap.h file.
- *
- * It includes all new definitions (structures and functions like pcap_open().
- * Some of the functions are not really a remote feature, but, right now,
- * they are placed here.
- */
-
-
-
-/*// All this stuff is public */
-/*
- * \addtogroup remote_struct
- * \{
- */
-
-
-
-
-/*
- * \brief Defines the maximum buffer size in which address, port, interface names are kept.
- *
- * In case the adapter name or such is larger than this value, it is truncated.
- * This is not used by the user; however it must be aware that an hostname / interface
- * name longer than this value will be truncated.
- */
-#define PCAP_BUF_SIZE 1024
-
-
-/*
- * \addtogroup remote_source_ID
- * \{
- */
-
-
-/*
- * \brief Internal representation of the type of source in use (file,
- * remote/local interface).
- *
- * This indicates a file, i.e. the user want to open a capture from a local file.
- */
-#define PCAP_SRC_FILE 2
-/*
- * \brief Internal representation of the type of source in use (file,
- * remote/local interface).
- *
- * This indicates a local interface, i.e. the user want to open a capture from
- * a local interface. This does not involve the RPCAP protocol.
- */
-#define PCAP_SRC_IFLOCAL 3
-/*
- * \brief Internal representation of the type of source in use (file,
- * remote/local interface).
- *
- * This indicates a remote interface, i.e. the user want to open a capture from
- * an interface on a remote host. This does involve the RPCAP protocol.
- */
-#define PCAP_SRC_IFREMOTE 4
-
-/*
- * \}
- */
-
-
-
-/* \addtogroup remote_source_string
- *
- * The formats allowed by the pcap_open() are the following:
- * - file://path_and_filename [opens a local file]
- * - rpcap://devicename [opens the selected device devices available on the local host, without using the RPCAP protocol]
- * - rpcap://host/devicename [opens the selected device available on a remote host]
- * - rpcap://host:port/devicename [opens the selected device available on a remote host, using a non-standard port for RPCAP]
- * - adaptername [to open a local adapter; kept for compability, but it is strongly discouraged]
- * - (NULL) [to open the first local adapter; kept for compability, but it is strongly discouraged]
- *
- * The formats allowed by the pcap_findalldevs_ex() are the following:
- * - file://folder/ [lists all the files in the given folder]
- * - rpcap:// [lists all local adapters]
- * - rpcap://host:port/ [lists the devices available on a remote host]
- *
- * Referring to the 'host' and 'port' parameters, they can be either numeric or literal. Since
- * IPv6 is fully supported, these are the allowed formats:
- *
- * - host (literal): e.g. host.foo.bar
- * - host (numeric IPv4): e.g. 10.11.12.13
- * - host (numeric IPv4, IPv6 style): e.g. [10.11.12.13]
- * - host (numeric IPv6): e.g. [1:2:3::4]
- * - port: can be either numeric (e.g. '80') or literal (e.g. 'http')
- *
- * Here you find some allowed examples:
- * - rpcap://host.foo.bar/devicename [everything literal, no port number]
- * - rpcap://host.foo.bar:1234/devicename [everything literal, with port number]
- * - rpcap://10.11.12.13/devicename [IPv4 numeric, no port number]
- * - rpcap://10.11.12.13:1234/devicename [IPv4 numeric, with port number]
- * - rpcap://[10.11.12.13]:1234/devicename [IPv4 numeric with IPv6 format, with port number]
- * - rpcap://[1:2:3::4]/devicename [IPv6 numeric, no port number]
- * - rpcap://[1:2:3::4]:1234/devicename [IPv6 numeric, with port number]
- * - rpcap://[1:2:3::4]:http/devicename [IPv6 numeric, with literal port number]
- *
- * \{
- */
-
-
-/*
- * \brief String that will be used to determine the type of source in use (file,
- * remote/local interface).
- *
- * This string will be prepended to the interface name in order to create a string
- * that contains all the information required to open the source.
- *
- * This string indicates that the user wants to open a capture from a local file.
- */
-#define PCAP_SRC_FILE_STRING "file://"
-/*
- * \brief String that will be used to determine the type of source in use (file,
- * remote/local interface).
- *
- * This string will be prepended to the interface name in order to create a string
- * that contains all the information required to open the source.
- *
- * This string indicates that the user wants to open a capture from a network interface.
- * This string does not necessarily involve the use of the RPCAP protocol. If the
- * interface required resides on the local host, the RPCAP protocol is not involved
- * and the local functions are used.
- */
-#define PCAP_SRC_IF_STRING "rpcap://"
-
-/*
- * \}
- */
-
-
-
-
-
-/*
- * \addtogroup remote_open_flags
- * \{
- */
-
-/*
- * \brief Defines if the adapter has to go in promiscuous mode.
- *
- * It is '1' if you have to open the adapter in promiscuous mode, '0' otherwise.
- * Note that even if this parameter is false, the interface could well be in promiscuous
- * mode for some other reason (for example because another capture process with
- * promiscuous mode enabled is currently using that interface).
- * On on Linux systems with 2.2 or later kernels (that have the "any" device), this
- * flag does not work on the "any" device; if an argument of "any" is supplied,
- * the 'promisc' flag is ignored.
- */
-#define PCAP_OPENFLAG_PROMISCUOUS 1
-
-/*
- * \brief Defines if the data transfer (in case of a remote
- * capture) has to be done with UDP protocol.
- *
- * If it is '1' if you want a UDP data connection, '0' if you want
- * a TCP data connection; control connection is always TCP-based.
- * A UDP connection is much lighter, but it does not guarantee that all
- * the captured packets arrive to the client workstation. Moreover,
- * it could be harmful in case of network congestion.
- * This flag is meaningless if the source is not a remote interface.
- * In that case, it is simply ignored.
- */
-#define PCAP_OPENFLAG_DATATX_UDP 2
-
-
-/*
- * \brief Defines if the remote probe will capture its own generated traffic.
- *
- * In case the remote probe uses the same interface to capture traffic and to send
- * data back to the caller, the captured traffic includes the RPCAP traffic as well.
- * If this flag is turned on, the RPCAP traffic is excluded from the capture, so that
- * the trace returned back to the collector is does not include this traffic.
- */
-#define PCAP_OPENFLAG_NOCAPTURE_RPCAP 4
-
-/*
- * \brief Defines if the local adapter will capture its own generated traffic.
- *
- * This flag tells the underlying capture driver to drop the packets that were sent by itself.
- * This is useful when building applications like bridges, that should ignore the traffic
- * they just sent.
- */
-#define PCAP_OPENFLAG_NOCAPTURE_LOCAL 8
-
-/*
- * \brief This flag configures the adapter for maximum responsiveness.
- *
- * In presence of a large value for nbytes, WinPcap waits for the arrival of several packets before
- * copying the data to the user. This guarantees a low number of system calls, i.e. lower processor usage,
- * i.e. better performance, which is good for applications like sniffers. If the user sets the
- * PCAP_OPENFLAG_MAX_RESPONSIVENESS flag, the capture driver will copy the packets as soon as the application
- * is ready to receive them. This is suggested for real time applications (like, for example, a bridge)
- * that need the best responsiveness.
- */
-#define PCAP_OPENFLAG_MAX_RESPONSIVENESS 16
-
-/*
- * \}
- */
-
-
-/*
- * \addtogroup remote_samp_methods
- * \{
- */
-
-/*
- *\brief No sampling has to be done on the current capture.
- *
- * In this case, no sampling algorithms are applied to the current capture.
- */
-#define PCAP_SAMP_NOSAMP 0
-
-/*
- * \brief It defines that only 1 out of N packets must be returned to the user.
- *
- * In this case, the 'value' field of the 'pcap_samp' structure indicates the
- * number of packets (minus 1) that must be discarded before one packet got accepted.
- * In other words, if 'value = 10', the first packet is returned to the caller, while
- * the following 9 are discarded.
- */
-#define PCAP_SAMP_1_EVERY_N 1
-
-/*
- * \brief It defines that we have to return 1 packet every N milliseconds.
- *
- * In this case, the 'value' field of the 'pcap_samp' structure indicates the 'waiting
- * time' in milliseconds before one packet got accepted.
- * In other words, if 'value = 10', the first packet is returned to the caller; the next
- * returned one will be the first packet that arrives when 10ms have elapsed.
- */
-#define PCAP_SAMP_FIRST_AFTER_N_MS 2
-
-/*
- * \}
- */
-
-
-/*
- * \addtogroup remote_auth_methods
- * \{
- */
-
-/*
- * \brief It defines the NULL authentication.
- *
- * This value has to be used within the 'type' member of the pcap_rmtauth structure.
- * The 'NULL' authentication has to be equal to 'zero', so that old applications
- * can just put every field of struct pcap_rmtauth to zero, and it does work.
- */
-#define RPCAP_RMTAUTH_NULL 0
-/*
- * \brief It defines the username/password authentication.
- *
- * With this type of authentication, the RPCAP protocol will use the username/
- * password provided to authenticate the user on the remote machine. If the
- * authentication is successful (and the user has the right to open network devices)
- * the RPCAP connection will continue; otherwise it will be dropped.
- *
- * This value has to be used within the 'type' member of the pcap_rmtauth structure.
- */
-#define RPCAP_RMTAUTH_PWD 1
-
-/*
- * \}
- */
-
-
-
-
-/*
- * \brief This structure keeps the information needed to autheticate
- * the user on a remote machine.
- *
- * The remote machine can either grant or refuse the access according
- * to the information provided.
- * In case the NULL authentication is required, both 'username' and
- * 'password' can be NULL pointers.
- *
- * This structure is meaningless if the source is not a remote interface;
- * in that case, the functions which requires such a structure can accept
- * a NULL pointer as well.
- */
-struct pcap_rmtauth
-{
- /*
- * \brief Type of the authentication required.
- *
- * In order to provide maximum flexibility, we can support different types
- * of authentication based on the value of this 'type' variable. The currently
- * supported authentication methods are defined into the
- * \link remote_auth_methods Remote Authentication Methods Section\endlink.
- */
- int type;
- /*
- * \brief Zero-terminated string containing the username that has to be
- * used on the remote machine for authentication.
- *
- * This field is meaningless in case of the RPCAP_RMTAUTH_NULL authentication
- * and it can be NULL.
- */
- char *username;
- /*
- * \brief Zero-terminated string containing the password that has to be
- * used on the remote machine for authentication.
- *
- * This field is meaningless in case of the RPCAP_RMTAUTH_NULL authentication
- * and it can be NULL.
- */
- char *password;
-};
-
-
-/*
- * \brief This structure defines the information related to sampling.
- *
- * In case the sampling is requested, the capturing device should read
- * only a subset of the packets coming from the source. The returned packets depend
- * on the sampling parameters.
- *
- * \warning The sampling process is applied <strong>after</strong> the filtering process.
- * In other words, packets are filtered first, then the sampling process selects a
- * subset of the 'filtered' packets and it returns them to the caller.
- */
-struct pcap_samp
-{
- /*
- * Method used for sampling. Currently, the supported methods are listed in the
- * \link remote_samp_methods Sampling Methods Section\endlink.
- */
- int method;
-
- /*
- * This value depends on the sampling method defined. For its meaning, please check
- * at the \link remote_samp_methods Sampling Methods Section\endlink.
- */
- int value;
-};
-
-
-
-
-// Maximum length of an host name (needed for the RPCAP active mode)
-#define RPCAP_HOSTLIST_SIZE 1024
-
-
-/*
- * \}
- */ // end of public documentation
-
-
-// Exported functions
-
-
-
-/*
- * \name New WinPcap functions
- *
- * This section lists the new functions that are able to help considerably in writing
- * WinPcap programs because of their easiness of use.
- */
-// \{
-PCAP_API pcap_t *pcap_open(const char *source, int snaplen, int flags, int read_timeout, struct pcap_rmtauth *auth, char *errbuf);
-PCAP_API int pcap_createsrcstr(char *source, int type, const char *host, const char *port, const char *name, char *errbuf);
-PCAP_API int pcap_parsesrcstr(const char *source, int *type, char *host, char *port, char *name, char *errbuf);
-PCAP_API int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **alldevs, char *errbuf);
-PCAP_API struct pcap_samp *pcap_setsampling(pcap_t *p);
-
-// \}
-// End of new WinPcap functions
-
-/*
- * \name Remote Capture functions
- */
-
-/*
- * 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);
-PCAP_API int pcap_remoteact_list(char *hostlist, char sep, int size, char *errbuf);
-PCAP_API int pcap_remoteact_close(const char *host, char *errbuf);
-PCAP_API void pcap_remoteact_cleanup();
-// \}
-// End of remote capture functions
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif
-
diff --git a/contrib/libpcap/rpcap-protocol.c b/contrib/libpcap/rpcap-protocol.c
new file mode 100644
index 0000000000000..692f7c5c0d6bc
--- /dev/null
+++ b/contrib/libpcap/rpcap-protocol.c
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2002 - 2005 NetGroup, Politecnico di Torino (Italy)
+ * Copyright (c) 2005 - 2008 CACE Technologies, Davis (California)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Politecnico di Torino, CACE Technologies
+ * nor the names of its contributors may be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h> /* for strlen(), ... */
+#include <stdlib.h> /* for malloc(), free(), ... */
+#include <stdarg.h> /* for functions with variable number of arguments */
+#include <errno.h> /* for the errno variable */
+#include "sockutils.h"
+#include "portability.h"
+#include "rpcap-protocol.h"
+#include <pcap/pcap.h>
+
+/*
+ * This file contains functions used both by the rpcap client and the
+ * rpcap daemon.
+ */
+
+/*
+ * This function sends a RPCAP error to our peer.
+ *
+ * It has to be called when the main program detects an error.
+ * It will send to our peer the 'buffer' specified by the user.
+ * This function *does not* request a RPCAP CLOSE connection. A CLOSE
+ * command must be sent explicitly by the program, since we do not know
+ * whether the error can be recovered in some way or if it is a
+ * non-recoverable one.
+ *
+ * \param sock: the socket we are currently using.
+ *
+ * \param ver: the protocol version we want to put in the reply.
+ *
+ * \param errcode: a integer which tells the other party the type of error
+ * we had.
+ *
+ * \param error: an user-allocated (and '0' terminated) buffer that contains
+ * the error description that has to be transmitted to our peer. The
+ * error message cannot be longer than PCAP_ERRBUF_SIZE.
+ *
+ * \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 network problem.
+ *
+ * \return '0' if everything is fine, '-1' if some errors occurred. The
+ * error message is returned in the 'errbuf' variable.
+ */
+int
+rpcap_senderror(SOCKET sock, uint8 ver, unsigned short errcode, const char *error, char *errbuf)
+{
+ 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 */
+ uint16 length;
+
+ length = (uint16)strlen(error);
+
+ if (length > PCAP_ERRBUF_SIZE)
+ length = PCAP_ERRBUF_SIZE;
+
+ rpcap_createhdr((struct rpcap_header *) sendbuf, ver, RPCAP_MSG_ERROR, errcode, length);
+
+ if (sock_bufferize(NULL, sizeof(struct rpcap_header), NULL, &sendbufidx,
+ RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errbuf, PCAP_ERRBUF_SIZE))
+ return -1;
+
+ if (sock_bufferize(error, length, sendbuf, &sendbufidx,
+ RPCAP_NETBUF_SIZE, SOCKBUF_BUFFERIZE, errbuf, PCAP_ERRBUF_SIZE))
+ return -1;
+
+ if (sock_send(sock, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) < 0)
+ return -1;
+
+ return 0;
+}
+
+/*
+ * This function fills in a structure of type rpcap_header.
+ *
+ * It is provided just because the creation of an rpcap header is a common
+ * task. It accepts all the values that appears into an rpcap_header, and
+ * it puts them in place using the proper hton() calls.
+ *
+ * \param header: a pointer to a user-allocated buffer which will contain
+ * the serialized header, ready to be sent on the network.
+ *
+ * \param ver: a value (in the host byte order) which will be placed into the
+ * header.ver field and that represents the protocol version number of the
+ * current message.
+ *
+ * \param type: a value (in the host byte order) which will be placed into the
+ * header.type field and that represents the type of the current message.
+ *
+ * \param value: a value (in the host byte order) which will be placed into
+ * the header.value field and that has a message-dependent meaning.
+ *
+ * \param length: a value (in the host by order) which will be placed into
+ * the header.length field, representing the payload length of the message.
+ *
+ * \return Nothing. The serialized header is returned into the 'header'
+ * variable.
+ */
+void
+rpcap_createhdr(struct rpcap_header *header, uint8 ver, uint8 type, uint16 value, uint32 length)
+{
+ memset(header, 0, sizeof(struct rpcap_header));
+
+ header->ver = ver;
+ header->type = type;
+ header->value = htons(value);
+ header->plen = htonl(length);
+}
+
+/*
+ * Convert a message type to a string containing the type name.
+ */
+static const char *requests[] =
+{
+ NULL, /* not a valid message type */
+ "RPCAP_MSG_ERROR",
+ "RPCAP_MSG_FINDALLIF_REQ",
+ "RPCAP_MSG_OPEN_REQ",
+ "RPCAP_MSG_STARTCAP_REQ",
+ "RPCAP_MSG_UPDATEFILTER_REQ",
+ "RPCAP_MSG_CLOSE",
+ "RPCAP_MSG_PACKET",
+ "RPCAP_MSG_AUTH_REQ",
+ "RPCAP_MSG_STATS_REQ",
+ "RPCAP_MSG_ENDCAP_REQ",
+ "RPCAP_MSG_SETSAMPLING_REQ",
+};
+#define NUM_REQ_TYPES (sizeof requests / sizeof requests[0])
+
+static const char *replies[] =
+{
+ NULL,
+ NULL, /* this would be a reply to RPCAP_MSG_ERROR */
+ "RPCAP_MSG_FINDALLIF_REPLY",
+ "RPCAP_MSG_OPEN_REPLY",
+ "RPCAP_MSG_STARTCAP_REPLY",
+ "RPCAP_MSG_UPDATEFILTER_REPLY",
+ NULL, /* this would be a reply to RPCAP_MSG_CLOSE */
+ NULL, /* this would be a reply to RPCAP_MSG_PACKET */
+ "RPCAP_MSG_AUTH_REPLY",
+ "RPCAP_MSG_STATS_REPLY",
+ "RPCAP_MSG_ENDCAP_REPLY",
+ "RPCAP_MSG_SETSAMPLING_REPLY",
+};
+#define NUM_REPLY_TYPES (sizeof replies / sizeof replies[0])
+
+const char *
+rpcap_msg_type_string(uint8 type)
+{
+ if (type & RPCAP_MSG_IS_REPLY) {
+ type &= ~RPCAP_MSG_IS_REPLY;
+ if (type >= NUM_REPLY_TYPES)
+ return NULL;
+ return replies[type];
+ } else {
+ if (type >= NUM_REQ_TYPES)
+ return NULL;
+ return requests[type];
+ }
+}
diff --git a/contrib/libpcap/rpcap-protocol.h b/contrib/libpcap/rpcap-protocol.h
new file mode 100644
index 0000000000000..83ebdc5b00638
--- /dev/null
+++ b/contrib/libpcap/rpcap-protocol.h
@@ -0,0 +1,450 @@
+/*
+ * Copyright (c) 2002 - 2005 NetGroup, Politecnico di Torino (Italy)
+ * Copyright (c) 2005 - 2008 CACE Technologies, Davis (California)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Politecnico di Torino, CACE Technologies
+ * nor the names of its contributors may be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __RPCAP_PROTOCOL_H__
+#define __RPCAP_PROTOCOL_H__
+
+#define RPCAP_DEFAULT_NETPORT "2002" /* Default port on which the RPCAP daemon is waiting for connections. */
+/* Default port on which the client workstation is waiting for connections in case of active mode. */
+#define RPCAP_DEFAULT_NETPORT_ACTIVE "2003"
+#define RPCAP_DEFAULT_NETADDR "" /* Default network address on which the RPCAP daemon binds to. */
+
+/*
+ * Minimum and maximum supported versions of the protocol.
+ *
+ * If new message types are added, the protocol version MUST be changed,
+ * so that a client knows, from the negotiated protocol version, what
+ * messages can be sent to the server.
+ *
+ * If the format of an existing message type is changed, the protocol
+ * version MUST be changed, so that each side knows, from the negotiated
+ * protocol version, what format should be used.
+ *
+ * The RPCAP_MSG_ERROR format MUST not change, as it's used to, among
+ * other things, report "incorrect version number" errors, where, if
+ * the format changed, the sender of the message might not know what
+ * versions the recipient would understand, or might know a version
+ * they support (the version number they sent) but might not know
+ * the format of the message in that version.
+ *
+ * Other message versions SHOULD not change, as that would complicate
+ * the process of interpreting the message, making it version-dependent.
+ * Introducing a new message with a new format is preferable.
+ *
+ * Version negotiation is done as part of the authentication process:
+ *
+ * The client sends an authentication request, with the version number
+ * in the request being the maximum version it supports.
+ *
+ * If the server supports that version, it attempts to authenticate the
+ * client, and replies as appropriate, with the version number in the
+ * reply being that version.
+ *
+ * If the server doesn't support that version because it's too large,
+ * it replies with a RPCAP_MSG_ERROR message, with the maximum version
+ * they support as the version number in the reply, and with the error
+ * code being PCAP_ERR_WRONGVER.
+ *
+ * If the server doesn't support that version because it's too small,
+ * it replies with a RPCAP_MSG_ERROR message, with that version as
+ * the version number in the reply, and with the error code being
+ * PCAP_ERR_WRONGVER.
+ *
+ * If the client supports that version, it retries the authentication
+ * with that version and, if that fails for any reason, including
+ * PCAP_ERR_WRONGVER, fails. Otherwise, it fails, telling its caller
+ * that there's no version that both support.
+ *
+ * This requires that the set of versions supported by a client or
+ * server be a range of integers, with no gaps. Thus:
+ *
+ * the client's version set is [Cmin, Cmax], with Cmin <= Cmax;
+ *
+ * the server's version set is [Smin, Smax], with Smin <= Smax;
+ *
+ * the client sends Cmax as the version number in the initial
+ * authentication request;
+ *
+ * if the server doesn't support the version sent by the client,
+ * either Smax < Cmax or Smin > Cmax (because the client sent Cmax
+ * to the server, and the server doesn't support it);
+ *
+ * if Smax < Cmax:
+ *
+ * the server sends Smax as the version number in the RPCAP_MSG_ERROR/
+ * PCAP_ERR_WRONGVER message - the client will accept this because
+ * Cmax != 0, as these numbers are unsigned, and this means that
+ * this isn't an old client that rejects all messages with a non-zero
+ * version number, it's a new client that accepts RPCAP_MSG_ERROR
+ * messages no matter what the version is;
+ *
+ * if Smax >= Cmin, both the client and the server can use it, and
+ * the client retries with Smax;
+ *
+ * if Smax < Cmin, there is no version the client and server can
+ * both support.
+ *
+ * if Smin > Cmax:
+ *
+ * the server sends Cmax as the version number in the RPCAP_MSG_ERROR/
+ * PCAP_ERR_WRONGVER message - the client will accept this because
+ * Cmax is a valid client version number.
+ *
+ * the client will retry with Cmax, get the same version failure,
+ * and report that there is no version the client and server can
+ * both support (as the version sets are disjoint).
+ *
+ * Old negotiation-unaware clients just send version 0 and, if they
+ * get back PCAP_ERR_WRONGVER, treat it as a fatal error. This
+ * means they'll fail to talk to any server that can't handle
+ * version 0, which is the appropriate thing to do, as they can
+ * only use version 0.
+ *
+ * Old negotiation-unaware servers fail if they get a version other
+ * than 0, sending back PCAP_ERR_WRONGVER with version 0, which is
+ * the only version, and thus both the minimum and maximum version,
+ * they support. The client will either fail if it doesn't support
+ * version 0, or will retry with version 0 and succeed, so it will
+ * fail with servers that can't handle version 0 or will negotiate
+ * version 0 with servers that can handle version 0.
+ */
+#define RPCAP_MIN_VERSION 0
+#define RPCAP_MAX_VERSION 0
+
+/*
+ * Version numbers are unsigned, so if RPCAP_MIN_VERSION is 0, they
+ * are >= the minimum version, by definition; don't check against
+ * RPCAP_MIN_VERSION, as you may get compiler warnings that the
+ * comparison will always succeed.
+ */
+#if RPCAP_MIN_VERSION == 0
+#define RPCAP_VERSION_IS_SUPPORTED(v) ((v) <= RPCAP_MAX_VERSION)
+#else
+#define RPCAP_VERSION_IS_SUPPORTED(v) \
+ ((v) >= RPCAP_MIN_VERSION && (v) <= RPCAP_MAX_VERSION)
+#endif
+
+/*
+ * Separators used for the host list.
+ *
+ * It is used:
+ * - by the rpcapd daemon, when you types a list of allowed connecting hosts
+ * - by the rpcap client in active mode, when the client waits for incoming
+ * connections from other hosts
+ */
+#define RPCAP_HOSTLIST_SEP " ,;\n\r"
+
+/*********************************************************
+ * *
+ * Protocol messages formats *
+ * *
+ *********************************************************/
+/*
+ * WARNING: This file defines some structures that are used to transfer
+ * data on the network.
+ * Note that your compiler MUST not insert padding into these structures
+ * for better alignment.
+ * These structures have been created in order to be correctly aligned to
+ * a 32-bit boundary, but be careful in any case.
+ */
+
+/*
+ * WARNING: These typedefs MUST be of a specific size.
+ * You might have to change them on your platform.
+ *
+ * XXX - use the C99 types? Microsoft's newer versions of Visual Studio
+ * support them.
+ */
+typedef unsigned char uint8; /* 8-bit unsigned integer */
+typedef unsigned short uint16; /* 16-bit unsigned integer */
+typedef unsigned int uint32; /* 32-bit unsigned integer */
+typedef int int32; /* 32-bit signed integer */
+
+/* Common header for all the RPCAP messages */
+struct rpcap_header
+{
+ uint8 ver; /* RPCAP version number */
+ uint8 type; /* RPCAP message type (error, findalldevs, ...) */
+ uint16 value; /* Message-dependent value (not always used) */
+ uint32 plen; /* Length of the payload of this RPCAP message */
+};
+
+/* Format of the message for the interface description (findalldevs command) */
+struct rpcap_findalldevs_if
+{
+ uint16 namelen; /* Length of the interface name */
+ uint16 desclen; /* Length of the interface description */
+ uint32 flags; /* Interface flags */
+ uint16 naddr; /* Number of addresses */
+ uint16 dummy; /* Must be zero */
+};
+
+/*
+ * Format of an address as sent over the wire.
+ *
+ * Do *NOT* use struct sockaddr_storage, as the layout for that is
+ * machine-dependent.
+ *
+ * RFC 2553 gives two sample layouts, both of which are 128 bytes long,
+ * both of which are aligned on an 8-byte boundary, and both of which
+ * have 2 bytes before the address data.
+ *
+ * However, one has a 2-byte address family value at the beginning
+ * and the other has a 1-byte address length value and a 1-byte
+ * address family value; this reflects the fact that the original
+ * BSD sockaddr structure had a 2-byte address family value, which
+ * was later changed to a 1-byte address length value and a 1-byte
+ * address family value, when support for variable-length OSI
+ * network-layer addresses was added.
+ *
+ * Furthermore, Solaris's struct sockaddr_storage is 256 bytes
+ * long.
+ *
+ * This structure is supposed to be aligned on an 8-byte boundary;
+ * the message header is 8 bytes long, so we don't have to do
+ * anything to ensure it's aligned on that boundary within a packet,
+ * so we just define it as 128 bytes long, with a 2-byte address
+ * family. (We only support IPv4 and IPv6 addresses, which are fixed-
+ * length.) That way, it's the same size as sockaddr_storage on
+ * Windows, and it'll look like what an older Windows client will
+ * expect.
+ *
+ * In addition, do *NOT* use the host's AF_ value for an address,
+ * as the value for AF_INET6 is machine-dependent. We use the
+ * Windows value, so it'll look like what an older Windows client
+ * will expect.
+ *
+ * (The Windows client is the only one that has been distributed
+ * as a standard part of *pcap; UN*X clients are probably built
+ * from source by the user or administrator, so they're in a
+ * better position to upgrade an old client. Therefore, we
+ * try to make what goes over the wire look like what comes
+ * from a Windows server.)
+ */
+struct rpcap_sockaddr
+{
+ uint16 family; /* Address family */
+ char data[128-2]; /* Data */
+};
+
+/*
+ * Format of an IPv4 address as sent over the wire.
+ */
+#define RPCAP_AF_INET 2 /* Value on all OSes */
+struct rpcap_sockaddr_in
+{
+ uint16 family; /* Address family */
+ uint16 port; /* Port number */
+ uint32 addr; /* IPv4 address */
+ uint8 zero[8]; /* Padding */
+};
+
+/*
+ * Format of an IPv6 address as sent over the wire.
+ */
+#define RPCAP_AF_INET6 23 /* Value on Windows */
+struct rpcap_sockaddr_in6
+{
+ uint16 family; /* Address family */
+ uint16 port; /* Port number */
+ uint32 flowinfo; /* IPv6 flow information */
+ uint8 addr[16]; /* IPv6 address */
+ uint32 scope_id; /* Scope zone index */
+};
+
+/* Format of the message for the address listing (findalldevs command) */
+struct rpcap_findalldevs_ifaddr
+{
+ struct rpcap_sockaddr addr; /* Network address */
+ struct rpcap_sockaddr netmask; /* Netmask for that address */
+ struct rpcap_sockaddr broadaddr; /* Broadcast address for that address */
+ struct rpcap_sockaddr dstaddr; /* P2P destination address for that address */
+};
+
+/*
+ * \brief Format of the message of the connection opening reply (open command).
+ *
+ * This structure transfers over the network some of the values useful on the client side.
+ */
+struct rpcap_openreply
+{
+ int32 linktype; /* Link type */
+ int32 tzoff; /* Timezone offset */
+};
+
+/* Format of the message that starts a remote capture (startcap command) */
+struct rpcap_startcapreq
+{
+ uint32 snaplen; /* Length of the snapshot (number of bytes to capture for each packet) */
+ uint32 read_timeout; /* Read timeout in milliseconds */
+ uint16 flags; /* Flags (see RPCAP_STARTCAPREQ_FLAG_xxx) */
+ uint16 portdata; /* Network port on which the client is waiting at (if 'serveropen') */
+};
+
+/* Format of the reply message that devoted to start a remote capture (startcap reply command) */
+struct rpcap_startcapreply
+{
+ int32 bufsize; /* Size of the user buffer allocated by WinPcap; it can be different from the one we chose */
+ uint16 portdata; /* Network port on which the server is waiting at (passive mode only) */
+ uint16 dummy; /* Must be zero */
+};
+
+/*
+ * \brief Format of the header which encapsulates captured packets when transmitted on the network.
+ *
+ * This message requires the general header as well, since we want to be able to exchange
+ * more information across the network in the future (for example statistics, and kind like that).
+ */
+struct rpcap_pkthdr
+{
+ uint32 timestamp_sec; /* 'struct timeval' compatible, it represents the 'tv_sec' field */
+ uint32 timestamp_usec; /* 'struct timeval' compatible, it represents the 'tv_usec' field */
+ uint32 caplen; /* Length of portion present in the capture */
+ uint32 len; /* Real length this packet (off wire) */
+ uint32 npkt; /* Ordinal number of the packet (i.e. the first one captured has '1', the second one '2', etc) */
+};
+
+/* General header used for the pcap_setfilter() command; keeps just the number of BPF instructions */
+struct rpcap_filter
+{
+ uint16 filtertype; /* type of the filter transferred (BPF instructions, ...) */
+ uint16 dummy; /* Must be zero */
+ uint32 nitems; /* Number of items contained into the filter (e.g. BPF instructions for BPF filters) */
+};
+
+/* Structure that keeps a single BPF instuction; it is repeated 'ninsn' times according to the 'rpcap_filterbpf' header */
+struct rpcap_filterbpf_insn
+{
+ uint16 code; /* opcode of the instruction */
+ uint8 jt; /* relative offset to jump to in case of 'true' */
+ uint8 jf; /* relative offset to jump to in case of 'false' */
+ int32 k; /* instruction-dependent value */
+};
+
+/* Structure that keeps the data required for the authentication on the remote host */
+struct rpcap_auth
+{
+ uint16 type; /* Authentication type */
+ uint16 dummy; /* Must be zero */
+ uint16 slen1; /* Length of the first authentication item (e.g. username) */
+ uint16 slen2; /* Length of the second authentication item (e.g. password) */
+};
+
+/* Structure that keeps the statistics about the number of packets captured, dropped, etc. */
+struct rpcap_stats
+{
+ uint32 ifrecv; /* Packets received by the kernel filter (i.e. pcap_stats.ps_recv) */
+ uint32 ifdrop; /* Packets dropped by the network interface (e.g. not enough buffers) (i.e. pcap_stats.ps_ifdrop) */
+ uint32 krnldrop; /* Packets dropped by the kernel filter (i.e. pcap_stats.ps_drop) */
+ uint32 svrcapt; /* Packets captured by the RPCAP daemon and sent on the network */
+};
+
+/* Structure that is needed to set sampling parameters */
+struct rpcap_sampling
+{
+ uint8 method; /* Sampling method */
+ uint8 dummy1; /* Must be zero */
+ uint16 dummy2; /* Must be zero */
+ uint32 value; /* Parameter related to the sampling method */
+};
+
+/* Messages field coding */
+#define RPCAP_MSG_IS_REPLY 0x080 /* Flag indicating a reply */
+
+#define RPCAP_MSG_ERROR 1 /* Message that keeps an error notification */
+#define RPCAP_MSG_FINDALLIF_REQ 2 /* Request to list all the remote interfaces */
+#define RPCAP_MSG_OPEN_REQ 3 /* Request to open a remote device */
+#define RPCAP_MSG_STARTCAP_REQ 4 /* Request to start a capture on a remote device */
+#define RPCAP_MSG_UPDATEFILTER_REQ 5 /* Send a compiled filter into the remote device */
+#define RPCAP_MSG_CLOSE 6 /* Close the connection with the remote peer */
+#define RPCAP_MSG_PACKET 7 /* This is a 'data' message, which carries a network packet */
+#define RPCAP_MSG_AUTH_REQ 8 /* Message that keeps the authentication parameters */
+#define RPCAP_MSG_STATS_REQ 9 /* It requires to have network statistics */
+#define RPCAP_MSG_ENDCAP_REQ 10 /* Stops the current capture, keeping the device open */
+#define RPCAP_MSG_SETSAMPLING_REQ 11 /* Set sampling parameters */
+
+#define RPCAP_MSG_FINDALLIF_REPLY (RPCAP_MSG_FINDALLIF_REQ | RPCAP_MSG_IS_REPLY) /* Keeps the list of all the remote interfaces */
+#define RPCAP_MSG_OPEN_REPLY (RPCAP_MSG_OPEN_REQ | RPCAP_MSG_IS_REPLY) /* The remote device has been opened correctly */
+#define RPCAP_MSG_STARTCAP_REPLY (RPCAP_MSG_STARTCAP_REQ | RPCAP_MSG_IS_REPLY) /* The capture is starting correctly */
+#define RPCAP_MSG_UPDATEFILTER_REPLY (RPCAP_MSG_UPDATEFILTER_REQ | RPCAP_MSG_IS_REPLY) /* The filter has been applied correctly on the remote device */
+#define RPCAP_MSG_AUTH_REPLY (RPCAP_MSG_AUTH_REQ | RPCAP_MSG_IS_REPLY) /* Sends a message that says 'ok, authorization successful' */
+#define RPCAP_MSG_STATS_REPLY (RPCAP_MSG_STATS_REQ | RPCAP_MSG_IS_REPLY) /* Message that keeps the network statistics */
+#define RPCAP_MSG_ENDCAP_REPLY (RPCAP_MSG_ENDCAP_REQ | RPCAP_MSG_IS_REPLY) /* Confirms that the capture stopped successfully */
+#define RPCAP_MSG_SETSAMPLING_REPLY (RPCAP_MSG_SETSAMPLING_REQ | RPCAP_MSG_IS_REPLY) /* Confirms that the capture stopped successfully */
+
+#define RPCAP_STARTCAPREQ_FLAG_PROMISC 0x00000001 /* Enables promiscuous mode (default: disabled) */
+#define RPCAP_STARTCAPREQ_FLAG_DGRAM 0x00000002 /* Use a datagram (i.e. UDP) connection for the data stream (default: use TCP)*/
+#define RPCAP_STARTCAPREQ_FLAG_SERVEROPEN 0x00000004 /* The server has to open the data connection toward the client */
+#define RPCAP_STARTCAPREQ_FLAG_INBOUND 0x00000008 /* Capture only inbound packets (take care: the flag has no effect with promiscuous enabled) */
+#define RPCAP_STARTCAPREQ_FLAG_OUTBOUND 0x00000010 /* Capture only outbound packets (take care: the flag has no effect with promiscuous enabled) */
+
+#define RPCAP_UPDATEFILTER_BPF 1 /* This code tells us that the filter is encoded with the BPF/NPF syntax */
+
+/* Network error codes */
+#define PCAP_ERR_NETW 1 /* Network error */
+#define PCAP_ERR_INITTIMEOUT 2 /* The RPCAP initial timeout has expired */
+#define PCAP_ERR_AUTH 3 /* Generic authentication error */
+#define PCAP_ERR_FINDALLIF 4 /* Generic findalldevs error */
+#define PCAP_ERR_NOREMOTEIF 5 /* The findalldevs was ok, but the remote end had no interfaces to list */
+#define PCAP_ERR_OPEN 6 /* Generic pcap_open error */
+#define PCAP_ERR_UPDATEFILTER 7 /* Generic updatefilter error */
+#define PCAP_ERR_GETSTATS 8 /* Generic pcap_stats error */
+#define PCAP_ERR_READEX 9 /* Generic pcap_next_ex error */
+#define PCAP_ERR_HOSTNOAUTH 10 /* The host is not authorized to connect to this server */
+#define PCAP_ERR_REMOTEACCEPT 11 /* Generic pcap_remoteaccept error */
+#define PCAP_ERR_STARTCAPTURE 12 /* Generic pcap_startcapture error */
+#define PCAP_ERR_ENDCAPTURE 13 /* Generic pcap_endcapture error */
+#define PCAP_ERR_RUNTIMETIMEOUT 14 /* The RPCAP run-time timeout has expired */
+#define PCAP_ERR_SETSAMPLING 15 /* Error during the settings of sampling parameters */
+#define PCAP_ERR_WRONGMSG 16 /* The other end endpoint sent a message which has not been recognized */
+#define PCAP_ERR_WRONGVER 17 /* The other end endpoint has a version number that is not compatible with our */
+
+/*
+ * \brief Buffer used by socket functions to send-receive packets.
+ * In case you plan to have messages larger than this value, you have to increase it.
+ */
+#define RPCAP_NETBUF_SIZE 64000
+
+/*********************************************************
+ * *
+ * Routines used by the rpcap client and rpcap daemon *
+ * *
+ *********************************************************/
+
+#include "sockutils.h"
+
+extern void rpcap_createhdr(struct rpcap_header *header, uint8 ver, uint8 type, uint16 value, uint32 length);
+extern const char *rpcap_msg_type_string(uint8 type);
+extern int rpcap_senderror(SOCKET sock, uint8 ver, uint16 errcode, const char *error, char *errbuf);
+
+#endif
diff --git a/contrib/libpcap/savefile.c b/contrib/libpcap/savefile.c
index 247338c5b879b..ec44ef4fe0566 100644
--- a/contrib/libpcap/savefile.c
+++ b/contrib/libpcap/savefile.c
@@ -29,21 +29,13 @@
*/
#ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
#endif
+#include <pcap-types.h>
#ifdef _WIN32
-#include <pcap-stdinc.h>
-#else /* _WIN32 */
-#if HAVE_INTTYPES_H
-#include <inttypes.h>
-#elif HAVE_STDINT_H
-#include <stdint.h>
-#endif
-#ifdef HAVE_SYS_BITYPES_H
-#include <sys/bitypes.h>
-#endif
-#include <sys/types.h>
+#include <io.h>
+#include <fcntl.h>
#endif /* _WIN32 */
#include <errno.h>
@@ -59,7 +51,7 @@
#endif
#include "sf-pcap.h"
-#include "sf-pcap-ng.h"
+#include "sf-pcapng.h"
#ifdef _WIN32
/*
@@ -92,7 +84,7 @@ static pcap_t *pcap_fopen_offline(FILE *, char *);
#endif
static int
-sf_getnonblock(pcap_t *p, char *errbuf)
+sf_getnonblock(pcap_t *p _U_)
{
/*
* This is a savefile, not a live capture file, so never say
@@ -102,7 +94,7 @@ sf_getnonblock(pcap_t *p, char *errbuf)
}
static int
-sf_setnonblock(pcap_t *p, int nonblock, char *errbuf)
+sf_setnonblock(pcap_t *p, int nonblock _U_)
{
/*
* This is a savefile, not a live capture file, so reject
@@ -118,7 +110,7 @@ sf_setnonblock(pcap_t *p, int nonblock, char *errbuf)
}
static int
-sf_stats(pcap_t *p, struct pcap_stat *ps)
+sf_stats(pcap_t *p, struct pcap_stat *ps _U_)
{
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"Statistics aren't available from savefiles");
@@ -236,7 +228,7 @@ sf_inject(pcap_t *p, const void *buf _U_, size_t size _U_)
* single device? IN, OUT or both?
*/
static int
-sf_setdirection(pcap_t *p, pcap_direction_t d)
+sf_setdirection(pcap_t *p, pcap_direction_t d _U_)
{
pcap_snprintf(p->errbuf, sizeof(p->errbuf),
"Setting direction is not supported on savefiles");
@@ -253,22 +245,6 @@ sf_cleanup(pcap_t *p)
pcap_freecode(&p->fcode);
}
-/*
-* fopen's safe version on Windows.
-*/
-#ifdef _MSC_VER
-FILE *fopen_safe(const char *filename, const char* mode)
-{
- FILE *fp = NULL;
- errno_t errno;
- errno = fopen_s(&fp, filename, mode);
- if (errno == 0)
- return fp;
- else
- return NULL;
-}
-#endif
-
pcap_t *
pcap_open_offline_with_tstamp_precision(const char *fname, u_int precision,
char *errbuf)
@@ -293,14 +269,16 @@ pcap_open_offline_with_tstamp_precision(const char *fname, u_int precision,
#endif
}
else {
-#if !defined(_WIN32) && !defined(MSDOS)
- fp = fopen(fname, "r");
-#else
+ /*
+ * "b" is supported as of C90, so *all* UN*Xes should
+ * support it, even though it does nothing. It's
+ * required on Windows, as the file is a binary file
+ * and must be read in binary mode.
+ */
fp = fopen(fname, "rb");
-#endif
if (fp == NULL) {
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", fname,
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ errno, "%s", fname);
return (NULL);
}
}
@@ -329,14 +307,16 @@ pcap_t* pcap_hopen_offline_with_tstamp_precision(intptr_t osfd, u_int precision,
fd = _open_osfhandle(osfd, _O_RDONLY);
if ( fd < 0 )
{
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ errno, "_open_osfhandle");
return NULL;
}
file = _fdopen(fd, "rb");
if ( file == NULL )
{
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ errno, "_fdopen");
return NULL;
}
@@ -373,7 +353,7 @@ pcap_fopen_offline_with_tstamp_precision(FILE *fp, u_int precision,
/*
* Read the first 4 bytes of the file; the network analyzer dump
- * file formats we support (pcap and pcap-ng), and several other
+ * file formats we support (pcap and pcapng), and several other
* formats we might support in the future (such as snoop, DOS and
* Windows Sniffer, and Microsoft Network Monitor) all have magic
* numbers that are unique in their first 4 bytes.
@@ -381,9 +361,8 @@ pcap_fopen_offline_with_tstamp_precision(FILE *fp, u_int precision,
amt_read = fread((char *)&magic, 1, sizeof(magic), fp);
if (amt_read != sizeof(magic)) {
if (ferror(fp)) {
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "error reading dump file: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ errno, "error reading dump file");
} else {
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"truncated dump file; tried to read %lu file header bytes, only got %lu",
diff --git a/contrib/libpcap/scanner.l b/contrib/libpcap/scanner.l
index d71a9bed1b5d5..e0890b43b1b9d 100644
--- a/contrib/libpcap/scanner.l
+++ b/contrib/libpcap/scanner.l
@@ -1,8 +1,30 @@
%top {
/* Must come first for _LARGE_FILE_API on AIX. */
#ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
#endif
+
+/*
+ * Must come first to avoid warnings on Windows.
+ *
+ * Flex-generated scanners may only include <inttypes.h> if __STDC_VERSION__
+ * is defined with a value >= 199901, meaning "full C99", and MSVC may not
+ * define it with that value, because it isn't 100% C99-compliant, even
+ * though it has an <inttypes.h> capable of defining everything the Flex
+ * scanner needs.
+ *
+ * We, however, will include it if we know we have an MSVC version that has
+ * it; this means that we may define the INTn_MAX and UINTn_MAX values in
+ * scanner.c, and then include <stdint.h>, which may define them differently
+ * (same value, but different string of characters), causing compiler warnings.
+ *
+ * If we include it here, and they're defined, that'll prevent scanner.c
+ * from defining them. So we include <pcap/pcap-inttypes.h>, to get
+ * <inttypes.h> if we have it.
+ */
+#include <pcap/pcap-inttypes.h>
+
+#include "diag-control.h"
}
/*
@@ -61,24 +83,8 @@
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * $FreeBSD$
*/
-#ifdef _WIN32
- #include <pcap-stdinc.h>
-#else
- #if HAVE_INTTYPES_H
- #include <inttypes.h>
- #elif HAVE_STDINT_H
- #include <stdint.h>
- #endif
- #ifdef HAVE_SYS_BITYPES_H
- #include <sys/bitypes.h>
- #endif
- #include <sys/types.h>
-#endif
-
#include <ctype.h>
#include <string.h>
@@ -98,6 +104,8 @@ void pcap_set_column(int, yyscan_t);
#ifdef INET6
#ifdef _WIN32
+#include <winsock2.h>
+#include <ws2tcpip.h>
/*
* To quote the MSDN page for getaddrinfo() at
*
@@ -117,10 +125,9 @@ void pcap_set_column(int, yyscan_t);
* Wspiapi.h header file. This inline code will be used on older Windows
* platforms that do not natively support the getaddrinfo function."
*
- * We use getaddrinfo(), so we include Wspiapi.h here. pcap-stdinc.h
- * includes Ws2tcpip.h, so we don't need to include it ourselves.
+ * We use getaddrinfo(), so we include Wspiapi.h here.
*/
-#include <Wspiapi.h>
+#include <wspiapi.h>
#else /* _WIN32 */
#include <sys/socket.h> /* for "struct sockaddr" in "struct addrinfo" */
#include <netdb.h> /* for "struct addrinfo" */
@@ -143,6 +150,11 @@ void pcap_set_column(int, yyscan_t);
static int stoi(char *);
static inline int xdtoi(int);
+/*
+ * Disable diagnostics in the code generated by Flex.
+ */
+DIAG_OFF_FLEX
+
%}
N ([0-9]+|(0X|0x)[0-9A-Fa-f]+)
@@ -430,6 +442,36 @@ icmp-ireq { yylval->i = 15; return NUM; }
icmp-ireqreply { yylval->i = 16; return NUM; }
icmp-maskreq { yylval->i = 17; return NUM; }
icmp-maskreply { yylval->i = 18; return NUM; }
+
+icmp6type { yylval->i = 0; return NUM; }
+icmp6code { yylval->i = 1; return NUM; }
+
+icmp6-echo { yylval->i = 128; return NUM; }
+icmp6-echoreply { yylval->i = 129; return NUM; }
+icmp6-multicastlistenerquery { yylval->i = 130; return NUM; }
+icmp6-multicastlistenerreportv1 { yylval->i = 131; return NUM; }
+icmp6-multicastlistenerdone { yylval->i = 132; return NUM; }
+icmp6-routersolicit { yylval->i = 133; return NUM; }
+icmp6-routeradvert { yylval->i = 134; return NUM; }
+icmp6-neighborsolicit { yylval->i = 135; return NUM; }
+icmp6-neighboradvert { yylval->i = 136; return NUM; }
+icmp6-redirect { yylval->i = 137; return NUM; }
+icmp6-routerrenum { yylval->i = 138; return NUM; }
+icmp6-nodeinformationquery { yylval->i = 139; return NUM; }
+icmp6-nodeinformationresponse { yylval->i = 140; return NUM; }
+icmp6-ineighbordiscoverysolicit { yylval->i = 141; return NUM; }
+icmp6-ineighbordiscoveryadvert { yylval->i = 142; return NUM; }
+icmp6-multicastlistenerreportv2 { yylval->i = 143; return NUM; }
+icmp6-homeagentdiscoveryrequest { yylval->i = 144; return NUM; }
+icmp6-homeagentdiscoveryreply { yylval->i = 145; return NUM; }
+icmp6-mobileprefixsolicit { yylval->i = 146; return NUM; }
+icmp6-mobileprefixadvert { yylval->i = 147; return NUM; }
+icmp6-certpathsolicit { yylval->i = 148; return NUM; }
+icmp6-certpathadvert { yylval->i = 149; return NUM; }
+icmp6-multicastrouteradvert { yylval->i = 151; return NUM; }
+icmp6-multicastroutersolicit { yylval->i = 152; return NUM; }
+icmp6-multicastrouterterm { yylval->i = 153; return NUM; }
+
tcpflags { yylval->i = 13; return NUM; }
tcp-fin { yylval->i = 0x01; return NUM; }
tcp-syn { yylval->i = 0x02; return NUM; }
@@ -447,10 +489,14 @@ tcp-cwr { yylval->i = 0x80; return NUM; }
. { bpf_error(yyextra, "illegal char '%c'", *yytext); }
%%
+/*
+ * Turn diagnostics back on, so we check the code that we've written.
+ */
+DIAG_ON_FLEX
+
/* Hex digit to integer. */
static inline int
-xdtoi(c)
- register int c;
+xdtoi(int c)
{
if (isdigit(c))
return c - '0';
@@ -465,8 +511,7 @@ xdtoi(c)
* preceding 0x or 0 and uses hex or octal instead of decimal.
*/
static int
-stoi(s)
- char *s;
+stoi(char *s)
{
int base = 10;
int n = 0;
diff --git a/contrib/libpcap/sf-pcap.c b/contrib/libpcap/sf-pcap.c
index ac305d4b01f32..96cb30801fc3a 100644
--- a/contrib/libpcap/sf-pcap.c
+++ b/contrib/libpcap/sf-pcap.c
@@ -28,27 +28,14 @@
* dependent values so we can print the dump file on any architecture.
*/
-#ifndef lint
-static const char rcsid[] _U_ =
- "@(#) $Header$ (LBL)";
-#endif
-
#ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
#endif
+#include <pcap-types.h>
#ifdef _WIN32
-#include <pcap-stdinc.h>
-#else /* _WIN32 */
-#if HAVE_INTTYPES_H
-#include <inttypes.h>
-#elif HAVE_STDINT_H
-#include <stdint.h>
-#endif
-#ifdef HAVE_SYS_BITYPES_H
-#include <sys/bitypes.h>
-#endif
-#include <sys/types.h>
+#include <io.h>
+#include <fcntl.h>
#endif /* _WIN32 */
#include <errno.h>
@@ -185,9 +172,8 @@ pcap_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
sizeof(hdr) - sizeof(hdr.magic), fp);
if (amt_read != sizeof(hdr) - sizeof(hdr.magic)) {
if (ferror(fp)) {
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "error reading dump file: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ errno, "error reading dump file");
} else {
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"truncated dump file; tried to read %lu file header bytes, only got %lu",
@@ -232,14 +218,6 @@ pcap_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
return NULL;
}
- if (hdr.snaplen > MAXIMUM_SNAPLEN) {
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "invalid file capture length %u, bigger than "
- "maximum of %u", hdr.snaplen, MAXIMUM_SNAPLEN);
- *err = 1;
- return NULL;
- }
-
/*
* OK, this is a good pcap file.
* Allocate a pcap_t for it.
@@ -255,6 +233,17 @@ pcap_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
p->version_minor = hdr.version_minor;
p->tzoff = hdr.thiszone;
p->snapshot = hdr.snaplen;
+ if (p->snapshot <= 0) {
+ /*
+ * Bogus snapshot length; use the maximum for this
+ * link-layer type as a fallback.
+ *
+ * XXX - the only reason why snapshot is signed is
+ * that pcap_snapshot() returns an int, not an
+ * unsigned int.
+ */
+ p->snapshot = max_snaplen_for_dlt(hdr.linktype);
+ }
p->linktype = linktype_to_dlt(LT_LINKTYPE(hdr.linktype));
p->linktype_ext = LT_LINKTYPE_EXT(hdr.linktype);
@@ -390,14 +379,16 @@ pcap_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
/*
* Allocate a buffer for the packet data.
+ * Choose the minimum of the file's snapshot length and 2K bytes;
+ * that should be enough for most network packets - we'll grow it
+ * if necessary. That way, we don't allocate a huge chunk of
+ * memory just because there's a huge snapshot length, as the
+ * snapshot length might be larger than the size of the largest
+ * packet.
*/
p->bufsize = p->snapshot;
- if (p->bufsize <= 0) {
- /*
- * Bogus snapshot length; use the maximum as a fallback.
- */
- p->bufsize = MAXIMUM_SNAPLEN;
- }
+ if (p->bufsize > 2048)
+ p->bufsize = 2048;
p->buffer = malloc(p->bufsize);
if (p->buffer == NULL) {
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "out of memory");
@@ -412,6 +403,24 @@ pcap_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
}
/*
+ * Grow the packet buffer to the specified size.
+ */
+static int
+grow_buffer(pcap_t *p, u_int bufsize)
+{
+ void *bigger_buffer;
+
+ bigger_buffer = realloc(p->buffer, bufsize);
+ if (bigger_buffer == NULL) {
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "out of memory");
+ return (0);
+ }
+ p->buffer = bigger_buffer;
+ p->bufsize = bufsize;
+ return (1);
+}
+
+/*
* Read and return the next packet from the savefile. Return the header
* in hdr and a pointer to the contents in data. Return 0 on success, 1
* if there were no more packets, and -1 on an error.
@@ -435,9 +444,8 @@ pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
amt_read = fread(&sf_hdr, 1, ps->hdrsize, fp);
if (amt_read != ps->hdrsize) {
if (ferror(fp)) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "error reading dump file: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "error reading dump file");
return (-1);
} else {
if (amt_read != 0) {
@@ -513,41 +521,87 @@ pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
break;
}
- if (hdr->caplen > p->bufsize) {
+ /*
+ * Is the packet bigger than we consider sane?
+ */
+ if (hdr->caplen > max_snaplen_for_dlt(p->linktype)) {
+ /*
+ * Yes. This may be a damaged or fuzzed file.
+ *
+ * Is it bigger than the snapshot length?
+ * (We don't treat that as an error if it's not
+ * bigger than the maximum we consider sane; see
+ * below.)
+ */
+ if (hdr->caplen > (bpf_u_int32)p->snapshot) {
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "invalid packet capture length %u, bigger than "
+ "snaplen of %d", hdr->caplen, p->snapshot);
+ } else {
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "invalid packet capture length %u, bigger than "
+ "maximum of %u", hdr->caplen,
+ max_snaplen_for_dlt(p->linktype));
+ }
+ return (-1);
+ }
+
+ if (hdr->caplen > (bpf_u_int32)p->snapshot) {
/*
+ * The packet is bigger than the snapshot length
+ * for this file.
+ *
* This can happen due to Solaris 2.3 systems tripping
* over the BUFMOD problem and not setting the snapshot
- * correctly in the savefile header.
- * This can also happen with a corrupted savefile or a
- * savefile built/modified by a fuzz tester.
- * If the caplen isn't grossly wrong, try to salvage.
+ * length correctly in the savefile header.
+ *
+ * libpcap 0.4 and later on Solaris 2.3 should set the
+ * snapshot length correctly in the pcap file header,
+ * even though they don't set a snapshot length in bufmod
+ * (the buggy bufmod chops off the *beginning* of the
+ * packet if a snapshot length is specified); they should
+ * also reduce the captured length, as supplied to the
+ * per-packet callback, to the snapshot length if it's
+ * greater than the snapshot length, so the code using
+ * libpcap should see the packet cut off at the snapshot
+ * length, even though the full packet is copied up to
+ * userland.
+ *
+ * However, perhaps some versions of libpcap failed to
+ * set the snapshot length currectly in the file header
+ * or the per-packet header, or perhaps this is a
+ * corrupted safefile or a savefile built/modified by a
+ * fuzz tester, so we check anyway. We grow the buffer
+ * to be big enough for the snapshot length, read up
+ * to the snapshot length, discard the rest of the
+ * packet, and report the snapshot length as the captured
+ * length; we don't want to hand our caller a packet
+ * bigger than the snapshot length, because they might
+ * be assuming they'll never be handed such a packet,
+ * and might copy the packet into a snapshot-length-
+ * sized buffer, assuming it'll fit.
*/
size_t bytes_to_discard;
size_t bytes_to_read, bytes_read;
char discard_buf[4096];
- if (hdr->caplen > MAXIMUM_SNAPLEN) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "invalid packet capture length %u, bigger than "
- "maximum of %u", hdr->caplen, MAXIMUM_SNAPLEN);
- return (-1);
+ if (hdr->caplen > p->bufsize) {
+ /*
+ * Grow the buffer to the snapshot length.
+ */
+ if (!grow_buffer(p, p->snapshot))
+ return (-1);
}
/*
- * XXX - we don't grow the buffer here because some
- * program might assume that it will never get packets
- * bigger than the snapshot length; for example, it might
- * copy data from our buffer to a buffer of its own,
- * allocated based on the return value of pcap_snapshot().
- *
- * Read the first p->bufsize bytes into the buffer.
+ * Read the first p->snapshot bytes into the buffer.
*/
- amt_read = fread(p->buffer, 1, p->bufsize, fp);
- if (amt_read != p->bufsize) {
+ amt_read = fread(p->buffer, 1, p->snapshot, fp);
+ if (amt_read != (bpf_u_int32)p->snapshot) {
if (ferror(fp)) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "error reading dump file: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf,
+ PCAP_ERRBUF_SIZE, errno,
+ "error reading dump file");
} else {
/*
* Yes, this uses hdr->caplen; technically,
@@ -558,7 +612,7 @@ pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
*/
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"truncated dump file; tried to read %u captured bytes, only got %lu",
- hdr->caplen, (unsigned long)amt_read);
+ p->snapshot, (unsigned long)amt_read);
}
return (-1);
}
@@ -566,7 +620,7 @@ pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
/*
* Now read and discard what's left.
*/
- bytes_to_discard = hdr->caplen - p->bufsize;
+ bytes_to_discard = hdr->caplen - p->snapshot;
bytes_read = amt_read;
while (bytes_to_discard != 0) {
bytes_to_read = bytes_to_discard;
@@ -576,9 +630,9 @@ pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
bytes_read += amt_read;
if (amt_read != bytes_to_read) {
if (ferror(fp)) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "error reading dump file: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf,
+ PCAP_ERRBUF_SIZE, errno,
+ "error reading dump file");
} else {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"truncated dump file; tried to read %u captured bytes, only got %lu",
@@ -593,15 +647,41 @@ pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
* Adjust caplen accordingly, so we don't get confused later
* as to how many bytes we have to play with.
*/
- hdr->caplen = p->bufsize;
+ hdr->caplen = p->snapshot;
} else {
+ if (hdr->caplen > p->bufsize) {
+ /*
+ * Grow the buffer to the next power of 2, or
+ * the snaplen, whichever is lower.
+ */
+ u_int new_bufsize;
+
+ new_bufsize = hdr->caplen;
+ /*
+ * http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
+ */
+ new_bufsize--;
+ new_bufsize |= new_bufsize >> 1;
+ new_bufsize |= new_bufsize >> 2;
+ new_bufsize |= new_bufsize >> 4;
+ new_bufsize |= new_bufsize >> 8;
+ new_bufsize |= new_bufsize >> 16;
+ new_bufsize++;
+
+ if (new_bufsize > (u_int)p->snapshot)
+ new_bufsize = p->snapshot;
+
+ if (!grow_buffer(p, new_bufsize))
+ return (-1);
+ }
+
/* read the packet itself */
amt_read = fread(p->buffer, 1, hdr->caplen, fp);
if (amt_read != hdr->caplen) {
if (ferror(fp)) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "error reading dump file: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf,
+ PCAP_ERRBUF_SIZE, errno,
+ "error reading dump file");
} else {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"truncated dump file; tried to read %u captured bytes, only got %lu",
@@ -672,11 +752,11 @@ pcap_setup_dump(pcap_t *p, int linktype, FILE *f, const char *fname)
if (f == stdout)
SET_BINMODE(f);
else
- setbuf(f, NULL);
+ setvbuf(f, NULL, _IONBF, 0);
#endif
if (sf_write_header(p, f, linktype, p->tzoff, p->snapshot) == -1) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Can't write to %s: %s",
- fname, pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "Can't write to %s", fname);
if (f != stdout)
(void)fclose(f);
return (NULL);
@@ -721,14 +801,16 @@ pcap_dump_open(pcap_t *p, const char *fname)
f = stdout;
fname = "standard output";
} else {
-#if !defined(_WIN32) && !defined(MSDOS)
- f = fopen(fname, "w");
-#else
+ /*
+ * "b" is supported as of C90, so *all* UN*Xes should
+ * support it, even though it does nothing. It's
+ * required on Windows, as the file is a binary file
+ * and must be written in binary mode.
+ */
f = fopen(fname, "wb");
-#endif
if (f == NULL) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s",
- fname, pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "%s", fname);
return (NULL);
}
}
@@ -779,14 +861,15 @@ pcap_dump_open_append(pcap_t *p, const char *fname)
if (fname[0] == '-' && fname[1] == '\0')
return (pcap_setup_dump(p, linktype, stdout, "standard output"));
-#if !defined(_WIN32) && !defined(MSDOS)
- f = fopen(fname, "r+");
-#else
+ /*
+ * "b" is supported as of C90, so *all* UN*Xes should support it,
+ * even though it does nothing. It's required on Windows, as the
+ * file is a binary file and must be read in binary mode.
+ */
f = fopen(fname, "rb+");
-#endif
if (f == NULL) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s",
- fname, pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "%s", fname);
return (NULL);
}
@@ -796,8 +879,8 @@ pcap_dump_open_append(pcap_t *p, const char *fname)
amt_read = fread(&ph, 1, sizeof (ph), f);
if (amt_read != sizeof (ph)) {
if (ferror(f)) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s",
- fname, pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "%s", fname);
fclose(f);
return (NULL);
} else if (feof(f) && amt_read > 0) {
@@ -813,7 +896,7 @@ pcap_dump_open_append(pcap_t *p, const char *fname)
* We turn off buffering.
* XXX - why? And why not on the standard output?
*/
- setbuf(f, NULL);
+ setvbuf(f, NULL, _IONBF, 0);
#endif
/*
@@ -904,8 +987,8 @@ pcap_dump_open_append(pcap_t *p, const char *fname)
* A header isn't present; attempt to write it.
*/
if (sf_write_header(p, f, linktype, p->tzoff, p->snapshot) == -1) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Can't write to %s: %s",
- fname, pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "Can't write to %s", fname);
(void)fclose(f);
return (NULL);
}
@@ -915,8 +998,8 @@ pcap_dump_open_append(pcap_t *p, const char *fname)
* Start writing at the end of the file.
*/
if (fseek(f, 0, SEEK_END) == -1) {
- pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Can't seek to end of %s: %s",
- fname, pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "Can't seek to end of %s", fname);
(void)fclose(f);
return (NULL);
}
@@ -935,6 +1018,45 @@ pcap_dump_ftell(pcap_dumper_t *p)
return (ftell((FILE *)p));
}
+#if defined(HAVE_FSEEKO)
+/*
+ * We have fseeko(), so we have ftello().
+ * If we have large file support (files larger than 2^31-1 bytes),
+ * ftello() will give us a current file position with more than 32
+ * bits.
+ */
+int64_t
+pcap_dump_ftell64(pcap_dumper_t *p)
+{
+ return (ftello((FILE *)p));
+}
+#elif defined(_MSC_VER)
+/*
+ * We have Visual Studio; we support only 2005 and later, so we have
+ * _ftelli64().
+ */
+int64_t
+pcap_dump_ftell64(pcap_dumper_t *p)
+{
+ return (_ftelli64((FILE *)p));
+}
+#else
+/*
+ * We don't have ftello() or _ftelli64(), so fall back on ftell().
+ * Either long is 64 bits, in which case ftell() should suffice,
+ * or this is probably an older 32-bit UN*X without large file
+ * support, which means you'll probably get errors trying to
+ * write files > 2^31-1, so it won't matter anyway.
+ *
+ * XXX - what about MinGW?
+ */
+int64_t
+pcap_dump_ftell64(pcap_dumper_t *p)
+{
+ return (ftell((FILE *)p));
+}
+#endif
+
int
pcap_dump_flush(pcap_dumper_t *p)
{
diff --git a/contrib/libpcap/sf-pcap-ng.c b/contrib/libpcap/sf-pcapng.c
index 0c02829e71e53..0f155afa97889 100644
--- a/contrib/libpcap/sf-pcap-ng.c
+++ b/contrib/libpcap/sf-pcapng.c
@@ -18,31 +18,14 @@
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * sf-pcap-ng.c - pcap-ng-file-format-specific code from savefile.c
+ * sf-pcapng.c - pcapng-file-format-specific code from savefile.c
*/
-#ifndef lint
-static const char rcsid[] _U_ =
- "@(#) $Header$ (LBL)";
-#endif
-
#ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
#endif
-#ifdef _WIN32
-#include <pcap-stdinc.h>
-#else /* _WIN32 */
-#if HAVE_INTTYPES_H
-#include <inttypes.h>
-#elif HAVE_STDINT_H
-#include <stdint.h>
-#endif
-#ifdef HAVE_SYS_BITYPES_H
-#include <sys/bitypes.h>
-#endif
-#include <sys/types.h>
-#endif /* _WIN32 */
+#include <pcap/pcap-inttypes.h>
#include <errno.h>
#include <memory.h>
@@ -58,7 +41,7 @@ static const char rcsid[] _U_ =
#include "os-proto.h"
#endif
-#include "sf-pcap-ng.h"
+#include "sf-pcapng.h"
/*
* Block types.
@@ -107,7 +90,7 @@ struct section_header_block {
bpf_u_int32 byte_order_magic;
u_short major_version;
u_short minor_version;
- u_int64_t section_length;
+ uint64_t section_length;
/* followed by options and trailer */
};
@@ -217,16 +200,48 @@ struct pcap_ng_if {
u_int tsresol; /* time stamp resolution */
tstamp_scale_type_t scale_type; /* how to scale */
u_int scale_factor; /* time stamp scale factor for power-of-10 tsresol */
- u_int64_t tsoffset; /* time stamp offset */
+ uint64_t tsoffset; /* time stamp offset */
};
+/*
+ * Per-pcap_t private data.
+ *
+ * max_blocksize is the maximum size of a block that we'll accept. We
+ * reject blocks bigger than this, so we don't consume too much memory
+ * with a truly huge block. It can change as we see IDBs with different
+ * link-layer header types. (Currently, we don't support IDBs with
+ * different link-layer header types, but we will support it in the
+ * future, when we offer file-reading APIs that support it.)
+ *
+ * XXX - that's an issue on ILP32 platforms, where the maximum block
+ * size of 2^31-1 would eat all but one byte of the entire address space.
+ * It's less of an issue on ILP64/LLP64 platforms, but the actual size
+ * of the address space may be limited by 1) the number of *significant*
+ * address bits (currently, x86-64 only supports 48 bits of address), 2)
+ * any limitations imposed by the operating system; 3) any limitations
+ * imposed by the amount of available backing store for anonymous pages,
+ * so we impose a limit regardless of the size of a pointer.
+ */
struct pcap_ng_sf {
u_int user_tsresol; /* time stamp resolution requested by the user */
+ u_int max_blocksize; /* don't grow buffer size past this */
bpf_u_int32 ifcount; /* number of interfaces seen in this capture */
bpf_u_int32 ifaces_size; /* size of array below */
struct pcap_ng_if *ifaces; /* array of interface information */
};
+/*
+ * Maximum block size for a given maximum snapshot length; we calculate
+ * this based
+ *
+ * We define it as the size of an EPB with a max_snaplen-sized
+ * packet and 128KB of options.
+ */
+#define MAX_BLOCKSIZE(max_snaplen) (sizeof (struct block_header) + \
+ sizeof (struct enhanced_packet_block) + \
+ (max_snaplen) + 131072 + \
+ sizeof (struct block_trailer))
+
static void pcap_ng_cleanup(pcap_t *p);
static int pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr,
u_char **data);
@@ -240,9 +255,8 @@ read_bytes(FILE *fp, void *buf, size_t bytes_to_read, int fail_on_eof,
amt_read = fread(buf, 1, bytes_to_read, fp);
if (amt_read != bytes_to_read) {
if (ferror(fp)) {
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "error reading dump file: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ errno, "error reading dump file");
} else {
if (amt_read == 0 && !fail_on_eof)
return (0); /* EOF */
@@ -259,11 +273,14 @@ read_bytes(FILE *fp, void *buf, size_t bytes_to_read, int fail_on_eof,
static int
read_block(FILE *fp, pcap_t *p, struct block_cursor *cursor, char *errbuf)
{
+ struct pcap_ng_sf *ps;
int status;
struct block_header bhdr;
u_char *bdata;
size_t data_remaining;
+ ps = p->priv;
+
status = read_bytes(fp, &bhdr, sizeof(bhdr), 0, errbuf);
if (status <= 0)
return (status); /* error or EOF */
@@ -282,7 +299,7 @@ read_block(FILE *fp, pcap_t *p, struct block_cursor *cursor, char *errbuf)
*/
if (bhdr.total_length > 16*1024*1024) {
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "pcap-ng block size %u > maximum %u",
+ "pcapng block size %u > maximum %u",
bhdr.total_length, 16*1024*1024);
return (-1);
}
@@ -294,7 +311,7 @@ read_block(FILE *fp, pcap_t *p, struct block_cursor *cursor, char *errbuf)
if (bhdr.total_length < sizeof(struct block_header) +
sizeof(struct block_trailer)) {
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "block in pcap-ng dump file has a length of %u < %lu",
+ "block in pcapng dump file has a length of %u < %lu",
bhdr.total_length,
(unsigned long)(sizeof(struct block_header) + sizeof(struct block_trailer)));
return (-1);
@@ -305,10 +322,15 @@ read_block(FILE *fp, pcap_t *p, struct block_cursor *cursor, char *errbuf)
*/
if (p->bufsize < bhdr.total_length) {
/*
- * No - make it big enough.
+ * No - make it big enough, unless it's too big.
*/
void *bigger_buffer;
+ if (bhdr.total_length > ps->max_blocksize) {
+ pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "block is larger than maximum block size %u",
+ ps->max_blocksize);
+ return (-1);
+ }
bigger_buffer = realloc(p->buffer, bhdr.total_length);
if (bigger_buffer == NULL) {
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "out of memory");
@@ -348,7 +370,7 @@ get_from_block_data(struct block_cursor *cursor, size_t chunk_size,
*/
if (cursor->data_remaining < chunk_size) {
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "block of type %u in pcap-ng dump file is too short",
+ "block of type %u in pcapng dump file is too short",
cursor->block_type);
return (NULL);
}
@@ -410,7 +432,7 @@ get_optvalue_from_block_data(struct block_cursor *cursor,
static int
process_idb_options(pcap_t *p, struct block_cursor *cursor, u_int *tsresol,
- u_int64_t *tsoffset, int *is_binary, char *errbuf)
+ uint64_t *tsoffset, int *is_binary, char *errbuf)
{
struct option_header *opthdr;
void *optvalue;
@@ -533,7 +555,7 @@ add_interface(pcap_t *p, struct block_cursor *cursor, char *errbuf)
{
struct pcap_ng_sf *ps;
u_int tsresol;
- u_int64_t tsoffset;
+ uint64_t tsoffset;
int is_binary;
ps = p->priv;
@@ -567,7 +589,7 @@ add_interface(pcap_t *p, struct block_cursor *cursor, char *errbuf)
* However, it doesn't complain that one of the
* multiplications below could overflow, which is
* a real, albeit extremely unlikely, problem (you'd
- * need a pcap-ng file with tens of millions of
+ * need a pcapng file with tens of millions of
* interfaces).)
*/
new_ifaces_size = 1;
@@ -699,7 +721,7 @@ add_interface(pcap_t *p, struct block_cursor *cursor, char *errbuf)
}
/*
- * Check whether this is a pcap-ng savefile and, if it is, extract the
+ * Check whether this is a pcapng savefile and, if it is, extract the
* relevant information from the header.
*/
pcap_t *
@@ -725,7 +747,7 @@ pcap_ng_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
/*
* Check whether the first 4 bytes of the file are the block
- * type for a pcap-ng savefile.
+ * type for a pcapng savefile.
*/
if (magic != BT_SHB) {
/*
@@ -734,7 +756,7 @@ pcap_ng_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
* UN*X and DOS/Windows text file format and, if it
* does, look for the byte-order magic number in
* the appropriate place and, if we find it, report
- * this as possibly being a pcap-ng file transferred
+ * this as possibly being a pcapng file transferred
* between UN*X and Windows in text file format?
*/
return (NULL); /* nope */
@@ -754,32 +776,30 @@ pcap_ng_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
amt_read = fread(&total_length, 1, sizeof(total_length), fp);
if (amt_read < sizeof(total_length)) {
if (ferror(fp)) {
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "error reading dump file: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ errno, "error reading dump file");
*err = 1;
return (NULL); /* fail */
}
/*
* Possibly a weird short text file, so just say
- * "not pcap-ng".
+ * "not pcapng".
*/
return (NULL);
}
amt_read = fread(&byte_order_magic, 1, sizeof(byte_order_magic), fp);
if (amt_read < sizeof(byte_order_magic)) {
if (ferror(fp)) {
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "error reading dump file: %s",
- pcap_strerror(errno));
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ errno, "error reading dump file");
*err = 1;
return (NULL); /* fail */
}
/*
* Possibly a weird short text file, so just say
- * "not pcap-ng".
+ * "not pcapng".
*/
return (NULL);
}
@@ -787,7 +807,7 @@ pcap_ng_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
byte_order_magic = SWAPLONG(byte_order_magic);
if (byte_order_magic != BYTE_ORDER_MAGIC) {
/*
- * Not a pcap-ng file.
+ * Not a pcapng file.
*/
return (NULL);
}
@@ -800,7 +820,7 @@ pcap_ng_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
*/
if (total_length < sizeof(*bhdrp) + sizeof(*shbp) + sizeof(struct block_trailer)) {
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "Section Header Block in pcap-ng dump file has a length of %u < %lu",
+ "Section Header Block in pcapng dump file has a length of %u < %lu",
total_length,
(unsigned long)(sizeof(*bhdrp) + sizeof(*shbp) + sizeof(struct block_trailer)));
*err = 1;
@@ -808,7 +828,7 @@ pcap_ng_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
}
/*
- * OK, this is a good pcap-ng file.
+ * OK, this is a good pcapng file.
* Allocate a pcap_t for it.
*/
p = pcap_open_offline_common(errbuf, sizeof (struct pcap_ng_sf));
@@ -853,7 +873,11 @@ pcap_ng_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
* Packet Block containing a full-size Ethernet frame, and
* leaving room for some options.
*
- * If we find a bigger block, we reallocate the buffer.
+ * If we find a bigger block, we reallocate the buffer, up to
+ * the maximum size. We start out with a maximum size based
+ * on a maximum snapshot length of MAXIMUM_SNAPLEN; if we see
+ * any link-layer header types with a larger maximum snapshot
+ * length, we boost the maximum.
*/
p->bufsize = 2048;
if (p->bufsize < total_length)
@@ -865,6 +889,7 @@ pcap_ng_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
*err = 1;
return (NULL);
}
+ ps->max_blocksize = MAX_BLOCKSIZE(MAXIMUM_SNAPLEN);
/*
* Copy the stuff we've read to the buffer, and read the rest
@@ -896,7 +921,7 @@ pcap_ng_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
if (! (shbp->major_version == PCAP_NG_VERSION_MAJOR &&
shbp->minor_version == PCAP_NG_VERSION_MINOR)) {
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "unsupported pcap-ng savefile version %u.%u",
+ "unsupported pcapng savefile version %u.%u",
shbp->major_version, shbp->minor_version);
goto fail;
}
@@ -945,17 +970,6 @@ pcap_ng_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
}
/*
- * Interface capture length sanity check
- */
- if (idbp->snaplen > MAXIMUM_SNAPLEN) {
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "invalid interface capture length %u, "
- "bigger than maximum of %u",
- idbp->snaplen, MAXIMUM_SNAPLEN);
- goto fail;
- }
-
- /*
* Try to add this interface.
*/
if (!add_interface(p, &cursor, errbuf))
@@ -986,9 +1000,28 @@ pcap_ng_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
done:
p->tzoff = 0; /* XXX - not used in pcap */
p->snapshot = idbp->snaplen;
+ if (p->snapshot <= 0) {
+ /*
+ * Bogus snapshot length; use the maximum for this
+ * link-layer type as a fallback.
+ *
+ * XXX - the only reason why snapshot is signed is
+ * that pcap_snapshot() returns an int, not an
+ * unsigned int.
+ */
+ p->snapshot = max_snaplen_for_dlt(idbp->linktype);
+ }
p->linktype = linktype_to_dlt(idbp->linktype);
p->linktype_ext = 0;
+ /*
+ * If the maximum block size for a packet with the maximum
+ * snapshot length for this DLT_ is bigger than the current
+ * maximum block size, increase the maximum.
+ */
+ if (MAX_BLOCKSIZE(max_snaplen_for_dlt(p->linktype)) > ps->max_blocksize)
+ ps->max_blocksize = MAX_BLOCKSIZE(max_snaplen_for_dlt(p->linktype));
+
p->next_packet_op = pcap_ng_next_packet;
p->cleanup_op = pcap_ng_cleanup;
@@ -1029,7 +1062,7 @@ pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
struct interface_description_block *idbp;
struct section_header_block *shbp;
FILE *fp = p->rfile;
- u_int64_t t, sec, frac;
+ uint64_t t, sec, frac;
/*
* Look for an Enhanced Packet Block, a Simple Packet Block,
@@ -1065,13 +1098,13 @@ pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
interface_id = SWAPLONG(epbp->interface_id);
hdr->caplen = SWAPLONG(epbp->caplen);
hdr->len = SWAPLONG(epbp->len);
- t = ((u_int64_t)SWAPLONG(epbp->timestamp_high)) << 32 |
+ t = ((uint64_t)SWAPLONG(epbp->timestamp_high)) << 32 |
SWAPLONG(epbp->timestamp_low);
} else {
interface_id = epbp->interface_id;
hdr->caplen = epbp->caplen;
hdr->len = epbp->len;
- t = ((u_int64_t)epbp->timestamp_high) << 32 |
+ t = ((uint64_t)epbp->timestamp_high) << 32 |
epbp->timestamp_low;
}
goto found;
@@ -1130,13 +1163,13 @@ pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
interface_id = SWAPSHORT(pbp->interface_id);
hdr->caplen = SWAPLONG(pbp->caplen);
hdr->len = SWAPLONG(pbp->len);
- t = ((u_int64_t)SWAPLONG(pbp->timestamp_high)) << 32 |
+ t = ((uint64_t)SWAPLONG(pbp->timestamp_high)) << 32 |
SWAPLONG(pbp->timestamp_low);
} else {
interface_id = pbp->interface_id;
hdr->caplen = pbp->caplen;
hdr->len = pbp->len;
- t = ((u_int64_t)pbp->timestamp_high) << 32 |
+ t = ((uint64_t)pbp->timestamp_high) << 32 |
pbp->timestamp_low;
}
goto found;
@@ -1245,7 +1278,7 @@ pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
*/
if (shbp->major_version != PCAP_NG_VERSION_MAJOR) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "unknown pcap-ng savefile major version number %u",
+ "unknown pcapng savefile major version number %u",
shbp->major_version);
return (-1);
}
@@ -1284,6 +1317,13 @@ found:
return (-1);
}
+ if (hdr->caplen > (bpf_u_int32)p->snapshot) {
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "invalid packet capture length %u, bigger than "
+ "snaplen of %d", hdr->caplen, p->snapshot);
+ return (-1);
+ }
+
/*
* Convert the time stamp to seconds and fractions of a second,
* with the fractions being in units of the file-supplied resolution.
diff --git a/contrib/libpcap/sf-pcap-ng.h b/contrib/libpcap/sf-pcapng.h
index 3c93498fb5692..d99b0d4e4e3e8 100644
--- a/contrib/libpcap/sf-pcap-ng.h
+++ b/contrib/libpcap/sf-pcapng.h
@@ -18,13 +18,13 @@
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * sf-pcap-ng.h - pcap-ng-file-format-specific routines
+ * sf-pcapng.h - pcapng-file-format-specific routines
*
- * Used to read pcap-ng savefiles.
+ * Used to read pcapng savefiles.
*/
-#ifndef sf_pcap_ng_h
-#define sf_pcap_ng_h
+#ifndef sf_pcapng_h
+#define sf_pcapng_h
extern pcap_t *pcap_ng_check_header(bpf_u_int32 magic, FILE *fp,
u_int precision, char *errbuf, int *err);
diff --git a/contrib/libpcap/sockutils.c b/contrib/libpcap/sockutils.c
index c05ff1a1b58b8..079c49db2cac1 100644
--- a/contrib/libpcap/sockutils.c
+++ b/contrib/libpcap/sockutils.c
@@ -31,7 +31,7 @@
*/
#ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
#endif
/*
@@ -50,7 +50,9 @@
* ways.
*/
-#include <string.h> /* for strerror() */
+#include "ftmacros.h"
+
+#include <string.h>
#include <errno.h> /* for the errno variable */
#include <stdio.h> /* for the stderr file */
#include <stdlib.h> /* for malloc() and free() */
@@ -60,8 +62,10 @@
#define INT_MAX 2147483647
#endif
-#include "portability.h"
+#include "pcap-int.h"
+
#include "sockutils.h"
+#include "portability.h"
#ifdef _WIN32
/*
@@ -88,6 +92,24 @@
#define SOCKET_NO_PORT_AVAILABLE "No port available"
#define SOCKET_NAME_NULL_DAD "Null address (possibly DAD Phase)"
+/*
+ * On UN*X, send() and recv() return ssize_t.
+ *
+ * On Windows, send() and recv() return an int.
+ *
+ * Wth MSVC, there *is* no ssize_t.
+ *
+ * With MinGW, there is an ssize_t type; it is either an int (32 bit)
+ * or a long long (64 bit).
+ *
+ * So, on Windows, if we don't have ssize_t defined, define it as an
+ * int, so we can use it, on all platforms, as the type of variables
+ * that hold the return values from send() and recv().
+ */
+#if defined(_WIN32) && !defined(_SSIZE_T_DEFINED)
+typedef int ssize_t;
+#endif
+
/****************************************************
* *
* Locally defined functions *
@@ -103,40 +125,21 @@ static int sock_ismcastaddr(const struct sockaddr *saddr);
****************************************************/
/*
- * \brief It retrieves the error message after an error occurred in the socket interface.
- *
- * This function is defined because of the different way errors are returned in UNIX
- * and Win32. This function provides a consistent way to retrieve the error message
- * (after a socket error occurred) on all the platforms.
- *
- * \param caller: a pointer to a user-allocated string which contains a message that has
- * to be printed *before* the true error message. It could be, for example, 'this error
- * comes from the recv() call at line 31'. It may be NULL.
- *
- * \param errbuf: a pointer to an user-allocated buffer that will contain the complete
- * error message. This buffer has to be at least 'errbuflen' in length.
- * It can be NULL; in this case the error cannot be printed.
- *
- * \param errbuflen: length of the buffer that will contains the error. The error message cannot be
- * larger than 'errbuflen - 1' because the last char is reserved for the string terminator.
- *
- * \return No return values. The error message is returned in the 'string' parameter.
+ * Format an error message given an errno value (UN*X) or a WinSock error
+ * (Windows).
*/
-void sock_geterror(const char *caller, char *errbuf, int errbuflen)
+void sock_fmterror(const char *caller, int errcode, char *errbuf, int errbuflen)
{
#ifdef _WIN32
int retval;
- int code;
TCHAR message[SOCK_ERRBUF_SIZE]; /* It will be char (if we're using ascii) or wchar_t (if we're using unicode) */
if (errbuf == NULL)
return;
- code = GetLastError();
-
retval = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS |
FORMAT_MESSAGE_MAX_WIDTH_MASK,
- NULL, code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ NULL, errcode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
message, sizeof(message) / sizeof(TCHAR), NULL);
if (retval == 0)
@@ -145,14 +148,13 @@ void sock_geterror(const char *caller, char *errbuf, int errbuflen)
pcap_snprintf(errbuf, errbuflen, "%sUnable to get the exact error message", caller);
else
pcap_snprintf(errbuf, errbuflen, "Unable to get the exact error message");
- return;
}
else
{
if ((caller) && (*caller))
- pcap_snprintf(errbuf, errbuflen, "%s%s (code %d)", caller, message, code);
+ pcap_snprintf(errbuf, errbuflen, "%s%s (code %d)", caller, message, errcode);
else
- pcap_snprintf(errbuf, errbuflen, "%s (code %d)", message, code);
+ pcap_snprintf(errbuf, errbuflen, "%s (code %d)", message, errcode);
}
#else
char *message;
@@ -160,12 +162,45 @@ void sock_geterror(const char *caller, char *errbuf, int errbuflen)
if (errbuf == NULL)
return;
- message = strerror(errno);
+ message = strerror(errcode);
if ((caller) && (*caller))
- pcap_snprintf(errbuf, errbuflen, "%s%s (code %d)", caller, message, errno);
+ pcap_snprintf(errbuf, errbuflen, "%s%s (code %d)", caller, message, errcode);
else
- pcap_snprintf(errbuf, errbuflen, "%s (code %d)", message, errno);
+ pcap_snprintf(errbuf, errbuflen, "%s (code %d)", message, errcode);
+#endif
+}
+
+/*
+ * \brief It retrieves the error message after an error occurred in the socket interface.
+ *
+ * This function is defined because of the different way errors are returned in UNIX
+ * and Win32. This function provides a consistent way to retrieve the error message
+ * (after a socket error occurred) on all the platforms.
+ *
+ * \param caller: a pointer to a user-allocated string which contains a message that has
+ * to be printed *before* the true error message. It could be, for example, 'this error
+ * comes from the recv() call at line 31'. It may be NULL.
+ *
+ * \param errbuf: a pointer to an user-allocated buffer that will contain the complete
+ * error message. This buffer has to be at least 'errbuflen' in length.
+ * It can be NULL; in this case the error cannot be printed.
+ *
+ * \param errbuflen: length of the buffer that will contains the error. The error message cannot be
+ * larger than 'errbuflen - 1' because the last char is reserved for the string terminator.
+ *
+ * \return No return values. The error message is returned in the 'string' parameter.
+ */
+void sock_geterror(const char *caller, char *errbuf, int errbuflen)
+{
+#ifdef _WIN32
+ if (errbuf == NULL)
+ return;
+ sock_fmterror(caller, GetLastError(), errbuf, errbuflen);
+#else
+ if (errbuf == NULL)
+ return;
+ sock_fmterror(caller, errno, errbuf, errbuflen);
#endif
}
@@ -185,9 +220,9 @@ void sock_geterror(const char *caller, char *errbuf, int errbuflen)
* \return '0' if everything is fine, '-1' if some errors occurred. The error message is returned
* in the 'errbuf' variable.
*/
+#ifdef _WIN32
int sock_init(char *errbuf, int errbuflen)
{
-#ifdef _WIN32
if (sockcount == 0)
{
WSADATA wsaData; /* helper variable needed to initialize Winsock */
@@ -205,8 +240,10 @@ int sock_init(char *errbuf, int errbuflen)
}
sockcount++;
+#else
+int sock_init(char *errbuf _U_, int errbuflen _U_)
+{
#endif
-
return 0;
}
@@ -277,56 +314,102 @@ static int sock_ismcastaddr(const struct sockaddr *saddr)
* larger than 'errbuflen - 1' because the last char is reserved for the string terminator.
*
* \return the socket that has been opened (that has to be used in the following sockets calls)
- * if everything is fine, '0' if some errors occurred. The error message is returned
+ * if everything is fine, INVALID_SOCKET if some errors occurred. The error message is returned
* in the 'errbuf' variable.
*/
SOCKET sock_open(struct addrinfo *addrinfo, int server, int nconn, char *errbuf, int errbuflen)
{
SOCKET sock;
+#if defined(SO_NOSIGPIPE) || defined(IPV6_V6ONLY) || defined(IPV6_BINDV6ONLY)
+ int on = 1;
+#endif
sock = socket(addrinfo->ai_family, addrinfo->ai_socktype, addrinfo->ai_protocol);
- if (sock == -1)
+ if (sock == INVALID_SOCKET)
{
sock_geterror("socket(): ", errbuf, errbuflen);
- return -1;
+ return INVALID_SOCKET;
}
+ /*
+ * Disable SIGPIPE, if we have SO_NOSIGPIPE. We don't want to
+ * have to deal with signals if the peer closes the connection,
+ * especially in client programs, which may not even be aware that
+ * they're sending to sockets.
+ */
+#ifdef SO_NOSIGPIPE
+ if (setsockopt(sock, SOL_SOCKET, SO_NOSIGPIPE, (char *)&on,
+ sizeof (int)) == -1)
+ {
+ sock_geterror("setsockopt(SO_NOSIGPIPE)", errbuf, errbuflen);
+ closesocket(sock);
+ return INVALID_SOCKET;
+ }
+#endif
/* This is a server socket */
if (server)
{
-#ifdef BSD
+#if defined(IPV6_V6ONLY) || defined(IPV6_BINDV6ONLY)
/*
- * Force the use of IPv6-only addresses; in BSD you can accept both v4 and v6
- * connections if you have a "NULL" pointer as the nodename in the getaddrinfo()
- * This behavior is not clear in the RFC 2553, so each system implements the
- * bind() differently from this point of view
+ * Force the use of IPv6-only addresses.
+ *
+ * RFC 3493 indicates that you can support IPv4 on an
+ * IPv6 socket:
+ *
+ * https://tools.ietf.org/html/rfc3493#section-3.7
+ *
+ * and that this is the default behavior. This means
+ * that if we first create an IPv6 socket bound to the
+ * "any" address, it is, in effect, also bound to the
+ * IPv4 "any" address, so when we create an IPv4 socket
+ * and try to bind it to the IPv4 "any" address, it gets
+ * EADDRINUSE.
+ *
+ * Not all network stacks support IPv4 on IPv6 sockets;
+ * pre-NT 6 Windows stacks don't support it, and the
+ * OpenBSD stack doesn't support it for security reasons
+ * (see the OpenBSD inet6(4) man page). Therefore, we
+ * don't want to rely on this behavior.
+ *
+ * So we try to disable it, using either the IPV6_V6ONLY
+ * option from RFC 3493:
+ *
+ * https://tools.ietf.org/html/rfc3493#section-5.3
+ *
+ * or the IPV6_BINDV6ONLY option from older UN*Xes.
*/
+#ifndef IPV6_V6ONLY
+ /* For older systems */
+ #define IPV6_V6ONLY IPV6_BINDV6ONLY
+#endif /* IPV6_V6ONLY */
if (addrinfo->ai_family == PF_INET6)
{
- int on;
-
- if (setsockopt(sock, IPPROTO_IPV6, IPV6_BINDV6ONLY, (char *)&on, sizeof (int)) == -1)
+ if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY,
+ (char *)&on, sizeof (int)) == -1)
{
if (errbuf)
- pcap_snprintf(errbuf, errbuflen, "setsockopt(IPV6_BINDV6ONLY)");
- return -1;
+ pcap_snprintf(errbuf, errbuflen, "setsockopt(IPV6_V6ONLY)");
+ closesocket(sock);
+ return INVALID_SOCKET;
}
}
-#endif
+#endif /* defined(IPV6_V6ONLY) || defined(IPV6_BINDV6ONLY) */
/* WARNING: if the address is a mcast one, I should place the proper Win32 code here */
if (bind(sock, addrinfo->ai_addr, (int) addrinfo->ai_addrlen) != 0)
{
sock_geterror("bind(): ", errbuf, errbuflen);
- return -1;
+ closesocket(sock);
+ return INVALID_SOCKET;
}
if (addrinfo->ai_socktype == SOCK_STREAM)
if (listen(sock, nconn) == -1)
{
sock_geterror("listen(): ", errbuf, errbuflen);
- return -1;
+ closesocket(sock);
+ return INVALID_SOCKET;
}
/* server side ended */
@@ -391,7 +474,7 @@ SOCKET sock_open(struct addrinfo *addrinfo, int server, int nconn, char *errbuf,
if (tempaddrinfo == NULL)
{
closesocket(sock);
- return -1;
+ return INVALID_SOCKET;
}
else
return sock;
@@ -513,6 +596,8 @@ int sock_initaddress(const char *host, const char *port,
{
if (errbuf)
pcap_snprintf(errbuf, errbuflen, "getaddrinfo(): socket type not supported");
+ freeaddrinfo(*addrinfo);
+ *addrinfo = NULL;
return -1;
}
@@ -524,6 +609,8 @@ int sock_initaddress(const char *host, const char *port,
{
if (errbuf)
pcap_snprintf(errbuf, errbuflen, "getaddrinfo(): multicast addresses are not valid when using TCP streams");
+ freeaddrinfo(*addrinfo);
+ *addrinfo = NULL;
return -1;
}
@@ -552,39 +639,84 @@ int sock_initaddress(const char *host, const char *port,
* \param errbuflen: length of the buffer that will contains the error. The error message cannot be
* larger than 'errbuflen - 1' because the last char is reserved for the string terminator.
*
- * \return '0' if everything is fine, '-1' if some errors occurred. The error message is returned
- * in the 'errbuf' variable.
+ * \return '0' if everything is fine, '-1' if an error other than
+ * "connection reset" or "peer has closed the receive side" occurred,
+ * '-2' if we got one of those errors.
+ * For errors, an error message is returned in the 'errbuf' variable.
*/
-int sock_send(SOCKET socket, const char *buffer, int size, char *errbuf, int errbuflen)
+int sock_send(SOCKET sock, const char *buffer, size_t size,
+ char *errbuf, int errbuflen)
{
- int nsent;
-
-send:
-#ifdef linux
- /*
- * Another pain... in Linux there's this flag
- * MSG_NOSIGNAL
- * Requests not to send SIGPIPE on errors on stream-oriented
- * sockets when the other end breaks the connection.
- * The EPIPE error is still returned.
- */
- nsent = send(socket, buffer, size, MSG_NOSIGNAL);
-#else
- nsent = send(socket, buffer, size, 0);
-#endif
+ int remaining;
+ ssize_t nsent;
- if (nsent == -1)
+ if (size > INT_MAX)
{
- sock_geterror("send(): ", errbuf, errbuflen);
+ if (errbuf)
+ {
+ pcap_snprintf(errbuf, errbuflen,
+ "Can't send more than %u bytes with sock_recv",
+ INT_MAX);
+ }
return -1;
}
+ remaining = (int)size;
- if (nsent != size)
- {
- size -= nsent;
+ do {
+#ifdef MSG_NOSIGNAL
+ /*
+ * Send with MSG_NOSIGNAL, so that we don't get SIGPIPE
+ * on errors on stream-oriented sockets when the other
+ * end breaks the connection.
+ * The EPIPE error is still returned.
+ */
+ nsent = send(sock, buffer, remaining, MSG_NOSIGNAL);
+#else
+ nsent = send(sock, buffer, remaining, 0);
+#endif
+
+ if (nsent == -1)
+ {
+ /*
+ * If the client closed the connection out from
+ * under us, there's no need to log that as an
+ * error.
+ */
+ int errcode;
+
+#ifdef _WIN32
+ errcode = GetLastError();
+ if (errcode == WSAECONNRESET ||
+ errcode == WSAECONNABORTED)
+ {
+ /*
+ * WSAECONNABORTED appears to be the error
+ * returned in Winsock when you try to send
+ * on a connection where the peer has closed
+ * the receive side.
+ */
+ return -2;
+ }
+ sock_fmterror("send(): ", errcode, errbuf, errbuflen);
+#else
+ errcode = errno;
+ if (errcode == ECONNRESET || errcode == EPIPE)
+ {
+ /*
+ * EPIPE is what's returned on UN*X when
+ * you try to send on a connection when
+ * the peer has closed the receive side.
+ */
+ return -2;
+ }
+ sock_fmterror("send(): ", errcode, errbuf, errbuflen);
+#endif
+ return -1;
+ }
+
+ remaining -= nsent;
buffer += nsent;
- goto send;
- }
+ } while (remaining != 0);
return 0;
}
@@ -682,9 +814,19 @@ int sock_bufferize(const char *buffer, int size, char *tempbuf, int *offset, int
* \param size: size of the allocated buffer. WARNING: this indicates the number of bytes
* that we are expecting to be read.
*
- * \param receiveall: if '0' (or SOCK_RECEIVEALL_NO), it returns as soon as some data
- * is ready; otherwise, (or SOCK_RECEIVEALL_YES) it waits until 'size' data has been
- * received (in case the socket does not have enough data available).
+ * \param flags:
+ *
+ * SOCK_RECEIVALL_XXX:
+ *
+ * if SOCK_RECEIVEALL_NO, return as soon as some data is ready
+ * if SOCK_RECEIVALL_YES, wait until 'size' data has been
+ * received (in case the socket does not have enough data available).
+ *
+ * SOCK_EOF_XXX:
+ *
+ * if SOCK_EOF_ISNT_ERROR, if the first read returns 0, just return 0,
+ * and return an error on any subsequent read that returns 0;
+ * if SOCK_EOF_IS_ERROR, if any read returns 0, return an error.
*
* \param errbuf: a pointer to an user-allocated buffer that will contain the complete
* error message. This buffer has to be at least 'errbuflen' in length.
@@ -697,17 +839,7 @@ int sock_bufferize(const char *buffer, int size, char *tempbuf, int *offset, int
* The error message is returned in the 'errbuf' variable.
*/
-/*
- * On UN*X, recv() returns ssize_t.
- * On Windows, there *is* no ssize_t, and it returns an int.
- * Define ssize_t as int on Windows so we can use it as the return value
- * from recv().
- */
-#ifdef _WIN32
-typedef int ssize_t;
-#endif
-
-int sock_recv(SOCKET sock, void *buffer, size_t size, int receiveall,
+int sock_recv(SOCKET sock, void *buffer, size_t size, int flags,
char *errbuf, int errbuflen)
{
char *bufp = buffer;
@@ -716,13 +848,17 @@ int sock_recv(SOCKET sock, void *buffer, size_t size, int receiveall,
if (size == 0)
{
- SOCK_ASSERT("I have been requested to read zero bytes", 1);
+ SOCK_DEBUG_MESSAGE("I have been requested to read zero bytes");
return 0;
}
if (size > INT_MAX)
{
- pcap_snprintf(errbuf, errbuflen, "Can't read more than %u bytes with sock_recv",
- INT_MAX);
+ if (errbuf)
+ {
+ pcap_snprintf(errbuf, errbuflen,
+ "Can't read more than %u bytes with sock_recv",
+ INT_MAX);
+ }
return -1;
}
@@ -748,19 +884,30 @@ int sock_recv(SOCKET sock, void *buffer, size_t size, int receiveall,
if (nread == 0)
{
- if (errbuf)
+ if ((flags & SOCK_EOF_IS_ERROR) ||
+ (remaining != (int) size))
{
- pcap_snprintf(errbuf, errbuflen,
- "The other host terminated the connection.");
+ /*
+ * Either we've already read some data,
+ * or we're always supposed to return
+ * an error on EOF.
+ */
+ if (errbuf)
+ {
+ pcap_snprintf(errbuf, errbuflen,
+ "The other host terminated the connection.");
+ }
+ return -1;
}
- return -1;
+ else
+ return 0;
}
/*
* Do we want to read the amount requested, or just return
* what we got?
*/
- if (!receiveall)
+ if (!(flags & SOCK_RECEIVEALL_YES))
{
/*
* Just return what we got.
@@ -777,6 +924,121 @@ int sock_recv(SOCKET sock, void *buffer, size_t size, int receiveall,
}
/*
+ * Receives a datagram from a socket.
+ *
+ * Returns the size of the datagram on success or -1 on error.
+ */
+int sock_recv_dgram(SOCKET sock, void *buffer, size_t size,
+ char *errbuf, int errbuflen)
+{
+ ssize_t nread;
+#ifndef _WIN32
+ struct msghdr message;
+ struct iovec iov;
+#endif
+
+ if (size == 0)
+ {
+ SOCK_DEBUG_MESSAGE("I have been requested to read zero bytes");
+ return 0;
+ }
+ if (size > INT_MAX)
+ {
+ if (errbuf)
+ {
+ pcap_snprintf(errbuf, errbuflen,
+ "Can't read more than %u bytes with sock_recv_dgram",
+ INT_MAX);
+ }
+ return -1;
+ }
+
+ /*
+ * This should be a datagram socket, so we should get the
+ * entire datagram in one recv() or recvmsg() call, and
+ * don't need to loop.
+ */
+#ifdef _WIN32
+ nread = recv(sock, buffer, size, 0);
+ if (nread == SOCKET_ERROR)
+ {
+ /*
+ * To quote the MSDN documentation for recv(),
+ * "If the datagram or message is larger than
+ * the buffer specified, the buffer is filled
+ * with the first part of the datagram, and recv
+ * generates the error WSAEMSGSIZE. For unreliable
+ * protocols (for example, UDP) the excess data is
+ * lost..."
+ *
+ * So if the message is bigger than the buffer
+ * supplied to us, the excess data is discarded,
+ * and we'll report an error.
+ */
+ sock_geterror("recv(): ", errbuf, errbuflen);
+ return -1;
+ }
+#else /* _WIN32 */
+ /*
+ * The Single UNIX Specification says that a recv() on
+ * a socket for a message-oriented protocol will discard
+ * the excess data. It does *not* indicate that the
+ * receive will fail with, for example, EMSGSIZE.
+ *
+ * Therefore, we use recvmsg(), which appears to be
+ * the only way to get a "message truncated" indication
+ * when receiving a message for a message-oriented
+ * protocol.
+ */
+ message.msg_name = NULL; /* we don't care who it's from */
+ message.msg_namelen = 0;
+ iov.iov_base = buffer;
+ iov.iov_len = size;
+ message.msg_iov = &iov;
+ message.msg_iovlen = 1;
+#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
+ message.msg_control = NULL; /* we don't care about control information */
+ message.msg_controllen = 0;
+#endif
+#ifdef HAVE_STRUCT_MSGHDR_MSG_FLAGS
+ message.msg_flags = 0;
+#endif
+ nread = recvmsg(sock, &message, 0);
+ if (nread == -1)
+ {
+ if (errno == EINTR)
+ return -3;
+ sock_geterror("recv(): ", errbuf, errbuflen);
+ return -1;
+ }
+#ifdef HAVE_STRUCT_MSGHDR_MSG_FLAGS
+ /*
+ * XXX - Solaris supports this, but only if you ask for the
+ * X/Open version of recvmsg(); should we use that, or will
+ * that cause other problems?
+ */
+ if (message.msg_flags & MSG_TRUNC)
+ {
+ /*
+ * Message was bigger than the specified buffer size.
+ *
+ * Report this as an error, as the Microsoft documentation
+ * implies we'd do in a similar case on Windows.
+ */
+ pcap_snprintf(errbuf, errbuflen, "recv(): Message too long");
+ return -1;
+ }
+#endif /* HAVE_STRUCT_MSGHDR_MSG_FLAGS */
+#endif /* _WIN32 */
+
+ /*
+ * The size we're reading fits in an int, so the return value
+ * will fit in an int.
+ */
+ return (int)nread;
+}
+
+/*
* \brief It discards N bytes that are currently waiting to be read on the current socket.
*
* This function is useful in case we receive a message we cannot understand (e.g.
@@ -833,7 +1095,7 @@ int sock_discard(SOCKET sock, int size, char *errbuf, int errbuflen)
return -1;
}
- SOCK_ASSERT("I'm currently discarding data\n", 1);
+ SOCK_DEBUG_MESSAGE("I'm currently discarding data\n");
return 0;
}
@@ -908,7 +1170,7 @@ int sock_check_hostlist(char *hostlist, const char *sep, struct sockaddr_storage
if (errbuf)
pcap_snprintf(errbuf, errbuflen, "getaddrinfo() %s", gai_strerror(retval));
- SOCK_ASSERT(errbuf, 1);
+ SOCK_DEBUG_MESSAGE(errbuf);
/* Get next token */
token = pcap_strtok_r(NULL, sep, &lasts);
@@ -922,6 +1184,7 @@ int sock_check_hostlist(char *hostlist, const char *sep, struct sockaddr_storage
if (sock_cmpaddr(from, (struct sockaddr_storage *) ai_next->ai_addr) == 0)
{
free(temphostlist);
+ freeaddrinfo(addrinfo);
return 0;
}
@@ -1051,13 +1314,9 @@ int sock_getmyinfo(SOCKET sock, char *address, int addrlen, char *port, int port
sock_geterror("getsockname(): ", errbuf, errbuflen);
return 0;
}
- else
- {
- /* Returns the numeric address of the host that triggered the error */
- return sock_getascii_addrport(&mysockaddr, address, addrlen, port, portlen, flags, errbuf, errbuflen);
- }
- return 0;
+ /* Returns the numeric address of the host that triggered the error */
+ return sock_getascii_addrport(&mysockaddr, address, addrlen, port, portlen, flags, errbuf, errbuflen);
}
/*
diff --git a/contrib/libpcap/sockutils.h b/contrib/libpcap/sockutils.h
index f50bbce881f6d..1df1ef7bb3ac3 100644
--- a/contrib/libpcap/sockutils.h
+++ b/contrib/libpcap/sockutils.h
@@ -33,25 +33,26 @@
#ifndef __SOCKUTILS_H__
#define __SOCKUTILS_H__
-#if _MSC_VER > 1000
+#ifdef _MSC_VER
#pragma once
#endif
#ifdef _WIN32
- /* Windows */
- /*
- * Prevents a compiler warning in case this was already defined (to
- * avoid that windows.h includes winsock.h)
- */
- #ifdef _WINSOCKAPI_
- #undef _WINSOCKAPI_
- #endif
/* 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;
#else
/* UN*X */
#include <stdio.h>
@@ -84,6 +85,14 @@
#ifndef INVALID_SOCKET
#define INVALID_SOCKET -1
#endif
+
+ /*!
+ * \brief In Winsock, the close() call cannot be used on a socket;
+ * closesocket() must be used.
+ * We define closesocket() to be a wrapper around close() on UN*X,
+ * so that it can be used on both platforms.
+ */
+ #define closesocket(a) close(a)
#endif
/*
@@ -114,28 +123,6 @@ int WSAAPI getnameinfo(const struct sockaddr*,socklen_t,char*,DWORD,
*/
/*
- * Some minor differences between UN*X sockets and and Winsock sockets.
- */
-#ifdef _WIN32
- /*
- * Winsock doesn't have these UN*X types; they're used in the UN*X
- * sockets API.
- *
- * XXX - do we need to worry about UN*Xes so old that *they* don't
- * have them, either?
- */
- typedef int socklen_t;
-#else
- /*!
- * \brief In Winsock, the close() call cannot be used on a socket;
- * closesocket() must be used.
- * We define closesocket() to be a wrapper around close() on UN*X,
- * so that it can be used on both platforms.
- */
- #define closesocket(a) close(a)
-#endif
-
-/*
* \brief DEBUG facility: it prints an error message on the screen (stderr)
*
* This macro prints the error on the standard error stream (stderr);
@@ -152,16 +139,15 @@ int WSAAPI getnameinfo(const struct sockaddr*,socklen_t,char*,DWORD,
* \return No return values.
*/
#ifdef NDEBUG
- #define SOCK_ASSERT(msg, expr) ((void)0)
+ #define SOCK_DEBUG_MESSAGE(msg) ((void)0)
#else
- #include <assert.h>
#if (defined(_WIN32) && defined(_MSC_VER))
#include <crtdbg.h> /* for _CrtDbgReport */
/* Use MessageBox(NULL, msg, "warning", MB_OK)' instead of the other calls if you want to debug a Win32 service */
/* Remember to activate the 'allow service to interact with desktop' flag of the service */
- #define SOCK_ASSERT(msg, expr) { _CrtDbgReport(_CRT_WARN, NULL, 0, NULL, "%s\n", msg); fprintf(stderr, "%s\n", msg); assert(expr); }
+ #define SOCK_DEBUG_MESSAGE(msg) { _CrtDbgReport(_CRT_WARN, NULL, 0, NULL, "%s\n", msg); fprintf(stderr, "%s\n", msg); }
#else
- #define SOCK_ASSERT(msg, expr) { fprintf(stderr, "%s\n", msg); assert(expr); }
+ #define SOCK_DEBUG_MESSAGE(msg) { fprintf(stderr, "%s\n", msg); }
#endif
#endif
@@ -181,10 +167,14 @@ int WSAAPI getnameinfo(const struct sockaddr*,socklen_t,char*,DWORD,
/* 'server' flag; it opens a server socket */
#define SOCKOPEN_SERVER 1
-/* Changes the behaviour of the sock_recv(); it does not wait to receive all data */
-#define SOCK_RECEIVEALL_NO 0
-/* Changes the behaviour of the sock_recv(); it waits to receive all data */
-#define SOCK_RECEIVEALL_YES 1
+/*
+ * Flags for sock_recv().
+ */
+#define SOCK_RECEIVEALL_NO 0x00000000 /* Don't wait to receive all data */
+#define SOCK_RECEIVEALL_YES 0x00000001 /* Wait to receive all data */
+
+#define SOCK_EOF_ISNT_ERROR 0x00000000 /* Return 0 on EOF */
+#define SOCK_EOF_IS_ERROR 0x00000002 /* Return an error on EOF */
/*
* \}
@@ -205,19 +195,22 @@ extern "C" {
int sock_init(char *errbuf, int errbuflen);
void sock_cleanup(void);
-/* It is 'public' because there are calls (like accept() ) which are not managed from inside the sockutils files */
+void sock_fmterror(const char *caller, int errcode, char *errbuf, int errbuflen);
void sock_geterror(const char *caller, char *errbuf, int errbufsize);
int sock_initaddress(const char *address, const char *port,
struct addrinfo *hints, struct addrinfo **addrinfo,
char *errbuf, int errbuflen);
-int sock_recv(SOCKET socket, void *buffer, size_t size, int receiveall,
+int sock_recv(SOCKET sock, void *buffer, size_t size, int receiveall,
+ char *errbuf, int errbuflen);
+int sock_recv_dgram(SOCKET sock, void *buffer, size_t size,
char *errbuf, int errbuflen);
SOCKET sock_open(struct addrinfo *addrinfo, int server, int nconn, char *errbuf, int errbuflen);
int sock_close(SOCKET sock, char *errbuf, int errbuflen);
-int sock_send(SOCKET socket, const char *buffer, int size, char *errbuf, int errbuflen);
+int sock_send(SOCKET sock, const char *buffer, size_t size,
+ char *errbuf, int errbuflen);
int sock_bufferize(const char *buffer, int size, char *tempbuf, int *offset, int totsize, int checkonly, char *errbuf, int errbuflen);
-int sock_discard(SOCKET socket, int size, char *errbuf, int errbuflen);
+int sock_discard(SOCKET sock, int size, char *errbuf, int errbuflen);
int sock_check_hostlist(char *hostlist, const char *sep, struct sockaddr_storage *from, char *errbuf, int errbuflen);
int sock_cmpaddr(struct sockaddr_storage *first, struct sockaddr_storage *second);
diff --git a/contrib/libpcap/tests/can_set_rfmon_test.c b/contrib/libpcap/tests/can_set_rfmon_test.c
deleted file mode 100644
index f1644e66b7684..0000000000000
--- a/contrib/libpcap/tests/can_set_rfmon_test.c
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that: (1) source code distributions
- * retain the above copyright notice and this paragraph in its entirety, (2)
- * distributions including binary code include the above copyright notice and
- * this paragraph in its entirety in the documentation or other materials
- * provided with the distribution, and (3) all advertising materials mentioning
- * features or use of this software display the following acknowledgement:
- * ``This product includes software developed by the University of California,
- * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
- * the University nor the names of its contributors may be used to endorse
- * or promote products derived from this software without specific prior
- * written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef lint
-static const char copyright[] _U_ =
- "@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000\n\
-The Regents of the University of California. All rights reserved.\n";
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-
-#include <pcap.h>
-
-static const char *program_name;
-
-/* Forwards */
-static void error(const char *, ...);
-
-int
-main(int argc, char **argv)
-{
- const char *cp;
- pcap_t *pd;
- char ebuf[PCAP_ERRBUF_SIZE];
- int status;
-
- if ((cp = strrchr(argv[0], '/')) != NULL)
- program_name = cp + 1;
- else
- program_name = argv[0];
-
- if (argc != 2) {
- fprintf(stderr, "Usage: %s <device>\n", program_name);
- return 2;
- }
-
- pd = pcap_create(argv[1], ebuf);
- if (pd == NULL)
- error("%s", ebuf);
- status = pcap_can_set_rfmon(pd);
- if (status < 0) {
- if (status == PCAP_ERROR)
- error("%s: pcap_can_set_rfmon failed: %s", argv[1],
- pcap_geterr(pd));
- else
- error("%s: pcap_can_set_rfmon failed: %s", argv[1],
- pcap_statustostr(status));
- return 1;
- }
- printf("%s: Monitor mode %s be set\n", argv[1], status ? "can" : "cannot");
- return 0;
-}
-
-/* VARARGS */
-static void
-error(const char *fmt, ...)
-{
- va_list ap;
-
- (void)fprintf(stderr, "%s: ", program_name);
- va_start(ap, fmt);
- (void)vfprintf(stderr, fmt, ap);
- va_end(ap);
- if (*fmt) {
- fmt += strlen(fmt);
- if (fmt[-1] != '\n')
- (void)fputc('\n', stderr);
- }
- exit(1);
- /* NOTREACHED */
-}
diff --git a/contrib/libpcap/tests/capturetest.c b/contrib/libpcap/tests/capturetest.c
deleted file mode 100644
index 14b1554b51892..0000000000000
--- a/contrib/libpcap/tests/capturetest.c
+++ /dev/null
@@ -1,334 +0,0 @@
-/*
- * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that: (1) source code distributions
- * retain the above copyright notice and this paragraph in its entirety, (2)
- * distributions including binary code include the above copyright notice and
- * this paragraph in its entirety in the documentation or other materials
- * provided with the distribution, and (3) all advertising materials mentioning
- * features or use of this software display the following acknowledgement:
- * ``This product includes software developed by the University of California,
- * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
- * the University nor the names of its contributors may be used to endorse
- * or promote products derived from this software without specific prior
- * written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef lint
-static const char copyright[] _U_ =
- "@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000\n\
-The Regents of the University of California. All rights reserved.\n";
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-#include <limits.h>
-#ifdef _WIN32
-#include "getopt.h"
-#else
-#include <unistd.h>
-#endif
-#include <errno.h>
-#include <sys/types.h>
-
-#include <pcap.h>
-
-static char *program_name;
-
-/*
- * This was introduced by Clang:
- *
- * http://clang.llvm.org/docs/LanguageExtensions.html#has-attribute
- *
- * in some version (which version?); it has been picked up by GCC 5.0.
- */
-#ifndef __has_attribute
- /*
- * It's a macro, so you can check whether it's defined to check
- * whether it's supported.
- *
- * If it's not, define it to always return 0, so that we move on to
- * the fallback checks.
- */
- #define __has_attribute(x) 0
-#endif
-
-#if __has_attribute(noreturn) \
- || (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 205)) \
- || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) \
- || (defined(__xlC__) && __xlC__ >= 0x0A01) \
- || (defined(__HP_aCC) && __HP_aCC >= 61000)
- /*
- * Compiler with support for it, 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.
- */
- #define PCAP_NORETURN __attribute((noreturn))
-#elif defined( _MSC_VER )
- #define PCAP_NORETURN __declspec(noreturn)
-#else
- #define PCAP_NORETURN
-#endif
-
-#if __has_attribute(__format__) \
- || (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 203)) \
- || (defined(__xlC__) && __xlC__ >= 0x0A01) \
- || (defined(__HP_aCC) && __HP_aCC >= 61000)
- /*
- * Compiler with support for it, or GCC 2.3 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.
- */
- #define PCAP_PRINTFLIKE(x,y) __attribute__((__format__(__printf__,x,y)))
-#else
- #define PCAP_PRINTFLIKE(x,y)
-#endif
-
-/* Forwards */
-static void countme(u_char *, const struct pcap_pkthdr *, const u_char *);
-static void PCAP_NORETURN usage(void);
-static void PCAP_NORETURN error(const char *, ...) PCAP_PRINTFLIKE(1, 2);
-static void warning(const char *, ...) PCAP_PRINTFLIKE(1, 2);
-static char *copy_argv(char **);
-
-static pcap_t *pd;
-
-int
-main(int argc, char **argv)
-{
- register int op;
- register char *cp, *cmdbuf, *device;
- long longarg;
- char *p;
- int timeout = 1000;
- int immediate = 0;
- int nonblock = 0;
- bpf_u_int32 localnet, netmask;
- struct bpf_program fcode;
- char ebuf[PCAP_ERRBUF_SIZE];
- int status;
- int packet_count;
-
- device = NULL;
- if ((cp = strrchr(argv[0], '/')) != NULL)
- program_name = cp + 1;
- else
- program_name = argv[0];
-
- opterr = 0;
- while ((op = getopt(argc, argv, "i:mnt:")) != -1) {
- switch (op) {
-
- case 'i':
- device = optarg;
- break;
-
- case 'm':
- immediate = 1;
- break;
-
- case 'n':
- nonblock = 1;
- break;
-
- case 't':
- longarg = strtol(optarg, &p, 10);
- if (p == optarg || *p != '\0') {
- error("Timeout value \"%s\" is not a number",
- optarg);
- /* NOTREACHED */
- }
- if (longarg < 0) {
- error("Timeout value %ld is negative", longarg);
- /* NOTREACHED */
- }
- if (longarg > INT_MAX) {
- error("Timeout value %ld is too large (> %d)",
- longarg, INT_MAX);
- /* NOTREACHED */
- }
- timeout = (int)longarg;
- break;
-
- default:
- usage();
- /* NOTREACHED */
- }
- }
-
- if (device == NULL) {
- device = pcap_lookupdev(ebuf);
- if (device == NULL)
- error("%s", ebuf);
- }
- *ebuf = '\0';
- pd = pcap_create(device, ebuf);
- if (pd == NULL)
- error("%s", ebuf);
- status = pcap_set_snaplen(pd, 65535);
- if (status != 0)
- error("%s: pcap_set_snaplen failed: %s",
- device, pcap_statustostr(status));
- if (immediate) {
- status = pcap_set_immediate_mode(pd, 1);
- if (status != 0)
- error("%s: pcap_set_immediate_mode failed: %s",
- device, pcap_statustostr(status));
- }
- status = pcap_set_timeout(pd, timeout);
- if (status != 0)
- error("%s: pcap_set_timeout failed: %s",
- device, pcap_statustostr(status));
- status = pcap_activate(pd);
- if (status < 0) {
- /*
- * pcap_activate() failed.
- */
- error("%s: %s\n(%s)", device,
- pcap_statustostr(status), pcap_geterr(pd));
- } else if (status > 0) {
- /*
- * pcap_activate() succeeded, but it's warning us
- * of a problem it had.
- */
- warning("%s: %s\n(%s)", device,
- pcap_statustostr(status), pcap_geterr(pd));
- }
- if (pcap_lookupnet(device, &localnet, &netmask, ebuf) < 0) {
- localnet = 0;
- netmask = 0;
- warning("%s", ebuf);
- }
- cmdbuf = copy_argv(&argv[optind]);
-
- if (pcap_compile(pd, &fcode, cmdbuf, 1, netmask) < 0)
- error("%s", pcap_geterr(pd));
-
- if (pcap_setfilter(pd, &fcode) < 0)
- error("%s", pcap_geterr(pd));
- if (pcap_setnonblock(pd, nonblock, ebuf) == -1)
- error("pcap_setnonblock failed: %s", ebuf);
- printf("Listening on %s\n", device);
- for (;;) {
- packet_count = 0;
- status = pcap_dispatch(pd, -1, countme,
- (u_char *)&packet_count);
- if (status < 0)
- break;
- if (status != 0) {
- printf("%d packets seen, %d packets counted after pcap_dispatch returns\n",
- status, packet_count);
- }
- }
- if (status == -2) {
- /*
- * We got interrupted, so perhaps we didn't
- * manage to finish a line we were printing.
- * Print an extra newline, just in case.
- */
- putchar('\n');
- }
- (void)fflush(stdout);
- if (status == -1) {
- /*
- * Error. Report it.
- */
- (void)fprintf(stderr, "%s: pcap_loop: %s\n",
- program_name, pcap_geterr(pd));
- }
- pcap_close(pd);
- exit(status == -1 ? 1 : 0);
-}
-
-static void
-countme(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
-{
- int *counterp = (int *)user;
-
- (*counterp)++;
-}
-
-static void
-usage(void)
-{
- (void)fprintf(stderr, "Usage: %s [ -mn ] [ -i interface ] [ -t timeout] [expression]\n",
- program_name);
- exit(1);
-}
-
-/* VARARGS */
-static void
-error(const char *fmt, ...)
-{
- va_list ap;
-
- (void)fprintf(stderr, "%s: ", program_name);
- va_start(ap, fmt);
- (void)vfprintf(stderr, fmt, ap);
- va_end(ap);
- if (*fmt) {
- fmt += strlen(fmt);
- if (fmt[-1] != '\n')
- (void)fputc('\n', stderr);
- }
- exit(1);
- /* NOTREACHED */
-}
-
-/* VARARGS */
-static void
-warning(const char *fmt, ...)
-{
- va_list ap;
-
- (void)fprintf(stderr, "%s: WARNING: ", program_name);
- va_start(ap, fmt);
- (void)vfprintf(stderr, fmt, ap);
- va_end(ap);
- if (*fmt) {
- fmt += strlen(fmt);
- if (fmt[-1] != '\n')
- (void)fputc('\n', stderr);
- }
-}
-
-/*
- * Copy arg vector into a new buffer, concatenating arguments with spaces.
- */
-static char *
-copy_argv(register char **argv)
-{
- register char **p;
- register u_int len = 0;
- char *buf;
- char *src, *dst;
-
- p = argv;
- if (*p == 0)
- return 0;
-
- while (*p)
- len += strlen(*p++) + 1;
-
- buf = (char *)malloc(len);
- if (buf == NULL)
- error("copy_argv: malloc");
-
- p = argv;
- dst = buf;
- while ((src = *p++) != NULL) {
- while ((*dst++ = *src++) != '\0')
- ;
- dst[-1] = ' ';
- }
- dst[-1] = '\0';
-
- return buf;
-}
diff --git a/contrib/libpcap/tests/filtertest.c b/contrib/libpcap/tests/filtertest.c
deleted file mode 100644
index d4440eb06b3d8..0000000000000
--- a/contrib/libpcap/tests/filtertest.c
+++ /dev/null
@@ -1,364 +0,0 @@
-/*
- * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that: (1) source code distributions
- * retain the above copyright notice and this paragraph in its entirety, (2)
- * distributions including binary code include the above copyright notice and
- * this paragraph in its entirety in the documentation or other materials
- * provided with the distribution, and (3) all advertising materials mentioning
- * features or use of this software display the following acknowledgement:
- * ``This product includes software developed by the University of California,
- * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
- * the University nor the names of its contributors may be used to endorse
- * or promote products derived from this software without specific prior
- * written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef lint
-static const char copyright[] _U_ =
- "@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000\n\
-The Regents of the University of California. All rights reserved.\n";
-#endif
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <pcap.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-#ifdef _WIN32
-#include "getopt.h"
-#else
-#include <unistd.h>
-#endif
-#include <fcntl.h>
-#include <errno.h>
-#ifdef _WIN32
- #include <winsock2.h>
- typedef unsigned __int32 in_addr_t;
-#else
- #include <arpa/inet.h>
-#endif
-#include <sys/types.h>
-#include <sys/stat.h>
-
-/*
- * This was introduced by Clang:
- *
- * http://clang.llvm.org/docs/LanguageExtensions.html#has-attribute
- *
- * in some version (which version?); it has been picked up by GCC 5.0.
- */
-#ifndef __has_attribute
- /*
- * It's a macro, so you can check whether it's defined to check
- * whether it's supported.
- *
- * If it's not, define it to always return 0, so that we move on to
- * the fallback checks.
- */
- #define __has_attribute(x) 0
-#endif
-
-#if __has_attribute(noreturn) \
- || (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 205)) \
- || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) \
- || (defined(__xlC__) && __xlC__ >= 0x0A01) \
- || (defined(__HP_aCC) && __HP_aCC >= 61000)
- /*
- * Compiler with support for it, 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.
- */
- #define PCAP_NORETURN __attribute((noreturn))
-#elif defined( _MSC_VER )
- #define PCAP_NORETURN __declspec(noreturn)
-#else
- #define PCAP_NORETURN
-#endif
-
-#if __has_attribute(__format__) \
- || (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 203)) \
- || (defined(__xlC__) && __xlC__ >= 0x0A01) \
- || (defined(__HP_aCC) && __HP_aCC >= 61000)
- /*
- * Compiler with support for it, or GCC 2.3 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.
- */
- #define PCAP_PRINTFLIKE(x,y) __attribute__((__format__(__printf__,x,y)))
-#else
- #define PCAP_PRINTFLIKE(x,y)
-#endif
-
-static char *program_name;
-
-/* Forwards */
-static void PCAP_NORETURN usage(void);
-static void PCAP_NORETURN error(const char *, ...) PCAP_PRINTFLIKE(1, 2);
-static void warn(const char *, ...) PCAP_PRINTFLIKE(1, 2);
-
-#ifdef BDEBUG
-int dflag;
-#endif
-
-/*
- * On Windows, we need to open the file in binary mode, so that
- * we get all the bytes specified by the size we get from "fstat()".
- * On UNIX, that's not necessary. O_BINARY is defined on Windows;
- * we define it as 0 if it's not defined, so it does nothing.
- */
-#ifndef O_BINARY
-#define O_BINARY 0
-#endif
-
-static char *
-read_infile(char *fname)
-{
- register int i, fd, cc;
- register char *cp;
- struct stat buf;
-
- fd = open(fname, O_RDONLY|O_BINARY);
- if (fd < 0)
- error("can't open %s: %s", fname, pcap_strerror(errno));
-
- if (fstat(fd, &buf) < 0)
- error("can't stat %s: %s", fname, pcap_strerror(errno));
-
- cp = malloc((u_int)buf.st_size + 1);
- if (cp == NULL)
- error("malloc(%d) for %s: %s", (u_int)buf.st_size + 1,
- fname, pcap_strerror(errno));
- cc = read(fd, cp, (u_int)buf.st_size);
- if (cc < 0)
- error("read %s: %s", fname, pcap_strerror(errno));
- if (cc != buf.st_size)
- error("short read %s (%d != %d)", fname, cc, (int)buf.st_size);
-
- close(fd);
- /* replace "# comment" with spaces */
- for (i = 0; i < cc; i++) {
- if (cp[i] == '#')
- while (i < cc && cp[i] != '\n')
- cp[i++] = ' ';
- }
- cp[cc] = '\0';
- return (cp);
-}
-
-/* VARARGS */
-static void
-error(const char *fmt, ...)
-{
- va_list ap;
-
- (void)fprintf(stderr, "%s: ", program_name);
- va_start(ap, fmt);
- (void)vfprintf(stderr, fmt, ap);
- va_end(ap);
- if (*fmt) {
- fmt += strlen(fmt);
- if (fmt[-1] != '\n')
- (void)fputc('\n', stderr);
- }
- exit(1);
- /* NOTREACHED */
-}
-
-/* VARARGS */
-static void
-warn(const char *fmt, ...)
-{
- va_list ap;
-
- (void)fprintf(stderr, "%s: WARNING: ", program_name);
- va_start(ap, fmt);
- (void)vfprintf(stderr, fmt, ap);
- va_end(ap);
- if (*fmt) {
- fmt += strlen(fmt);
- if (fmt[-1] != '\n')
- (void)fputc('\n', stderr);
- }
-}
-
-/*
- * Copy arg vector into a new buffer, concatenating arguments with spaces.
- */
-static char *
-copy_argv(register char **argv)
-{
- register char **p;
- register u_int len = 0;
- char *buf;
- char *src, *dst;
-
- p = argv;
- if (*p == 0)
- return 0;
-
- while (*p)
- len += strlen(*p++) + 1;
-
- buf = (char *)malloc(len);
- if (buf == NULL)
- error("copy_argv: malloc");
-
- p = argv;
- dst = buf;
- while ((src = *p++) != NULL) {
- while ((*dst++ = *src++) != '\0')
- ;
- dst[-1] = ' ';
- }
- dst[-1] = '\0';
-
- return buf;
-}
-
-int
-main(int argc, char **argv)
-{
- char *cp;
- int op;
-#ifndef BDEBUG
- int dflag;
-#endif
- char *infile;
- int Oflag;
- long snaplen;
- char *p;
- int dlt;
- bpf_u_int32 netmask = PCAP_NETMASK_UNKNOWN;
- char *cmdbuf;
- pcap_t *pd;
- struct bpf_program fcode;
-
-#ifdef _WIN32
- if(wsockinit() != 0) return 1;
-#endif /* _WIN32 */
-
-#ifndef BDEBUG
- dflag = 1;
-#else
- /* if optimizer debugging is enabled, output DOT graph
- * `dflag=4' is equivalent to -dddd to follow -d/-dd/-ddd
- * convention in tcpdump command line
- */
- dflag = 4;
-#endif
- infile = NULL;
- Oflag = 1;
- snaplen = 68;
-
- if ((cp = strrchr(argv[0], '/')) != NULL)
- program_name = cp + 1;
- else
- program_name = argv[0];
-
- opterr = 0;
- while ((op = getopt(argc, argv, "dF:m:Os:")) != -1) {
- switch (op) {
-
- case 'd':
- ++dflag;
- break;
-
- case 'F':
- infile = optarg;
- break;
-
- case 'O':
- Oflag = 0;
- break;
-
- case 'm': {
- in_addr_t addr;
-
- addr = inet_addr(optarg);
- if (addr == (in_addr_t)(-1))
- error("invalid netmask %s", optarg);
- netmask = addr;
- break;
- }
-
- case 's': {
- char *end;
-
- snaplen = strtol(optarg, &end, 0);
- if (optarg == end || *end != '\0'
- || snaplen < 0 || snaplen > 65535)
- error("invalid snaplen %s", optarg);
- else if (snaplen == 0)
- snaplen = 65535;
- break;
- }
-
- default:
- usage();
- /* NOTREACHED */
- }
- }
-
- if (optind >= argc) {
- usage();
- /* NOTREACHED */
- }
-
- dlt = pcap_datalink_name_to_val(argv[optind]);
- if (dlt < 0) {
- dlt = (int)strtol(argv[optind], &p, 10);
- if (p == argv[optind] || *p != '\0')
- error("invalid data link type %s", argv[optind]);
- }
-
- if (infile)
- cmdbuf = read_infile(infile);
- else
- cmdbuf = copy_argv(&argv[optind+1]);
-
- pd = pcap_open_dead(dlt, snaplen);
- if (pd == NULL)
- error("Can't open fake pcap_t");
-
- if (pcap_compile(pd, &fcode, cmdbuf, Oflag, netmask) < 0)
- error("%s", pcap_geterr(pd));
-
- if (!bpf_validate(fcode.bf_insns, fcode.bf_len))
- warn("Filter doesn't pass validation");
-
-#ifdef BDEBUG
- // replace line feed with space
- for (cp = cmdbuf; *cp != '\0'; ++cp) {
- if (*cp == '\r' || *cp == '\n') {
- *cp = ' ';
- }
- }
- // only show machine code if BDEBUG defined, since dflag > 3
- printf("machine codes for filter: %s\n", cmdbuf);
-#endif
-
- bpf_dump(&fcode, dflag);
- pcap_close(pd);
- exit(0);
-}
-
-static void
-usage(void)
-{
- (void)fprintf(stderr, "%s, with %s\n", program_name,
- pcap_lib_version());
- (void)fprintf(stderr,
- "Usage: %s [-dO] [ -F file ] [ -m netmask] [ -s snaplen ] dlt [ expression ]\n",
- program_name);
- exit(1);
-}
diff --git a/contrib/libpcap/tests/findalldevstest.c b/contrib/libpcap/tests/findalldevstest.c
deleted file mode 100644
index 5925bf6a81764..0000000000000
--- a/contrib/libpcap/tests/findalldevstest.c
+++ /dev/null
@@ -1,161 +0,0 @@
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <stdlib.h>
-#include <sys/types.h>
-#ifdef _WIN32
- #include <winsock2.h>
-#else
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <netdb.h>
-#endif
-
-#include <pcap.h>
-
-static int ifprint(pcap_if_t *d);
-static char *iptos(bpf_u_int32 in);
-
-int main(int argc, char **argv)
-{
- pcap_if_t *alldevs;
- pcap_if_t *d;
- char *s;
- bpf_u_int32 net, mask;
- int exit_status = 0;
-
- char errbuf[PCAP_ERRBUF_SIZE+1];
- if (pcap_findalldevs(&alldevs, errbuf) == -1)
- {
- fprintf(stderr,"Error in pcap_findalldevs: %s\n",errbuf);
- exit(1);
- }
- for(d=alldevs;d;d=d->next)
- {
- if (!ifprint(d))
- exit_status = 2;
- }
-
- if ( (s = pcap_lookupdev(errbuf)) == NULL)
- {
- fprintf(stderr,"Error in pcap_lookupdev: %s\n",errbuf);
- exit_status = 2;
- }
- else
- {
- printf("Preferred device name: %s\n",s);
- }
-
- if (pcap_lookupnet(s, &net, &mask, errbuf) < 0)
- {
- fprintf(stderr,"Error in pcap_lookupnet: %s\n",errbuf);
- exit_status = 2;
- }
- else
- {
- printf("Preferred device is on network: %s/%s\n",iptos(net), iptos(mask));
- }
-
- exit(exit_status);
-}
-
-static int ifprint(pcap_if_t *d)
-{
- pcap_addr_t *a;
-#ifdef INET6
- char ntop_buf[INET6_ADDRSTRLEN];
-#endif
- const char *sep;
- int status = 1; /* success */
-
- printf("%s\n",d->name);
- if (d->description)
- printf("\tDescription: %s\n",d->description);
- printf("\tFlags: ");
- sep = "";
- if (d->flags & PCAP_IF_UP) {
- printf("%sUP", sep);
- sep = ", ";
- }
- if (d->flags & PCAP_IF_RUNNING) {
- printf("%sRUNNING", sep);
- sep = ", ";
- }
- if (d->flags & PCAP_IF_LOOPBACK) {
- printf("%sLOOPBACK", sep);
- sep = ", ";
- }
- printf("\n");
-
- for(a=d->addresses;a;a=a->next) {
- if (a->addr != NULL)
- switch(a->addr->sa_family) {
- case AF_INET:
- printf("\tAddress Family: AF_INET\n");
- if (a->addr)
- printf("\t\tAddress: %s\n",
- inet_ntoa(((struct sockaddr_in *)(a->addr))->sin_addr));
- if (a->netmask)
- printf("\t\tNetmask: %s\n",
- inet_ntoa(((struct sockaddr_in *)(a->netmask))->sin_addr));
- if (a->broadaddr)
- printf("\t\tBroadcast Address: %s\n",
- inet_ntoa(((struct sockaddr_in *)(a->broadaddr))->sin_addr));
- if (a->dstaddr)
- printf("\t\tDestination Address: %s\n",
- inet_ntoa(((struct sockaddr_in *)(a->dstaddr))->sin_addr));
- break;
-#ifdef INET6
- case AF_INET6:
- printf("\tAddress Family: AF_INET6\n");
- if (a->addr)
- printf("\t\tAddress: %s\n",
- inet_ntop(AF_INET6,
- ((struct sockaddr_in6 *)(a->addr))->sin6_addr.s6_addr,
- ntop_buf, sizeof ntop_buf));
- if (a->netmask)
- printf("\t\tNetmask: %s\n",
- inet_ntop(AF_INET6,
- ((struct sockaddr_in6 *)(a->netmask))->sin6_addr.s6_addr,
- ntop_buf, sizeof ntop_buf));
- if (a->broadaddr)
- printf("\t\tBroadcast Address: %s\n",
- inet_ntop(AF_INET6,
- ((struct sockaddr_in6 *)(a->broadaddr))->sin6_addr.s6_addr,
- ntop_buf, sizeof ntop_buf));
- if (a->dstaddr)
- printf("\t\tDestination Address: %s\n",
- inet_ntop(AF_INET6,
- ((struct sockaddr_in6 *)(a->dstaddr))->sin6_addr.s6_addr,
- ntop_buf, sizeof ntop_buf));
- break;
-#endif
- default:
- printf("\tAddress Family: Unknown (%d)\n", a->addr->sa_family);
- break;
- }
- else
- {
- fprintf(stderr, "\tWarning: a->addr is NULL, skipping this address.\n");
- status = 0;
- }
- }
- printf("\n");
- return status;
-}
-
-/* From tcptraceroute */
-#define IPTOSBUFFERS 12
-static char *iptos(bpf_u_int32 in)
-{
- static char output[IPTOSBUFFERS][3*4+3+1];
- static short which;
- u_char *p;
-
- p = (u_char *)&in;
- which = (which + 1 == IPTOSBUFFERS ? 0 : which + 1);
- sprintf(output[which], "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
- return output[which];
-}
diff --git a/contrib/libpcap/tests/opentest.c b/contrib/libpcap/tests/opentest.c
deleted file mode 100644
index b6d634f0d901e..0000000000000
--- a/contrib/libpcap/tests/opentest.c
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that: (1) source code distributions
- * retain the above copyright notice and this paragraph in its entirety, (2)
- * distributions including binary code include the above copyright notice and
- * this paragraph in its entirety in the documentation or other materials
- * provided with the distribution, and (3) all advertising materials mentioning
- * features or use of this software display the following acknowledgement:
- * ``This product includes software developed by the University of California,
- * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
- * the University nor the names of its contributors may be used to endorse
- * or promote products derived from this software without specific prior
- * written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef lint
-static const char copyright[] _U_ =
- "@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000\n\
-The Regents of the University of California. All rights reserved.\n";
-#endif
-
-#include <pcap.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-#ifdef _WIN32
-#include "getopt.h"
-#else
-#include <unistd.h>
-#endif
-#include <errno.h>
-
-#define MAXIMUM_SNAPLEN 65535
-
-static char *program_name;
-
-/*
- * This was introduced by Clang:
- *
- * http://clang.llvm.org/docs/LanguageExtensions.html#has-attribute
- *
- * in some version (which version?); it has been picked up by GCC 5.0.
- */
-#ifndef __has_attribute
- /*
- * It's a macro, so you can check whether it's defined to check
- * whether it's supported.
- *
- * If it's not, define it to always return 0, so that we move on to
- * the fallback checks.
- */
- #define __has_attribute(x) 0
-#endif
-
-#if __has_attribute(noreturn) \
- || (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 205)) \
- || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) \
- || (defined(__xlC__) && __xlC__ >= 0x0A01) \
- || (defined(__HP_aCC) && __HP_aCC >= 61000)
- /*
- * Compiler with support for it, 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.
- */
- #define PCAP_NORETURN __attribute((noreturn))
-#elif defined( _MSC_VER )
- #define PCAP_NORETURN __declspec(noreturn)
-#else
- #define PCAP_NORETURN
-#endif
-
-#if __has_attribute(__format__) \
- || (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 203)) \
- || (defined(__xlC__) && __xlC__ >= 0x0A01) \
- || (defined(__HP_aCC) && __HP_aCC >= 61000)
- /*
- * Compiler with support for it, or GCC 2.3 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.
- */
- #define PCAP_PRINTFLIKE(x,y) __attribute__((__format__(__printf__,x,y)))
-#else
- #define PCAP_PRINTFLIKE(x,y)
-#endif
-
-/* Forwards */
-static void PCAP_NORETURN usage(void);
-static void PCAP_NORETURN error(const char *, ...) PCAP_PRINTFLIKE(1, 2);
-static void warning(const char *, ...) PCAP_PRINTFLIKE(1, 2);
-
-int
-main(int argc, char **argv)
-{
- register int op;
- register char *cp, *device;
- int dorfmon, dopromisc, snaplen, useactivate, bufsize;
- char ebuf[PCAP_ERRBUF_SIZE];
- pcap_t *pd;
- int status = 0;
-
- device = NULL;
- dorfmon = 0;
- dopromisc = 0;
- snaplen = MAXIMUM_SNAPLEN;
- bufsize = 0;
- useactivate = 0;
- if ((cp = strrchr(argv[0], '/')) != NULL)
- program_name = cp + 1;
- else
- program_name = argv[0];
-
- opterr = 0;
- while ((op = getopt(argc, argv, "i:Ips:aB:")) != -1) {
- switch (op) {
-
- case 'i':
- device = optarg;
- break;
-
- case 'I':
- dorfmon = 1;
- useactivate = 1; /* required for rfmon */
- break;
-
- case 'p':
- dopromisc = 1;
- break;
-
- case 's': {
- char *end;
-
- snaplen = strtol(optarg, &end, 0);
- if (optarg == end || *end != '\0'
- || snaplen < 0 || snaplen > MAXIMUM_SNAPLEN)
- error("invalid snaplen %s", optarg);
- else if (snaplen == 0)
- snaplen = MAXIMUM_SNAPLEN;
- break;
- }
-
- case 'B':
- bufsize = atoi(optarg)*1024;
- if (bufsize <= 0)
- error("invalid packet buffer size %s", optarg);
- useactivate = 1; /* required for bufsize */
- break;
-
- case 'a':
- useactivate = 1;
- break;
-
- default:
- usage();
- /* NOTREACHED */
- }
- }
-
- if (device == NULL) {
- device = pcap_lookupdev(ebuf);
- if (device == NULL)
- error("pcap_lookupdev failed: %s", ebuf);
- }
- if (useactivate) {
- pd = pcap_create(device, ebuf);
- if (pd == NULL)
- error("%s: pcap_create failed: %s", device, ebuf);
- status = pcap_set_snaplen(pd, snaplen);
- if (status != 0)
- error("%s: pcap_set_snaplen failed: %s",
- device, pcap_statustostr(status));
- if (dopromisc) {
- status = pcap_set_promisc(pd, 1);
- if (status != 0)
- error("%s: pcap_set_promisc failed: %s",
- device, pcap_statustostr(status));
- }
- if (dorfmon) {
- status = pcap_set_rfmon(pd, 1);
- if (status != 0)
- error("%s: pcap_set_rfmon failed: %s",
- device, pcap_statustostr(status));
- }
- status = pcap_set_timeout(pd, 1000);
- if (status != 0)
- error("%s: pcap_set_timeout failed: %s",
- device, pcap_statustostr(status));
- if (bufsize != 0) {
- status = pcap_set_buffer_size(pd, bufsize);
- if (status != 0)
- error("%s: pcap_set_buffer_size failed: %s",
- device, pcap_statustostr(status));
- }
- status = pcap_activate(pd);
- if (status < 0) {
- /*
- * pcap_activate() failed.
- */
- error("%s: %s\n(%s)", device,
- pcap_statustostr(status), pcap_geterr(pd));
- } else if (status > 0) {
- /*
- * pcap_activate() succeeded, but it's warning us
- * of a problem it had.
- */
- warning("%s: %s\n(%s)", device,
- pcap_statustostr(status), pcap_geterr(pd));
- } else
- printf("%s opened successfully\n", device);
- } else {
- *ebuf = '\0';
- pd = pcap_open_live(device, 65535, 0, 1000, ebuf);
- if (pd == NULL)
- error("%s", ebuf);
- else if (*ebuf)
- warning("%s", ebuf);
- else
- printf("%s opened successfully\n", device);
- }
- pcap_close(pd);
- exit(status < 0 ? 1 : 0);
-}
-
-static void
-usage(void)
-{
- (void)fprintf(stderr,
- "Usage: %s [ -Ipa ] [ -i interface ] [ -s snaplen ] [ -B bufsize ]\n",
- program_name);
- exit(1);
-}
-
-/* VARARGS */
-static void
-error(const char *fmt, ...)
-{
- va_list ap;
-
- (void)fprintf(stderr, "%s: ", program_name);
- va_start(ap, fmt);
- (void)vfprintf(stderr, fmt, ap);
- va_end(ap);
- if (*fmt) {
- fmt += strlen(fmt);
- if (fmt[-1] != '\n')
- (void)fputc('\n', stderr);
- }
- exit(1);
- /* NOTREACHED */
-}
-
-/* VARARGS */
-static void
-warning(const char *fmt, ...)
-{
- va_list ap;
-
- (void)fprintf(stderr, "%s: WARNING: ", program_name);
- va_start(ap, fmt);
- (void)vfprintf(stderr, fmt, ap);
- va_end(ap);
- if (*fmt) {
- fmt += strlen(fmt);
- if (fmt[-1] != '\n')
- (void)fputc('\n', stderr);
- }
-}
diff --git a/contrib/libpcap/tests/reactivatetest.c b/contrib/libpcap/tests/reactivatetest.c
deleted file mode 100644
index 2e1b7b67adb75..0000000000000
--- a/contrib/libpcap/tests/reactivatetest.c
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that: (1) source code distributions
- * retain the above copyright notice and this paragraph in its entirety, (2)
- * distributions including binary code include the above copyright notice and
- * this paragraph in its entirety in the documentation or other materials
- * provided with the distribution, and (3) all advertising materials mentioning
- * features or use of this software display the following acknowledgement:
- * ``This product includes software developed by the University of California,
- * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
- * the University nor the names of its contributors may be used to endorse
- * or promote products derived from this software without specific prior
- * written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef lint
-static const char copyright[] _U_ =
- "@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000\n\
-The Regents of the University of California. All rights reserved.\n";
-#endif
-
-#include <pcap.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-
-/* Forwards */
-static void error(const char *, ...);
-
-int
-main(void)
-{
- char ebuf[PCAP_ERRBUF_SIZE];
- pcap_t *pd;
- int status = 0;
-
- pd = pcap_open_live("lo0", 65535, 0, 1000, ebuf);
- if (pd == NULL) {
- pd = pcap_open_live("lo", 65535, 0, 1000, ebuf);
- if (pd == NULL) {
- error("Neither lo0 nor lo could be opened: %s",
- ebuf);
- return 2;
- }
- }
- status = pcap_activate(pd);
- if (status != PCAP_ERROR_ACTIVATED) {
- if (status == 0)
- error("pcap_activate() of opened pcap_t succeeded");
- else if (status == PCAP_ERROR)
- error("pcap_activate() of opened pcap_t failed with %s, not PCAP_ERROR_ACTIVATED",
- pcap_geterr(pd));
- else
- error("pcap_activate() of opened pcap_t failed with %s, not PCAP_ERROR_ACTIVATED",
- pcap_statustostr(status));
- }
- return 0;
-}
-
-/* VARARGS */
-static void
-error(const char *fmt, ...)
-{
- va_list ap;
-
- (void)fprintf(stderr, "reactivatetest: ");
- va_start(ap, fmt);
- (void)vfprintf(stderr, fmt, ap);
- va_end(ap);
- if (*fmt) {
- fmt += strlen(fmt);
- if (fmt[-1] != '\n')
- (void)fputc('\n', stderr);
- }
- exit(1);
- /* NOTREACHED */
-}
diff --git a/contrib/libpcap/tests/selpolltest.c b/contrib/libpcap/tests/selpolltest.c
deleted file mode 100644
index 4c1415b683545..0000000000000
--- a/contrib/libpcap/tests/selpolltest.c
+++ /dev/null
@@ -1,407 +0,0 @@
-/*
- * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that: (1) source code distributions
- * retain the above copyright notice and this paragraph in its entirety, (2)
- * distributions including binary code include the above copyright notice and
- * this paragraph in its entirety in the documentation or other materials
- * provided with the distribution, and (3) all advertising materials mentioning
- * features or use of this software display the following acknowledgement:
- * ``This product includes software developed by the University of California,
- * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
- * the University nor the names of its contributors may be used to endorse
- * or promote products derived from this software without specific prior
- * written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef lint
-static const char copyright[] _U_ =
- "@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000\n\
-The Regents of the University of California. All rights reserved.\n";
-#endif
-
-/*
- * Tests how select() and poll() behave on the selectable file descriptor
- * for a pcap_t.
- *
- * This would be significantly different on Windows, as it'd test
- * how WaitForMultipleObjects() would work on the event handle for a
- * pcap_t.
- */
-#include <pcap.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-#include <unistd.h>
-#include <errno.h>
-#include <sys/types.h>
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#else
-#include <sys/time.h> /* older UN*Xes */
-#endif
-#include <poll.h>
-
-char *program_name;
-
-/*
- * This was introduced by Clang:
- *
- * http://clang.llvm.org/docs/LanguageExtensions.html#has-attribute
- *
- * in some version (which version?); it has been picked up by GCC 5.0.
- */
-#ifndef __has_attribute
- /*
- * It's a macro, so you can check whether it's defined to check
- * whether it's supported.
- *
- * If it's not, define it to always return 0, so that we move on to
- * the fallback checks.
- */
- #define __has_attribute(x) 0
-#endif
-
-#if __has_attribute(noreturn) \
- || (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 205)) \
- || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) \
- || (defined(__xlC__) && __xlC__ >= 0x0A01) \
- || (defined(__HP_aCC) && __HP_aCC >= 61000)
- /*
- * Compiler with support for it, 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.
- */
- #define PCAP_NORETURN __attribute((noreturn))
-#elif defined( _MSC_VER )
- #define PCAP_NORETURN __declspec(noreturn)
-#else
- #define PCAP_NORETURN
-#endif
-
-#if __has_attribute(__format__) \
- || (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 203)) \
- || (defined(__xlC__) && __xlC__ >= 0x0A01) \
- || (defined(__HP_aCC) && __HP_aCC >= 61000)
- /*
- * Compiler with support for it, or GCC 2.3 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.
- */
- #define PCAP_PRINTFLIKE(x,y) __attribute__((__format__(__printf__,x,y)))
-#else
- #define PCAP_PRINTFLIKE(x,y)
-#endif
-
-/* Forwards */
-static void countme(u_char *, const struct pcap_pkthdr *, const u_char *);
-static void PCAP_NORETURN usage(void);
-static void PCAP_NORETURN error(const char *, ...) PCAP_PRINTFLIKE(1, 2);
-static void warning(const char *, ...) PCAP_PRINTFLIKE(1, 2);
-static char *copy_argv(char **);
-
-static pcap_t *pd;
-
-int
-main(int argc, char **argv)
-{
- register int op;
- bpf_u_int32 localnet, netmask;
- register char *cp, *cmdbuf, *device;
- int doselect, dopoll, dotimeout, dononblock;
- struct bpf_program fcode;
- char ebuf[PCAP_ERRBUF_SIZE];
- int selectable_fd;
- int status;
- int packet_count;
-
- device = NULL;
- doselect = 0;
- dopoll = 0;
- dotimeout = 0;
- dononblock = 0;
- if ((cp = strrchr(argv[0], '/')) != NULL)
- program_name = cp + 1;
- else
- program_name = argv[0];
-
- opterr = 0;
- while ((op = getopt(argc, argv, "i:sptn")) != -1) {
- switch (op) {
-
- case 'i':
- device = optarg;
- break;
-
- case 's':
- doselect = 1;
- break;
-
- case 'p':
- dopoll = 1;
- break;
-
- case 't':
- dotimeout = 1;
- break;
-
- case 'n':
- dononblock = 1;
- break;
-
- default:
- usage();
- /* NOTREACHED */
- }
- }
-
- if (doselect && dopoll) {
- fprintf(stderr, "selpolltest: choose select (-s) or poll (-p), but not both\n");
- return 1;
- }
- if (dotimeout && !doselect && !dopoll) {
- fprintf(stderr, "selpolltest: timeout (-t) requires select (-s) or poll (-p)\n");
- return 1;
- }
- if (device == NULL) {
- device = pcap_lookupdev(ebuf);
- if (device == NULL)
- error("%s", ebuf);
- }
- *ebuf = '\0';
- pd = pcap_open_live(device, 65535, 0, 1000, ebuf);
- if (pd == NULL)
- error("%s", ebuf);
- else if (*ebuf)
- warning("%s", ebuf);
- if (pcap_lookupnet(device, &localnet, &netmask, ebuf) < 0) {
- localnet = 0;
- netmask = 0;
- warning("%s", ebuf);
- }
- cmdbuf = copy_argv(&argv[optind]);
-
- if (pcap_compile(pd, &fcode, cmdbuf, 1, netmask) < 0)
- error("%s", pcap_geterr(pd));
-
- if (pcap_setfilter(pd, &fcode) < 0)
- error("%s", pcap_geterr(pd));
- if (pcap_get_selectable_fd(pd) == -1)
- error("pcap_get_selectable_fd() fails");
- if (dononblock) {
- if (pcap_setnonblock(pd, 1, ebuf) == -1)
- error("pcap_setnonblock failed: %s", ebuf);
- }
- selectable_fd = pcap_get_selectable_fd(pd);
- printf("Listening on %s\n", device);
- if (doselect) {
- for (;;) {
- fd_set setread, setexcept;
- struct timeval seltimeout;
-
- FD_ZERO(&setread);
- FD_SET(selectable_fd, &setread);
- FD_ZERO(&setexcept);
- FD_SET(selectable_fd, &setexcept);
- if (dotimeout) {
- seltimeout.tv_sec = 0;
- seltimeout.tv_usec = 1000;
- status = select(selectable_fd + 1, &setread,
- NULL, &setexcept, &seltimeout);
- } else {
- status = select(selectable_fd + 1, &setread,
- NULL, &setexcept, NULL);
- }
- if (status == -1) {
- printf("Select returns error (%s)\n",
- strerror(errno));
- } else {
- if (status == 0)
- printf("Select timed out: ");
- else
- printf("Select returned a descriptor: ");
- if (FD_ISSET(selectable_fd, &setread))
- printf("readable, ");
- else
- printf("not readable, ");
- if (FD_ISSET(selectable_fd, &setexcept))
- printf("exceptional condition\n");
- else
- printf("no exceptional condition\n");
- packet_count = 0;
- status = pcap_dispatch(pd, -1, countme,
- (u_char *)&packet_count);
- if (status < 0)
- break;
- printf("%d packets seen, %d packets counted after select returns\n",
- status, packet_count);
- }
- }
- } else if (dopoll) {
- for (;;) {
- struct pollfd fd;
- int polltimeout;
-
- fd.fd = selectable_fd;
- fd.events = POLLIN;
- if (dotimeout)
- polltimeout = 1;
- else
- polltimeout = -1;
- status = poll(&fd, 1, polltimeout);
- if (status == -1) {
- printf("Poll returns error (%s)\n",
- strerror(errno));
- } else {
- if (status == 0)
- printf("Poll timed out\n");
- else {
- printf("Poll returned a descriptor: ");
- if (fd.revents & POLLIN)
- printf("readable, ");
- else
- printf("not readable, ");
- if (fd.revents & POLLERR)
- printf("exceptional condition, ");
- else
- printf("no exceptional condition, ");
- if (fd.revents & POLLHUP)
- printf("disconnect, ");
- else
- printf("no disconnect, ");
- if (fd.revents & POLLNVAL)
- printf("invalid\n");
- else
- printf("not invalid\n");
- }
- packet_count = 0;
- status = pcap_dispatch(pd, -1, countme,
- (u_char *)&packet_count);
- if (status < 0)
- break;
- printf("%d packets seen, %d packets counted after poll returns\n",
- status, packet_count);
- }
- }
- } else {
- for (;;) {
- packet_count = 0;
- status = pcap_dispatch(pd, -1, countme,
- (u_char *)&packet_count);
- if (status < 0)
- break;
- printf("%d packets seen, %d packets counted after pcap_dispatch returns\n",
- status, packet_count);
- }
- }
- if (status == -2) {
- /*
- * We got interrupted, so perhaps we didn't
- * manage to finish a line we were printing.
- * Print an extra newline, just in case.
- */
- putchar('\n');
- }
- (void)fflush(stdout);
- if (status == -1) {
- /*
- * Error. Report it.
- */
- (void)fprintf(stderr, "%s: pcap_loop: %s\n",
- program_name, pcap_geterr(pd));
- }
- pcap_close(pd);
- exit(status == -1 ? 1 : 0);
-}
-
-static void
-countme(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
-{
- int *counterp = (int *)user;
-
- (*counterp)++;
-}
-
-static void
-usage(void)
-{
- (void)fprintf(stderr, "Usage: %s [ -sptn ] [ -i interface ] [expression]\n",
- program_name);
- exit(1);
-}
-
-/* VARARGS */
-static void
-error(const char *fmt, ...)
-{
- va_list ap;
-
- (void)fprintf(stderr, "%s: ", program_name);
- va_start(ap, fmt);
- (void)vfprintf(stderr, fmt, ap);
- va_end(ap);
- if (*fmt) {
- fmt += strlen(fmt);
- if (fmt[-1] != '\n')
- (void)fputc('\n', stderr);
- }
- exit(1);
- /* NOTREACHED */
-}
-
-/* VARARGS */
-static void
-warning(const char *fmt, ...)
-{
- va_list ap;
-
- (void)fprintf(stderr, "%s: WARNING: ", program_name);
- va_start(ap, fmt);
- (void)vfprintf(stderr, fmt, ap);
- va_end(ap);
- if (*fmt) {
- fmt += strlen(fmt);
- if (fmt[-1] != '\n')
- (void)fputc('\n', stderr);
- }
-}
-
-/*
- * Copy arg vector into a new buffer, concatenating arguments with spaces.
- */
-static char *
-copy_argv(register char **argv)
-{
- register char **p;
- register u_int len = 0;
- char *buf;
- char *src, *dst;
-
- p = argv;
- if (*p == 0)
- return 0;
-
- while (*p)
- len += strlen(*p++) + 1;
-
- buf = (char *)malloc(len);
- if (buf == NULL)
- error("copy_argv: malloc");
-
- p = argv;
- dst = buf;
- while ((src = *p++) != NULL) {
- while ((*dst++ = *src++) != '\0')
- ;
- dst[-1] = ' ';
- }
- dst[-1] = '\0';
-
- return buf;
-}
diff --git a/contrib/libpcap/tests/shb-option-too-long.pcapng b/contrib/libpcap/tests/shb-option-too-long.pcapng
new file mode 100644
index 0000000000000..f77397476f384
--- /dev/null
+++ b/contrib/libpcap/tests/shb-option-too-long.pcapng
Binary files differ
diff --git a/contrib/libpcap/tests/valgrindtest.c b/contrib/libpcap/tests/valgrindtest.c
deleted file mode 100644
index 011fe117b2cd3..0000000000000
--- a/contrib/libpcap/tests/valgrindtest.c
+++ /dev/null
@@ -1,470 +0,0 @@
-/*
- * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that: (1) source code distributions
- * retain the above copyright notice and this paragraph in its entirety, (2)
- * distributions including binary code include the above copyright notice and
- * this paragraph in its entirety in the documentation or other materials
- * provided with the distribution, and (3) all advertising materials mentioning
- * features or use of this software display the following acknowledgement:
- * ``This product includes software developed by the University of California,
- * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
- * the University nor the names of its contributors may be used to endorse
- * or promote products derived from this software without specific prior
- * written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-/*
- * This doesn't actually test libpcap itself; it tests whether
- * valgrind properly handles the APIs libpcap uses. If it doesn't,
- * we end up getting patches submitted to "fix" references that
- * valgrind claims are being made to uninitialized data, when, in
- * fact, the OS isn't making any such references - or we get
- * valgrind *not* detecting *actual* incorrect references.
- *
- * Both BPF and Linux socket filters aren't handled correctly
- * by some versions of valgrind. See valgrind bug 318203 for
- * Linux:
- *
- * https://bugs.kde.org/show_bug.cgi?id=318203
- *
- * and valgrind bug 312989 for OS X:
- *
- * https://bugs.kde.org/show_bug.cgi?id=312989
- *
- * The fixes for both of those are checked into the official valgrind
- * repository.
- *
- * The unofficial FreeBSD port has similar issues to the official OS X
- * port, for similar reasons.
- */
-#ifndef lint
-static const char copyright[] _U_ =
- "@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000\n\
-The Regents of the University of California. All rights reserved.\n";
-#endif
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <arpa/inet.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
-/* BSD-flavored OS - use BPF */
-#define USE_BPF
-#elif defined(linux)
-/* Linux - use socket filters */
-#define USE_SOCKET_FILTERS
-#else
-#error "Unknown platform or platform that doesn't support Valgrind"
-#endif
-
-#if defined(USE_BPF)
-
-#include <sys/ioctl.h>
-#include <net/bpf.h>
-
-/*
- * Make "pcap.h" not include "pcap/bpf.h"; we are going to include the
- * native OS version, as we're going to be doing our own ioctls to
- * make sure that, in the uninitialized-data tests, the filters aren't
- * checked by libpcap before being handed to BPF.
- */
-#define PCAP_DONT_INCLUDE_PCAP_BPF_H
-
-#elif defined(USE_SOCKET_FILTERS)
-
-#include <sys/socket.h>
-#include <linux/types.h>
-#include <linux/filter.h>
-
-#endif
-
-#include <pcap.h>
-
-static char *program_name;
-
-/*
- * This was introduced by Clang:
- *
- * http://clang.llvm.org/docs/LanguageExtensions.html#has-attribute
- *
- * in some version (which version?); it has been picked up by GCC 5.0.
- */
-#ifndef __has_attribute
- /*
- * It's a macro, so you can check whether it's defined to check
- * whether it's supported.
- *
- * If it's not, define it to always return 0, so that we move on to
- * the fallback checks.
- */
- #define __has_attribute(x) 0
-#endif
-
-#if __has_attribute(noreturn) \
- || (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 205)) \
- || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) \
- || (defined(__xlC__) && __xlC__ >= 0x0A01) \
- || (defined(__HP_aCC) && __HP_aCC >= 61000)
- /*
- * Compiler with support for it, 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.
- */
- #define PCAP_NORETURN __attribute((noreturn))
-#elif defined( _MSC_VER )
- #define PCAP_NORETURN __declspec(noreturn)
-#else
- #define PCAP_NORETURN
-#endif
-
-#if __has_attribute(__format__) \
- || (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 203)) \
- || (defined(__xlC__) && __xlC__ >= 0x0A01) \
- || (defined(__HP_aCC) && __HP_aCC >= 61000)
- /*
- * Compiler with support for it, or GCC 2.3 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.
- */
- #define PCAP_PRINTFLIKE(x,y) __attribute__((__format__(__printf__,x,y)))
-#else
- #define PCAP_PRINTFLIKE(x,y)
-#endif
-
-/* Forwards */
-static void PCAP_NORETURN usage(void);
-static void PCAP_NORETURN error(const char *, ...) PCAP_PRINTFLIKE(1, 2);
-static void warning(const char *, ...) PCAP_PRINTFLIKE(1, 2);
-
-/*
- * On Windows, we need to open the file in binary mode, so that
- * we get all the bytes specified by the size we get from "fstat()".
- * On UNIX, that's not necessary. O_BINARY is defined on Windows;
- * we define it as 0 if it's not defined, so it does nothing.
- */
-#ifndef O_BINARY
-#define O_BINARY 0
-#endif
-
-static char *
-read_infile(char *fname)
-{
- register int i, fd, cc;
- register char *cp;
- struct stat buf;
-
- fd = open(fname, O_RDONLY|O_BINARY);
- if (fd < 0)
- error("can't open %s: %s", fname, pcap_strerror(errno));
-
- if (fstat(fd, &buf) < 0)
- error("can't stat %s: %s", fname, pcap_strerror(errno));
-
- cp = malloc((u_int)buf.st_size + 1);
- if (cp == NULL)
- error("malloc(%d) for %s: %s", (u_int)buf.st_size + 1,
- fname, pcap_strerror(errno));
- cc = read(fd, cp, (u_int)buf.st_size);
- if (cc < 0)
- error("read %s: %s", fname, pcap_strerror(errno));
- if (cc != buf.st_size)
- error("short read %s (%d != %d)", fname, cc, (int)buf.st_size);
-
- close(fd);
- /* replace "# comment" with spaces */
- for (i = 0; i < cc; i++) {
- if (cp[i] == '#')
- while (i < cc && cp[i] != '\n')
- cp[i++] = ' ';
- }
- cp[cc] = '\0';
- return (cp);
-}
-
-/* VARARGS */
-static void
-error(const char *fmt, ...)
-{
- va_list ap;
-
- (void)fprintf(stderr, "%s: ", program_name);
- va_start(ap, fmt);
- (void)vfprintf(stderr, fmt, ap);
- va_end(ap);
- if (*fmt) {
- fmt += strlen(fmt);
- if (fmt[-1] != '\n')
- (void)fputc('\n', stderr);
- }
- exit(1);
- /* NOTREACHED */
-}
-
-/* VARARGS */
-static void
-warning(const char *fmt, ...)
-{
- va_list ap;
-
- (void)fprintf(stderr, "%s: WARNING: ", program_name);
- va_start(ap, fmt);
- (void)vfprintf(stderr, fmt, ap);
- va_end(ap);
- if (*fmt) {
- fmt += strlen(fmt);
- if (fmt[-1] != '\n')
- (void)fputc('\n', stderr);
- }
-}
-
-/*
- * Copy arg vector into a new buffer, concatenating arguments with spaces.
- */
-static char *
-copy_argv(register char **argv)
-{
- register char **p;
- register u_int len = 0;
- char *buf;
- char *src, *dst;
-
- p = argv;
- if (*p == 0)
- return 0;
-
- while (*p)
- len += strlen(*p++) + 1;
-
- buf = (char *)malloc(len);
- if (buf == NULL)
- error("copy_argv: malloc");
-
- p = argv;
- dst = buf;
- while ((src = *p++) != NULL) {
- while ((*dst++ = *src++) != '\0')
- ;
- dst[-1] = ' ';
- }
- dst[-1] = '\0';
-
- return buf;
-}
-
-#define INSN_COUNT 17
-
-int
-main(int argc, char **argv)
-{
- char *cp, *device;
- int op;
- int dorfmon, useactivate;
- char ebuf[PCAP_ERRBUF_SIZE];
- char *infile;
- char *cmdbuf;
- pcap_t *pd;
- int status = 0;
- int pcap_fd;
-#if defined(USE_BPF)
- struct bpf_program bad_fcode;
- struct bpf_insn uninitialized[INSN_COUNT];
-#elif defined(USE_SOCKET_FILTERS)
- struct sock_fprog bad_fcode;
- struct sock_filter uninitialized[INSN_COUNT];
-#endif
- struct bpf_program fcode;
-
- device = NULL;
- dorfmon = 0;
- useactivate = 0;
- infile = NULL;
-
- if ((cp = strrchr(argv[0], '/')) != NULL)
- program_name = cp + 1;
- else
- program_name = argv[0];
-
- opterr = 0;
- while ((op = getopt(argc, argv, "aF:i:I")) != -1) {
- switch (op) {
-
- case 'a':
- useactivate = 1;
- break;
-
- case 'F':
- infile = optarg;
- break;
-
- case 'i':
- device = optarg;
- break;
-
- case 'I':
- dorfmon = 1;
- useactivate = 1; /* required for rfmon */
- break;
-
- default:
- usage();
- /* NOTREACHED */
- }
- }
-
- if (device == NULL) {
- /*
- * No interface specified; get whatever pcap_lookupdev()
- * finds.
- */
- device = pcap_lookupdev(ebuf);
- if (device == NULL) {
- error("couldn't find interface to use: %s",
- ebuf);
- }
- }
-
- if (infile != NULL) {
- /*
- * Filter specified with "-F" and a file containing
- * a filter.
- */
- cmdbuf = read_infile(infile);
- } else {
- if (optind < argc) {
- /*
- * Filter specified with arguments on the
- * command line.
- */
- cmdbuf = copy_argv(&argv[optind+1]);
- } else {
- /*
- * No filter specified; use an empty string, which
- * compiles to an "accept all" filter.
- */
- cmdbuf = "";
- }
- }
-
- if (useactivate) {
- pd = pcap_create(device, ebuf);
- if (pd == NULL)
- error("%s: pcap_create() failed: %s", device, ebuf);
- status = pcap_set_snaplen(pd, 65535);
- if (status != 0)
- error("%s: pcap_set_snaplen failed: %s",
- device, pcap_statustostr(status));
- status = pcap_set_promisc(pd, 1);
- if (status != 0)
- error("%s: pcap_set_promisc failed: %s",
- device, pcap_statustostr(status));
- if (dorfmon) {
- status = pcap_set_rfmon(pd, 1);
- if (status != 0)
- error("%s: pcap_set_rfmon failed: %s",
- device, pcap_statustostr(status));
- }
- status = pcap_set_timeout(pd, 1000);
- if (status != 0)
- error("%s: pcap_set_timeout failed: %s",
- device, pcap_statustostr(status));
- status = pcap_activate(pd);
- if (status < 0) {
- /*
- * pcap_activate() failed.
- */
- error("%s: %s\n(%s)", device,
- pcap_statustostr(status), pcap_geterr(pd));
- } else if (status > 0) {
- /*
- * pcap_activate() succeeded, but it's warning us
- * of a problem it had.
- */
- warning("%s: %s\n(%s)", device,
- pcap_statustostr(status), pcap_geterr(pd));
- }
- } else {
- *ebuf = '\0';
- pd = pcap_open_live(device, 65535, 1, 1000, ebuf);
- if (pd == NULL)
- error("%s", ebuf);
- else if (*ebuf)
- warning("%s", ebuf);
- }
-
- pcap_fd = pcap_fileno(pd);
-
- /*
- * Try setting a filter with an uninitialized bpf_program
- * structure. This should cause valgrind to report a
- * problem.
- *
- * We don't check for errors, because it could get an
- * error due to a bad pointer or count.
- */
-#if defined(USE_BPF)
- ioctl(pcap_fd, BIOCSETF, &bad_fcode);
-#elif defined(USE_SOCKET_FILTERS)
- setsockopt(pcap_fd, SOL_SOCKET, SO_ATTACH_FILTER, &bad_fcode,
- sizeof(bad_fcode));
-#endif
-
- /*
- * Try setting a filter with an initialized bpf_program
- * structure that points to an uninitialized program.
- * That should also cause valgrind to report a problem.
- *
- * We don't check for errors, because it could get an
- * error due to a bad pointer or count.
- */
-#if defined(USE_BPF)
- bad_fcode.bf_len = INSN_COUNT;
- bad_fcode.bf_insns = uninitialized;
- ioctl(pcap_fd, BIOCSETF, &bad_fcode);
-#elif defined(USE_SOCKET_FILTERS)
- bad_fcode.len = INSN_COUNT;
- bad_fcode.filter = uninitialized;
- setsockopt(pcap_fd, SOL_SOCKET, SO_ATTACH_FILTER, &bad_fcode,
- sizeof(bad_fcode));
-#endif
-
- /*
- * Now compile a filter and set the filter with that.
- * That should *not* cause valgrind to report a
- * problem.
- */
- if (pcap_compile(pd, &fcode, cmdbuf, 1, 0) < 0)
- error("can't compile filter: %s", pcap_geterr(pd));
- if (pcap_setfilter(pd, &fcode) < 0)
- error("can't set filter: %s", pcap_geterr(pd));
-
- pcap_close(pd);
- exit(status < 0 ? 1 : 0);
-}
-
-static void
-usage(void)
-{
- (void)fprintf(stderr, "%s, with %s\n", program_name,
- pcap_lib_version());
- (void)fprintf(stderr,
- "Usage: %s [-aI] [ -F file ] [ -I interface ] [ expression ]\n",
- program_name);
- exit(1);
-}
diff --git a/contrib/libpcap/fad-null.c b/contrib/libpcap/varattrs.h
index cecfbcb460525..05bfe8cd4a032 100644
--- a/contrib/libpcap/fad-null.c
+++ b/contrib/libpcap/varattrs.h
@@ -1,6 +1,6 @@
/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */
/*
- * Copyright (c) 1994, 1995, 1996, 1997, 1998
+ * 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
@@ -32,29 +32,28 @@
* SUCH DAMAGE.
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
+#ifndef varattrs_h
+#define varattrs_h
-#include <pcap.h>
+#include <pcap/compiler-tests.h>
/*
- * Get a list of all interfaces that are up and that we can open.
- * Returns -1 on error, 0 otherwise.
- * The list, as returned through "alldevsp", may be null if no interfaces
- * were up and could be opened.
- *
- * This is the implementation used on platforms that have no support for
- * packet capture.
+ * Attributes to apply to variables, using various compiler-specific
+ * extensions.
*/
-int
-pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
-{
- /*
- * Succeed, but don't return any interfaces; we return only those
- * we can open, and we can't open any if there's no support
- * for packet capture.
- */
- *alldevsp = NULL;
- return (0);
-}
+
+#if __has_attribute(unused) \
+ || PCAP_IS_AT_LEAST_GNUC_VERSION(2,0)
+ /*
+ * Compiler with support for __attribute__((unused)), or GCC 2.0 and
+ * later, so it supports __attribute__((unused)).
+ */
+ #define _U_ __attribute__((unused))
+#else
+ /*
+ * We don't know of any way to mark a variable as unused.
+ */
+ #define _U_
+#endif
+
+#endif